From 93d949e711b5f95d5dc0fe855d67c662dbc74325 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sat, 5 Sep 2020 01:51:22 +0200 Subject: [PATCH 1/2] Original Pebble changes --- CMakeLists.txt | 15 + Makefile | 22 + Makefile.objs | 14 + README.md | 136 + README.rst | 71 + VERSION | 4 + assets/qemu-spalding-overlay.png | Bin 0 -> 3854 bytes assets/qemu-spalding-overlay.psd | Bin 0 -> 71588 bytes block/qcow2-cache.c | 4 + block/qcow2.c | 9 + block/quorum.c | 4 + block/raw-posix.c | 2634 ++ configure | 16 + crypto/tlssession.c | 3 +- default-configs/arm-softmmu.mak | 44 + docs/qapi-code-gen.txt | 1183 + hw/arm/Makefile.objs | 22 + hw/arm/armv7m.c | 141 + hw/arm/pebble.c | 682 + hw/arm/pebble.h | 55 + hw/arm/pebble_control.c | 560 + hw/arm/pebble_control.h | 10 + hw/arm/pebble_robert.c | 146 + hw/arm/pebble_silk.c | 125 + hw/arm/stellaris.c | 5 + hw/arm/stm32.c | 81 + hw/arm/stm32_clktree.c | 299 + hw/arm/stm32_exti.c | 397 + hw/arm/stm32_flash.c | 106 + hw/arm/stm32_p103.c | 134 + hw/arm/stm32_rcc.c | 50 + hw/arm/stm32_rcc.h | 20 + hw/arm/stm32f1xx.c | 197 + hw/arm/stm32f1xx.h | 61 + hw/arm/stm32f1xx_rcc.c | 685 + hw/arm/stm32f1xx_rcc.h | 51 + hw/arm/stm32f205_soc.c | 5 + hw/arm/stm32f2xx.c | 382 + hw/arm/stm32f2xx.h | 11 + hw/arm/stm32f2xx_adc.c | 247 + hw/arm/stm32f2xx_crc.c | 233 + hw/arm/stm32f2xx_dma.c | 414 + hw/arm/stm32f2xx_dummy.c | 105 + hw/arm/stm32f2xx_flash.c | 146 + hw/arm/stm32f2xx_gpio.c | 285 + hw/arm/stm32f2xx_i2c.c | 292 + hw/arm/stm32f2xx_pwr.c | 191 + hw/arm/stm32f2xx_rcc.c | 1134 + hw/arm/stm32f2xx_rcc.h | 78 + hw/arm/stm32f2xx_rtc.c | 688 + hw/arm/stm32f2xx_syscfg.c | 276 + hw/arm/stm32f2xx_tim.c | 331 + hw/arm/stm32f4xx.c | 425 + hw/arm/stm32f4xx.h | 15 + hw/arm/stm32f7xx.c | 422 + hw/arm/stm32f7xx.h | 15 + hw/arm/stm32f7xx_i2c.c | 252 + hw/arm/stm32f7xx_lptim.c | 241 + hw/block/Makefile.objs | 6 + hw/block/m25p80.c | 9 + hw/block/mt25q.c | 512 + hw/block/mx25u.c | 533 + hw/block/pflash_jedec_424.c | 1073 + hw/char/Makefile.objs | 6 + hw/char/stm32_uart.c | 851 + hw/char/stm32f7xx_uart.c | 737 + hw/core/irq.c | 35 +- hw/core/qdev.c | 9 + hw/display/Makefile.objs | 6 + hw/display/ls013b7dh01.c | 379 + hw/display/pebble_snowy_display.c | 2185 ++ hw/display/pebble_snowy_display.h | 12 + hw/display/pebble_snowy_display_overlays.h | 32416 +++++++++++++++++++ hw/gpio/Makefile.objs | 6 + hw/gpio/stm32_afio.c | 305 + hw/gpio/stm32_exti.c | 331 + hw/gpio/stm32_gpio.c | 358 + hw/i386/kvm/pci-assign.c | 1901 ++ hw/i386/pc.c | 6 + hw/i386/pc_piix.c | 198 +- hw/ide/ahci.c | 30 + hw/intc/arm_gic.c | 6 + hw/intc/armv7m_nvic.c | 468 + hw/net/vmxnet3.c | 8 + hw/ssi/Makefile.objs | 7 + hw/ssi/stm32f2xx_spi.c | 211 + hw/ssi/stm32f412_qspi.c | 347 + include/hw/arm/boot.h | 19 + include/hw/arm/stm32.h | 554 + include/hw/arm/stm32_clktree.h | 82 + include/hw/block/flash.h | 27 + include/hw/irq.h | 10 +- include/hw/qdev-core.h | 1 + include/hw/sysbus.h | 7 + monitor.c | 4244 +++ pebble.py | 60 + pebble_dbgserial.sh | 1 + qemu-char.c | 4393 +++ qtest.c | 92 +- scripts/png_to_cstruct.py | 90 + target-arm/arm-semi.c | 660 + target-arm/cpu.c | 1509 + target-arm/cpu.h | 2060 ++ target-arm/helper.c | 8971 +++++ target-arm/internals.h | 445 + target-arm/machine.c | 355 + target-arm/op_helper.c | 1009 + target-arm/translate.c | 11688 +++++++ tests/Makefile | 674 + tests/libqtest.c | 1060 + tests/qemu-iotests/061.out | 30 +- tests/qemu-iotests/067.out | 301 + tests/qemu-iotests/071.out | 10 + tests/qemu-iotests/087.out | 6 + tests/qtest/libqtest.h | 389 +- tests/test-stm32.c | 311 + ui/cocoa.m | 45 +- ui/gtk.c | 6 + ui/sdl.c | 1009 + ui/sdl2.c | 6 + ui/vnc-ws.c | 31 + util/qemu-thread-posix.c | 4 + 122 files changed, 97250 insertions(+), 34 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 assets/qemu-spalding-overlay.png create mode 100644 assets/qemu-spalding-overlay.psd create mode 100644 block/raw-posix.c create mode 100644 docs/qapi-code-gen.txt create mode 100644 hw/arm/pebble.c create mode 100644 hw/arm/pebble.h create mode 100644 hw/arm/pebble_control.c create mode 100644 hw/arm/pebble_control.h create mode 100644 hw/arm/pebble_robert.c create mode 100644 hw/arm/pebble_silk.c create mode 100644 hw/arm/stm32.c create mode 100644 hw/arm/stm32_clktree.c create mode 100644 hw/arm/stm32_exti.c create mode 100644 hw/arm/stm32_flash.c create mode 100644 hw/arm/stm32_p103.c create mode 100644 hw/arm/stm32_rcc.c create mode 100644 hw/arm/stm32_rcc.h create mode 100644 hw/arm/stm32f1xx.c create mode 100644 hw/arm/stm32f1xx.h create mode 100644 hw/arm/stm32f1xx_rcc.c create mode 100644 hw/arm/stm32f1xx_rcc.h create mode 100644 hw/arm/stm32f2xx.c create mode 100644 hw/arm/stm32f2xx.h create mode 100644 hw/arm/stm32f2xx_adc.c create mode 100644 hw/arm/stm32f2xx_crc.c create mode 100644 hw/arm/stm32f2xx_dma.c create mode 100644 hw/arm/stm32f2xx_dummy.c create mode 100644 hw/arm/stm32f2xx_flash.c create mode 100644 hw/arm/stm32f2xx_gpio.c create mode 100644 hw/arm/stm32f2xx_i2c.c create mode 100644 hw/arm/stm32f2xx_pwr.c create mode 100644 hw/arm/stm32f2xx_rcc.c create mode 100644 hw/arm/stm32f2xx_rcc.h create mode 100644 hw/arm/stm32f2xx_rtc.c create mode 100644 hw/arm/stm32f2xx_syscfg.c create mode 100644 hw/arm/stm32f2xx_tim.c create mode 100644 hw/arm/stm32f4xx.c create mode 100644 hw/arm/stm32f4xx.h create mode 100644 hw/arm/stm32f7xx.c create mode 100644 hw/arm/stm32f7xx.h create mode 100644 hw/arm/stm32f7xx_i2c.c create mode 100644 hw/arm/stm32f7xx_lptim.c create mode 100644 hw/block/mt25q.c create mode 100644 hw/block/mx25u.c create mode 100644 hw/block/pflash_jedec_424.c create mode 100644 hw/char/stm32_uart.c create mode 100644 hw/char/stm32f7xx_uart.c create mode 100644 hw/display/ls013b7dh01.c create mode 100644 hw/display/pebble_snowy_display.c create mode 100644 hw/display/pebble_snowy_display.h create mode 100644 hw/display/pebble_snowy_display_overlays.h create mode 100644 hw/gpio/stm32_afio.c create mode 100644 hw/gpio/stm32_exti.c create mode 100644 hw/gpio/stm32_gpio.c create mode 100644 hw/i386/kvm/pci-assign.c create mode 100644 hw/ssi/stm32f412_qspi.c create mode 100644 include/hw/arm/stm32.h create mode 100644 include/hw/arm/stm32_clktree.h create mode 100644 monitor.c create mode 100755 pebble.py create mode 100755 pebble_dbgserial.sh create mode 100644 qemu-char.c create mode 100755 scripts/png_to_cstruct.py create mode 100644 target-arm/arm-semi.c create mode 100644 target-arm/cpu.c create mode 100644 target-arm/cpu.h create mode 100644 target-arm/helper.c create mode 100644 target-arm/internals.h create mode 100644 target-arm/machine.c create mode 100644 target-arm/op_helper.c create mode 100644 target-arm/translate.c create mode 100644 tests/Makefile create mode 100644 tests/libqtest.c create mode 100644 tests/test-stm32.c create mode 100644 ui/sdl.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000..5ce5a6fcf3c49 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.3) +project(qemu_dev) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +file(GLOB_RECURSE src "*.c") + +set(SOURCES + ${src}) + +include_directories(include) + +add_custom_target(qemu_dev COMMAND make + CLION_EXE_DIR=${PROJECT_BINARY_DIR}) + diff --git a/Makefile b/Makefile index 8a9113e6663eb..11d36c2423945 100644 --- a/Makefile +++ b/Makefile @@ -494,6 +494,7 @@ qemu-version.h: FORCE config-host.h: config-host.h-timestamp config-host.h-timestamp: config-host.mak +<<<<<<< HEAD qemu-options.def: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"GEN","$@") @@ -510,6 +511,27 @@ $(SOFTMMU_ALL_RULES): config-all-devices.mak ifdef DECOMPRESS_EDK2_BLOBS $(SOFTMMU_ALL_RULES): $(edk2-decompressed) endif +======= +qemu-options.def: $(SRC_PATH)/qemu-options.hx + $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") + +SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) +SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES)) + +$(SOFTMMU_SUBDIR_RULES): $(block-obj-y) +$(SOFTMMU_SUBDIR_RULES): $(crypto-obj-y) +$(SOFTMMU_SUBDIR_RULES): $(qom-obj-y) +$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak + +subdir-%: + $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" all,) + +subdir-pixman: pixman/Makefile + $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" all,) + +pixman/Makefile: $(SRC_PATH)/pixman/configure + (cd pixman; CFLAGS="$(CFLAGS) -fPIC $(extra_cflags) $(extra_ldflags)" $(SRC_PATH)/pixman/configure $(AUTOCONF_HOST) --disable-gtk --disable-shared --enable-static) +>>>>>>> 919b29ba7d... Pebble Qemu SOFTMMU_FUZZ_RULES=$(filter %-softmmu/fuzz, $(TARGET_DIRS_RULES)) $(SOFTMMU_FUZZ_RULES): $(authz-obj-y) diff --git a/Makefile.objs b/Makefile.objs index a7c967633acf9..bdcb689abdff0 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -1,8 +1,14 @@ ####################################################################### # Common libraries for tools and emulators stub-obj-y = stubs/ +<<<<<<< HEAD util-obj-y = crypto/ util/ qobject/ qapi/ qom-obj-y = qom/ +======= +util-obj-y = util/ qobject/ qapi/ +util-obj-y += crypto/ +util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o +>>>>>>> 919b29ba7d... Pebble Qemu ####################################################################### # code used by both qemu system emulation and qemu-img @@ -36,6 +42,14 @@ storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o job-qmp.o storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o +crypto-obj-y = crypto/ +crypto-aes-obj-y = crypto/ + +####################################################################### +# qom-obj-y is code used by both qemu system emulation and qemu-img + +qom-obj-y = qom/ + ###################################################################### # Target independent part of system emulation. The long term path is to # suppress *all* target specific code in case of system emulation, i.e. a diff --git a/README.md b/README.md new file mode 100644 index 0000000000000..4486888f44931 --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ +# Pebble Smartwatch QEMU Implementation + +## Overview +This is a derivative of QEMU v2.1.1 that has been modified to include an implementation of the STM32F2xx microcontroller. +This is based off of a QEMU fork that is targeting the STM32F103: https://github.com/beckus/qemu_stm32. +This repo contains both beckus' STM32F1xx implementation and Pebble's STM32F2xx additions. + +__DANGER DANGER: It is very much a work-in-progress! Only some of the peripherals are working at the moment. Please contribute!__ + +## Dependencies +QEMU requires that development packages for glib20 and pixman are installed. + +### FreeBSD +Install the `devel/glib20` and `x11/pixman` ports. + +### Linux + +### Mac OS X + +### Windows + +## Building +Commands for a typical build: + + ./configure --disable-werror --enable-debug --target-list="arm-softmmu" \ + --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY + make + +Summary set of configure options that are useful when developing (tested only on OS X 10.9.5): + + ./configure --enable-tcg-interpreter --extra-ldflags=-g \ + --with-coroutine=gthread --enable-debug-tcg --enable-cocoa \ + --enable-debug --disable-werror --target-list="arm-softmmu" \ + --extra-cflags=-DDEBUG_CLKTREE --extra-cflags=-DDEBUG_STM32_RCC \ + --extra-cflags=-DDEBUG_STM32_UART --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY \ + --extra-cflags=-DDEBUG_GIC + +####Configure options which control the STM32 implementation: + + --extra-cflags=-DDEBUG_CLKTREE + Print out clock tree debug statements. + + --extra-cflags=-DDEBUG_STM32_RCC + Print RCC debug statements. + + --extra-cflags=-DDEBUG_STM32_UART + Print UART debug statements. + + --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY + Disable the BAUD rate timing simulation + (i.e. the UART will transmit or receive as fast as possible, rather than + using a realistic delay). + + --extra-cflags=-DSTM32_UART_ENABLE_OVERRUN + Enable setting of the overrun flag if a character is + received before the last one is processed. If this is not set, the UART + will not receive the next character until the previous one is read by + software. Although less realisitic, it is safer NOT to use this, in case the VM is + running slow. + +####Other QEMU configure options which are useful for troubleshooting: + --extra-cflags=-DDEBUG_GIC + Extra logging around which interrupts are asserted + +####qemu-system-arm options which are useful for troubleshooting: + -d ? + To see available log levels + + -d cpu,in_asm + Enable logging to view the CPU state during execution and the ARM + instructions which are being executed. I believe --enable-debug must be + used for this to work. + + +Useful make commands when rebuilding: + + make defconfig + make clean + +## Generating Images +* Use `./waf build qemu_image_spi` to generate `qemu_spi_flash.bin` from tintin. +* Use `./waf build qemu_image_micro` to generate `qemu_micro_flash.bin` from tintin. + + +### Under the covers of the images + +QEMU's -pflash argument is used to specify a file to use as the micro flash. +An image can be created by concatenating the boot and main firmware files, +like so: + + truncate -s 64k tintin_boot.bin + cat tintin_boot.bin tintin_fw.bin > micro_flash.bin + truncate -s 512k micro_flash.bin + +## Running +There is a convenience script `pebble.sh` that runs QEMU. It depends on the existence of (symlinked) images `qemu_micro_flash.bin` and `qemu_spi_flash.bin`. + +### More details about running QEMU + +The generated executable is arm-softmmu/qemu-system-arm . + +Example: + + qemu-system-arm -rtc base=localtime -machine pebble-bb2 -cpu cortex-m3 -s \ + -pflash qemu_micro_flash.bin -mtdblock qemu_spi_flash.bin + +Adding `-S` to the commandline will have QEMU wait in the monitor at start; +the _c_ontinue command is necessary to start the virtual CPU. + +## QEMU Docs +Read original the documentation in qemu-doc.html or on http://wiki.qemu.org + +## QEMU Modifications +This emulator consists largely of new hardware device models; it includes +only minor changes to existing QEMU functionality. + +The changes can be reviewed by running `git diff --diff-filter=M v1.5.0-backports`. + +To list the added files, use `git diff --name-only --diff-filter=A v1.5.0-backports`. + +## License + +The following points clarify the QEMU license: + +1. QEMU as a whole is released under the GNU General Public License + +2. Parts of QEMU have specific licenses which are compatible with the +GNU General Public License. Hence each source file contains its own +licensing information. + +Many hardware device emulation sources are released under the BSD license. + +3. The Tiny Code Generator (TCG) is released under the BSD license + (see license headers in files). + +4. QEMU is a trademark of Fabrice Bellard. diff --git a/README.rst b/README.rst index 7497709291dc9..9e99bec861e01 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,77 @@ +<<<<<<< HEAD:README.rst =========== QEMU README =========== +======= +QEMU with STM32 Microcontroller Implementation + +Official Homepage: http://beckus.github.io/qemu_stm32/ + +OVERVIEW +This is a copy of QEMU that has been modified to include an implementation +of the STM32 microcontroller. It also implements an Olimex STM32_P103 +developmentvboard. This project runs the demos located in the +stm32_p103_demos project located at: https://github.com/beckus/stm32_p103_demos . + +Commands for a typical build: +./configure --enable-debug --target-list="arm-softmmu" +make + +Useful make commands when rebuilding: + make defconfig + make clean + +The generated executable is arm-softmmu/qemu-system-arm . + +Other configure options which control the STM32 implementation: + + --extra-cflags=-DDEBUG_CLKTREE + Print out clock tree debug statements. + + --extra-cflags=-DDEBUG_STM32_RCC + Print RCC debug statements. + + --extra-cflags=-DDEBUG_STM32_UART + Print UART debug statements. + + --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY + Disable the BAUD rate timing simulation + (i.e. the UART will transmit or receive as fast as possible, rather than + using a realistic delay). + + --extra-cflags=-DSTM32_UART_ENABLE_OVERRUN + Enable setting of the overrun flag if a character is + received before the last one is processed. If this is not set, the UART + will not receive the next character until the previous one is read by + software. Although less realisitic, this is safer in case the VM is + running slow. + +Other QEMU configure options which are useful for troubleshooting: + --extra-cflags=-DDEBUG_GIC + +qemu-system-arm options which are useful for trobuleshooting: + -d ? + To see available log levels + + -d cpu,in_asm + Enable logging to view the CPU state during execution and the ARM + instructions which are being executed. I believe --enable-debug must be + used for this to work. + By default, you can find the output in /tmp/qemu.log: + +UNIT TESTING +Unit test scripts are included for the STM32 implementation. +These test will be executed when running "make" with the standard +check targets (see tests/Makefile for documentation of QEMU's unit +testing features): + make check + make check-qtest-arm + + + +The original QEMU README follows: + +>>>>>>> 919b29ba7d... Pebble Qemu:README QEMU is a generic and open source machine & userspace emulator and virtualizer. diff --git a/VERSION b/VERSION index 0062ac971805f..09854fb74eea1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1,5 @@ +<<<<<<< HEAD 5.0.0 +======= +2.5.0-pebble4 +>>>>>>> 919b29ba7d... Pebble Qemu diff --git a/assets/qemu-spalding-overlay.png b/assets/qemu-spalding-overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..2d422882ae31501b231c656a23da9c9c6a43666d GIT binary patch literal 3854 zcmaJ^c|4SB`xhnq_8vgwX)C0(o6UIlsS7t<*ZlP;UMj(*$&tPpM_flZOIC$oqYfGdL#O7Wr)$kE}g6ts+t z+$oy3AJ@-)FN(xsfCy_kpeRO|)LKRcZ5tIvAkisY0Fe?(V`7Y_8}1qdXk?7Bua!H* zJq$;o(p+NLlmjsy-lP~h2}w4#{S|J^+rzrU0x!)<6=(8Ua8cK~O6M0*sn zjHS`o#(i6s*%H@Wkz~IQpNKm9Dh{X;CLy<@%7y<*sU_hw`kQ2@15~6@i zj>%6C4ipZFO$+1FSWLj0M*@)*!NnL$k^Y?mBh20XAID7252B=$fujgvU?>OzW-!+B z`mW94dQtu##=mNFyraV?U@r=X6~QJ+>k(q|(^$&g{|>aKC`E(vWYeTYAslsJks=rr zCfC&gV=TP^k!fU<6$}O^L#&8ED3lZegcG1}pbgZT2!tajNVtuS6%0zY{^{r6>>Y4$ z7~ILp-pbL*3JP_!vPW3jBM~r1q_u;+6$AnKY3s`5a0yHjnj_o@SSxD!Y;=9+NlTA}{V+kwKS{YD`>u~`hjccxLa ze?dWkQAkiLYZwrMK)`@-A`uEC!jN!ah&6=_Lm)%Qa3ab0hduef82r0ar4nf-VLt(( zNLDawA`wOa5)f7)Qc@8%K%_N-EG3l;heOB+7!d|B21_A=*P7?Qn(3!V+M#RPe?~)k z_-D8%OzA|irK59odyb)ujIx2NgS~fD|3twmD|>j;iRqjt>Kn{=0rlb&RMPivFSgt= zV0xo&Z>|}~aN>05r01-yf6fJ9`;`G$A8asXz>c){;b*WU`oSz`ryjJ^J%jS z=7&`3^sXf@EZWQPf^--(=fJ?~x}(6OL6VK5a{Mt^cmZEk2PeKEhyCX3qx~s`UnO1! z$;Z0Jv#;&$le^W4@)jQRQZ?@UuV$kV@av%OO5}TNG3a!bC=8Z|dtz zzn3E~3a?B{1HX6`@1)P1^fcY9=|4zkO#UH4C4`HbgA-dd4KLL8RrUDD&LQjS+)z~^Jv)w6BL7QixfnLIlKJ%F`0bmc5}j|s z0FF^~cj4s14FzEU?>K1qrM;I9sNb@1SG}nIL|fOio%6+Y0$HCDQ=JJFe~GZnlW9kH7HKE+RuiXos2$JohS|;X)D*-fynJhOiWMw zTE&ly&N+OW?y-L7JRwO8mGkC2d#SL8idmX5E8P0*of*eeK@g!R;WT~L6Vq&_-2%L3wQc6%kmu9c#2(=OUvdPZJNWLEEPpkvz^H zOHy7{5?T&D+hgd8r(#w|+}X;=*_?;y_?_jVz<#-CHjc=wOEa0jcKz6vkE4G+)B~lN zRKIp=Hn4BWqj4%3g0mTJGd$9yl5pc>c$(!>lcWF0z3#5xY&B&z%{g7gj(;uB8d68& z#wCe9JcA60te(uJecRu#93=;a)X>b5JS}|Qd}Pa(sJ7h;ZD}#s@psR%hE&lMuQC1N zU{6WakP3Q~Yl-C;ZCmQP`(8=diQIlBVOp}j-9cZ_?Is(VvhH#U3Z>;N(PVFkpE<5C z0H<$P;3>B&3TtE85l~)}wm%y;=_PRf>ypuRR7`b-h%}@i`-eaj2vQe7os?A_iMIyf!#i4l5Vc<_#2#wkof0Lt}9nb^G0@Vtd@57SFU|PTjUE>JV#f21J!5 zP8n_0*zu}{Hw6G|#5@QDa&@EQ?fm0K`%LSPD86zI0_g>$_%ydd1#eTCWlDr6BT+;5m zu~mKjBfAAd)RtAx6Eb>7P2oT|@6oaownA6zh_m5ZZ0CZv;uOx*j2t~A$W9$nlzq3& zm#)~DgtiA9O*Wa=8KWv(K5md~QVnVjaK3Yo!#xunp)bhp&H&HkAEU2QFoN1l>2|VH zA@=O`lN-J`BAS_0C+h0T%33kIVy3K7159#W|8z~oj>NMpRVzOkAMIg1CCi6EgDaZulN9(Zk&L$`!9nl!R%nj#> z3*M?{dCn9?OnG3bP=RmyffmJx=?t4-JzwgfUaoC)Vt(Inv8}5hyRk{=pN<)O>6`cY zeVruU;K7hCETr$HTOf6KKc3c77jeA$MVv?_vaZj)(8$C9GV1l8`X_rhf0|rQMcu5( z-qz^PtWqsB4R9_)oWiSG27 zH*aEw*IhW>sjBEs9nSL_J$z(`*+8eF;z8=_*Ed-bnTQ>TPv?~jjFf?5{%Qs!-#0{j zLC*Z?S9||d2MN@}R)_f)(1bqu;#0`%gB$wzr@I3RoyMNDeyJu$1$&A~%`vi1Jt?h; zgZo^>164r% zRYZ1gDF`%ZZzRg*yvbH^vi$uQd=GMUYtD(eB@K&Z{kxzZ=49aW8E$lDdZXCn`0M6~ zFA7RPAh$M2*RmD5TD-CM|wjSpI@-kafADrWo53({nm7|9-{Zo~jY8-62I2!1*WQn7$+9 z>VX|^@nwJBdy_+L@Mi4**PGvS@b$pN_BIoAtLk!h#IWx$GnO-lYzBQ#>BM{(e{I?$ z%22|L5H)oNu%S!bvE>t1diFupo6AJK1=*86$r6=8?T1WPa-;XcMzP)cSTtLL^%ddV zrmEQF*AIj4^-|j1wf(vu_nB-!>bp2=6z+WcV7a524ho8drZymAmkcu{QxgXrk8vEe z>l4J!O9S;e;gv(iy$siNpwC`>V$E6-+XwO%A8p3YqnBmyeJh`AsL3eHXqm_ zBb$I;S7FD!h5k>|Rb2s>VvCl6Q|XfOaWw-uZ0VsZ2QSO1k3&y1%^0qemuX9pz+UFB RS6%xT2Su>)N|(?-l#n z*511a_KGMXus9WIqA+@rhL1&ZZC5_f>n+riG3Mp2IKV&{ng zw%_*~XzMMHl-Rno?_?kB*vZw_)vdjgi>qr#*LJqfj!rHPjvX92INCdRaPR2o-qG1s z`?2e43DCEZ;?eGdy7$x;2Ur)oP^B`$-N9kPgbD2@bZ9S+3~_LBb8~ZWbarrdwucz@ ziit91V6?qV(VWYK&!@XY5gZv7p$wDDY%$-!AbFIsi=7=7r2A;w6&|50NTz5{+t@x> z9_|nw7~$a5-qGQ6iNwLWG!apeQd%`}u!BS@375!}3P|Vl*>n-1a;01mD*r-}y5KJs z41LnCpRVlB);B!-vqdYEJ;nnGv?Tp(N`?Q#2#LcWi9#L~87%2B9-5-3E0FD5DBayV zQWB_?NBYa<(ym;;59AwV>+MbZ+4k#xfx%%iY-#In9V#Z$_klh?N%ugdq$~1>y`!7G zlZ(HzvwKG;_l~aij;`*Gj)F|Mm=*HqCl`l}o>(pqXE%Q*XGrSa!AY2hAZEopfTzWQ z%D_tHB8)4@M;z=vS{@l5sO%aT5g`o=4nziY7%vlR*-F>H-#X}{3exMs-M!^fc_dU; z(zV044xjTDq@q0G?jutu17*PypYC13qkUMI*xkjkbLXJWfzI}BfgQy59XmQZ0^}mG zcXJ7Lb#@I55{un}DQWxl6DI#8>+bU4DCBF%niBzHc`#(JuU4>&bElvn=Ro^FSC`TD zPEM|!?cF-LitRf)i92?56uUYHIdgpo1qm|yq@V$jVIZLbrGhxv7BRNP*}0?G(Ip6S z4<2pbG0>?ae?jsumoXt!BKxyJ$7MxheK`|_e6(^xV5Gz|1URH}5`oLNe8P$aeCxoG{C}e> z8NfiU%1}uc$3QL}DJlaP$W<9C>Eam3r6WaU z00X%yLnU1t1G#jhs0?5rS7oTAi(?>{jue#v4CJZ|m2`0oz00weZhDy3P26E|0Q5oP*$z`cOm@1LMY19dD?3A8cb;on7 zOcnU6jsRlBDk2gN6b^_|MnowAH9^0D3Z-8V97Cird}K3i}0SKe(EsaFH8cpjL z7L75y!jzZ>gSk8qv^BR5 ziVBk|!(=o|2)CfIz55OA%boW92J;Zv!=IiqH3XCyKu^44NTPZ#^PY>Ji@{sX`ahKSViRhx7=ScGn?5Z++HY!DBSAD z)I3ORYb%yV1$C3Z#2V61uSnS^eqPc~<9S7j{R3pmp3MhIkq2}iFR9q}bN+)AQYG~t z7%lBKNEh95yd)To{=qpHcAO#Eo`sG^J2gx0uzdE6+6;uiED{(ZmNKz*Am5GsV|OWrd&BDGz`3Jz|V{#KHUXnnT15kqawBgT+NmB1*ayq82KiNxc*;6d_8Y;C1X_Kj zmB83F<$d}oLU^6W#W4+(D*XdP%EhW0EP-^AXr+&$w|_rhURs*--sK`&gvui)c}l}V zcx6_NYkY6s8(MBAmW&RJqSD&}kKleL`e5F>d~~az5PBqDKwKLxf3IG;07ydm%VkJw z3#B{)tObQcC>|}PAV)v(wGN_k_Y;3B==RVG(dlUU8p{DK55vGCi^AMELm3DBrj=~9 zD2DuONmF5bVzC7Nkl-7+AM=th?EthGPwEkdeayZm*7Q<^k>34?h|MHbDMrLQ$>& zuT`~b)mr#hwHBAerZO3@=ZK9tG+?6&(N;FWrBWyY0y32g!MZN00wy#rC6D9;W2G_8Jm0Vb*Uuj$M6}T3|y& zBB-q~t&^Fli3_blGp8EHP=j%HHBFqSEv|(%I6vr4R)-cruOfe5;_X*ESkdugOH-_X z*;g(X?m{KD)D`y#=%kb+>8kMM8nn_^fqhD>jcA!R#Dj>J__S=@Vu?>5pC8gSuCBX= zr@eY~Ryt`#<9gRw(wikEuT{NIWUk8d-jQ^9m1^I}(u1|9m#$XjZqHqo-Fdjf&b(@A z(I1YSP47BimH#&XVB+I~y{F_mi{v$bTXy5@Qop`&n&YG6O7l-5XOU3Sf5}?QsoQdY z@jUqG$H|#LRXcIu@~A2PX+~vtr+=KXp~z+5l0K2u9`skM-hbWH>x4&?92M?ZRe4nJeegqPcOx$PwBOTCB9du__D+& zcQ;Fp4Lv@;>}l?$OCobS&-kC0Y-r;%q49u>Sp#mYaq{pxTO=CWs>q)u>0Rb7&S>oF zx;-H+WypaOQ@%0X^OI_eO7k&st4}|FErABG@sw6lWz*fqqWs=I@7LM(%E#P2%~#wj zU6^>X>{;K851w5Hzm9r2uYqsZj-9^ISPjTjZC7c+C(H}3cje&xD#6{VgjOewTsF0I zymI;KrEQ0U2S1G&^~=G{W@X|J$#z?p^cm#SV#%^4J}tIEhqMN`&!9T}+jkw_e#=)! zpZQ&KTTsIzr>?4X?H0?jx=hY^pYU~Y?$YrVPNy_&uD?1qHOC|JL&><{{r;2d<-08m zRWveJ^j_qdyw7TS@#Xjdef}8Ut(EC(>vjEPEb)3>vLS6GONROMcZXs&uy-V5x966e zSP>qrOg}rU>Fq1kc7$m1He}6-$?UpQ8TY%AB}X263|Lhyr#4Hbg_HqR`-~rVaMz`) z`y2f7OMsvE_jg`;e7Lr&V)cdX={>ab{p8nA=1=y{II?YjSe8e@8~-JKDO39HNVunv zUOYK`^}{mP0~#xj5Bpg%BVfq5ytCVczoW%e(M&&CEHb@2Uh!lQYkZteN;U|H=2 zyI4}E>7cX4Cu{hz_uik`_TbP~_X{pZQ&0RfW3WfY;Nok=JDYC|Dw?&S)aLDQ?I3Hh zWDxZ4vaPyNC-fLKMY&tmJ6t_B;Fhw`$Yn$EwllwXJu*A3{s_-mEHMu1qhjxWI1^Jp zt=<{W*WfYf(f3UUy-&Q`c&PgW#j_?o+cnMWJEbxOiKmQpig!MB(X7n;^1cIIPYgS> zwbOy9qbZ%f?Y5?xrVo_!Aie9BWK&6UP}8hE;d=@X6pvRuczCjQ$`l9Jca3{B?T|A@ zmF|(0@a|aY!*3?#9`Gd7Z8OY$`a-+@g2?T^d3$Bx)WPj-q5fBYV9DIL9V0b8<{oH4 zd>qYMPTb)iTcY~z+O5)?Ba1x>kCwDyiQD`a(B%&$&!-H`P>oGziTFU-hN|^b#c#sb)BjpMRlRYj(at{E??i_(B#zWMok0uRt=st zjU{L8w(7^%r_9hyBEC0!;pl#u)-l_E>vHv+DshS5{JgWfG)s4AmK>^^()ZiTs#hCW zvia=MKcdF&in4-Hv+B37vwhyC2Ajq2FDqq9VUK{89_%9&7vD4;GU;RbkOuM=FP}?3 z?%JD}zS={f>EQ8p?y2C%`7ZAw6pfg%(-wKYifw!2;Z@J#%MCSCXnfCjH^DXLxkpu$dieIEFc2kAM8Ctp3FU zkN87nfBZHA>JiX&rtQ6-?|oD4?tul3CuANffUY=J$DJ0qK`RSEO!eEh;r^jX;V+Ih zUgN5A8~X6r)#9G2#An4l9x3DYYCPJsy{YNXlH^r;HoQq-$+k}I8@E_iywg_gxhTrG z)rgRp58M|HD4VsYcvacL^dT$>_fRwhx%Bwx$1|rS2YQZZYhM=7A4Gh@8W8bGeJ0mh zVd62|-TUSD&vtbwaPE~jbkc#YM{=QwW7LJe$CduvC+hA{v$rF=HO=4IbUF{_Ln^!{qUQzM3iMv<GS4tBifk?t&0?_wh@C&ZimYwlmOuKCbk(rX7B?8O8?=Xxxt4)SRbN? zczzlBFbBiWKm!90{Qt=Vda*$mUqJNpUse4BBSR!gSO~z$U7UHMvugd6O7C(r zP?r7SR>1L+@1g>6wg{yc!O3pz92AvMI3X^?anf9f`$x*?v^+|>YLf6EiP*>68`ca) zhe;*;tg_b_FsB+^qF0&`=^P`DeAF1%E$;0?L+^D*^4lR6xx0r}|}F_r9_Foo&taG16M zKu=p^?c5^HrqscyC@;9s6ldyWVxHdRXw1jQS=*ZWxU@Z9(kO|5n6)Yd_lktcJ3)Aj z3gLq!VnJxd)P72s1=NOP?+6O_!8_vy1}a0#&6?E;P)KNqr$S#4PjYK)>Yp~S4wO;b zQ#v7VqQX-w_LM3;mCDGlpeQBf1FS(6osT!n$!e>HTxabql`ABkFu@lXqFdxK?;#6@ zyEJ7X+K3R3)Ih%R3mgx=e_9uqv?o=)oyIlQ#uRDYdVk>}Wol5$`b7nemP^Iu*7?j}6)zkXD?)T@ zc{W%pEEPs)P?$7KIq|a`g_NtJj|%sk@|{&x?;FtH=X>ubjJ3Ra-C` z!Pa~j&I@b(!JAa`kp)Ym#F!hske4sMhSvWFNhFB4NVsg2mX94}>LU{azhNd?1JKGh zOeX0e!{MON=8fHN#r50w{FFGBSL3@Vxe^DHZnWw0wef@7m*M8f9^nzniQX`w&gX^c z_&}H>51S;1yNspUf>6>`)275JakxuX7-a3IoCxf~$#+4!tN3>x5++uL_Lc}%2C;Q! zFv=?k08{7+Z$Cete^COS;@p+hm zUytv7dh)m_;BaL$Uw%yv^`mzWBR2*N^5Mg*sN^0fhn1I!g4R~$YgH};`>5Iw&`Xkj zVY0CBK&iG6BtsqQ4<7z3-AvG!au|}c4x~lCFUjrmCO=cL}Q-AUoH5R`%nXb5Ljct zy#D%UO-W-5&5+vSawV4GC-;^Eh>xjy9m=oIAsKLIgl#$b_Sr>xjLCoaMS31bmtUmk z{jh9llq?MJM)0$S2Vgmo!Y`88!d8kffTaLA(|9rkt_B(h1J_f0Vi?*($oF(jGFTcU zMI5V(;bF4TKy?~U@v*Y8*hY*`aj7C=bU8d&iuqF;jE|!T4aYKi!;h|n1_Os;7<@Xy zPfsgzyx<%!g9cx$fQ2-0q9oEkEL?(n7d#*Qd}wHskj}K+(b17Sogw09KOAqs<0Uk0 z1;(%}!CWmiBX3xkVe2@qKn-feXHjVmunI>FVm~2J85~L}sqX-OLXXo^erpYb=18W0JVnpXZ|iKgQ#`qaQ- zD-Z7hmpDu15t1Q5mU5!(GvSaA_OxZVL=ier4i7xA`M?v!gTBA2!1_H%{y-@Whak!l zNR|LuPib?mSs0yuy7kw(BebrdY3TF689q2t8T`3AaW(n$Uso5t&J|t04PSD#ZR1(J zqKh)ePmW{I^lOFOw>#7TJ5EnpUh`DLy7`D@O6?O+OOQnpm>w0w<~mo>0sielLg9A1 z(EvHY*Ohbz$c=OYNDNSC@Dqcq?nqO)!sKcYonXa`O(W}T_KraAuOdBa|?{`|%) z%1BBWMACuqK*t+%=xZ?=ZwdEPO3L#i-+W{!3wTh*og%siAFR0**q!olxc6S?E&3k3 z&Bak1PnP5Ee>68sS~+jQBR5u=c*=B-;FP%qb~GITFx48Z*X!~gAV`l)CC z>ZuCV7XA*=ALR|p^#Bv&_UI4)(CfzS@rm1VJuP5u&_K|g=?wB0S7O~Oc6_V{qcSOCw#52roA3Znm?`{P>qxe&D1=<4$) zfv^|taeLzaGKIQo2uJ*K(*_V9eKoD_67)qEebHsgVSFgYW@sGD0eyuzb8V4_KwB6` z2*dvQ)P6)?o3WCK{QDN5 zau`PQf6Hk8JKJH990ti@kQ{&Ki2H9T3+8wj*w-TbnwGM_sK)Dhb?3u!cmqN4J{lF%Ymt-@W$-X47$R_qZ`-&uyjqE#^6n;b2vl;9g zl1$dI>1;AdA#2$*Hie{;HEb%IO47(`Hib0}j)?aCl4**9zkc}sp{U$bv@?mM!A zO=91X_hdQy3XY^_l4a~mX#WSYlucwm=-e!_gnhwgk&k3Co4|e~*<=y>oXys`Ib6KrQ{d(F7!`DS3_p9cUTRn=$4TgY&`U1MVBSh**Mt7^;a$- zKeM;#lGC5NfA{=JW$X18M(uc<@(v!z4(x1oqe&XGV{mJ8ezw<877ra}Me|Wy) z`HXif@*~fu75SIvYo5<5@;^T=_;JFIn~LL!A7}iy_{ zKUpxIW}qA8OSQR!R`(G=l}Kqi|ndQ&hywbunxpbv^ht zgnVj)FP}mmgZJU{u%NW4Nw{x)NQpG60lrA1I`FMUe>DNC*v9|CEZXlx6u^Sq!~Zha zOI${w6wpowi71AR(cu2#fKNhbY(89{<^VB+G`J@@02As1_5)@V0AZySyh(rtq_8mR zK4KID=_}#6pBM+Q5Vw3(S`=u@3PpXfYH?6{vbOy|1=?c1;tU%T2Pzs!5R-!cv{gcK zq!JRNjf50T#eAUP^3+TtOaN$v+vGMSX&PYzib)xIVSWJ+90LVluo2`DaFQlR0|5zq zl9n4wZc+C%B@P7LqLEI6CldhZO&WTZ7*p~i&IH7q!9O%L{#9n}TS5X>f(bza-ja7* zH?0N>g7()t@WJAMNNd5003tz~-h%zWLF)k024`R}MvU12<^%_&fdN8;H$pZTlmZqC zQgI_#7(kVnfaJeyMFJOb7c}?a zoQVm5Ti2+^Wo_aQTKu9G&qlgn4(GKw=JFnAv{~kJ9?2vp0PP|cMyn_wCI&`D%tOAE zB3&G6JF#HVaO{jM25qBlhArnY0SQ3(99<-ik@5cyjbs!64)*a2s1cL}l0!G*dC6q*4Qg6M_1>YzL_fkr`{E|OxXyuLCTfdItb z;F_(k6elFO!F~Zr_gqk8keD$9g&6!pVzAU>$<8mhyO3}gK?uYIXnj5b2;2dLaX;_I zU}hLW2*dK-Wd(hJ7kLXK?c28qESm2bCb{C>Vg?kl{6~!((kcz)|vWeQ|{gft+dApa23! zjk$!?cnn1qj)xfV0v!Pioy>Uw6o6jH<*=0o z$%exl1rryGHVi{i*Kn~wQcz{|3dlrtR2)r{jKML*^#3K~&aeSmMF@fzQ{uoYgHeRz z2}6L$zzH+}br2iy620Qc0j(#?V&9+;;CxC6jK&xUq~lZP2MKW~;+W<9G{g)_pv4G1 zv0X6!AbOG@Dwa=2WsKgJAEhij{PLO7l&Gd5{cC|Qni5z|-VX%>phyOx7o;ktRC)tx zr&aRzZ*2OaDO^Qs5LX9-+ZK*y@uqKGFuHBP?5s=8*IJ)5HUGk|iq>dFgSGl!#N`cH zG{w>6uL|F~2GjRbd)Q$58cbh-;Q6;SeJ?@p|5eXg8MC`{)eU)q-M$M(Y|u zvAi0@>Xi4_+o@}zu*#~le zvz%eL3dn&P|J}c|k(~7gPu}G%H|im<+USG3-eNn&*>}9P29Nv#L+v=Vne;XqJjcLv z!6z1)hz$Tc1Z*BKt14J%aJAm&Ei^8mf`!I;8Z5Mb<&qg%E@)SwTNUgcoV@(U{rJg2 zbS<^hmk3*HClWc=S}?K5O(Ry(*>z~)abNw!XGNci_@`<37`(MuF@~_7LfEim21{rB z)IYxzz%LC{Tr%L75n5T51EuS2xp@?$}ZO34ehy*;LUL3a#x1=ah4P=$Ww;_( z)I^wDf;&R%!ePbauomN%<37QlZ6xLyU92mCMNw=k;@l$L@3cG)E5)T!sM#~^f?Y+d z6c%D}DNjQV!2dJt^4$Si`sc7RSaL<0J<~4e0Y=My{#l$Qd$IJG=h|gHiUoWLD<%36 z9)`OYX?f4J3xI!t(Yhq);|lN?XkP+sw6DC2?c`DjAe!R~nh$Mx00$S7MDW`Ui>oie zg<8fGLc3p4IG=pp)yLt}#egM*`M`a<@Wf7HFz=l(X$=HKfB@OQ?CwHy5hDlzm@5Mx z$O?0LrX@@Tga8k6%d0S}@fnyUaKSYAb4#^*u$V6)Fq@{2#v^6G1q4PJw*>roSOZJ= z7>8Rv7Q*|nJT9OVn3N*i;xiyH~Er!kjcYjzv78 zq9hjt4MjK^1PDy1QGt{Ldmku*vML+o79kI{@=On-+(UodE|5jeP#Cumd?4pA+lSiy z1p*|KoaaJt2f}-D0n2zuwqIha^q>gtr+7ndLHhf2k3|we7Q9dQUA!W36vn+6 z|B-97{M3xW{g+YT@7~*CD9>;n>wl96zA(l8FB>nFoIL*jpuB%(_QjC)@0sN?(7Ez- zHb{=YOST!fvhrMMpw+)WtqhXGAUXd1xzr#@{{8w0Bu8_)gSr-MP{9S7>e?+Q+)@p{ zV8bojeEP3n+~FZy?BQSzLQMGM7GCsm__&-uF6(e#;lha!#^)L#E`<5C`kn1uIl?;W z%NN#)hxxkl^(((v^=bP#A3d$O9r{Sc8g#=?9n$<5+psL@+@|Sczwho~SHq?XT#Ij0 z!_J}m_hYATI+s+I3NxdpSd;9ti^VRMsl>$6MZEZI_B-%B#~P>Z2=8DFuZ%SA5WXWd z3;Zsz#--<@+A|N}zUTH)=Sy?J?<#9l`iHnyEHSDj{-d-2e6F*i2jl8qC8E0H?iT@m zixuT=a6eB(ZX0q-0l&?PQYY0oO++;&rIrC6&x#%gn;j=cX2FjEy~~OcMi?J~*G!He z33p*uRg@wzfsODcl9c-}FDlBPVGY~MiO70J{zI4>Wp+2&3(E{l6PVt7!ZNS>?S}J2 zjPL6waHL73SynX$jva}rEYm!LIZh_Yb0?fqVmy7H&8PS|1n66|>#2aCX zlnE+%1BbPkT%QdvNy_--B*Tm)^TB;RoXTR{Kcv9HF6OQCI+z({oZqIxoF$XedM&QM zw@yieLtsos+chvZ%CyZ$hiOYD%V{<4)pp9tVBbQ`I|TJIz<1}tp*g0&77?atK|Ww)`h48{ z{c}DGdr{t4Bf?m}DFBQ}=D~3~A}N3acT9pYB8>6#Lcqv~xwuJuL?K(mGLMZAVT>LZ z0Y-x7kf-n>t|BUCRc8_0DEi{U1p;4fP z^ct!b9j-INi1sbQ@^Cq`p-1^-X$$T5*?FEAGOz#PT|mYE)y; zsK#Q@sGx42k1zstYczs9zl+NFkyaT$`i!ndUB2E8b@_U#%R$%QmDK@VUq^Nqbv;@G z$F$bKu@bZfE`iVaDEoWF$Uf>EwHVN{*dFd=1eS%7Q}}jjS)dJaW>IiQYJ+qPUUY`q zAk=s{vvJy(Azo;_Siv3KXuNn088dC;8P0g2&z==+Nc~ww-1hS&yNUDXEI@>LNNBI| zmYLAi+i-l$PhE_ow+G8ZXfu}g(PLcRTup@K@Fj4y|XJ)f(cINwp_>()9{WQX(F_Q*SP7;$U-DGQS zb1(zOW6i-uFvxl_apnCAXG*U+*LMU4*{xI_FN=1J=0g&YZ4BdEj@2 z7#a0i^EQ?>db_5VQ6czTBce77(yp?iv;}R80f&8lR--PTXGK>=S!n==lNa@7zCX2{kR)ssVIA_=qZ{WjnC{t zF?psj9{*mUwePP*p?1GEULe3!yS)a5+U;t1jR0eLbu|jLtCo0~0AqA; z6$-V3MtG$FS+Npi8d*Wl_DuK#_I|gyAnj0lID0gk8GL;8zIQ10(=x`Rf-5x+6u2PAZzD> zBqi$#;pzgWei0%}QGL9~fJ~nQJF>|1B6yl$tllHSWLn{s1|)Dc$XgOf;mZ`hQVfqE zq}{I|c}Y9G-heEk@Zu7<+JF(IBEqB^;Y9}o-b?)eUMEiB-zfYW?wVqZG7w=hjPTk6 z^6fA197MjQ@N^2#qi`&R?`q%*1g4G#5vHs@UWh=xp9%X^$PX0$jlwG_e4oPi;b8KTzlgfF@ID57IjIGZ>pR2wked+od>1+8DEeUI`Z;if%4QObCa*e04(gcq5A%0>Xhkv8hAs;0|3tu@CL^-U6D_CZh8yc1U$#_*-FZDUV8px zjP#rdJiD0ZSsgFimmt4i;dxxg`$5S2j8!Hb6(3+!=*G)j96S6-DsEDQV{APgW1Dci z=|(C)jg`Y?zKv!T5SW>Y8ybS={4R5(0HH?o1CNC@LZE;R98x~ zIbA6QT?v}B@nNb-4>x{{T6VBj%MO0{i4LYJx&&2p$r@16pun4NDg^~z%4}+W2etdx zTJ8Szr@9|)gTO0j8w66@0Bi^Q#pz%>q%XEd+X1bM-dgLTw=r557s03NoVy?a@6Pd{ z76@7@Lzmnx1xuy$_L8C0QbC)>Q@-{lwP|jym3vZ~h8jbjBd0Fkc^ZwOT$as6W9anG zfwaOdvV_KiCQJf8EAuus783Gtl5aod*ok;_r|oD3=XC0}cMudB7ko{uXJG z6_+*5@H5chKb!}sv@pz*^Rwgn8Fb<7IOqFkGv$VPa>G2iVV>MDPi~ke7tZDz=E(`H z?HK0C4fEu<`fHdc&-)+GlhgNz!e%V)v=Q1bBtL5?*W{O4`EHr{IXAkznmufJ z;hf`d*1r*lEG@JwiEQZM`Rm#%`yQJPu&(i2U|*ScE2G7Uf!02dUj^!uc5=^_LrQU()IO%U5%YH{-`DK zx;eMWh|tspssiU(ci(!CnBuXid+71nlWT7~{c@6|>f&Ln<;Uf%Pe!kORuH8rD>(7u ztZV5SMf%yBZ8z4){H1N%O^XHuWz_lM=wmOxs>f@O@3FS++jr(GY!A&hwzNOAxtrz0 z@Rq$ppLj?HbS|);a51{m;s-LX87usn9hnh)JIAMAi)~d*%y{Nvxt)?b9uIrdM zBh@fxtAu@`Kc*IXggyxo{L^_37W?n}dKKK0=f;&j$Q|E#`qu#&Q=?k8-Jj{p zj(d40IBrPIuZLW15!h(b^MX~|<;h)QIDV>N#)p%|6WliJIJD2#x#xih%So3e zjA{4np(Wev4H>s(%i${*Cfr#wYP;#uk)&1ljYQD*4-T7fpJKygXdhMq--iha%UknaTi2iW*W?;>0KZ&;-y0&w3 zWX7x*)bxmZfi5K>FJ#lb`J`@wzg;5p}}o-DXcG!KUb@^S9AA~)6ElB zL_Vs%>E!fhnx2Ec?zp)_y?(0{CSKktA%j|*+2u~oPVm0L_%3b@Auqp*J1?{OAtQUp zYtI`t7vJ^NTwJN>y0y>j3sZcZ`!sZ@H>0ZS?NtM$$Gp=HRcrQPy?fJkinBHE46;=| zE}J51xHSIErB;$*QuBnfv8!f&)o0}1=gVL0*i$kzE#Ta^`E51R>mIrlc<`+6qvu|; z#*Qv{@4D^y@x{f(O{cX=8WYvMn7Sfa+9P- z>Z0)7HP?7FKEK>$#r}&y&6V@&P9C}_Wct|q=8co?+5B21$lvn)E}O|euAl$JtE#`% zdrz|((RHpjzVJio;fd{^tx!2F8`tQ>v)Q5NPdjxsTf9SUJA1zgCcY;!+KVHWROE8pu>_7rSqsvdwLXU6sD} zMTy@<+YV6;aEYnwy$1U3?J$pV`=+0r*>Fg4pDy<<%%9L?cJ1OZF5mUtJ@4V%)0ypy z9eXX%{3QMDmg|e_tL9uvz4Bn>ps_zDM&<-QPYpUIKJ#(c{0omRy8K);;J|>1wZ3`n z{YTvSprRp%J3A&xT7782Ru~VCEz9ZhCr z-kRrXJ5ID|T5DTnNcBxuvlCA(y?3t3&7aMy_OjG*7VUo`%qzogIGtn6_e+^`u&==?#93KUa%m_t$s2HS85) zLrZAoD8B0L6}q)?H>;2#Hk-bgW*%!a!*u(#9~Yjr?;suOl(Y55i3Q)c-rdABw!w7W999FY57adDQ5M z9h;k6*%&u3vRQDeC)=W{gsHN~rBl!3sZU~j-`|+Ae%-388%wg=DM#O!7H##%bwzc* z#B;SwyqfnhYM-6Zc3%9V2J^Pxa@*Qy{`p0X9YA*Vnf~3flfRfJ)axEPqRq^n%S=!2 zQoP%?a%IHq^IQ8^Wf*-msOqRWzj-y!BYP*N`cF5nvdgpWi<9@iPFCOVUhh?OuZFW0 zc^mn4tkvMV2KVpYUU$W2l5E%F$ougRS5<9&_4%ObHT;iXC>gk2HDl@lt$F zL)+sCcZv(Uj@;Tk-D%gVu;NbDdxcyb*<<&~y6!(7STrmxE4p~ZD8G$I#>vjCNy|U^ z`m*J5$%2K~=iKsr9e?w#`;Mna<+86`CM-DiYLR3A%wzMTkG=SDPX7Dd=4HKI?7U{3 zwOw+zs?~RH-Ou@MTHLm1yZyzqMm<9~3Hc-0JRyt82Qh<-n&+59j-6Y}oo zmKGy-WvhzUZ&nnp{&7=O??#(jcwN1=KdsTGi;t4K)MS~pY45X{bQS7HJA5YYm(C{dUU7b@B21# zesF#L!8Qdy)|llxIVt4u%`W>dHQPC3*w#K(C+_cdxmJfCBCid*z<#~6gYCgilOw_S zB0fF(ci-nV>SqA8CLsFqwrCF??%7W<7GP`GAg8lm>1?ZUg|lt?y|p;Q_7=ee{?<6%Unnc}zdQiax?0k8v@%IabX7&t_YBD&c-)eowdHY@2TVr~JIO zfzBLN_0-ivU!pcYuWg_+&!0T+3wc-w8~B;0(0`=dn5K$V;qQp5p?blFeW$PAOGwSk z&o5-z!uE)WO);EmD1H-rbi*&1;Cn`8Ja_lCWDV>U z)FfZqJvSTtE~t#Bt-q8;Pc@`nT0box{4T4ErfrGMgHsK8v0J7UfzMTyXxWt<*qNAf zWqAqUH&mjT`;%bjV$%MZWq{vOiRNC&Kg}BDUziK%ZIx(gY{_xhy&g-J-d4q{M2q4z zN8oI0{Gxc(U6p9wtx|k_p{VrMyt}IVD$$J7MQ|G@D=IoY+4zTuF0vEZrdnTmV=9~l#1^>WKtKsP$jCEt@-%oLneP~qUxoJIZ?J1kC~R8c&SQK zG1Fr4Er`tRX-TTrDrV+Wd>10~bmnW-8x=Dv3EzmwB+YuGN>(wmQ#Rl^hLqXKsuUG7 zF9Y9_$Yjh*QKhPwIqCSWL?(SsswxfArQjPAnUq;+s&uH?YkY4a^Lj?QDg(-UjBih5 z9#6{vjNHIiD3Ti)s<$d~5?`Z8PQF#WQ!!gKh%lNh?^N%hHTn2vMJ9jIdsQanmx}LI zWKw5j0!D7*%N5D(Ow|V!*^4h&Bzr%ovQ*5%LPVItg;}bPDn^}%?_6XO)gJ*Phw+7r z1DstbomU7LIgc-LBO>$CWX@}oUT!o0dK(W_`8r|RvBPq zBfdJ4Y^3lp3LmF%EQRAK{D#6QWhz$1sEZIWDpsoiBlGYDlcISPhI0@Auch!F3h$xt zX$qgBFzo$@IM*qBpThSkoIv3O3a3ywg~A^woJHXr3g=R|fWie7E~Ib~!t}M40+$HF zh%k*XFJT$NvW0aL)>YUBVcUdl7ScjMBO&#G_By%(ETp%v9|Zj)>^bObU7rFh?CU*x z9uRT|@RN>j02cBS$7k!2w|EZB0}cc})$wL|o@J)#xf%HU8qeoC{$EjyV?;MD%8wU* zBo)9&(v7jpINo%lZ$TlB%iDBZ#^V?jj#%MXhEcv)KgxCEKNe+yP%?nbIK#^flqOkJ znq+}A0XY*xNaQBCD zva!6>EH6<(+HU2fZQ0g$<>atXK9`r=<)u1G{8TFOQ$gaRHprmbAOo~Pc})RYWR6yg z%t@}GVNm-#quS>gXdl!}w>i!9bCOD+wNAc7jkc|TYP5pwiKy+Crc-T~zVrpvgmF|8 z#(^f(Ysmu8lBhuwsRm614O&sZK7!CEoc3Mt2sLwzUNcwJ+f=V>s9x8^f?fx$zgVmF z7sppL2`U&2XiprV_QU~dPk_C#;#w})8@bn3puO>_MREab6tG+1Bt+V!4b*Bu>t@fj z6l&e1T-!sf8?=Kq9*a$;c2IKcv5nLYq6XB){bz36dw~X25z7{#0rleEjWhcuWr4QW@a4)FNdU3wRN#MHeNYx78x4v+;4b6vmlIZ>!_gBDsU;2;6q&Adgqy zRf`lIj1IvaP$Huaio5FjYSCmb(}QrIkjT_)@_qFKH8Z%{emM5PR10{Zexzn1TkXZ` ze!hx)q<*3nsrs1hfjfRgW_?so)KAsSxMneUeNVG-Pu0)VOn}8MxW0$62zaJWP&1RA zcHq@KPLmVVFVu{@-gdl>r=I+UI#JCGv)G20h*=CvRKHX+J(#U{+b+}Nr8-H?Om*Ij z*X}q?O;W#BGm~0w!VAkW@!Wr>Gf4ZG4F> zQ(KXuPE|8eb@1)AOr5AybsD6rzZNgssUMxDPKTN`!k5@GjV7n7GoZXytMRg(R#P(o zBQE$hTjG+Teyb+kSHev@r2AX-J2ms82oXl~<2&_xXpO~hcmII@j4z`)knZc-z9Jx z59#|+oedN>LxeGl%m$2nwHR;J{VH3Xqb7qF;XS&8bJV$N=BMh2Fx7v`1q`+z!i_z| zGgqAl=}i$~Oe6CEBOMmN?LDMJo;n|DEkcA5$?^ds4)gIIU59*iftrzu5Me~p0>Fs# zJhnhT%;~m zlQFa5Mj$e#7~#$ob}d$yK>Mu`VXUW?07gds3U}m^kreJo;f^KhQs^5iL>Q~7rGSy3 zS#aSW38HXU3cFLdK85R+sx{E>3?dAp&;UmKf5E$P{V3d#!W}7Ghr)F<>N4OB1`&pd zE(45=oQZecj-+sJ3iqTi+!YJ{4is)k;reB2R?VnP5iv4RsR1L386=*F6ci4oa4?1a zDC|dJFA958xD$mtQ5f#8g|uxcY)4@`3fHG_eF|5na5V~BQ`m~a<`g!kuo;C-5uOg$ zVz2_22*QXkjW91^8N#xKbrRN9*al(Sgl!hmLP6`N!1@WP2ejAG6<{H~h5aDtA7Rfy zU+el5U}0bT>3KlN9l%dIz5!UsPaK~GB5&~=XbBt$e5&Kk@;u8-)pIlOxhv1-I{ptU z#xbHB7v;wbKa$L0BVxu2D9u39jkBPV&SG2^ z%D@0B1N}dgla1x2W_gJU(smdpZJA;3%E@7&d@e7!%S&~X`1Pp7uLlwzwLxvF4Qhin zD6c6%i$rO)NK|qK4TIXJ1=T(+K>MI(a^f`8lq9u4YjuB#8tn&js?p4cCZe{J)}h+2 zj`Ri9gpO1bI)WzDYe{p^lBhv#sRp$L4O&sZK7!D%IPE*`5o+cDy=Jbcx2awiQN1p5 z2E7hiU#8XiviOQ7K?Q>W?TG=@o)|#w39vW9T&=*~uyPGUd*f4!entries[i].offset = 0; c->entries[i].lru_counter = 0; } +<<<<<<< HEAD qcow2_cache_table_release(c, 0, c->size); +======= + qcow2_cache_table_release(bs, c, 0, c->size); +>>>>>>> 919b29ba7d... Pebble Qemu c->lru_counter = 0; diff --git a/block/qcow2.c b/block/qcow2.c index b524b0c53f847..18ed2c14ac6cd 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1253,7 +1253,11 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, Error *local_err = NULL; uint64_t ext_end; uint64_t l1_vm_state_index; +<<<<<<< HEAD bool update_header = false; +======= + uint64_t l2_cache_size, refcount_cache_size; +>>>>>>> 919b29ba7d... Pebble Qemu ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); if (ret < 0) { @@ -1516,6 +1520,11 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, if (ret < 0) { goto fail; } + if (s->l2_table_cache == NULL || s->refcount_block_cache == NULL) { + error_setg(errp, "Could not allocate metadata caches"); + ret = -ENOMEM; + goto fail; + } s->flags = flags; diff --git a/block/quorum.c b/block/quorum.c index 6d7a56bd93d8e..01f45b8740c66 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -929,6 +929,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, } s->threshold = qemu_opt_get_number(opts, QUORUM_OPT_VOTE_THRESHOLD, 0); +<<<<<<< HEAD /* and validate it against s->num_children */ ret = quorum_valid_threshold(s->threshold, s->num_children, &local_err); if (ret < 0) { @@ -942,6 +943,9 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, ret = qapi_enum_parse(&QuorumReadPattern_lookup, pattern_str, -EINVAL, NULL); } +======= + ret = parse_read_pattern(qemu_opt_get(opts, QUORUM_OPT_READ_PATTERN)); +>>>>>>> 919b29ba7d... Pebble Qemu if (ret < 0) { error_setg(&local_err, "Please set read-pattern as fifo or quorum"); goto exit; diff --git a/block/raw-posix.c b/block/raw-posix.c new file mode 100644 index 0000000000000..5f19a40697777 --- /dev/null +++ b/block/raw-posix.c @@ -0,0 +1,2634 @@ +/* + * Block driver for RAW files (posix) + * + * Copyright (c) 2006 Fabrice Bellard + * + * 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-common.h" +#include "qemu/error-report.h" +#include "qemu/timer.h" +#include "qemu/log.h" +#include "block/block_int.h" +#include "qemu/module.h" +#include "trace.h" +#include "block/thread-pool.h" +#include "qemu/iov.h" +#include "raw-aio.h" +#include "qapi/util.h" +#include "qapi/qmp/qstring.h" + +#if defined(__APPLE__) && (__MACH__) +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#endif + +#ifdef __sun__ +#define _POSIX_PTHREAD_SEMANTICS 1 +#include +#endif +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __s390__ +#include +#endif +#ifndef FS_NOCOW_FL +#define FS_NOCOW_FL 0x00800000 /* Do not cow file */ +#endif +#endif +#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_FALLOCATE_ZERO_RANGE) +#include +#endif +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +#include +#include +#endif + +#ifdef __OpenBSD__ +#include +#include +#include +#endif + +#ifdef __NetBSD__ +#include +#include +#include +#include +#endif + +#ifdef __DragonFly__ +#include +#include +#endif + +#ifdef CONFIG_XFS +#include +#endif + +//#define DEBUG_BLOCK + +#ifdef DEBUG_BLOCK +# define DEBUG_BLOCK_PRINT 1 +#else +# define DEBUG_BLOCK_PRINT 0 +#endif +#define DPRINTF(fmt, ...) \ +do { \ + if (DEBUG_BLOCK_PRINT) { \ + printf(fmt, ## __VA_ARGS__); \ + } \ +} while (0) + +/* OS X does not have O_DSYNC */ +#ifndef O_DSYNC +#ifdef O_SYNC +#define O_DSYNC O_SYNC +#elif defined(O_FSYNC) +#define O_DSYNC O_FSYNC +#endif +#endif + +/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */ +#ifndef O_DIRECT +#define O_DIRECT O_DSYNC +#endif + +#define FTYPE_FILE 0 +#define FTYPE_CD 1 + +#define MAX_BLOCKSIZE 4096 + +typedef struct BDRVRawState { + int fd; + int type; + int open_flags; + size_t buf_align; + +#ifdef CONFIG_LINUX_AIO + int use_aio; + void *aio_ctx; +#endif +#ifdef CONFIG_XFS + bool is_xfs:1; +#endif + bool has_discard:1; + bool has_write_zeroes:1; + bool discard_zeroes:1; + bool has_fallocate; + bool needs_alignment; +} BDRVRawState; + +typedef struct BDRVRawReopenState { + int fd; + int open_flags; +#ifdef CONFIG_LINUX_AIO + int use_aio; +#endif +} BDRVRawReopenState; + +static int fd_open(BlockDriverState *bs); +static int64_t raw_getlength(BlockDriverState *bs); + +typedef struct RawPosixAIOData { + BlockDriverState *bs; + int aio_fildes; + union { + struct iovec *aio_iov; + void *aio_ioctl_buf; + }; + int aio_niov; + uint64_t aio_nbytes; +#define aio_ioctl_cmd aio_nbytes /* for QEMU_AIO_IOCTL */ + off_t aio_offset; + int aio_type; +} RawPosixAIOData; + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static int cdrom_reopen(BlockDriverState *bs); +#endif + +#if defined(__NetBSD__) +static int raw_normalize_devicepath(const char **filename) +{ + static char namebuf[PATH_MAX]; + const char *dp, *fname; + struct stat sb; + + fname = *filename; + dp = strrchr(fname, '/'); + if (lstat(fname, &sb) < 0) { + fprintf(stderr, "%s: stat failed: %s\n", + fname, strerror(errno)); + return -errno; + } + + if (!S_ISBLK(sb.st_mode)) { + return 0; + } + + if (dp == NULL) { + snprintf(namebuf, PATH_MAX, "r%s", fname); + } else { + snprintf(namebuf, PATH_MAX, "%.*s/r%s", + (int)(dp - fname), fname, dp + 1); + } + fprintf(stderr, "%s is a block device", fname); + *filename = namebuf; + fprintf(stderr, ", using %s\n", *filename); + + return 0; +} +#else +static int raw_normalize_devicepath(const char **filename) +{ + return 0; +} +#endif + +/* + * Get logical block size via ioctl. On success store it in @sector_size_p. + */ +static int probe_logical_blocksize(int fd, unsigned int *sector_size_p) +{ + unsigned int sector_size; + bool success = false; + + errno = ENOTSUP; + + /* Try a few ioctls to get the right size */ +#ifdef BLKSSZGET + if (ioctl(fd, BLKSSZGET, §or_size) >= 0) { + *sector_size_p = sector_size; + success = true; + } +#endif +#ifdef DKIOCGETBLOCKSIZE + if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { + *sector_size_p = sector_size; + success = true; + } +#endif +#ifdef DIOCGSECTORSIZE + if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) { + *sector_size_p = sector_size; + success = true; + } +#endif + + return success ? 0 : -errno; +} + +/** + * Get physical block size of @fd. + * On success, store it in @blk_size and return 0. + * On failure, return -errno. + */ +static int probe_physical_blocksize(int fd, unsigned int *blk_size) +{ +#ifdef BLKPBSZGET + if (ioctl(fd, BLKPBSZGET, blk_size) < 0) { + return -errno; + } + return 0; +#else + return -ENOTSUP; +#endif +} + +/* Check if read is allowed with given memory buffer and length. + * + * This function is used to check O_DIRECT memory buffer and request alignment. + */ +static bool raw_is_io_aligned(int fd, void *buf, size_t len) +{ + ssize_t ret = pread(fd, buf, len, 0); + + if (ret >= 0) { + return true; + } + +#ifdef __linux__ + /* The Linux kernel returns EINVAL for misaligned O_DIRECT reads. Ignore + * other errors (e.g. real I/O error), which could happen on a failed + * drive, since we only care about probing alignment. + */ + if (errno != EINVAL) { + return true; + } +#endif + + return false; +} + +static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) +{ + BDRVRawState *s = bs->opaque; + char *buf; + size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize()); + + /* For SCSI generic devices the alignment is not really used. + With buffered I/O, we don't have any restrictions. */ + if (bdrv_is_sg(bs) || !s->needs_alignment) { + bs->request_alignment = 1; + s->buf_align = 1; + return; + } + + bs->request_alignment = 0; + s->buf_align = 0; + /* Let's try to use the logical blocksize for the alignment. */ + if (probe_logical_blocksize(fd, &bs->request_alignment) < 0) { + bs->request_alignment = 0; + } +#ifdef CONFIG_XFS + if (s->is_xfs) { + struct dioattr da; + if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) { + bs->request_alignment = da.d_miniosz; + /* The kernel returns wrong information for d_mem */ + /* s->buf_align = da.d_mem; */ + } + } +#endif + + /* If we could not get the sizes so far, we can only guess them */ + if (!s->buf_align) { + size_t align; + buf = qemu_memalign(max_align, 2 * max_align); + for (align = 512; align <= max_align; align <<= 1) { + if (raw_is_io_aligned(fd, buf + align, max_align)) { + s->buf_align = align; + break; + } + } + qemu_vfree(buf); + } + + if (!bs->request_alignment) { + size_t align; + buf = qemu_memalign(s->buf_align, max_align); + for (align = 512; align <= max_align; align <<= 1) { + if (raw_is_io_aligned(fd, buf, align)) { + bs->request_alignment = align; + break; + } + } + qemu_vfree(buf); + } + + if (!s->buf_align || !bs->request_alignment) { + error_setg(errp, "Could not find working O_DIRECT alignment. " + "Try cache.direct=off."); + } +} + +static void raw_parse_flags(int bdrv_flags, int *open_flags) +{ + assert(open_flags != NULL); + + *open_flags |= O_BINARY; + *open_flags &= ~O_ACCMODE; + if (bdrv_flags & BDRV_O_RDWR) { + *open_flags |= O_RDWR; + } else { + *open_flags |= O_RDONLY; + } + + /* Use O_DSYNC for write-through caching, no flags for write-back caching, + * and O_DIRECT for no caching. */ + if ((bdrv_flags & BDRV_O_NOCACHE)) { + *open_flags |= O_DIRECT; + } +} + +static void raw_detach_aio_context(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + + if (s->use_aio) { + laio_detach_aio_context(s->aio_ctx, bdrv_get_aio_context(bs)); + } +#endif +} + +static void raw_attach_aio_context(BlockDriverState *bs, + AioContext *new_context) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + + if (s->use_aio) { + laio_attach_aio_context(s->aio_ctx, new_context); + } +#endif +} + +#ifdef CONFIG_LINUX_AIO +static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags) +{ + int ret = -1; + assert(aio_ctx != NULL); + assert(use_aio != NULL); + /* + * Currently Linux do AIO only for files opened with O_DIRECT + * specified so check NOCACHE flag too + */ + if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) == + (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) { + + /* if non-NULL, laio_init() has already been run */ + if (*aio_ctx == NULL) { + *aio_ctx = laio_init(); + if (!*aio_ctx) { + goto error; + } + } + *use_aio = 1; + } else { + *use_aio = 0; + } + + ret = 0; + +error: + return ret; +} +#endif + +static void raw_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* The filename does not have to be prefixed by the protocol name, since + * "file" is the default protocol; therefore, the return value of this + * function call can be ignored. */ + strstart(filename, "file:", &filename); + + qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); +} + +static QemuOptsList raw_runtime_opts = { + .name = "raw", + .head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), + .desc = { + { + .name = "filename", + .type = QEMU_OPT_STRING, + .help = "File name of the image", + }, + { /* end of list */ } + }, +}; + +static int raw_open_common(BlockDriverState *bs, QDict *options, + int bdrv_flags, int open_flags, Error **errp) +{ + BDRVRawState *s = bs->opaque; + QemuOpts *opts; + Error *local_err = NULL; + const char *filename = NULL; + int fd, ret; + struct stat st; + + opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort); + qemu_opts_absorb_qdict(opts, options, &local_err); + if (local_err) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto fail; + } + + filename = qemu_opt_get(opts, "filename"); + + ret = raw_normalize_devicepath(&filename); + if (ret != 0) { + error_setg_errno(errp, -ret, "Could not normalize device path"); + goto fail; + } + + s->open_flags = open_flags; + raw_parse_flags(bdrv_flags, &s->open_flags); + + s->fd = -1; + fd = qemu_open(filename, s->open_flags, 0644); + if (fd < 0) { + ret = -errno; + if (ret == -EROFS) { + ret = -EACCES; + } + goto fail; + } + s->fd = fd; + +#ifdef CONFIG_LINUX_AIO + if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) { + qemu_close(fd); + ret = -errno; + error_setg_errno(errp, -ret, "Could not set AIO state"); + goto fail; + } + if (!s->use_aio && (bdrv_flags & BDRV_O_NATIVE_AIO)) { + error_printf("WARNING: aio=native was specified for '%s', but " + "it requires cache.direct=on, which was not " + "specified. Falling back to aio=threads.\n" + " This will become an error condition in " + "future QEMU versions.\n", + bs->filename); + } +#else + if (bdrv_flags & BDRV_O_NATIVE_AIO) { + error_printf("WARNING: aio=native was specified for '%s', but " + "is not supported in this build. Falling back to " + "aio=threads.\n" + " This will become an error condition in " + "future QEMU versions.\n", + bs->filename); + } +#endif /* !defined(CONFIG_LINUX_AIO) */ + + s->has_discard = true; + s->has_write_zeroes = true; + if ((bs->open_flags & BDRV_O_NOCACHE) != 0) { + s->needs_alignment = true; + } + + if (fstat(s->fd, &st) < 0) { + ret = -errno; + error_setg_errno(errp, errno, "Could not stat file"); + goto fail; + } + if (S_ISREG(st.st_mode)) { + s->discard_zeroes = true; + s->has_fallocate = true; + } + if (S_ISBLK(st.st_mode)) { +#ifdef BLKDISCARDZEROES + unsigned int arg; + if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) { + s->discard_zeroes = true; + } +#endif +#ifdef __linux__ + /* On Linux 3.10, BLKDISCARD leaves stale data in the page cache. Do + * not rely on the contents of discarded blocks unless using O_DIRECT. + * Same for BLKZEROOUT. + */ + if (!(bs->open_flags & BDRV_O_NOCACHE)) { + s->discard_zeroes = false; + s->has_write_zeroes = false; + } +#endif + } +#ifdef __FreeBSD__ + if (S_ISCHR(st.st_mode)) { + /* + * The file is a char device (disk), which on FreeBSD isn't behind + * a pager, so force all requests to be aligned. This is needed + * so QEMU makes sure all IO operations on the device are aligned + * to sector size, or else FreeBSD will reject them with EINVAL. + */ + s->needs_alignment = true; + } +#endif + +#ifdef CONFIG_XFS + if (platform_test_xfs_fd(s->fd)) { + s->is_xfs = true; + } +#endif + + raw_attach_aio_context(bs, bdrv_get_aio_context(bs)); + + ret = 0; +fail: + if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { + unlink(filename); + } + qemu_opts_del(opts); + return ret; +} + +static int raw_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + BDRVRawState *s = bs->opaque; + Error *local_err = NULL; + int ret; + + s->type = FTYPE_FILE; + ret = raw_open_common(bs, options, flags, 0, &local_err); + if (local_err) { + error_propagate(errp, local_err); + } + return ret; +} + +static int raw_reopen_prepare(BDRVReopenState *state, + BlockReopenQueue *queue, Error **errp) +{ + BDRVRawState *s; + BDRVRawReopenState *raw_s; + int ret = 0; + Error *local_err = NULL; + + assert(state != NULL); + assert(state->bs != NULL); + + s = state->bs->opaque; + + state->opaque = g_new0(BDRVRawReopenState, 1); + raw_s = state->opaque; + +#ifdef CONFIG_LINUX_AIO + raw_s->use_aio = s->use_aio; + + /* we can use s->aio_ctx instead of a copy, because the use_aio flag is + * valid in the 'false' condition even if aio_ctx is set, and raw_set_aio() + * won't override aio_ctx if aio_ctx is non-NULL */ + if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) { + error_setg(errp, "Could not set AIO state"); + return -1; + } +#endif + + if (s->type == FTYPE_CD) { + raw_s->open_flags |= O_NONBLOCK; + } + + raw_parse_flags(state->flags, &raw_s->open_flags); + + raw_s->fd = -1; + + int fcntl_flags = O_APPEND | O_NONBLOCK; +#ifdef O_NOATIME + fcntl_flags |= O_NOATIME; +#endif + +#ifdef O_ASYNC + /* Not all operating systems have O_ASYNC, and those that don't + * will not let us track the state into raw_s->open_flags (typically + * you achieve the same effect with an ioctl, for example I_SETSIG + * on Solaris). But we do not use O_ASYNC, so that's fine. + */ + assert((s->open_flags & O_ASYNC) == 0); +#endif + + if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) { + /* dup the original fd */ + /* TODO: use qemu fcntl wrapper */ +#ifdef F_DUPFD_CLOEXEC + raw_s->fd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0); +#else + raw_s->fd = dup(s->fd); + if (raw_s->fd != -1) { + qemu_set_cloexec(raw_s->fd); + } +#endif + if (raw_s->fd >= 0) { + ret = fcntl_setfl(raw_s->fd, raw_s->open_flags); + if (ret) { + qemu_close(raw_s->fd); + raw_s->fd = -1; + } + } + } + + /* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */ + if (raw_s->fd == -1) { + const char *normalized_filename = state->bs->filename; + ret = raw_normalize_devicepath(&normalized_filename); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not normalize device path"); + } else { + assert(!(raw_s->open_flags & O_CREAT)); + raw_s->fd = qemu_open(normalized_filename, raw_s->open_flags); + if (raw_s->fd == -1) { + error_setg_errno(errp, errno, "Could not reopen file"); + ret = -1; + } + } + } + + /* Fail already reopen_prepare() if we can't get a working O_DIRECT + * alignment with the new fd. */ + if (raw_s->fd != -1) { + raw_probe_alignment(state->bs, raw_s->fd, &local_err); + if (local_err) { + qemu_close(raw_s->fd); + raw_s->fd = -1; + error_propagate(errp, local_err); + ret = -EINVAL; + } + } + + return ret; +} + +static void raw_reopen_commit(BDRVReopenState *state) +{ + BDRVRawReopenState *raw_s = state->opaque; + BDRVRawState *s = state->bs->opaque; + + s->open_flags = raw_s->open_flags; + + qemu_close(s->fd); + s->fd = raw_s->fd; +#ifdef CONFIG_LINUX_AIO + s->use_aio = raw_s->use_aio; +#endif + + g_free(state->opaque); + state->opaque = NULL; +} + + +static void raw_reopen_abort(BDRVReopenState *state) +{ + BDRVRawReopenState *raw_s = state->opaque; + + /* nothing to do if NULL, we didn't get far enough */ + if (raw_s == NULL) { + return; + } + + if (raw_s->fd >= 0) { + qemu_close(raw_s->fd); + raw_s->fd = -1; + } + g_free(state->opaque); + state->opaque = NULL; +} + +static void raw_refresh_limits(BlockDriverState *bs, Error **errp) +{ + BDRVRawState *s = bs->opaque; + + raw_probe_alignment(bs, s->fd, errp); + bs->bl.min_mem_alignment = s->buf_align; + bs->bl.opt_mem_alignment = MAX(s->buf_align, getpagesize()); +} + +static int check_for_dasd(int fd) +{ +#ifdef BIODASDINFO2 + struct dasd_information2_t info = {0}; + + return ioctl(fd, BIODASDINFO2, &info); +#else + return -1; +#endif +} + +/** + * Try to get @bs's logical and physical block size. + * On success, store them in @bsz and return zero. + * On failure, return negative errno. + */ +static int hdev_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz) +{ + BDRVRawState *s = bs->opaque; + int ret; + + /* If DASD, get blocksizes */ + if (check_for_dasd(s->fd) < 0) { + return -ENOTSUP; + } + ret = probe_logical_blocksize(s->fd, &bsz->log); + if (ret < 0) { + return ret; + } + return probe_physical_blocksize(s->fd, &bsz->phys); +} + +/** + * Try to get @bs's geometry: cyls, heads, sectors. + * On success, store them in @geo and return 0. + * On failure return -errno. + * (Allows block driver to assign default geometry values that guest sees) + */ +#ifdef __linux__ +static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo) +{ + BDRVRawState *s = bs->opaque; + struct hd_geometry ioctl_geo = {0}; + uint32_t blksize; + + /* If DASD, get its geometry */ + if (check_for_dasd(s->fd) < 0) { + return -ENOTSUP; + } + if (ioctl(s->fd, HDIO_GETGEO, &ioctl_geo) < 0) { + return -errno; + } + /* HDIO_GETGEO may return success even though geo contains zeros + (e.g. certain multipath setups) */ + if (!ioctl_geo.heads || !ioctl_geo.sectors || !ioctl_geo.cylinders) { + return -ENOTSUP; + } + /* Do not return a geometry for partition */ + if (ioctl_geo.start != 0) { + return -ENOTSUP; + } + geo->heads = ioctl_geo.heads; + geo->sectors = ioctl_geo.sectors; + if (!probe_physical_blocksize(s->fd, &blksize)) { + /* overwrite cyls: HDIO_GETGEO result is incorrect for big drives */ + geo->cylinders = bdrv_nb_sectors(bs) / (blksize / BDRV_SECTOR_SIZE) + / (geo->heads * geo->sectors); + return 0; + } + geo->cylinders = ioctl_geo.cylinders; + + return 0; +} +#else /* __linux__ */ +static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo) +{ + return -ENOTSUP; +} +#endif + +static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) +{ + int ret; + + ret = ioctl(aiocb->aio_fildes, aiocb->aio_ioctl_cmd, aiocb->aio_ioctl_buf); + if (ret == -1) { + return -errno; + } + + return 0; +} + +static ssize_t handle_aiocb_flush(RawPosixAIOData *aiocb) +{ + int ret; + + ret = qemu_fdatasync(aiocb->aio_fildes); + if (ret == -1) { + return -errno; + } + return 0; +} + +#ifdef CONFIG_PREADV + +static bool preadv_present = true; + +static ssize_t +qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset) +{ + return preadv(fd, iov, nr_iov, offset); +} + +static ssize_t +qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset) +{ + return pwritev(fd, iov, nr_iov, offset); +} + +#else + +static bool preadv_present = false; + +static ssize_t +qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset) +{ + return -ENOSYS; +} + +static ssize_t +qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset) +{ + return -ENOSYS; +} + +#endif + +static ssize_t handle_aiocb_rw_vector(RawPosixAIOData *aiocb) +{ + ssize_t len; + + do { + if (aiocb->aio_type & QEMU_AIO_WRITE) + len = qemu_pwritev(aiocb->aio_fildes, + aiocb->aio_iov, + aiocb->aio_niov, + aiocb->aio_offset); + else + len = qemu_preadv(aiocb->aio_fildes, + aiocb->aio_iov, + aiocb->aio_niov, + aiocb->aio_offset); + } while (len == -1 && errno == EINTR); + + if (len == -1) { + return -errno; + } + return len; +} + +/* + * Read/writes the data to/from a given linear buffer. + * + * Returns the number of bytes handles or -errno in case of an error. Short + * reads are only returned if the end of the file is reached. + */ +static ssize_t handle_aiocb_rw_linear(RawPosixAIOData *aiocb, char *buf) +{ + ssize_t offset = 0; + ssize_t len; + + while (offset < aiocb->aio_nbytes) { + if (aiocb->aio_type & QEMU_AIO_WRITE) { + len = pwrite(aiocb->aio_fildes, + (const char *)buf + offset, + aiocb->aio_nbytes - offset, + aiocb->aio_offset + offset); + } else { + len = pread(aiocb->aio_fildes, + buf + offset, + aiocb->aio_nbytes - offset, + aiocb->aio_offset + offset); + } + if (len == -1 && errno == EINTR) { + continue; + } else if (len == -1 && errno == EINVAL && + (aiocb->bs->open_flags & BDRV_O_NOCACHE) && + !(aiocb->aio_type & QEMU_AIO_WRITE) && + offset > 0) { + /* O_DIRECT pread() may fail with EINVAL when offset is unaligned + * after a short read. Assume that O_DIRECT short reads only occur + * at EOF. Therefore this is a short read, not an I/O error. + */ + break; + } else if (len == -1) { + offset = -errno; + break; + } else if (len == 0) { + break; + } + offset += len; + } + + return offset; +} + +static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb) +{ + ssize_t nbytes; + char *buf; + + if (!(aiocb->aio_type & QEMU_AIO_MISALIGNED)) { + /* + * If there is just a single buffer, and it is properly aligned + * we can just use plain pread/pwrite without any problems. + */ + if (aiocb->aio_niov == 1) { + return handle_aiocb_rw_linear(aiocb, aiocb->aio_iov->iov_base); + } + /* + * We have more than one iovec, and all are properly aligned. + * + * Try preadv/pwritev first and fall back to linearizing the + * buffer if it's not supported. + */ + if (preadv_present) { + nbytes = handle_aiocb_rw_vector(aiocb); + if (nbytes == aiocb->aio_nbytes || + (nbytes < 0 && nbytes != -ENOSYS)) { + return nbytes; + } + preadv_present = false; + } + + /* + * XXX(hch): short read/write. no easy way to handle the reminder + * using these interfaces. For now retry using plain + * pread/pwrite? + */ + } + + /* + * Ok, we have to do it the hard way, copy all segments into + * a single aligned buffer. + */ + buf = qemu_try_blockalign(aiocb->bs, aiocb->aio_nbytes); + if (buf == NULL) { + return -ENOMEM; + } + + if (aiocb->aio_type & QEMU_AIO_WRITE) { + char *p = buf; + int i; + + for (i = 0; i < aiocb->aio_niov; ++i) { + memcpy(p, aiocb->aio_iov[i].iov_base, aiocb->aio_iov[i].iov_len); + p += aiocb->aio_iov[i].iov_len; + } + assert(p - buf == aiocb->aio_nbytes); + } + + nbytes = handle_aiocb_rw_linear(aiocb, buf); + if (!(aiocb->aio_type & QEMU_AIO_WRITE)) { + char *p = buf; + size_t count = aiocb->aio_nbytes, copy; + int i; + + for (i = 0; i < aiocb->aio_niov && count; ++i) { + copy = count; + if (copy > aiocb->aio_iov[i].iov_len) { + copy = aiocb->aio_iov[i].iov_len; + } + memcpy(aiocb->aio_iov[i].iov_base, p, copy); + assert(count >= copy); + p += copy; + count -= copy; + } + assert(count == 0); + } + qemu_vfree(buf); + + return nbytes; +} + +#ifdef CONFIG_XFS +static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes) +{ + struct xfs_flock64 fl; + int err; + + memset(&fl, 0, sizeof(fl)); + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = bytes; + + if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) { + err = errno; + DPRINTF("cannot write zero range (%s)\n", strerror(errno)); + return -err; + } + + return 0; +} + +static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes) +{ + struct xfs_flock64 fl; + int err; + + memset(&fl, 0, sizeof(fl)); + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = bytes; + + if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) { + err = errno; + DPRINTF("cannot punch hole (%s)\n", strerror(errno)); + return -err; + } + + return 0; +} +#endif + +static int translate_err(int err) +{ + if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP || + err == -ENOTTY) { + err = -ENOTSUP; + } + return err; +} + +#ifdef CONFIG_FALLOCATE +static int do_fallocate(int fd, int mode, off_t offset, off_t len) +{ + do { + if (fallocate(fd, mode, offset, len) == 0) { + return 0; + } + } while (errno == EINTR); + return translate_err(-errno); +} +#endif + +static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb) +{ + int ret = -ENOTSUP; + BDRVRawState *s = aiocb->bs->opaque; + + if (!s->has_write_zeroes) { + return -ENOTSUP; + } + +#ifdef BLKZEROOUT + do { + uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes }; + if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) { + return 0; + } + } while (errno == EINTR); + + ret = translate_err(-errno); +#endif + + if (ret == -ENOTSUP) { + s->has_write_zeroes = false; + } + return ret; +} + +static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb) +{ +#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS) + BDRVRawState *s = aiocb->bs->opaque; +#endif + + if (aiocb->aio_type & QEMU_AIO_BLKDEV) { + return handle_aiocb_write_zeroes_block(aiocb); + } + +#ifdef CONFIG_XFS + if (s->is_xfs) { + return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes); + } +#endif + +#ifdef CONFIG_FALLOCATE_ZERO_RANGE + if (s->has_write_zeroes) { + int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE, + aiocb->aio_offset, aiocb->aio_nbytes); + if (ret == 0 || ret != -ENOTSUP) { + return ret; + } + s->has_write_zeroes = false; + } +#endif + +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE + if (s->has_discard && s->has_fallocate) { + int ret = do_fallocate(s->fd, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + aiocb->aio_offset, aiocb->aio_nbytes); + if (ret == 0) { + ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); + if (ret == 0 || ret != -ENOTSUP) { + return ret; + } + s->has_fallocate = false; + } else if (ret != -ENOTSUP) { + return ret; + } else { + s->has_discard = false; + } + } +#endif + +#ifdef CONFIG_FALLOCATE + if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) { + int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); + if (ret == 0 || ret != -ENOTSUP) { + return ret; + } else { + s->has_discard = false; + } + } +#endif + +#ifdef CONFIG_FALLOCATE + if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) { + int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); + if (ret == 0 || ret != -ENOTSUP) { + return ret; + } + s->has_fallocate = false; + } +#endif + + return -ENOTSUP; +} + +static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb) +{ + int ret = -EOPNOTSUPP; + BDRVRawState *s = aiocb->bs->opaque; + + if (!s->has_discard) { + return -ENOTSUP; + } + + if (aiocb->aio_type & QEMU_AIO_BLKDEV) { +#ifdef BLKDISCARD + do { + uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes }; + if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0) { + return 0; + } + } while (errno == EINTR); + + ret = -errno; +#endif + } else { +#ifdef CONFIG_XFS + if (s->is_xfs) { + return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes); + } +#endif + +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE + ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + aiocb->aio_offset, aiocb->aio_nbytes); +#endif + } + + ret = translate_err(ret); + if (ret == -ENOTSUP) { + s->has_discard = false; + } + return ret; +} + +static int aio_worker(void *arg) +{ + RawPosixAIOData *aiocb = arg; + ssize_t ret = 0; + + switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { + case QEMU_AIO_READ: + ret = handle_aiocb_rw(aiocb); + if (ret >= 0 && ret < aiocb->aio_nbytes) { + iov_memset(aiocb->aio_iov, aiocb->aio_niov, ret, + 0, aiocb->aio_nbytes - ret); + + ret = aiocb->aio_nbytes; + } + if (ret == aiocb->aio_nbytes) { + ret = 0; + } else if (ret >= 0 && ret < aiocb->aio_nbytes) { + ret = -EINVAL; + } + break; + case QEMU_AIO_WRITE: + ret = handle_aiocb_rw(aiocb); + if (ret == aiocb->aio_nbytes) { + ret = 0; + } else if (ret >= 0 && ret < aiocb->aio_nbytes) { + ret = -EINVAL; + } + break; + case QEMU_AIO_FLUSH: + ret = handle_aiocb_flush(aiocb); + break; + case QEMU_AIO_IOCTL: + ret = handle_aiocb_ioctl(aiocb); + break; + case QEMU_AIO_DISCARD: + ret = handle_aiocb_discard(aiocb); + break; + case QEMU_AIO_WRITE_ZEROES: + ret = handle_aiocb_write_zeroes(aiocb); + break; + default: + fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type); + ret = -EINVAL; + break; + } + + g_free(aiocb); + return ret; +} + +static int paio_submit_co(BlockDriverState *bs, int fd, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + int type) +{ + RawPosixAIOData *acb = g_new(RawPosixAIOData, 1); + ThreadPool *pool; + + acb->bs = bs; + acb->aio_type = type; + acb->aio_fildes = fd; + + acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE; + acb->aio_offset = sector_num * BDRV_SECTOR_SIZE; + + if (qiov) { + acb->aio_iov = qiov->iov; + acb->aio_niov = qiov->niov; + assert(qiov->size == acb->aio_nbytes); + } + + trace_paio_submit_co(sector_num, nb_sectors, type); + pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); + return thread_pool_submit_co(pool, aio_worker, acb); +} + +static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockCompletionFunc *cb, void *opaque, int type) +{ + RawPosixAIOData *acb = g_new(RawPosixAIOData, 1); + ThreadPool *pool; + + acb->bs = bs; + acb->aio_type = type; + acb->aio_fildes = fd; + + acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE; + acb->aio_offset = sector_num * BDRV_SECTOR_SIZE; + + if (qiov) { + acb->aio_iov = qiov->iov; + acb->aio_niov = qiov->niov; + assert(qiov->size == acb->aio_nbytes); + } + + trace_paio_submit(acb, opaque, sector_num, nb_sectors, type); + pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); + return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); +} + +static BlockAIOCB *raw_aio_submit(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockCompletionFunc *cb, void *opaque, int type) +{ + BDRVRawState *s = bs->opaque; + + if (fd_open(bs) < 0) + return NULL; + + /* + * Check if the underlying device requires requests to be aligned, + * and if the request we are trying to submit is aligned or not. + * If this is the case tell the low-level driver that it needs + * to copy the buffer. + */ + if (s->needs_alignment) { + if (!bdrv_qiov_is_aligned(bs, qiov)) { + type |= QEMU_AIO_MISALIGNED; +#ifdef CONFIG_LINUX_AIO + } else if (s->use_aio) { + return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, + nb_sectors, cb, opaque, type); +#endif + } + } + + return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors, + cb, opaque, type); +} + +static void raw_aio_plug(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + if (s->use_aio) { + laio_io_plug(bs, s->aio_ctx); + } +#endif +} + +static void raw_aio_unplug(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + if (s->use_aio) { + laio_io_unplug(bs, s->aio_ctx, true); + } +#endif +} + +static void raw_aio_flush_io_queue(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + if (s->use_aio) { + laio_io_unplug(bs, s->aio_ctx, false); + } +#endif +} + +static BlockAIOCB *raw_aio_readv(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockCompletionFunc *cb, void *opaque) +{ + return raw_aio_submit(bs, sector_num, qiov, nb_sectors, + cb, opaque, QEMU_AIO_READ); +} + +static BlockAIOCB *raw_aio_writev(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockCompletionFunc *cb, void *opaque) +{ + return raw_aio_submit(bs, sector_num, qiov, nb_sectors, + cb, opaque, QEMU_AIO_WRITE); +} + +static BlockAIOCB *raw_aio_flush(BlockDriverState *bs, + BlockCompletionFunc *cb, void *opaque) +{ + BDRVRawState *s = bs->opaque; + + if (fd_open(bs) < 0) + return NULL; + + return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH); +} + +static void raw_close(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + + raw_detach_aio_context(bs); + +#ifdef CONFIG_LINUX_AIO + if (s->use_aio) { + laio_cleanup(s->aio_ctx); + } +#endif + if (s->fd >= 0) { + qemu_close(s->fd); + s->fd = -1; + } +} + +static int raw_truncate(BlockDriverState *bs, int64_t offset) +{ + BDRVRawState *s = bs->opaque; + struct stat st; + + if (fstat(s->fd, &st)) { + return -errno; + } + + if (S_ISREG(st.st_mode)) { + if (ftruncate(s->fd, offset) < 0) { + return -errno; + } + } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { + if (offset > raw_getlength(bs)) { + return -EINVAL; + } + } else { + return -ENOTSUP; + } + + return 0; +} + +#ifdef __OpenBSD__ +static int64_t raw_getlength(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int fd = s->fd; + struct stat st; + + if (fstat(fd, &st)) + return -errno; + if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { + struct disklabel dl; + + if (ioctl(fd, DIOCGDINFO, &dl)) + return -errno; + return (uint64_t)dl.d_secsize * + dl.d_partitions[DISKPART(st.st_rdev)].p_size; + } else + return st.st_size; +} +#elif defined(__NetBSD__) +static int64_t raw_getlength(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int fd = s->fd; + struct stat st; + + if (fstat(fd, &st)) + return -errno; + if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { + struct dkwedge_info dkw; + + if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) { + return dkw.dkw_size * 512; + } else { + struct disklabel dl; + + if (ioctl(fd, DIOCGDINFO, &dl)) + return -errno; + return (uint64_t)dl.d_secsize * + dl.d_partitions[DISKPART(st.st_rdev)].p_size; + } + } else + return st.st_size; +} +#elif defined(__sun__) +static int64_t raw_getlength(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + struct dk_minfo minfo; + int ret; + int64_t size; + + ret = fd_open(bs); + if (ret < 0) { + return ret; + } + + /* + * Use the DKIOCGMEDIAINFO ioctl to read the size. + */ + ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo); + if (ret != -1) { + return minfo.dki_lbsize * minfo.dki_capacity; + } + + /* + * There are reports that lseek on some devices fails, but + * irc discussion said that contingency on contingency was overkill. + */ + size = lseek(s->fd, 0, SEEK_END); + if (size < 0) { + return -errno; + } + return size; +} +#elif defined(CONFIG_BSD) +static int64_t raw_getlength(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int fd = s->fd; + int64_t size; + struct stat sb; +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) + int reopened = 0; +#endif + int ret; + + ret = fd_open(bs); + if (ret < 0) + return ret; + +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +again: +#endif + if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { +#ifdef DIOCGMEDIASIZE + if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) +#elif defined(DIOCGPART) + { + struct partinfo pi; + if (ioctl(fd, DIOCGPART, &pi) == 0) + size = pi.media_size; + else + size = 0; + } + if (size == 0) +#endif +#if defined(__APPLE__) && defined(__MACH__) + { + uint64_t sectors = 0; + uint32_t sector_size = 0; + + if (ioctl(fd, DKIOCGETBLOCKCOUNT, §ors) == 0 + && ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) == 0) { + size = sectors * sector_size; + } else { + size = lseek(fd, 0LL, SEEK_END); + if (size < 0) { + return -errno; + } + } + } +#else + size = lseek(fd, 0LL, SEEK_END); + if (size < 0) { + return -errno; + } +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + switch(s->type) { + case FTYPE_CD: + /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */ + if (size == 2048LL * (unsigned)-1) + size = 0; + /* XXX no disc? maybe we need to reopen... */ + if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) { + reopened = 1; + goto again; + } + } +#endif + } else { + size = lseek(fd, 0, SEEK_END); + if (size < 0) { + return -errno; + } + } + return size; +} +#else +static int64_t raw_getlength(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int ret; + int64_t size; + + ret = fd_open(bs); + if (ret < 0) { + return ret; + } + + size = lseek(s->fd, 0, SEEK_END); + if (size < 0) { + return -errno; + } + return size; +} +#endif + +static int64_t raw_get_allocated_file_size(BlockDriverState *bs) +{ + struct stat st; + BDRVRawState *s = bs->opaque; + + if (fstat(s->fd, &st) < 0) { + return -errno; + } + return (int64_t)st.st_blocks * 512; +} + +static int raw_create(const char *filename, QemuOpts *opts, Error **errp) +{ + int fd; + int result = 0; + int64_t total_size = 0; + bool nocow = false; + PreallocMode prealloc; + char *buf = NULL; + Error *local_err = NULL; + + strstart(filename, "file:", &filename); + + /* Read out options */ + total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); + nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); + buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); + prealloc = qapi_enum_parse(PreallocMode_lookup, buf, + PREALLOC_MODE_MAX, PREALLOC_MODE_OFF, + &local_err); + g_free(buf); + if (local_err) { + error_propagate(errp, local_err); + result = -EINVAL; + goto out; + } + + fd = qemu_open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, + 0644); + if (fd < 0) { + result = -errno; + error_setg_errno(errp, -result, "Could not create file"); + goto out; + } + + if (nocow) { +#ifdef __linux__ + /* Set NOCOW flag to solve performance issue on fs like btrfs. + * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value + * will be ignored since any failure of this operation should not + * block the left work. + */ + int attr; + if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) { + attr |= FS_NOCOW_FL; + ioctl(fd, FS_IOC_SETFLAGS, &attr); + } +#endif + } + + if (ftruncate(fd, total_size) != 0) { + result = -errno; + error_setg_errno(errp, -result, "Could not resize file"); + goto out_close; + } + + switch (prealloc) { +#ifdef CONFIG_POSIX_FALLOCATE + case PREALLOC_MODE_FALLOC: + /* posix_fallocate() doesn't set errno. */ + result = -posix_fallocate(fd, 0, total_size); + if (result != 0) { + error_setg_errno(errp, -result, + "Could not preallocate data for the new file"); + } + break; +#endif + case PREALLOC_MODE_FULL: + { + int64_t num = 0, left = total_size; + buf = g_malloc0(65536); + + while (left > 0) { + num = MIN(left, 65536); + result = write(fd, buf, num); + if (result < 0) { + result = -errno; + error_setg_errno(errp, -result, + "Could not write to the new file"); + break; + } + left -= result; + } + if (result >= 0) { + result = fsync(fd); + if (result < 0) { + result = -errno; + error_setg_errno(errp, -result, + "Could not flush new file to disk"); + } + } + g_free(buf); + break; + } + case PREALLOC_MODE_OFF: + break; + default: + result = -EINVAL; + error_setg(errp, "Unsupported preallocation mode: %s", + PreallocMode_lookup[prealloc]); + break; + } + +out_close: + if (qemu_close(fd) != 0 && result == 0) { + result = -errno; + error_setg_errno(errp, -result, "Could not close the new file"); + } +out: + return result; +} + +/* + * Find allocation range in @bs around offset @start. + * May change underlying file descriptor's file offset. + * If @start is not in a hole, store @start in @data, and the + * beginning of the next hole in @hole, and return 0. + * If @start is in a non-trailing hole, store @start in @hole and the + * beginning of the next non-hole in @data, and return 0. + * If @start is in a trailing hole or beyond EOF, return -ENXIO. + * If we can't find out, return a negative errno other than -ENXIO. + */ +static int find_allocation(BlockDriverState *bs, off_t start, + off_t *data, off_t *hole) +{ +#if defined SEEK_HOLE && defined SEEK_DATA + BDRVRawState *s = bs->opaque; + off_t offs; + + /* + * SEEK_DATA cases: + * D1. offs == start: start is in data + * D2. offs > start: start is in a hole, next data at offs + * D3. offs < 0, errno = ENXIO: either start is in a trailing hole + * or start is beyond EOF + * If the latter happens, the file has been truncated behind + * our back since we opened it. All bets are off then. + * Treating like a trailing hole is simplest. + * D4. offs < 0, errno != ENXIO: we learned nothing + */ + offs = lseek(s->fd, start, SEEK_DATA); + if (offs < 0) { + return -errno; /* D3 or D4 */ + } + assert(offs >= start); + + if (offs > start) { + /* D2: in hole, next data at offs */ + *hole = start; + *data = offs; + return 0; + } + + /* D1: in data, end not yet known */ + + /* + * SEEK_HOLE cases: + * H1. offs == start: start is in a hole + * If this happens here, a hole has been dug behind our back + * since the previous lseek(). + * H2. offs > start: either start is in data, next hole at offs, + * or start is in trailing hole, EOF at offs + * Linux treats trailing holes like any other hole: offs == + * start. Solaris seeks to EOF instead: offs > start (blech). + * If that happens here, a hole has been dug behind our back + * since the previous lseek(). + * H3. offs < 0, errno = ENXIO: start is beyond EOF + * If this happens, the file has been truncated behind our + * back since we opened it. Treat it like a trailing hole. + * H4. offs < 0, errno != ENXIO: we learned nothing + * Pretend we know nothing at all, i.e. "forget" about D1. + */ + offs = lseek(s->fd, start, SEEK_HOLE); + if (offs < 0) { + return -errno; /* D1 and (H3 or H4) */ + } + assert(offs >= start); + + if (offs > start) { + /* + * D1 and H2: either in data, next hole at offs, or it was in + * data but is now in a trailing hole. In the latter case, + * all bets are off. Treating it as if it there was data all + * the way to EOF is safe, so simply do that. + */ + *data = start; + *hole = offs; + return 0; + } + + /* D1 and H1 */ + return -EBUSY; +#else + return -ENOTSUP; +#endif +} + +/* + * Returns the allocation status of the specified sectors. + * + * If 'sector_num' is beyond the end of the disk image the return value is 0 + * and 'pnum' is set to 0. + * + * 'pnum' is set to the number of sectors (including and immediately following + * the specified sector) that are known to be in the same + * allocated/unallocated state. + * + * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes + * beyond the end of the disk image it will be clamped. + */ +static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, + int64_t sector_num, + int nb_sectors, int *pnum) +{ + off_t start, data = 0, hole = 0; + int64_t total_size; + int ret; + + ret = fd_open(bs); + if (ret < 0) { + return ret; + } + + start = sector_num * BDRV_SECTOR_SIZE; + total_size = bdrv_getlength(bs); + if (total_size < 0) { + return total_size; + } else if (start >= total_size) { + *pnum = 0; + return 0; + } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) { + nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE); + } + + ret = find_allocation(bs, start, &data, &hole); + if (ret == -ENXIO) { + /* Trailing hole */ + *pnum = nb_sectors; + ret = BDRV_BLOCK_ZERO; + } else if (ret < 0) { + /* No info available, so pretend there are no holes */ + *pnum = nb_sectors; + ret = BDRV_BLOCK_DATA; + } else if (data == start) { + /* On a data extent, compute sectors to the end of the extent, + * possibly including a partial sector at EOF. */ + *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE)); + ret = BDRV_BLOCK_DATA; + } else { + /* On a hole, compute sectors to the beginning of the next extent. */ + assert(hole == start); + *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE); + ret = BDRV_BLOCK_ZERO; + } + return ret | BDRV_BLOCK_OFFSET_VALID | start; +} + +static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockCompletionFunc *cb, void *opaque) +{ + BDRVRawState *s = bs->opaque; + + return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors, + cb, opaque, QEMU_AIO_DISCARD); +} + +static int coroutine_fn raw_co_write_zeroes( + BlockDriverState *bs, int64_t sector_num, + int nb_sectors, BdrvRequestFlags flags) +{ + BDRVRawState *s = bs->opaque; + + if (!(flags & BDRV_REQ_MAY_UNMAP)) { + return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + QEMU_AIO_WRITE_ZEROES); + } else if (s->discard_zeroes) { + return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + QEMU_AIO_DISCARD); + } + return -ENOTSUP; +} + +static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) +{ + BDRVRawState *s = bs->opaque; + + bdi->unallocated_blocks_are_zero = s->discard_zeroes; + bdi->can_write_zeroes_with_unmap = s->discard_zeroes; + return 0; +} + +static QemuOptsList raw_create_opts = { + .name = "raw-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_NOCOW, + .type = QEMU_OPT_BOOL, + .help = "Turn off copy-on-write (valid only on btrfs)" + }, + { + .name = BLOCK_OPT_PREALLOC, + .type = QEMU_OPT_STRING, + .help = "Preallocation mode (allowed values: off, falloc, full)" + }, + { /* end of list */ } + } +}; + +BlockDriver bdrv_file = { + .format_name = "file", + .protocol_name = "file", + .instance_size = sizeof(BDRVRawState), + .bdrv_needs_filename = true, + .bdrv_probe = NULL, /* no probe for protocols */ + .bdrv_parse_filename = raw_parse_filename, + .bdrv_file_open = raw_open, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, + .bdrv_close = raw_close, + .bdrv_create = raw_create, + .bdrv_has_zero_init = bdrv_has_zero_init_1, + .bdrv_co_get_block_status = raw_co_get_block_status, + .bdrv_co_write_zeroes = raw_co_write_zeroes, + + .bdrv_aio_readv = raw_aio_readv, + .bdrv_aio_writev = raw_aio_writev, + .bdrv_aio_flush = raw_aio_flush, + .bdrv_aio_discard = raw_aio_discard, + .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, + .bdrv_flush_io_queue = raw_aio_flush_io_queue, + + .bdrv_truncate = raw_truncate, + .bdrv_getlength = raw_getlength, + .bdrv_get_info = raw_get_info, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, + + .bdrv_detach_aio_context = raw_detach_aio_context, + .bdrv_attach_aio_context = raw_attach_aio_context, + + .create_opts = &raw_create_opts, +}; + +/***********************************************/ +/* host device */ + +#if defined(__APPLE__) && defined(__MACH__) +static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ); +static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, + CFIndex maxPathSize, int flags); +kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) +{ + kern_return_t kernResult; + mach_port_t masterPort; + CFMutableDictionaryRef classesToMatch; + + kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort ); + if ( KERN_SUCCESS != kernResult ) { + printf( "IOMasterPort returned %d\n", kernResult ); + } + + classesToMatch = IOServiceMatching( kIOCDMediaClass ); + if ( classesToMatch == NULL ) { + printf( "IOServiceMatching returned a NULL dictionary.\n" ); + } else { + CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue ); + } + kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator ); + if ( KERN_SUCCESS != kernResult ) + { + printf( "IOServiceGetMatchingServices returned %d\n", kernResult ); + } + + return kernResult; +} + +kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, + CFIndex maxPathSize, int flags) +{ + io_object_t nextMedia; + kern_return_t kernResult = KERN_FAILURE; + *bsdPath = '\0'; + nextMedia = IOIteratorNext( mediaIterator ); + if ( nextMedia ) + { + CFTypeRef bsdPathAsCFString; + bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 ); + if ( bsdPathAsCFString ) { + size_t devPathLength; + strcpy( bsdPath, _PATH_DEV ); + if (flags & BDRV_O_NOCACHE) { + strcat(bsdPath, "r"); + } + devPathLength = strlen( bsdPath ); + if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) { + kernResult = KERN_SUCCESS; + } + CFRelease( bsdPathAsCFString ); + } + IOObjectRelease( nextMedia ); + } + + return kernResult; +} + +#endif + +static int hdev_probe_device(const char *filename) +{ + struct stat st; + + /* allow a dedicated CD-ROM driver to match with a higher priority */ + if (strstart(filename, "/dev/cdrom", NULL)) + return 50; + + if (stat(filename, &st) >= 0 && + (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { + return 100; + } + + return 0; +} + +static int check_hdev_writable(BDRVRawState *s) +{ +#if defined(BLKROGET) + /* Linux block devices can be configured "read-only" using blockdev(8). + * This is independent of device node permissions and therefore open(2) + * with O_RDWR succeeds. Actual writes fail with EPERM. + * + * bdrv_open() is supposed to fail if the disk is read-only. Explicitly + * check for read-only block devices so that Linux block devices behave + * properly. + */ + struct stat st; + int readonly = 0; + + if (fstat(s->fd, &st)) { + return -errno; + } + + if (!S_ISBLK(st.st_mode)) { + return 0; + } + + if (ioctl(s->fd, BLKROGET, &readonly) < 0) { + return -errno; + } + + if (readonly) { + return -EACCES; + } +#endif /* defined(BLKROGET) */ + return 0; +} + +static void hdev_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* The prefix is optional, just as for "file". */ + strstart(filename, "host_device:", &filename); + + qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); +} + +static bool hdev_is_sg(BlockDriverState *bs) +{ + +#if defined(__linux__) + + struct stat st; + struct sg_scsi_id scsiid; + int sg_version; + + if (stat(bs->filename, &st) >= 0 && S_ISCHR(st.st_mode) && + !bdrv_ioctl(bs, SG_GET_VERSION_NUM, &sg_version) && + !bdrv_ioctl(bs, SG_GET_SCSI_ID, &scsiid)) { + DPRINTF("SG device found: type=%d, version=%d\n", + scsiid.scsi_type, sg_version); + return true; + } + +#endif + + return false; +} + +static int hdev_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + BDRVRawState *s = bs->opaque; + Error *local_err = NULL; + int ret; + +#if defined(__APPLE__) && defined(__MACH__) + const char *filename = qdict_get_str(options, "filename"); + + if (strstart(filename, "/dev/cdrom", NULL)) { + kern_return_t kernResult; + io_iterator_t mediaIterator; + char bsdPath[ MAXPATHLEN ]; + int fd; + + kernResult = FindEjectableCDMedia( &mediaIterator ); + kernResult = GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath), + flags); + if ( bsdPath[ 0 ] != '\0' ) { + strcat(bsdPath,"s0"); + /* some CDs don't have a partition 0 */ + fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); + if (fd < 0) { + bsdPath[strlen(bsdPath)-1] = '1'; + } else { + qemu_close(fd); + } + filename = bsdPath; + qdict_put(options, "filename", qstring_from_str(filename)); + } + + if ( mediaIterator ) + IOObjectRelease( mediaIterator ); + } +#endif + + s->type = FTYPE_FILE; + + ret = raw_open_common(bs, options, flags, 0, &local_err); + if (ret < 0) { + if (local_err) { + error_propagate(errp, local_err); + } + return ret; + } + + /* Since this does ioctl the device must be already opened */ + bs->sg = hdev_is_sg(bs); + + if (flags & BDRV_O_RDWR) { + ret = check_hdev_writable(s); + if (ret < 0) { + raw_close(bs); + error_setg_errno(errp, -ret, "The device is not writable"); + return ret; + } + } + + return ret; +} + +#if defined(__linux__) + +static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs, + unsigned long int req, void *buf, + BlockCompletionFunc *cb, void *opaque) +{ + BDRVRawState *s = bs->opaque; + RawPosixAIOData *acb; + ThreadPool *pool; + + if (fd_open(bs) < 0) + return NULL; + + acb = g_new(RawPosixAIOData, 1); + acb->bs = bs; + acb->aio_type = QEMU_AIO_IOCTL; + acb->aio_fildes = s->fd; + acb->aio_offset = 0; + acb->aio_ioctl_buf = buf; + acb->aio_ioctl_cmd = req; + pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); + return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); +} +#endif /* linux */ + +static int fd_open(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + + /* this is just to ensure s->fd is sane (its called by io ops) */ + if (s->fd >= 0) + return 0; + return -EIO; +} + +static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockCompletionFunc *cb, void *opaque) +{ + BDRVRawState *s = bs->opaque; + + if (fd_open(bs) < 0) { + return NULL; + } + return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors, + cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); +} + +static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +{ + BDRVRawState *s = bs->opaque; + int rc; + + rc = fd_open(bs); + if (rc < 0) { + return rc; + } + if (!(flags & BDRV_REQ_MAY_UNMAP)) { + return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV); + } else if (s->discard_zeroes) { + return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); + } + return -ENOTSUP; +} + +static int hdev_create(const char *filename, QemuOpts *opts, + Error **errp) +{ + int fd; + int ret = 0; + struct stat stat_buf; + int64_t total_size = 0; + bool has_prefix; + + /* This function is used by both protocol block drivers and therefore either + * of these prefixes may be given. + * The return value has to be stored somewhere, otherwise this is an error + * due to -Werror=unused-value. */ + has_prefix = + strstart(filename, "host_device:", &filename) || + strstart(filename, "host_cdrom:" , &filename); + + (void)has_prefix; + + ret = raw_normalize_devicepath(&filename); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not normalize device path"); + return ret; + } + + /* Read out options */ + total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), + BDRV_SECTOR_SIZE); + + fd = qemu_open(filename, O_WRONLY | O_BINARY); + if (fd < 0) { + ret = -errno; + error_setg_errno(errp, -ret, "Could not open device"); + return ret; + } + + if (fstat(fd, &stat_buf) < 0) { + ret = -errno; + error_setg_errno(errp, -ret, "Could not stat device"); + } else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) { + error_setg(errp, + "The given file is neither a block nor a character device"); + ret = -ENODEV; + } else if (lseek(fd, 0, SEEK_END) < total_size) { + error_setg(errp, "Device is too small"); + ret = -ENOSPC; + } + + qemu_close(fd); + return ret; +} + +static BlockDriver bdrv_host_device = { + .format_name = "host_device", + .protocol_name = "host_device", + .instance_size = sizeof(BDRVRawState), + .bdrv_needs_filename = true, + .bdrv_probe_device = hdev_probe_device, + .bdrv_parse_filename = hdev_parse_filename, + .bdrv_file_open = hdev_open, + .bdrv_close = raw_close, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, + .bdrv_create = hdev_create, + .create_opts = &raw_create_opts, + .bdrv_co_write_zeroes = hdev_co_write_zeroes, + + .bdrv_aio_readv = raw_aio_readv, + .bdrv_aio_writev = raw_aio_writev, + .bdrv_aio_flush = raw_aio_flush, + .bdrv_aio_discard = hdev_aio_discard, + .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, + .bdrv_flush_io_queue = raw_aio_flush_io_queue, + + .bdrv_truncate = raw_truncate, + .bdrv_getlength = raw_getlength, + .bdrv_get_info = raw_get_info, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, + .bdrv_probe_blocksizes = hdev_probe_blocksizes, + .bdrv_probe_geometry = hdev_probe_geometry, + + .bdrv_detach_aio_context = raw_detach_aio_context, + .bdrv_attach_aio_context = raw_attach_aio_context, + + /* generic scsi device */ +#ifdef __linux__ + .bdrv_aio_ioctl = hdev_aio_ioctl, +#endif +}; + +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static void cdrom_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* The prefix is optional, just as for "file". */ + strstart(filename, "host_cdrom:", &filename); + + qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); +} +#endif + +#ifdef __linux__ +static int cdrom_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + BDRVRawState *s = bs->opaque; + Error *local_err = NULL; + int ret; + + s->type = FTYPE_CD; + + /* open will not fail even if no CD is inserted, so add O_NONBLOCK */ + ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err); + if (local_err) { + error_propagate(errp, local_err); + } + return ret; +} + +static int cdrom_probe_device(const char *filename) +{ + int fd, ret; + int prio = 0; + struct stat st; + + fd = qemu_open(filename, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + goto out; + } + ret = fstat(fd, &st); + if (ret == -1 || !S_ISBLK(st.st_mode)) { + goto outc; + } + + /* Attempt to detect via a CDROM specific ioctl */ + ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); + if (ret >= 0) + prio = 100; + +outc: + qemu_close(fd); +out: + return prio; +} + +static bool cdrom_is_inserted(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int ret; + + ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); + return ret == CDS_DISC_OK; +} + +static void cdrom_eject(BlockDriverState *bs, bool eject_flag) +{ + BDRVRawState *s = bs->opaque; + + if (eject_flag) { + if (ioctl(s->fd, CDROMEJECT, NULL) < 0) + perror("CDROMEJECT"); + } else { + if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0) + perror("CDROMEJECT"); + } +} + +static void cdrom_lock_medium(BlockDriverState *bs, bool locked) +{ + BDRVRawState *s = bs->opaque; + + if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) { + /* + * Note: an error can happen if the distribution automatically + * mounts the CD-ROM + */ + /* perror("CDROM_LOCKDOOR"); */ + } +} + +static BlockDriver bdrv_host_cdrom = { + .format_name = "host_cdrom", + .protocol_name = "host_cdrom", + .instance_size = sizeof(BDRVRawState), + .bdrv_needs_filename = true, + .bdrv_probe_device = cdrom_probe_device, + .bdrv_parse_filename = cdrom_parse_filename, + .bdrv_file_open = cdrom_open, + .bdrv_close = raw_close, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, + .bdrv_create = hdev_create, + .create_opts = &raw_create_opts, + + .bdrv_aio_readv = raw_aio_readv, + .bdrv_aio_writev = raw_aio_writev, + .bdrv_aio_flush = raw_aio_flush, + .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, + .bdrv_flush_io_queue = raw_aio_flush_io_queue, + + .bdrv_truncate = raw_truncate, + .bdrv_getlength = raw_getlength, + .has_variable_length = true, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, + + .bdrv_detach_aio_context = raw_detach_aio_context, + .bdrv_attach_aio_context = raw_attach_aio_context, + + /* removable device support */ + .bdrv_is_inserted = cdrom_is_inserted, + .bdrv_eject = cdrom_eject, + .bdrv_lock_medium = cdrom_lock_medium, + + /* generic scsi device */ + .bdrv_aio_ioctl = hdev_aio_ioctl, +}; +#endif /* __linux__ */ + +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +static int cdrom_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + BDRVRawState *s = bs->opaque; + Error *local_err = NULL; + int ret; + + s->type = FTYPE_CD; + + ret = raw_open_common(bs, options, flags, 0, &local_err); + if (ret) { + if (local_err) { + error_propagate(errp, local_err); + } + return ret; + } + + /* make sure the door isn't locked at this time */ + ioctl(s->fd, CDIOCALLOW); + return 0; +} + +static int cdrom_probe_device(const char *filename) +{ + if (strstart(filename, "/dev/cd", NULL) || + strstart(filename, "/dev/acd", NULL)) + return 100; + return 0; +} + +static int cdrom_reopen(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int fd; + + /* + * Force reread of possibly changed/newly loaded disc, + * FreeBSD seems to not notice sometimes... + */ + if (s->fd >= 0) + qemu_close(s->fd); + fd = qemu_open(bs->filename, s->open_flags, 0644); + if (fd < 0) { + s->fd = -1; + return -EIO; + } + s->fd = fd; + + /* make sure the door isn't locked at this time */ + ioctl(s->fd, CDIOCALLOW); + return 0; +} + +static bool cdrom_is_inserted(BlockDriverState *bs) +{ + return raw_getlength(bs) > 0; +} + +static void cdrom_eject(BlockDriverState *bs, bool eject_flag) +{ + BDRVRawState *s = bs->opaque; + + if (s->fd < 0) + return; + + (void) ioctl(s->fd, CDIOCALLOW); + + if (eject_flag) { + if (ioctl(s->fd, CDIOCEJECT) < 0) + perror("CDIOCEJECT"); + } else { + if (ioctl(s->fd, CDIOCCLOSE) < 0) + perror("CDIOCCLOSE"); + } + + cdrom_reopen(bs); +} + +static void cdrom_lock_medium(BlockDriverState *bs, bool locked) +{ + BDRVRawState *s = bs->opaque; + + if (s->fd < 0) + return; + if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) { + /* + * Note: an error can happen if the distribution automatically + * mounts the CD-ROM + */ + /* perror("CDROM_LOCKDOOR"); */ + } +} + +static BlockDriver bdrv_host_cdrom = { + .format_name = "host_cdrom", + .protocol_name = "host_cdrom", + .instance_size = sizeof(BDRVRawState), + .bdrv_needs_filename = true, + .bdrv_probe_device = cdrom_probe_device, + .bdrv_parse_filename = cdrom_parse_filename, + .bdrv_file_open = cdrom_open, + .bdrv_close = raw_close, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, + .bdrv_create = hdev_create, + .create_opts = &raw_create_opts, + + .bdrv_aio_readv = raw_aio_readv, + .bdrv_aio_writev = raw_aio_writev, + .bdrv_aio_flush = raw_aio_flush, + .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, + .bdrv_flush_io_queue = raw_aio_flush_io_queue, + + .bdrv_truncate = raw_truncate, + .bdrv_getlength = raw_getlength, + .has_variable_length = true, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, + + .bdrv_detach_aio_context = raw_detach_aio_context, + .bdrv_attach_aio_context = raw_attach_aio_context, + + /* removable device support */ + .bdrv_is_inserted = cdrom_is_inserted, + .bdrv_eject = cdrom_eject, + .bdrv_lock_medium = cdrom_lock_medium, +}; +#endif /* __FreeBSD__ */ + +static void bdrv_file_init(void) +{ + /* + * Register all the drivers. Note that order is important, the driver + * registered last will get probed first. + */ + bdrv_register(&bdrv_file); + bdrv_register(&bdrv_host_device); +#ifdef __linux__ + bdrv_register(&bdrv_host_cdrom); +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + bdrv_register(&bdrv_host_cdrom); +#endif +} + +block_init(bdrv_file_init); diff --git a/configure b/configure index 23b5e93752b6a..6aa07f3a6c53f 100755 --- a/configure +++ b/configure @@ -490,6 +490,7 @@ tpm="" libssh="" live_block_migration="yes" numa="" +mouse="yes" tcmalloc="no" jemalloc="no" replication="yes" @@ -1497,9 +1498,13 @@ for opt do ;; --enable-numa) numa="yes" ;; +<<<<<<< HEAD --disable-libxml2) libxml2="no" ;; --enable-libxml2) libxml2="yes" +======= + --disable-mouse) mouse="no" +>>>>>>> 919b29ba7d... Pebble Qemu ;; --disable-tcmalloc) tcmalloc="no" ;; @@ -6251,6 +6256,13 @@ case "$slirp" in esac +########################################## +# check for mouse support + +if test "$mouse" = "no"; then + CFLAGS="-DNO_MOUSE $CFLAGS" +fi + ########################################## # End of CC checks # After here, no more $cc or $ld runs @@ -6713,6 +6725,7 @@ echo "NUMA host support $numa" echo "libxml2 $libxml2" echo "tcmalloc support $tcmalloc" echo "jemalloc support $jemalloc" +<<<<<<< HEAD echo "avx2 optimization $avx2_opt" echo "avx512f optimization $avx512f_opt" echo "replication support $replication" @@ -6746,6 +6759,9 @@ if test "$supported_cpu" = "no"; then echo "if you care about QEMU on this platform you should contact" echo "us upstream at qemu-devel@nongnu.org." fi +======= +echo "Mouse support $mouse" +>>>>>>> 919b29ba7d... Pebble Qemu if test "$supported_os" = "no"; then echo diff --git a/crypto/tlssession.c b/crypto/tlssession.c index 33203e8ca711d..a5f8ec16c4dfb 100644 --- a/crypto/tlssession.c +++ b/crypto/tlssession.c @@ -227,7 +227,8 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds, goto error; } - if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { + if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER && + creds->verifyPeer) { /* This requests, but does not enforce a client cert. * The cert checking code later does enforcement */ gnutls_certificate_server_set_request(session->handle, diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 36a0e89daae27..71eac79b5ca21 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -1,7 +1,51 @@ # Default configuration for arm-softmmu +<<<<<<< HEAD # TODO: ARM_V7M is currently always required - make this more flexible! CONFIG_ARM_V7M=y +======= +include pci.mak +include usb.mak +CONFIG_VGA=y +CONFIG_ISA_MMIO=y +CONFIG_NAND=y +CONFIG_ECC=y +CONFIG_SERIAL=y +CONFIG_PTIMER=y +CONFIG_SD=y +CONFIG_MAX7310=y +CONFIG_WM8750=y +CONFIG_TWL92230=y +CONFIG_TSC2005=y +CONFIG_LM832X=y +CONFIG_TMP105=y +CONFIG_STELLARIS=y +CONFIG_STELLARIS_INPUT=y +CONFIG_STELLARIS_ENET=y +CONFIG_STM32=y +CONFIG_SSD0303=y +CONFIG_SSD0323=y +CONFIG_LS013B7DH01=y +CONFIG_PEBBLE_SNOWY_DISPLAY=y +CONFIG_ADS7846=y +CONFIG_MAX111X=y +CONFIG_SSI=y +CONFIG_SSI_SD=y +CONFIG_SSI_M25P80=y +CONFIG_LAN9118=y +CONFIG_SMC91C111=y +CONFIG_ALLWINNER_EMAC=y +CONFIG_IMX_FEC=y +CONFIG_DS1338=y +CONFIG_PFLASH_CFI01=y +CONFIG_PFLASH_CFI02=y +CONFIG_PFLASH_JEDEC_424=y +CONFIG_MICRODRIVE=y +CONFIG_USB=y +CONFIG_USB_MUSB=y +CONFIG_USB_EHCI_SYSBUS=y +CONFIG_PLATFORM_BUS=y +>>>>>>> 919b29ba7d... Pebble Qemu # CONFIG_PCI_DEVICES=n # CONFIG_TEST_DEVICES=n diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt new file mode 100644 index 0000000000000..5a89004c22e08 --- /dev/null +++ b/docs/qapi-code-gen.txt @@ -0,0 +1,1183 @@ += How to use the QAPI code generator = + +Copyright IBM Corp. 2011 +Copyright (C) 2012-2015 Red Hat, Inc. + +This work is licensed under the terms of the GNU GPL, version 2 or +later. See the COPYING file in the top-level directory. + +== Introduction == + +QAPI is a native C API within QEMU which provides management-level +functionality to internal and external users. For external +users/processes, this interface is made available by a JSON-based wire +format for the QEMU Monitor Protocol (QMP) for controlling qemu, as +well as the QEMU Guest Agent (QGA) for communicating with the guest. +The remainder of this document uses "Client JSON Protocol" when +referring to the wire contents of a QMP or QGA connection. + +To map Client JSON Protocol interfaces to the native C QAPI +implementations, a JSON-based schema is used to define types and +function signatures, and a set of scripts is used to generate types, +signatures, and marshaling/dispatch code. This document will describe +how the schemas, scripts, and resulting code are used. + + +== QMP/Guest agent schema == + +A QAPI schema file is designed to be loosely based on JSON +(http://www.ietf.org/rfc/rfc7159.txt) with changes for quoting style +and the use of comments; a QAPI schema file is then parsed by a python +code generation program. A valid QAPI schema consists of a series of +top-level expressions, with no commas between them. Where +dictionaries (JSON objects) are used, they are parsed as python +OrderedDicts so that ordering is preserved (for predictable layout of +generated C structs and parameter lists). Ordering doesn't matter +between top-level expressions or the keys within an expression, but +does matter within dictionary values for 'data' and 'returns' members +of a single expression. QAPI schema input is written using 'single +quotes' instead of JSON's "double quotes" (in contrast, Client JSON +Protocol uses no comments, and while input accepts 'single quotes' as +an extension, output is strict JSON using only "double quotes"). As +in JSON, trailing commas are not permitted in arrays or dictionaries. +Input must be ASCII (although QMP supports full Unicode strings, the +QAPI parser does not). At present, there is no place where a QAPI +schema requires the use of JSON numbers or null. + +Comments are allowed; anything between an unquoted # and the following +newline is ignored. Although there is not yet a documentation +generator, a form of stylized comments has developed for consistently +documenting details about an expression and when it was added to the +schema. The documentation is delimited between two lines of ##, then +the first line names the expression, an optional overview is provided, +then individual documentation about each member of 'data' is provided, +and finally, a 'Since: x.y.z' tag lists the release that introduced +the expression. Optional fields are tagged with the phrase +'#optional', often with their default value; and extensions added +after the expression was first released are also given a '(since +x.y.z)' comment. For example: + + ## + # @BlockStats: + # + # Statistics of a virtual block device or a block backing device. + # + # @device: #optional If the stats are for a virtual block device, the name + # corresponding to the virtual block device. + # + # @stats: A @BlockDeviceStats for the device. + # + # @parent: #optional This describes the file block device if it has one. + # + # @backing: #optional This describes the backing block device if it has one. + # (Since 2.0) + # + # Since: 0.14.0 + ## + { 'struct': 'BlockStats', + 'data': {'*device': 'str', 'stats': 'BlockDeviceStats', + '*parent': 'BlockStats', + '*backing': 'BlockStats'} } + +The schema sets up a series of types, as well as commands and events +that will use those types. Forward references are allowed: the parser +scans in two passes, where the first pass learns all type names, and +the second validates the schema and generates the code. This allows +the definition of complex structs that can have mutually recursive +types, and allows for indefinite nesting of Client JSON Protocol that +satisfies the schema. A type name should not be defined more than +once. It is permissible for the schema to contain additional types +not used by any commands or events in the Client JSON Protocol, for +the side effect of generated C code used internally. + +There are seven top-level expressions recognized by the parser: +'include', 'command', 'struct', 'enum', 'union', 'alternate', and +'event'. There are several groups of types: simple types (a number of +built-in types, such as 'int' and 'str'; as well as enumerations), +complex types (structs and two flavors of unions), and alternate types +(a choice between other types). The 'command' and 'event' expressions +can refer to existing types by name, or list an anonymous type as a +dictionary. Listing a type name inside an array refers to a +single-dimension array of that type; multi-dimension arrays are not +directly supported (although an array of a complex struct that +contains an array member is possible). + +Types, commands, and events share a common namespace. Therefore, +generally speaking, type definitions should always use CamelCase for +user-defined type names, while built-in types are lowercase. Type +definitions should not end in 'Kind', as this namespace is used for +creating implicit C enums for visiting union types, or in 'List', as +this namespace is used for creating array types. Command names, +and field names within a type, should be all lower case with words +separated by a hyphen. However, some existing older commands and +complex types use underscore; when extending such expressions, +consistency is preferred over blindly avoiding underscore. Event +names should be ALL_CAPS with words separated by underscore. Field +names cannot start with 'has-' or 'has_', as this is reserved for +tracking optional fields. + +Any name (command, event, type, field, or enum value) beginning with +"x-" is marked experimental, and may be withdrawn or changed +incompatibly in a future release. Downstream vendors may add +extensions; such extensions should begin with a prefix matching +"__RFQDN_" (for the reverse-fully-qualified-domain-name of the +vendor), even if the rest of the name uses dash (example: +__com.redhat_drive-mirror). Other than downstream extensions (with +leading underscore and the use of dots), all names should begin with a +letter, and contain only ASCII letters, digits, dash, and underscore. +Names beginning with 'q_' are reserved for the generator: QMP names +that resemble C keywords or other problematic strings will be munged +in C to use this prefix. For example, a field named "default" in +qapi becomes "q_default" in the generated C code. + +In the rest of this document, usage lines are given for each +expression type, with literal strings written in lower case and +placeholders written in capitals. If a literal string includes a +prefix of '*', that key/value pair can be omitted from the expression. +For example, a usage statement that includes '*base':STRUCT-NAME +means that an expression has an optional key 'base', which if present +must have a value that forms a struct name. + +There are seven top-level expressions recognized by the parser: +'include', 'command', 'struct', 'enum', 'union', 'alternate', and +'event'. There are several groups of types: simple types (a number of +built-in types, such as 'int' and 'str'; as well as enumerations), +complex types (structs and two flavors of unions), and alternate types +(a choice between other types). The 'command' and 'event' expressions +can refer to existing types by name, or list an anonymous type as a +dictionary. Listing a type name inside an array refers to a +single-dimension array of that type; multi-dimension arrays are not +directly supported (although an array of a complex struct that +contains an array member is possible). + +Types, commands, and events share a common namespace. Therefore, +generally speaking, type definitions should always use CamelCase for +user-defined type names, while built-in types are lowercase. Type +definitions should not end in 'Kind', as this namespace is used for +creating implicit C enums for visiting union types. Command names, +and field names within a type, should be all lower case with words +separated by a hyphen. However, some existing older commands and +complex types use underscore; when extending such expressions, +consistency is preferred over blindly avoiding underscore. Event +names should be ALL_CAPS with words separated by underscore. The +special string '**' appears for some commands that manually perform +their own type checking rather than relying on the type-safe code +produced by the qapi code generators. + +Any name (command, event, type, field, or enum value) beginning with +"x-" is marked experimental, and may be withdrawn or changed +incompatibly in a future release. Downstream vendors may add +extensions; such extensions should begin with a prefix matching +"__RFQDN_" (for the reverse-fully-qualified-domain-name of the +vendor), even if the rest of the name uses dash (example: +__com.redhat_drive-mirror). Other than downstream extensions (with +leading underscore and the use of dots), all names should begin with a +letter, and contain only ASCII letters, digits, dash, and underscore. +It is okay to reuse names that match C keywords; the generator will +rename a field named "default" in the QAPI to "q_default" in the +generated C code. + +In the rest of this document, usage lines are given for each +expression type, with literal strings written in lower case and +placeholders written in capitals. If a literal string includes a +prefix of '*', that key/value pair can be omitted from the expression. +For example, a usage statement that includes '*base':STRUCT-NAME +means that an expression has an optional key 'base', which if present +must have a value that forms a struct name. + + +=== Built-in Types === + +The following types are predefined, and map to C as follows: + + Schema C JSON + str char * any JSON string, UTF-8 + number double any JSON number + int int64_t a JSON number without fractional part + that fits into the C integer type + int8 int8_t likewise + int16 int16_t likewise + int32 int32_t likewise + int64 int64_t likewise + uint8 uint8_t likewise + uint16 uint16_t likewise + uint32 uint32_t likewise + uint64 uint64_t likewise + size uint64_t like uint64_t, except StringInputVisitor + accepts size suffixes + bool bool JSON true or false + any QObject * any JSON value + + +=== Includes === + +Usage: { 'include': STRING } + +The QAPI schema definitions can be modularized using the 'include' directive: + + { 'include': 'path/to/file.json' } + +The directive is evaluated recursively, and include paths are relative to the +file using the directive. Multiple includes of the same file are +idempotent. No other keys should appear in the expression, and the include +value should be a string. + +As a matter of style, it is a good idea to have all files be +self-contained, but at the moment, nothing prevents an included file +from making a forward reference to a type that is only introduced by +an outer file. The parser may be made stricter in the future to +prevent incomplete include files. + +As a matter of style, it is a good idea to have all files be +self-contained, but at the moment, nothing prevents an included file +from making a forward reference to a type that is only introduced by +an outer file. The parser may be made stricter in the future to +prevent incomplete include files. + +=== Struct types === + +Usage: { 'struct': STRING, 'data': DICT, '*base': STRUCT-NAME } + +A struct is a dictionary containing a single 'data' key whose +value is a dictionary. This corresponds to a struct in C or an Object +in JSON. Each value of the 'data' dictionary must be the name of a +type, or a one-element array containing a type name. An example of a +struct is: + + { 'struct': 'MyType', + + { 'struct': 'MyType', + 'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } } + +The use of '*' as a prefix to the name means the member is optional in +the corresponding JSON protocol usage. + +The default initialization value of an optional argument should not be changed +between versions of QEMU unless the new default maintains backward +compatibility to the user-visible behavior of the old default. + +With proper documentation, this policy still allows some flexibility; for +example, documenting that a default of 0 picks an optimal buffer size allows +one release to declare the optimal size at 512 while another release declares +the optimal size at 4096 - the user-visible behavior is not the bytes used by +the buffer, but the fact that the buffer was optimal size. + +On input structures (only mentioned in the 'data' side of a command), changing +from mandatory to optional is safe (older clients will supply the option, and +newer clients can benefit from the default); changing from optional to +mandatory is backwards incompatible (older clients may be omitting the option, +and must continue to work). + +On output structures (only mentioned in the 'returns' side of a command), +changing from mandatory to optional is in general unsafe (older clients may be +expecting the field, and could crash if it is missing), although it can be done +if the only way that the optional argument will be omitted is when it is +triggered by the presence of a new input flag to the command that older clients +don't know to send. Changing from optional to mandatory is safe. + +A structure that is used in both input and output of various commands +must consider the backwards compatibility constraints of both directions +of use. + +A struct definition can specify another struct as its base. +In this case, the fields of the base type are included as top-level fields +of the new struct's dictionary in the Client JSON Protocol wire +format. An example definition is: + + { 'struct': 'BlockdevOptionsGenericFormat', 'data': { 'file': 'str' } } + { 'struct': 'BlockdevOptionsGenericCOWFormat', + 'base': 'BlockdevOptionsGenericFormat', + 'data': { '*backing': 'str' } } + +An example BlockdevOptionsGenericCOWFormat object on the wire could use +both fields like this: + + { "file": "/some/place/my-image", + "backing": "/some/place/my-backing-file" } + + +=== Enumeration types === + +Usage: { 'enum': STRING, 'data': ARRAY-OF-STRING } + { 'enum': STRING, '*prefix': STRING, 'data': ARRAY-OF-STRING } + +An enumeration type is a dictionary containing a single 'data' key +whose value is a list of strings. An example enumeration is: + + { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] } + +Nothing prevents an empty enumeration, although it is probably not +useful. The list of strings should be lower case; if an enum name +represents multiple words, use '-' between words. The string 'max' is +not allowed as an enum value, and values should not be repeated. + +The enum constants will be named by using a heuristic to turn the +type name into a set of underscore separated words. For the example +above, 'MyEnum' will turn into 'MY_ENUM' giving a constant name +of 'MY_ENUM_VALUE1' for the first value. If the default heuristic +does not result in a desirable name, the optional 'prefix' field +can be used when defining the enum. + +The enumeration values are passed as strings over the Client JSON +Protocol, but are encoded as C enum integral values in generated code. +While the C code starts numbering at 0, it is better to use explicit +comparisons to enum values than implicit comparisons to 0; the C code +will also include a generated enum member ending in _MAX for tracking +the size of the enum, useful when using common functions for +converting between strings and enum values. Since the wire format +always passes by name, it is acceptable to reorder or add new +enumeration members in any location without breaking clients of Client +JSON Protocol; however, removing enum values would break +compatibility. For any struct that has a field that will only contain +a finite set of string values, using an enum type for that field is +better than open-coding the field to be type 'str'. + + +=== Union types === + +Usage: { 'union': STRING, 'data': DICT } +or: { 'union': STRING, 'data': DICT, 'base': STRUCT-NAME, + 'discriminator': ENUM-MEMBER-OF-BASE } + +Union types are used to let the user choose between several different +variants for an object. There are two flavors: simple (no +discriminator or base), flat (both discriminator and base). A union +type is defined using a data dictionary as explained in the following +paragraphs. + +A simple union type defines a mapping from automatic discriminator +values to data types like in this example: + + { 'struct': 'FileOptions', 'data': { 'filename': 'str' } } + { 'struct': 'Qcow2Options', + 'data': { 'backing-file': 'str', 'lazy-refcounts': 'bool' } } + + { 'union': 'BlockdevOptions', + 'data': { 'file': 'FileOptions', + 'qcow2': 'Qcow2Options' } } + +In the Client JSON Protocol, a simple union is represented by a +dictionary that contains the 'type' field as a discriminator, and a +'data' field that is of the specified data type corresponding to the +discriminator value, as in these examples: + + { "type": "file", "data" : { "filename": "/some/place/my-image" } } + { "type": "qcow2", "data" : { "backing-file": "/some/place/my-image", + "lazy-refcounts": true } } + +The generated C code uses a struct containing a union. Additionally, +an implicit C enum 'NameKind' is created, corresponding to the union +'Name', for accessing the various branches of the union. No branch of +the union can be named 'max', as this would collide with the implicit +enum. The value for each branch can be of any type. + +A flat union definition specifies a struct as its base, and +avoids nesting on the wire. All branches of the union must be +complex types, and the top-level fields of the union dictionary on +the wire will be combination of fields from both the base type and the +appropriate branch type (when merging two dictionaries, there must be +no keys in common). The 'discriminator' field must be the name of an +enum-typed member of the base struct. +The following example enhances the above simple union example by +adding a common field 'readonly', renaming the discriminator to +something more applicable, and reducing the number of {} required on +the wire: + + { 'enum': 'BlockdevDriver', 'data': [ 'file', 'qcow2' ] } + { 'struct': 'BlockdevCommonOptions', + 'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } } + 'discriminator': 'driver', + 'data': { 'file': 'FileOptions', +Resulting in these JSON objects: + { "driver": "file", "readonly": true, + "filename": "/some/place/my-image" } + { "driver": "qcow2", "readonly": false, + "backing-file": "/some/place/my-image", "lazy-refcounts": true } + +Notice that in a flat union, the discriminator name is controlled by +the user, but because it must map to a base member with enum type, the +code generator can ensure that branches exist for all values of the +enum (although the order of the keys need not match the declaration of +the enum). In the resulting generated C data types, a flat union is +represented as a struct with the base member fields included directly, +and then a union of structures for each branch of the struct. + +A simple union can always be re-written as a flat union where the base +class has a single member named 'type', and where each branch of the +union has a struct with a single member named 'data'. That is, + + { 'union': 'Simple', 'data': { 'one': 'str', 'two': 'int' } } + +is identical on the wire to: + + { 'enum': 'Enum', 'data': ['one', 'two'] } + { 'struct': 'Base', 'data': { 'type': 'Enum' } } + { 'struct': 'Branch1', 'data': { 'data': 'str' } } + { 'struct': 'Branch2', 'data': { 'data': 'int' } } + { 'union': 'Flat', 'base': 'Base', 'discriminator': 'type', + 'data': { 'one': 'Branch1', 'two': 'Branch2' } } + +Notice that in a flat union, the discriminator name is controlled by +the user, but because it must map to a base member with enum type, the +code generator can ensure that branches exist for all values of the +enum (although the order of the keys need not match the declaration of +the enum). In the resulting generated C data types, a flat union is +represented as a struct with the base member fields included directly, +and then a union of structures for each branch of the struct. + +=== Alternate types === + +Usage: { 'alternate': STRING, 'data': DICT } + +An alternate type is one that allows a choice between two or more JSON +data types (string, integer, number, or object, but currently not +array) on the wire. The definition is similar to a simple union type, +where each branch of the union names a QAPI type. For example: + + { 'alternate': 'BlockRef', + { 'union': 'Flat': 'base': 'Base', 'discriminator': 'type', + 'data': { 'one': 'Branch1', 'two': 'Branch2' } } + + +=== Alternate types === + +Usage: { 'alternate': STRING, 'data': DICT } + +An alternate type is one that allows a choice between two or more JSON +data types (string, integer, number, or object, but currently not +array) on the wire. The definition is similar to a simple union type, +where each branch of the union names a QAPI type. For example: + + { 'alternate': 'BlockRef', + 'data': { 'definition': 'BlockdevOptions', + 'reference': 'str' } } + +Just like for a simple union, an implicit C enum 'NameKind' is created +to enumerate the branches for the alternate 'Name'. + +Unlike a union, the discriminator string is never passed on the wire +for the Client JSON Protocol. Instead, the value's JSON type serves +as an implicit discriminator, which in turn means that an alternate +can only express a choice between types represented differently in +JSON. If a branch is typed as the 'bool' built-in, the alternate +accepts true and false; if it is typed as any of the various numeric +built-ins, it accepts a JSON number; if it is typed as a 'str' +built-in or named enum type, it accepts a JSON string; and if it is +typed as a complex type (struct or union), it accepts a JSON object. +Two different complex types, for instance, aren't permitted, because +both are represented as a JSON object. + +The example alternate declaration above allows using both of the +following example objects: + + { "file": "my_existing_block_device_id" } + { "file": { "driver": "file", + "readonly": false, + "filename": "/tmp/mydisk.qcow2" } } + + +=== Commands === + +Usage: { 'command': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT, + '*returns': TYPE-NAME, + '*gen': false, '*success-response': false } + +Commands are defined by using a dictionary containing several members, +where three members are most common. The 'command' member is a +mandatory string, and determines the "execute" value passed in a +Client JSON Protocol command exchange. + +The 'data' argument maps to the "arguments" dictionary passed in as +part of a Client JSON Protocol command. The 'data' member is optional +and defaults to {} (an empty dictionary). If present, it must be the +string name of a complex type, or a dictionary that declares an +anonymous type with the same semantics as a 'struct' expression, with +one exception noted below when 'gen' is used. + +The 'returns' member describes what will appear in the "return" field +of a Client JSON Protocol reply on successful completion of a command. +The member is optional from the command declaration; if absent, the +"return" field will be an empty dictionary. If 'returns' is present, +it must be the string name of a complex or built-in type, a +one-element array containing the name of a complex or built-in type, +with one exception noted below when 'gen' is used. Although it is +permitted to have the 'returns' member name a built-in type or an +array of built-in types, any command that does this cannot be extended +to return additional information in the future; thus, new commands +should strongly consider returning a dictionary-based type or an array +of dictionaries, even if the dictionary only contains one field at the +present. + +All commands in Client JSON Protocol use a dictionary to report +failure, with no way to specify that in QAPI. Where the error return +is different than the usual GenericError class in order to help the +client react differently to certain error conditions, it is worth +documenting this in the comments before the command declaration. + +Some example commands: + + { 'command': 'my-first-command', + 'data': { 'arg1': 'str', '*arg2': 'str' } } + { 'struct': 'MyType', 'data': { '*value': 'str' } } + { 'command': 'my-second-command', + 'returns': [ 'MyType' ] } + +which would validate this Client JSON Protocol transaction: + + => { "execute": "my-first-command", + "arguments": { "arg1": "hello" } } + <= { "return": { } } + => { "execute": "my-second-command" } + <= { "return": [ { "value": "one" }, { } ] } + +In rare cases, QAPI cannot express a type-safe representation of a +corresponding Client JSON Protocol command. You then have to suppress +generation of a marshalling function by including a key 'gen' with +boolean value false, and instead write your own function. Please try +to avoid adding new commands that rely on this, and instead use +type-safe unions. For an example of this usage: + + { 'command': 'netdev_add', + 'data': {'type': 'str', 'id': 'str'}, + 'gen': false } + +Normally, the QAPI schema is used to describe synchronous exchanges, +where a response is expected. But in some cases, the action of a +command is expected to change state in a way that a successful +response is not possible (although the command will still return a +normal dictionary error on failure). When a successful reply is not +possible, the command expression should include the optional key +'success-response' with boolean value false. So far, only QGA makes +use of this field. +'success-response' with boolean value false. So far, only QGA makes +use of this field. + + +=== Events === + +Usage: { 'event': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT } + +Events are defined with the keyword 'event'. It is not allowed to +name an event 'MAX', since the generator also produces a C enumeration +of all event names with a generated _MAX value at the end. When +'data' is also specified, additional info will be included in the +event, with similar semantics to a 'struct' expression. Finally there +will be C API generated in qapi-event.h; when called by QEMU code, a +message with timestamp will be emitted on the wire. + +An example event is: + +{ 'event': 'EVENT_C', + 'data': { '*a': 'int', 'b': 'str' } } + +Resulting in this JSON object: + +{ "event": "EVENT_C", + "data": { "b": "test string" }, + "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } + + +== Client JSON Protocol introspection == + +Clients of a Client JSON Protocol commonly need to figure out what +exactly the server (QEMU) supports. + +For this purpose, QMP provides introspection via command +query-qmp-schema. QGA currently doesn't support introspection. + +While Client JSON Protocol wire compatibility should be maintained +between qemu versions, we cannot make the same guarantees for +introspection stability. For example, one version of qemu may provide +a non-variant optional member of a struct, and a later version rework +the member to instead be non-optional and associated with a variant. +Likewise, one version of qemu may list a member with open-ended type +'str', and a later version could convert it to a finite set of strings +via an enum type; or a member may be converted from a specific type to +an alternate that represents a choice between the original type and +something else. + +query-qmp-schema returns a JSON array of SchemaInfo objects. These +objects together describe the wire ABI, as defined in the QAPI schema. +There is no specified order to the SchemaInfo objects returned; a +client must search for a particular name throughout the entire array +to learn more about that name, but is at least guaranteed that there +will be no collisions between type, command, and event names. + +However, the SchemaInfo can't reflect all the rules and restrictions +that apply to QMP. It's interface introspection (figuring out what's +there), not interface specification. The specification is in the QAPI +schema. To understand how QMP is to be used, you need to study the +QAPI schema. + +Like any other command, query-qmp-schema is itself defined in the QAPI +schema, along with the SchemaInfo type. This text attempts to give an +overview how things work. For details you need to consult the QAPI +schema. + +SchemaInfo objects have common members "name" and "meta-type", and +additional variant members depending on the value of meta-type. + +Each SchemaInfo object describes a wire ABI entity of a certain +meta-type: a command, event or one of several kinds of type. + +SchemaInfo for commands and events have the same name as in the QAPI +schema. + +Command and event names are part of the wire ABI, but type names are +not. Therefore, the SchemaInfo for types have auto-generated +meaningless names. For readability, the examples in this section use +meaningful type names instead. + +To examine a type, start with a command or event using it, then follow +references by name. + +QAPI schema definitions not reachable that way are omitted. + +The SchemaInfo for a command has meta-type "command", and variant +members "arg-type" and "ret-type". On the wire, the "arguments" +member of a client's "execute" command must conform to the object type +named by "arg-type". The "return" member that the server passes in a +success response conforms to the type named by "ret-type". + +If the command takes no arguments, "arg-type" names an object type +without members. Likewise, if the command returns nothing, "ret-type" +names an object type without members. + +Example: the SchemaInfo for command query-qmp-schema + + { "name": "query-qmp-schema", "meta-type": "command", + "arg-type": ":empty", "ret-type": "SchemaInfoList" } + + Type ":empty" is an object type without members, and type + "SchemaInfoList" is the array of SchemaInfo type. + +The SchemaInfo for an event has meta-type "event", and variant member +"arg-type". On the wire, a "data" member that the server passes in an +event conforms to the object type named by "arg-type". + +If the event carries no additional information, "arg-type" names an +object type without members. The event may not have a data member on +the wire then. + +Each command or event defined with dictionary-valued 'data' in the +QAPI schema implicitly defines an object type. + +Example: the SchemaInfo for EVENT_C from section Events + + { "name": "EVENT_C", "meta-type": "event", + "arg-type": ":obj-EVENT_C-arg" } + + Type ":obj-EVENT_C-arg" is an implicitly defined object type with + the two members from the event's definition. + +The SchemaInfo for struct and union types has meta-type "object". + +The SchemaInfo for a struct type has variant member "members". + +The SchemaInfo for a union type additionally has variant members "tag" +and "variants". + +"members" is a JSON array describing the object's common members, if +any. Each element is a JSON object with members "name" (the member's +name), "type" (the name of its type), and optionally "default". The +member is optional if "default" is present. Currently, "default" can +only have value null. Other values are reserved for future +extensions. The "members" array is in no particular order; clients +must search the entire object when learning whether a particular +member is supported. + +Example: the SchemaInfo for MyType from section Struct types + + { "name": "MyType", "meta-type": "object", + "members": [ + { "name": "member1", "type": "str" }, + { "name": "member2", "type": "int" }, + { "name": "member3", "type": "str", "default": null } ] } + +"tag" is the name of the common member serving as type tag. +"variants" is a JSON array describing the object's variant members. +Each element is a JSON object with members "case" (the value of type +tag this element applies to) and "type" (the name of an object type +that provides the variant members for this type tag value). The +"variants" array is in no particular order, and is not guaranteed to +list cases in the same order as the corresponding "tag" enum type. + +Example: the SchemaInfo for flat union BlockdevOptions from section +Union types + + { "name": "BlockdevOptions", "meta-type": "object", + "members": [ + { "name": "driver", "type": "BlockdevDriver" }, + { "name": "readonly", "type": "bool"} ], + "tag": "driver", + "variants": [ + { "case": "file", "type": "FileOptions" }, + { "case": "qcow2", "type": "Qcow2Options" } ] } + +Note that base types are "flattened": its members are included in the +"members" array. + +A simple union implicitly defines an enumeration type for its implicit +discriminator (called "type" on the wire, see section Union types). + +A simple union implicitly defines an object type for each of its +variants. + +Example: the SchemaInfo for simple union BlockdevOptions from section +Union types + + { "name": "BlockdevOptions", "meta-type": "object", + "members": [ + { "name": "kind", "type": "BlockdevOptionsKind" } ], + "tag": "type", + "variants": [ + { "case": "file", "type": ":obj-FileOptions-wrapper" }, + { "case": "qcow2", "type": ":obj-Qcow2Options-wrapper" } ] } + + Enumeration type "BlockdevOptionsKind" and the object types + ":obj-FileOptions-wrapper", ":obj-Qcow2Options-wrapper" are + implicitly defined. + +The SchemaInfo for an alternate type has meta-type "alternate", and +variant member "members". "members" is a JSON array. Each element is +a JSON object with member "type", which names a type. Values of the +alternate type conform to exactly one of its member types. There is +no guarantee on the order in which "members" will be listed. + +Example: the SchemaInfo for BlockRef from section Alternate types + + { "name": "BlockRef", "meta-type": "alternate", + "members": [ + { "type": "BlockdevOptions" }, + { "type": "str" } ] } + +The SchemaInfo for an array type has meta-type "array", and variant +member "element-type", which names the array's element type. Array +types are implicitly defined. For convenience, the array's name may +resemble the element type; however, clients should examine member +"element-type" instead of making assumptions based on parsing member +"name". + +Example: the SchemaInfo for ['str'] + + { "name": "[str]", "meta-type": "array", + "element-type": "str" } + +The SchemaInfo for an enumeration type has meta-type "enum" and +variant member "values". The values are listed in no particular +order; clients must search the entire enum when learning whether a +particular value is supported. + +Example: the SchemaInfo for MyEnum from section Enumeration types + + { "name": "MyEnum", "meta-type": "enum", + "values": [ "value1", "value2", "value3" ] } + +The SchemaInfo for a built-in type has the same name as the type in +the QAPI schema (see section Built-in Types), with one exception +detailed below. It has variant member "json-type" that shows how +values of this type are encoded on the wire. + +Example: the SchemaInfo for str + + { "name": "str", "meta-type": "builtin", "json-type": "string" } + +The QAPI schema supports a number of integer types that only differ in +how they map to C. They are identical as far as SchemaInfo is +concerned. Therefore, they get all mapped to a single type "int" in +SchemaInfo. + +As explained above, type names are not part of the wire ABI. Not even +the names of built-in types. Clients should examine member +"json-type" instead of hard-coding names of built-in types. + + +== Code generation == + +Schemas are fed into four scripts to generate all the code/files that, +paired with the core QAPI libraries, comprise everything required to +take JSON commands read in by a Client JSON Protocol server, unmarshal +the arguments into the underlying C types, call into the corresponding +C function, and map the response back to a Client JSON Protocol +response to be returned to the user. + +As an example, we'll use the following schema, which describes a single +complex user-defined type (which will produce a C struct, along with a list +node structure that can be used to chain together a list of such types in +case we want to accept/return a list of this type with a command), and a +command which takes that type as a parameter and returns the same type: + + $ cat example-schema.json + { 'struct': 'UserDefOne', + 'data': { 'integer': 'int', 'string': 'str' } } + + { 'command': 'my-command', + 'data': {'arg1': 'UserDefOne'}, + 'returns': 'UserDefOne' } + + { 'event': 'MY_EVENT' } + +=== scripts/qapi-types.py === + +Used to generate the C types defined by a schema. The following files are +created: + +$(prefix)qapi-types.h - C types corresponding to types defined in + the schema you pass in +$(prefix)qapi-types.c - Cleanup functions for the above C types + +The $(prefix) is an optional parameter used as a namespace to keep the +generated code from one schema/code-generation separated from others so code +can be generated/used from multiple schemas without clobbering previously +created code. + +Example: + + $ python scripts/qapi-types.py --output-dir="qapi-generated" \ + --prefix="example-" example-schema.json + $ cat qapi-generated/example-qapi-types.c +[Uninteresting stuff omitted...] + + void qapi_free_UserDefOne(UserDefOne *obj) + { + QapiDeallocVisitor *qdv; + Visitor *v; + + if (!obj) { + return; + } + + qdv = qapi_dealloc_visitor_new(); + v = qapi_dealloc_get_visitor(qdv); + visit_type_UserDefOne(v, &obj, NULL, NULL); + qapi_dealloc_visitor_cleanup(qdv); + } + + void qapi_free_UserDefOneList(UserDefOneList *obj) + { + QapiDeallocVisitor *qdv; + Visitor *v; + + if (!obj) { + return; + } + + qdv = qapi_dealloc_visitor_new(); + v = qapi_dealloc_get_visitor(qdv); + visit_type_UserDefOneList(v, &obj, NULL, NULL); + qapi_dealloc_visitor_cleanup(qdv); + } + $ cat qapi-generated/example-qapi-types.h +[Uninteresting stuff omitted...] + + #ifndef EXAMPLE_QAPI_TYPES_H + #define EXAMPLE_QAPI_TYPES_H + +[Built-in types omitted...] + + typedef struct UserDefOne UserDefOne; + + typedef struct UserDefOneList UserDefOneList; + + struct UserDefOne { + int64_t integer; + char *string; + }; + + void qapi_free_UserDefOne(UserDefOne *obj); + + struct UserDefOneList { + union { + UserDefOne *value; + uint64_t padding; + }; + UserDefOneList *next; + }; + + void qapi_free_UserDefOneList(UserDefOneList *obj); + + #endif + +=== scripts/qapi-visit.py === + +Used to generate the visitor functions used to walk through and convert +a QObject (as provided by QMP) to a native C data structure and +vice-versa, as well as the visitor function used to dealloc a complex +schema-defined C type. + +The following files are generated: + +$(prefix)qapi-visit.c: visitor function for a particular C type, used + to automagically convert QObjects into the + corresponding C type and vice-versa, as well + as for deallocating memory for an existing C + type + +$(prefix)qapi-visit.h: declarations for previously mentioned visitor + functions + +Example: + + $ python scripts/qapi-visit.py --output-dir="qapi-generated" + --prefix="example-" example-schema.json + $ cat qapi-generated/example-qapi-visit.c +[Uninteresting stuff omitted...] + + static void visit_type_UserDefOne_fields(Visitor *v, UserDefOne **obj, Error **errp) + { + Error *err = NULL; + + visit_type_int(v, &(*obj)->integer, "integer", &err); + if (err) { + goto out; + } + visit_type_str(v, &(*obj)->string, "string", &err); + if (err) { + goto out; + } + + out: + error_propagate(errp, err); + } + + void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name, Error **errp) + { + Error *err = NULL; + + visit_start_struct(v, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), &err); + if (!err) { + if (*obj) { + visit_type_UserDefOne_fields(v, obj, errp); + } + visit_end_struct(v, &err); + } + error_propagate(errp, err); + } + + void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const char *name, Error **errp) + { + Error *err = NULL; + GenericList *i, **prev; + + visit_start_list(v, name, &err); + if (err) { + goto out; + } + + for (prev = (GenericList **)obj; + !err && (i = visit_next_list(v, prev, &err)) != NULL; + prev = &i) { + UserDefOneList *native_i = (UserDefOneList *)i; + visit_type_UserDefOne(v, &native_i->value, NULL, &err); + } + + error_propagate(errp, err); + err = NULL; + visit_end_list(v, &err); + out: + error_propagate(errp, err); + } + $ cat qapi-generated/example-qapi-visit.h +[Uninteresting stuff omitted...] + + #ifndef EXAMPLE_QAPI_VISIT_H + #define EXAMPLE_QAPI_VISIT_H + +[Visitors for built-in types omitted...] + + void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name, Error **errp); + void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const char *name, Error **errp); + + #endif + +=== scripts/qapi-commands.py === + +Used to generate the marshaling/dispatch functions for the commands defined +in the schema. The following files are generated: + +$(prefix)qmp-marshal.c: command marshal/dispatch functions for each + QMP command defined in the schema. Functions + generated by qapi-visit.py are used to + convert QObjects received from the wire into + function parameters, and uses the same + visitor functions to convert native C return + values to QObjects from transmission back + over the wire. + +$(prefix)qmp-commands.h: Function prototypes for the QMP commands + specified in the schema. + +Example: + + $ python scripts/qapi-commands.py --output-dir="qapi-generated" + --prefix="example-" example-schema.json + $ cat qapi-generated/example-qmp-marshal.c +[Uninteresting stuff omitted...] + + static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in, QObject **ret_out, Error **errp) + { + Error *err = NULL; + QmpOutputVisitor *qov = qmp_output_visitor_new(); + QapiDeallocVisitor *qdv; + Visitor *v; + + v = qmp_output_get_visitor(qov); + visit_type_UserDefOne(v, &ret_in, "unused", &err); + if (err) { + goto out; + } + *ret_out = qmp_output_get_qobject(qov); + + out: + error_propagate(errp, err); + qmp_output_visitor_cleanup(qov); + qdv = qapi_dealloc_visitor_new(); + v = qapi_dealloc_get_visitor(qdv); + visit_type_UserDefOne(v, &ret_in, "unused", NULL); + qapi_dealloc_visitor_cleanup(qdv); + } + + static void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp) + { + Error *err = NULL; + UserDefOne *retval; + QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args)); + QapiDeallocVisitor *qdv; + Visitor *v; + UserDefOne *arg1 = NULL; + + v = qmp_input_get_visitor(qiv); + visit_type_UserDefOne(v, &arg1, "arg1", &err); + if (err) { + goto out; + } + + retval = qmp_my_command(arg1, &err); + if (err) { + goto out; + } + + qmp_marshal_output_UserDefOne(retval, ret, &err); + + out: + error_propagate(errp, err); + qmp_input_visitor_cleanup(qiv); + qdv = qapi_dealloc_visitor_new(); + v = qapi_dealloc_get_visitor(qdv); + visit_type_UserDefOne(v, &arg1, "arg1", NULL); + qapi_dealloc_visitor_cleanup(qdv); + } + + static void qmp_init_marshal(void) + { + qmp_register_command("my-command", qmp_marshal_my_command, QCO_NO_OPTIONS); + } + + qapi_init(qmp_init_marshal); + $ cat qapi-generated/example-qmp-commands.h +[Uninteresting stuff omitted...] + + #ifndef EXAMPLE_QMP_COMMANDS_H + #define EXAMPLE_QMP_COMMANDS_H + + #include "example-qapi-types.h" + #include "qapi/qmp/qdict.h" + #include "qapi/error.h" + + UserDefOne *qmp_my_command(UserDefOne *arg1, Error **errp); + + #endif + +=== scripts/qapi-event.py === + +Used to generate the event-related C code defined by a schema. The +following files are created: + +$(prefix)qapi-event.h - Function prototypes for each event type, plus an + enumeration of all event names +$(prefix)qapi-event.c - Implementation of functions to send an event + +Example: + + $ python scripts/qapi-event.py --output-dir="qapi-generated" + --prefix="example-" example-schema.json + $ cat qapi-generated/example-qapi-event.c +[Uninteresting stuff omitted...] + + void qapi_event_send_my_event(Error **errp) + { + QDict *qmp; + Error *err = NULL; + QMPEventFuncEmit emit; + emit = qmp_event_get_func_emit(); + if (!emit) { + return; + } + + qmp = qmp_event_build_dict("MY_EVENT"); + + emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp, &err); + + error_propagate(errp, err); + QDECREF(qmp); + } + + const char *const example_QAPIEvent_lookup[] = { + [EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT", + [EXAMPLE_QAPI_EVENT_MAX] = NULL, + }; + $ cat qapi-generated/example-qapi-event.h +[Uninteresting stuff omitted...] + + #ifndef EXAMPLE_QAPI_EVENT_H + #define EXAMPLE_QAPI_EVENT_H + + #include "qapi/error.h" + #include "qapi/qmp/qdict.h" + #include "example-qapi-types.h" + + + void qapi_event_send_my_event(Error **errp); + + typedef enum example_QAPIEvent { + EXAMPLE_QAPI_EVENT_MY_EVENT = 0, + EXAMPLE_QAPI_EVENT_MAX = 1, + } example_QAPIEvent; + + extern const char *const example_QAPIEvent_lookup[]; + + #endif + +=== scripts/qapi-introspect.py === + +Used to generate the introspection C code for a schema. The following +files are created: + +$(prefix)qmp-introspect.c - Defines a string holding a JSON + description of the schema. +$(prefix)qmp-introspect.h - Declares the above string. + +Example: + + $ python scripts/qapi-introspect.py --output-dir="qapi-generated" + --prefix="example-" example-schema.json + $ cat qapi-generated/example-qmp-introspect.c +[Uninteresting stuff omitted...] + + const char example_qmp_schema_json[] = "[" + "{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, " + "{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"2\"}, " + "{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, " + "{\"members\": [{\"name\": \"arg1\", \"type\": \"2\"}], \"meta-type\": \"object\", \"name\": \"1\"}, " + "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, " + "{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": \"int\"}, " + "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}]"; + $ cat qapi-generated/example-qmp-introspect.h +[Uninteresting stuff omitted...] + + #ifndef EXAMPLE_QMP_INTROSPECT_H + #define EXAMPLE_QMP_INTROSPECT_H + + extern const char example_qmp_schema_json[]; + + #endif diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 534a6a119e5d7..96ff08bfff015 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -43,6 +43,7 @@ obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o +<<<<<<< HEAD obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o aspeed_ast2600.o obj-$(CONFIG_MPS2) += mps2.o @@ -54,3 +55,24 @@ obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o obj-$(CONFIG_NRF51_SOC) += nrf51_soc.o +======= + +obj-y += stm32.o stm32_rcc.o stm32_clktree.o stm32_p103.o +obj-y += stm32f1xx.o stm32f2xx.o stm32f4xx.o stm32f7xx.o stm32_flash.o +obj-y += stm32f1xx_rcc.o stm32f2xx_rcc.o +obj-y += stm32f2xx_gpio.o stm32f2xx_adc.o +obj-y += stm32_exti.o stm32f2xx_syscfg.o +obj-y += stm32f2xx_rtc.o +obj-y += stm32f2xx_flash.o +obj-y += stm32f2xx_dummy.o +obj-y += stm32f2xx_tim.o stm32f7xx_lptim.o +obj-y += stm32f2xx_i2c.o stm32f7xx_i2c.o +obj-y += stm32f2xx_crc.o +obj-y += stm32f2xx_dma.o +obj-y += stm32f2xx_pwr.o +obj-y += pebble.o +obj-y += pebble_control.o +obj-y += pebble_robert.o +obj-y += pebble_silk.o + +>>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 7531b97ccd3ee..32c35843c70a2 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -12,7 +12,12 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/sysbus.h" +<<<<<<< HEAD #include "hw/arm/boot.h" +======= +#include "hw/arm/arm.h" +#include "hw/arm/stm32.h" +>>>>>>> 919b29ba7d... Pebble Qemu #include "hw/loader.h" #include "hw/qdev-properties.h" #include "elf.h" @@ -269,6 +274,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp) } } +<<<<<<< HEAD static Property armv7m_properties[] = { DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type), DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION, @@ -289,6 +295,27 @@ static void armv7m_class_init(ObjectClass *klass, void *data) dc->realize = armv7m_realize; device_class_set_props(dc, armv7m_properties); +======= +static void armv7m_bitband_init(Object *parent) +{ + DeviceState *dev; + + dev = qdev_create(NULL, TYPE_BITBAND); + qdev_prop_set_uint32(dev, "base", 0x20000000); + if(parent) { + object_property_add_child(parent, "bitband-sram", OBJECT(dev), NULL); + } + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x22000000); + + dev = qdev_create(NULL, TYPE_BITBAND); + qdev_prop_set_uint32(dev, "base", 0x40000000); + if(parent) { + object_property_add_child(parent, "bitband-periph", OBJECT(dev), NULL); + } + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x42000000); +>>>>>>> 919b29ba7d... Pebble Qemu } static const TypeInfo armv7m_info = { @@ -306,15 +333,121 @@ static void armv7m_reset(void *opaque) cpu_reset(CPU(cpu)); } +<<<<<<< HEAD void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) { +======= +/* Init CPU and memory for a v7-M based board. + flash_size and sram_size are in bytes. + Returns the NVIC array. */ + + +DeviceState *armv7m_init(Object *parent, MemoryRegion *system_memory, + int flash_size, int sram_size, int num_irq, + const char *kernel_filename, const char *cpu_model) +{ + ARMCPU *cpu; + return armv7m_translated_init(parent, system_memory, flash_size, sram_size, num_irq, + kernel_filename, NULL, NULL, cpu_model, &cpu); +} + +DeviceState *armv7m_translated_init(Object *parent, MemoryRegion *system_memory, + int flash_size, int sram_size, int num_irq, + const char *kernel_filename, + uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, + const char *cpu_model, + ARMCPU **cpu_device) +{ + ARMCPU *cpu; + CPUARMState *env; + DeviceState *nvic; + if (num_irq == 0) { + num_irq = STM32_MAX_IRQ + 1; + } +>>>>>>> 919b29ba7d... Pebble Qemu int image_size; uint64_t entry; uint64_t lowaddr; int big_endian; +<<<<<<< HEAD AddressSpace *as; int asidx; CPUState *cs = CPU(cpu); +======= + MemoryRegion *hack = g_new(MemoryRegion, 1); + MemoryRegion *flash = NULL; + MemoryRegion *sram = g_new(MemoryRegion, 1); + ObjectClass *cpu_oc; + Error *err = NULL; + + if (kernel_filename) { + flash = g_new(MemoryRegion, 1); + } + + if (cpu_model == NULL) { + cpu_model = "cortex-m3"; + } + cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); + cpu = ARM_CPU(object_new(object_class_get_name(cpu_oc))); + if (cpu == NULL) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + /* On Cortex-M3/M4, the MPU has 8 windows */ + object_property_set_int(OBJECT(cpu), 8, "pmsav7-dregion", &err); + if (err) { + error_report_err(err); + exit(1); + } + object_property_set_bool(OBJECT(cpu), true, "realized", &err); + if (err) { + error_report_err(err); + exit(1); + } + *cpu_device = cpu; + env = &cpu->env; + + if (kernel_filename) { + memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size, &err); + vmstate_register_ram_global(flash); + memory_region_set_readonly(flash, true); + memory_region_add_subregion(system_memory, 0, flash); + } + + if (sram_size) { + memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size, &err); + vmstate_register_ram_global(sram); + memory_region_add_subregion(system_memory, 0x20000000, sram); + } + armv7m_bitband_init(parent); + + /* If this is an M4, create the core-coupled memory region */ + if (!strcmp(cpu_model, "cortex-m4")) { + MemoryRegion *ccm = g_new(MemoryRegion, 1); + memory_region_init_ram(ccm, NULL, "armv7m.ccm", 64 * 1024 /* 64K */, &err); + vmstate_register_ram_global(ccm); + memory_region_add_subregion(system_memory, 0x10000000, ccm); + } + + nvic = qdev_create(NULL, "armv7m_nvic"); + qdev_prop_set_uint32(nvic, "num-irq", num_irq); + env->nvic = nvic; + if(parent) { + object_property_add_child(parent, "nvic", OBJECT(nvic), NULL); + } + qdev_init_nofail(nvic); + + // Connect the nvic's CPU #0 "parent_irq" output to the CPU's IRQ input handler + sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, + qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ)); +>>>>>>> 919b29ba7d... Pebble Qemu + + // Connect the nvic's "wakeup_out" output to the CPU's WKUP input handler + qemu_irq cpu_wakeup_in = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_WKUP); + qdev_connect_gpio_out_named(DEVICE(nvic), "wakeup_out", 0, cpu_wakeup_in); + + #ifdef TARGET_WORDS_BIGENDIAN big_endian = 1; @@ -322,6 +455,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) big_endian = 0; #endif +<<<<<<< HEAD if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { asidx = ARMASIdx_S; } else { @@ -336,6 +470,13 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) if (image_size < 0) { image_size = load_image_targphys_as(kernel_filename, 0, mem_size, as); +======= + if (kernel_filename) { + image_size = load_elf(kernel_filename, translate_fn, translate_opaque, &entry, &lowaddr, + NULL, big_endian, EM_ARM, 1); + if (image_size < 0) { + image_size = load_image_targphys(kernel_filename, 0, flash_size); +>>>>>>> 919b29ba7d... Pebble Qemu lowaddr = 0; } if (image_size < 0) { diff --git a/hw/arm/pebble.c b/hw/arm/pebble.c new file mode 100644 index 0000000000000..4c1c6d8c77e6f --- /dev/null +++ b/hw/arm/pebble.c @@ -0,0 +1,682 @@ +/*- + * Copyright (c) 2013, 2014 + * + * 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 "hw/ssi.h" +#include "hw/boards.h" +#include "hw/block/flash.h" +#include "sysemu/sysemu.h" +#include "sysemu/blockdev.h" +#include "ui/console.h" +#include "pebble_control.h" +#include "pebble.h" + +// Disable jiggling the display when Pebble vibration is on. +//#define PEBBLE_NO_DISPLAY_VIBRATE + +//#define DEBUG_PEBBLE +#ifdef DEBUG_PEBBLE +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("DEBUG_PEBBLE: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +const static PblBoardConfig s_board_config_bb2_ev1_ev2 = { + .dbgserial_uart_index = 2, // USART3 + .pebble_control_uart_index = 1, // USART2 + .button_map = { + {STM32_GPIOC_INDEX, 3}, // back + {STM32_GPIOA_INDEX, 2}, // up + {STM32_GPIOC_INDEX, 6}, // select + {STM32_GPIOA_INDEX, 1}, // down + }, + .flash_size = 4096, /* Kbytes - larger to aid in development and debugging */ + .ram_size = 128, /* Kbytes */ + .num_rows = 172, /* not currently used */ + .num_cols = 148, /* not currently used */ + .num_border_rows = 2, /* not currently used */ + .num_border_cols = 2, /* not currently used */ + .row_major = false, /* not currently used */ + .row_inverted = false, /* not currently used */ + .col_inverted = false, /* not currently used */ + .round_mask = false /* not currently used */ +}; + +const static PblBoardConfig s_board_config_bigboard = { + .dbgserial_uart_index = 2, // USART3 + .pebble_control_uart_index = 1, // USART2 + .button_map = { + {STM32_GPIOA_INDEX, 2}, // back + {STM32_GPIOA_INDEX, 1}, // up + {STM32_GPIOA_INDEX, 3}, // select + {STM32_GPIOC_INDEX, 9}, // down + }, + .flash_size = 4096, /* Kbytes - larger to aid in development and debugging */ + .ram_size = 128, /* Kbytes */ + .num_rows = 172, /* not currently used */ + .num_cols = 148, /* not currently used */ + .num_border_rows = 2, /* not currently used */ + .num_border_cols = 2, /* not currently used */ + .row_major = false, /* not currently used */ + .row_inverted = false, /* not currently used */ + .col_inverted = false, /* not currently used */ + .round_mask = false /* not currently used */ +}; + +const static PblBoardConfig s_board_config_snowy_bb = { + .dbgserial_uart_index = 2, // USART3 + .pebble_control_uart_index = 1, // USART2 + .button_map = { + {STM32_GPIOG_INDEX, 4}, // back + {STM32_GPIOG_INDEX, 3}, // up + {STM32_GPIOG_INDEX, 1}, // select + {STM32_GPIOG_INDEX, 2}, // down + }, + .flash_size = 4096, /* Kbytes - larger to aid in development and debugging */ + .ram_size = 256, /* Kbytes */ + .num_rows = 172, + .num_cols = 148, + .num_border_rows = 2, + .num_border_cols = 2, + .row_major = false, + .row_inverted = true, + .col_inverted = false, + .round_mask = false +}; + +const static PblBoardConfig s_board_config_s4_bb = { + .dbgserial_uart_index = 2, // USART3 + .pebble_control_uart_index = 1, // USART2 + .button_map = { + {STM32_GPIOG_INDEX, 4}, + {STM32_GPIOG_INDEX, 3}, + {STM32_GPIOG_INDEX, 1}, + {STM32_GPIOG_INDEX, 2}, + }, + .flash_size = 4096, /* Kbytes - larger to aid in development and debugging */ + .ram_size = 256, /* Kbytes */ + .num_rows = 180, + .num_cols = 180, + .num_border_rows = 0, + .num_border_cols = 0, + .row_major = true, + .row_inverted = false, + .col_inverted = false, + .round_mask = true +}; + +// ---------------------------------------------------------------------------------------- +// Static globals +static PblButtonID s_waiting_key_up_id = PBL_BUTTON_ID_NONE; +static QEMUTimer *s_button_timer; + +// This is the instance of pebble_control that intercepts packets sent to the emulated +// pebble over uart 2 +static PebbleControl *s_pebble_control; + +// The irq callbacks for each button +static qemu_irq s_button_irq[PBL_NUM_BUTTONS]; +static qemu_irq s_button_wakeup; + + +static void prv_send_key_up(void *opaque) +{ + qemu_irq *button_irqs = opaque; + if (s_waiting_key_up_id == PBL_BUTTON_ID_NONE) { + /* Should never happen */ + return; + } + + DPRINTF("button %d released\n", s_waiting_key_up_id); + qemu_set_irq(button_irqs[s_waiting_key_up_id], true); + qemu_set_irq(s_button_wakeup, false); + s_waiting_key_up_id = PBL_BUTTON_ID_NONE; +} + + +// NOTE: When running using a VNC display, we alwqys get a key-up immediately after the key-down, +// even if the user is holding the key down. For long presses, this results in a series of +// quick back to back key-down, key-up callbacks. +static void pebble_key_handler(void *arg, int keycode) +{ + qemu_irq *button_irqs = arg; + static int prev_keycode; + + int pressed = (keycode & 0x80) == 0; + int button_id = PBL_BUTTON_ID_NONE; + + switch (keycode & 0x7F) { + case 16: /* Q */ + button_id = PBL_BUTTON_ID_BACK; + break; + case 17: /* W */ + button_id = PBL_BUTTON_ID_UP; + break; + case 31: /* S */ + button_id = PBL_BUTTON_ID_SELECT; + break; + case 45: /* X */ + button_id = PBL_BUTTON_ID_DOWN; + break; + case 72: /* up arrow */ + if (prev_keycode == 224) { + button_id = PBL_BUTTON_ID_UP; + } + break; + case 80: /* down arrow */ + if (prev_keycode == 224) { + button_id = PBL_BUTTON_ID_DOWN; + } + break; + case 75: /* left arrow */ + if (prev_keycode == 224) { + button_id = PBL_BUTTON_ID_BACK; + } + break; + case 77: /* right arrow */ + if (prev_keycode == 224) { + button_id = PBL_BUTTON_ID_SELECT; + } + break; + default: + break; + } + + prev_keycode = keycode; + if (button_id == PBL_BUTTON_ID_NONE || !pressed) { + /* Ignore key ups and keys we don't care about */ + return; + } + + // If this is a different key, and we are waiting for the prior one to key up, send the + // key up now + if (s_waiting_key_up_id != PBL_BUTTON_ID_NONE && button_id != s_waiting_key_up_id) { + prv_send_key_up(button_irqs); + } + + if (s_waiting_key_up_id != button_id) { + DPRINTF("button %d pressed\n", button_id); + s_waiting_key_up_id = button_id; + qemu_set_irq(button_irqs[button_id], false); // Pressed + qemu_set_irq(s_button_wakeup, true); + } + + /* Set or reschedule the timer to release the key */ + if (!s_button_timer) { + s_button_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, prv_send_key_up, button_irqs); + } + timer_mod(s_button_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 250); +} + + +// ------------------------------------------------------------------------------------------ +// This method used externally (by pebble_control) for setting a given button state +void pebble_set_button_state(uint32_t button_state) +{ + // Toggle the GPIOs to match the new button state + int button_id; + for (button_id=0; button_id < PBL_NUM_BUTTONS; button_id++) { + uint32_t mask = 1 << button_id; + qemu_set_irq(s_button_irq[button_id], !(button_state & mask)); // Set new state + } +} + + +// ------------------------------------------------------------------------------------------ +// Connect up the uarts to serial drivers that connect to the outside world +void pebble_connect_uarts(Stm32Uart *uart[], const PblBoardConfig *board_config) +{ + // This UART is used for control messages, put in our pebble_control device in between + // the qemu serial chr and the uart. This enables us to intercept and act selectively + // act on messages sent to the Pebble in QEMU before they get to it. + s_pebble_control = pebble_control_create(serial_hds[1], + uart[board_config->pebble_control_uart_index]); + + stm32_uart_connect(uart[board_config->dbgserial_uart_index], serial_hds[2], 0); +} + +void pebble_connect_uarts_stm32f7xx(Stm32F7xxUart *uart[], const PblBoardConfig *board_config) +{ + // This UART is used for control messages, put in our pebble_control device in between + // the qemu serial chr and the uart. This enables us to intercept and act selectively + // act on messages sent to the Pebble in QEMU before they get to it. + s_pebble_control = pebble_control_create_stm32f7xx(serial_hds[1], + uart[board_config->pebble_control_uart_index]); + + stm32f7xx_uart_connect(uart[board_config->dbgserial_uart_index], serial_hds[2], 0); +} + + +// ----------------------------------------------------------------------------------------- +// Init button handling +void pebble_init_buttons(Stm32Gpio *gpio[], const PblButtonMap *map) +{ + int i; + for (i = 0; i < PBL_NUM_BUTTONS; i++) { + qemu_irq irq = qdev_get_gpio_in((DeviceState *)gpio[map[i].gpio], map[i].pin); + if (map[i].active_high) { + s_button_irq[i] = qemu_irq_invert(irq); + + } else { + s_button_irq[i] = irq; + } + } + // GPIO A, pin 0 is the WKUP pin. + s_button_wakeup = qdev_get_gpio_in((DeviceState *)gpio[STM32_GPIOA_INDEX], 0); + qemu_add_kbd_event_handler(pebble_key_handler, s_button_irq); +} + + +// ---------------------------------------------------------------------------------------- +// Init the board device +DeviceState *pebble_init_board(Stm32Gpio *gpio[], qemu_irq display_vibe) +{ + // Create the board device and wire it up + DeviceState *board = qdev_create(NULL, "pebble_board"); + qdev_prop_set_ptr(board, "name", (void *)"Pebble"); + +#ifndef PEBBLE_NO_DISPLAY_VIBRATE + qdev_prop_set_ptr(board, "display_vibe", display_vibe); +#endif + + qdev_init_nofail(board); + return board; +} + +// ---------------------------------------------------------------------------------------- +// Set our QEMU specific settings to the target +void pebble_set_qemu_settings(DeviceState *rtc_dev) +{ + #define QEMU_REG_0_FIRST_BOOT_LOGIC_ENABLE 0x00000001 + #define QEMU_REG_0_START_CONNECTED 0x00000002 + #define QEMU_REG_0_START_PLUGGED_IN 0x00000004 + + // Default settings + uint32_t flags = QEMU_REG_0_START_CONNECTED; + + // Set the QEMU specific settings in the extra backup registers + char *strval; + strval = getenv("PEBBLE_QEMU_FIRST_BOOT_LOGIC_ENABLE"); + if (strval) { + // If set, allow "first boot" behavior, which displays the "Ready for Update" + // screen + if (atoi(strval)) { + flags |= QEMU_REG_0_FIRST_BOOT_LOGIC_ENABLE; + } else { + flags &= ~QEMU_REG_0_FIRST_BOOT_LOGIC_ENABLE; + } + } + + strval = getenv("PEBBLE_QEMU_START_CONNECTED"); + if (strval) { + // If set, default to bluetooth not connected + if (atoi(strval)) { + flags |= QEMU_REG_0_START_CONNECTED; + } else { + flags &= ~QEMU_REG_0_START_CONNECTED; + } + + } + + strval = getenv("PEBBLE_QEMU_START_PLUGGED_IN"); + if (strval) { + // If set, default to plugged in + if (atoi(strval)) { + flags |= QEMU_REG_0_START_PLUGGED_IN; + } else { + flags &= ~QEMU_REG_0_START_PLUGGED_IN; + } + } + + f2xx_rtc_set_extra_bkup_reg(rtc_dev, 0, flags); +} + + +// ------------------------------------------------------------------------------------------ +// Instantiate a 32f2xx based pebble +static void pebble_32f2_init(MachineState *machine, const PblBoardConfig *board_config) +{ + Stm32Gpio *gpio[STM32F2XX_GPIO_COUNT]; + Stm32Uart *uart[STM32F2XX_UART_COUNT]; + Stm32Timer *timer[STM32F2XX_TIM_COUNT]; + DeviceState *spi_flash; + DeviceState *rtc_dev; + SSIBus *spi; + struct stm32f2xx stm; + ARMCPU *cpu; + + // Note: allow for bigger flash images (4MByte) to aid in development and debugging + stm32f2xx_init( + board_config->flash_size, + board_config->ram_size, + machine->kernel_filename, + gpio, + uart, + timer, + &rtc_dev, + 8000000, /* osc_freq*/ + 32768, /* osc2_freq*/ + &stm, + &cpu); + + + // Set the Pebble specific QEMU settings on the target + pebble_set_qemu_settings(rtc_dev); + + /* SPI flash */ + spi = (SSIBus *)qdev_get_child_bus(stm.spi_dev[0], "ssi"); + spi_flash = ssi_create_slave_no_init(spi, "n25q032a11"); + qdev_init_nofail(spi_flash); + + qemu_irq cs; + cs = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOA_INDEX], 4, cs); + + + /* Display */ + spi = (SSIBus *)qdev_get_child_bus(stm.spi_dev[1], "ssi"); + DeviceState *display_dev = ssi_create_slave_no_init(spi, "sm-lcd"); + qdev_prop_set_bit(display_dev, "rotate_display", true); + qdev_init_nofail(display_dev); + + qemu_irq backlight_enable; + backlight_enable = qdev_get_gpio_in_named(display_dev, "backlight_enable", 0); + qdev_connect_gpio_out_named((DeviceState *)gpio[STM32_GPIOB_INDEX], "af", 5, + backlight_enable); + + qemu_irq backlight_level; + backlight_level = qdev_get_gpio_in_named(display_dev, "backlight_level", 0); + qdev_connect_gpio_out_named((DeviceState *)timer[2], "pwm_ratio_changed", 0, // TIM3 + backlight_level); + + qemu_irq display_power; + display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); + qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, + display_power); + + // Connect up the uarts + pebble_connect_uarts(uart, board_config); + + // Init the buttons + pebble_init_buttons(gpio, board_config->button_map); + + // Create the board device and wire it up + qemu_irq display_vibe; + display_vibe = qdev_get_gpio_in_named(display_dev, "vibe_ctl", 0); + DeviceState *board = pebble_init_board(gpio, display_vibe); + + // The GPIO from vibrate drives the vibe input on the board + qemu_irq board_vibe_in; + board_vibe_in = qdev_get_gpio_in_named(board, "pebble_board_vibe_in", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOB_INDEX], 0, board_vibe_in); +} + +// ------------------------------------------------------------------------------------------ +// Instantiate a 32f439 based pebble +void pebble_32f439_init(MachineState *machine, const PblBoardConfig *board_config) +{ + Stm32Gpio *gpio[STM32F4XX_GPIO_COUNT]; + Stm32Uart *uart[STM32F4XX_UART_COUNT]; + Stm32Timer *timer[STM32F4XX_TIM_COUNT]; + DeviceState *rtc_dev; + SSIBus *spi; + struct stm32f4xx stm; + ARMCPU *cpu; + + // Note: allow for bigger flash images (4MByte) to aid in development and debugging + stm32f4xx_init(board_config->flash_size, + board_config->ram_size, + machine->kernel_filename, + gpio, + board_config->gpio_idr_masks, + uart, + timer, + &rtc_dev, + 8000000 /*osc_freq*/, + 32768 /*osc2_freq*/, + &stm, + &cpu); + + + // Set the Pebble specific QEMU settings on the target + pebble_set_qemu_settings(rtc_dev); + + /* Storage flash (NOR-flash on Snowy) */ + const uint32_t flash_size_bytes = 16 * 1024 * 1024; /* 16 MBytes */ + const uint32_t flash_sector_size_bytes = 32 * 1024; /* 32 KBytes */ + const uint32_t bank_size_bytes = 2 * 1024 * 1024; /* 2 MBytes */ + DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 1); /* Use the 2nd -pflash drive */ + if (dinfo) { + pflash_jedec_424_register( + 0x60000000, /* flash_base*/ + NULL, /* qdev, not used */ + "mx29vs128fb", /* name */ + flash_size_bytes, /* size */ + blk_by_legacy_dinfo(dinfo), /* driver state */ + flash_sector_size_bytes, /* sector size */ + flash_size_bytes / flash_sector_size_bytes, /* number of sectors */ + bank_size_bytes, /* size of each bank */ + 2, /* width in bytes */ + 0x00c2, 0x007e, 0x0065, 0x0001, /* id: 0, 1, 2, 3 */ + 0 /* big endian */ + ); + } + + + /* --- Display ------------------------------------------------ */ + spi = (SSIBus *)qdev_get_child_bus(stm.spi_dev[5], "ssi"); + DeviceState *display_dev = ssi_create_slave_no_init(spi, "pebble-snowy-display"); + + /* Create the outputs that the display will drive and associate them with the correct + * GPIO input pins on the MCU */ + qemu_irq display_done_irq = qdev_get_gpio_in((DeviceState *)gpio[STM32_GPIOG_INDEX], 9); + qdev_prop_set_ptr(display_dev, "done_output", display_done_irq); + qemu_irq display_intn_irq = qdev_get_gpio_in((DeviceState *)gpio[STM32_GPIOG_INDEX], 10); + qdev_prop_set_ptr(display_dev, "intn_output", display_intn_irq); + + qdev_prop_set_int32(display_dev, "num_rows", board_config->num_rows); + qdev_prop_set_int32(display_dev, "num_cols", board_config->num_cols); + qdev_prop_set_int32(display_dev, "num_border_rows", board_config->num_border_rows); + qdev_prop_set_int32(display_dev, "num_border_cols", board_config->num_border_cols); + qdev_prop_set_uint8(display_dev, "row_major", board_config->row_major); + qdev_prop_set_uint8(display_dev, "row_inverted", board_config->row_inverted); + qdev_prop_set_uint8(display_dev, "col_inverted", board_config->col_inverted); + qdev_prop_set_uint8(display_dev, "round_mask", board_config->round_mask); + + qdev_init_nofail(display_dev); + + /* Connect the correct MCU GPIO outputs to the inputs on the display */ + qemu_irq display_cs; + display_cs = qdev_get_gpio_in_named(display_dev, SSI_GPIO_CS, 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOG_INDEX], 8, display_cs); + + qemu_irq display_reset; + display_reset = qdev_get_gpio_in_named(display_dev, "reset", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOG_INDEX], 15, display_reset); + + qemu_irq display_sclk; + display_sclk = qdev_get_gpio_in_named(display_dev, "sclk", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOG_INDEX], 13, display_sclk); + + qemu_irq backlight_enable; + backlight_enable = qdev_get_gpio_in_named(display_dev, + "backlight_enable", 0); + qdev_connect_gpio_out_named((DeviceState *)gpio[STM32_GPIOB_INDEX], "af", 14, + backlight_enable); + + qemu_irq backlight_level; + backlight_level = qdev_get_gpio_in_named(display_dev, + "backlight_level", 0); + qdev_connect_gpio_out_named((DeviceState *)timer[11], "pwm_ratio_changed", 0, // TIM12 + backlight_level); + + qemu_irq display_power; + display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); + qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, + display_power); + + + // Connect up the uarts + pebble_connect_uarts(uart, board_config); + + // Init the buttons + pebble_init_buttons(gpio, board_config->button_map); + + + // Create the board device and wire it up + qemu_irq display_vibe; + display_vibe = qdev_get_gpio_in_named(display_dev, "vibe_ctl", 0); + DeviceState *board = pebble_init_board(gpio, display_vibe); + + // The GPIO from vibrate drives the vibe input on the board + qemu_irq board_vibe_in; + board_vibe_in = qdev_get_gpio_in_named(board, "pebble_board_vibe_in", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOF_INDEX], 4, board_vibe_in); +} + + +// ================================================================================ +// Pebble "board" device. Used when we need to fan out a GPIO outputs to one or more other +// devices/instances +typedef struct PebbleBoard { + SysBusDevice busdev; + void *name; + + union { + void *vibe_out_irq_prop; + qemu_irq vibe_out_irq; + }; + +} PebbleBoard; + + +static void pebble_board_vibe_ctl(void *opaque, int n, int level) +{ + PebbleBoard *s = (PebbleBoard *)opaque; + assert(n == 0); + + // Tell the pebble control instance that we vibrated + pebble_control_send_vibe_notification(s_pebble_control, level != 0); + + // Tell pass onto the vibe out output as well + qemu_set_irq(s->vibe_out_irq, level); +} + + +static int pebble_board_init(SysBusDevice *dev) +{ + //PebbleBoard *s = FROM_SYSBUS(PebbleBoard, dev); + + /* This callback informs us that the vibrate is on/orr */ + qdev_init_gpio_in_named(DEVICE(dev), pebble_board_vibe_ctl, + "pebble_board_vibe_in", 1); + + return 0; +} + +static Property pebble_board_properties[] = { + DEFINE_PROP_PTR("name", PebbleBoard, name), + DEFINE_PROP_PTR("display_vibe", PebbleBoard, vibe_out_irq_prop), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pebble_board_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = pebble_board_init; + dc->props = pebble_board_properties; +} + +static const TypeInfo pebble_board_info = { + .name = "pebble_board", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(PebbleBoard), + .class_init = pebble_board_class_init, +}; + +static void pebble_board_register_types(void) +{ + type_register_static(&pebble_board_info); +} + +type_init(pebble_board_register_types) + + +// ================================================================================ +// Machines +static void pebble_bb2_init(MachineState *machine) +{ + pebble_32f2_init(machine, &s_board_config_bb2_ev1_ev2); +} + +static void pebble_bb_init(MachineState *machine) +{ + pebble_32f2_init(machine, &s_board_config_bigboard); +} + +static void pebble_snowy_init(MachineState *machine) +{ + pebble_32f439_init(machine, &s_board_config_snowy_bb); +} + +static void pebble_s4_init(MachineState *machine) +{ + pebble_32f439_init(machine, &s_board_config_s4_bb); +} + + +static void pebble_bb2_machine_init(MachineClass *mc) +{ + mc->desc = "Pebble smartwatch (bb2/ev1/ev2)"; + mc->init = pebble_bb2_init; +} + +DEFINE_MACHINE("pebble-bb2", pebble_bb2_machine_init) + +static void pebble_bb_machine_init(MachineClass *mc) +{ + mc->desc = "Pebble smartwatch (bb)"; + mc->init = pebble_bb_init; +} + +DEFINE_MACHINE("pebble-bb", pebble_bb_machine_init) + +static void pebble_snowy_bb_machine_init(MachineClass *mc) +{ + mc->desc = "Pebble smartwatch (snowy)"; + mc->init = pebble_snowy_init; +} + +DEFINE_MACHINE("pebble-snowy-bb", pebble_snowy_bb_machine_init) + +static void pebble_s4_bb_machine_init(MachineClass *mc) +{ + mc->desc = "Pebble smartwatch (s4)"; + mc->init = pebble_s4_init; +} + +DEFINE_MACHINE("pebble-s4-bb", pebble_s4_bb_machine_init) + diff --git a/hw/arm/pebble.h b/hw/arm/pebble.h new file mode 100644 index 0000000000000..80898d52c995b --- /dev/null +++ b/hw/arm/pebble.h @@ -0,0 +1,55 @@ +#include +#include +#include +#include "stm32f2xx.h" +#include "stm32f4xx.h" +#include "stm32f7xx.h" + +typedef enum { + PBL_BUTTON_ID_NONE = -1, + PBL_BUTTON_ID_BACK = 0, + PBL_BUTTON_ID_UP = 1, + PBL_BUTTON_ID_SELECT = 2, + PBL_BUTTON_ID_DOWN = 3, + PBL_NUM_BUTTONS = 4 +} PblButtonID; + +typedef struct { + int gpio; + int pin; + bool active_high; +} PblButtonMap; + +typedef struct { + int dbgserial_uart_index; + int pebble_control_uart_index; + + PblButtonMap button_map[PBL_NUM_BUTTONS]; + uint32_t gpio_idr_masks[STM32F4XX_GPIO_COUNT]; + + // memory sizes + uint32_t flash_size; + uint32_t ram_size; + // screen sizes + uint32_t num_rows; + uint32_t num_cols; + uint32_t num_border_rows; + uint32_t num_border_cols; + bool row_major; + bool row_inverted; + bool col_inverted; + bool round_mask; +} PblBoardConfig; + +void pebble_32f412_init(MachineState *machine, const PblBoardConfig *board_config); +void pebble_32f439_init(MachineState *machine, const PblBoardConfig *board_config); +void pebble_32f7xx_init(MachineState *machine, const PblBoardConfig *board_config); + +// This method used externally (by pebble_control) for setting the button state +void pebble_set_button_state(uint32_t button_state); +void pebble_set_qemu_settings(DeviceState *rtc_dev); +void pebble_connect_uarts(Stm32Uart *uart[], const PblBoardConfig *board_config); +void pebble_connect_uarts_stm32f7xx(Stm32F7xxUart *uart[], const PblBoardConfig *board_config); +void pebble_init_buttons(Stm32Gpio *gpio[], const PblButtonMap *map); +DeviceState *pebble_init_board(Stm32Gpio *gpio[], qemu_irq display_vibe); + diff --git a/hw/arm/pebble_control.c b/hw/arm/pebble_control.c new file mode 100644 index 0000000000000..f77d7b0920b4f --- /dev/null +++ b/hw/arm/pebble_control.c @@ -0,0 +1,560 @@ +/* + * Pebble "remote control" module. + * + * This device is designed to sit in between a qemu_chr module and a UART device used + * by the emulated Pebble. It intercepts the traffic being sent to the UART, looks for + * specific packets that should be interpreted by QEMU and acts upon them. For other + * types of packets, it simply passes them on through to the Pebble UART. + * + * 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 . + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "sysemu/char.h" +#include "qemu/timer.h" +#include "qemu/sockets.h" + +#include "pebble_control.h" +#include "pebble.h" + +//#define DEBUG_PEBBLE_CONTROL +#ifdef DEBUG_PEBBLE_CONTROL +#define DPRINTF(fmt, ...) \ + do { printf("PEBBLE_CONTROL: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define EPRINTF(fmt, ...) \ + do { printf("PEBBLE_CONTROL: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) + + +// ------------------------------------------------------------------------------------------ +// NOTE: The following QemuProtocol defines describe the protocol used by the host +// to control/communicate with the emulated Pebble. +#define QEMU_HEADER_SIGNATURE 0xFEED +#define QEMU_FOOTER_SIGNATURE 0xBEEF +#define QEMU_MAX_DATA_LEN 2048 + +// Every message sent over the QEMU control channel has the following header. All +// data is set in network byte order. The maximum data len (not including header or footer) +// allowed is QEMU_MAX_DATA_LEN bytes +typedef struct QEMU_PACKED { + uint16_t signature; // QEMU_HEADER_SIGNATURE + uint16_t protocol; // one of QemuProtocol + uint16_t len; // number of bytes that follow (not including this header or footer) +} QemuCommChannelHdr; + +// Every message sent over the QEMU comm channel has the following footer. +typedef struct QEMU_PACKED { + uint16_t signature; // QEMU_FOOTER_SIGNATURE +} QemuCommChannelFooter; + + +// Protocol IDs +typedef enum { + QemuProtocol_SPP = 1, + QemuProtocol_Tap = 2, + QemuProtocol_BluetoothConnection = 3, + QemuProtocol_Compass = 4, + QemuProtocol_Battery = 5, + QemuProtocol_Accel = 6, + QemuProtocol_Vibration = 7, + QemuProtocol_Button = 8 +} QemuProtocol; + + +// Structure of the data for various protocols + +// For QemuProtocol_SPP, the data is raw Pebble Protocol + +// QemuProtocol_Tap +typedef struct QEMU_PACKED { + uint8_t axis; // 0: x-axis, 1: y-axis, 2: z-axis + int8_t direction; // either +1 or -1 +} QemuProtocolTapHeader; + + +// QemuProtocol_BluetoothConnection +typedef struct QEMU_PACKED { + uint8_t connected; // true if connected +} QemuProtocolBluetoothConnectionHeader; + + +// QemuProtocol_Compass +typedef struct QEMU_PACKED { + uint32_t magnetic_heading; // 0x10000 represents 360 degress + uint8_t calib_status:8; // CompassStatus enum +} QemuProtocolCompassHeader; + + +// QemuProtocol_Battery +typedef struct QEMU_PACKED { + uint8_t battery_pct; // from 0 to 100 + uint8_t charger_connected; +} QemuProtocolBatteryHeader; + + +// QemuProtocol_Accel request (to Pebble) +//! A single accelerometer sample for all three axes +typedef struct QEMU_PACKED { + int16_t x; + int16_t y; + int16_t z; +} QemuProtocolAccelSample; +typedef struct QEMU_PACKED { + uint8_t num_samples; + QemuProtocolAccelSample samples[0]; +} QemuProtocolAccelHeader; + +// QemuProtocol_Accel response (back to host) +typedef struct QEMU_PACKED { + uint16_t avail_space; // Number of samples we can accept +} QemuProtocolAccelResponseHeader; + + +// QemuProtocol_Vibration notification (sent from Pebble to host) +typedef struct QEMU_PACKED { + uint8_t on; // non-zero if vibe is on, 0 if off +} QemuProtocolVibrationNotificationHeader; + + +// QemuProtocol_Button +typedef struct QEMU_PACKED { + // New button state. Bit x specifies the state of button x, where x is one of the + // ButtonId enum values. + uint8_t button_state; +} QemuProtocolButtonHeader; + + + +// ----------------------------------------------------------------------------------------- +// PebbleControl globals +#define PBLCONTROL_BUF_LEN (QEMU_MAX_DATA_LEN + sizeof(QemuCommChannelHdr) \ + + sizeof(QemuCommChannelFooter)) + +struct PebbleControl { + /* Inherited */ + SysBusDevice busdev; + + // The qemu_chr driver that connects to the host over a socket connection. We receive + // data from this device, interpret it, and either process it directly in here or forward + // it onto the uart in the emulated pebble. + CharDriverState *chr; + + // The uart used by the emulated Pebble. We send data to it using its IOHandler + // callbacks. Data written to the UART by the emulated Pebble gets passed onto us + // because we provide the UART device a pointer to our pebble_control_write() method. + void *uart; + IOEventHandler *uart_chr_event; + IOCanReadHandler *uart_chr_can_read; + IOReadHandler *uart_chr_read; + + + // We buffer the characters we receive from our qemu_chr receive handler here until + // we get a complete packet. From there, we can figure out if we should process it + // directly or pass it onto the target's UART + uint8_t rcv_char_buf[PBLCONTROL_BUF_LEN]; + uint32_t rcv_char_bytes; /* number of bytes avaialable in rcv_char_buf */ + + + // If we are passing a packet onto the target UART, this contains the number of bytes left + // to transfer. The bytes we are transferring are always at the front of the + // rcv_char_buf. + uint32_t target_send_bytes; + + // Timer used to wake us up to pump more data to the target + struct QEMUTimer *target_send_timer; + + // We buffer the characters the UART from the target wants to send out here. + // We only send it to the front end once we have a complete packet. This insures + // that packets we went to send out don't interrupt midstream one that the target is + // sending. + uint8_t send_char_buf[PBLCONTROL_BUF_LEN]; + uint32_t send_char_bytes; /* number of bytes avaialable in send_char_buf */ +}; + + +// Control channel handlers are defined using this structure +typedef void (*PebbleControlMessageCallback)(PebbleControl *s, const uint8_t* data, + uint32_t length); +typedef struct { + uint16_t protocol_id; + PebbleControlMessageCallback callback; +} PebbleControlMessageHandler; + + + +// ----------------------------------------------------------------------------------- +static void pebble_control_button_msg_callback(PebbleControl *s, const uint8_t *data, + uint32_t len) +{ + DPRINTF("%s: \n", __func__); + QemuProtocolButtonHeader *hdr = (QemuProtocolButtonHeader *)data; + if (len != sizeof(*hdr)) { + EPRINTF("%s: invalid packet\n", __func__); + return; + } + + DPRINTF("%s: new button state: 0x%x\n", __func__, (int)hdr->button_state); + pebble_set_button_state(hdr->button_state); +} + + + +// ----------------------------------------------------------------------------------------- +// Find handler from s_qemu_endpoints for a given protocol +static const PebbleControlMessageHandler* pebble_control_find_handler(PebbleControl *s, + uint16_t protocol_id) { + static const PebbleControlMessageHandler s_msg_endpoints[] = { + // IMPORTANT: These must be in sorted order!! + { QemuProtocol_Button, pebble_control_button_msg_callback }, + }; + + size_t i; + for (i = 0; i < ARRAY_LENGTH(s_msg_endpoints); ++i) { + const PebbleControlMessageHandler* handler = &s_msg_endpoints[i]; + if (!handler || handler->protocol_id > protocol_id) { + break; + } + + if (handler->protocol_id == protocol_id) { + return handler; + } + } + + return NULL; +} + + + + +// ----------------------------------------------------------------------------------- +// Drop the first N bytes out of the beginning of the receive buffer +static void pebble_control_consume_rcv_bytes(PebbleControl *s, uint32_t n) +{ + assert (n <= s->rcv_char_bytes); + s->rcv_char_bytes -= n; + memmove(&s->rcv_char_buf[0], &s->rcv_char_buf[n], s->rcv_char_bytes); +} + + +// ----------------------------------------------------------------------------------- +// Forward the remaining portion of the packet at the front of our receive buffer onto the +// target +static void pebble_control_forward_to_target(PebbleControl *s) +{ + if (s->target_send_bytes == 0) { + return; + } + DPRINTF("%s: %d bytes left to send to target\n", __func__, s->target_send_bytes); + + int can_read_bytes = s->uart_chr_can_read(s->uart); + if (can_read_bytes > 0) { + can_read_bytes = MIN(can_read_bytes, s->target_send_bytes); + s->uart_chr_read(s->uart, s->rcv_char_buf, can_read_bytes); + pebble_control_consume_rcv_bytes(s, can_read_bytes); + s->target_send_bytes -= can_read_bytes; + DPRINTF("%s: sent %d bytes to target, %d remaining\n", __func__, can_read_bytes, + s->target_send_bytes); + } + + // If more data to send, set a timer so we run again later + if (s->target_send_bytes) { + DPRINTF("%s: Scheduling pebble_control_forward_to_target timer\n", __func__); + timer_mod(s->target_send_timer, qemu_clock_get_ms(QEMU_CLOCK_HOST) + 1); + } +} + + +// ----------------------------------------------------------------------------------- +// Parse through our receive buffer, for each complete control packet, process it +static void pebble_control_parse_receive_buffer(PebbleControl *s) +{ + // If we are still forwarding data to the target, finish that first + if (s->target_send_bytes) { + pebble_control_forward_to_target(s); + if (s->target_send_bytes) { + return; + } + } + + // Look for a complete packet + while (s->rcv_char_bytes >= sizeof(QemuCommChannelHdr) + sizeof(QemuCommChannelFooter)) { + QemuCommChannelHdr *hdr = (QemuCommChannelHdr *)s->rcv_char_buf; + + // Check the header signature + if (ntohs(hdr->signature) != QEMU_HEADER_SIGNATURE) { + DPRINTF("%s: invalid packet hdr signature detected\n", __func__); + pebble_control_consume_rcv_bytes(s, sizeof(hdr->signature)); + } + + // Validate the length + uint16_t data_len = ntohs(hdr->len); + if (data_len > QEMU_MAX_DATA_LEN) { + DPRINTF("%s: invalid packet hdr len detected\n", __func__); + pebble_control_consume_rcv_bytes(s, sizeof(*hdr)); + } + + // If not a complete packet yet, break out + uint16_t total_size = sizeof(QemuCommChannelHdr) + data_len + + sizeof(QemuCommChannelFooter); + if (s->rcv_char_bytes < total_size) { + break; + } + + // We have a complete packet, see if we should process it directly or pass it onto + // the target + uint16_t protocol = ntohs(hdr->protocol); + const PebbleControlMessageHandler* handler = pebble_control_find_handler(s, protocol); + if (!handler) { + DPRINTF("%s: passing packet with protocol %d onto target\n", __func__, protocol); + s->target_send_bytes = total_size; + pebble_control_forward_to_target(s); + if (s->target_send_bytes) { + // If we couldn't pass it all on, break out and wait for the timer callback + // to send the rest out + break; + } + } else { + handler->callback(s, (uint8_t *)(hdr+1), data_len); + pebble_control_consume_rcv_bytes(s, total_size); + } + + } + +} + + +// ----------------------------------------------------------------------------------- +// Char device receive handlers +static void pebble_control_event(void *opaque, int event) +{ + PebbleControl *s = (PebbleControl *)opaque; + + s->uart_chr_event(s->uart, event); +} + +static int pebble_control_can_receive(void *opaque) +{ + PebbleControl *s = (PebbleControl *)opaque; + + /* How much space do we have in our buffer? */ + return (PBLCONTROL_BUF_LEN - s->rcv_char_bytes); +} + +static void pebble_control_receive(void *opaque, const uint8_t *buf, int size) +{ + PebbleControl *s = (PebbleControl *)opaque; + + assert(size > 0); + + // Copy the characters into our buffer first + assert (size <= PBLCONTROL_BUF_LEN - s->rcv_char_bytes); + memmove(s->rcv_char_buf + s->rcv_char_bytes, buf, size); + s->rcv_char_bytes += size; + + // Process any complete packets in the receive buffer + pebble_control_parse_receive_buffer(s); +} + + +// ----------------------------------------------------------------------------------- +// Drop the first N bytes out of the beginning of the send buffer +static void pebble_control_consume_send_bytes(PebbleControl *s, uint32_t n) +{ + assert (n <= s->send_char_bytes); + s->send_char_bytes -= n; + memmove(&s->send_char_buf[0], &s->send_char_buf[n], s->send_char_bytes); +} + + +// ----------------------------------------------------------------------------------- +// This method gets passed to the UART's stm32_uart_set_write_handler(). This way +// we can intercept all writes that the UART sends to the front end and insure that +// we don't interrupt one mid-stream by sending a packet from QEMU +static int pebble_control_write(void *opaque, const uint8_t *buf, int len) { + PebbleControl *s = (PebbleControl *)opaque; + + while (len) { + // Copy the new bytes in + uint32_t space_left = sizeof(s->send_char_buf) - s->send_char_bytes; + + if (space_left == 0) { + EPRINTF("%s: overflowed send buffer, aborting queued up data\n", __func__); + s->send_char_bytes = 0; + space_left = sizeof(s->send_char_buf); + } + uint32_t bytes_to_copy = MIN(space_left, len); + memmove(&s->send_char_buf[s->send_char_bytes], buf, bytes_to_copy); + s->send_char_bytes += bytes_to_copy; + len -= bytes_to_copy; + + + // ------------------------------------------------------------------ + // See if we have a complete packet yet + if (s->send_char_bytes < sizeof(QemuCommChannelHdr) + + sizeof(QemuCommChannelFooter)) { + break; + } + QemuCommChannelHdr *hdr = (QemuCommChannelHdr *)s->send_char_buf; + + // Check the header signature + if (ntohs(hdr->signature) != QEMU_HEADER_SIGNATURE) { + DPRINTF("%s: invalid packet hdr signature detected\n", __func__); + pebble_control_consume_send_bytes(s, sizeof(hdr->signature)); + } + + // Validate the length + uint16_t data_len = ntohs(hdr->len); + if (data_len > QEMU_MAX_DATA_LEN) { + DPRINTF("%s: invalid packet hdr len detected\n", __func__); + pebble_control_consume_send_bytes(s, sizeof(*hdr)); + } + + // If not a complete packet yet, break out + uint16_t total_size = sizeof(QemuCommChannelHdr) + data_len + + sizeof(QemuCommChannelFooter); + if (s->send_char_bytes < total_size) { + if (len > 0) { + // If we still have not put in all the bytes the caller wanted, + // we must be off-frame because we ran out of room. + EPRINTF("%s: overflowed send buffer, aborting queued up data\n", __func__); + s->send_char_bytes = 0; + continue; + } + break; + } + + // We have a complete packet, send it out the front end + int bytes_sent; + DPRINTF("%s: Sending packet of %d bytes to host\n", __func__, total_size); + while (total_size) { + bytes_sent = qemu_chr_fe_write(s->chr, s->send_char_buf, total_size); + total_size -= bytes_sent; + pebble_control_consume_send_bytes(s, bytes_sent); + } + + } + + return qemu_chr_fe_write(s->chr, buf, len); +} + + +// ----------------------------------------------------------------------------------------- +static void pebble_control_send_packet(PebbleControl *s, QemuProtocol protocol, void *data, + uint32_t len) +{ + // Send the header + QemuCommChannelHdr hdr = (QemuCommChannelHdr) { + .signature = htons(QEMU_HEADER_SIGNATURE), + .protocol = htons(protocol), + .len = htons(len) + }; + qemu_chr_fe_write(s->chr, (uint8_t *)&hdr, sizeof(hdr)); + + // Send the data + qemu_chr_fe_write(s->chr, data, len); + + // Send the footer + QemuCommChannelFooter footer = (QemuCommChannelFooter) { + .signature = htons(QEMU_FOOTER_SIGNATURE) + }; + + qemu_chr_fe_write(s->chr, (uint8_t *)&footer, sizeof(footer)); +} + +// ----------------------------------------------------------------------------------- +// Send a vibe notification to the host +void pebble_control_send_vibe_notification(PebbleControl *s, bool on) +{ + DPRINTF("%s: vibe %d\n", __func__, (int)on); + + QemuProtocolVibrationNotificationHeader hdr = { + .on = on + }; + pebble_control_send_packet(s, QemuProtocol_Vibration, &hdr, sizeof(hdr)); +} + +// ----------------------------------------------------------------------------------- +PebbleControl *pebble_control_create(CharDriverState *chr, Stm32Uart *uart) +{ + PebbleControl *s = malloc(sizeof(PebbleControl)); + memset(s, 0, sizeof(*s)); + + if (chr) { + s->chr = chr; + s->uart = uart; + + // The timer we use to pump more data to the uart + s->target_send_timer = timer_new_ms(QEMU_CLOCK_HOST, + (QEMUTimerCB *)pebble_control_parse_receive_buffer, s); + + + // Have the UART send writes to us + stm32_uart_set_write_handler(uart, s, pebble_control_write); + + // Save away the receive handlers that the uart installed into chr + stm32_uart_get_rcv_handlers(uart, &s->uart_chr_can_read, &s->uart_chr_read, &s->uart_chr_event); + + // Install our own receive handlers into the CharDriver + qemu_chr_add_handlers( + chr, + pebble_control_can_receive, + pebble_control_receive, + pebble_control_event, + (void *)s); + } + + return s; +} + +// ----------------------------------------------------------------------------------- +PebbleControl *pebble_control_create_stm32f7xx(CharDriverState *chr, Stm32F7xxUart *uart) +{ + PebbleControl *s = malloc(sizeof(PebbleControl)); + memset(s, 0, sizeof(*s)); + + if (chr) { + s->chr = chr; + s->uart = uart; + + // The timer we use to pump more data to the uart + s->target_send_timer = timer_new_ms(QEMU_CLOCK_HOST, + (QEMUTimerCB *)pebble_control_parse_receive_buffer, s); + + + // Have the UART send writes to us + stm32f7xx_uart_set_write_handler(uart, s, pebble_control_write); + + // Save away the receive handlers that the uart installed into chr + stm32f7xx_uart_get_rcv_handlers(uart, &s->uart_chr_can_read, &s->uart_chr_read, &s->uart_chr_event); + + // Install our own receive handlers into the CharDriver + qemu_chr_add_handlers( + chr, + pebble_control_can_receive, + pebble_control_receive, + pebble_control_event, + (void *)s); + } + + return s; +} + diff --git a/hw/arm/pebble_control.h b/hw/arm/pebble_control.h new file mode 100644 index 0000000000000..3cf220264e158 --- /dev/null +++ b/hw/arm/pebble_control.h @@ -0,0 +1,10 @@ +#include "qemu/typedefs.h" +#include "hw/arm/stm32.h" + +typedef struct PebbleControl PebbleControl; + +PebbleControl *pebble_control_create(CharDriverState *chr, Stm32Uart *uart); +PebbleControl *pebble_control_create_stm32f7xx(CharDriverState *chr, Stm32F7xxUart *uart); + +void pebble_control_send_vibe_notification(PebbleControl *s, bool on); + diff --git a/hw/arm/pebble_robert.c b/hw/arm/pebble_robert.c new file mode 100644 index 0000000000000..7180cc4009b60 --- /dev/null +++ b/hw/arm/pebble_robert.c @@ -0,0 +1,146 @@ +#include "pebble.h" +#include "hw/boards.h" +#include "hw/ssi.h" + + +const static PblBoardConfig s_board_config_robert_bb = { + .dbgserial_uart_index = 2, // USART3 + .pebble_control_uart_index = 1, // USART2 + .button_map = { + {STM32_GPIOG_INDEX, 6}, + {STM32_GPIOG_INDEX, 3}, + {STM32_GPIOG_INDEX, 5}, + {STM32_GPIOG_INDEX, 4}, + }, + .flash_size = 4096, /* Kbytes - larger to aid in development and debugging */ + .ram_size = 512, /* Kbytes */ + .num_rows = 228, + .num_cols = 200, + .num_border_rows = 0, + .num_border_cols = 0, + .row_major = true, + .row_inverted = true, + .col_inverted = true, + .round_mask = false +}; + + +void pebble_32f7xx_init(MachineState *machine, const PblBoardConfig *board_config) +{ + Stm32Gpio *gpio[STM32F7XX_GPIO_COUNT]; + Stm32F7xxUart *uart[STM32F7XX_UART_COUNT]; + Stm32Timer *timer[STM32F7XX_TIM_COUNT]; + Stm32F7xxLPTimer *lptimer; + DeviceState *qspi_flash; + DeviceState *rtc_dev; + SSIBus *spi; + SSIBus *qspi; + struct stm32f7xx stm; + ARMCPU *cpu; + + stm32f7xx_init(board_config->flash_size, + board_config->ram_size, + machine->kernel_filename, + gpio, + board_config->gpio_idr_masks, + uart, + timer, + &lptimer, + &rtc_dev, + 8000000 /*osc_freq*/, + 32768 /*osc2_freq*/, + &stm, + &cpu); + + + // Set the Pebble specific QEMU settings on the target + pebble_set_qemu_settings(rtc_dev); + + /* --- QSPI Flash --------------------------------------------- */ + qspi = (SSIBus *)qdev_get_child_bus(stm.qspi_dev, "ssi"); + qspi_flash = ssi_create_slave_no_init(qspi, "mt25q256"); + qdev_init_nofail(qspi_flash); + + qemu_irq mt25q_cs = qdev_get_gpio_in_named(qspi_flash, SSI_GPIO_CS, 0); + qdev_connect_gpio_out_named(stm.qspi_dev, "qspi-gpio-cs", 0, mt25q_cs); + + + /* --- Display ------------------------------------------------ */ + spi = (SSIBus *)qdev_get_child_bus(stm.spi_dev[5], "ssi"); + DeviceState *display_dev = ssi_create_slave_no_init(spi, "pebble-snowy-display"); + + /* Create the outputs that the display will drive and associate them with the correct + * GPIO input pins on the MCU */ + qemu_irq display_done_irq = qdev_get_gpio_in((DeviceState *)gpio[STM32_GPIOB_INDEX], 2); + qdev_prop_set_ptr(display_dev, "done_output", display_done_irq); + qemu_irq display_intn_irq = qdev_get_gpio_in((DeviceState *)gpio[STM32_GPIOB_INDEX], 0); + qdev_prop_set_ptr(display_dev, "intn_output", display_intn_irq); + + qdev_prop_set_int32(display_dev, "num_rows", board_config->num_rows); + qdev_prop_set_int32(display_dev, "num_cols", board_config->num_cols); + qdev_prop_set_int32(display_dev, "num_border_rows", board_config->num_border_rows); + qdev_prop_set_int32(display_dev, "num_border_cols", board_config->num_border_cols); + qdev_prop_set_uint8(display_dev, "row_major", board_config->row_major); + qdev_prop_set_uint8(display_dev, "row_inverted", board_config->row_inverted); + qdev_prop_set_uint8(display_dev, "col_inverted", board_config->col_inverted); + qdev_prop_set_uint8(display_dev, "round_mask", board_config->round_mask); + + qdev_init_nofail(display_dev); + + /* Connect the correct MCU GPIO outputs to the inputs on the display */ + qemu_irq display_cs; + display_cs = qdev_get_gpio_in_named(display_dev, SSI_GPIO_CS, 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOA_INDEX], 4, display_cs); + + qemu_irq display_reset; + display_reset = qdev_get_gpio_in_named(display_dev, "reset", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOA_INDEX], 3, display_reset); + + qemu_irq display_sclk; + display_sclk = qdev_get_gpio_in_named(display_dev, "sclk", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOA_INDEX], 5, display_sclk); + + qemu_irq backlight_enable; + backlight_enable = qdev_get_gpio_in_named(display_dev, "backlight_enable", 0); + qdev_connect_gpio_out_named((DeviceState *)gpio[STM32_GPIOG_INDEX], "af", 13, + backlight_enable); + + qemu_irq backlight_level; + backlight_level = qdev_get_gpio_in_named(display_dev, "backlight_level", 0); + qdev_connect_gpio_out_named((DeviceState *)lptimer, "pwm_ratio_changed", 0, // LPTIM1 + backlight_level); + + qemu_irq display_power; + display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); + qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, + display_power); + + // Connect up the uarts + pebble_connect_uarts_stm32f7xx(uart, board_config); + + // Init the buttons + pebble_init_buttons(gpio, board_config->button_map); + + // Create the board device and wire it up + qemu_irq display_vibe; + display_vibe = qdev_get_gpio_in_named(display_dev, "vibe_ctl", 0); + DeviceState *board = pebble_init_board(gpio, display_vibe); + + // The GPIO from vibrate drives the vibe input on the board + qemu_irq board_vibe_in; + board_vibe_in = qdev_get_gpio_in_named(board, "pebble_board_vibe_in", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOD_INDEX], 14, board_vibe_in); +} + +static void pebble_robert_init(MachineState *machine) +{ + pebble_32f7xx_init(machine, &s_board_config_robert_bb); +} + +static void pebble_robert_bb_machine_init(MachineClass *mc) +{ + mc->desc = "Pebble smartwatch (robert)"; + mc->init = pebble_robert_init; +} + +DEFINE_MACHINE("pebble-robert-bb", pebble_robert_bb_machine_init) diff --git a/hw/arm/pebble_silk.c b/hw/arm/pebble_silk.c new file mode 100644 index 0000000000000..f3f224b65837d --- /dev/null +++ b/hw/arm/pebble_silk.c @@ -0,0 +1,125 @@ +#include "pebble.h" +#include "hw/boards.h" +#include "hw/ssi.h" + +const static PblBoardConfig s_board_config_silk_bb = { + .dbgserial_uart_index = 0, // USART1 + .pebble_control_uart_index = 1, // USART2 -- note this is also used by the DA14681 on real HW + .button_map = { + { STM32_GPIOC_INDEX, 13, true }, + { STM32_GPIOD_INDEX, 2, true }, + { STM32_GPIOH_INDEX, 0, true }, + { STM32_GPIOH_INDEX, 1, true }, + }, + .gpio_idr_masks = { + [STM32_GPIOC_INDEX] = 1 << 13, + [STM32_GPIOD_INDEX] = 1 << 2, + [STM32_GPIOH_INDEX] = (1 << 1) | (1 << 0), + }, + .flash_size = 4096, /* Kbytes - larger to aid in development and debugging */ + .ram_size = 256, /* Kbytes */ + .num_rows = 172, /* not currently used */ + .num_cols = 148, /* not currently used */ + .num_border_rows = 2, /* not currently used */ + .num_border_cols = 2, /* not currently used */ + .row_major = false, /* not currently used */ + .row_inverted = false, /* not currently used */ + .col_inverted = false, /* not currently used */ + .round_mask = false /* not currently used */ +}; + +void pebble_32f412_init(MachineState *machine, const PblBoardConfig *board_config) +{ + Stm32Gpio *gpio[STM32F4XX_GPIO_COUNT]; + Stm32Uart *uart[STM32F4XX_UART_COUNT]; + Stm32Timer *timer[STM32F4XX_TIM_COUNT]; + DeviceState *qspi_flash; + DeviceState *rtc_dev; + SSIBus *spi; + SSIBus *qspi; + struct stm32f4xx stm; + ARMCPU *cpu; + + // Note: allow for bigger flash images (4MByte) to aid in development and debugging + stm32f4xx_init(board_config->flash_size, + board_config->ram_size, + machine->kernel_filename, + gpio, + board_config->gpio_idr_masks, + uart, + timer, + &rtc_dev, + 8000000 /*osc_freq*/, + 32768 /*osc2_freq*/, + &stm, + &cpu); + + + // Set the Pebble specific QEMU settings on the target + pebble_set_qemu_settings(rtc_dev); + + /* --- QSPI Flash --------------------------------------------- */ + qspi = (SSIBus *)qdev_get_child_bus(stm.qspi_dev, "ssi"); + qspi_flash = ssi_create_slave_no_init(qspi, "mx25u6435f"); + qdev_init_nofail(qspi_flash); + + qemu_irq mx25u_cs = qdev_get_gpio_in_named(qspi_flash, SSI_GPIO_CS, 0); + qdev_connect_gpio_out_named(stm.qspi_dev, "qspi-gpio-cs", 0, mx25u_cs); + + + /* --- Display ------------------------------------------------ */ + spi = (SSIBus *)qdev_get_child_bus(stm.spi_dev[1], "ssi"); // SPI2 + DeviceState *display_dev = ssi_create_slave_no_init(spi, "sm-lcd"); + qdev_prop_set_bit(display_dev, "rotate_display", false); + qdev_init_nofail(display_dev); + + qemu_irq backlight_enable; + backlight_enable = qdev_get_gpio_in_named(display_dev, "backlight_enable", 0); + qdev_connect_gpio_out((DeviceState *)gpio[STM32_GPIOB_INDEX], 13, backlight_enable); + + qemu_irq backlight_level; + backlight_level = qdev_get_gpio_in_named(display_dev, "backlight_level", 0); + qdev_connect_gpio_out_named((DeviceState *)timer[2], // TIM3 + "pwm_ratio_changed", + 0, + backlight_level); + + qemu_irq display_power; + display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); + qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, + display_power); + + + // Connect up the uarts + pebble_connect_uarts(uart, board_config); + + // Init the buttons + pebble_init_buttons(gpio, board_config->button_map); + + // Create the board device and wire it up + qemu_irq display_vibe; + display_vibe = qdev_get_gpio_in_named(display_dev, "vibe_ctl", 0); + DeviceState *board = pebble_init_board(gpio, display_vibe); + + // The vibe PWM enables the qemu vibe + qemu_irq board_vibe_in; + board_vibe_in = qdev_get_gpio_in_named(board, "pebble_board_vibe_in", 0); + qdev_connect_gpio_out_named((DeviceState *)timer[13], // TIM14 + "pwm_enable", + 0, + board_vibe_in); +} + +static void pebble_silk_init(MachineState *machine) +{ + pebble_32f412_init(machine, &s_board_config_silk_bb); +} + +static void pebble_silk_bb_machine_init(MachineClass *mc) +{ + mc->desc = "Pebble smartwatch (silk)"; + mc->init = pebble_silk_init; +} + +DEFINE_MACHINE("pebble-silk-bb", pebble_silk_bb_machine_init) + diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index d136ba1a92adf..149ca82152ab1 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1308,6 +1308,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) &error_fatal); memory_region_add_subregion(system_memory, 0x20000000, sram); +<<<<<<< HEAD nvic = qdev_create(NULL, TYPE_ARMV7M); qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); @@ -1316,6 +1317,10 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) "memory", &error_abort); /* This will exit with an error if the user passed us a bad cpu_type */ qdev_init_nofail(nvic); +======= + nvic = armv7m_init(/* no parent */ NULL, system_memory, flash_size, 128 * 1024, NUM_IRQ_LINES, + kernel_filename, cpu_model); +>>>>>>> 919b29ba7d... Pebble Qemu qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, qemu_allocate_irq(&do_sys_reset, NULL, 0)); diff --git a/hw/arm/stm32.c b/hw/arm/stm32.c new file mode 100644 index 0000000000000..ae6733abc1962 --- /dev/null +++ b/hw/arm/stm32.c @@ -0,0 +1,81 @@ +/* + * STM32 Microcontroller + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "exec/address-spaces.h" +#include "exec/gdbstub.h" + +/* DEFINITIONS */ + +/* COMMON */ + +void stm32_hw_warn(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "qemu stm32: hardware warning: "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + cpu_dump_state(first_cpu, stderr, fprintf, 0); + va_end(ap); +} + + +void stm32_create_uart_dev( + Object *stm32_container, + stm32_periph_t periph, + int uart_num, + DeviceState *rcc_dev, + DeviceState **gpio_dev, + DeviceState *afio_dev, + hwaddr addr, + qemu_irq irq) +{ + char child_name[8]; + DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + QDEV_PROP_SET_PERIPH_T(uart_dev, "periph", periph); + qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); + qdev_prop_set_ptr(uart_dev, "stm32_gpio", gpio_dev); + qdev_prop_set_ptr(uart_dev, "stm32_afio", afio_dev); + snprintf(child_name, sizeof(child_name), "uart[%i]", uart_num); + object_property_add_child(stm32_container, child_name, OBJECT(uart_dev), NULL); + stm32_init_periph(uart_dev, periph, addr, irq); +} + + +/* INITIALIZATION */ + +/* I copied sysbus_create_varargs and split it into two parts. This is so that + * you can set properties before calling the device init function. + */ + +DeviceState *stm32_init_periph(DeviceState *dev, stm32_periph_t periph, + hwaddr addr, qemu_irq irq) +{ + qdev_init_nofail(dev); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); + if (irq) { + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); + } + return dev; +} + diff --git a/hw/arm/stm32_clktree.c b/hw/arm/stm32_clktree.c new file mode 100644 index 0000000000000..34270d660ca6a --- /dev/null +++ b/hw/arm/stm32_clktree.c @@ -0,0 +1,299 @@ +/* + * Basic Clock Tree Building Blocks + * + * Copyright (C) 2012 Andre Beckus + * + * Source code roughly based on omap_clk.c + * + * 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 . + */ + +#include "hw/hw.h" +#include "hw/arm/stm32_clktree.h" + + +/* DEFINITIONS*/ + +/* See README for DEBUG documentation */ +//#define DEBUG_CLKTREE + + +/* Helper to: + * 1) Add a value to an array. + * 2) Increment the array size count. + * 3) Make sure the array does not overflow. + */ +#define CLKTREE_ADD_LINK(array, count, value, array_size) \ + (array)[(count)++] = (value); \ + assert((count) <= (array_size)); + + +struct Clk { + const char *name; + + bool enabled; + + uint32_t input_freq, output_freq, max_output_freq; + + uint16_t multiplier, divisor; + + unsigned user_count; + qemu_irq user[CLKTREE_MAX_IRQ]; /* Who to notify on change */ + + unsigned output_count; + struct Clk *output[CLKTREE_MAX_OUTPUT]; + + unsigned input_count; + int selected_input; + struct Clk *input[CLKTREE_MAX_INPUT]; +}; + +static void clktree_recalc_output_freq(Clk clk); + + + + +/* HELPER FUNCTIONS */ + +static Clk clktree_get_input_clk(Clk clk) +{ + return clk->input[clk->selected_input + 1]; +} + +#ifdef DEBUG_CLKTREE + +static void clktree_print_state(Clk clk) +{ + Clk input_clk = clktree_get_input_clk(clk); + + printf("CLKTREE: %s Output Change (SrcClk:%s InFreq:%lu OutFreq:%lu Mul:%u Div:%u Enabled:%c)\n", + clk->name, + input_clk ? input_clk->name : "None", + (unsigned long)clk->input_freq, + (unsigned long)clk->output_freq, + (unsigned)clk->multiplier, + (unsigned)clk->divisor, + clk->enabled ? '1' : '0'); +} +#endif + +static void clktree_set_input_freq(Clk clk, uint32_t input_freq) +{ + clk->input_freq = input_freq; + + clktree_recalc_output_freq(clk); +} + +/* Recalculates the output frequency based on the clock's input_freq variable. + */ +static void clktree_recalc_output_freq(Clk clk) { + int i; + Clk next_clk, next_clk_input; + uint32_t new_output_freq; + + /* Get the output frequency, or 0 if the output is disabled. */ + new_output_freq = clk->enabled ? + muldiv64(clk->input_freq, + clk->multiplier, + clk->divisor) + : 0; + + /* if the frequency has changed. */ + if(new_output_freq != clk->output_freq) { + clk->output_freq = new_output_freq; + +#ifdef DEBUG_CLKTREE + clktree_print_state(clk); +#endif + + /* Check the new frequency against the max frequency. */ + if(new_output_freq > clk->max_output_freq) { + fprintf(stderr, "%s: Clock %s output frequency (%d Hz) exceeds max frequency (%d Hz).\n", + __FUNCTION__, + clk->name, + new_output_freq, + clk->max_output_freq); + } + + /* Notify users of change. */ + for(i=0; i < clk->user_count; i++) { + qemu_set_irq(clk->user[i], 1); + } + + /* Propagate the frequency change to the child clocks */ + for(i=0; i < clk->output_count; i++) { + next_clk = clk->output[i]; + assert(next_clk != NULL); + + /* Only propagate the change if the child has selected the current + * clock as input. + */ + next_clk_input = clktree_get_input_clk(next_clk); + if(next_clk_input == clk) { + /* Recursively propagate changes. The clock tree should not be + * too deep, so we shouldn't have to recurse too many times. + */ + clktree_set_input_freq(next_clk, new_output_freq); + } + } + } +} + + +/* Generic create routine used by the public create routines. */ +static Clk clktree_create_generic( + const char *name, + uint16_t multiplier, + uint16_t divisor, + bool enabled) +{ + Clk clk = (Clk)g_malloc(sizeof(struct Clk)); + + clk->name = name; + + clk->input_freq = 0; + clk->output_freq = 0; + clk->max_output_freq = CLKTREE_NO_MAX_FREQ; + + clk->multiplier = multiplier; + clk->divisor = divisor; + + clk->enabled = enabled; + + clk->user_count = 0; + + clk->output_count = 0; + + clk->input_count = 1; + clk->input[0] = NULL; + clk->selected_input = CLKTREE_NO_INPUT; + + return clk; +} + + + + + + + + + +/* PUBLIC FUNCTIONS */ +bool clktree_is_enabled(Clk clk) +{ + return clk->enabled; +} + +uint32_t clktree_get_output_freq(Clk clk) +{ + return clk->output_freq; +} + +void clktree_adduser(Clk clk, qemu_irq user) +{ + CLKTREE_ADD_LINK( + clk->user, + clk->user_count, + user, + CLKTREE_MAX_IRQ); +} + + +Clk clktree_create_src_clk( + const char *name, + uint32_t src_freq, + bool enabled) +{ + Clk clk; + + clk = clktree_create_generic(name, 1, 1, enabled); + + clktree_set_input_freq(clk, src_freq); + + return clk; +} + + +Clk clktree_create_clk( + const char *name, + uint16_t multiplier, + uint16_t divisor, + bool enabled, + uint32_t max_output_freq, + int selected_input, + ...) +{ + va_list input_clks; + Clk clk, input_clk; + + clk = clktree_create_generic(name, multiplier, divisor, enabled); + + /* Add the input clock connections. */ + va_start(input_clks, selected_input); + while((input_clk = va_arg(input_clks, Clk)) != NULL) { + CLKTREE_ADD_LINK( + clk->input, + clk->input_count, + input_clk, + CLKTREE_MAX_INPUT); + + CLKTREE_ADD_LINK( + input_clk->output, + input_clk->output_count, + clk, + CLKTREE_MAX_OUTPUT); + } + + clktree_set_selected_input(clk, selected_input); + + return clk; +} + + +void clktree_set_scale(Clk clk, uint16_t multiplier, uint16_t divisor) +{ + clk->multiplier = multiplier; + clk->divisor = divisor; + + clktree_recalc_output_freq(clk); +} + + +void clktree_set_enabled(Clk clk, bool enabled) +{ + clk->enabled = enabled; + + clktree_recalc_output_freq(clk); +} + + +void clktree_set_selected_input(Clk clk, int selected_input) +{ + uint32_t input_freq; + + assert((selected_input + 1) < clk->input_count); + + clk->selected_input = selected_input; + + /* Get the input clock frequency. If there is no input, this should be 0. + */ + if(selected_input > -1) { + input_freq = clktree_get_input_clk(clk)->output_freq; + } else { + input_freq = 0; + } + + clktree_set_input_freq(clk, input_freq); +} diff --git a/hw/arm/stm32_exti.c b/hw/arm/stm32_exti.c new file mode 100644 index 0000000000000..ae1d7b63abc51 --- /dev/null +++ b/hw/arm/stm32_exti.c @@ -0,0 +1,397 @@ +/* + * STM32 Microcontroller EXTI (External Interrupt/Event Controller) module + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" + + + + +/* DEFINITIONS*/ + +#define EXTI_IMR_OFFSET 0x00 + +#define EXTI_EMR_OFFSET 0x04 + +#define EXTI_RTSR_OFFSET 0x08 + +#define EXTI_FTSR_OFFSET 0x0c + +#define EXTI_SWIER_OFFSET 0x10 + +#define EXTI_PR_OFFSET 0x14 + +/* Some devices have fewer lines, but it doesn't hurt to handle the maximum + possible. */ +#define EXTI_LINE_COUNT 23 + +/* The number of IRQ connections to the NVIC */ +#define EXTI_IRQ_COUNT 14 + + +struct Stm32Exti { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + /* Array of Stm32Gpio pointers (one for each GPIO). The QEMU property + * library expects this to be a void pointer. */ + void *stm32_gpio_prop; + + /* Private */ + MemoryRegion iomem; + + /* Copy of stm32_gpio_prop correctly typed as an array of Stm32Gpio + * pointers. */ + stm32f2xx_gpio **stm32_gpio; + + uint32_t + EXTI_IMR, + EXTI_RTSR, + EXTI_FTSR, + EXTI_SWIER, + EXTI_PR; + + qemu_irq irq[EXTI_IRQ_COUNT]; +}; + +static void stm32_exti_change_EXTI_PR_bit(Stm32Exti *s, unsigned pos, + unsigned new_bit_value); + + + +/* HELPER FUNCTIONS */ + +/* Call when the EXTI shouldbe tri */ +static void stm32_exti_trigger(Stm32Exti *s, int line) +{ + /* Make sure the interrupt for this EXTI line has been enabled. */ + if(IS_BIT_SET(s->EXTI_IMR, line)) { + /* Set the Pending flag for this line, which will trigger the interrupt + * (if the flag isn't already set). */ + stm32_exti_change_EXTI_PR_bit(s, line, 1); + } +} + +/* We will assume that this handler will only be called if the pin actually + * changed state. */ +static void stm32_exti_gpio_in_handler(void *opaque, int n, int level) +{ + Stm32Exti *s = (Stm32Exti *)opaque; + unsigned pin = n; + + assert(pin < EXTI_LINE_COUNT); + + /* Check the level - if it is rising, then trigger an interrupt if the + * corresponding Rising Trigger Selection Register flag is set. Otherwise, + * trigger if the Falling Trigger Selection Register flag is set. + */ + if((level && GET_BIT_VALUE(s->EXTI_RTSR, pin)) || + (!level && GET_BIT_VALUE(s->EXTI_FTSR, pin))) { + stm32_exti_trigger(s, pin); + } +} + + + + +/* REGISTER IMPLEMENTATION */ + +/* Update a Trigger Selection Register (both the Rising and Falling TSR + * registers are handled by this routine). + */ +static void update_TSR_bit(Stm32Exti *s, uint32_t *tsr_register, unsigned pos, + unsigned new_bit_value) +{ + assert((new_bit_value == 0) || (new_bit_value == 1)); + assert(pos < EXTI_LINE_COUNT); + + if(new_bit_value != GET_BIT_VALUE(*tsr_register, pos)) { + /* According to the documentation, the Pending register is cleared when + * the "sensitivity of the edge detector changes. Is this right??? */ + stm32_exti_change_EXTI_PR_bit(s, pos, 0); + } + CHANGE_BIT(*tsr_register, pos, new_bit_value); +} + +/* Update the Pending Register. This will trigger an interrupt if a bit is + * set. + */ +static void stm32_exti_change_EXTI_PR_bit(Stm32Exti *s, unsigned pos, + unsigned new_bit_value) +{ + unsigned old_bit_value; + + assert((new_bit_value == 0) || (new_bit_value == 1)); + assert(pos < EXTI_LINE_COUNT); + + old_bit_value = GET_BIT_VALUE(s->EXTI_PR, pos); + + /* Only continue if the PR bit is actually changing value. */ + if(new_bit_value != old_bit_value) { + /* If the bit is being reset, the corresponding Software Interrupt Event + * Register bit is automatically reset. + */ + if(!new_bit_value) { + RESET_BIT(s->EXTI_SWIER, pos); + } + + /* Update the IRQ for this EXTI line. Some lines share the same + * NVIC IRQ. + */ + if(pos <= 4) { + /* EXTI0 - EXTI4 each have their own NVIC IRQ */ + qemu_set_irq(s->irq[pos], new_bit_value); + } else if(pos <= 9) { + /* EXTI5 - EXTI9 share an NVIC IRQ */ + qemu_set_irq(s->irq[5], new_bit_value); + } else if(pos <= 15) { + /* EXTI10 - EXTI15 share an NVIC IRQ */ + qemu_set_irq(s->irq[6], new_bit_value); + } else if(pos == 16) { + /* PVD IRQ */ + qemu_set_irq(s->irq[7], new_bit_value); + } else if(pos == 17) { + /* RTCAlarm IRQ */ + qemu_set_irq(s->irq[8], new_bit_value); + } else if(pos == 18) { + /* OTG_FS_WKUP IRQ */ + qemu_set_irq(s->irq[9], new_bit_value); + } else if(pos == 19) { + /* ETH_WKUP IRQ */ + qemu_set_irq(s->irq[10], new_bit_value); + } else if(pos == 20) { + /* OTG_HS_WKUP IRQ */ + qemu_set_irq(s->irq[11], new_bit_value); + } else if(pos == 21) { + /* TAMP_STAMP IRQ */ + qemu_set_irq(s->irq[12], new_bit_value); + } else if(pos == 22) { + /* RTC_WKUP IRQ */ + qemu_set_irq(s->irq[13], new_bit_value); + } else { + assert(false); + } + + /* Update the register. */ + CHANGE_BIT(s->EXTI_PR, pos, new_bit_value); + } +} + + +static uint64_t stm32_exti_readw(void *opaque, hwaddr offset) +{ + Stm32Exti *s = (Stm32Exti *)opaque; + + switch (offset) { + case EXTI_IMR_OFFSET: + return s->EXTI_IMR; + case EXTI_EMR_OFFSET: + /* Do nothing, events are not implemented yet. */ + return 0; + case EXTI_RTSR_OFFSET: + return s->EXTI_RTSR; + case EXTI_FTSR_OFFSET: + return s->EXTI_FTSR; + case EXTI_SWIER_OFFSET: + return s->EXTI_SWIER; + case EXTI_PR_OFFSET: + return s->EXTI_PR; + default: + STM32_BAD_REG(offset, WORD_ACCESS_SIZE); + return 0; + } +} + + +static void stm32_exti_writew(void *opaque, hwaddr offset, uint64_t value) +{ + Stm32Exti *s = (Stm32Exti *)opaque; + + int pos, bit_value; + + if(offset <= EXTI_EMR_OFFSET) { + switch (offset) { + case EXTI_IMR_OFFSET: + s->EXTI_IMR = value; + break; + case EXTI_EMR_OFFSET: + /* Do nothing, events are not implemented yet. + * But we don't want to throw an error. */ + break; + default: + STM32_BAD_REG(offset, WORD_ACCESS_SIZE); + break; + } + } else { + /* These registers all contain one bit per EXTI line. We will loop + * through each line and then update each bit in the appropriate + * register. + */ + for(pos = 0; pos < EXTI_LINE_COUNT; pos++) { + bit_value = GET_BIT_VALUE(value, pos); + + switch (offset) { + case EXTI_RTSR_OFFSET: + update_TSR_bit(s, &(s->EXTI_RTSR), pos, bit_value); + break; + case EXTI_FTSR_OFFSET: + update_TSR_bit(s, &(s->EXTI_FTSR), pos, bit_value); + break; + case EXTI_SWIER_OFFSET: + /* If the Software Interrupt Event Register is changed + * from 0 to 1, trigger an interrupt. Changing the + * bit to 0 does nothing. */ + if(bit_value == 1) { + if(GET_BIT_VALUE(s->EXTI_SWIER, pos) == 0) { + SET_BIT(s->EXTI_SWIER, pos); + stm32_exti_trigger(s, pos); + } + } + break; + case EXTI_PR_OFFSET: + /* When a 1 is written to a PR bit, it actually clears the + * PR bit. */ + if(bit_value == 1) { + stm32_exti_change_EXTI_PR_bit(s, pos, 0); + } + break; + default: + STM32_BAD_REG(offset, WORD_ACCESS_SIZE); + break; + } + } + } +} + +static uint64_t stm32_exti_read(void *opaque, hwaddr offset, unsigned size) +{ + switch(size) { + case WORD_ACCESS_SIZE: + return stm32_exti_readw(opaque, offset); + default: + STM32_BAD_REG(offset, size); + return 0; + } +} + +static void stm32_exti_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + switch(size) { + case WORD_ACCESS_SIZE: + stm32_exti_writew(opaque, offset, value); + break; + default: + STM32_BAD_REG(offset, size); + break; + } +} + +static const MemoryRegionOps stm32_exti_ops = { + .read = stm32_exti_read, + .write = stm32_exti_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void stm32_exti_reset(DeviceState *dev) +{ + Stm32Exti *s = FROM_SYSBUS(Stm32Exti, SYS_BUS_DEVICE(dev)); + + s->EXTI_IMR = 0x00000000; + s->EXTI_RTSR = 0x00000000; + s->EXTI_FTSR = 0x00000000; + s->EXTI_SWIER = 0x00000000; + s->EXTI_PR = 0x00000000; +} + + + +/* PUBLIC FUNCTIONS */ + +void stm32_exti_set_gpio(Stm32Exti *s, unsigned exti_line, const uint8_t gpio_index) +{ + assert(exti_line < EXTI_LINE_COUNT); + + /* Call the GPIO module with the EXTI lines IRQ handler. */ + f2xx_gpio_exti_set(s->stm32_gpio[gpio_index], exti_line, qdev_get_gpio_in(DEVICE(&s->busdev), exti_line)); +} + +void stm32_exti_reset_gpio(Stm32Exti *s, unsigned exti_line, const uint8_t gpio_index) +{ + assert(exti_line < EXTI_LINE_COUNT); + + /* Call the GPIO module to clear its IRQ assignment. */ + f2xx_gpio_exti_set(s->stm32_gpio[gpio_index], exti_line, NULL); +} + + + +/* DEVICE INITIALIZATION */ + +static int stm32_exti_init(SysBusDevice *dev) +{ + int i; + + Stm32Exti *s = FROM_SYSBUS(Stm32Exti, dev); + + s->stm32_gpio = (stm32f2xx_gpio **)s->stm32_gpio_prop; + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_exti_ops, s, + "exti", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + for(i = 0; i < EXTI_IRQ_COUNT; i++) { + sysbus_init_irq(dev, &s->irq[i]); + } + + qdev_init_gpio_in(DEVICE(dev), stm32_exti_gpio_in_handler, EXTI_LINE_COUNT); + + return 0; +} + +static Property stm32_exti_properties[] = { + DEFINE_PROP_PTR("stm32_gpio", Stm32Exti, stm32_gpio_prop), + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32_exti_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_exti_init; + dc->reset = stm32_exti_reset; + dc->props = stm32_exti_properties; +} + +static TypeInfo stm32_exti_info = { + .name = "stm32_exti", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Exti), + .class_init = stm32_exti_class_init +}; + +static void stm32_exti_register_types(void) +{ + type_register_static(&stm32_exti_info); +} + +type_init(stm32_exti_register_types) diff --git a/hw/arm/stm32_flash.c b/hw/arm/stm32_flash.c new file mode 100644 index 0000000000000..740d9ac96dca2 --- /dev/null +++ b/hw/arm/stm32_flash.c @@ -0,0 +1,106 @@ +/* + * STM32 Microcontroller Flash Memory + * The STM32 family stores its Flash memory at some base address in memory + * (0x08000000 for medium density devices), and then aliases it to the + * boot memory space, which starts at 0x00000000 (the System Memory can also + * be aliased to 0x00000000, but this is not implemented here). The processor + * executes the code in the aliased memory at 0x00000000, but we need to + * implement the "real" flash memory as well. This "real" flash memory will + * pass reads through to the memory at 0x00000000, which is where QEMU loads + * the executable image. Note that this is opposite of real hardware, where the + * memory at 0x00000000 passes reads through the "real" flash memory, but it + * works the same either way. + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +//#include "exec-memory.h" + +typedef struct { + SysBusDevice busdev; + MemoryRegion iomem; + uint32_t size; +} Stm32Flash; + +static uint64_t stm32_flash_read(void *opaque, hwaddr offset, unsigned size) +{ + uint32_t v = 0; + + /* Pass the read through to base memory at 0x00000000 where QEMU has loaded + * the executable image. + */ + cpu_physical_memory_read(offset, (uint8_t *)&v, size); + return v; +} + +static void stm32_flash_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + /* Flash is treated as read only memory. */ + hw_error("stm32_flash: Attempted to write flash memory (read only)"); +} + +static const MemoryRegionOps stm32_flash_ops = { + .read = stm32_flash_read, + .write = stm32_flash_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static int stm32_flash_init(SysBusDevice *dev) +{ + Stm32Flash *s = FROM_SYSBUS(Stm32Flash, dev); + + memory_region_init_io( + &s->iomem, + OBJECT(s), + &stm32_flash_ops, + &s, + "stm32_flash", + s->size); + sysbus_init_mmio(dev, &s->iomem); + return 0; +} + +static Property stm32_flash_properties[] = { + DEFINE_PROP_UINT32("size", Stm32Flash, size, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void stm32_flash_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_flash_init; + dc->props = stm32_flash_properties; +} + +static TypeInfo stm32_flash_info = { + .name = "stm32_flash", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Flash), + .class_init = stm32_flash_class_init, +}; + +static void stm32_flash_register_types(void) +{ + type_register_static(&stm32_flash_info); +} + +type_init(stm32_flash_register_types) diff --git a/hw/arm/stm32_p103.c b/hw/arm/stm32_p103.c new file mode 100644 index 0000000000000..3ec75aa93a855 --- /dev/null +++ b/hw/arm/stm32_p103.c @@ -0,0 +1,134 @@ +/* + * Olimex STM32 P103 Development Board + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on + * Olimex "STM-P103 Development Board Users Manual Rev. A, April 2008" + * + * 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 . + */ + +#include "stm32f1xx.h" +#include "hw/sysbus.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" +#include "ui/console.h" +#include "sysemu/sysemu.h" +#include "hw/boards.h" + + +typedef struct { + Stm32 *stm32; + Stm32Gpio *stm32_gpio[STM32F1XX_GPIO_COUNT]; + Stm32Uart *stm32_uart[STM32_UART_COUNT]; + + bool last_button_pressed; + qemu_irq button_irq; +} Stm32P103; + + + + +static void led_irq_handler(void *opaque, int n, int level) +{ + /* There should only be one IRQ for the LED */ + assert(n == 0); + + /* Assume that the IRQ is only triggered if the LED has changed state. + * If this is not correct, we may get multiple LED Offs or Ons in a row. + */ + switch (level) { + case 0: + printf("LED Off\n"); + break; + case 1: + printf("LED On\n"); + break; + } +} + +static void stm32_p103_key_event(void *opaque, int keycode) +{ + Stm32P103 *s = (Stm32P103 *)opaque; + bool make; + int core_keycode; + + if((keycode & 0x80) == 0) { + make = true; + core_keycode = keycode; + } else { + make = false; + core_keycode = keycode & 0x7f; + } + + /* Responds when a "B" key press is received. + * Inside the monitor, you can type "sendkey b" + */ + if(core_keycode == 0x30) { + if(make) { + if(!s->last_button_pressed) { + qemu_irq_raise(s->button_irq); + s->last_button_pressed = true; + } + } else { + if(s->last_button_pressed) { + qemu_irq_lower(s->button_irq); + s->last_button_pressed = false; + } + } + } + return; + +} + + +static void stm32_p103_init(MachineState *machine) { + + const char* kernel_filename = machine->kernel_filename; + qemu_irq *led_irq; + Stm32P103 *s; + + s = (Stm32P103 *)g_malloc0(sizeof(Stm32P103)); + + stm32f1xx_init(/*flash_size in bytes */ 128 * 1024, + /*ram_size in bytes */ 20 * 1024, + kernel_filename, + s->stm32_gpio, + s->stm32_uart, + 8000000, + 32768); + + /* Connect LED to GPIO C pin 12 */ + led_irq = qemu_allocate_irqs(led_irq_handler, NULL, 1); + qdev_connect_gpio_out((DeviceState *)s->stm32_gpio[STM32_GPIOC_INDEX], 12, led_irq[0]); + + /* Connect button to GPIO A pin 0 */ + s->button_irq = qdev_get_gpio_in((DeviceState *)s->stm32_gpio[STM32_GPIOA_INDEX], 0); + qemu_add_kbd_event_handler(stm32_p103_key_event, s); + + /* Connect RS232 to UART */ + stm32_uart_connect( + s->stm32_uart[STM32_UART2_INDEX], + serial_hds[0], + STM32_USART2_NO_REMAP); +} + +static void stm32_p103_machine_init(MachineClass *mc) +{ + mc->desc = "Olimex STM32 p103 Dev Board"; + mc->init = stm32_p103_init; +} + +DEFINE_MACHINE("stm32-p103", stm32_p103_machine_init) \ No newline at end of file diff --git a/hw/arm/stm32_rcc.c b/hw/arm/stm32_rcc.c new file mode 100644 index 0000000000000..11c0e1dca08a9 --- /dev/null +++ b/hw/arm/stm32_rcc.c @@ -0,0 +1,50 @@ +#include "stm32_rcc.h" +#include "hw/arm/stm32.h" +#include "hw/arm/stm32_clktree.h" + + + +/* PUBLIC FUNCTIONS */ + +void stm32_rcc_check_periph_clk(Stm32Rcc *s, stm32_periph_t periph) +{ + Clk clk = s->PERIPHCLK[periph]; + + assert(clk != NULL); + + if(!clktree_is_enabled(clk)) { + /* I assume writing to a peripheral register while the peripheral clock + * is disabled is a bug and give a warning to unsuspecting programmers. + * When I made this mistake on real hardware the write had no effect. + */ + stm32_hw_warn("Warning: You are attempting to use the stm32_rcc peripheral while " + "its clock is disabled.\n"); + } +} + +void stm32_rcc_set_periph_clk_irq( + Stm32Rcc *s, + stm32_periph_t periph, + qemu_irq periph_irq) +{ + Clk clk = s->PERIPHCLK[periph]; + + assert(clk != NULL); + + clktree_adduser(clk, periph_irq); +} + +uint32_t stm32_rcc_get_periph_freq( + Stm32Rcc *s, + stm32_periph_t periph) +{ + Clk clk; + + clk = s->PERIPHCLK[periph]; + + assert(clk != NULL); + + return clktree_get_output_freq(clk); +} + + diff --git a/hw/arm/stm32_rcc.h b/hw/arm/stm32_rcc.h new file mode 100644 index 0000000000000..c24b0cf98124f --- /dev/null +++ b/hw/arm/stm32_rcc.h @@ -0,0 +1,20 @@ +#include "hw/sysbus.h" +#include "hw/arm/stm32_clktree.h" +#include "hw/arm/stm32.h" + +/** RCC Base data structure */ +struct Stm32Rcc { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + uint32_t osc_freq; + uint32_t osc32_freq; + + /* Private */ + MemoryRegion iomem; + qemu_irq irq; + + /* Peripheral clocks */ + Clk PERIPHCLK[]; +}; diff --git a/hw/arm/stm32f1xx.c b/hw/arm/stm32f1xx.c new file mode 100644 index 0000000000000..da4f30e5a0a84 --- /dev/null +++ b/hw/arm/stm32f1xx.c @@ -0,0 +1,197 @@ +/* + * STM32 Microcontroller + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "stm32f1xx.h" +#include "exec/address-spaces.h" + +/* PERIPHERALS */ + +static const char *stm32f1xx_periph_name_arr[] = { + ENUM_STRING(STM32F1XX_RCC), + ENUM_STRING(STM32F1XX_GPIOA), + ENUM_STRING(STM32F1XX_GPIOB), + ENUM_STRING(STM32F1XX_GPIOC), + ENUM_STRING(STM32F1XX_GPIOD), + ENUM_STRING(STM32F1XX_GPIOE), + ENUM_STRING(STM32F1XX_GPIOF), + ENUM_STRING(STM32F1XX_GPIOG), + ENUM_STRING(STM32F1XX_AFIO), + ENUM_STRING(STM32F1XX_UART1), + ENUM_STRING(STM32F1XX_UART2), + ENUM_STRING(STM32F1XX_UART3), + ENUM_STRING(STM32F1XX_UART4), + ENUM_STRING(STM32F1XX_UART5), + ENUM_STRING(STM32F1XX_ADC1), + ENUM_STRING(STM32F1XX_ADC2), + ENUM_STRING(STM32F1XX_ADC3), + ENUM_STRING(STM32F1XX_DAC), + ENUM_STRING(STM32F1XX_TIM1), + ENUM_STRING(STM32F1XX_TIM2), + ENUM_STRING(STM32F1XX_TIM3), + ENUM_STRING(STM32F1XX_TIM4), + ENUM_STRING(STM32F1XX_TIM5), + ENUM_STRING(STM32F1XX_TIM6), + ENUM_STRING(STM32F1XX_TIM7), + ENUM_STRING(STM32F1XX_TIM8), + ENUM_STRING(STM32F1XX_BKP), + ENUM_STRING(STM32F1XX_PWR), + ENUM_STRING(STM32F1XX_I2C1), + ENUM_STRING(STM32F1XX_I2C2), + ENUM_STRING(STM32F1XX_I2S2), + ENUM_STRING(STM32F1XX_I2S3), + ENUM_STRING(STM32F1XX_WWDG), + ENUM_STRING(STM32F1XX_CAN1), + ENUM_STRING(STM32F1XX_CAN2), + ENUM_STRING(STM32F1XX_CAN), + ENUM_STRING(STM32F1XX_USB), + ENUM_STRING(STM32F1XX_SPI1), + ENUM_STRING(STM32F1XX_SPI2), + ENUM_STRING(STM32F1XX_SPI3), + ENUM_STRING(STM32F1XX_EXTI), + ENUM_STRING(STM32F1XX_SDIO), + ENUM_STRING(STM32F1XX_FSMC), + ENUM_STRING(STM32F1XX_PERIPH_COUNT), +}; + +void stm32f1xx_init( + ram_addr_t flash_size, + ram_addr_t sram_size, + const char *kernel_filename, + Stm32Gpio *stm32_gpio[], + Stm32Uart *stm32_uart[], + uint32_t osc_freq, + uint32_t osc32_freq) +{ + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *flash_alias_mem = g_malloc(sizeof(MemoryRegion)); + DeviceState *nvic; + int i; + + Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); + + nvic = armv7m_init( + stm32_container, + address_space_mem, + flash_size, + sram_size, + 0, /* default number of irqs */ + kernel_filename, + "cortex-m3"); + + /* The STM32 family stores its Flash memory at some base address in memory + * (0x08000000 for medium density devices), and then aliases it to the + * boot memory space, which starts at 0x00000000 (the "System Memory" can also + * be aliased to 0x00000000, but this is not implemented here). The processor + * executes the code in the aliased memory at 0x00000000. We need to make a + * QEMU alias so that reads in the 0x08000000 area are passed through to the + * 0x00000000 area. Note that this is the opposite of real hardware, where the + * memory at 0x00000000 passes reads through the "real" flash memory at + * 0x08000000, but it works the same either way. */ + /* TODO: Parameterize the base address of the aliased memory. */ + memory_region_init_alias( + flash_alias_mem, + NULL, + "stm32-flash-alias-mem", + address_space_mem, + 0, + flash_size); + memory_region_add_subregion(address_space_mem, 0x08000000, flash_alias_mem); + + DeviceState *rcc_dev = qdev_create(NULL, "stm32f1xx_rcc"); + qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); + qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); + object_property_add_child(stm32_container, "stm32f1xx_rcc", OBJECT(rcc_dev), NULL); + stm32_init_periph(rcc_dev, STM32_RCC_PERIPH, 0x40021000, qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); + + DeviceState **gpio_dev = (DeviceState **)stm32_gpio; + for(i = 0; i < STM32F1XX_GPIO_COUNT; i++) { + char child_name[8]; + stm32_periph_t periph = STM32_GPIOA + i; + gpio_dev[i] = qdev_create(NULL, TYPE_STM32_GPIO); + gpio_dev[i]->id = stm32f1xx_periph_name_arr[periph]; + QDEV_PROP_SET_PERIPH_T(gpio_dev[i], "periph", periph); + qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); + snprintf(child_name, sizeof(child_name), "gpio[%c]", 'a' + i); + object_property_add_child(stm32_container, child_name, OBJECT(gpio_dev[i]), NULL); + stm32_init_periph(gpio_dev[i], periph, 0x40010800 + (i * 0x400), NULL); + } + + DeviceState *exti_dev = qdev_create(NULL, TYPE_STM32_EXTI); + object_property_add_child(stm32_container, "exti", OBJECT(exti_dev), NULL); + stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40010400, NULL); + SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); + sysbus_connect_irq(exti_busdev, 0, qdev_get_gpio_in(nvic, STM32_EXTI0_IRQ)); + sysbus_connect_irq(exti_busdev, 1, qdev_get_gpio_in(nvic, STM32_EXTI1_IRQ)); + sysbus_connect_irq(exti_busdev, 2, qdev_get_gpio_in(nvic, STM32_EXTI2_IRQ)); + sysbus_connect_irq(exti_busdev, 3, qdev_get_gpio_in(nvic, STM32_EXTI3_IRQ)); + sysbus_connect_irq(exti_busdev, 4, qdev_get_gpio_in(nvic, STM32_EXTI4_IRQ)); + sysbus_connect_irq(exti_busdev, 5, qdev_get_gpio_in(nvic, STM32_EXTI9_5_IRQ)); + sysbus_connect_irq(exti_busdev, 6, qdev_get_gpio_in(nvic, STM32_EXTI15_10_IRQ)); + sysbus_connect_irq(exti_busdev, 7, qdev_get_gpio_in(nvic, STM32_PVD_IRQ)); + sysbus_connect_irq(exti_busdev, 8, qdev_get_gpio_in(nvic, STM32_RTCAlarm_IRQ)); + sysbus_connect_irq(exti_busdev, 9, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + + DeviceState *afio_dev = qdev_create(NULL, TYPE_STM32_AFIO); + qdev_prop_set_ptr(afio_dev, "stm32_rcc", rcc_dev); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[0]), "gpio[a]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[1]), "gpio[b]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[2]), "gpio[c]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[3]), "gpio[d]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[4]), "gpio[e]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[5]), "gpio[f]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(gpio_dev[6]), "gpio[g]", NULL); + object_property_set_link(OBJECT(afio_dev), OBJECT(exti_dev), "exti", NULL); + object_property_add_child(stm32_container, "afio", OBJECT(afio_dev), NULL); + stm32_init_periph(afio_dev, STM32_AFIO_PERIPH, 0x40010000, NULL); + + // Create UARTs: + struct { + uint32_t addr; + uint8_t irq_idx; + } const uart_desc[] = { + {0x40013800, STM32_UART1_IRQ}, + {0x40004400, STM32_UART2_IRQ}, + {0x40004800, STM32_UART3_IRQ}, + {0x40004c00, STM32_UART4_IRQ}, + {0x40005000, STM32_UART5_IRQ}, + }; + for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { + const stm32_periph_t periph = STM32F1XX_UART1 + i; + DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + uart_dev->id = stm32f1xx_periph_name_arr[periph]; + qdev_prop_set_int32(uart_dev, "periph", periph); + qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); + qdev_prop_set_ptr(uart_dev, "stm32_gpio", gpio_dev); + qdev_prop_set_ptr(uart_dev, "stm32_afio", afio_dev); + qdev_prop_set_ptr(uart_dev, "stm32_check_tx_pin_callback", (void *)stm32_afio_uart_check_tx_pin_callback); + stm32_init_periph(uart_dev, periph, uart_desc[i].addr, + qdev_get_gpio_in(nvic, uart_desc[i].irq_idx)); + stm32_uart[i] = (Stm32Uart*)uart_dev; + } + /* + stm32_create_uart_dev(stm32_container, STM32_UART1, 1, rcc_dev, gpio_dev, afio_dev, 0x40013800, pic[STM32_UART1_IRQ]); + stm32_create_uart_dev(stm32_container, STM32_UART2, 2, rcc_dev, gpio_dev, afio_dev, 0x40004400, pic[STM32_UART2_IRQ]); + stm32_create_uart_dev(stm32_container, STM32_UART3, 3, rcc_dev, gpio_dev, afio_dev, 0x40004800, pic[STM32_UART3_IRQ]); + stm32_create_uart_dev(stm32_container, STM32_UART4, 4, rcc_dev, gpio_dev, afio_dev, 0x40004c00, pic[STM32_UART4_IRQ]); + stm32_create_uart_dev(stm32_container, STM32_UART5, 5, rcc_dev, gpio_dev, afio_dev, 0x40005000, pic[STM32_UART5_IRQ]); + */ +} diff --git a/hw/arm/stm32f1xx.h b/hw/arm/stm32f1xx.h new file mode 100644 index 0000000000000..e30591c470ba4 --- /dev/null +++ b/hw/arm/stm32f1xx.h @@ -0,0 +1,61 @@ +#include "hw/arm/stm32.h" + +enum { + STM32F1XX_PERIPH_UNDEFINED = -1, + STM32F1XX_RCC = 0, + STM32F1XX_GPIOA, + STM32F1XX_GPIOB, + STM32F1XX_GPIOC, + STM32F1XX_GPIOD, + STM32F1XX_GPIOE, + STM32F1XX_GPIOF, + STM32F1XX_GPIOG, + STM32F1XX_GPIOH, + STM32F1XX_GPIOI, + STM32F1XX_GPIOJ, + STM32F1XX_GPIOK, + STM32F1XX_SYSCFG, + STM32F1XX_AFIO, + STM32F1XX_UART1, + STM32F1XX_UART2, + STM32F1XX_UART3, + STM32F1XX_UART4, + STM32F1XX_UART5, + STM32F1XX_UART6, + STM32F1XX_UART7, + STM32F1XX_UART8, + STM32F1XX_ADC1, + STM32F1XX_ADC2, + STM32F1XX_ADC3, + STM32F1XX_DAC, + STM32F1XX_TIM1, + STM32F1XX_TIM2, + STM32F1XX_TIM3, + STM32F1XX_TIM4, + STM32F1XX_TIM5, + STM32F1XX_TIM6, + STM32F1XX_TIM7, + STM32F1XX_TIM8, + STM32F1XX_BKP, + STM32F1XX_PWR, + STM32F1XX_I2C1, + STM32F1XX_I2C2, + STM32F1XX_I2S2, + STM32F1XX_I2S3, + STM32F1XX_WWDG, + STM32F1XX_CAN1, + STM32F1XX_CAN2, + STM32F1XX_CAN, + STM32F1XX_USB, + STM32F1XX_SPI1, + STM32F1XX_SPI2, + STM32F1XX_SPI3, + STM32F1XX_EXTI, + STM32F1XX_SDIO, + STM32F1XX_FSMC, + STM32F1XX_PERIPH_COUNT, +}; + +const char *stm32f1xx_periph_name(stm32_periph_t periph); + +#define STM32F1XX_GPIO_COUNT (STM32F1XX_GPIOG - STM32F1XX_GPIOA + 1) diff --git a/hw/arm/stm32f1xx_rcc.c b/hw/arm/stm32f1xx_rcc.c new file mode 100644 index 0000000000000..10458680dab3e --- /dev/null +++ b/hw/arm/stm32f1xx_rcc.c @@ -0,0 +1,685 @@ +/* + * STM32 Microcontroller RCC (Reset and Clock Control) module + * + * Copyright (C) 2010 Andre Beckus + * + * Source code based on omap_clk.c + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "stm32f1xx_rcc.h" +#include "qemu/timer.h" +#include + + +/* DEFINITIONS*/ + +/* See README for DEBUG details. */ +//#define DEBUG_STM32_RCC + +#ifdef DEBUG_STM32_RCC +#define DPRINTF(fmt, ...) \ +do { printf("STM32F1XX_RCC: " fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define HSI_FREQ 8000000 +#define LSI_FREQ 40000 + +#define RCC_CR_OFFSET 0x00 +#define RCC_CR_PLL3RDY_CL_BIT 29 +#define RCC_CR_PLL3ON_CL_BIT 28 +#define RCC_CR_PLL2RDY_CL_BIT 27 +#define RCC_CR_PLL2ON_CL_BIT 26 +#define RCC_CR_PLLRDY_BIT 25 +#define RCC_CR_PLLON_BIT 24 +#define RCC_CR_CSSON_BIT 19 +#define RCC_CR_HSEBYP_BIT 18 +#define RCC_CR_HSERDY_BIT 17 +#define RCC_CR_HSEON_BIT 16 +#define RCC_CR_HSICAL_START 8 +#define RCC_CR_HSICAL_MASK 0x0000ff00 +#define RCC_CR_HSITRIM_START 3 +#define RCC_CR_HSITRIM_MASK 0x000000f8 +#define RCC_CR_HSIRDY_BIT 1 +#define RCC_CR_HSION_BIT 0 + +#define RCC_CFGR_OFFSET 0x04 +#define RCC_CFGR_MCO_START 24 +#define RCC_CFGR_MCO_MASK 0x07000000 +#define RCC_CFGR_MCO_CL_MASK 0x0f000000 +#define RCC_CFGR_USBPRE_BIT 22 +#define RCC_CFGR_OTGFSPRE_CL_BIT 22 +#define RCC_CFGR_PLLMUL_START 18 +#define RCC_CFGR_PLLMUL_MASK 0x003c0000 +#define RCC_CFGR_PLLXTPRE_BIT 17 +#define RCC_CFGR_PLLSRC_BIT 16 +#define RCC_CFGR_ADCPRE_START 14 +#define RCC_CFGR_ADCPRE_MASK 0x0000c000 +#define RCC_CFGR_PPRE2_START 11 +#define RCC_CFGR_PPRE2_MASK 0x00003c00 +#define RCC_CFGR_PPRE1_START 8 +#define RCC_CFGR_PPRE1_MASK 0x00000700 +#define RCC_CFGR_HPRE_START 4 +#define RCC_CFGR_HPRE_MASK 0x000000f0 +#define RCC_CFGR_SWS_START 2 +#define RCC_CFGR_SWS_MASK 0x0000000c +#define RCC_CFGR_SW_START 0 +#define RCC_CFGR_SW_MASK 0x00000003 + +#define RCC_CIR_OFFSET 0x08 + +#define RCC_APB2RSTR_OFFSET 0x0c + +#define RCC_APB1RSTR_OFFSET 0x10 + +#define RCC_AHBENR_OFFSET 0x14 + +#define RCC_APB2ENR_OFFSET 0x18 +#define RCC_APB2ENR_ADC3EN_BIT 15 +#define RCC_APB2ENR_USART1EN_BIT 14 +#define RCC_APB2ENR_TIM8EN_BIT 13 +#define RCC_APB2ENR_SPI1EN_BIT 12 +#define RCC_APB2ENR_TIM1EN_BIT 11 +#define RCC_APB2ENR_ADC2EN_BIT 10 +#define RCC_APB2ENR_ADC1EN_BIT 9 +#define RCC_APB2ENR_IOPGEN_BIT 8 +#define RCC_APB2ENR_IOPFEN_BIT 7 +#define RCC_APB2ENR_IOPEEN_BIT 6 +#define RCC_APB2ENR_IOPDEN_BIT 5 +#define RCC_APB2ENR_IOPCEN_BIT 4 +#define RCC_APB2ENR_IOPBEN_BIT 3 +#define RCC_APB2ENR_IOPAEN_BIT 2 +#define RCC_APB2ENR_AFIOEN_BIT 0 + +#define RCC_APB1ENR_OFFSET 0x1c +#define RCC_APB1ENR_DACEN_BIT 29 +#define RCC_APB1ENR_PWREN_BIT 28 +#define RCC_APB1ENR_BKPEN_BIT 27 +#define RCC_APB1ENR_CAN2EN_BIT 26 +#define RCC_APB1ENR_CAN1EN_BIT 25 +#define RCC_APB1ENR_CANEN_BIT 25 +#define RCC_APB1ENR_USBEN_BIT 23 +#define RCC_APB1ENR_I2C2EN_BIT 22 +#define RCC_APB1ENR_I2C1EN_BIT 21 +#define RCC_APB1ENR_USART5EN_BIT 20 +#define RCC_APB1ENR_USART4EN_BIT 19 +#define RCC_APB1ENR_USART3EN_BIT 18 +#define RCC_APB1ENR_USART2EN_BIT 17 +#define RCC_APB1ENR_SPI3EN_BIT 15 +#define RCC_APB1ENR_SPI2EN_BIT 14 +#define RCC_APB1ENR_WWDGEN_BIT 11 +#define RCC_APB1ENR_TIM7EN_BIT 5 +#define RCC_APB1ENR_TIM6EN_BIT 4 +#define RCC_APB1ENR_TIM5EN_BIT 3 +#define RCC_APB1ENR_TIM4EN_BIT 2 +#define RCC_APB1ENR_TIM3EN_BIT 1 +#define RCC_APB1ENR_TIM2EN_BIT 0 + +#define RCC_BDCR_OFFSET 0x20 +#define RCC_BDCR_RTCEN_BIT 15 +#define RCC_BDCR_RTCSEL_START 8 +#define RCC_BDCR_RTCSEL_MASK 0x00000300 +#define RCC_BDCR_LSERDY_BIT 1 +#define RCC_BDCR_LSEON_BIT 0 + +#define RCC_CSR_OFFSET 0x24 +#define RCC_CSR_LSIRDY_BIT 1 +#define RCC_CSR_LSION_BIT 0 + +#define RCC_AHBRSTR 0x28 + +#define RCC_CFGR2_OFFSET 0x2c +#define RCC_CFGR2_I2S3SRC_BIT 18 +#define RCC_CFGR2_I2S2SRC_BIT 17 +#define RCC_CFGR2_PREDIV1SRC_BIT 16 +#define RCC_CFGR2_PLL3MUL_START 12 +#define RCC_CFGR2_PLL3MUL_MASK 0x0000f000 +#define RCC_CFGR2_PLL2MUL_START 8 +#define RCC_CFGR2_PLL2MUL_MASK 0x00000f00 +#define RCC_CFGR2_PREDIV2_START 4 +#define RCC_CFGR2_PREDIV2_MASK 0x000000f0 +#define RCC_CFGR2_PREDIV_START 0 +#define RCC_CFGR2_PREDIV_MASK 0x0000000f +#define RCC_CFGR2_PLLXTPRE_BIT 0 + +#define PLLSRC_HSI_SELECTED 0 +#define PLLSRC_HSE_SELECTED 1 + +#define SW_HSI_SELECTED 0 +#define SW_HSE_SELECTED 1 +#define SW_PLL_SELECTED 2 + + +/* HELPER FUNCTIONS */ + +/* Enable the peripheral clock if the specified bit is set in the value. */ +static void stm32_rcc_periph_enable( + Stm32Rcc *s, + uint32_t new_value, + bool init, + int periph, + uint32_t bit_mask) +{ + clktree_set_enabled(s->PERIPHCLK[periph], IS_BIT_SET(new_value, bit_mask)); +} + + + + + +/* REGISTER IMPLEMENTATION */ + +/* Read the configuration register. */ +static uint32_t stm32_rcc_RCC_CR_read(Stm32f1xxRcc *s) +{ + /* Get the status of the clocks. */ + bool PLLON = clktree_is_enabled(s->PLLCLK); + bool HSEON = clktree_is_enabled(s->HSECLK); + bool HSION = clktree_is_enabled(s->HSICLK); + + /* build the register value based on the clock states. If a clock is on, + * then its ready bit is always set. + */ + return GET_BIT_MASK(RCC_CR_PLLRDY_BIT, PLLON) | + GET_BIT_MASK(RCC_CR_PLLON_BIT, PLLON) | + GET_BIT_MASK(RCC_CR_HSERDY_BIT, HSEON) | + GET_BIT_MASK(RCC_CR_HSEON_BIT, HSEON) | + GET_BIT_MASK(RCC_CR_HSIRDY_BIT, HSION) | + GET_BIT_MASK(RCC_CR_HSION_BIT, HSION); +} + +/* Write the Configuration Register. + * This updates the states of the corresponding clocks. The bit values are not + * saved - when the register is read, its value will be built using the clock + * states. + */ +static void stm32_rcc_RCC_CR_write(Stm32f1xxRcc *s, uint32_t new_value, bool init) +{ + bool new_PLLON, new_HSEON, new_HSION; + + new_PLLON = IS_BIT_SET(new_value, RCC_CR_PLLON_BIT); + if((clktree_is_enabled(s->PLLCLK) && !new_PLLON) && + s->RCC_CFGR_SW == SW_PLL_SELECTED) { + stm32_hw_warn("PLL cannot be disabled while it is selected as the system clock."); + } + clktree_set_enabled(s->PLLCLK, new_PLLON); + + new_HSEON = IS_BIT_SET(new_value, RCC_CR_HSEON_BIT); + if((clktree_is_enabled(s->HSECLK) && !new_HSEON) && + (s->RCC_CFGR_SW == SW_HSE_SELECTED || + (s->RCC_CFGR_SW == SW_PLL_SELECTED && s->RCC_CFGR_PLLSRC == PLLSRC_HSE_SELECTED) + ) + ) { + stm32_hw_warn("HSE oscillator cannot be disabled while it is driving the system clock."); + } + clktree_set_enabled(s->HSECLK, new_HSEON); + + new_HSION = IS_BIT_SET(new_value, RCC_CR_HSION_BIT); + if((clktree_is_enabled(s->HSECLK) && !new_HSEON) && + (s->RCC_CFGR_SW == SW_HSI_SELECTED || + (s->RCC_CFGR_SW == SW_PLL_SELECTED && s->RCC_CFGR_PLLSRC == PLLSRC_HSI_SELECTED) + ) + ) { + stm32_hw_warn("HSI oscillator cannot be disabled while it is driving the system clock."); + } + clktree_set_enabled(s->HSICLK, new_HSION); +} + + +static uint32_t stm32_rcc_RCC_CFGR_read(Stm32f1xxRcc *s) +{ + return (s->RCC_CFGR_PLLMUL << RCC_CFGR_PLLMUL_START) | + (s->RCC_CFGR_PLLXTPRE << RCC_CFGR_PLLXTPRE_BIT) | + (s->RCC_CFGR_PLLSRC << RCC_CFGR_PLLSRC_BIT) | + (s->RCC_CFGR_PPRE2 << RCC_CFGR_PPRE2_START) | + (s->RCC_CFGR_PPRE1 << RCC_CFGR_PPRE1_START) | + (s->RCC_CFGR_HPRE << RCC_CFGR_HPRE_START) | + (s->RCC_CFGR_SW << RCC_CFGR_SW_START) | + (s->RCC_CFGR_SW << RCC_CFGR_SWS_START); +} + + +static void stm32_rcc_RCC_CFGR_write(Stm32f1xxRcc *s, uint32_t new_value, bool init) +{ + uint32_t new_PLLMUL, new_PLLXTPRE, new_PLLSRC; + + /* PLLMUL */ + new_PLLMUL = (new_value & RCC_CFGR_PLLMUL_MASK) >> RCC_CFGR_PLLMUL_START; + if(!init) { + if(clktree_is_enabled(s->PLLCLK) && + (new_PLLMUL != s->RCC_CFGR_PLLMUL)) { + stm32_hw_warn("Can only change PLLMUL while PLL is disabled"); + } + } + assert(new_PLLMUL <= 0xf); + if(new_PLLMUL == 0xf) { + clktree_set_scale(s->PLLCLK, 16, 1); + } else { + clktree_set_scale(s->PLLCLK, new_PLLMUL + 2, 1); + } + s->RCC_CFGR_PLLMUL = new_PLLMUL; + + /* PLLXTPRE */ + new_PLLXTPRE = GET_BIT_VALUE(new_value, RCC_CFGR_PLLXTPRE_BIT); + if(!init) { + if(clktree_is_enabled(s->PLLCLK) && + (new_PLLXTPRE != s->RCC_CFGR_PLLXTPRE)) { + stm32_hw_warn("Can only change PLLXTPRE while PLL is disabled"); + } + } + clktree_set_selected_input(s->PLLXTPRECLK, new_PLLXTPRE); + s->RCC_CFGR_PLLXTPRE = new_PLLXTPRE; + + /* PLLSRC */ + new_PLLSRC = GET_BIT_VALUE(new_value, RCC_CFGR_PLLSRC_BIT); + if(!init) { + if(clktree_is_enabled(s->PLLCLK) && + (new_PLLSRC != s->RCC_CFGR_PLLSRC)) { + stm32_hw_warn("Can only change PLLSRC while PLL is disabled"); + } + } + clktree_set_selected_input(s->PLLCLK, new_PLLSRC); + s->RCC_CFGR_PLLSRC = new_PLLSRC; + + /* PPRE2 */ + s->RCC_CFGR_PPRE2 = (new_value & RCC_CFGR_PPRE2_MASK) >> RCC_CFGR_PPRE2_START; + if(s->RCC_CFGR_PPRE2 < 0x4) { + clktree_set_scale(s->PCLK2, 1, 1); + } else { + clktree_set_scale(s->PCLK2, 1, 2 * (s->RCC_CFGR_PPRE2 - 3)); + } + + /* PPRE1 */ + s->RCC_CFGR_PPRE1 = (new_value & RCC_CFGR_PPRE1_MASK) >> RCC_CFGR_PPRE1_START; + if(s->RCC_CFGR_PPRE1 < 4) { + clktree_set_scale(s->PCLK1, 1, 1); + } else { + clktree_set_scale(s->PCLK1, 1, 2 * (s->RCC_CFGR_PPRE1 - 3)); + } + + /* HPRE */ + s->RCC_CFGR_HPRE = (new_value & RCC_CFGR_HPRE_MASK) >> RCC_CFGR_HPRE_START; + if(s->RCC_CFGR_HPRE < 8) { + clktree_set_scale(s->HCLK, 1, 1); + } else { + clktree_set_scale(s->HCLK, 1, 2 * (s->RCC_CFGR_HPRE - 7)); + } + + /* SW */ + s->RCC_CFGR_SW = (new_value & RCC_CFGR_SW_MASK) >> RCC_CFGR_SW_START; + switch(s->RCC_CFGR_SW) { + case 0x0: + case 0x1: + case 0x2: + clktree_set_selected_input(s->SYSCLK, s->RCC_CFGR_SW); + break; + default: + hw_error("Invalid input selected for SYSCLK"); + break; + } +} + +/* Write the APB2 peripheral clock enable register + * Enables/Disables the peripheral clocks based on each bit. */ +static void stm32_rcc_RCC_APB2ENR_write(Stm32f1xxRcc *s, uint32_t new_value, + bool init) +{ + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_UART1, + RCC_APB2ENR_USART1EN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOE, + RCC_APB2ENR_IOPEEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOD, + RCC_APB2ENR_IOPDEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOC, + RCC_APB2ENR_IOPCEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOB, + RCC_APB2ENR_IOPBEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOA, + RCC_APB2ENR_IOPAEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_AFIO, + RCC_APB2ENR_AFIOEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOG, + RCC_APB2ENR_IOPGEN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_GPIOF, + RCC_APB2ENR_IOPFEN_BIT); + + s->RCC_APB2ENR = new_value & 0x0000fffd; +} + +/* Write the APB1 peripheral clock enable register + * Enables/Disables the peripheral clocks based on each bit. */ +static void stm32_rcc_RCC_APB1ENR_write(Stm32f1xxRcc *s, uint32_t new_value, + bool init) +{ + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_UART5, + RCC_APB1ENR_USART5EN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_UART4, + RCC_APB1ENR_USART4EN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_UART3, + RCC_APB1ENR_USART3EN_BIT); + stm32_rcc_periph_enable(&(s->inherited), new_value, init, STM32F1XX_UART2, + RCC_APB1ENR_USART2EN_BIT); + + s->RCC_APB1ENR = new_value & 0x00005e7d; +} + +static uint32_t stm32_rcc_RCC_BDCR_read(Stm32f1xxRcc *s) +{ + bool lseon = clktree_is_enabled(s->LSECLK); + + return GET_BIT_MASK(RCC_BDCR_LSERDY_BIT, lseon) | + GET_BIT_MASK(RCC_BDCR_LSEON_BIT, lseon); +} + +static void stm32_rcc_RCC_BDCR_write(Stm32f1xxRcc *s, uint32_t new_value, bool init) +{ + clktree_set_enabled(s->LSECLK, IS_BIT_SET(new_value, RCC_BDCR_LSEON_BIT)); +} + +/* Works the same way as stm32_rcc_RCC_CR_read */ +static uint32_t stm32_rcc_RCC_CSR_read(Stm32f1xxRcc *s) +{ + bool lseon = clktree_is_enabled(s->LSICLK); + + return GET_BIT_MASK(RCC_CSR_LSIRDY_BIT, lseon) | + GET_BIT_MASK(RCC_CSR_LSION_BIT, lseon); +} + +/* Works the same way as stm32_rcc_RCC_CR_write */ +static void stm32_rcc_RCC_CSR_write(Stm32f1xxRcc *s, uint32_t new_value, bool init) +{ + clktree_set_enabled(s->LSICLK, IS_BIT_SET(new_value, RCC_CSR_LSION_BIT)); +} + + + +static uint64_t stm32_rcc_readw(void *opaque, hwaddr offset) +{ + Stm32f1xxRcc *s = (Stm32f1xxRcc *)opaque; + + switch (offset) { + case RCC_CR_OFFSET: + return stm32_rcc_RCC_CR_read(s); + case RCC_CFGR_OFFSET: + return stm32_rcc_RCC_CFGR_read(s); + case RCC_CIR_OFFSET: + return 0; + case RCC_APB2RSTR_OFFSET: + case RCC_APB1RSTR_OFFSET: + case RCC_AHBENR_OFFSET: + STM32_NOT_IMPL_REG(offset, 4); + return 0; + case RCC_APB2ENR_OFFSET: + return s->RCC_APB2ENR; + case RCC_APB1ENR_OFFSET: + return s->RCC_APB1ENR; + case RCC_BDCR_OFFSET: + return stm32_rcc_RCC_BDCR_read(s); + case RCC_CSR_OFFSET: + return stm32_rcc_RCC_CSR_read(s); + case RCC_AHBRSTR: + STM32_NOT_IMPL_REG(offset, 4); + return 0; + case RCC_CFGR2_OFFSET: + STM32_NOT_IMPL_REG(offset, 4); + return 0; + default: + STM32_BAD_REG(offset, 4); + break; + } +} + + +static void stm32_rcc_writew(void *opaque, hwaddr offset, + uint64_t value) +{ + Stm32f1xxRcc *s = (Stm32f1xxRcc *)opaque; + + switch(offset) { + case RCC_CR_OFFSET: + stm32_rcc_RCC_CR_write(s, value, false); + break; + case RCC_CFGR_OFFSET: + stm32_rcc_RCC_CFGR_write(s, value, false); + break; + case RCC_CIR_OFFSET: + /* Allow a write but don't take any action */ + break; + case RCC_APB2RSTR_OFFSET: + case RCC_APB1RSTR_OFFSET: + case RCC_AHBENR_OFFSET: + STM32_NOT_IMPL_REG(offset, 4); + break; + case RCC_APB2ENR_OFFSET: + stm32_rcc_RCC_APB2ENR_write(s, value, false); + break; + case RCC_APB1ENR_OFFSET: + stm32_rcc_RCC_APB1ENR_write(s, value, false); + break; + case RCC_BDCR_OFFSET: + stm32_rcc_RCC_BDCR_write(s, value, false); + break; + case RCC_CSR_OFFSET: + stm32_rcc_RCC_CSR_write(s, value, false); + break; + case RCC_AHBRSTR: + STM32_NOT_IMPL_REG(offset, 4); + break; + case RCC_CFGR2_OFFSET: + STM32_NOT_IMPL_REG(offset, 4); + break; + default: + STM32_BAD_REG(offset, 4); + break; + } +} + +static uint64_t stm32_rcc_read(void *opaque, hwaddr offset, + unsigned size) +{ + switch(size) { + case 4: + return stm32_rcc_readw(opaque, offset); + default: + STM32_NOT_IMPL_REG(offset, size); + return 0; + } +} + +static void stm32_rcc_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + switch(size) { + case 4: + stm32_rcc_writew(opaque, offset, value); + break; + default: + STM32_NOT_IMPL_REG(offset, size); + break; + } +} + +static const MemoryRegionOps stm32_rcc_ops = { + .read = stm32_rcc_read, + .write = stm32_rcc_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + + +static void stm32_rcc_reset(DeviceState *dev) +{ + Stm32f1xxRcc *s = FROM_SYSBUS(Stm32f1xxRcc, SYS_BUS_DEVICE(dev)); + + stm32_rcc_RCC_CR_write(s, 0x00000083, true); + stm32_rcc_RCC_CFGR_write(s, 0x00000000, true); + stm32_rcc_RCC_APB2ENR_write(s, 0x00000000, true); + stm32_rcc_RCC_APB1ENR_write(s, 0x00000000, true); + stm32_rcc_RCC_BDCR_write(s, 0x00000000, true); + stm32_rcc_RCC_CSR_write(s, 0x0c000000, true); +} + +/* IRQ handler to handle updates to the HCLK frequency. + * This updates the SysTick scales. */ +static void stm32_rcc_hclk_upd_irq_handler(void *opaque, int n, int level) +{ + Stm32f1xxRcc *s = (Stm32f1xxRcc *)opaque; + + uint32_t hclk_freq = 0; + uint32_t ext_ref_freq = 0; + + hclk_freq = clktree_get_output_freq(s->HCLK); + + /* Only update the scales if the frequency is not zero. */ + if (hclk_freq > 0) { + ext_ref_freq = hclk_freq / 8; + + /* Update the scales - these are the ratio of QEMU clock ticks + * (which is an unchanging number independent of the CPU frequency) to + * system/external clock ticks. + */ + system_clock_scale = get_ticks_per_sec() / hclk_freq; + } + +#ifdef DEBUG_STM32_RCC + DPRINTF("Cortex SYSTICK frequency set to %lu Hz (scale set to %d).\n", + (unsigned long)hclk_freq, system_clock_scale); +#endif +} + + + + +/* DEVICE INITIALIZATION */ + +/* Set up the clock tree */ +static void stm32_rcc_init_clk(Stm32f1xxRcc *s) +{ + int i; + qemu_irq *hclk_upd_irq = + qemu_allocate_irqs(stm32_rcc_hclk_upd_irq_handler, s, 1); + Clk HSI_DIV2, HSE_DIV2; + + /* Make sure all the peripheral clocks are null initially. + * This will be used for error checking to make sure + * an invalid clock is not referenced (not all of the + * indexes will be used). + */ + for(i = 0; i < STM32F1XX_PERIPH_COUNT; i++) { + s->PERIPHCLK[i] = NULL; + } + + /* Initialize clocks */ + /* Source clocks are initially disabled, which represents + * a disabled oscillator. Enabling the clock represents + * turning the clock on. + */ + s->HSICLK = clktree_create_src_clk("HSI", HSI_FREQ, false); + s->LSICLK = clktree_create_src_clk("LSI", LSI_FREQ, false); + s->HSECLK = clktree_create_src_clk("HSE", s->osc_freq, false); + s->LSECLK = clktree_create_src_clk("LSE", s->osc32_freq, false); + + HSI_DIV2 = clktree_create_clk("HSI/2", 1, 2, true, CLKTREE_NO_MAX_FREQ, 0, + s->HSICLK, NULL); + HSE_DIV2 = clktree_create_clk("HSE/2", 1, 2, true, CLKTREE_NO_MAX_FREQ, 0, + s->HSECLK, NULL); + + s->PLLXTPRECLK = clktree_create_clk("PLLXTPRE", 1, 1, true, CLKTREE_NO_MAX_FREQ, CLKTREE_NO_INPUT, + s->HSECLK, HSE_DIV2, NULL); + /* PLLCLK contains both the switch and the multiplier, which are shown as + * two separate components in the clock tree diagram. + */ + s->PLLCLK = clktree_create_clk("PLLCLK", 0, 1, false, 72000000, CLKTREE_NO_INPUT, + HSI_DIV2, s->PLLXTPRECLK, NULL); + + s->SYSCLK = clktree_create_clk("SYSCLK", 1, 1, true, 72000000, CLKTREE_NO_INPUT, + s->HSICLK, s->HSECLK, s->PLLCLK, NULL); + + s->HCLK = clktree_create_clk("HCLK", 0, 1, true, 72000000, 0, + s->SYSCLK, NULL); + clktree_adduser(s->HCLK, hclk_upd_irq[0]); + + s->PCLK1 = clktree_create_clk("PCLK1", 0, 1, true, 36000000, 0, + s->HCLK, NULL); + s->PCLK2 = clktree_create_clk("PCLK2", 0, 1, true, 72000000, 0, + s->HCLK, NULL); + + /* Peripheral clocks */ + s->PERIPHCLK[STM32F1XX_GPIOA] = clktree_create_clk("GPIOA", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_GPIOB] = clktree_create_clk("GPIOB", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_GPIOC] = clktree_create_clk("GPIOC", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_GPIOD] = clktree_create_clk("GPIOD", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_GPIOE] = clktree_create_clk("GPIOE", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_GPIOF] = clktree_create_clk("GPIOF", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_GPIOG] = clktree_create_clk("GPIOG", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + + s->PERIPHCLK[STM32F1XX_AFIO] = clktree_create_clk("AFIO", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + + s->PERIPHCLK[STM32F1XX_UART1] = clktree_create_clk("UART1", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32F1XX_UART2] = clktree_create_clk("UART2", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32F1XX_UART3] = clktree_create_clk("UART3", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32F1XX_UART4] = clktree_create_clk("UART4", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32F1XX_UART5] = clktree_create_clk("UART5", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); +} + +static int stm32_rcc_init(SysBusDevice *dev) +{ + Stm32f1xxRcc *s = FROM_SYSBUS(Stm32f1xxRcc, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_rcc_ops, s, + "rcc", 0x1000); + + sysbus_init_mmio(dev, &s->iomem); + + sysbus_init_irq(dev, &s->irq); + + stm32_rcc_init_clk(s); + + return 0; +} + + +static Property stm32_rcc_properties[] = { + DEFINE_PROP_UINT32("osc_freq", Stm32Rcc, osc_freq, 0), + DEFINE_PROP_UINT32("osc32_freq", Stm32Rcc, osc32_freq, 0), + DEFINE_PROP_END_OF_LIST() +}; + + +static void stm32_rcc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_rcc_init; + dc->reset = stm32_rcc_reset; + dc->props = stm32_rcc_properties; +} + +static TypeInfo stm32_rcc_info = { + .name = "stm32f1xx_rcc", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32f1xxRcc), + .class_init = stm32_rcc_class_init +}; + +static void stm32_rcc_register_types(void) +{ + type_register_static(&stm32_rcc_info); +} + +type_init(stm32_rcc_register_types) diff --git a/hw/arm/stm32f1xx_rcc.h b/hw/arm/stm32f1xx_rcc.h new file mode 100644 index 0000000000000..fe9bb9b96e036 --- /dev/null +++ b/hw/arm/stm32f1xx_rcc.h @@ -0,0 +1,51 @@ +#include "hw/sysbus.h" +#include "hw/arm/stm32_clktree.h" +#include "stm32f1xx.h" +#include "stm32_rcc.h" + +typedef struct Stm32f1xxRcc { + /* Inherited */ + union { + Stm32Rcc inherited; + struct { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + uint32_t osc_freq; + uint32_t osc32_freq; + + /* Private */ + MemoryRegion iomem; + qemu_irq irq; + }; + }; + + Clk PERIPHCLK[STM32F1XX_PERIPH_COUNT], // MUST be first field after `inherited`, because Stm32Rcc's last field aliases this array + HSICLK, + HSECLK, + LSECLK, + LSICLK, + SYSCLK, + PLLXTPRECLK, + PLLCLK, + HCLK, /* Output from AHB Prescaler */ + PCLK1, /* Output from APB1 Prescaler */ + PCLK2; /* Output from APB2 Prescaler */ + + /* Register Values */ + uint32_t + RCC_APB1ENR, + RCC_APB2ENR; + + /* Register Field Values */ + uint32_t + RCC_CFGR_PLLMUL, + RCC_CFGR_PLLXTPRE, + RCC_CFGR_PLLSRC, + RCC_CFGR_PPRE1, + RCC_CFGR_PPRE2, + RCC_CFGR_HPRE, + RCC_CFGR_SW; + +} Stm32f1xxRcc; diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index 118c3425591cc..4c24b60d92a80 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -105,6 +105,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) &error_fatal); memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram); +<<<<<<< HEAD armv7m = DEVICE(&s->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 96); qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type); @@ -116,6 +117,10 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) error_propagate(errp, err); return; } +======= + nvic = armv7m_init(/* no parent */ NULL, get_system_memory(), FLASH_SIZE, SRAM_SIZE, 96, + s->kernel_filename, s->cpu_model); +>>>>>>> 919b29ba7d... Pebble Qemu /* System configuration controller */ dev = DEVICE(&s->syscfg); diff --git a/hw/arm/stm32f2xx.c b/hw/arm/stm32f2xx.c new file mode 100644 index 0000000000000..d8397d95495b8 --- /dev/null +++ b/hw/arm/stm32f2xx.c @@ -0,0 +1,382 @@ +/* + * STM32 Microcontroller + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "stm32f2xx.h" +#include "exec/address-spaces.h" +#include "exec/memory.h" +#include "hw/ssi.h" +#include "hw/block/flash.h" +#include "sysemu/blockdev.h" // drive_get + +static const char *stm32f2xx_periph_name_arr[] = { + ENUM_STRING(STM32_UART1), + ENUM_STRING(STM32_UART2), + ENUM_STRING(STM32_UART3), + ENUM_STRING(STM32_UART4), + ENUM_STRING(STM32_UART5), + ENUM_STRING(STM32_UART6), + + ENUM_STRING(STM32_SPI1), + ENUM_STRING(STM32_SPI2), + ENUM_STRING(STM32_SPI3), + + ENUM_STRING(STM32_I2C1), + ENUM_STRING(STM32_I2C2), + ENUM_STRING(STM32_I2C3), + + ENUM_STRING(STM32_TIM1), + ENUM_STRING(STM32_TIM2), + ENUM_STRING(STM32_TIM3), + ENUM_STRING(STM32_TIM4), + ENUM_STRING(STM32_TIM5), + ENUM_STRING(STM32_TIM6), + ENUM_STRING(STM32_TIM7), + ENUM_STRING(STM32_TIM8), + ENUM_STRING(STM32_TIM9), + ENUM_STRING(STM32_TIM10), + ENUM_STRING(STM32_TIM11), + ENUM_STRING(STM32_TIM12), + ENUM_STRING(STM32_TIM13), + ENUM_STRING(STM32_TIM14), + + ENUM_STRING(STM32_GPIOA), + ENUM_STRING(STM32_GPIOB), + ENUM_STRING(STM32_GPIOC), + ENUM_STRING(STM32_GPIOD), + ENUM_STRING(STM32_GPIOE), + ENUM_STRING(STM32_GPIOF), + ENUM_STRING(STM32_GPIOG), + ENUM_STRING(STM32_GPIOH), + ENUM_STRING(STM32_GPIOI), + ENUM_STRING(STM32_GPIOJ), + ENUM_STRING(STM32_GPIOK), + + ENUM_STRING(STM32_PERIPH_COUNT) +}; + +/* Init STM32F2XX CPU and memory. + flash_size and sram_size are in kb. */ + +static uint64_t kernel_load_translate_fn(void *opaque, uint64_t from_addr) { + if (from_addr == STM32_FLASH_ADDR_START) { + return 0x00000000; + } + return from_addr; +} + +static +void do_sys_reset(void *opaque, int n, int level) +{ + if (level) { + qemu_system_reset_request(); + } +} + +void stm32f2xx_init( + ram_addr_t flash_size, + ram_addr_t ram_size, + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + Stm32Uart **stm32_uart, + Stm32Timer **stm32_timer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f2xx *stm, + ARMCPU **cpu) +{ + MemoryRegion *address_space_mem = get_system_memory(); + DriveInfo *dinfo; + DeviceState *nvic; + int i; + + Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); + + nvic = armv7m_translated_init( + stm32_container, + address_space_mem, + flash_size * 1024, + ram_size * 1024, + 0, /* default number of irqs */ + kernel_filename, + kernel_load_translate_fn, + NULL, + "cortex-m3", + cpu); + + qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, + qemu_allocate_irq(&do_sys_reset, NULL, 0)); + + dinfo = drive_get(IF_PFLASH, 0, 0); + if (dinfo) { + f2xx_flash_register(blk_by_legacy_dinfo(dinfo), 1 * 0x08000000, flash_size * 1024); + } + + // Create alias at 0x08000000 for internal flash, that is hard-coded at 0x00000000 in armv7m.c: + // TODO: Let BOOT0 and BOOT1 configuration pins determine what is mapped at 0x00000000, see SYSCFG_MEMRMP. + + MemoryRegionSection mrs = memory_region_find(address_space_mem, STM32_FLASH_ADDR_START, WORD_ACCESS_SIZE); + MemoryRegion *flash_alias = g_new(MemoryRegion, 1); + memory_region_init_alias( + flash_alias, + NULL, + "stm32f2xx.flash.alias", + mrs.mr, + 0, + flash_size * 1024); + memory_region_add_subregion(address_space_mem, 0, flash_alias); + + DeviceState *rcc_dev = qdev_create(NULL, "stm32f2xx_rcc"); + qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); + qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); + object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); + stm32_init_periph(rcc_dev, STM32_RCC_PERIPH, 0x40023800, + qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); + + DeviceState **gpio_dev = (DeviceState **)g_malloc0(sizeof(DeviceState *) * STM32F2XX_GPIO_COUNT); + for(i = 0; i < STM32F2XX_GPIO_COUNT; i++) { + stm32_periph_t periph = STM32_GPIOA + i; + gpio_dev[i] = qdev_create(NULL, "stm32f2xx_gpio"); + gpio_dev[i]->id = stm32f2xx_periph_name_arr[periph]; + qdev_prop_set_int32(gpio_dev[i], "periph", periph); +// qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); + stm32_init_periph(gpio_dev[i], periph, 0x40020000 + (i * 0x400), NULL); + stm32_gpio[i] = (Stm32Gpio *)gpio_dev[i]; + } + + /* Connect the WKUP pin (GPIO A, pin 0) to the NVIC's WKUP handler */ + qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); + f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); + + + /* EXTI */ + DeviceState *exti_dev = qdev_create(NULL, "stm32_exti"); + qdev_prop_set_ptr(exti_dev, "stm32_gpio", gpio_dev); + stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40013C00, NULL); + SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); + /* IRQs from EXTI to NVIC */ + sysbus_connect_irq(exti_busdev, 0, qdev_get_gpio_in(nvic, STM32_EXTI0_IRQ)); + sysbus_connect_irq(exti_busdev, 1, qdev_get_gpio_in(nvic, STM32_EXTI1_IRQ)); + sysbus_connect_irq(exti_busdev, 2, qdev_get_gpio_in(nvic, STM32_EXTI2_IRQ)); + sysbus_connect_irq(exti_busdev, 3, qdev_get_gpio_in(nvic, STM32_EXTI3_IRQ)); + sysbus_connect_irq(exti_busdev, 4, qdev_get_gpio_in(nvic, STM32_EXTI4_IRQ)); + sysbus_connect_irq(exti_busdev, 5, qdev_get_gpio_in(nvic, STM32_EXTI9_5_IRQ)); + sysbus_connect_irq(exti_busdev, 6, qdev_get_gpio_in(nvic, STM32_EXTI15_10_IRQ)); + sysbus_connect_irq(exti_busdev, 7, qdev_get_gpio_in(nvic, STM32_PVD_IRQ)); + sysbus_connect_irq(exti_busdev, 8, qdev_get_gpio_in(nvic, STM32_RTCAlarm_IRQ)); + sysbus_connect_irq(exti_busdev, 9, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 10, qdev_get_gpio_in(nvic, STM32_ETH_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 11, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 12, qdev_get_gpio_in(nvic, STM32_TAMP_STAMP_IRQ)); + sysbus_connect_irq(exti_busdev, 13, qdev_get_gpio_in(nvic, STM32_RTC_WKUP_IRQ)); + + DeviceState *syscfg_dev = qdev_create(NULL, "stm32f2xx_syscfg"); + qdev_prop_set_ptr(syscfg_dev, "stm32_rcc", rcc_dev); + qdev_prop_set_ptr(syscfg_dev, "stm32_exti", exti_dev); + qdev_prop_set_bit(syscfg_dev, "boot0", 0); + qdev_prop_set_bit(syscfg_dev, "boot1", 0); + stm32_init_periph(syscfg_dev, STM32_SYSCFG, 0x40013800, NULL); + + struct { + uint32_t addr; + uint8_t irq_idx; + } const uart_desc[] = { + {0x40011000, STM32_UART1_IRQ}, + {0x40004400, STM32_UART2_IRQ}, + {0x40004800, STM32_UART3_IRQ}, + {0x40004C00, STM32_UART4_IRQ}, + {0x40005000, STM32_UART5_IRQ}, + {0x40011400, STM32_UART6_IRQ}, + }; + for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { + assert(i < STM32F2XX_UART_COUNT); + const stm32_periph_t periph = STM32_UART1 + i; + DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + uart_dev->id = stm32f2xx_periph_name_arr[periph]; + qdev_prop_set_int32(uart_dev, "periph", periph); + qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); +// qdev_prop_set_ptr(uart_dev, "stm32_gpio", gpio_dev); +// qdev_prop_set_ptr(uart_dev, "stm32_afio", afio_dev); +// qdev_prop_set_ptr(uart_dev, "stm32_check_tx_pin_callback", (void *)stm32_afio_uart_check_tx_pin_callback); + stm32_init_periph(uart_dev, periph, uart_desc[i].addr, + qdev_get_gpio_in(nvic, uart_desc[i].irq_idx)); + stm32_uart[i] = (Stm32Uart *)uart_dev; + } + + + /* SPI */ + struct { + uint32_t addr; + uint8_t irq_idx; + } const spi_desc[] = { + {0x40013000, STM32_SPI1_IRQ}, + {0x40003800, STM32_SPI2_IRQ}, + {0x40003CD0, STM32_SPI3_IRQ}, + }; + for (i = 0; i < ARRAY_LENGTH(spi_desc); ++i) { + const stm32_periph_t periph = STM32_SPI1 + i; + stm->spi_dev[i] = qdev_create(NULL, "stm32f2xx_spi"); + stm->spi_dev[i]->id = stm32f2xx_periph_name_arr[periph]; + qdev_prop_set_int32(stm->spi_dev[i], "periph", periph); + stm32_init_periph(stm->spi_dev[i], periph, spi_desc[i].addr, + qdev_get_gpio_in(nvic, spi_desc[i].irq_idx)); + + } + +// stm32_uart[STM32_UART1_INDEX] = stm32_create_uart_dev(STM32_UART1, rcc_dev, gpio_dev, afio_dev, 0x40011000, qdev_get_gpio_in(nvic, STM32_UART1_IRQ]); +// stm32_uart[STM32_UART2_INDEX] = stm32_create_uart_dev(STM32_UART2, rcc_dev, gpio_dev, afio_dev, 0x40004400, qdev_get_gpio_in(nvic, STM32_UART2_IRQ]); +// stm32_uart[STM32_UART3_INDEX] = stm32_create_uart_dev(STM32_UART3, rcc_dev, gpio_dev, afio_dev, 0x40004800, qdev_get_gpio_in(nvic, STM32_UART3_IRQ]); +// stm32_uart[STM32_UART4_INDEX] = stm32_create_uart_dev(STM32_UART4, rcc_dev, gpio_dev, afio_dev, 0x40004C00, qdev_get_gpio_in(nvic, STM32_UART4_IRQ]); +// stm32_uart[STM32_UART5_INDEX] = stm32_create_uart_dev(STM32_UART5, rcc_dev, gpio_dev, afio_dev, 0x40005000, qdev_get_gpio_in(nvic, STM32_UART5_IRQ]); +// stm32_uart[STM32_UART6_INDEX] = stm32_create_uart_dev(STM32_UART6, rcc_dev, gpio_dev, afio_dev, 0x40011400, qdev_get_gpio_in(nvic, STM32_UART6_IRQ]); + DeviceState *adc_dev = qdev_create(NULL, "stm32f2xx_adc"); + stm32_init_periph(adc_dev, STM32_ADC1, 0x40012000, NULL); + + /* RTC real time clock */ + DeviceState *rtc_dev = qdev_create(NULL, "f2xx_rtc"); + *stm32_rtc = rtc_dev; + stm32_init_periph(rtc_dev, STM32_RTC, 0x40002800, NULL); + // Alarm A + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 0, qdev_get_gpio_in(exti_dev, 17)); + // Alarm B + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 1, qdev_get_gpio_in(exti_dev, 17)); + // Wake up timer + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 2, qdev_get_gpio_in(exti_dev, 22)); + + /* Power management */ + DeviceState *pwr_dev = qdev_create(NULL, "f2xx_pwr"); + stm32_init_periph(pwr_dev, STM32_RTC, 0x40007000, NULL); + qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); + + +#define dummy_dev(name, start, size) do {\ + DeviceState *dummy = qdev_create(NULL, "f2xx_dummy"); \ + qdev_prop_set_ptr(dummy, "name", (void *)name); \ + qdev_prop_set_int32(dummy, "size", size); \ + qdev_init_nofail(dummy); \ + sysbus_mmio_map(SYS_BUS_DEVICE(dummy), 0, start); \ +} while (0) + + /* Timers */ + struct { + uint8_t timer_num; + uint32_t addr; + uint8_t irq_idx; + } const timer_desc[] = { + {2, 0x40000000, STM32_TIM2_IRQ}, + {3, 0x40000400, STM32_TIM3_IRQ}, + {4, 0x40000800, STM32_TIM4_IRQ}, + {5, 0x40000C00, STM32_TIM5_IRQ}, + {6, 0x40001000, STM32_TIM6_IRQ}, + {7, 0x40001400, STM32_TIM7_IRQ}, + {9, 0x40014000, STM32_TIM1_BRK_TIM9_IRQ}, + {10, 0x40014400, STM32_TIM1_UP_TIM10_IRQ}, + {11, 0x40014800, STM32_TIM1_TRG_COM_TIM11_IRQ}, + {12, 0x40001800, STM32_TIM8_BRK_TIM12_IRQ}, + {13, 0x40001C00, STM32_TIM8_UP_TIM13_IRQ}, + {14, 0x40002000, STM32_TIM8_TRG_COMM_TIM14_IRQ}, + }; + for (i = 0; i < ARRAY_LENGTH(timer_desc); ++i) { + assert(i < STM32F2XX_TIM_COUNT); + const stm32_periph_t periph = STM32_TIM1 + timer_desc[i].timer_num - 1; + + DeviceState *timer = qdev_create(NULL, "f2xx_tim"); + timer->id = stm32f2xx_periph_name_arr[periph]; + stm32_init_periph(timer, periph, timer_desc[i].addr, qdev_get_gpio_in(nvic, timer_desc[i].irq_idx)); + stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *)timer; + } + + dummy_dev("Reserved", 0x40002400, 0x400); + // + dummy_dev("WWDG", 0x40002C00, 0x400); + dummy_dev("IWDG", 0x40003000, 0x400); + dummy_dev("Reserved", 0x40003400, 0x400); + // + // + dummy_dev("Reserved", 0x40004000, 0x400); + // + // + // + // + + DeviceState *i2c1 = qdev_create(NULL, "f2xx_i2c"); + i2c1->id = stm32f2xx_periph_name_arr[STM32_I2C1]; + qdev_prop_set_int32(i2c1, "periph", STM32_I2C1); + stm32_init_periph(i2c1, STM32_I2C1, 0x40005400, qdev_get_gpio_in(nvic, STM32_I2C1_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c1), 1, qdev_get_gpio_in(nvic, STM32_I2C1_ER_IRQ)); + + DeviceState *i2c2 = qdev_create(NULL, "f2xx_i2c"); + i2c2->id = stm32f2xx_periph_name_arr[STM32_I2C2]; + qdev_prop_set_int32(i2c2, "periph", STM32_I2C2); + stm32_init_periph(i2c2, STM32_I2C2, 0x40005800, qdev_get_gpio_in(nvic, STM32_I2C2_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c2), 1, qdev_get_gpio_in(nvic, STM32_I2C2_ER_IRQ)); + + DeviceState *i2c3 = qdev_create(NULL, "f2xx_i2c"); + i2c3->id = stm32f2xx_periph_name_arr[STM32_I2C3]; + qdev_prop_set_int32(i2c3, "periph", STM32_I2C3); + stm32_init_periph(i2c3, STM32_I2C2, 0x40005C00, qdev_get_gpio_in(nvic, STM32_I2C3_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c3), 1, qdev_get_gpio_in(nvic, STM32_I2C3_ER_IRQ)); + + dummy_dev("Reserved", 0x40006000, 0x400); + dummy_dev("BxCAN1", 0x40006400, 0x400); + dummy_dev("BxCAN2", 0x40006800, 0x400); + dummy_dev("Reserved", 0x40006C00, 0x400); + // PWR + dummy_dev("DAC1/DAC2", 0x40007400, 0x400); + dummy_dev("Reserved", 0x40007800, 0x400); + dummy_dev("Reserved", 0x40008000, 0x8000); + dummy_dev("TIM1/PWM1", 0x40010000, 0x400); + dummy_dev("TIM8/PWM2", 0x40010400, 0x400); + // USART1 + // USART6 + dummy_dev("Reserved", 0x40011800, 0x800); + // ADC1 - ADC2 - ADC3 + // skipped reserved from here on + dummy_dev("SDIO", 0x40012C00, 0x400); + // SPI1 + // SYSCFG needed + + DeviceState *crc = qdev_create(NULL, "f2xx_crc"); + stm32_init_periph(crc, STM32_CRC, 0x40023000, NULL); + + DeviceState *dma1 = qdev_create(NULL, "f2xx_dma"); + stm32_init_periph(dma1, STM32_DMA1, 0x40026000, NULL); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 0, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM0_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 1, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM1_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 2, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM2_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 3, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM3_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 4, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM4_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 5, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM5_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 6, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM6_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 7, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM7_IRQ)); + + DeviceState *dma2 = qdev_create(NULL, "f2xx_dma"); + stm32_init_periph(dma2, STM32_DMA2, 0x40026400, NULL); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 0, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM0_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 1, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM1_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 2, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM2_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 3, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM3_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 4, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM4_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 5, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM5_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 6, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM6_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 7, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM7_IRQ)); +} diff --git a/hw/arm/stm32f2xx.h b/hw/arm/stm32f2xx.h new file mode 100644 index 0000000000000..2f0629224cd59 --- /dev/null +++ b/hw/arm/stm32f2xx.h @@ -0,0 +1,11 @@ +#include "hw/arm/stm32.h" + +#define STM32F2XX_GPIO_COUNT (STM32_GPIOI - STM32_GPIOA + 1) +#define STM32F2XX_SPI_COUNT 3 + +#define STM32F2XX_UART_COUNT 6 +#define STM32F2XX_TIM_COUNT 14 + +struct stm32f2xx { + DeviceState *spi_dev[STM32F2XX_SPI_COUNT]; +}; diff --git a/hw/arm/stm32f2xx_adc.c b/hw/arm/stm32f2xx_adc.c new file mode 100644 index 0000000000000..a663fcd2d70ab --- /dev/null +++ b/hw/arm/stm32f2xx_adc.c @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU model of the stm32f2xx ADC. + */ + +#include "hw/sysbus.h" + +/* Per-ADC registers */ +#define R_ADC_SR (0x00 / 4) +#define R_ADC_SR_MASK 0x3f +#define R_ADC_SR_EOC (1 << 1) +#define R_ADC_CR1 (0x04 / 4) +#define R_ADC_CR2 (0x08 / 4) +#define R_ADC_SMPR1 (0x0c / 4) +#define R_ADC_SMPR2 (0x10 / 4) +#define R_ADC_JOFRx (0x14 / 4) +#define R_ADC_HTR (0x24 / 4) +#define R_ADC_HTR_RESET 0x00000fff +#define R_ADC_LTR (0x28 / 4) +#define R_ADC_SQR1 (0x2c / 4) +#define R_ADC_SQR2 (0x30 / 4) +#define R_ADC_SQR3 (0x34 / 4) +#define R_ADC_JSQR (0x38 / 4) +#define R_ADC_JDRx (0x3c / 4) +#define R_ADC_DR (0x4c / 4) +#define R_ADC_MAX (0x50 / 4) + +/* Common registers */ +#define R_ADC_CSR (0x00 / 4) +#define R_ADC_CCR (0x04 / 4) +#define R_ADC_CDR (0x08 / 4) +#define R_ADC_CMAX (0x0c / 4) + +typedef struct { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t regs[3][R_ADC_MAX]; + uint32_t ccr; +} stm32_adc; + +static uint64_t +stm32f2xx_adc_common_read(stm32_adc *s, hwaddr offset, unsigned int size) +{ + uint32_t r = 0; + int i; + + offset >>= 2; + switch(offset) { + case R_ADC_CSR: + for (i = 0; i < 3; i++) { + r |= (s->regs[i][R_ADC_SR] & R_ADC_SR_MASK) << 8 * i; + } + break; + case R_ADC_CCR: + r = s->ccr; + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx adc unimplemented read reg 0x%x\n", + (int)offset << 2); + } + return 0; +} + +static uint64_t +stm32f2xx_adc_read(void *arg, hwaddr offset, unsigned int size) +{ + stm32_adc *s = arg; + uint32_t r; + int unit = (offset & 0x300) >> 8; + + if (unit == 3) { + return stm32f2xx_adc_common_read(s, offset - 0x300, size); + } + offset = (offset & 0xFF) >> 2; + r = s->regs[unit][offset]; + switch (offset) { + case R_ADC_SR: + r |= R_ADC_SR_EOC; + break; + + /* Registers with standard read behaviour. */ + case R_ADC_CR1: + case R_ADC_CR2: + case R_ADC_SMPR1: + case R_ADC_SMPR2: + case R_ADC_SQR1: + case R_ADC_SQR2: + case R_ADC_SQR3: + break; + case R_ADC_DR: + break; /* Hack */ + default: + qemu_log_mask(LOG_UNIMP, "adc %d reg %x return 0x%x\n", unit, (int)offset << 2, r); + } + return r; +} + +static void +stm32f2xx_adc_common_write(stm32_adc *s, hwaddr offset, uint64_t data, + unsigned int size) +{ + offset >>= 2; + switch (offset) { + case R_ADC_CSR: + case R_ADC_CDR: + break; + case R_ADC_CCR: + //printf("ccr set 0x%x\n", (int)data); + s->ccr = data; + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx adc unimplemented write reg 0x%x\n", + (int)offset << 2); + } +} + +static void +stm32f2xx_adc_write(void *arg, hwaddr offset, uint64_t data, unsigned int size) +{ + stm32_adc *s = arg; + int unit = (offset & 0x300) >> 8; + + if (unit == 3) { + stm32f2xx_adc_common_write(s, offset - 0x300, data, size); + return; + } + offset = (offset & 0xFF) >> 2; + switch (offset) { + case R_ADC_SR: + s->regs[unit][offset] &= data; /* rc_w0 */ + break; + case R_ADC_CR1: + s->regs[unit][offset] = data; + if (data != 0) { + qemu_log_mask(LOG_UNIMP, "f2xx adc unimplemented CR1 write 0x%08x\n", (unsigned int)data); + } + break; + case R_ADC_CR2: + if (data & ~0x40000001) { + qemu_log_mask(LOG_UNIMP, "f2xx adc unimplemented CR2 write 0x%08x\n", (unsigned int)data); + } + s->regs[unit][offset] = data; + break; + case R_ADC_SMPR1: /* XXX Ignore sampling time setting. */ + case R_ADC_SQR1: + case R_ADC_SQR2: + case R_ADC_SQR3: + s->regs[unit][offset] = data; + break; + case R_ADC_DR: + qemu_log_mask(LOG_GUEST_ERROR, "f2xx adc write to r/o data reg\n"); + break; + default: + qemu_log_mask(LOG_UNIMP, "adc %d reg %x write 0x%x\n", unit, + (int)offset << 2, (int)data); + if (offset < R_ADC_MAX) { + s->regs[unit][offset] = data; + } + break; + } +} + +static const MemoryRegionOps stm32f2xx_adc_ops = { + .read = stm32f2xx_adc_read, + .write = stm32f2xx_adc_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, /* XXX actually 1 */ + .max_access_size = 4 + } +}; + +static void +f2xx_adc_reset(DeviceState *ds) +{ + stm32_adc *s = FROM_SYSBUS(stm32_adc, SYS_BUS_DEVICE(ds)); + + /* Hack for low ambient light level (2500) */ + s->regs[0][R_ADC_DR] = 2730; + s->regs[1][R_ADC_DR] = 2500; +} + +static int +stm32f2xx_adc_init(SysBusDevice *dev) +{ + stm32_adc *s = FROM_SYSBUS(stm32_adc, dev); + +#if 0 + sysbus_init_irq(dev, &s->irq); +#endif + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32f2xx_adc_ops, s, "adc", 0x400); + sysbus_init_mmio(dev, &s->iomem); + + return 0; +} + +static Property stm32f2xx_adc_properties[] = { + DEFINE_PROP_END_OF_LIST() +}; + +static void +stm32f2xx_adc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + + sc->init = stm32f2xx_adc_init; + dc->reset = f2xx_adc_reset; + dc->props = stm32f2xx_adc_properties; +} + +static const TypeInfo stm32f2xx_adc_info = { + .name = "stm32f2xx_adc", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(stm32_adc), + .class_init = stm32f2xx_adc_class_init +}; + +static void +stm32f2xx_adc_register_types(void) +{ + type_register_static(&stm32f2xx_adc_info); +} + +type_init(stm32f2xx_adc_register_types); diff --git a/hw/arm/stm32f2xx_crc.c b/hw/arm/stm32f2xx_crc.c new file mode 100644 index 0000000000000..fa5eb0450c291 --- /dev/null +++ b/hw/arm/stm32f2xx_crc.c @@ -0,0 +1,233 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU crc emulation + */ +#include "hw/sysbus.h" + +#define R_CRC_DR (0x00 / 4) +#define R_CRC_DR_RESET 0xffffffff +#define R_CRC_IDR (0x04 / 4) +#define R_CRC_CR (0x08 / 4) +#define R_CRC_MAX (0x0c / 4) + +/*****************************************************************/ +/* */ +/* CRC LOOKUP TABLE */ +/* ================ */ +/* The following CRC lookup table was generated automagically */ +/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ +/* Program V1.0 using the following model parameters: */ +/* */ +/* Width : 4 bytes. */ +/* Poly : 0x04C11DB7L */ +/* Reverse : FALSE. */ +/* */ +/* For more information on the Rocksoft^tm Model CRC Algorithm, */ +/* see the document titled "A Painless Guide to CRC Error */ +/* Detection Algorithms" by Ross Williams */ +/* (ross@guest.adelaide.edu.au.). This document is likely to be */ +/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/*****************************************************************/ + +static unsigned long crctable[256] = +{ + 0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L, 0x130476DCL, 0x17C56B6BL, + 0x1A864DB2L, 0x1E475005L, 0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L, + 0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL, 0x4C11DB70L, 0x48D0C6C7L, + 0x4593E01EL, 0x4152FDA9L, 0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L, + 0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L, 0x791D4014L, 0x7DDC5DA3L, + 0x709F7B7AL, 0x745E66CDL, 0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L, + 0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L, 0xBE2B5B58L, 0xBAEA46EFL, + 0xB7A96036L, 0xB3687D81L, 0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL, + 0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L, 0xC7361B4CL, 0xC3F706FBL, + 0xCEB42022L, 0xCA753D95L, 0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L, + 0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL, 0x34867077L, 0x30476DC0L, + 0x3D044B19L, 0x39C556AEL, 0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L, + 0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L, 0x018AEB13L, 0x054BF6A4L, + 0x0808D07DL, 0x0CC9CDCAL, 0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL, + 0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L, 0x5E9F46BFL, 0x5A5E5B08L, + 0x571D7DD1L, 0x53DC6066L, 0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL, + 0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL, 0xBFA1B04BL, 0xBB60ADFCL, + 0xB6238B25L, 0xB2E29692L, 0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L, + 0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL, 0xE0B41DE7L, 0xE4750050L, + 0xE9362689L, 0xEDF73B3EL, 0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L, + 0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L, 0xD5B88683L, 0xD1799B34L, + 0xDC3ABDEDL, 0xD8FBA05AL, 0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L, + 0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL, 0x4F040D56L, 0x4BC510E1L, + 0x46863638L, 0x42472B8FL, 0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L, + 0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L, 0x36194D42L, 0x32D850F5L, + 0x3F9B762CL, 0x3B5A6B9BL, 0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL, + 0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L, 0xF12F560EL, 0xF5EE4BB9L, + 0xF8AD6D60L, 0xFC6C70D7L, 0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL, + 0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL, 0xC423CD6AL, 0xC0E2D0DDL, + 0xCDA1F604L, 0xC960EBB3L, 0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L, + 0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL, 0x9B3660C6L, 0x9FF77D71L, + 0x92B45BA8L, 0x9675461FL, 0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L, + 0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L, 0x4E8EE645L, 0x4A4FFBF2L, + 0x470CDD2BL, 0x43CDC09CL, 0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L, + 0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L, 0x119B4BE9L, 0x155A565EL, + 0x18197087L, 0x1CD86D30L, 0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL, + 0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L, 0x2497D08DL, 0x2056CD3AL, + 0x2D15EBE3L, 0x29D4F654L, 0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L, + 0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL, 0xE3A1CBC1L, 0xE760D676L, + 0xEA23F0AFL, 0xEEE2ED18L, 0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L, + 0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L, 0x9ABC8BD5L, 0x9E7D9662L, + 0x933EB0BBL, 0x97FFAD0CL, 0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L, + 0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L +}; + +static inline uint32_t +update_crc(uint32_t crc, uint8_t byte) +{ + return crctable[((crc >> 24) ^ byte) & 0xff] ^ (crc << 8); +} + +typedef struct f2xx_crc { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t crc; + uint8_t idr; +} f2xx_crc; + +static uint64_t +f2xx_crc_read(void *arg, hwaddr addr, unsigned int size) +{ + f2xx_crc *s = arg; + + if (size != 4) { + qemu_log_mask(LOG_UNIMP, "f2xx crc only supports 4-byte reads\n"); + return 0; + } + + addr >>= 2; + if (addr >= R_CRC_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid read f2xx crc register 0x%x\n", + (unsigned int)addr << 2); + return 0; + } + switch(addr) { + case R_CRC_DR: + return s->crc; + case R_CRC_IDR: + return s->idr; + } + return 0; +} + + +static void +f2xx_crc_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + f2xx_crc *s = arg; + + /* XXX Check periph clock enable. */ + if (size != 4) { + qemu_log_mask(LOG_UNIMP, "f2xx crc only supports 4-byte writes\n"); + return; + } + + addr >>= 2; + if (addr >= R_CRC_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid write f2xx crc register 0x%x\n", + (unsigned int)addr << 2); + return; + } + switch(addr) { + case R_CRC_DR: + s->crc = update_crc(s->crc, (data >> 24) & 0xff); + s->crc = update_crc(s->crc, (data >> 16) & 0xff); + s->crc = update_crc(s->crc, (data >> 8) & 0xff); + s->crc = update_crc(s->crc, data & 0xff); + break; + case R_CRC_IDR: + s->idr = data; + break; + case R_CRC_CR: + if (data & 0x1) { + s->crc = R_CRC_DR_RESET; + } + break; + } +} + +static const MemoryRegionOps f2xx_crc_ops = { + .read = f2xx_crc_read, + .write = f2xx_crc_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + +static int +f2xx_crc_init(SysBusDevice *dev) +{ + f2xx_crc *s = FROM_SYSBUS(f2xx_crc, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_crc_ops, s, "crc", 0x400); + sysbus_init_mmio(dev, &s->iomem); + + return 0; +} + +static void +f2xx_crc_reset(DeviceState *ds) +{ + f2xx_crc *s = FROM_SYSBUS(f2xx_crc, SYS_BUS_DEVICE(ds)); + + s->crc = R_CRC_DR_RESET; +} + +static Property f2xx_crc_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static void +f2xx_crc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f2xx_crc_init; + dc->reset = f2xx_crc_reset; + //TODO: fix this: dc->no_user = 1; + dc->props = f2xx_crc_properties; +} + +static const TypeInfo +f2xx_crc_info = { + .name = "f2xx_crc", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f2xx_crc), + .class_init = f2xx_crc_class_init, +}; + +static void +f2xx_crc_register_types(void) +{ + type_register_static(&f2xx_crc_info); +} + +type_init(f2xx_crc_register_types) diff --git a/hw/arm/stm32f2xx_dma.c b/hw/arm/stm32f2xx_dma.c new file mode 100644 index 0000000000000..eb04c43e488a3 --- /dev/null +++ b/hw/arm/stm32f2xx_dma.c @@ -0,0 +1,414 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU DMA controller device model + */ +#include "hw/sysbus.h" + +//#define DEBUG_STM32F2XX_DMA +#ifdef DEBUG_STM32F2XX_DMA + +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("STM32F2XX_DMA: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + +/* Common interrupt status / clear registers. */ +#define R_DMA_LISR (0x00 / 4) +#define R_DMA_HISR (0x04 / 4)//r +#define R_DMA_LIFCR (0x08 / 4) +#define R_DMA_HIFCR (0x0c / 4)//w +#define R_DMA_ISR_FIEF (1 << 0) +#define R_DMA_ISR_DMEIF (1 << 2) +#define R_DMA_ISR_TIEF (1 << 3) +#define R_DMA_ISR_HTIF (1 << 4) +#define R_DMA_ISR_TCIF (1 << 5) + +/* Per-stream registers. */ +#define R_DMA_Sx (0x10 / 4) +#define R_DMA_Sx_COUNT 8 +#define R_DMA_Sx_REGS 6 +#define R_DMA_SxCR (0x00 / 4) +#define R_DMA_SxCR_EN 0x00000001 +#define R_DMA_SxNDTR (0x04 / 4) +#define R_DMA_SxNDTR_EN 0x00000001 +#define R_DMA_SxPAR (0x08 / 4) +#define R_DMA_SxM0AR (0x0c / 4) +#define R_DMA_SxM1AR (0x10 / 4) +#define R_DMA_SxFCR (0x14 / 4) + +#define R_DMA_MAX (0xd0 / 4) + +typedef struct f2xx_dma_stream { + qemu_irq irq; + + uint32_t cr; + uint16_t ndtr; + uint32_t par; + uint32_t m0ar; + uint32_t m1ar; + uint8_t isr; +} f2xx_dma_stream; + +static int msize_table[] = {1, 2, 4, 0}; + +typedef struct f2xx_dma { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t ifcr[R_DMA_HIFCR - R_DMA_LIFCR + 1]; + f2xx_dma_stream stream[R_DMA_Sx_COUNT]; +} f2xx_dma; + +/* Pack ISR bits from four streams, for {L,H}ISR. */ +static uint32_t +f2xx_dma_pack_isr(struct f2xx_dma *s, int start_stream) +{ + uint32_t r = 0; + int i; + + for (i = 0; i < 4; i++) { + r |= s->stream[i + start_stream].isr << (6 * i); + } + return r; +} + +/* Per-stream read. */ +static uint32_t +f2xx_dma_stream_read(f2xx_dma_stream *s, int stream_no, uint32_t reg) +{ + switch (reg) { + case R_DMA_SxCR: + DPRINTF(" %s: stream: %d, register CR\n", __func__, stream_no); + return s->cr; + case R_DMA_SxNDTR: + DPRINTF(" %s: stream: %d, register NDTR (UNIMPLEMENTED)\n", __func__, stream_no); + qemu_log_mask(LOG_UNIMP, "f2xx dma unimp read reg NDTR\n"); + return 0; + case R_DMA_SxPAR: + DPRINTF(" %s: stream: %d, register PAR (UNIMPLEMENTED)\n", __func__, stream_no); + qemu_log_mask(LOG_UNIMP, "f2xx dma unimp read reg PAR\n"); + return 0; + case R_DMA_SxM0AR: + DPRINTF(" %s: stream: %d, register M0AR (UNIMPLEMENTED)\n", __func__, stream_no); + qemu_log_mask(LOG_UNIMP, "f2xx dma unimp read reg M0AR\n"); + return 0; + case R_DMA_SxM1AR: + DPRINTF(" %s: stream: %d, register M1AR (UNIMPLEMENTED)\n", __func__, stream_no); + qemu_log_mask(LOG_UNIMP, "f2xx dma unimp read reg M1AR\n"); + return 0; + case R_DMA_SxFCR: + DPRINTF(" %s: stream: %d, register FCR (UNIMPLEMENTED)\n", __func__, stream_no); + qemu_log_mask(LOG_UNIMP, "f2xx dma unimp read reg FCR\n"); + return 0; + default: + DPRINTF(" %s: stream: %d, register 0x%02x\n", __func__, stream_no, reg<<2); + qemu_log_mask(LOG_UNIMP, "f2xx dma unimp read stream reg 0x%02x\n", + (unsigned int)reg<<2); + } + return 0; +} + +/* Register read. */ +static uint64_t +f2xx_dma_read(void *arg, hwaddr addr, unsigned int size) +{ + f2xx_dma *s = arg; + uint64_t result; + + DPRINTF("%s: addr: 0x%llx, size:%d...\n", __func__, addr, size); + + if (size != 4) { + qemu_log_mask(LOG_UNIMP, "f2xx crc only supports 4-byte reads\n"); + return 0; + } + + addr >>= 2; + if (addr >= R_DMA_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid read f2xx dma register 0x%02x\n", + (unsigned int)addr << 2); + result = 0; + } else { + switch(addr) { + case R_DMA_LISR: + DPRINTF(" %s: register LISR\n", __func__); + result = f2xx_dma_pack_isr(s, 0); + break; + case R_DMA_HISR: + DPRINTF(" %s: register HISR\n", __func__); + result = f2xx_dma_pack_isr(s, 4); + break; + case R_DMA_LIFCR: + DPRINTF(" %s: register LIFCR\n", __func__); + result = s->ifcr[addr - R_DMA_LIFCR]; + break; + case R_DMA_HIFCR: + DPRINTF(" %s: register HIFCR\n", __func__); + result = s->ifcr[addr - R_DMA_LIFCR]; + break; + default: + /* Only per-stream registers remain. */ + addr -= R_DMA_Sx; + int stream_no = addr / R_DMA_Sx_REGS; + result = f2xx_dma_stream_read(&s->stream[stream_no], stream_no, + addr % R_DMA_Sx_REGS); + break; + } + } + + DPRINTF(" %s: result:0x%llx\n", __func__, result); + return result; +} + +/* Start a DMA transfer for a given stream. */ +static void +f2xx_dma_stream_start(f2xx_dma_stream *s, int stream_no) +{ + uint8_t buf[4]; + int msize = msize_table[(s->cr >> 13) & 0x3]; + + DPRINTF("%s: stream: %d\n", __func__, stream_no); + + if (msize == 0) { + qemu_log_mask(LOG_GUEST_ERROR, "f2xx dma: invalid MSIZE\n"); + return; + } + /* XXX Skip USART, as pacing control is not yet in place. */ + if (s->par == 0x40011004) { + qemu_log_mask(LOG_UNIMP, "f2xx dma: skipping USART\n"); + return; + } + + /* XXX hack do the entire transfer here for now. */ + DPRINTF("%s: transferring %d x %d byte(s) from 0x%08x to 0x%08x\n", __func__, s->ndtr, + msize, s->m0ar, s->par); + while (s->ndtr--) { + cpu_physical_memory_read(s->m0ar, buf, msize); + cpu_physical_memory_write(s->par, buf, msize); + s->m0ar += msize; + } + /* Transfer complete. */ + s->cr &= ~R_DMA_SxCR_EN; + s->isr |= R_DMA_ISR_TCIF; + qemu_set_irq(s->irq, 1); +} + +/* Per-stream register write. */ +static void +f2xx_dma_stream_write(f2xx_dma_stream *s, int stream_no, uint32_t addr, uint32_t data) +{ + switch (addr) { + case R_DMA_SxCR: + DPRINTF("%s: stream: %d, register CR, data:0x%x\n", __func__, stream_no, data); + if ((s->cr & R_DMA_SxCR_EN) == 0 && (data & R_DMA_SxCR_EN) != 0) { + f2xx_dma_stream_start(s, stream_no); + } + s->cr = data; + break; + case R_DMA_SxNDTR: + DPRINTF("%s: stream: %d, register NDTR, data:0x%x\n", __func__, stream_no, data); + if (s->cr & R_DMA_SxNDTR_EN) { + qemu_log_mask(LOG_GUEST_ERROR, "f2xx dma write to NDTR while enabled\n"); + return; + } + s->ndtr = data; + break; + case R_DMA_SxPAR: + DPRINTF("%s: stream: %d, register PAR, data:0x%x\n", __func__, stream_no, data); + s->par = data; + break; + case R_DMA_SxM0AR: + DPRINTF("%s: stream: %d, register M0AR, data:0x%x\n", __func__, stream_no, data); + s->m0ar = data; + break; + case R_DMA_SxM1AR: + DPRINTF("%s: stream: %d, register M1AR, data:0x%x\n", __func__, stream_no, data); + s->m1ar = data; + break; + case R_DMA_SxFCR: + DPRINTF("%s: stream: %d, register FCR (UINIMPLEMENTED), data:0x%x\n", __func__, + stream_no, data); + qemu_log_mask(LOG_UNIMP, "f2xx dma SxFCR unimplemented\n"); + break; + } +} + +/* Register write. */ +static void +f2xx_dma_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + f2xx_dma *s = arg; + int offset = addr & 0x3; + + (void)offset; + + /* XXX Check DMA peripheral clock enable. */ + if (size != 4) { + qemu_log_mask(LOG_UNIMP, "f2xx dma only supports 4-byte writes\n"); + return; + } + + addr >>= 2; + if (addr >= R_DMA_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid write f2xx dma register 0x%02x\n", + (unsigned int)addr << 2); + return; + } + if (addr >= R_DMA_Sx && addr <= 0xcc) { + int num = (addr - R_DMA_Sx) / R_DMA_Sx_REGS; + f2xx_dma_stream_write(&s->stream[num], num, + (addr - R_DMA_Sx) % R_DMA_Sx_REGS, data); + return; + } + switch(addr) { + case R_DMA_LISR: + DPRINTF("%s: register LISR (READ-ONLY), data: 0x%llx\n", __func__, data); + qemu_log_mask(LOG_GUEST_ERROR, "f2xx dma: invalid write to ISR\n"); + break; + case R_DMA_HISR: + DPRINTF("%s: register HISR (READ-ONLY), data: 0x%llx\n", __func__, data); + qemu_log_mask(LOG_GUEST_ERROR, "f2xx dma: invalid write to ISR\n"); + break; + case R_DMA_LIFCR: + DPRINTF("%s: register LIFCR, data: 0x%llx\n", __func__, data); + // Any interrupt clear write to stream x clears all interrupts for that stream + s->ifcr[addr - R_DMA_LIFCR] = data; + if (data & 0x0f400000) { + s->stream[3].isr = 0; + qemu_set_irq(s->stream[3].irq, 0); + } + if (data & 0x003d0000) { + s->stream[2].isr = 0; + qemu_set_irq(s->stream[2].irq, 0); + } + if (data & 0x00000f40) { + s->stream[1].isr = 0; + qemu_set_irq(s->stream[1].irq, 0); + } + if (data & 0x0000003d) { + s->stream[0].isr = 0; + qemu_set_irq(s->stream[0].irq, 0); + } + break; + case R_DMA_HIFCR: + DPRINTF("%s: register HIFCR, data: 0x%llx\n", __func__, data); + // Any interrupt clear write to stream x clears all interrupts for that stream + s->ifcr[addr - R_DMA_LIFCR] = data; + if (data & 0x0f400000) { + s->stream[7].isr = 0; + qemu_set_irq(s->stream[7].irq, 0); + } + if (data & 0x003d0000) { + s->stream[6].isr = 0; + qemu_set_irq(s->stream[6].irq, 0); + } + if (data & 0x00000f40) { + s->stream[5].isr = 0; + qemu_set_irq(s->stream[5].irq, 0); + } + if (data & 0x0000003d) { + s->stream[4].isr = 0; + qemu_set_irq(s->stream[4].irq, 0); + } + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx dma unimpl write reg 0x%02x\n", + (unsigned int)addr << 2); + } +} + +static const MemoryRegionOps f2xx_dma_ops = { + .read = f2xx_dma_read, + .write = f2xx_dma_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + +static int +f2xx_dma_init(SysBusDevice *dev) +{ + f2xx_dma *s = FROM_SYSBUS(f2xx_dma, dev); + int i; + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_dma_ops, s, "dma", 0x400); + sysbus_init_mmio(dev, &s->iomem); + + for (i = 0; i < R_DMA_Sx_COUNT; i++) { + sysbus_init_irq(dev, &s->stream[i].irq); + } + + return 0; +} + +static void +f2xx_dma_reset(DeviceState *ds) +{ + f2xx_dma *s = FROM_SYSBUS(f2xx_dma, SYS_BUS_DEVICE(ds)); + + memset(&s->ifcr, 0, sizeof(s->ifcr)); + + int i; + for (i=0; istream[i].irq; + memset(&s->stream[i], 0, sizeof(f2xx_dma_stream)); + s->stream[i].irq = save; + } +} + +static Property f2xx_dma_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static void +f2xx_dma_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f2xx_dma_init; + dc->reset = f2xx_dma_reset; + //TODO: fix this: dc->no_user = 1; + dc->props = f2xx_dma_properties; +} + +static const TypeInfo +f2xx_dma_info = { + .name = "f2xx_dma", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f2xx_dma), + .class_init = f2xx_dma_class_init, +}; + +static void +f2xx_dma_register_types(void) +{ + type_register_static(&f2xx_dma_info); +} + +type_init(f2xx_dma_register_types) diff --git a/hw/arm/stm32f2xx_dummy.c b/hw/arm/stm32f2xx_dummy.c new file mode 100644 index 0000000000000..0bc59879d2dfc --- /dev/null +++ b/hw/arm/stm32f2xx_dummy.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU dummy emulation + */ +#include "hw/sysbus.h" + +typedef struct f2xx_dummy { + SysBusDevice busdev; + MemoryRegion iomem; + void *name; + int32_t size; +} f2xx_dummy; + +static uint64_t +f2xx_dummy_read(void *arg, hwaddr addr, unsigned int size) +{ + f2xx_dummy *s = arg; + + qemu_log_mask(LOG_UNIMP, "%s dummy read 0x%x %d byte%s\n", s->name, + (unsigned int)addr, size, size != 1 ? "s" : ""); + + return 0; +} + +static void +f2xx_dummy_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + f2xx_dummy *s = arg; + + qemu_log_mask(LOG_UNIMP, "%s dummy write 0x%x %d byte%s value 0x%x\n", + s->name, (unsigned int)addr, size, size != 1 ? "s" : "", + (unsigned int)data); +} + +static const MemoryRegionOps f2xx_dummy_ops = { + .read = f2xx_dummy_read, + .write = f2xx_dummy_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + +static int +f2xx_dummy_init(SysBusDevice *dev) +{ + f2xx_dummy *s = FROM_SYSBUS(f2xx_dummy, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_dummy_ops, s, "dummy", s->size); + sysbus_init_mmio(dev, &s->iomem); + return 0; +} + +static Property f2xx_dummy_properties[] = { + DEFINE_PROP_PTR("name", f2xx_dummy, name), + DEFINE_PROP_INT32("size", f2xx_dummy, size, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void +f2xx_dummy_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f2xx_dummy_init; + // TODO: fix this: dc->no_user = 1; + dc->props = f2xx_dummy_properties; +} + +static const TypeInfo +f2xx_dummy_info = { + .name = "f2xx_dummy", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f2xx_dummy), + .class_init = f2xx_dummy_class_init, +}; + +static void +f2xx_dummy_register_types(void) +{ + type_register_static(&f2xx_dummy_info); +} + +type_init(f2xx_dummy_register_types) diff --git a/hw/arm/stm32f2xx_flash.c b/hw/arm/stm32f2xx_flash.c new file mode 100644 index 0000000000000..f2a6492aa05c8 --- /dev/null +++ b/hw/arm/stm32f2xx_flash.c @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 2013 + * + * 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 "sysemu/blockdev.h" +#include "hw/hw.h" +#include "hw/block/flash.h" +#include "block/block.h" +#include "sysemu/block-backend.h" +#include "hw/sysbus.h" + + +struct f2xx_flash { + SysBusDevice busdev; + BlockBackend *blk; + hwaddr base_address; + uint32_t size; + + MemoryRegion mem; + void *data; +}; // f2xx_flash_t; + +/* */ +f2xx_flash_t *f2xx_flash_register(BlockBackend *blk, hwaddr base, + hwaddr size) +{ + DeviceState *dev = qdev_create(NULL, "f2xx.flash"); + //SysBusDevice *busdev = SYS_BUS_DEVICE(dev); + f2xx_flash_t *flash = (f2xx_flash_t *)object_dynamic_cast(OBJECT(dev), + "f2xx.flash"); + qdev_prop_set_uint32(dev, "size", size); + qdev_prop_set_uint64(dev, "base_address", base); + if (blk) { + Error *err = NULL; + qdev_prop_set_drive(dev, "drive", blk, &err); + if (err) { + printf("%s, have no drive???\n", __func__); + return NULL; + } + } + qdev_init_nofail(dev); + //sysbus_mmio_map(busdev, 0, base); + return flash; +} + +/* */ + +static uint64_t +f2xx_flash_read(void *arg, hwaddr offset, unsigned int size) +{ + //f2xx_flash_t *flash = arg; + + printf("read offset 0x%jx size %ju\n", (uintmax_t)offset, (uintmax_t)size); + return 0; +} + +static void +f2xx_flash_write(void *arg, hwaddr offset, uint64_t data, unsigned int size) +{ +} + +static const MemoryRegionOps f2xx_flash_ops = { + .read = f2xx_flash_read, + .write = f2xx_flash_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +MemoryRegion *get_system_memory(void); /* XXX */ + +static int f2xx_flash_init(SysBusDevice *dev) +{ + Error *err = NULL; + f2xx_flash_t *flash = FROM_SYSBUS(typeof(*flash), dev); + +// memory_region_init_rom_device(&flash->mem, &f2xx_flash_ops, flash, "name", +// size); + memory_region_init_ram(&flash->mem, NULL, "f2xx.flash", flash->size, &err); + + vmstate_register_ram(&flash->mem, DEVICE(flash)); + //vmstate_register_ram_global(&flash->mem); + memory_region_set_readonly(&flash->mem, true); + memory_region_add_subregion(get_system_memory(), flash->base_address, &flash->mem); +// sysbus_init_mmio(dev, &flash->mem); + + flash->data = memory_region_get_ram_ptr(&flash->mem); + memset(flash->data, 0xff, flash->size); + if (flash->blk) { + int r; + r = blk_read(flash->blk, 0, flash->data, blk_getlength(flash->blk)/BDRV_SECTOR_SIZE); + if (r < 0) { + vmstate_unregister_ram(&flash->mem, DEVICE(flash)); + // memory_region_destroy(&flash->mem); + return 1; + } + } + + return 0; +} + +static Property f2xx_flash_properties[] = { + DEFINE_PROP_DRIVE("drive", struct f2xx_flash, blk), + DEFINE_PROP_UINT32("size", struct f2xx_flash, size, 512*1024), + DEFINE_PROP_UINT64("base_address", struct f2xx_flash, base_address, 0x08000000), + DEFINE_PROP_END_OF_LIST(), +}; + +static void f2xx_flash_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = f2xx_flash_init; + dc->props = f2xx_flash_properties; +} + +static const TypeInfo f2xx_flash_info = { + .name = "f2xx.flash", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct f2xx_flash), + .class_init = f2xx_flash_class_init, +}; + +static void f2xx_flash_register_types(void) +{ + type_register_static(&f2xx_flash_info); +} + +type_init(f2xx_flash_register_types) diff --git a/hw/arm/stm32f2xx_gpio.c b/hw/arm/stm32f2xx_gpio.c new file mode 100644 index 0000000000000..b6afa0c9c261c --- /dev/null +++ b/hw/arm/stm32f2xx_gpio.c @@ -0,0 +1,285 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU model of the stm32f2xx GPIO module + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" + +//#define DEBUG_STM32_GPIO +#ifdef DEBUG_STM32_GPIO +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("STM32F2XX_GPIO: " fmt , ## __VA_ARGS__); \ + usleep(100); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + +#define R_GPIO_MODER (0x00 / 4) +#define R_GPIO_OTYPER (0x04 / 4) +#define R_GPIO_OSPEEDR (0x08 / 4) +#define R_GPIO_PUPDR (0x0c / 4) +#define R_GPIO_IDR (0x10 / 4) +#define R_GPIO_ODR (0x14 / 4) +#define R_GPIO_BSRR (0x18 / 4) +#define R_GPIO_LCKR (0x1c / 4) +#define R_GPIO_AFRL (0x20 / 4) +#define R_GPIO_AFRH (0x24 / 4) +#define R_GPIO_MAX (0x28 / 4) + +struct stm32f2xx_gpio { + SysBusDevice busdev; + MemoryRegion iomem; + + stm32_periph_t periph; + uint32_t idr_mask; + + qemu_irq pin[STM32_GPIO_PIN_COUNT]; + qemu_irq exti[STM32_GPIO_PIN_COUNT]; + qemu_irq alternate_function[STM32_GPIO_PIN_COUNT]; + qemu_irq cpu_wake[STM32_GPIO_PIN_COUNT]; + + uint32_t regs[R_GPIO_MAX]; + uint32_t ccr; +}; + +static uint64_t +stm32f2xx_gpio_read(void *arg, hwaddr offset, unsigned int size) +{ + stm32f2xx_gpio *s = arg; + uint32_t r; + + offset >>= 2; + r = s->regs[offset]; +//printf("GPIO unit %d reg %x return 0x%x\n", s->periph, (int)offset << 2, r); + return r; +} + +static void +f2xx_update_odr(stm32f2xx_gpio *s, uint16_t val) +{ + int i; + uint16_t changed = s->regs[R_GPIO_ODR] ^ val; + + for (i = 0; i < STM32_GPIO_PIN_COUNT; i++) + { + if ((changed & 1<busdev.parent_obj.id, i, !!(val & 1<periph, i, val & 1<pin[i], !!(val & 1<regs[R_GPIO_ODR] = val; +} + +static void +f2xx_update_mode(stm32f2xx_gpio *s, uint32_t val) +{ + int i; + uint32_t prev_value = s->regs[R_GPIO_MODER]; + + for (i = 0; i < STM32_GPIO_PIN_COUNT; i++) + { + uint32_t setting = (val >> i*2) & 0x03; + uint32_t prev_setting = (prev_value >> i*2) & 0x03; + if (setting == prev_setting) { + continue; + } + + DPRINTF("%s mode of pin %i changing to %d\n", s->busdev.parent_obj.id, i, setting); + bool is_alternate_function = (setting == 2); + qemu_set_irq(s->alternate_function[i], is_alternate_function); + } + s->regs[R_GPIO_MODER] = val; +} + +static void +stm32f2xx_gpio_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + stm32f2xx_gpio *s = arg; + int offset = addr % 3; + + addr >>= 2; + if (addr > R_GPIO_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid GPIO %d write reg 0x%x\n", + s->periph, (unsigned int)addr << 2); + return; + } + + switch(size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + + switch (addr) { + case R_GPIO_MODER: + f2xx_update_mode(s, data); + break; + case R_GPIO_ODR: + f2xx_update_odr(s, data); + break; + case R_GPIO_BSRR: + { + uint16_t new_val = s->regs[R_GPIO_ODR]; + new_val &= ~((data >> 16) & 0xffff); /* BRy */ + new_val |= data & 0xffff; /* BSy */ + f2xx_update_odr(s, new_val); + break; + } + default: + qemu_log_mask(LOG_UNIMP, "f2xx GPIO %d reg 0x%x:%d write (0x%x) unimplemented\n", + s->periph, (int)addr << 2, offset, (int)data); + s->regs[addr] = data; + break; + } +} + +static const MemoryRegionOps stm32f2xx_gpio_ops = { + .read = stm32f2xx_gpio_read, + .write = stm32f2xx_gpio_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4 + } +}; + +static void +stm32f2xx_gpio_reset(DeviceState *dev) +{ + stm32f2xx_gpio *s = FROM_SYSBUS(stm32f2xx_gpio, SYS_BUS_DEVICE(dev)); + + switch (s->periph) { + case 0: + s->regs[R_GPIO_MODER] = 0xa8000000; + s->regs[R_GPIO_OSPEEDR] = 0x00000000; + s->regs[R_GPIO_PUPDR] = 0x64000000; + break; + case 1: + s->regs[R_GPIO_MODER] = 0x00000280; + s->regs[R_GPIO_OSPEEDR] = 0x000000C0; + s->regs[R_GPIO_PUPDR] = 0x00000100; + break; + default: + s->regs[R_GPIO_MODER] = 0x00000000; + s->regs[R_GPIO_OSPEEDR] = 0x00000000; + s->regs[R_GPIO_PUPDR] = 0x00000000; + break; + } + /* Mask out the IDR bits as specified */ + s->regs[R_GPIO_IDR] = 0x0000ffff & ~(s->idr_mask); +} + +static void +f2xx_gpio_set(void *arg, int pin, int level) +{ + stm32f2xx_gpio *s = arg; + uint32_t bit = 1<regs[R_GPIO_IDR] |= bit; + else + s->regs[R_GPIO_IDR] &= ~bit; + + /* Inform EXTI module of pin state */ + qemu_set_irq(s->exti[pin], level); + + // For the stm32, only GPIOA, pin 0 will have a wakeup handler tied to it. It will be + // tied to a handler callback in the NVIC. + qemu_set_irq(s->cpu_wake[pin], level); + + DPRINTF("GPIO %d set pin %d level %d\n", s->periph, pin, level); +} + +void +f2xx_gpio_exti_set(stm32f2xx_gpio *s, unsigned pin, qemu_irq irq) +{ + s->exti[pin] = irq; + DPRINTF("GPIO %d set exti %d irq %p\n", s->periph, pin, irq); +} + +void +f2xx_gpio_wake_set(stm32f2xx_gpio *s, unsigned pin, qemu_irq irq) +{ + s->cpu_wake[pin] = irq; + DPRINTF("GPIO %d set cpu_wake %d irq %p\n", s->periph, pin, irq); +} + +static int +stm32f2xx_gpio_init(SysBusDevice *dev) +{ + stm32f2xx_gpio *s = FROM_SYSBUS(stm32f2xx_gpio, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32f2xx_gpio_ops, s, "gpio", 0x400); + sysbus_init_mmio(dev, &s->iomem); + + qdev_init_gpio_in(DEVICE(dev), f2xx_gpio_set, STM32_GPIO_PIN_COUNT); + qdev_init_gpio_out(DEVICE(dev), s->pin, STM32_GPIO_PIN_COUNT); + qdev_init_gpio_out_named(DEVICE(dev), s->alternate_function, "af", STM32_GPIO_PIN_COUNT); + + return 0; +} + +static Property stm32f2xx_gpio_properties[] = { + DEFINE_PROP_INT32("periph", stm32f2xx_gpio, periph, -1), + DEFINE_PROP_UINT32("idr-mask", stm32f2xx_gpio, idr_mask, 0), + DEFINE_PROP_END_OF_LIST() +}; + +static void +stm32f2xx_gpio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + + sc->init = stm32f2xx_gpio_init; + dc->reset = stm32f2xx_gpio_reset; + dc->props = stm32f2xx_gpio_properties; +} + +static const TypeInfo stm32f2xx_gpio_info = { + .name = "stm32f2xx_gpio", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(stm32f2xx_gpio), + .class_init = stm32f2xx_gpio_class_init +}; + +static void +stm32f2xx_gpio_register_types(void) +{ + type_register_static(&stm32f2xx_gpio_info); +} + +type_init(stm32f2xx_gpio_register_types) diff --git a/hw/arm/stm32f2xx_i2c.c b/hw/arm/stm32f2xx_i2c.c new file mode 100644 index 0000000000000..f73dc8692aec8 --- /dev/null +++ b/hw/arm/stm32f2xx_i2c.c @@ -0,0 +1,292 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU model of the stm32f2xx I2C controller. + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/i2c/i2c.h" + +#define R_I2C_CR1 (0x00 / 4) +#define R_I2C_CR2 (0x04 / 4) +#define R_I2C_OAR1 (0x08 / 4) +#define R_I2C_OAR2 (0x0c / 4) +#define R_I2C_DR (0x10 / 4) +#define R_I2C_SR1 (0x14 / 4) +#define R_I2C_SR2 (0x18 / 4) +#define R_I2C_CCR (0x1c / 4) +#define R_I2C_TRISE (0x20 / 4) +#define R_I2C_MAX (0x24 / 4) + + +#define R_I2C_CR1_PE_BIT 0x00001 +#define R_I2C_CR1_SMBUS_BIT 0x00002 +#define R_I2C_CR1_SMBTYPE_BIT 0x00008 +#define R_I2C_CR1_ENARB_BIT 0x00010 +#define R_I2C_CR1_ENPEC_BIT 0x00020 +#define R_I2C_CR1_ENGC_BIT 0x00040 +#define R_I2C_CR1_NOSTRETCH_BIT 0x00080 +#define R_I2C_CR1_START_BIT 0x00100 +#define R_I2C_CR1_STOP_BIT 0x00200 +#define R_I2C_CR1_ACK_BIT 0x00400 +#define R_I2C_CR1_POS_BIT 0x00800 +#define R_I2C_CR1_PEC_BIT 0x01000 +#define R_I2C_CR1_ALERT_BIT 0x02000 +#define R_I2C_CR1_SWRTS_BIT 0x08000 + + +#define R_I2C_CR2_ITERREN_BIT 0x00100 +#define R_I2C_CR2_ITEVTEN_BIT 0x00200 +#define R_I2C_CR2_ITBUFEN_BIT 0x00400 +#define R_I2C_CR2_DMAEN_BIT 0x00800 +#define R_I2C_CR2_LAST_BIT 0x01000 + +#define R_I2C_SR1_SB_BIT 0x00001 +#define R_I2C_SR1_ADDR_BIT 0x00002 +#define R_I2C_SR1_BTF_BIT 0x00004 +#define R_I2C_SR1_ADD10_BIT 0x00008 +#define R_I2C_SR1_STOPF_BIT 0x00010 +#define R_I2C_SR1_RxNE_BIT 0x00040 +#define R_I2C_SR1_TxE_BIT 0x00080 +#define R_I2C_SR1_BERR_BIT 0x00100 +#define R_I2C_SR1_ARLO_BIT 0x00200 +#define R_I2C_SR1_AF_BIT 0x00400 +#define R_I2C_SR1_OVR_BIT 0x00800 +#define R_I2C_SR1_PECERR_BIT 0x01000 +#define R_I2C_SR1_TIMEOUT_BIT 0x04000 +#define R_I2C_SR1_SMBALERT_BIT 0x08000 + + + +//#define DEBUG_STM32F2XX_I2c +#ifdef DEBUG_STM32F2XX_I2c +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("STM32F2XX_I2c: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +static const char *f2xx_i2c_reg_name_arr[] = { + "CR1", + "CR2", + "OAR1", + "OAR2", + "DR", + "SR1", + "SR2", + "CCR", + "TRISE" +}; + + + +typedef struct f2xx_i2c { + SysBusDevice busdev; + MemoryRegion iomem; + qemu_irq evt_irq; + qemu_irq err_irq; + + I2CBus *bus; + + stm32_periph_t periph; + + int32_t rx; + int rx_full; + uint16_t regs[R_I2C_MAX]; + +} f2xx_i2c; + + +/* Routine which updates the I2C's IRQs. This should be called whenever + * an interrupt-related flag is updated. + */ +static void f2xx_i2c_update_irq(f2xx_i2c *s) { + int new_err_irq_level = 0; + if (s->regs[R_I2C_CR2] & R_I2C_CR2_ITERREN_BIT) { + new_err_irq_level = (s->regs[R_I2C_SR1] & R_I2C_SR1_BERR_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_ARLO_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_AF_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_OVR_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_PECERR_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_TIMEOUT_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_SMBALERT_BIT); + } + + int new_evt_irq_level = 0; + if (s->regs[R_I2C_CR2] & R_I2C_CR2_ITEVTEN_BIT) { + new_evt_irq_level = (s->regs[R_I2C_SR1] & R_I2C_SR1_SB_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_ADDR_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_ADD10_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_STOPF_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_BTF_BIT); + + if (s->regs[R_I2C_CR2] & R_I2C_CR2_ITBUFEN_BIT) { + new_evt_irq_level |= (s->regs[R_I2C_SR1] & R_I2C_SR1_TxE_BIT) + | (s->regs[R_I2C_SR1] & R_I2C_SR1_RxNE_BIT); + } + } + + DPRINTF("%s %s: setting evt_irq to %d\n", __func__, s->busdev.parent_obj.id, + !!new_evt_irq_level); + qemu_set_irq(s->evt_irq, !!new_evt_irq_level); + + DPRINTF("%s %s: setting err_irq to %d\n", __func__, s->busdev.parent_obj.id, + !!new_err_irq_level); + qemu_set_irq(s->err_irq, !!new_err_irq_level); +} + + + +static uint64_t +f2xx_i2c_read(void *arg, hwaddr offset, unsigned size) +{ + f2xx_i2c *s = arg; + uint16_t r = UINT16_MAX; + const char *reg_name = "UNKNOWN"; + + if (!(size == 2 || size == 4 || (offset & 0x3) != 0)) { + STM32_BAD_REG(offset, size); + } + offset >>= 2; + if (offset < R_I2C_MAX) { + r = s->regs[offset]; + reg_name = f2xx_i2c_reg_name_arr[offset]; + } else { + qemu_log_mask(LOG_GUEST_ERROR, "Out of range I2C write, offset 0x%x\n", + (unsigned)offset << 2); + } + + DPRINTF("%s %s: register %s, result: 0x%x\n", __func__, s->busdev.parent_obj.id, + reg_name, r); + return r; +} + + +static void +f2xx_i2c_write(void *arg, hwaddr offset, uint64_t data, unsigned size) +{ + const char *reg_name = "UNKNOWN"; + struct f2xx_i2c *s = (struct f2xx_i2c *)arg; + + if (size != 2 && size != 4) { + STM32_BAD_REG(offset, size); + } + /* I2C registers are all at most 16 bits wide */ + data &= 0xFFFFF; + offset >>= 2; + + if (offset < R_I2C_MAX) { + reg_name = f2xx_i2c_reg_name_arr[offset]; + } + DPRINTF("%s %s: register %s, data: 0x%llx, size:%d\n", __func__, s->busdev.parent_obj.id, + reg_name, data, size); + + + switch (offset) { + case R_I2C_CR1: + s->regs[offset] = data; + if (data & R_I2C_CR1_START_BIT) { + // For now, abort all attempted master transfers with a bus error + s->regs[R_I2C_SR1] |= R_I2C_SR1_BERR_BIT; + } + if ((data & R_I2C_CR1_PE_BIT) == 0) { + s->regs[R_I2C_SR1] = 0; + } + break; + + case R_I2C_DR: + i2c_send(s->bus, (uint8_t)data); + break; + + default: + if (offset < ARRAY_SIZE(s->regs)) { + s->regs[offset] = data; + } else { + STM32_BAD_REG(offset, WORD_ACCESS_SIZE); + } + } + f2xx_i2c_update_irq(s); +} + +static const MemoryRegionOps f2xx_i2c_ops = { + .read = f2xx_i2c_read, + .write = f2xx_i2c_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void +f2xx_i2c_reset(DeviceState *dev) +{ + //struct f2xx_i2c *s = FROM_SYSBUS(struct f2xx_i2c, SYS_BUS_DEVICE(dev)); + +// s->regs[R_SR] = R_SR_RESET; +} + +static int +f2xx_i2c_init(SysBusDevice *dev) +{ + struct f2xx_i2c *s = FROM_SYSBUS(struct f2xx_i2c, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_i2c_ops, s, "i2c", 0x3ff); + sysbus_init_mmio(dev, &s->iomem); + sysbus_init_irq(dev, &s->evt_irq); + sysbus_init_irq(dev, &s->err_irq); + s->bus = i2c_init_bus(DEVICE(dev), "i2c"); + + return 0; +} + + +static Property f2xx_i2c_properties[] = { + DEFINE_PROP_INT32("periph", struct f2xx_i2c, periph, -1), + DEFINE_PROP_END_OF_LIST() +}; + +static void +f2xx_i2c_class_init(ObjectClass *c, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(c); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); + + sc->init = f2xx_i2c_init; + dc->reset = f2xx_i2c_reset; + dc->props = f2xx_i2c_properties; +} + +static const TypeInfo f2xx_i2c_info = { + .name = "f2xx_i2c", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct f2xx_i2c), + .class_init = f2xx_i2c_class_init +}; + +static void +f2xx_i2c_register_types(void) +{ + type_register_static(&f2xx_i2c_info); +} + +type_init(f2xx_i2c_register_types) diff --git a/hw/arm/stm32f2xx_pwr.c b/hw/arm/stm32f2xx_pwr.c new file mode 100644 index 0000000000000..33913929eec4b --- /dev/null +++ b/hw/arm/stm32f2xx_pwr.c @@ -0,0 +1,191 @@ +/*- + * Copyright (c) 2014 + * + * 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. + */ +/* + * QEMU stm32f2xx RTC emulation + */ +#include +#include "hw/sysbus.h" +#include "qemu/timer.h" + +//#define DEBUG_STM32F2XX_PWR +#ifdef DEBUG_STM32F2XX_PWR +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("DEBUG_STM32F2XX_PWR: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define R_PWR_CR (0x00/4) +#define R_PWR_CR_LPDS 0x00000001 +#define R_PWR_CR_PDDS 0x00000002 + +#define R_PWR_CSR (0x04/4) + +#define R_PWR_MAX (0x08/4) + +typedef struct f2xx_pwr { + SysBusDevice busdev; + MemoryRegion iomem; + + uint32_t regs[R_PWR_MAX]; +} f2xx_pwr; + + + +static uint64_t +f2xx_pwr_read(void *arg, hwaddr addr, unsigned int size) +{ + f2xx_pwr *s = arg; + uint32_t r; + int offset = addr & 0x3; + + addr >>= 2; + if (addr >= R_PWR_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid read f2xx pwr register 0x%x\n", + (unsigned int)addr << 2); + DPRINTF(" %s: result: 0\n", __func__); + return 0; + } + + uint32_t value = s->regs[addr]; + + r = (value >> offset * 8) & ((1ull << (8 * size)) - 1); + + DPRINTF("%s: addr: 0x%llx, size: %d, value: 0x%x\n", __func__, addr, size, r); + return r; +} + +static void +f2xx_pwr_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + f2xx_pwr *s = arg; + int offset = addr & 0x3; + + DPRINTF("%s: addr: 0x%llx, data: 0x%llx, size: %d\n", __func__, addr, data, size); + + addr >>= 2; + if (addr >= R_PWR_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid write f2xx pwr register 0x%x\n", + (unsigned int)addr << 2); + return; + } + + switch(size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + + switch(addr) { + case R_PWR_CR: + case R_PWR_CSR: + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx pwr unimplemented write 0x%x+%u size %u val 0x%x\n", + (unsigned int)addr << 2, offset, size, (unsigned int)data); + } + + // Save new value + s->regs[addr] = data; +} + +static const MemoryRegionOps f2xx_pwr_ops = { + .read = f2xx_pwr_read, + .write = f2xx_pwr_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + + +// Return true if we should go into standby mode when the process goes into deepsleep. +// deepsleep is entered if the SLEEPDEEP bit is set in the SCR register when the processor +// executes a WFI instruction. +bool f2xx_pwr_powerdown_deepsleep(void *opaqe) +{ + f2xx_pwr *s = opaqe; + return s->regs[R_PWR_CR] & R_PWR_CR_PDDS; +} + +static void f2xx_pwr_reset(DeviceState *dev) +{ + f2xx_pwr *s = FROM_SYSBUS(f2xx_pwr, SYS_BUS_DEVICE(dev)); + + memset(s->regs, 0, sizeof(s->regs)); +} + + +static int +f2xx_pwr_init(SysBusDevice *dev) +{ + f2xx_pwr *s = FROM_SYSBUS(f2xx_pwr, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_pwr_ops, s, "pwr", 0x08); + sysbus_init_mmio(dev, &s->iomem); + + s->regs[R_PWR_CR] = 0; + s->regs[R_PWR_CSR] = 0; + + return 0; +} + +static Property f2xx_pwr_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static void +f2xx_pwr_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f2xx_pwr_init; + dc->reset = f2xx_pwr_reset; + dc->props = f2xx_pwr_properties; +} + +static const TypeInfo +f2xx_pwr_info = { + .name = "f2xx_pwr", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f2xx_pwr), + .class_init = f2xx_pwr_class_init, +}; + +static void +f2xx_pwr_register_types(void) +{ + type_register_static(&f2xx_pwr_info); +} + +type_init(f2xx_pwr_register_types) diff --git a/hw/arm/stm32f2xx_rcc.c b/hw/arm/stm32f2xx_rcc.c new file mode 100644 index 0000000000000..a55f760ad23cc --- /dev/null +++ b/hw/arm/stm32f2xx_rcc.c @@ -0,0 +1,1134 @@ +/* + * STM32 Microcontroller RCC (Reset and Clock Control) module + * + * Copyright (C) 2010 Andre Beckus + * + * Source code based on omap_clk.c + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "stm32f2xx_rcc.h" +#include "qemu/timer.h" +#include + + +/* DEFINITIONS*/ + +/* See README for DEBUG details. */ +//#define DEBUG_STM32_RCC + +#ifdef DEBUG_STM32_RCC +#define DPRINTF(fmt, ...) \ +do { printf("STM32F2XX_RCC: " fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define IS_RESET_VALUE(new_value, mask, reset_value) ((new_value & mask) == (mask & reset_value)) + +#define WARN_UNIMPLEMENTED(new_value, mask, reset_value) \ + if (!IS_RESET_VALUE(new_value, mask, reset_value)) { \ + stm32_unimp("Not implemented: RCC " #mask ". Masked value: 0x%08x\n", (new_value & mask)); \ + } + +#define WARN_UNIMPLEMENTED_REG(offset) \ + stm32_unimp("STM32f2xx_rcc: unimplemented register: 0x%x", (int)offset) + +#define HSI_FREQ 16000000 +#define LSI_FREQ 32000 + +#define RCC_CR_RESET_VALUE 0x00000083 +#define RCC_CR_OFFSET 0x00 +#define RCC_CR_PLLI2SRDY_BIT 27 +#define RCC_CR_PLLI2SON_BIT 26 +#define RCC_CR_PLLRDY_BIT 25 +#define RCC_CR_PLLON_BIT 24 +#define RCC_CR_CSSON_BIT 19 +#define RCC_CR_HSEBYP_BIT 18 +#define RCC_CR_HSERDY_BIT 17 +#define RCC_CR_HSEON_BIT 16 +#define RCC_CR_HSICAL_START 8 +#define RCC_CR_HSICAL_MASK 0x0000ff00 +#define RCC_CR_HSITRIM_START 3 +#define RCC_CR_HSITRIM_MASK 0x000000f8 +#define RCC_CR_HSIRDY_BIT 1 +#define RCC_CR_HSION_BIT 0 + +#define RCC_PLLCFGR_RESET_VALUE 0x24003010 +#define RCC_PLLCFGR_OFFSET 0x04 +#define RCC_PLLCFGR_PLLQ_MASK 0x0F000000 +#define RCC_PLLCFGR_PLLQ_START 24 +#define RCC_PLLCFGR_PLLSRC_BIT 22 +#define RCC_PLLCFGR_PLLP_MASK 0x00030000 +#define RCC_PLLCFGR_PLLP_START 16 +#define RCC_PLLCFGR_PLLN_MASK 0x00007FC0 +#define RCC_PLLCFGR_PLLN_START 6 +#define RCC_PLLCFGR_PLLM_MASK 0x0000003F +#define RCC_PLLCFGR_PLLM_START 0 + +#define RCC_CFGR_RESET_VALUE 0x00000000 +#define RCC_CFGR_OFFSET 0x08 +#define RCC_CFGR_MCO2_START 30 +#define RCC_CFGR_MCO2_MASK 0xC0000000 +#define RCC_CFGR_MCO2PRE_START 27 +#define RCC_CFGR_MCO2PRE_MASK 0x38000000 +#define RCC_CFGR_MCO1PRE_START 24 +#define RCC_CFGR_MCO1PRE_MASK 0x07000000 +#define RCC_CFGR_I2CSRC_BIT 23 +#define RCC_CFGR_MCO1_START 21 +#define RCC_CFGR_MCO1_MASK 0x00600000 +#define RCC_CFGR_RTCPRE_START 16 +#define RCC_CFGR_RTCPRE_MASK 0x001F0000 +#define RCC_CFGR_PPRE2_START 13 +#define RCC_CFGR_PPRE2_MASK 0x0000E000 +#define RCC_CFGR_PPRE1_START 10 +#define RCC_CFGR_PPRE1_MASK 0x00001C00 +#define RCC_CFGR_HPRE_START 4 +#define RCC_CFGR_HPRE_MASK 0x000000F0 +#define RCC_CFGR_SWS_START 2 +#define RCC_CFGR_SWS_MASK 0x0000000C +#define RCC_CFGR_SW_START 0 +#define RCC_CFGR_SW_MASK 0x00000003 + +#define RCC_CIR_RESET_VALUE 0x00000000 +#define RCC_CIR_OFFSET 0x0C +#define RCC_CIR_CSSC_BIT 23 +#define RCC_CIR_PLLI2SRDYC_BIT 21 +#define RCC_CIR_PLLRDYC_BIT 20 +#define RCC_CIR_HSERDYC_BIT 19 +#define RCC_CIR_HSIRDYC_BIT 18 +#define RCC_CIR_LSERDYC_BIT 17 +#define RCC_CIR_LSIRDYC_BIT 16 +#define RCC_CIR_PLLI2SRDYIE_BIT 13 +#define RCC_CIR_PLLRDYIE_BIT 12 +#define RCC_CIR_HSERDYIE_BIT 11 +#define RCC_CIR_HSIRDYIE_BIT 10 +#define RCC_CIR_LSERDYIE_BIT 9 +#define RCC_CIR_LSIRDYIE_BIT 8 +#define RCC_CIR_CSSF_BIT 7 +#define RCC_CIR_PLLI2SRDYF_BIT 5 +#define RCC_CIR_PLLRDYF_BIT 4 +#define RCC_CIR_HSERDYF_BIT 3 +#define RCC_CIR_HSIRDYF_BIT 2 +#define RCC_CIR_LSERDYF_BIT 1 +#define RCC_CIR_LSIRDYF_BIT 0 + +#define RCC_AHB1RSTR_OFFSET 0x10 + +#define RCC_AHB2RSTR_OFFSET 0x14 + +#define RCC_AHB3RSTR_OFFSET 0x18 + +#define RCC_APB1RSTR_OFFSET 0x20 + +#define RCC_APB2RSTR_RESET_VALUE 0x00000000 +#define RCC_APB2RSTR_OFFSET 0x24 +#define RCC_APB2RSTR_TIM11RST_BIT 18 +#define RCC_APB2RSTR_TIM10RST_BIT 17 +#define RCC_APB2RSTR_TIM9RST_BIT 16 +#define RCC_APB2RSTR_SYSCFGRST 14 +#define RCC_APB2RSTR_SPI1_BIT 12 +#define RCC_APB2RSTR_SDIORST_BIT 11 +#define RCC_APB2RSTR_ADCRST_BIT 8 +#define RCC_APB2RSTR_USART6RST 5 +#define RCC_APB2RSTR_USART1RST 4 +#define RCC_APB2RSTR_TIM8RST_BIT 1 +#define RCC_APB2RSTR_TIM1RST_BIT 0 + +#define RCC_AHB1ENR_RESET_VALUE 0x00000000 +#define RCC_AHB1ENR_OFFSET 0x30 +#define RCC_AHB1ENR_OTGHSULPIEN_BIT 30 +#define RCC_AHB1ENR_OTGHSEN_BIT 29 +#define RCC_AHB1ENR_ETHMACPTPEN_BIT 28 +#define RCC_AHB1ENR_ETHMACRXEN_BIT 27 +#define RCC_AHB1ENR_ETHMACTXEN_BIT 26 +#define RCC_AHB1ENR_ETHMACEN_BIT 25 +#define RCC_AHB1ENR_DMA2EN_BIT 22 +#define RCC_AHB1ENR_DMA1EN_BIT 21 +#define RCC_AHB1ENR_BKPSRAMEN_BIT 18 +#define RCC_AHB1ENR_CRCEN_BIT 12 +#define RCC_AHB1ENR_GPIOKEN_BIT 10 +#define RCC_AHB1ENR_GPIOJEN_BIT 9 +#define RCC_AHB1ENR_GPIOIEN_BIT 8 +#define RCC_AHB1ENR_GPIOHEN_BIT 7 +#define RCC_AHB1ENR_GPIOGEN_BIT 6 +#define RCC_AHB1ENR_GPIOFEN_BIT 5 +#define RCC_AHB1ENR_GPIOEEN_BIT 4 +#define RCC_AHB1ENR_GPIODEN_BIT 3 +#define RCC_AHB1ENR_GPIOCEN_BIT 2 +#define RCC_AHB1ENR_GPIOBEN_BIT 1 +#define RCC_AHB1ENR_GPIOAEN_BIT 0 + +#define RCC_AHB2ENR_OFFSET 0x34 +#define RCC_AHB2ENR_DCMIEN_BIT 0 +#define RCC_AHB2ENR_CRYPEN_BIT 4 +#define RCC_AHB2ENR_HASHEN_BIT 5 +#define RCC_AHB2ENR_RNGEN_BIT 6 +#define RCC_AHB2ENR_OTGFSEN_BIT 7 + +#define RCC_AHB3ENR_OFFSET 0x38 +#define RCC_AHB3ENR_FSMCEN_BIT 0 + +#define RCC_APB1ENR_RESET_VALUE 0x00000000 +#define RCC_APB1ENR_OFFSET 0x40 +#define RCC_APB1ENR_USART8EN_BIT 31 +#define RCC_APB1ENR_USART7EN_BIT 30 +#define RCC_APB1ENR_DACEN_BIT 29 +#define RCC_APB1ENR_PWREN_BIT 28 +#define RCC_APB1ENR_BKPEN_BIT 27 +#define RCC_APB1ENR_CAN2EN_BIT 26 +#define RCC_APB1ENR_CAN1EN_BIT 25 +#define RCC_APB1ENR_CANEN_BIT 25 +#define RCC_APB1ENR_USBEN_BIT 23 +#define RCC_APB1ENR_I2C2EN_BIT 22 +#define RCC_APB1ENR_I2C1EN_BIT 21 +#define RCC_APB1ENR_USART5EN_BIT 20 +#define RCC_APB1ENR_USART4EN_BIT 19 +#define RCC_APB1ENR_USART3EN_BIT 18 +#define RCC_APB1ENR_USART2EN_BIT 17 +#define RCC_APB1ENR_SPI3EN_BIT 15 +#define RCC_APB1ENR_SPI2EN_BIT 14 +#define RCC_APB1ENR_WWDGEN_BIT 11 +#define RCC_APB1ENR_TIM7EN_BIT 5 +#define RCC_APB1ENR_TIM6EN_BIT 4 +#define RCC_APB1ENR_TIM5EN_BIT 3 +#define RCC_APB1ENR_TIM4EN_BIT 2 +#define RCC_APB1ENR_TIM3EN_BIT 1 +#define RCC_APB1ENR_TIM2EN_BIT 0 + +#define RCC_APB2ENR_RESET_VALUE 0x00000000 +#define RCC_APB2ENR_OFFSET 0x44 +#define RCC_APB2ENR_MASK 0x00075F33 +#define RCC_APB2ENR_TIM11EN 18 +#define RCC_APB2ENR_TIM10EN 17 +#define RCC_APB2ENR_TIM9EN 16 +#define RCC_APB2ENR_SYSCFGEN_BIT 14 +#define RCC_APB2ENR_SPI1EN_BIT 12 +#define RCC_APB2ENR_SDIOEN_BIT 11 +#define RCC_APB2ENR_ADC3EN_BIT 10 +#define RCC_APB2ENR_ADC2EN_BIT 9 +#define RCC_APB2ENR_ADC1EN_BIT 8 +#define RCC_APB2ENR_USART6EN_BIT 5 +#define RCC_APB2ENR_USART1EN_BIT 4 +#define RCC_APB2ENR_TIM8EN_BIT 1 +#define RCC_APB2ENR_TIM1EN_BIT 0 + +#define RCC_AHB1LPENR_RESET_VALUE 0x7E6791FF +#define RCC_AHB1LPENR_OFFSET 0x50 + +#define RCC_AHB2LPENR_RESET_VALUE 0x000000F1 +#define RCC_AHB2LPENR_OFFSET 0x54 + +#define RCC_AHB3LPENR_RESET_VALUE 0x00000001 +#define RCC_AHB3LPENR_OFFSET 0x58 + +#define RCC_APB1LPENR_RESET_VALUE 0x36FEC9FF +#define RCC_APB1LPENR_OFFSET 0x60 + +#define RCC_APB2LPENR_RESET_VALUE 0x00075F33 +#define RCC_APB2LPENR_OFFSET 0x64 + +#define RCC_BDCR_RESET_VALUE 0x00000000 +#define RCC_BDCR_OFFSET 0x70 +#define RCC_BDCR_BDRST_BIT 16 +#define RCC_BDCR_RTCEN_BIT 15 +#define RCC_BDCR_RTCSEL_START 8 +#define RCC_BDCR_RTCSEL_MASK 0x00000300 +#define RCC_BDCR_LSEBYP_BIT 2 +#define RCC_BDCR_LSERDY_BIT 1 +#define RCC_BDCR_LSEON_BIT 0 + +#define RCC_CSR_RESET_VALUE 0x0E000000 +#define RCC_CSR_OFFSET 0x74 +#define RCC_CSR_LPWRRSTF_BIT 31 +#define RCC_CSR_WWDGRSTF_BIT 30 +#define RCC_CSR_IWDGRSTF_BIT 29 +#define RCC_CSR_SFTRSTF_BIT 28 +#define RCC_CSR_PORRSTF_BIT 27 +#define RCC_CSR_PINRSTF_BIT 26 +#define RCC_CSR_BORRSTF_BIT 25 +#define RCC_CSR_RMVF_BIT 24 +#define RCC_CSR_LSIRDY_BIT 1 +#define RCC_CSR_LSION_BIT 0 + +#define RCC_SSCGR_RESET_VALUE 0x00000000 +#define RCC_SSCGR_OFFSET 0x80 + +#define RCC_PLLI2SCFGR_RESET_VALUE 0x20003000 +#define RCC_PLLI2SCFGR_OFFSET 0x84 +#define RCC_PLLI2SCFGR_PLLR_MASK 0x70000000 +#define RCC_PLLI2SCFGR_PLLR_START 28 +#define RCC_PLLI2SCFGR_PLLQ_MASK 0x0F000000 +#define RCC_PLLI2SCFGR_PLLQ_START 24 +#define RCC_PLLI2SCFGR_PLLN_MASK 0x00007FC0 +#define RCC_PLLI2SCFGR_PLLN_START 6 + + + +#define PLLSRC_HSI_SELECTED 0 +#define PLLSRC_HSE_SELECTED 1 + +#define SW_HSI_SELECTED 0 +#define SW_HSE_SELECTED 1 +#define SW_PLL_SELECTED 2 + +/* HELPER FUNCTIONS */ +struct Clk { + const char *name; + + bool enabled; + + uint32_t input_freq, output_freq, max_output_freq; + + uint16_t multiplier, divisor; + + unsigned user_count; + qemu_irq user[CLKTREE_MAX_IRQ]; /* Who to notify on change */ + + unsigned output_count; + struct Clk *output[CLKTREE_MAX_OUTPUT]; + + unsigned input_count; + int selected_input; + struct Clk *input[CLKTREE_MAX_INPUT]; +}; + + +/* Enable the peripheral clock if the specified bit is set in the value. */ +static void stm32_rcc_periph_enable( + Stm32f2xxRcc *s, + uint32_t new_value, + bool init, + int periph, + uint32_t bit_mask) +{ + //printf("rcc set 0x%x %s %d %x: %sable\n", new_value, s->PERIPHCLK[periph]->name, periph, bit_mask, IS_BIT_SET(new_value, bit_mask)?"en":"dis"); + clktree_set_enabled(s->PERIPHCLK[periph], IS_BIT_SET(new_value, bit_mask)); +} + + + + + +/* REGISTER IMPLEMENTATION */ + +/* Read the configuration register. + NOTE: Not implemented: CSS, PLLI2S, clock calibration and trimming. */ +static uint32_t stm32_rcc_RCC_CR_read(Stm32f2xxRcc *s) +{ + /* Get the status of the clocks. */ + const bool PLLON = clktree_is_enabled(s->PLLCLK); + const bool HSEON = clktree_is_enabled(s->HSECLK); + const bool HSION = clktree_is_enabled(s->HSICLK); + const bool PLLI2SON = clktree_is_enabled(s->PLLI2SCLK); + + /* build the register value based on the clock states. If a clock is on, + * then its ready bit is always set. + */ + return ( + GET_BIT_MASK(RCC_CR_PLLRDY_BIT, PLLON) | + GET_BIT_MASK(RCC_CR_PLLON_BIT, PLLON) | + + GET_BIT_MASK(RCC_CR_HSERDY_BIT, HSEON) | + GET_BIT_MASK(RCC_CR_HSEON_BIT, HSEON) | + + GET_BIT_MASK(RCC_CR_HSIRDY_BIT, HSION) | + GET_BIT_MASK(RCC_CR_HSION_BIT, HSION) | + + GET_BIT_MASK(RCC_CR_PLLI2SRDY_BIT, PLLI2SON) | + GET_BIT_MASK(RCC_CR_PLLI2SON_BIT, PLLI2SON) + ); +} + +/* Write the Configuration Register. + * This updates the states of the corresponding clocks. The bit values are not + * saved - when the register is read, its value will be built using the clock + * states. + */ +static void stm32_rcc_RCC_CR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + bool new_PLLON, new_HSEON, new_HSION, new_PLLI2SON; + + new_PLLON = IS_BIT_SET(new_value, RCC_CR_PLLON_BIT); + if((clktree_is_enabled(s->PLLCLK) && !new_PLLON) && + s->RCC_CFGR_SW == SW_PLL_SELECTED) { + stm32_hw_warn("PLL cannot be disabled while it is selected as the system clock."); + } + clktree_set_enabled(s->PLLCLK, new_PLLON); + + new_HSEON = IS_BIT_SET(new_value, RCC_CR_HSEON_BIT); + if((clktree_is_enabled(s->HSECLK) && !new_HSEON) && + (s->RCC_CFGR_SW == SW_HSE_SELECTED || s->RCC_CFGR_SW == SW_PLL_SELECTED) + ) { + stm32_hw_warn("HSE oscillator cannot be disabled while it is driving the system clock."); + } + clktree_set_enabled(s->HSECLK, new_HSEON); + + new_HSION = IS_BIT_SET(new_value, RCC_CR_HSION_BIT); + if((clktree_is_enabled(s->HSECLK) && !new_HSEON) && + (s->RCC_CFGR_SW == SW_HSI_SELECTED || s->RCC_CFGR_SW == SW_PLL_SELECTED) + ) { + stm32_hw_warn("HSI oscillator cannot be disabled while it is driving the system clock."); + } + clktree_set_enabled(s->HSICLK, new_HSION); + + new_PLLI2SON = IS_BIT_SET(new_value, RCC_CR_PLLI2SON_BIT); + clktree_set_enabled(s->PLLI2SCLK, new_PLLI2SON); + + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CR_CSSON_BIT, RCC_CR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CR_HSICAL_MASK, RCC_CR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CR_HSITRIM_MASK, RCC_CR_RESET_VALUE); +} + + +static uint32_t stm32_rcc_RCC_PLLCFGR_read(Stm32f2xxRcc *s) +{ + return s->RCC_PLLCFGR; +} + +static void stm32_rcc_RCC_PLLCFGR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + /* PLLM division factor */ + const uint8_t new_PLLM = (new_value & RCC_PLLCFGR_PLLM_MASK) >> RCC_PLLCFGR_PLLM_START; + if (new_PLLM <= 1) { + hw_error("PLLM division factor cannot be 0 or 1. Given: %u", new_PLLM); + } + + /* PLLN multiplication factor */ + const uint16_t new_PLLN = (new_value & RCC_PLLCFGR_PLLN_MASK) >> RCC_PLLCFGR_PLLN_START; + if (new_PLLN <= 1 || new_PLLN >= 433) { + hw_error("PLLN multiplication factor must be between 2 and 432 (inclusive). Given: %u", new_PLLN); + } + + /* PLLSRC */ + const uint8_t new_PLLSRC = IS_BIT_SET(new_value, RCC_PLLCFGR_PLLSRC_BIT); + + /* PPLP division factor */ + const uint8_t new_PLLP = 2 + (2 * ((new_value & RCC_PLLCFGR_PLLP_MASK) >> RCC_PLLCFGR_PLLP_START)); + + /* Warn in case of illegal writes: */ + if (init == false) { + const bool are_disabled = (!clktree_is_enabled(s->PLLCLK) /* && TODO: !clktree_is_enabled(s->PLLI2SCLK) */); + if (are_disabled == false) { + const char *warning_fmt = "Can only change %s while PLL and PLLI2S are disabled"; + if (new_PLLM != s->RCC_PLLCFGR_PLLM) { + stm32_hw_warn(warning_fmt, "PLLM"); + } + if (new_PLLN != s->RCC_PLLCFGR_PLLN) { + stm32_hw_warn(warning_fmt, "PLLN"); + } + if (new_PLLSRC != s->RCC_PLLCFGR_PLLSRC) { + stm32_hw_warn(warning_fmt, "PLLSRC"); + } + } + } + + /* Save new register value */ + s->RCC_PLLCFGR = new_value; + + /* Set the new values: */ + s->RCC_PLLCFGR_PLLM = new_PLLM; + s->RCC_PLLCFGR_PLLN = new_PLLN; + clktree_set_scale(s->PLLM, new_PLLN, new_PLLM); + + s->RCC_PLLCFGR_PLLSRC = new_PLLSRC; + clktree_set_selected_input(s->PLLM, new_PLLSRC); + + s->RCC_PLLCFGR_PLLP = new_PLLP; + clktree_set_scale(s->PLLCLK, 1, new_PLLP); + + WARN_UNIMPLEMENTED(new_value, RCC_PLLCFGR_PLLQ_MASK, RCC_PLLCFGR_RESET_VALUE); +} + + +static uint32_t stm32_rcc_RCC_PLLI2SCFGR_read(Stm32f2xxRcc *s) +{ + return s->RCC_PLLI2SCFGR; +} + + +static void stm32_rcc_RCC_PLLI2SCFGR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + /* PLLR division factor */ + const uint16_t new_PLLR = (new_value & RCC_PLLI2SCFGR_PLLR_MASK) >> RCC_PLLI2SCFGR_PLLR_START; + if (new_PLLR < 2 || new_PLLR > 7) { + hw_error("PLLR multiplication factor must be between 2 and 7. Given: %u", new_PLLR); + } + + /* PLLQ division factor */ + const uint16_t new_PLLQ = (new_value & RCC_PLLI2SCFGR_PLLQ_MASK) >> RCC_PLLI2SCFGR_PLLQ_START; + if (new_PLLQ > 15) { + hw_error("PLLQ multiplication factor must be between 0 and 15 " + "(inclusive). Given: %u", new_PLLQ); + } + + /* PLLN multiplication factor */ + const uint16_t new_PLLN = (new_value & RCC_PLLI2SCFGR_PLLN_MASK) >> RCC_PLLI2SCFGR_PLLN_START; + if (new_PLLN < 2 || new_PLLN > 433) { + hw_error("PLLN multiplication factor must be between 2 and 432 (inclusive). Given: %u", new_PLLN); + } + + + /* Warn in case of illegal writes: */ + if (init == false) { + const bool are_disabled = (!clktree_is_enabled(s->PLLI2SCLK) /* && TODO: !clktree_is_enabled(s->PLLI2SCLK) */); + if (are_disabled == false) { + const char *warning_fmt = "Can only change %s while PLL and PLLI2S are disabled"; + if (new_PLLR != s->RCC_PLLI2SCFGR_PLLR) { + stm32_hw_warn(warning_fmt, "PLLR"); + } + if (new_PLLQ != s->RCC_PLLI2SCFGR_PLLQ) { + stm32_hw_warn(warning_fmt, "PLLQ"); + } + if (new_PLLN != s->RCC_PLLCFGR_PLLN) { + stm32_hw_warn(warning_fmt, "PLLN"); + } + } + } + + /* Save new register value */ + s->RCC_PLLI2SCFGR = new_value; + + /* Set the new values: */ + s->RCC_PLLI2SCFGR_PLLR = new_PLLR; + s->RCC_PLLI2SCFGR_PLLQ = new_PLLQ; + s->RCC_PLLI2SCFGR_PLLN = new_PLLN; + clktree_set_scale(s->PLLI2SM, new_PLLN, s->RCC_PLLCFGR_PLLM ); + + clktree_set_scale(s->PLLI2SCLK, 1, new_PLLR); + WARN_UNIMPLEMENTED(new_value, RCC_PLLI2SCFGR_PLLQ_MASK, RCC_PLLI2SCFGR_RESET_VALUE); +} + + +static uint32_t stm32_rcc_RCC_CFGR_read(Stm32f2xxRcc *s) +{ + return + (s->RCC_CFGR_PPRE2 << RCC_CFGR_PPRE2_START) | + (s->RCC_CFGR_PPRE1 << RCC_CFGR_PPRE1_START) | + (s->RCC_CFGR_HPRE << RCC_CFGR_HPRE_START) | + (s->RCC_CFGR_SW << RCC_CFGR_SW_START) | + (s->RCC_CFGR_SW << RCC_CFGR_SWS_START); +} + +static void stm32_rcc_RCC_CFGR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + /* PPRE2 */ + s->RCC_CFGR_PPRE2 = (new_value & RCC_CFGR_PPRE2_MASK) >> RCC_CFGR_PPRE2_START; + if(s->RCC_CFGR_PPRE2 < 0x4) { + clktree_set_scale(s->PCLK2, 1, 1); + } else { + clktree_set_scale(s->PCLK2, 1, 2 * (s->RCC_CFGR_PPRE2 - 3)); + } + + /* PPRE1 */ + s->RCC_CFGR_PPRE1 = (new_value & RCC_CFGR_PPRE1_MASK) >> RCC_CFGR_PPRE1_START; + if(s->RCC_CFGR_PPRE1 < 4) { + clktree_set_scale(s->PCLK1, 1, 1); + } else { + clktree_set_scale(s->PCLK1, 1, 2 * (s->RCC_CFGR_PPRE1 - 3)); + } + + /* HPRE */ + s->RCC_CFGR_HPRE = (new_value & RCC_CFGR_HPRE_MASK) >> RCC_CFGR_HPRE_START; + if(s->RCC_CFGR_HPRE < 8) { + clktree_set_scale(s->HCLK, 1, 1); + } else { + clktree_set_scale(s->HCLK, 1, 2 * (s->RCC_CFGR_HPRE - 7)); + } + + /* SW */ + s->RCC_CFGR_SW = (new_value & RCC_CFGR_SW_MASK) >> RCC_CFGR_SW_START; + switch(s->RCC_CFGR_SW) { + case 0x0: + case 0x1: + case 0x2: + clktree_set_selected_input(s->SYSCLK, s->RCC_CFGR_SW); + break; + default: + hw_error("Invalid input selected for SYSCLK"); + break; + } + + WARN_UNIMPLEMENTED(new_value, RCC_CFGR_MCO2_MASK, RCC_CFGR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CFGR_MCO2PRE_MASK, RCC_CFGR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CFGR_MCO1PRE_MASK, RCC_CFGR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CFGR_I2CSRC_BIT, RCC_CFGR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CFGR_MCO1_MASK, RCC_CFGR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CFGR_RTCPRE_MASK, RCC_CFGR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_CFGR_SWS_MASK, RCC_CFGR_RESET_VALUE); +} + +static uint32_t stm32_rcc_RCC_CIR_read(Stm32f2xxRcc *s) +{ + return s->RCC_CIR; +} + +static void stm32_rcc_RCC_CIR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_CSSC_BIT, RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_PLLI2SRDYC_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_PLLRDYC_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_HSERDYC_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_HSIRDYC_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_LSERDYC_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_LSIRDYC_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_PLLI2SRDYIE_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_PLLRDYIE_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_HSERDYIE_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_HSIRDYIE_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_LSERDYIE_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_LSIRDYIE_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_CSSF_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_PLLI2SRDYF_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_PLLRDYF_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_HSERDYF_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_HSIRDYF_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_LSERDYF_BIT , RCC_CIR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_CIR_LSIRDYF_BIT , RCC_CIR_RESET_VALUE); +} + +static uint32_t stm32_rcc_RCC_AHB1ENR_read(Stm32f2xxRcc *s) +{ + return s->RCC_AHB1ENR; +} + +static uint32_t stm32_rcc_RCC_AHB2ENR_read(Stm32f2xxRcc *s) +{ + return s->RCC_AHB2ENR; +} + +static uint32_t stm32_rcc_RCC_AHB3ENR_read(Stm32f2xxRcc *s) +{ + return s->RCC_AHB3ENR; +} + +static void stm32_rcc_RCC_AHB1ENR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + clktree_set_enabled(s->PERIPHCLK[STM32_DMA2], IS_BIT_SET(new_value, RCC_AHB1ENR_DMA2EN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_DMA1], IS_BIT_SET(new_value, RCC_AHB1ENR_DMA1EN_BIT)); + + clktree_set_enabled(s->PERIPHCLK[STM32_CRC], IS_BIT_SET(new_value, RCC_AHB1ENR_CRCEN_BIT)); + + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOK], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOKEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOJ], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOJEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOI], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOIEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOH], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOHEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOG], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOGEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOF], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOFEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOE], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOEEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOD], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIODEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOC], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOCEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOB], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOBEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_GPIOA], IS_BIT_SET(new_value, RCC_AHB1ENR_GPIOAEN_BIT)); + + s->RCC_AHB1ENR = new_value; + + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_OTGHSULPIEN_BIT, RCC_AHB1ENR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_OTGHSEN_BIT, RCC_AHB1ENR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_ETHMACPTPEN_BIT, RCC_AHB1ENR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_ETHMACRXEN_BIT, RCC_AHB1ENR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_ETHMACTXEN_BIT, RCC_AHB1ENR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_ETHMACEN_BIT, RCC_AHB1ENR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_AHB1ENR_BKPSRAMEN_BIT, RCC_AHB1ENR_RESET_VALUE); +} + +static void stm32_rcc_RCC_AHB2ENR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + clktree_set_enabled(s->PERIPHCLK[STM32_DCMI_PERIPH], + IS_BIT_SET(new_value, RCC_AHB2ENR_DCMIEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_CRYP_PERIPH], + IS_BIT_SET(new_value, RCC_AHB2ENR_CRYPEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_HASH_PERIPH], + IS_BIT_SET(new_value, RCC_AHB2ENR_HASHEN_BIT)); + clktree_set_enabled(s->PERIPHCLK[STM32_RNG_PERIPH], + IS_BIT_SET(new_value, RCC_AHB2ENR_RNGEN_BIT)); + s->RCC_AHB2ENR = new_value; +} + +static void stm32_rcc_RCC_AHB3ENR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + clktree_set_enabled(s->PERIPHCLK[STM32_FSMC], + IS_BIT_SET(new_value, RCC_AHB3ENR_FSMCEN_BIT)); + s->RCC_AHB3ENR = new_value; +} + +/* Write the APB2 peripheral clock enable register + * Enables/Disables the peripheral clocks based on each bit. */ +static void stm32_rcc_RCC_APB2ENR_write(Stm32f2xxRcc *s, uint32_t new_value, + bool init) +{ + /* TODO: enable/disable missing peripherals */ + stm32_rcc_periph_enable(s, new_value, init, STM32_SYSCFG, RCC_APB2ENR_SYSCFGEN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART1, RCC_APB2ENR_USART1EN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART6, RCC_APB2ENR_USART6EN_BIT); + + s->RCC_APB2ENR = new_value & RCC_APB2ENR_MASK; +} + +/* Write the APB1 peripheral clock enable register + * Enables/Disables the peripheral clocks based on each bit. */ +static void stm32_rcc_RCC_APB1ENR_write(Stm32f2xxRcc *s, uint32_t new_value, + bool init) +{ + stm32_rcc_periph_enable(s, new_value, init, STM32_UART8, + RCC_APB1ENR_USART8EN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART7, + RCC_APB1ENR_USART7EN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART5, + RCC_APB1ENR_USART5EN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART4, + RCC_APB1ENR_USART4EN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART3, + RCC_APB1ENR_USART3EN_BIT); + stm32_rcc_periph_enable(s, new_value, init, STM32_UART2, + RCC_APB1ENR_USART2EN_BIT); + + /* 0b00110110111111101100100111111111 */ + s->RCC_APB1ENR = new_value & 0x36fec9ff; +} + +static uint32_t stm32_rcc_RCC_BDCR_read(Stm32f2xxRcc *s) +{ + bool lseon = clktree_is_enabled(s->LSECLK); + + return GET_BIT_MASK(RCC_BDCR_LSERDY_BIT, lseon) | + GET_BIT_MASK(RCC_BDCR_LSEON_BIT, lseon) | 0x100; /* XXX force LSE */ +} + +static void stm32_rcc_RCC_BDCR_writeb0(Stm32f2xxRcc *s, uint8_t new_value, bool init) +{ + clktree_set_enabled(s->LSECLK, IS_BIT_SET(new_value, RCC_BDCR_LSEON_BIT)); + + WARN_UNIMPLEMENTED(new_value, 1 << RCC_BDCR_LSEBYP_BIT, RCC_BDCR_RESET_VALUE); +} + +static void stm32_rcc_RCC_BDCR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + stm32_rcc_RCC_BDCR_writeb0(s, new_value & 0xff, init); + + WARN_UNIMPLEMENTED(new_value, 1 << RCC_BDCR_BDRST_BIT, RCC_BDCR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, 1 << RCC_BDCR_RTCEN_BIT, RCC_BDCR_RESET_VALUE); + WARN_UNIMPLEMENTED(new_value, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RESET_VALUE); +} + +/* Works the same way as stm32_rcc_RCC_CR_read */ +static uint32_t stm32_rcc_RCC_CSR_read(Stm32f2xxRcc *s) +{ + bool lseon = clktree_is_enabled(s->LSICLK); + + return GET_BIT_MASK(RCC_CSR_LSIRDY_BIT, lseon) | + GET_BIT_MASK(RCC_CSR_LSION_BIT, lseon); +} + +/* Works the same way as stm32_rcc_RCC_CR_write */ +static void stm32_rcc_RCC_CSR_write(Stm32f2xxRcc *s, uint32_t new_value, bool init) +{ + clktree_set_enabled(s->LSICLK, IS_BIT_SET(new_value, RCC_CSR_LSION_BIT)); +} + + + +static uint64_t stm32_rcc_readw(void *opaque, hwaddr offset) +{ + Stm32f2xxRcc *s = (Stm32f2xxRcc *)opaque; + + switch (offset) { + case RCC_CR_OFFSET: + return stm32_rcc_RCC_CR_read(s); + case RCC_PLLCFGR_OFFSET: + return stm32_rcc_RCC_PLLCFGR_read(s); + case RCC_CFGR_OFFSET: + return stm32_rcc_RCC_CFGR_read(s); + case RCC_CIR_OFFSET: + return stm32_rcc_RCC_CIR_read(s); + case RCC_AHB1RSTR_OFFSET: + case RCC_AHB2RSTR_OFFSET: + case RCC_AHB3RSTR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + return 0; + case RCC_APB1RSTR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + return 0; + case RCC_APB2RSTR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + return 0; + case RCC_AHB1ENR_OFFSET: + return stm32_rcc_RCC_AHB1ENR_read(s); + case RCC_AHB2ENR_OFFSET: + return stm32_rcc_RCC_AHB2ENR_read(s); + case RCC_AHB3ENR_OFFSET: + return stm32_rcc_RCC_AHB3ENR_read(s); + case RCC_APB1ENR_OFFSET: + return s->RCC_APB1ENR; + case RCC_APB2ENR_OFFSET: + return s->RCC_APB2ENR; + case RCC_AHB1LPENR_OFFSET: + case RCC_AHB2LPENR_OFFSET: + case RCC_AHB3LPENR_OFFSET: + case RCC_APB1LPENR_OFFSET: + case RCC_APB2LPENR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + return 0; + case RCC_BDCR_OFFSET: + return stm32_rcc_RCC_BDCR_read(s); + case RCC_CSR_OFFSET: + return stm32_rcc_RCC_CSR_read(s); + case RCC_SSCGR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + return 0; + case RCC_PLLI2SCFGR_OFFSET: + return stm32_rcc_RCC_PLLI2SCFGR_read(s); + default: + WARN_UNIMPLEMENTED_REG(offset); + break; + } + return 0; +} + +static void stm32_rcc_writeb(void *opaque, hwaddr offset, uint64_t value) +{ + Stm32f2xxRcc *s = (Stm32f2xxRcc *)opaque; + + switch (offset) { + case RCC_BDCR_OFFSET: + stm32_rcc_RCC_BDCR_writeb0(s, value, false); + break; + default: + STM32_BAD_REG(offset, 1); + break; + } +} + +static void stm32_rcc_writew(void *opaque, hwaddr offset, + uint64_t value) +{ + Stm32f2xxRcc *s = (Stm32f2xxRcc *)opaque; + + switch(offset) { + case RCC_CR_OFFSET: + stm32_rcc_RCC_CR_write(s, value, false); + break; + case RCC_PLLCFGR_OFFSET: + stm32_rcc_RCC_PLLCFGR_write(s, value, false); + break; + case RCC_CFGR_OFFSET: + stm32_rcc_RCC_CFGR_write(s, value, false); + break; + case RCC_CIR_OFFSET: + stm32_rcc_RCC_CIR_write(s, value, false); + break; + case RCC_APB1RSTR_OFFSET: + stm32_unimp("Unimplemented write: RCC_APB1RSTR_OFFSET 0x%x\n", (uint32_t)value); + break; + case RCC_APB2RSTR_OFFSET: + stm32_unimp("Unimplemented write: RCC_APB2RSTR_OFFSET 0x%x\n", (uint32_t)value); + break; + case RCC_AHB3RSTR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + break; + case RCC_AHB1ENR_OFFSET: + stm32_rcc_RCC_AHB1ENR_write(s, value, false); + break; + case RCC_AHB2ENR_OFFSET: + stm32_rcc_RCC_AHB2ENR_write(s, value, false); + break; + case RCC_AHB3ENR_OFFSET: + stm32_rcc_RCC_AHB3ENR_write(s, value, false); + break; + case RCC_APB1LPENR_OFFSET: + case RCC_APB2LPENR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + break; + case RCC_APB2ENR_OFFSET: + stm32_rcc_RCC_APB2ENR_write(s, value, false); + break; + case RCC_APB1ENR_OFFSET: + stm32_rcc_RCC_APB1ENR_write(s, value, false); + break; + case RCC_AHB1LPENR_OFFSET: + stm32_unimp("Unimplemented: RCC_AHB1LPENR_OFFSET\n"); + break; + case RCC_AHB2LPENR_OFFSET: + stm32_unimp("Unimplemented: RCC_AHB2LPENR_OFFSET\n"); + break; + case RCC_AHB3LPENR_OFFSET: + stm32_unimp("Unimplemented: RCC_AHB3LPENR_OFFSET\n"); + break; + case RCC_BDCR_OFFSET: + stm32_rcc_RCC_BDCR_write(s, value, false); + break; + case RCC_CSR_OFFSET: + stm32_rcc_RCC_CSR_write(s, value, false); + break; + case RCC_SSCGR_OFFSET: + WARN_UNIMPLEMENTED_REG(offset); + break; + case RCC_PLLI2SCFGR_OFFSET: + stm32_rcc_RCC_PLLI2SCFGR_write(s, value, false); + break; + default: + WARN_UNIMPLEMENTED_REG(offset); + break; + } +} + +static uint64_t stm32_rcc_read(void *opaque, hwaddr offset, + unsigned size) +{ + switch(size) { + case 4: + return stm32_rcc_readw(opaque, offset); + default: + stm32_unimp("Unimplemented: RCC read from register at offset %lld", offset); + return 0; + } +} + +static void stm32_rcc_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + switch(size) { + case 4: + stm32_rcc_writew(opaque, offset, value); + break; + case 1: + stm32_rcc_writeb(opaque, offset, value); + break; + default: + WARN_UNIMPLEMENTED_REG(offset); + break; + } +} + +static const MemoryRegionOps stm32_rcc_ops = { + .read = stm32_rcc_read, + .write = stm32_rcc_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + + +static void stm32_rcc_reset(DeviceState *dev) +{ + Stm32f2xxRcc *s = FROM_SYSBUS(Stm32f2xxRcc, SYS_BUS_DEVICE(dev)); + + stm32_rcc_RCC_CR_write(s, RCC_CR_RESET_VALUE, true); + stm32_rcc_RCC_PLLCFGR_write(s, RCC_PLLCFGR_RESET_VALUE, true); + stm32_rcc_RCC_CFGR_write(s, RCC_CFGR_RESET_VALUE, true); + stm32_rcc_RCC_APB2ENR_write(s, RCC_APB2ENR_RESET_VALUE, true); + stm32_rcc_RCC_APB1ENR_write(s, RCC_APB1ENR_RESET_VALUE, true); + stm32_rcc_RCC_BDCR_write(s, RCC_BDCR_RESET_VALUE, true); + stm32_rcc_RCC_CSR_write(s, RCC_CSR_RESET_VALUE, true); +} + +/* IRQ handler to handle updates to the HCLK frequency. + * This updates the SysTick scales. */ +static void stm32_rcc_hclk_upd_irq_handler(void *opaque, int n, int level) +{ + Stm32f2xxRcc *s = (Stm32f2xxRcc *)opaque; + + uint32_t hclk_freq = 0; + uint32_t ext_ref_freq = 0; + + hclk_freq = clktree_get_output_freq(s->HCLK); + + /* Only update the scales if the frequency is not zero. */ + if (hclk_freq > 0) { + ext_ref_freq = hclk_freq / 8; + + /* Update the scales - these are the ratio of QEMU clock ticks + * (which is an unchanging number independent of the CPU frequency) to + * system/external clock ticks. + */ + system_clock_scale = get_ticks_per_sec() / hclk_freq; + } + +#ifdef DEBUG_STM32_RCC + DPRINTF("Cortex SYSTICK frequency set to %lu Hz (scale set to %d).\n", + (unsigned long)hclk_freq, system_clock_scale); +#endif +} + + + +/* DEVICE INITIALIZATION */ + +/* Set up the clock tree */ +static void stm32_rcc_init_clk(Stm32f2xxRcc *s) +{ + int i; + qemu_irq *hclk_upd_irq = + qemu_allocate_irqs(stm32_rcc_hclk_upd_irq_handler, s, 1); + + /* Make sure all the peripheral clocks are null initially. + * This will be used for error checking to make sure + * an invalid clock is not referenced (not all of the + * indexes will be used). + */ + for(i = 0; i < STM32_PERIPH_COUNT; i++) { + s->PERIPHCLK[i] = NULL; + } + + /* Initialize clocks */ + /* Source clocks are initially disabled, which represents + * a disabled oscillator. Enabling the clock represents + * turning the clock on. + */ + s->HSICLK = clktree_create_src_clk("HSI", HSI_FREQ, false); + s->LSICLK = clktree_create_src_clk("LSI", LSI_FREQ, false); + s->HSECLK = clktree_create_src_clk("HSE", s->osc_freq, false); + s->LSECLK = clktree_create_src_clk("LSE", s->osc32_freq, false); + + s->IWDGCLK = clktree_create_clk("IWDGCLK", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, + s->LSICLK, NULL); + s->RTCCLK = clktree_create_clk("RTCCLK", 1, 1, false, CLKTREE_NO_MAX_FREQ, + CLKTREE_NO_INPUT, s->LSECLK, s->LSICLK, s->HSECLK, NULL); + + s->PLLM = clktree_create_clk("PLLM", 1, 16, true, CLKTREE_NO_MAX_FREQ, 0, s->HSICLK, + s->HSECLK, NULL); + s->PLLCLK = clktree_create_clk("PLLCLK", 1, 2, false, 120000000, 0, s->PLLM, NULL); + s->PLL48CLK = clktree_create_clk("PLL48CLK", 1, 1, false, 48000000, 0, s->PLLM, NULL); + + s->PLLI2SM = clktree_create_clk("PLLI2SM", 1, 16, true, CLKTREE_NO_MAX_FREQ, 0, s->PLLM, NULL); + s->PLLI2SCLK = clktree_create_clk("PLLI2SCLK", 1, 2, false, 120000000, 0, s->PLLI2SM, NULL); + + s->SYSCLK = clktree_create_clk("SYSCLK", 1, 1, true, 168000000, CLKTREE_NO_INPUT, + s->HSICLK, s->HSECLK, s->PLLCLK, NULL); + + // HCLK: to AHB bus, core memory and DMA + s->HCLK = clktree_create_clk("HCLK", 0, 1, true, 168000000, 0, s->SYSCLK, NULL); + clktree_adduser(s->HCLK, hclk_upd_irq[0]); + + // Clock source for APB1 peripherals: + s->PCLK1 = clktree_create_clk("PCLK1", 0, 1, true, 30000000, 0, s->HCLK, NULL); + + // Clock source for APB2 peripherals: + s->PCLK2 = clktree_create_clk("PCLK2", 0, 1, true, 60000000, 0, s->HCLK, NULL); + + /* Peripheral clocks */ + s->PERIPHCLK[STM32_GPIOA] = + clktree_create_clk("GPIOA", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOB] = + clktree_create_clk("GPIOB", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOC] = + clktree_create_clk("GPIOC", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOD] = + clktree_create_clk("GPIOD", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOE] = + clktree_create_clk("GPIOE", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOF] = + clktree_create_clk("GPIOF", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOG] = + clktree_create_clk("GPIOG", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOH] = + clktree_create_clk("GPIOH", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOI] = + clktree_create_clk("GPIOI", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOJ] = + clktree_create_clk("GPIOJ", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_GPIOK] = + clktree_create_clk("GPIOK", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + + s->PERIPHCLK[STM32_CRC] = + clktree_create_clk("CRC", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + + s->PERIPHCLK[STM32_DMA1] = + clktree_create_clk("DMA1", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_DMA2] = + clktree_create_clk("DMA2", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + + s->PERIPHCLK[STM32_SYSCFG] = + clktree_create_clk("SYSCFG", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + + s->PERIPHCLK[STM32_UART1] = + clktree_create_clk("UART1", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32_UART2] = + clktree_create_clk("UART2", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32_UART3] = + clktree_create_clk("UART3", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32_UART4] = + clktree_create_clk("UART4", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32_UART5] = + clktree_create_clk("UART5", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32_UART6] = + clktree_create_clk("UART6", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK2, NULL); + s->PERIPHCLK[STM32_UART7] = + clktree_create_clk("UART7", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + s->PERIPHCLK[STM32_UART8] = + clktree_create_clk("UART8", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); + + + s->PERIPHCLK[STM32_DCMI_PERIPH] = + clktree_create_clk("DCMI", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_CRYP_PERIPH] = + clktree_create_clk("CRYP", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_HASH_PERIPH] = + clktree_create_clk("HASH", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + s->PERIPHCLK[STM32_RNG_PERIPH] = + clktree_create_clk("RNG", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); + + s->PERIPHCLK[STM32_FSMC] = + clktree_create_clk("FSMC", 1, 2, false, CLKTREE_NO_MAX_FREQ, 0, s->HCLK, NULL); +} + + + +static int stm32_rcc_init(SysBusDevice *dev) +{ + Stm32f2xxRcc *s = FROM_SYSBUS(Stm32f2xxRcc, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_rcc_ops, s, + "rcc", 0x40023BFF - 0x40023800 + 1); + + sysbus_init_mmio(dev, &s->iomem); + + sysbus_init_irq(dev, &s->irq); + + stm32_rcc_init_clk(s); + + return 0; +} + + +static Property stm32_rcc_properties[] = { + DEFINE_PROP_UINT32("osc_freq", Stm32f2xxRcc, osc_freq, 0), + DEFINE_PROP_UINT32("osc32_freq", Stm32f2xxRcc, osc32_freq, 0), + DEFINE_PROP_END_OF_LIST() +}; + + +static void stm32_rcc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_rcc_init; + dc->reset = stm32_rcc_reset; + dc->props = stm32_rcc_properties; +} + +static TypeInfo stm32_rcc_info = { + .name = "stm32f2xx_rcc", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32f2xxRcc), + .class_init = stm32_rcc_class_init +}; + +static void stm32_rcc_register_types(void) +{ + type_register_static(&stm32_rcc_info); +} + +type_init(stm32_rcc_register_types) diff --git a/hw/arm/stm32f2xx_rcc.h b/hw/arm/stm32f2xx_rcc.h new file mode 100644 index 0000000000000..54ded12733b07 --- /dev/null +++ b/hw/arm/stm32f2xx_rcc.h @@ -0,0 +1,78 @@ +#include "hw/sysbus.h" +#include "hw/arm/stm32_clktree.h" +#include "stm32f2xx.h" +#include "stm32_rcc.h" + +typedef struct Stm32f2xxRcc { + /* Inherited */ + union { + Stm32Rcc inherited; + struct { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + uint32_t osc_freq; + uint32_t osc32_freq; + + /* Private */ + MemoryRegion iomem; + qemu_irq irq; + }; + }; + + /* Peripheral clocks */ + Clk PERIPHCLK[STM32_PERIPH_COUNT], // MUST be first field after `inherited`, because Stm32Rcc's last field aliases this array + HSICLK, + HSECLK, + LSECLK, + LSICLK, + SYSCLK, + IWDGCLK, + RTCCLK, + + PLLM, /* Applies "M" division and "N" multiplication factors for PLL */ + PLLCLK, + PLL48CLK, + + PLLI2SM, /* Applies "M" division and "N" multiplication factors for PLLI2S */ + PLLI2SCLK, + + HCLK, /* Output from AHB Prescaler */ + PCLK1, /* Output from APB1 Prescaler */ + PCLK2; /* Output from APB2 Prescaler */ + + /* Register Values */ + uint32_t + RCC_CIR, + RCC_APB1ENR, + RCC_APB2ENR; + + /* Register Field Values */ + uint32_t + RCC_CFGR_PPRE1, + RCC_CFGR_PPRE2, + RCC_CFGR_HPRE, + RCC_AHB1ENR, + RCC_AHB2ENR, + RCC_AHB3ENR, + RCC_CFGR_SW, + RCC_PLLCFGR, + RCC_PLLI2SCFGR; + + uint8_t + RCC_PLLCFGR_PLLM, + RCC_PLLCFGR_PLLP, + RCC_PLLCFGR_PLLSRC; + + uint16_t + RCC_PLLCFGR_PLLN; + + uint8_t + RCC_PLLI2SCFGR_PLLR, + RCC_PLLI2SCFGR_PLLQ; + + uint16_t + RCC_PLLI2SCFGR_PLLN; + +} Stm32f2xxRcc; diff --git a/hw/arm/stm32f2xx_rtc.c b/hw/arm/stm32f2xx_rtc.c new file mode 100644 index 0000000000000..c37a7ed955073 --- /dev/null +++ b/hw/arm/stm32f2xx_rtc.c @@ -0,0 +1,688 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU stm32f2xx RTC emulation + */ +#include +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "hw/arm/stm32.h" + +// Define this to add extra BKUP registers past the normal ones implemented by the STM. +// For Pebble emulation, we use these to pass settings flags to the emulated target +#define STM32F2XX_RTC_NUM_EXTRA_BKUP_REG 1 + +//#define DEBUG_STM32F2XX_RTC +#ifdef DEBUG_STM32F2XX_RTC +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("DEBUG_STM32F2XX_RTC: " fmt , ## __VA_ARGS__); \ + usleep(100); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + + +#define R_RTC_TR (0x00 / 4) +#define R_RTC_DR (0x04 / 4) +#define R_RTC_CR (0x08 / 4) +#define R_RTC_CR_ALRAE_BIT 8 +#define R_RTC_CR_WUTE 0x00000400 +#define R_RTC_CR_WUTIE 0x00004000 + +#define R_RTC_ISR (0x0c / 4) +#define R_RTC_ISR_RESET 0x00000007 +#define R_RTC_ISR_RSF 0x00000020 +#define R_RTC_ISR_WUT 0x00000400 + +#define R_RTC_PRER (0x10 / 4) +#define R_RTC_PRER_PREDIV_A_MASK 0x7f +#define R_RTC_PRER_PREDIV_A_SHIFT 16 +#define R_RTC_PRER_PREDIV_S_MASK 0x1fff +#define R_RTC_PRER_PREDIV_S_SHIFT 0 +#define R_RTC_PRER_RESET 0x007f00ff +#define R_RTC_WUTR (0x14 / 4) +#define R_RTC_WUTR_RESET 0x0000ffff +#define R_RTC_CALIBR (0x18 / 4) +#define R_RTC_ALRMAR (0x1c / 4) +#define R_RTC_ALRMBR (0x20 / 4) +#define R_RTC_WPR (0x24 / 4) +#define R_RTC_SSR (0x28 / 4) +#define R_RTC_TSTR (0x30 / 4) +#define R_RTC_TSDR (0x34 / 4) +#define R_RTC_TAFCR (0x40 / 4) +#define R_RTC_BKPxR (0x50 / 4) +#define R_RTC_BKPxR_LAST (0x9c / 4) +#define R_RTC_BKPxR_INC_EXTRA_LAST (R_RTC_BKPxR_LAST + STM32F2XX_RTC_NUM_EXTRA_BKUP_REG) +#define R_RTC_MAX (R_RTC_BKPxR_INC_EXTRA_LAST + 1) + +#define R_RTC_CR_FMT_MASK (0x01 << 6) + +#define DEBUG_ALARM(x...) + +typedef struct f2xx_rtc { + SysBusDevice busdev; + MemoryRegion iomem; + QEMUTimer *timer; + QEMUTimer *wu_timer; + qemu_irq irq[2]; + qemu_irq wut_irq; + + // target_us = host_us + host_to_target_offset_us + int64_t host_to_target_offset_us; + + // target time in ticks (seconds according to the RTC registers) + time_t ticks; + + uint32_t regs[R_RTC_MAX]; + int wp_count; /* Number of correct writes to WP reg */ +} f2xx_rtc; + + +// Update target date and time from the host +static void f2xx_update_current_date_and_time(void *arg); + + +// Compute the period for the clock (seconds increments) in nanoseconds +static uint64_t +f2xx_clock_period_ns(f2xx_rtc *s) +{ + uint32_t prer = s->regs[R_RTC_PRER]; + unsigned int prescale; + + // NOTE: We are making the assumption here, as in f2xx_wut_period_ns, that RTC_CLK + // is the 32768 LSE clock + prescale = (((prer >> R_RTC_PRER_PREDIV_A_SHIFT) & R_RTC_PRER_PREDIV_A_MASK) + 1) * + (((prer >> R_RTC_PRER_PREDIV_S_SHIFT) & R_RTC_PRER_PREDIV_S_MASK) + 1); + uint64_t result = 1000000000LL * prescale / 32768; + + //DPRINTF("%s: period = %lldns\n", __func__, result); + return result; +} + + +// Compute the period for the wakeup timer in nanoseconds if the WUT counter is set to the +// given value +static uint64_t +f2xx_wut_period_ns(f2xx_rtc *s, uint32_t counter) +{ + uint32_t clock_sel = s->regs[R_RTC_CR] & 0x07; + + // NOTE: We are making the assumption here, as in f2xx_clock_period_ns, that RTC_CLK + // is the 32768 LSE clock + uint64_t rtc_clk_period_ns = 1000000000LL / 32768; + + // Using the synchronous clock (clk_spre) + if (clock_sel & 0x04) { + if (clock_sel & 0x02) { + return counter * f2xx_clock_period_ns(s); + } else { + return (counter + 65536) * f2xx_clock_period_ns(s); + } + } else if (clock_sel == 0) { + return counter * rtc_clk_period_ns * 16; + } else if (clock_sel == 1) { + return counter * rtc_clk_period_ns * 8; + } else if (clock_sel == 2) { + return counter * rtc_clk_period_ns * 4; + } else if (clock_sel == 3) { + return counter * rtc_clk_period_ns * 2; + } else { + abort(); + } +} + + +// Set the time and registers based on the content of the passed in tm struct +static void +f2xx_rtc_set_time_and_date_registers(f2xx_rtc *s, struct tm *tm) +{ + uint8_t wday; + + wday = tm->tm_wday == 0 ? tm->tm_wday : 7; + s->regs[R_RTC_TR] = to_bcd(tm->tm_sec) | + to_bcd(tm->tm_min) << 8 | + to_bcd(tm->tm_hour) << 16; + s->regs[R_RTC_DR] = to_bcd(tm->tm_mday) | + to_bcd(tm->tm_mon + 1) << 8 | + wday << 13 | + to_bcd(tm->tm_year % 100) << 16; +} + + +// Compute what time we want in the target based on the host's current date and time. +// This takes into consideration the host_to_target_offset_us we have computed and captured +// previously. +// The rtc_period_ns passed in is the number of nanoseconds in host time that corresponds to 1 +// "tick" (i.e. a second increment in the RTC register). Usually, you would expect this to +// be 1e9, but on Pebble plastic for example, the firmware sets up the RTC so that the +// seconds increment 1024 times/sec. +static time_t +f2xx_rtc_compute_target_time_from_host_time(f2xx_rtc *s, uint64_t rtc_period_ns, + struct tm *target_tm) +{ + // Get the host time in microseconds + struct timeval tv; + gettimeofday(&tv, NULL); + int64_t host_time_us = tv.tv_sec * 1000000LL + (tv.tv_usec); + + // Compute the target time by adding the offset + int64_t target_time_us = host_time_us + s->host_to_target_offset_us; + + // Convert to target ticks according period set in the RTC + time_t target_time_ticks = (target_time_us * 1000) / rtc_period_ns; + + // Convert to date, hour, min, sec components + gmtime_r(&target_time_ticks, target_tm); + + +#ifdef DEBUG_STM32F2XX_RTC + char new_date_time[256]; + strftime(new_date_time, sizeof(new_date_time), "%c", target_tm); + //DPRINTF("%s: setting new date & time to: %s\n", __func__, new_date_time); +#endif + return target_time_ticks; +} + + +// Return the current date and time as stored in the RTC TR and DR registers in two forms: +// By filling in the passed in tm struct and by returning the UTC time in seconds. +static time_t +f2xx_rtc_get_current_target_time(f2xx_rtc *s, struct tm *target_tm) +{ + memset(target_tm, 0, sizeof(*target_tm)); + + // Fill in the target_tm from the contents of the time register and date registers + uint32_t time_reg = s->regs[R_RTC_TR]; + + target_tm->tm_hour = from_bcd((time_reg & 0x003F0000) >> 16); + bool pm = (time_reg & 0x00800000) != 0; + if (pm && (s->regs[R_RTC_CR] & R_RTC_CR_FMT_MASK)) { + target_tm->tm_hour += 12; + } + target_tm->tm_min = from_bcd((time_reg & 0x00007F00) >> 8); + target_tm->tm_sec = from_bcd(time_reg & 0x0000007F); + + uint32_t date_reg = s->regs[R_RTC_DR]; + target_tm->tm_mday = from_bcd(date_reg & 0x3f); + target_tm->tm_mon = from_bcd((date_reg & 0x00001F00) >> 8) - 1; + target_tm->tm_year = from_bcd((date_reg & 0x00FF0000) >> 16) + 100; + + // Have mktime fill in the remaining fields and return the UTC seconds as well + return mktimegm(target_tm); +} + + + +// Compute the host to target offset based on the passed in target ticks and the current +// host time. +static int64_t +f2xx_rtc_compute_host_to_target_offset(f2xx_rtc *s, int64_t period_ns, time_t target_ticks) +{ + // Convert target ticks to real clock microseconds + int64_t target_time_us = target_ticks * period_ns / 1000; + + // Get the host time in microseconds + struct timeval tv; + gettimeofday(&tv, NULL); + int64_t host_time_us = tv.tv_sec * 1000000LL + (tv.tv_usec); + + // Get the host to target offset in micro seconds + return target_time_us - host_time_us; +} + + +static uint64_t +f2xx_rtc_read(void *arg, hwaddr addr, unsigned int size) +{ + f2xx_rtc *s = arg; + uint32_t r; + int offset = addr & 0x3; + + addr >>= 2; + if (addr >= R_RTC_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid read f2xx rtc register 0x%x\n", + (unsigned int)addr << 2); + DPRINTF(" %s: result: 0\n", __func__); + return 0; + } + + // If reading the time or date register, make sure they are brought up to date first + if (addr == R_RTC_TR || addr == R_RTC_DR) { + f2xx_update_current_date_and_time(s); + } + + uint32_t value = s->regs[addr]; + if (addr == R_RTC_ISR) { + value |= R_RTC_ISR_RSF; + } + + // HACK for Pebble. Clear the "entered standby" bit. If this bit is set, the Pebble + // will only continue booting if one of the buttons is held down. Because the button GPIOs + // are setup AFTER QEMU gets the key press event, it is difficult to set the GPIOs according + // to the buttons held down before the reset. + if (addr == R_RTC_BKPxR) { + value &= ~0x10000; + } + + // If reading the sub-second register, determine what it should be from the current + // host time + if (addr == R_RTC_SSR) { + // How many ns are in in a full cycle of the subsecond counter? + uint32_t prer = s->regs[R_RTC_PRER];; + uint32_t prer_s = (prer >> R_RTC_PRER_PREDIV_S_SHIFT) & R_RTC_PRER_PREDIV_S_MASK; + + uint64_t full_cycle_us = f2xx_clock_period_ns(s) / 1000; + + // What fraction of a full cycle are we in? + struct timeval tv; + gettimeofday(&tv, NULL); + int64_t host_time_us = tv.tv_sec * 1000000LL + (tv.tv_usec); + host_time_us += s->host_to_target_offset_us; + + int64_t host_mod = host_time_us % full_cycle_us; + double fract = (double)host_mod / full_cycle_us; + + // Compute the prescaler value + value = prer_s - (fract * prer_s); + DPRINTF("%s: SSR value = %d\n", __func__, value); + } + + r = (value >> offset * 8) & ((1ull << (8 * size)) - 1); + +#ifdef DEBUG_STM32F2XX_RTC + // Debug printing + if (addr == R_RTC_TR || addr == R_RTC_DR) { + struct tm target_tm; + f2xx_rtc_get_current_target_time(s, &target_tm); + + char date_time_str[256]; + strftime(date_time_str, sizeof(date_time_str), "%x %X", &target_tm); + DPRINTF("%s: current date/time: %s\n", __func__, date_time_str); + } else { + DPRINTF("%s: addr: 0x%llx, size: %d, value: 0x%x\n", __func__, addr << 2, size, r); + } +#endif + + return r; +} + +static void +f2xx_rtc_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + f2xx_rtc *s = arg; + int offset = addr & 0x3; + bool compute_new_target_offset = false; + bool update_wut = false; + + DPRINTF("%s: addr: 0x%llx, data: 0x%llx, size: %d\n", __func__, addr, data, size); + + addr >>= 2; + if (addr >= R_RTC_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid write f2xx rtc register 0x%x\n", + (unsigned int)addr << 2); + return; + } + + /* Special case for write protect state machine. */ + if (addr == R_RTC_WPR) { + if (offset > 0) { + return; + } + data &= 0xff; + if ((s->wp_count == 0 && data == 0xca) || + (s->wp_count == 1 && data == 0x53)) { + s->wp_count++; + } else { + s->wp_count = 0; + } + s->regs[addr] = data; + return; + } + + switch(size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + if (addr >= R_RTC_BKPxR && addr <= R_RTC_BKPxR_INC_EXTRA_LAST) { + s->regs[addr] = data; + return; + } + /* Write protect */ + if (s->wp_count < 2 && addr != R_RTC_TAFCR && addr != R_RTC_ISR + && addr != R_RTC_WPR) { + qemu_log_mask(LOG_GUEST_ERROR, "f2xx rtc write reg 0x%x+%u without wp disable\n", + (unsigned int)addr << 2, offset); + return; + } + switch(addr) { + case R_RTC_TR: + case R_RTC_DR: + compute_new_target_offset = true; + break; + case R_RTC_CR: + if ((data & R_RTC_CR_WUTE) != (s->regs[R_RTC_CR] & R_RTC_CR_WUTE)) { + update_wut = true; + } + break; + case R_RTC_ISR: + if ((data & 1<<8) == 0 && (s->regs[R_RTC_ISR] & 1<<8) != 0) { + DPRINTF("f2xx rtc isr lowered\n"); + qemu_irq_lower(s->irq[0]); + } + if ((data & 1<<10) == 0 && (s->regs[R_RTC_ISR] & 1<<10) != 0) { + DPRINTF("f2xx rtc WUT isr lowered\n"); + qemu_irq_lower(s->wut_irq); + } + break; + case R_RTC_PRER: + /* + * XXX currently updates upon next clock tick. To do this properly we + * would need to account for the time already elapsed, and then update + * the timer for the remaining period. + */ + break; + case R_RTC_WUTR: + update_wut = true; + break; + case R_RTC_ALRMAR: + case R_RTC_ALRMBR: + break; + case R_RTC_TAFCR: + if (data) { + qemu_log_mask(LOG_UNIMP, + "f2xx rtc unimplemented write TAFCR+%u size %u val %u\n", + offset, size, (unsigned int)data); + } + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx rtc unimplemented write 0x%x+%u size %u val 0x%x\n", + (unsigned int)addr << 2, offset, size, (unsigned int)data); + } + s->regs[addr] = data; + + + // Do we need to recompute the host to target offset? + if (compute_new_target_offset) { + struct tm target_tm; + // Recompute ticks based on the modified contents of the TR and DR registers + s->ticks = f2xx_rtc_get_current_target_time(s, &target_tm); + // Update the host to target offset as well + s->host_to_target_offset_us = f2xx_rtc_compute_host_to_target_offset(s, + f2xx_clock_period_ns(s), s->ticks); + } + + // Do we need to update the timer for the wake-up-timer? + if (update_wut) { + if (s->regs[R_RTC_CR] & R_RTC_CR_WUTE) { + int64_t elapsed = f2xx_wut_period_ns(s, s->regs[R_RTC_WUTR]); + DPRINTF("%s: scheduling WUT to fire in %f ms\n", __func__, (float)elapsed/1000000.0); + timer_mod(s->wu_timer, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + elapsed); + } else { + DPRINTF("%s: Cancelling WUT\n", __func__); + qemu_set_irq(s->wut_irq, 0); + timer_del(s->wu_timer); + } + } +} + + +static bool +f2xx_alarm_match(f2xx_rtc *s, uint32_t alarm_reg) +{ + uint32_t tr = s->regs[R_RTC_TR]; + + if ((alarm_reg & (1<<7)) == 0 && (tr & 0x7f) != (alarm_reg & 0x7f)) { + /* Seconds match requested, but do not match. */ + return false; + } + if ((alarm_reg & (1<<15)) == 0 && (tr & 0x7f00) != (alarm_reg & 0x7f00)) { + /* Minutes match requested, but do not match. */ + return false; + } + if ((alarm_reg & (1<<23)) == 0 && (tr & 0x7f0000) != (alarm_reg & 0x7f0000)) { + /* Hours match requested, but do not match. */ + return false; + } + if ((alarm_reg & (1<<31)) == 0) { /* Day match. */ + uint32_t dr = s->regs[R_RTC_DR]; + if (alarm_reg & (1<<30)) { /* Day is week day. */ + if (((alarm_reg>>24) & 0xf) != ((dr>>13) & 0xf)) { + return false; + } + } else { /* Day is day of month. */ + if (((alarm_reg>>24) & 0x3f) != (dr & 0x3f)) { + return false; + } + } + } + return true; +} + +static void +f2xx_alarm_check(f2xx_rtc *s, int unit) +{ + uint32_t cr = s->regs[R_RTC_CR]; + uint32_t isr = s->regs[R_RTC_ISR]; + + if ((cr & 1<<(R_RTC_CR_ALRAE_BIT + unit)) == 0) { + return; /* Not enabled. */ + } + + if ((isr & 1<<(R_RTC_CR_ALRAE_BIT + unit)) == 0) { + if (f2xx_alarm_match(s, s->regs[R_RTC_ALRMAR + unit])) { + isr |= 1<<(8 + unit); + s->regs[R_RTC_ISR] = isr; + DPRINTF("f2xx rtc alarm activated 0x%x 0x%x\n", isr, cr); + } + } + qemu_set_irq(s->irq[unit], cr & 1<<(12 + unit) && isr & 1<<(8 + unit)); +} + +// This method updates the current time and date registers to match the current +// host time. While it advances the target time, it checks for alarms that need to fire. +static void +f2xx_update_current_date_and_time(void *arg) +{ + f2xx_rtc *s = arg; + uint64_t period_ns = f2xx_clock_period_ns(s); + + struct tm new_target_tm; + time_t new_target_ticks = f2xx_rtc_compute_target_time_from_host_time(s, + period_ns, &new_target_tm); + + + // Normally, we would advance the target ticks until we catch up to the host ticks and + // check for an alarm at each tick. But, if the clocks got too far off (host or target + // changed time), just jam in the new target time without checking alarms + int delta = new_target_ticks - s->ticks; + //DPRINTF("%s: advancing target by %d ticks\n", __func__, delta); + if (delta < 0 || delta > 1000) { + printf("DEBUG_STM32F2XX_RTC %s: detected %d mismatch between host and target ticks, " + "jamming new host time into RTC without checking for alarms\n", __func__, delta); + s->ticks = new_target_ticks; + f2xx_rtc_set_time_and_date_registers(s, &new_target_tm); + } else { + while (s->ticks != new_target_ticks) { + s->ticks += 1; + gmtime_r(&s->ticks, &new_target_tm); + f2xx_rtc_set_time_and_date_registers(s, &new_target_tm); + + f2xx_alarm_check(s, 0); + f2xx_alarm_check(s, 1); + } + } + + // Reschedule tick timer to run one tick from now to check for alarms again + timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + period_ns); +} + + +// This timer runs on every tick (usually second) +static void +f2xx_timer(void *arg) +{ + f2xx_rtc *s = arg; + f2xx_update_current_date_and_time(s); +} + + +// This timer fires when the wake up time has expired +static void +f2xx_wu_timer(void *arg) +{ + f2xx_rtc *s = arg; + + DPRINTF("%s: fired\n", __func__); + + // Fire the interrupt? + uint32_t cr = s->regs[R_RTC_CR]; + uint32_t isr = s->regs[R_RTC_ISR]; + + // Make sure WUT is enabled + if ( (cr & R_RTC_CR_WUTE) == 0 ) { + return; /* Not enabled */ + } + + // If interrupt not already asserted, assert it + if ( (isr & R_RTC_ISR_WUT) == 0 ) { + isr |= R_RTC_ISR_WUT; + s->regs[R_RTC_ISR] = isr; + DPRINTF("f2xx wakeup timer ISR activated 0x%x 0x%x\n", isr, cr); + } + + qemu_set_irq(s->wut_irq, (cr & R_RTC_CR_WUTIE) && (isr & R_RTC_ISR_WUT)); + + // Reschedule again + int64_t elapsed = f2xx_wut_period_ns(s, s->regs[R_RTC_WUTR]); + timer_mod(s->wu_timer, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + elapsed); +} + + +// External interface to set the value of an "extra" backup register. This can be used to +// communicate emulator specific settings to the target +void f2xx_rtc_set_extra_bkup_reg(void *opaque, uint32_t idx, uint32_t value) +{ + f2xx_rtc *s = (f2xx_rtc *)opaque; + + // Copy in the extra backup registers that were specified via properties + assert(idx < STM32F2XX_RTC_NUM_EXTRA_BKUP_REG); + s->regs[R_RTC_BKPxR_LAST + 1 + idx] = value; +} + + + +static const MemoryRegionOps f2xx_rtc_ops = { + .read = f2xx_rtc_read, + .write = f2xx_rtc_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + +static void f2xx_rtc_reset(DeviceState *dev) +{ + f2xx_rtc *s = FROM_SYSBUS(f2xx_rtc, SYS_BUS_DEVICE(dev)); + s->regs[R_RTC_CR] = 0; +} + +static int +f2xx_rtc_init(SysBusDevice *dev) +{ + f2xx_rtc *s = FROM_SYSBUS(f2xx_rtc, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_rtc_ops, s, "rtc", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + sysbus_init_irq(dev, &s->irq[0]); + sysbus_init_irq(dev, &s->irq[1]); + sysbus_init_irq(dev, &s->wut_irq); + + s->regs[R_RTC_ISR] = R_RTC_ISR_RESET; + s->regs[R_RTC_PRER] = R_RTC_PRER_RESET; + s->regs[R_RTC_WUTR] = R_RTC_WUTR_RESET; + + uint32_t period_ns = f2xx_clock_period_ns(s); + DPRINTF("%s: period: %d ns\n", __func__, period_ns); + + // Init the time and date registers from the time on the host as the default + s->host_to_target_offset_us = 0; + struct tm now; + qemu_get_timedate(&now, 0); + + // Set time and date registers from the now struct + f2xx_rtc_set_time_and_date_registers(s, &now); + + // Compute current ticks and host to target offset + s->ticks = mktimegm(&now); + s->host_to_target_offset_us = f2xx_rtc_compute_host_to_target_offset(s, + f2xx_clock_period_ns(s), s->ticks); + + s->timer = timer_new_ns(QEMU_CLOCK_HOST, f2xx_timer, s); + timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + period_ns); + + s->wu_timer = timer_new_ns(QEMU_CLOCK_REALTIME, f2xx_wu_timer, s); + return 0; +} + +static Property f2xx_rtc_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static void +f2xx_rtc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f2xx_rtc_init; + //TODO: fix this: dc->no_user = 1; + dc->props = f2xx_rtc_properties; + dc->reset = f2xx_rtc_reset; +} + +static const TypeInfo +f2xx_rtc_info = { + .name = "f2xx_rtc", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f2xx_rtc), + .class_init = f2xx_rtc_class_init, +}; + +static void +f2xx_rtc_register_types(void) +{ + type_register_static(&f2xx_rtc_info); +} + +type_init(f2xx_rtc_register_types) diff --git a/hw/arm/stm32f2xx_syscfg.c b/hw/arm/stm32f2xx_syscfg.c new file mode 100644 index 0000000000000..3e4dbc6dd5a66 --- /dev/null +++ b/hw/arm/stm32f2xx_syscfg.c @@ -0,0 +1,276 @@ +/* + * STM32F2XX Microcontroller SYSCFG (System Configuration Controller) module + * + * Copyright (C) 2013 Martijn The + * + * Implementation based on ST Microelectronics "RM0033 Reference Manual Rev 4" + * + * 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 . + */ + +#include "stm32f2xx.h" + + + +/* DEFINITIONS */ + +#define SYSCFG_MEMRMP_OFFSET 0x00 +#define SYSCFG_MEMRMP_MEM_MODE_MASK 0x3 + +#define SYSCFG_PMC_OFFSET 0x04 + +#define SYSCFG_EXTICR1_OFFSET 0x08 +#define SYSCFG_EXTICR2_OFFSET 0x0c +#define SYSCFG_EXTICR3_OFFSET 0x10 +#define SYSCFG_EXTICR4_OFFSET 0x14 + +#define SYSCFG_EXTICR_COUNT 4 +#define SYSCFG_EXTI_PER_CR 4 + +#define SYSCFG_CMPCR_OFFSET 0x20 + +typedef struct { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + void *stm32_rcc_prop; + void *stm32_exti_prop; + uint32_t boot_pins; //!< BOOT0 and BOOT1 pins + + /* Private */ + MemoryRegion iomem; + + Stm32Rcc *stm32_rcc; + Stm32Exti *stm32_exti; + + uint32_t + USART1_REMAP, + USART2_REMAP, + USART3_REMAP, + SYSCFG_MEMRMP, + SYSCFG_EXTICR[SYSCFG_EXTICR_COUNT]; +} Stm32Syscfg; + + +/* REGISTER IMPLEMENTATION */ + +static uint32_t stm32_syscfg_SYSCFG_MEMRMP_read(Stm32Syscfg *s) +{ + return s->SYSCFG_MEMRMP; +} + +static void stm32_syscfg_SYSCFG_MEMRMP_write(Stm32Syscfg *s, uint32_t new_value, + bool init) +{ + if (init) { + // "After reset these bits take the value selected by the BOOT pins." + s->SYSCFG_MEMRMP = (SYSCFG_MEMRMP_MEM_MODE_MASK & s->boot_pins); + } else { + s->SYSCFG_MEMRMP = new_value; + } +} + +/* Write the External Interrupt Configuration Register. + * There are four of these registers, each of which configures + * four EXTI interrupt lines. Each line is represented by four bits, which + * indicate which GPIO the line is connected to. When the register is + * written, the changes are propagated to the EXTI module. + */ +static void stm32_syscfg_SYSCFG_EXTICR_write(Stm32Syscfg *s, unsigned index, + uint32_t new_value, bool init) +{ + int i; + unsigned exti_line; + unsigned start; + unsigned old_gpio_index, new_gpio_index; + + assert(index < SYSCFG_EXTICR_COUNT); + + /* Loop through the four EXTI lines controlled by this register. */ + for(i = 0; i < SYSCFG_EXTI_PER_CR; i++) { + /* For each line, notify the EXTI module if it has changed. */ + exti_line = (index * SYSCFG_EXTI_PER_CR) + i; + start = i * 4; + + new_gpio_index = (new_value >> start) & 0xf; + if(!init) { + old_gpio_index = (s->SYSCFG_EXTICR[index] >> start) & 0xf; + if (old_gpio_index == new_gpio_index) { + continue; + } + stm32_exti_reset_gpio(s->stm32_exti, exti_line, old_gpio_index); + } + stm32_exti_set_gpio(s->stm32_exti, exti_line, new_gpio_index); + } + + s->SYSCFG_EXTICR[index] = new_value; +} + + +static uint64_t stm32_syscfg_readw(Stm32Syscfg *s, hwaddr offset) +{ + switch (offset) { + case SYSCFG_MEMRMP_OFFSET: + return stm32_syscfg_SYSCFG_MEMRMP_read(s); + case SYSCFG_PMC_OFFSET: + STM32_NOT_IMPL_REG(SYSCFG_PMC_OFFSET, WORD_ACCESS_SIZE); + return 0; + case SYSCFG_EXTICR1_OFFSET: + return s->SYSCFG_EXTICR[0]; + case SYSCFG_EXTICR2_OFFSET: + return s->SYSCFG_EXTICR[1]; + case SYSCFG_EXTICR3_OFFSET: + return s->SYSCFG_EXTICR[2]; + case SYSCFG_EXTICR4_OFFSET: + return s->SYSCFG_EXTICR[3]; + case SYSCFG_CMPCR_OFFSET: + STM32_NOT_IMPL_REG(SYSCFG_CMPCR_OFFSET, WORD_ACCESS_SIZE); + return 0; + default: + STM32_BAD_REG(offset, WORD_ACCESS_SIZE); + return 0; + } +} + +static void stm32_syscfg_writew(Stm32Syscfg *s, hwaddr offset, + uint64_t value) +{ + switch (offset) { + case SYSCFG_MEMRMP_OFFSET: + stm32_syscfg_SYSCFG_MEMRMP_write(s, value, false); + break; + case SYSCFG_PMC_OFFSET: + STM32_NOT_IMPL_REG(SYSCFG_PMC_OFFSET, WORD_ACCESS_SIZE); + break; + case SYSCFG_EXTICR1_OFFSET: + stm32_syscfg_SYSCFG_EXTICR_write(s, 0, value, false); + break; + case SYSCFG_EXTICR2_OFFSET: + stm32_syscfg_SYSCFG_EXTICR_write(s, 1, value, false); + break; + case SYSCFG_EXTICR3_OFFSET: + stm32_syscfg_SYSCFG_EXTICR_write(s, 2, value, false); + break; + case SYSCFG_EXTICR4_OFFSET: + stm32_syscfg_SYSCFG_EXTICR_write(s, 3, value, false); + break; + case SYSCFG_CMPCR_OFFSET: + STM32_NOT_IMPL_REG(SYSCFG_CMPCR_OFFSET, WORD_ACCESS_SIZE); + break; + default: + STM32_BAD_REG(offset, WORD_ACCESS_SIZE); + break; + } +} + +static uint64_t stm32_syscfg_read(void *opaque, hwaddr offset, + unsigned size) +{ + Stm32Syscfg *s = (Stm32Syscfg *)opaque; + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, STM32_SYSCFG); + + switch(size) { + case 4: + return stm32_syscfg_readw(opaque, offset); + default: + STM32_BAD_REG(offset, size); + return 0; + } +} + +static void stm32_syscfg_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + Stm32Syscfg *s = (Stm32Syscfg *)opaque; + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, STM32_SYSCFG); + + switch(size) { + case 4: + stm32_syscfg_writew(opaque, offset, value); + break; + default: + STM32_BAD_REG(offset, size); + break; + } +} + +static const MemoryRegionOps stm32_syscfg_ops = { + .read = stm32_syscfg_read, + .write = stm32_syscfg_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void stm32_syscfg_reset(DeviceState *dev) +{ + Stm32Syscfg *s = FROM_SYSBUS(Stm32Syscfg, SYS_BUS_DEVICE(dev)); + + stm32_syscfg_SYSCFG_MEMRMP_write(s, 0x00000000, true); + stm32_syscfg_SYSCFG_EXTICR_write(s, 0, 0x00000000, true); + stm32_syscfg_SYSCFG_EXTICR_write(s, 1, 0x00000000, true); + stm32_syscfg_SYSCFG_EXTICR_write(s, 2, 0x00000000, true); + stm32_syscfg_SYSCFG_EXTICR_write(s, 3, 0x00000000, true); +} + + + +/* DEVICE INITIALIZATION */ + +static int stm32_syscfg_init(SysBusDevice *dev) +{ + Stm32Syscfg *s = FROM_SYSBUS(Stm32Syscfg, dev); + + s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; + s->stm32_exti = (Stm32Exti *)s->stm32_exti_prop; + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_syscfg_ops, s, + "syscfg", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + return 0; +} + +static Property stm32_syscfg_properties[] = { + DEFINE_PROP_PTR("stm32_rcc", Stm32Syscfg, stm32_rcc_prop), + DEFINE_PROP_PTR("stm32_exti", Stm32Syscfg, stm32_exti_prop), + DEFINE_PROP_BIT("boot0", Stm32Syscfg, boot_pins, 0, 0), // BOOT0 pin + DEFINE_PROP_BIT("boot1", Stm32Syscfg, boot_pins, 1, 0), // BOOT1 pin + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32_syscfg_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_syscfg_init; + dc->reset = stm32_syscfg_reset; + dc->props = stm32_syscfg_properties; +} + +static TypeInfo stm32_syscfg_info = { + .name = "stm32f2xx_syscfg", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Syscfg), + .class_init = stm32_syscfg_class_init +}; + +static void stm32_syscfg_register_types(void) +{ + type_register_static(&stm32_syscfg_info); +} + +type_init(stm32_syscfg_register_types) diff --git a/hw/arm/stm32f2xx_tim.c b/hw/arm/stm32f2xx_tim.c new file mode 100644 index 0000000000000..b974a3f349154 --- /dev/null +++ b/hw/arm/stm32f2xx_tim.c @@ -0,0 +1,331 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU stm32f2xx TIM emulation + */ +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "qemu/timer.h" + +//#define DEBUG_STM32F2XX_TIM +#ifdef DEBUG_STM32F2XX_TIM +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("DEBUG_STM32F2XX_TIM: " fmt , ## __VA_ARGS__); \ + usleep(100); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + + +#define R_TIM_CR1 (0x00 / 4) //p +#define R_TIM_CR2 (0x04 / 4) +#define R_TIM_SMCR (0x08 / 4) +#define R_TIM_DIER (0x0c / 4) //p +#define R_TIM_SR (0x10 / 4) //p +#define R_TIM_EGR (0x14 / 4) //p +#define R_TIM_CCMR1 (0x18 / 4) +#define R_TIM_CCMR2 (0x1c / 4) +#define R_TIM_CCER (0x20 / 4) +#define R_TIM_CNT (0x24 / 4) +#define R_TIM_PSC (0x28 / 4) //p +#define R_TIM_ARR (0x2c / 4) //p +#define R_TIM_CCR1 (0x34 / 4) +#define R_TIM_CCR2 (0x38 / 4) +#define R_TIM_CCR3 (0x3c / 4) +#define R_TIM_CCR4 (0x40 / 4) +#define R_TIM_DCR (0x48 / 4) +#define R_TIM_DMAR (0x4c / 4) +#define R_TIM_OR (0x50 / 4) +#define R_TIM_MAX (0x54 / 4) + +static const char *f2xx_tim_reg_names[] = { + ENUM_STRING(R_TIM_CR1), + ENUM_STRING(R_TIM_CR2), + ENUM_STRING(R_TIM_SMCR), + ENUM_STRING(R_TIM_DIER), + ENUM_STRING(R_TIM_SR), + ENUM_STRING(R_TIM_EGR), + ENUM_STRING(R_TIM_CCMR1), + ENUM_STRING(R_TIM_CCMR2), + ENUM_STRING(R_TIM_CCER), + ENUM_STRING(R_TIM_CNT), + ENUM_STRING(R_TIM_PSC), + ENUM_STRING(R_TIM_ARR), + ENUM_STRING(R_TIM_CCR1), + ENUM_STRING(R_TIM_CCR2), + ENUM_STRING(R_TIM_CCR3), + ENUM_STRING(R_TIM_CCR4), + ENUM_STRING(R_TIM_DCR), + ENUM_STRING(R_TIM_CCMR1), + ENUM_STRING(R_TIM_DMAR), + ENUM_STRING(R_TIM_OR) +}; + + +typedef struct f2xx_tim { + SysBusDevice busdev; + MemoryRegion iomem; + QEMUTimer *timer; + qemu_irq irq; + uint32_t regs[R_TIM_MAX]; + + qemu_irq pwm_ratio_changed; + qemu_irq pwm_enable; +} f2xx_tim; + +static uint32_t +f2xx_tim_period(f2xx_tim *s) +{ + /* FIXME: hard coded to 32kHz */ + return 31250; +} + +static int64_t +f2xx_tim_next_transition(f2xx_tim *s, int64_t current_time) +{ + if (s->regs[R_TIM_CR1] & 0x70) { + qemu_log_mask(LOG_UNIMP, "f2xx tim, only upedge-aligned mode supported\n"); + return -1; + } + return current_time + f2xx_tim_period(s) * s->regs[R_TIM_ARR]; +} + +static void +f2xx_tim_timer(void *arg) +{ + f2xx_tim *s = arg; + + if (s->regs[R_TIM_CR1] & 1) { + timer_mod(s->timer, f2xx_tim_next_transition(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))); + } + if (!(s->regs[R_TIM_SR] & 1)) { + //printf("f2xx tim timer expired, setting int\n"); + s->regs[R_TIM_SR] |= 1; + } + qemu_set_irq(s->irq, 1); +} + +static uint64_t +f2xx_tim_read(void *arg, hwaddr addr, unsigned int size) +{ + f2xx_tim *s = arg; + uint32_t r; + int offset = addr & 0x3; + + addr >>= 2; + if (addr >= R_TIM_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "f2xx tim invalid read register 0x%x\n", + (unsigned int)addr << 2); + return 0; + } + r = (s->regs[addr] >> offset * 8) & ((1ull << (8 * size)) - 1); + switch (addr) { + case R_TIM_CR1: + case R_TIM_DIER: + case R_TIM_SR: + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx tim unimplemented read 0x%x+%u size %u val 0x%x\n", + (unsigned int)addr << 2, offset, size, (unsigned int)r); + } + + DPRINTF("%s %s: reg: %s, size: %d, value: 0x%x\n", s->busdev.parent_obj.id, + __func__, f2xx_tim_reg_names[addr], size, r); + return r; +} + +static void +f2xx_tim_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) +{ + f2xx_tim *s = arg; + int offset = addr & 0x3; + + addr >>= 2; + + DPRINTF("%s %s: reg:%s, size: %d, value: 0x%llx\n", s->busdev.parent_obj.id, + __func__, f2xx_tim_reg_names[addr], size, data); + if (addr >= R_TIM_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "f2xx tim invalid write register 0x%x\n", + (unsigned int)addr << 2); + return; + } + + switch(size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + + switch(addr) { + case R_TIM_CR1: + if (data & ~1) { + qemu_log_mask(LOG_UNIMP, "f2xx tim non-zero CR1 unimplemented\n"); + } + if ((s->regs[addr] & 1) == 0 && data & 1) { + //printf("f2xx tim started\n"); + timer_mod(s->timer, f2xx_tim_next_transition(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))); + qemu_set_irq(s->pwm_enable, 1); + } else if (s->regs[addr] & 1 && (data & 1) == 0) { + timer_del(s->timer); + qemu_set_irq(s->pwm_enable, 0); + } + s->regs[addr] = data; + break; + case R_TIM_SR: + if (s->regs[addr] & 1 && (data & 1) == 0) { + //printf("f2xx tim clearing int\n"); + qemu_set_irq(s->irq, 0); + } + s->regs[addr] &= data; + break; + case R_TIM_EGR: + qemu_log_mask(LOG_UNIMP, "f2xx tim unimplemented write EGR+%u size %u val 0x%x\n", + offset, size, (unsigned int)data); + break; + case R_TIM_CCER: + // Capture/Compare Enable register + s->regs[addr] = data; + + // If we are enabling PWM mode in output 1, notify the callback if we have one registered + if ( (data & 0x01) // Capture Compare 1 output enable + && ((s->regs[R_TIM_CCMR1] & 0x60) == 0x60) + && ((s->regs[R_TIM_CCMR1] & 0x03) == 0x00)) { + + uint32_t ratio = (s->regs[R_TIM_CCR1] * 255) / s->regs[R_TIM_ARR]; + DPRINTF("Setting PWM ratio to %d\n", ratio); + qemu_set_irq(s->pwm_ratio_changed, ratio); + } + + // If we are enabling PWM mode in output 1, notify the callback if we have one registered + else if ( (data & 0x10) // Capture Compare 2 output enable + && ((s->regs[R_TIM_CCMR1] & 0x6000) == 0x6000) + && ((s->regs[R_TIM_CCMR1] & 0x0300) == 0x0000)) { + + uint32_t ratio = (s->regs[R_TIM_CCR2] * 255) / s->regs[R_TIM_ARR]; + DPRINTF("Setting PWM ratio to %d\n", ratio); + qemu_set_irq(s->pwm_ratio_changed, ratio); + + } else { + qemu_set_irq(s->pwm_ratio_changed, 0); + } + + break; + case R_TIM_CCMR1: + // Capture/Compare mode register 1 + s->regs[addr] = data; + break; + case R_TIM_CCMR2: + // Capture/Compare mode register 2 + s->regs[addr] = data; + break; + case R_TIM_DIER: + case R_TIM_PSC: + case R_TIM_ARR: + case R_TIM_CCR1: + case R_TIM_CCR2: + s->regs[addr] = data; + break; + default: + qemu_log_mask(LOG_UNIMP, "f2xx tim unimplemented write 0x%x+%u size %u val 0x%x\n", + (unsigned int)addr << 2, offset, size, (unsigned int)data); + } + +} + +static const MemoryRegionOps f2xx_tim_ops = { + .read = f2xx_tim_read, + .write = f2xx_tim_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + +static void f2xx_tim_reset(DeviceState *dev) +{ + f2xx_tim *s = FROM_SYSBUS(f2xx_tim, SYS_BUS_DEVICE(dev)); + + timer_del(s->timer); + memset(&s->regs, 0, sizeof(s->regs)); +} + + +static int +f2xx_tim_init(SysBusDevice *dev) +{ + f2xx_tim *s = FROM_SYSBUS(f2xx_tim, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_tim_ops, s, "tim", 0xa0); + sysbus_init_mmio(dev, &s->iomem); + //s->regs[R_RTC_ISR] = R_RTC_ISR_RESET; + ////s->regs[R_RTC_PRER] = R_RTC_PRER_RESET; + //s->regs[R_RTC_WUTR] = R_RTC_WUTR_RESET; + s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, f2xx_tim_timer, s); + sysbus_init_irq(dev, &s->irq); + + qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_ratio_changed, "pwm_ratio_changed", 1); + qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_enable, "pwm_enable", 1); + + return 0; +} + +static Property f2xx_tim_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static void +f2xx_tim_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f2xx_tim_init; + //TODO: fix this: dc->no_user = 1; + dc->props = f2xx_tim_properties; + dc->reset = f2xx_tim_reset; +} + +static const TypeInfo +f2xx_tim_info = { + .name = "f2xx_tim", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f2xx_tim), + .class_init = f2xx_tim_class_init, +}; + +static void +f2xx_tim_register_types(void) +{ + type_register_static(&f2xx_tim_info); +} + +type_init(f2xx_tim_register_types) diff --git a/hw/arm/stm32f4xx.c b/hw/arm/stm32f4xx.c new file mode 100644 index 0000000000000..711cc7c88188d --- /dev/null +++ b/hw/arm/stm32f4xx.c @@ -0,0 +1,425 @@ +/* + * STM32F4xx Microcontroller + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0090 Reference Manual Rev 8" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "stm32f4xx.h" +#include "exec/address-spaces.h" +#include "exec/memory.h" +#include "hw/ssi.h" +#include "hw/block/flash.h" +#include "sysemu/blockdev.h" // drive_get + +static const char *stm32f4xx_periph_name_arr[] = { + ENUM_STRING(STM32_UART1), + ENUM_STRING(STM32_UART2), + ENUM_STRING(STM32_UART3), + ENUM_STRING(STM32_UART4), + ENUM_STRING(STM32_UART5), + ENUM_STRING(STM32_UART6), + ENUM_STRING(STM32_UART7), + ENUM_STRING(STM32_UART8), + + ENUM_STRING(STM32_SPI1), + ENUM_STRING(STM32_SPI2), + ENUM_STRING(STM32_SPI3), + + ENUM_STRING(STM32_I2C1), + ENUM_STRING(STM32_I2C2), + ENUM_STRING(STM32_I2C3), + + ENUM_STRING(STM32_TIM1), + ENUM_STRING(STM32_TIM2), + ENUM_STRING(STM32_TIM3), + ENUM_STRING(STM32_TIM4), + ENUM_STRING(STM32_TIM5), + ENUM_STRING(STM32_TIM6), + ENUM_STRING(STM32_TIM7), + ENUM_STRING(STM32_TIM8), + ENUM_STRING(STM32_TIM9), + ENUM_STRING(STM32_TIM10), + ENUM_STRING(STM32_TIM11), + ENUM_STRING(STM32_TIM12), + ENUM_STRING(STM32_TIM13), + ENUM_STRING(STM32_TIM14), + + ENUM_STRING(STM32_GPIOA), + ENUM_STRING(STM32_GPIOB), + ENUM_STRING(STM32_GPIOC), + ENUM_STRING(STM32_GPIOD), + ENUM_STRING(STM32_GPIOE), + ENUM_STRING(STM32_GPIOF), + ENUM_STRING(STM32_GPIOG), + ENUM_STRING(STM32_GPIOH), + ENUM_STRING(STM32_GPIOI), + ENUM_STRING(STM32_GPIOJ), + ENUM_STRING(STM32_GPIOK), + + ENUM_STRING(STM32_QSPI), + + ENUM_STRING(STM32_PERIPH_COUNT) +}; + +/* Init STM32F4XX CPU and memory. + flash_size and sram_size are in kb. */ + +static uint64_t kernel_load_translate_fn(void *opaque, uint64_t from_addr) { + if (from_addr == STM32_FLASH_ADDR_START) { + return 0x00000000; + } + return from_addr; +} + +static +void do_sys_reset(void *opaque, int n, int level) +{ + if (level) { + qemu_system_reset_request(); + } +} + +void stm32f4xx_init( + ram_addr_t flash_size, /* in KBytes */ + ram_addr_t ram_size, /* in KBytes */ + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + const uint32_t *gpio_idr_masks, + Stm32Uart **stm32_uart, + Stm32Timer **stm32_timer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f4xx *stm, + ARMCPU **cpu) +{ + MemoryRegion *address_space_mem = get_system_memory(); + DriveInfo *dinfo; + DeviceState *nvic; + int i; + + Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); + + nvic = armv7m_translated_init( + stm32_container, /* parent */ + address_space_mem, /* address space memory */ + flash_size * 1024, /* flash size in bytes */ + ram_size * 1024, /* sram size in bytes */ + 0, /* default number of irqs */ + kernel_filename, /* kernel filename */ + kernel_load_translate_fn, /* kernel translate address function */ + NULL, /* translate function opaque argument */ + "cortex-m4", /* cpu model */ + cpu); /* Returned cpu instance */ + + qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, + qemu_allocate_irq(&do_sys_reset, NULL, 0)); + + dinfo = drive_get(IF_PFLASH, 0, 0); /* Use the first -pflash argument */ + if (dinfo) { + f2xx_flash_register(blk_by_legacy_dinfo(dinfo), STM32_FLASH_ADDR_START, flash_size * 1024); + } + + + // Create alias at 0x08000000 for internal flash, that is hard-coded at 0x00000000 + // in armv7m.c: + // TODO: Let BOOT0 and BOOT1 configuration pins determine what is mapped at 0x00000000, + // see SYSCFG_MEMRMP. + MemoryRegionSection mrs = memory_region_find(address_space_mem, STM32_FLASH_ADDR_START, + WORD_ACCESS_SIZE); + MemoryRegion *flash_alias = g_new(MemoryRegion, 1); + memory_region_init_alias( + flash_alias, /* alias memory region */ + NULL, /* owner */ + "stm32f4xx.flash.alias", /* name */ + mrs.mr, /* original region */ + 0, /* offset */ + flash_size * 1024); /* size in bytes */ + memory_region_add_subregion(address_space_mem, 0, flash_alias); + + + /* Setup the RCC */ + DeviceState *rcc_dev = qdev_create(NULL, "stm32f2xx_rcc"); + qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); + qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); + object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); + stm32_init_periph(rcc_dev, + STM32_RCC_PERIPH, /* periph index, not used */ + 0x40023800, /* base address */ + qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); /* irq */ + + /* Setup GPIOs */ + DeviceState **gpio_dev = (DeviceState **)g_malloc0(sizeof(DeviceState *) + * STM32F4XX_GPIO_COUNT); + for(i = 0; i < STM32F4XX_GPIO_COUNT; i++) { + stm32_periph_t periph = STM32_GPIOA + i; + gpio_dev[i] = qdev_create(NULL, "stm32f2xx_gpio"); + gpio_dev[i]->id = stm32f4xx_periph_name_arr[periph]; + qdev_prop_set_int32(gpio_dev[i], "periph", periph); + qdev_prop_set_uint32(gpio_dev[i], "idr-mask", gpio_idr_masks[i]); + // qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); + stm32_init_periph(gpio_dev[i], periph, 0x40020000 + (i * 0x400), NULL /*irq*/); + stm32_gpio[i] = (Stm32Gpio *)gpio_dev[i]; + } + + /* Connect the WKUP pin (GPIO A, pin 0) to the NVIC's WKUP handler */ + qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); + f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); + + + /* EXTI */ + DeviceState *exti_dev = qdev_create(NULL, "stm32_exti"); + qdev_prop_set_ptr(exti_dev, "stm32_gpio", gpio_dev); + stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40013C00, NULL); + SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); + + /* IRQs from EXTI to NVIC */ + sysbus_connect_irq(exti_busdev, 0, qdev_get_gpio_in(nvic, STM32_EXTI0_IRQ)); + sysbus_connect_irq(exti_busdev, 1, qdev_get_gpio_in(nvic, STM32_EXTI1_IRQ)); + sysbus_connect_irq(exti_busdev, 2, qdev_get_gpio_in(nvic, STM32_EXTI2_IRQ)); + sysbus_connect_irq(exti_busdev, 3, qdev_get_gpio_in(nvic, STM32_EXTI3_IRQ)); + sysbus_connect_irq(exti_busdev, 4, qdev_get_gpio_in(nvic, STM32_EXTI4_IRQ)); + sysbus_connect_irq(exti_busdev, 5, qdev_get_gpio_in(nvic, STM32_EXTI9_5_IRQ)); + sysbus_connect_irq(exti_busdev, 6, qdev_get_gpio_in(nvic, STM32_EXTI15_10_IRQ)); + sysbus_connect_irq(exti_busdev, 7, qdev_get_gpio_in(nvic, STM32_PVD_IRQ)); + sysbus_connect_irq(exti_busdev, 8, qdev_get_gpio_in(nvic, STM32_RTCAlarm_IRQ)); + sysbus_connect_irq(exti_busdev, 9, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 10, qdev_get_gpio_in(nvic, STM32_ETH_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 11, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 12, qdev_get_gpio_in(nvic, STM32_TAMP_STAMP_IRQ)); + sysbus_connect_irq(exti_busdev, 13, qdev_get_gpio_in(nvic, STM32_RTC_WKUP_IRQ)); + + + /* System configuration controller */ + DeviceState *syscfg_dev = qdev_create(NULL, "stm32f2xx_syscfg"); + qdev_prop_set_ptr(syscfg_dev, "stm32_rcc", rcc_dev); + qdev_prop_set_ptr(syscfg_dev, "stm32_exti", exti_dev); + qdev_prop_set_bit(syscfg_dev, "boot0", 0); + qdev_prop_set_bit(syscfg_dev, "boot1", 0); + stm32_init_periph(syscfg_dev, STM32_SYSCFG, 0x40013800, NULL /*irq*/); + + /* UARTS */ + struct { + uint32_t addr; + uint8_t irq_idx; + } const uart_desc[] = { + {0x40011000, STM32_UART1_IRQ}, + {0x40004400, STM32_UART2_IRQ}, + {0x40004800, STM32_UART3_IRQ}, + {0x40004C00, STM32_UART4_IRQ}, + {0x40005000, STM32_UART5_IRQ}, + {0x40011400, STM32_UART6_IRQ}, + {0x40007800, 0}, /* no IRQ for UART 7 */ + {0x40007C00, 0}, /* no IRQ for UART 8 */ + }; + for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { + assert(i < STM32F4XX_UART_COUNT); + const stm32_periph_t periph = STM32_UART1 + i; + DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + uart_dev->id = stm32f4xx_periph_name_arr[periph]; + qdev_prop_set_int32(uart_dev, "periph", periph); + qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); + // qdev_prop_set_ptr(uart_dev, "stm32_gpio", gpio_dev); + // qdev_prop_set_ptr(uart_dev, "stm32_afio", afio_dev); + // qdev_prop_set_ptr(uart_dev, "stm32_check_tx_pin_callback", + // (void *)stm32_afio_uart_check_tx_pin_callback); + qemu_irq irq = NULL; + if (uart_desc[i].irq_idx != 0) { + irq = qdev_get_gpio_in(nvic, uart_desc[i].irq_idx); + } + stm32_init_periph(uart_dev, periph, uart_desc[i].addr, irq); + stm32_uart[i] = (Stm32Uart *)uart_dev; + } + // TODO: Should we use these instead? +// stm32_uart[STM32_UART1_INDEX] = stm32_create_uart_dev(STM32_UART1, rcc_dev, gpio_dev, afio_dev, 0x40011000, pic[STM32_UART1_IRQ]); +// stm32_uart[STM32_UART2_INDEX] = stm32_create_uart_dev(STM32_UART2, rcc_dev, gpio_dev, afio_dev, 0x40004400, pic[STM32_UART2_IRQ]); +// stm32_uart[STM32_UART3_INDEX] = stm32_create_uart_dev(STM32_UART3, rcc_dev, gpio_dev, afio_dev, 0x40004800, pic[STM32_UART3_IRQ]); +// stm32_uart[STM32_UART4_INDEX] = stm32_create_uart_dev(STM32_UART4, rcc_dev, gpio_dev, afio_dev, 0x40004C00, pic[STM32_UART4_IRQ]); +// stm32_uart[STM32_UART5_INDEX] = stm32_create_uart_dev(STM32_UART5, rcc_dev, gpio_dev, afio_dev, 0x40005000, pic[STM32_UART5_IRQ]); +// stm32_uart[STM32_UART6_INDEX] = stm32_create_uart_dev(STM32_UART6, rcc_dev, gpio_dev, afio_dev, 0x40011400, pic[STM32_UART6_IRQ]); + + + /* SPI */ + struct { + uint32_t addr; + uint8_t irq_idx; + } const spi_desc[] = { + {0x40013000, STM32_SPI1_IRQ}, + {0x40003800, STM32_SPI2_IRQ}, + {0x40003CD0, STM32_SPI3_IRQ}, + {0x40013400, STM32_SPI4_IRQ}, + {0x40015000, STM32_SPI5_IRQ}, + {0x40015400, STM32_SPI6_IRQ}, + }; + for (i = 0; i < ARRAY_LENGTH(spi_desc); ++i) { + assert(i < STM32F4XX_SPI_COUNT); + const stm32_periph_t periph = STM32_SPI1 + i; + stm->spi_dev[i] = qdev_create(NULL, "stm32f2xx_spi"); + stm->spi_dev[i]->id = stm32f4xx_periph_name_arr[periph]; + qdev_prop_set_int32(stm->spi_dev[i], "periph", periph); + stm32_init_periph(stm->spi_dev[i], periph, spi_desc[i].addr, + qdev_get_gpio_in(nvic, spi_desc[i].irq_idx)); + } + + /* QSPI */ + stm->qspi_dev = qdev_create(NULL, "stm32f412_qspi"); + stm->qspi_dev->id = stm32f4xx_periph_name_arr[STM32_QSPI]; + stm32_init_periph(stm->qspi_dev, STM32_QSPI, 0xA0001000, qdev_get_gpio_in(nvic, STM32_QSPI_IRQ)); + + /* ADC */ + DeviceState *adc_dev = qdev_create(NULL, "stm32f2xx_adc"); + stm32_init_periph(adc_dev, STM32_ADC1, 0x40012000, NULL); + + /* RTC real time clock */ + DeviceState *rtc_dev = qdev_create(NULL, "f2xx_rtc"); + *stm32_rtc = rtc_dev; + stm32_init_periph(rtc_dev, STM32_RTC, 0x40002800, NULL); + // Alarm A + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 0, qdev_get_gpio_in(exti_dev, 17)); + // Alarm B + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 1, qdev_get_gpio_in(exti_dev, 17)); + // Wake up timer + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 2, qdev_get_gpio_in(exti_dev, 22)); + + /* Power management */ + DeviceState *pwr_dev = qdev_create(NULL, "f2xx_pwr"); + stm32_init_periph(pwr_dev, STM32_RTC, 0x40007000, NULL); + qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); + +#define dummy_dev(name, start, size) do {\ + DeviceState *dummy = qdev_create(NULL, "f2xx_dummy"); \ + qdev_prop_set_ptr(dummy, "name", (void *)name); \ + qdev_prop_set_int32(dummy, "size", size); \ + qdev_init_nofail(dummy); \ + sysbus_mmio_map(SYS_BUS_DEVICE(dummy), 0, start); \ +} while (0) + + + /* Timers */ + struct { + uint8_t timer_num; + uint32_t addr; + uint8_t irq_idx; + } const timer_desc[] = { + {1, 0x40010000, 0}, // TIM1 FIXME: TIM1 is a complex timer w/ multiple IRQs + {2, 0x40000000, STM32_TIM2_IRQ}, // TIM2 + {3, 0x40000400, STM32_TIM3_IRQ}, // TIM3 + {4, 0x40000800, STM32_TIM4_IRQ}, // TIM4 + {5, 0x40000C00, STM32_TIM5_IRQ}, // TIM5 + {6, 0x40001000, STM32_TIM6_IRQ}, // TIM6 + {7, 0x40001400, STM32_TIM7_IRQ}, // TIM7 + {8, 0x40010400, 0}, // TIM8 FIXME: TIM8 is a complex timer w/ multiple IRQs + {9, 0x40014000, STM32_TIM1_BRK_TIM9_IRQ}, // TIM9 + {10, 0x40014400, STM32_TIM1_UP_TIM10_IRQ}, // TIM10 + {11, 0x40014800, STM32_TIM1_TRG_COM_TIM11_IRQ}, // TIM11 + {12, 0x40001800, STM32_TIM8_BRK_TIM12_IRQ}, // TIM12 + {13, 0x40001C00, STM32_TIM8_UP_TIM13_IRQ}, // TIM13 + {14, 0x40002000, STM32_TIM8_TRG_COMM_TIM14_IRQ}, // TIM14 + }; + for (i = 0; i < ARRAY_LENGTH(timer_desc); ++i) { + assert(i < STM32F4XX_TIM_COUNT); + const stm32_periph_t periph = STM32_TIM1 + timer_desc[i].timer_num - 1; + + DeviceState *timer = qdev_create(NULL, "f2xx_tim"); + timer->id = stm32f4xx_periph_name_arr[periph]; + stm32_init_periph(timer, periph, timer_desc[i].addr, + qdev_get_gpio_in(nvic, timer_desc[i].irq_idx)); + stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *)timer; + } + + dummy_dev("Reserved", 0x40002400, 0x400); + // 0x40002800 + dummy_dev("WWDG", 0x40002C00, 0x400); + dummy_dev("IWDG", 0x40003000, 0x400); + dummy_dev("Reserved", 0x40003400, 0x400); + // 0x40003800 + // 0x40003C00 + dummy_dev("Reserved", 0x40004000, 0x400); + // 0x40004400 + // 0x40004800 + // 0x40004C00 + // 0x40005000 + + DeviceState *i2c1 = qdev_create(NULL, "f2xx_i2c"); + i2c1->id = stm32f4xx_periph_name_arr[STM32_I2C1]; + qdev_prop_set_int32(i2c1, "periph", STM32_I2C1); + stm32_init_periph(i2c1, STM32_I2C1, 0x40005400, + qdev_get_gpio_in(nvic, STM32_I2C1_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c1), 1, + qdev_get_gpio_in(nvic, STM32_I2C1_ER_IRQ)); + + DeviceState *i2c2 = qdev_create(NULL, "f2xx_i2c"); + i2c2->id = stm32f4xx_periph_name_arr[STM32_I2C2]; + qdev_prop_set_int32(i2c2, "periph", STM32_I2C2); + stm32_init_periph(i2c2, STM32_I2C2, 0x40005800, + qdev_get_gpio_in(nvic, STM32_I2C2_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c2), 1, + qdev_get_gpio_in(nvic, STM32_I2C2_ER_IRQ)); + + DeviceState *i2c3 = qdev_create(NULL, "f2xx_i2c"); + i2c3->id = stm32f4xx_periph_name_arr[STM32_I2C3]; + qdev_prop_set_int32(i2c3, "periph", STM32_I2C3); + stm32_init_periph(i2c3, STM32_I2C2, 0x40005C00, + qdev_get_gpio_in(nvic, STM32_I2C3_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c3), 1, + qdev_get_gpio_in(nvic, STM32_I2C3_ER_IRQ)); + + dummy_dev("Reserved", 0x40006000, 0x400); + dummy_dev("BxCAN1", 0x40006400, 0x400); + dummy_dev("BxCAN2", 0x40006800, 0x400); + dummy_dev("Reserved", 0x40006C00, 0x400); + // 0x40007000 PWR probably common + dummy_dev("DAC1/DAC2", 0x40007400, 0x400); + dummy_dev("Reserved", 0x40007800, 0x400); + dummy_dev("Reserved", 0x40008000, 0x8000); + // USART1 + // USART6 + dummy_dev("Reserved", 0x40011800, 0x800); + // ADC1 - ADC2 - ADC3 + // skipped reserved from here on + dummy_dev("SDIO", 0x40012C00, 0x400); + // SPI1 + // SYSCFG needed + + DeviceState *crc = qdev_create(NULL, "f2xx_crc"); + stm32_init_periph(crc, STM32_CRC, 0x40023000, NULL); + + DeviceState *dma1 = qdev_create(NULL, "f2xx_dma"); + stm32_init_periph(dma1, STM32_DMA1, 0x40026000, NULL); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 0, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM0_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 1, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM1_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 2, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM2_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 3, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM3_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 4, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM4_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 5, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM5_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 6, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM6_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 7, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM7_IRQ)); + + DeviceState *dma2 = qdev_create(NULL, "f2xx_dma"); + stm32_init_periph(dma2, STM32_DMA2, 0x40026400, NULL); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 0, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM0_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 1, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM1_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 2, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM2_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 3, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM3_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 4, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM4_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 5, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM5_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 6, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM6_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 7, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM7_IRQ)); +} + diff --git a/hw/arm/stm32f4xx.h b/hw/arm/stm32f4xx.h new file mode 100644 index 0000000000000..fdc92b714996f --- /dev/null +++ b/hw/arm/stm32f4xx.h @@ -0,0 +1,15 @@ +#include "hw/arm/stm32.h" + + +#define STM32F4XX_GPIO_COUNT (STM32_GPIOK - STM32_GPIOA + 1) +#define STM32F4XX_SPI_COUNT 6 + +#define STM32F4XX_UART_COUNT 8 +#define STM32F4XX_TIM_COUNT 14 + +struct stm32f4xx { + DeviceState *spi_dev[STM32F4XX_SPI_COUNT]; + DeviceState *qspi_dev; + + qemu_irq display_done_signal; +}; diff --git a/hw/arm/stm32f7xx.c b/hw/arm/stm32f7xx.c new file mode 100644 index 0000000000000..5e5ccc8fbf8da --- /dev/null +++ b/hw/arm/stm32f7xx.c @@ -0,0 +1,422 @@ +/* + * STM32F7xx Microcontroller + * + * Copyright (C) 2010 Andre Beckus + * Copyright (C) 2016 Pebble + * + * This implementation contains support for many of the STM32F7xx peripherals based on RM0410 rev 2, + * but currently uses a cortex-m4 core. + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "stm32f7xx.h" +#include "exec/address-spaces.h" +#include "exec/memory.h" +#include "hw/ssi.h" +#include "hw/block/flash.h" +#include "sysemu/blockdev.h" // drive_get + +static const char *stm32f7xx_periph_name_arr[] = { + ENUM_STRING(STM32_UART1), + ENUM_STRING(STM32_UART2), + ENUM_STRING(STM32_UART3), + ENUM_STRING(STM32_UART4), + ENUM_STRING(STM32_UART5), + ENUM_STRING(STM32_UART6), + ENUM_STRING(STM32_UART7), + ENUM_STRING(STM32_UART8), + + ENUM_STRING(STM32_SPI1), + ENUM_STRING(STM32_SPI2), + ENUM_STRING(STM32_SPI3), + + ENUM_STRING(STM32_I2C1), + ENUM_STRING(STM32_I2C2), + ENUM_STRING(STM32_I2C3), + ENUM_STRING(STM32_I2C4), + + ENUM_STRING(STM32_TIM1), + ENUM_STRING(STM32_TIM2), + ENUM_STRING(STM32_TIM3), + ENUM_STRING(STM32_TIM4), + ENUM_STRING(STM32_TIM5), + ENUM_STRING(STM32_TIM6), + ENUM_STRING(STM32_TIM7), + ENUM_STRING(STM32_TIM8), + ENUM_STRING(STM32_TIM9), + ENUM_STRING(STM32_TIM10), + ENUM_STRING(STM32_TIM11), + ENUM_STRING(STM32_TIM12), + ENUM_STRING(STM32_TIM13), + ENUM_STRING(STM32_TIM14), + + ENUM_STRING(STM32_GPIOA), + ENUM_STRING(STM32_GPIOB), + ENUM_STRING(STM32_GPIOC), + ENUM_STRING(STM32_GPIOD), + ENUM_STRING(STM32_GPIOE), + ENUM_STRING(STM32_GPIOF), + ENUM_STRING(STM32_GPIOG), + ENUM_STRING(STM32_GPIOH), + ENUM_STRING(STM32_GPIOI), + ENUM_STRING(STM32_GPIOJ), + ENUM_STRING(STM32_GPIOK), + + ENUM_STRING(STM32_QSPI), + ENUM_STRING(STM32_LPTIM1), + + ENUM_STRING(STM32_PERIPH_COUNT) +}; + +/* Init STM32F7XX CPU and memory. + flash_size and sram_size are in kb. */ + +static uint64_t kernel_load_translate_fn(void *opaque, uint64_t from_addr) { + if (from_addr == STM32_FLASH_ADDR_START) { + return 0x00000000; + } + return from_addr; +} + +static +void do_sys_reset(void *opaque, int n, int level) +{ + if (level) { + qemu_system_reset_request(); + } +} + +void stm32f7xx_init( + ram_addr_t flash_size, /* in KBytes */ + ram_addr_t ram_size, /* in KBytes */ + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + const uint32_t *gpio_idr_masks, + Stm32F7xxUart **stm32_uart, + Stm32Timer **stm32_timer, + Stm32F7xxLPTimer **stm32_lptimer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f7xx *stm, + ARMCPU **cpu) +{ + MemoryRegion *address_space_mem = get_system_memory(); + DriveInfo *dinfo; + DeviceState *nvic; + int i; + + Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); + + nvic = armv7m_translated_init( + stm32_container, /* parent */ + address_space_mem, /* address space memory */ + flash_size * 1024, /* flash size in bytes */ + ram_size * 1024, /* sram size in bytes */ + 0, /* default number of irqs */ + kernel_filename, /* kernel filename */ + kernel_load_translate_fn, /* kernel translate address function */ + NULL, /* translate function opaque argument */ + "cortex-m4", /* cpu model */ + cpu); /* Returned cpu instance */ + + qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, + qemu_allocate_irq(&do_sys_reset, NULL, 0)); + + dinfo = drive_get(IF_PFLASH, 0, 0); /* Use the first -pflash argument */ + if (dinfo) { + f2xx_flash_register(blk_by_legacy_dinfo(dinfo), STM32_FLASH_ADDR_START, flash_size * 1024); + } + + + // Create alias at 0x08000000 for internal flash, that is hard-coded at 0x00000000 + // in armv7m.c: + // TODO: Let BOOT0 and BOOT1 configuration pins determine what is mapped at 0x00000000, + // see SYSCFG_MEMRMP. + MemoryRegionSection mrs = memory_region_find(address_space_mem, STM32_FLASH_ADDR_START, + WORD_ACCESS_SIZE); + MemoryRegion *flash_alias = g_new(MemoryRegion, 1); + memory_region_init_alias( + flash_alias, /* alias memory region */ + NULL, /* owner */ + "stm32f7xx.flash.alias", /* name */ + mrs.mr, /* original region */ + 0, /* offset */ + flash_size * 1024); /* size in bytes */ + memory_region_add_subregion(address_space_mem, 0, flash_alias); + + + /* Setup the RCC */ + DeviceState *rcc_dev = qdev_create(NULL, "stm32f2xx_rcc"); + qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); + qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); + object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); + stm32_init_periph(rcc_dev, + STM32_RCC_PERIPH, /* periph index, not used */ + 0x40023800, /* base address */ + qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); /* irq */ + + /* Setup GPIOs */ + DeviceState **gpio_dev = (DeviceState **)g_malloc0(sizeof(DeviceState *) + * STM32F7XX_GPIO_COUNT); + for(i = 0; i < STM32F7XX_GPIO_COUNT; i++) { + stm32_periph_t periph = STM32_GPIOA + i; + gpio_dev[i] = qdev_create(NULL, "stm32f2xx_gpio"); + gpio_dev[i]->id = stm32f7xx_periph_name_arr[periph]; + qdev_prop_set_int32(gpio_dev[i], "periph", periph); + qdev_prop_set_uint32(gpio_dev[i], "idr-mask", gpio_idr_masks[i]); + // qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); + stm32_init_periph(gpio_dev[i], periph, 0x40020000 + (i * 0x400), NULL /*irq*/); + stm32_gpio[i] = (Stm32Gpio *)gpio_dev[i]; + } + + /* Connect the WKUP pin (GPIO A, pin 0) to the NVIC's WKUP handler */ + qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); + f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); + + + /* EXTI */ + DeviceState *exti_dev = qdev_create(NULL, "stm32_exti"); + qdev_prop_set_ptr(exti_dev, "stm32_gpio", gpio_dev); + stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40013C00, NULL); + SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); + + /* IRQs from EXTI to NVIC */ + sysbus_connect_irq(exti_busdev, 0, qdev_get_gpio_in(nvic, STM32_EXTI0_IRQ)); + sysbus_connect_irq(exti_busdev, 1, qdev_get_gpio_in(nvic, STM32_EXTI1_IRQ)); + sysbus_connect_irq(exti_busdev, 2, qdev_get_gpio_in(nvic, STM32_EXTI2_IRQ)); + sysbus_connect_irq(exti_busdev, 3, qdev_get_gpio_in(nvic, STM32_EXTI3_IRQ)); + sysbus_connect_irq(exti_busdev, 4, qdev_get_gpio_in(nvic, STM32_EXTI4_IRQ)); + sysbus_connect_irq(exti_busdev, 5, qdev_get_gpio_in(nvic, STM32_EXTI9_5_IRQ)); + sysbus_connect_irq(exti_busdev, 6, qdev_get_gpio_in(nvic, STM32_EXTI15_10_IRQ)); + sysbus_connect_irq(exti_busdev, 7, qdev_get_gpio_in(nvic, STM32_PVD_IRQ)); + sysbus_connect_irq(exti_busdev, 8, qdev_get_gpio_in(nvic, STM32_RTCAlarm_IRQ)); + sysbus_connect_irq(exti_busdev, 9, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 10, qdev_get_gpio_in(nvic, STM32_ETH_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 11, qdev_get_gpio_in(nvic, STM32_OTG_FS_WKUP_IRQ)); + sysbus_connect_irq(exti_busdev, 12, qdev_get_gpio_in(nvic, STM32_TAMP_STAMP_IRQ)); + sysbus_connect_irq(exti_busdev, 13, qdev_get_gpio_in(nvic, STM32_RTC_WKUP_IRQ)); + + + /* System configuration controller */ + DeviceState *syscfg_dev = qdev_create(NULL, "stm32f2xx_syscfg"); + qdev_prop_set_ptr(syscfg_dev, "stm32_rcc", rcc_dev); + qdev_prop_set_ptr(syscfg_dev, "stm32_exti", exti_dev); + qdev_prop_set_bit(syscfg_dev, "boot0", 0); + qdev_prop_set_bit(syscfg_dev, "boot1", 0); + stm32_init_periph(syscfg_dev, STM32_SYSCFG, 0x40013800, NULL /*irq*/); + + /* UARTS */ + struct { + uint32_t addr; + uint8_t irq_idx; + } const uart_desc[] = { + {0x40011000, STM32_UART1_IRQ}, + {0x40004400, STM32_UART2_IRQ}, + {0x40004800, STM32_UART3_IRQ}, + {0x40004C00, STM32_UART4_IRQ}, + {0x40005000, STM32_UART5_IRQ}, + {0x40011400, STM32_UART6_IRQ}, + {0x40007800, 0}, /* no IRQ for UART 7 */ + {0x40007C00, 0}, /* no IRQ for UART 8 */ + }; + for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { + assert(i < STM32F7XX_UART_COUNT); + const stm32_periph_t periph = STM32_UART1 + i; + DeviceState *uart_dev = qdev_create(NULL, "stm32f7xx-uart"); + uart_dev->id = stm32f7xx_periph_name_arr[periph]; + qdev_prop_set_int32(uart_dev, "periph", periph); + qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); + qemu_irq irq = NULL; + if (uart_desc[i].irq_idx != 0) { + irq = qdev_get_gpio_in(nvic, uart_desc[i].irq_idx); + } + stm32_init_periph(uart_dev, periph, uart_desc[i].addr, irq); + stm32_uart[i] = (Stm32F7xxUart *)uart_dev; + } + + /* SPI */ + struct { + uint32_t addr; + uint8_t irq_idx; + } const spi_desc[] = { + {0x40013000, STM32_SPI1_IRQ}, + {0x40003800, STM32_SPI2_IRQ}, + {0x40003CD0, STM32_SPI3_IRQ}, + {0x40013400, STM32_SPI4_IRQ}, + {0x40015000, STM32_SPI5_IRQ}, + {0x40015400, STM32_SPI6_IRQ}, + }; + for (i = 0; i < ARRAY_LENGTH(spi_desc); ++i) { + assert(i < STM32F7XX_SPI_COUNT); + const stm32_periph_t periph = STM32_SPI1 + i; + stm->spi_dev[i] = qdev_create(NULL, "stm32f2xx_spi"); + stm->spi_dev[i]->id = stm32f7xx_periph_name_arr[periph]; + qdev_prop_set_int32(stm->spi_dev[i], "periph", periph); + stm32_init_periph(stm->spi_dev[i], periph, spi_desc[i].addr, + qdev_get_gpio_in(nvic, spi_desc[i].irq_idx)); + } + + /* QSPI */ + stm->qspi_dev = qdev_create(NULL, "stm32f412_qspi"); + stm->qspi_dev->id = stm32f7xx_periph_name_arr[STM32_QSPI]; + stm32_init_periph(stm->qspi_dev, STM32_QSPI, 0xA0001000, qdev_get_gpio_in(nvic, STM32_QSPI_IRQ)); + + /* ADC */ + DeviceState *adc_dev = qdev_create(NULL, "stm32f2xx_adc"); + stm32_init_periph(adc_dev, STM32_ADC1, 0x40012000, NULL); + + /* RTC real time clock */ + DeviceState *rtc_dev = qdev_create(NULL, "f2xx_rtc"); + *stm32_rtc = rtc_dev; + stm32_init_periph(rtc_dev, STM32_RTC, 0x40002800, NULL); + // Alarm A + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 0, qdev_get_gpio_in(exti_dev, 17)); + // Alarm B + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 1, qdev_get_gpio_in(exti_dev, 17)); + // Wake up timer + sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 2, qdev_get_gpio_in(exti_dev, 22)); + + /* Power management */ + DeviceState *pwr_dev = qdev_create(NULL, "f2xx_pwr"); + stm32_init_periph(pwr_dev, STM32_RTC, 0x40007000, NULL); + qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); + +#define dummy_dev(name, start, size) do {\ + DeviceState *dummy = qdev_create(NULL, "f2xx_dummy"); \ + qdev_prop_set_ptr(dummy, "name", (void *)name); \ + qdev_prop_set_int32(dummy, "size", size); \ + qdev_init_nofail(dummy); \ + sysbus_mmio_map(SYS_BUS_DEVICE(dummy), 0, start); \ +} while (0) + + + /* Timers */ + struct { + uint8_t timer_num; + uint32_t addr; + uint8_t irq_idx; + } const timer_desc[] = { + {1, 0x40010000, 0}, // TIM1 FIXME: TIM1 is a complex timer w/ multiple IRQs + {2, 0x40000000, STM32_TIM2_IRQ}, // TIM2 + {3, 0x40000400, STM32_TIM3_IRQ}, // TIM3 + {4, 0x40000800, STM32_TIM4_IRQ}, // TIM4 + {5, 0x40000C00, STM32_TIM5_IRQ}, // TIM5 + {6, 0x40001000, STM32_TIM6_IRQ}, // TIM6 + {7, 0x40001400, STM32_TIM7_IRQ}, // TIM7 + {8, 0x40010400, 0}, // TIM8 FIXME: TIM8 is a complex timer w/ multiple IRQs + {9, 0x40014000, STM32_TIM1_BRK_TIM9_IRQ}, // TIM9 + {10, 0x40014400, STM32_TIM1_UP_TIM10_IRQ}, // TIM10 + {11, 0x40014800, STM32_TIM1_TRG_COM_TIM11_IRQ}, // TIM11 + {12, 0x40001800, STM32_TIM8_BRK_TIM12_IRQ}, // TIM12 + {13, 0x40001C00, STM32_TIM8_UP_TIM13_IRQ}, // TIM13 + {14, 0x40002000, STM32_TIM8_TRG_COMM_TIM14_IRQ}, // TIM14 + }; + for (i = 0; i < ARRAY_LENGTH(timer_desc); ++i) { + assert(i < STM32F7XX_TIM_COUNT); + const stm32_periph_t periph = STM32_TIM1 + timer_desc[i].timer_num - 1; + + DeviceState *timer = qdev_create(NULL, "f2xx_tim"); + timer->id = stm32f7xx_periph_name_arr[periph]; + stm32_init_periph(timer, periph, timer_desc[i].addr, + qdev_get_gpio_in(nvic, timer_desc[i].irq_idx)); + stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *)timer; + } + + /* Low-Power Timer */ + DeviceState *lptimer = qdev_create(NULL, "f7xx_lptim"); + lptimer->id = stm32f7xx_periph_name_arr[STM32_LPTIM1]; + stm32_init_periph(lptimer, STM32_LPTIM1, 0x40002400, qdev_get_gpio_in(nvic, STM32_LPTIM1_IRQ)); + *stm32_lptimer = (Stm32F7xxLPTimer *)lptimer; + + // 0x40002800 + dummy_dev("WWDG", 0x40002C00, 0x400); + dummy_dev("IWDG", 0x40003000, 0x400); + dummy_dev("Reserved", 0x40003400, 0x400); + // 0x40003800 + // 0x40003C00 + dummy_dev("Reserved", 0x40004000, 0x400); + // 0x40004400 + // 0x40004800 + // 0x40004C00 + // 0x40005000 + + DeviceState *i2c1 = qdev_create(NULL, "stm32f7xx_i2c"); + i2c1->id = stm32f7xx_periph_name_arr[STM32_I2C1]; + qdev_prop_set_int32(i2c1, "periph", STM32_I2C1); + stm32_init_periph(i2c1, STM32_I2C1, 0x40005400, qdev_get_gpio_in(nvic, STM32_I2C1_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c1), 1, qdev_get_gpio_in(nvic, STM32_I2C1_ER_IRQ)); + + DeviceState *i2c2 = qdev_create(NULL, "stm32f7xx_i2c"); + i2c2->id = stm32f7xx_periph_name_arr[STM32_I2C2]; + qdev_prop_set_int32(i2c2, "periph", STM32_I2C2); + stm32_init_periph(i2c2, STM32_I2C2, 0x40005800, qdev_get_gpio_in(nvic, STM32_I2C2_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c2), 1, qdev_get_gpio_in(nvic, STM32_I2C2_ER_IRQ)); + + DeviceState *i2c3 = qdev_create(NULL, "stm32f7xx_i2c"); + i2c3->id = stm32f7xx_periph_name_arr[STM32_I2C3]; + qdev_prop_set_int32(i2c3, "periph", STM32_I2C3); + stm32_init_periph(i2c3, STM32_I2C3, 0x40005C00, qdev_get_gpio_in(nvic, STM32_I2C3_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c3), 1, qdev_get_gpio_in(nvic, STM32_I2C3_ER_IRQ)); + + DeviceState *i2c4 = qdev_create(NULL, "stm32f7xx_i2c"); + i2c4->id = stm32f7xx_periph_name_arr[STM32_I2C4]; + qdev_prop_set_int32(i2c4, "periph", STM32_I2C4); + stm32_init_periph(i2c4, STM32_I2C4, 0x40006000, qdev_get_gpio_in(nvic, STM32_I2C4_EV_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(i2c4), 1, qdev_get_gpio_in(nvic, STM32_I2C4_ER_IRQ)); + + dummy_dev("BxCAN1", 0x40006400, 0x400); + dummy_dev("BxCAN2", 0x40006800, 0x400); + dummy_dev("Reserved", 0x40006C00, 0x400); + // 0x40007000 PWR probably common + dummy_dev("DAC1/DAC2", 0x40007400, 0x400); + dummy_dev("Reserved", 0x40007800, 0x400); + dummy_dev("Reserved", 0x40008000, 0x8000); + // USART1 + // USART6 + dummy_dev("Reserved", 0x40011800, 0x800); + // ADC1 - ADC2 - ADC3 + // skipped reserved from here on + dummy_dev("SDIO", 0x40012C00, 0x400); + // SPI1 + // SYSCFG needed + + DeviceState *crc = qdev_create(NULL, "f2xx_crc"); + stm32_init_periph(crc, STM32_CRC, 0x40023000, NULL); + + DeviceState *dma1 = qdev_create(NULL, "f2xx_dma"); + stm32_init_periph(dma1, STM32_DMA1, 0x40026000, NULL); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 0, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM0_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 1, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM1_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 2, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM2_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 3, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM3_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 4, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM4_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 5, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM5_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 6, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM6_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 7, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM7_IRQ)); + + DeviceState *dma2 = qdev_create(NULL, "f2xx_dma"); + stm32_init_periph(dma2, STM32_DMA2, 0x40026400, NULL); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 0, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM0_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 1, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM1_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 2, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM2_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 3, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM3_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 4, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM4_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 5, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM5_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 6, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM6_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 7, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM7_IRQ)); +} + diff --git a/hw/arm/stm32f7xx.h b/hw/arm/stm32f7xx.h new file mode 100644 index 0000000000000..2620f61a1c99e --- /dev/null +++ b/hw/arm/stm32f7xx.h @@ -0,0 +1,15 @@ +#include "hw/arm/stm32.h" + + +#define STM32F7XX_GPIO_COUNT (STM32_GPIOK - STM32_GPIOA + 1) +#define STM32F7XX_SPI_COUNT 6 + +#define STM32F7XX_UART_COUNT 8 +#define STM32F7XX_TIM_COUNT 14 + +struct stm32f7xx { + DeviceState *spi_dev[STM32F7XX_SPI_COUNT]; + DeviceState *qspi_dev; + + qemu_irq display_done_signal; +}; diff --git a/hw/arm/stm32f7xx_i2c.c b/hw/arm/stm32f7xx_i2c.c new file mode 100644 index 0000000000000..f417bdfb55917 --- /dev/null +++ b/hw/arm/stm32f7xx_i2c.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2016 + * + * 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. + */ + +/* + * QEMU model of the stm32f7xx I2C controller. + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/i2c/i2c.h" + +#define R_I2C_CR1 (0x00 / 4) +#define R_I2C_CR2 (0x04 / 4) +#define R_I2C_OAR1 (0x08 / 4) +#define R_I2C_OAR2 (0x0c / 4) +#define R_I2C_TIMINGR (0x10 / 4) +#define R_I2C_TIMEOUTR (0x14 / 4) +#define R_I2C_ISR (0x18 / 4) +#define R_I2C_ICR (0x1C / 4) +#define R_I2C_PECR (0x20 / 4) +#define R_I2C_RXDR (0x24 / 4) +#define R_I2C_TXDR (0x28 / 4) +#define R_I2C_MAX (0x28 / 4) + +#define R_I2C_CR1_PE_BIT (1 << 0) + +#define R_I2C_CR2_START_BIT (1 << 13) + +#define R_I2C_ISR_BERR_BIT (1 << 8) + + +#ifdef DEBUG_STM32_I2C +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("STM32F7XX_I2c: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +static const char *stm32f7xx_i2c_reg_name_arr[] = { + "CR1", + "CR2", + "OAR1", + "OAR2", + "TIMINGR", + "TIMEOUTR", + "ISR", + "ICR", + "PECR", + "RXDR", + "TXDR", +}; + + + +typedef struct stm32f7xx_i2c { + SysBusDevice busdev; + MemoryRegion iomem; + qemu_irq evt_irq; + qemu_irq err_irq; + + I2CBus *bus; + + stm32_periph_t periph; + + int32_t rx; + int rx_full; + uint16_t regs[R_I2C_MAX]; + +} stm32f7xx_i2c; + + +/* Routine which updates the I2C's IRQs. This should be called whenever + * an interrupt-related flag is updated. + */ +static void stm32f7xx_i2c_update_irq(stm32f7xx_i2c *s) { + int new_err_irq_level = (s->regs[R_I2C_ISR] & R_I2C_ISR_BERR_BIT); + + int new_evt_irq_level = 0; + + DPRINTF("%s %s: setting evt_irq to %d\n", __func__, s->busdev.parent_obj.id, + !!new_evt_irq_level); + qemu_set_irq(s->evt_irq, !!new_evt_irq_level); + + DPRINTF("%s %s: setting err_irq to %d\n", __func__, s->busdev.parent_obj.id, + !!new_err_irq_level); + qemu_set_irq(s->err_irq, !!new_err_irq_level); +} + + + +static uint64_t stm32f7xx_i2c_read(void *arg, hwaddr offset, unsigned size) +{ + stm32f7xx_i2c *s = arg; + uint32_t r = UINT32_MAX; + const char *reg_name = "UNKNOWN"; + + if (!(size == 2 || size == 4 || (offset & 0x3) != 0)) { + STM32_BAD_REG(offset, size); + } + offset >>= 2; + if (offset < R_I2C_MAX) { + r = s->regs[offset]; + reg_name = stm32f7xx_i2c_reg_name_arr[offset]; + } else { + qemu_log_mask(LOG_GUEST_ERROR, "Out of range I2C write, offset 0x%x\n", + (unsigned)offset << 2); + } + + DPRINTF("%s %s: register %s, result: 0x%x\n", __func__, s->busdev.parent_obj.id, + reg_name, r); + return r; +} + + +static void stm32f7xx_i2c_write(void *arg, hwaddr offset, uint64_t data, unsigned size) +{ + const char *reg_name = "UNKNOWN"; + struct stm32f7xx_i2c *s = (struct stm32f7xx_i2c *)arg; + + if (size != 2 && size != 4) { + STM32_BAD_REG(offset, size); + } + /* I2C registers are all at most 32 bits wide */ + data &= 0xffffffff; + offset >>= 2; + + if (offset < R_I2C_MAX) { + reg_name = stm32f7xx_i2c_reg_name_arr[offset]; + } + DPRINTF("%s %s: register %s, data: 0x%llx, size:%d\n", __func__, s->busdev.parent_obj.id, + reg_name, data, size); + + + switch (offset) { + case R_I2C_CR1: + if ((data & R_I2C_CR1_PE_BIT) == 0) { + s->regs[R_I2C_ISR] = 0; + } + break; + + case R_I2C_CR2: + if (data & R_I2C_CR2_START_BIT) { + // Abort all attempted master transfers with a bus error + s->regs[R_I2C_ISR] |= R_I2C_ISR_BERR_BIT; + } else { + s->regs[offset] = data; + } + break; + + case R_I2C_TXDR: + i2c_send(s->bus, (uint8_t)data); + break; + + case R_I2C_ICR: + s->regs[R_I2C_ISR] &= ~data; + break; + + case R_I2C_ISR: + case R_I2C_RXDR: + STM32_WARN_RO_REG(offset); + break; + + case R_I2C_OAR1: + case R_I2C_OAR2: + case R_I2C_TIMINGR: + case R_I2C_TIMEOUTR: + case R_I2C_PECR: + s->regs[offset] = data; + break; + + default: + STM32_BAD_REG(offset, size); + break; + } + stm32f7xx_i2c_update_irq(s); +} + +static const MemoryRegionOps stm32f7xx_i2c_ops = { + .read = stm32f7xx_i2c_read, + .write = stm32f7xx_i2c_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void stm32f7xx_i2c_reset(DeviceState *dev) +{ +} + +static int stm32f7xx_i2c_init(SysBusDevice *dev) +{ + struct stm32f7xx_i2c *s = FROM_SYSBUS(struct stm32f7xx_i2c, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32f7xx_i2c_ops, s, "i2c", 0x3ff); + sysbus_init_mmio(dev, &s->iomem); + sysbus_init_irq(dev, &s->evt_irq); + sysbus_init_irq(dev, &s->err_irq); + s->bus = i2c_init_bus(DEVICE(dev), "i2c"); + + DPRINTF("%s %s: INITIALIZED\n", __func__, s->busdev.parent_obj.id); + return 0; +} + + +static Property stm32f7xx_i2c_properties[] = { + DEFINE_PROP_INT32("periph", struct stm32f7xx_i2c, periph, -1), + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32f7xx_i2c_class_init(ObjectClass *c, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(c); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); + + sc->init = stm32f7xx_i2c_init; + dc->reset = stm32f7xx_i2c_reset; + dc->props = stm32f7xx_i2c_properties; +} + +static const TypeInfo stm32f7xx_i2c_info = { + .name = "stm32f7xx_i2c", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct stm32f7xx_i2c), + .class_init = stm32f7xx_i2c_class_init +}; + +static void stm32f7xx_i2c_register_types(void) +{ + type_register_static(&stm32f7xx_i2c_info); +} + +type_init(stm32f7xx_i2c_register_types) diff --git a/hw/arm/stm32f7xx_lptim.c b/hw/arm/stm32f7xx_lptim.c new file mode 100644 index 0000000000000..cc4583c498bf3 --- /dev/null +++ b/hw/arm/stm32f7xx_lptim.c @@ -0,0 +1,241 @@ +/* + * Source code based on stm32f2xx_tim.c + * + * 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. + */ +/* + * QEMU stm32f7xx LPTIM emulation + */ +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "qemu/timer.h" + +//#define DEBUG_STM32F7XX_LPTIM +#ifdef DEBUG_STM32F7XX_LPTIM +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { \ + printf("DEBUG_STM32F7XX_LPTIM %s: " fmt , __func__, ## __VA_ARGS__); \ + usleep(100); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + +#define R_LPTIM_ISR (0x00 / 4) +#define R_LPTIM_ICR (0x04 / 4) +#define R_LPTIM_IER (0x08 / 4) +#define R_LPTIM_CFGR (0x0C / 4) +#define R_LPTIM_CR (0x10 / 4) +#define R_LPTIM_CMP (0x14 / 4) +#define R_LPTIM_ARR (0x18 / 4) +#define R_LPTIM_CNT (0x1C / 4) +#define R_LPTIM_OR (0x20 / 4) +#define R_LPTIM_MAX (0x24 / 4) + +static const char *f7xx_lptim_reg_names[] = { + ENUM_STRING(R_LPTIM_ISR), + ENUM_STRING(R_LPTIM_ICR), + ENUM_STRING(R_LPTIM_IER), + ENUM_STRING(R_LPTIM_CFGR), + ENUM_STRING(R_LPTIM_CR), + ENUM_STRING(R_LPTIM_CMP), + ENUM_STRING(R_LPTIM_ARR), + ENUM_STRING(R_LPTIM_CNT), + ENUM_STRING(R_LPTIM_OR), +}; + + +typedef struct f7xx_lptim { + SysBusDevice busdev; + MemoryRegion iomem; + QEMUTimer *timer; + qemu_irq irq; + uint32_t regs[R_LPTIM_MAX]; + + qemu_irq pwm_ratio_changed; + qemu_irq pwm_enable; +} f7xx_lptim; + +static uint32_t f7xx_lptim_period(f7xx_lptim *s) { + /* FIXME: hard coded to 32kHz */ + return 31250; +} + +static int64_t f7xx_lptim_next_transition(f7xx_lptim *s, int64_t current_time) { + return current_time + f7xx_lptim_period(s) * s->regs[R_LPTIM_ARR]; +} + +static void f7xx_lptim_timer(void *arg) { + f7xx_lptim *s = arg; + if (s->regs[R_LPTIM_CR] & 1) { + timer_mod(s->timer, f7xx_lptim_next_transition(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))); + } + qemu_set_irq(s->irq, 1); +} + +static uint64_t f7xx_lptim_read(void *arg, hwaddr addr, unsigned int size) { + f7xx_lptim *s = arg; + uint32_t r = 0; + int offset = addr & 0x3; + addr >>= 2; + if (addr >= R_LPTIM_MAX) { + DPRINTF("invalid read register 0x%x\n", (unsigned int)addr << 2); + qemu_log_mask(LOG_GUEST_ERROR, "f7xx lptim invalid read register 0x%x\n", + (unsigned int)addr << 2); + return 0; + } + + switch (addr) { + case R_LPTIM_CFGR: + case R_LPTIM_CMP: + case R_LPTIM_ARR: + case R_LPTIM_CNT: + case R_LPTIM_CR: + r = (s->regs[addr] >> offset * 8) & ((1ull << (8 * size)) - 1); + break; + default: + DPRINTF("unimplemented read 0x%x+%u size %u\n", (unsigned int)addr << 2, offset, size); + qemu_log_mask(LOG_UNIMP, "f7xx lptim unimplemented read 0x%x+%u size %u\n", + (unsigned int)addr << 2, offset, size); + break; + } + + DPRINTF("reg: %s, size: %d, value: 0x%x\n", f7xx_lptim_reg_names[addr], size, r); + return r; +} + +static void f7xx_lptim_write(void *arg, hwaddr addr, uint64_t data, unsigned int size) { + f7xx_lptim *s = arg; + int offset = addr & 0x3; + addr >>= 2; + DPRINTF("reg:%s, size: %d, value: 0x%llx\n", f7xx_lptim_reg_names[addr], size, data); + if (addr >= R_LPTIM_MAX) { + DPRINTF("invalid write register 0x%x\n", (unsigned int)addr << 2); + qemu_log_mask(LOG_GUEST_ERROR, "f7xx lptim invalid write register 0x%x\n", + (unsigned int)addr << 2); + return; + } + + switch (size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + + switch (addr) { + case R_LPTIM_CR: + if ((s->regs[addr] & 1) == 0 && data & 1) { + DPRINTF("started\n"); + timer_mod(s->timer, f7xx_lptim_next_transition(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))); + qemu_set_irq(s->pwm_enable, 1); + } else if (s->regs[addr] & 1 && (data & 1) == 0) { + DPRINTF("stopped\n"); + timer_del(s->timer); + qemu_set_irq(s->pwm_enable, 0); + } + s->regs[addr] = data; + break; + case R_LPTIM_CMP: + { + s->regs[addr] = data; + uint32_t ratio = (s->regs[R_LPTIM_CMP] * 255) / s->regs[R_LPTIM_ARR]; + DPRINTF("Setting PWM ratio to %d (0x%x, 0x%x)\n", ratio, s->regs[R_LPTIM_CMP], s->regs[R_LPTIM_ARR]); + qemu_set_irq(s->pwm_ratio_changed, ratio); + break; + } + case R_LPTIM_CFGR: + case R_LPTIM_ARR: + case R_LPTIM_CNT: + s->regs[addr] = data; + break; + default: + DPRINTF("unimplemented write 0x%x+%u size %u val 0x%x\n", (unsigned int)addr << 2, + offset, size, (unsigned int)data); + qemu_log_mask(LOG_UNIMP, "f7xx lptim unimplemented write 0x%x+%u size %u val 0x%x\n", + (unsigned int)addr << 2, offset, size, (unsigned int)data); + break; + } +} + +static const MemoryRegionOps f7xx_lptim_ops = { + .read = f7xx_lptim_read, + .write = f7xx_lptim_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + } +}; + +static void f7xx_lptim_reset(DeviceState *dev) { + f7xx_lptim *s = FROM_SYSBUS(f7xx_lptim, SYS_BUS_DEVICE(dev)); + + timer_del(s->timer); + memset(&s->regs, 0, sizeof(s->regs)); +} + + +static int f7xx_lptim_init(SysBusDevice *dev) { + f7xx_lptim *s = FROM_SYSBUS(f7xx_lptim, dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &f7xx_lptim_ops, s, "lptim", 0xa0); + sysbus_init_mmio(dev, &s->iomem); + s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, f7xx_lptim_timer, s); + sysbus_init_irq(dev, &s->irq); + + qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_ratio_changed, "pwm_ratio_changed", 1); + qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_enable, "pwm_enable", 1); + + return 0; +} + +static Property f7xx_lptim_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static void f7xx_lptim_class_init(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); + sc->init = f7xx_lptim_init; + //TODO: fix this: dc->no_user = 1; + dc->props = f7xx_lptim_properties; + dc->reset = f7xx_lptim_reset; +} + +static const TypeInfo f7xx_lptim_info = { + .name = "f7xx_lptim", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(f7xx_lptim), + .class_init = f7xx_lptim_class_init, +}; + +static void f7xx_lptim_register_types(void) { + type_register_static(&f7xx_lptim_info); +} + +type_init(f7xx_lptim_register_types) diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index 4b4a2b338dc47..10bb6772bc17c 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -1,10 +1,16 @@ common-obj-y += block.o cdrom.o hd-geometry.o +common-obj-y += mx25u.o mt25q.o common-obj-$(CONFIG_FDC) += fdc.o common-obj-$(CONFIG_SSI_M25P80) += m25p80.o common-obj-$(CONFIG_NAND) += nand.o common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o +<<<<<<< HEAD common-obj-$(CONFIG_XEN) += xen-block.o +======= +common-obj-$(CONFIG_PFLASH_JEDEC_424) += pflash_jedec_424.o +common-obj-$(CONFIG_XEN_BACKEND) += xen_disk.o +>>>>>>> 919b29ba7d... Pebble Qemu common-obj-$(CONFIG_ECC) += ecc.o common-obj-$(CONFIG_ONENAND) += onenand.o common-obj-$(CONFIG_NVME_PCI) += nvme.o diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 82270884416e3..c035d872a9a07 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -215,6 +215,7 @@ static const FlashPartInfo known_devices[] = { { INFO("mx25l1606e", 0xc22015, 0, 64 << 10, 32, ER_4K) }, { INFO("mx25l3205d", 0xc22016, 0, 64 << 10, 64, 0) }, { INFO("mx25l6405d", 0xc22017, 0, 64 << 10, 128, 0) }, + //{ INFO("mx25u6435f", 0xc22537, 0, 64 << 10, 128, ER_4K | ER_32K) }, { INFO("mx25l12805d", 0xc22018, 0, 64 << 10, 256, 0) }, { INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) }, { INFO("mx25l25635e", 0xc22019, 0, 64 << 10, 512, 0) }, @@ -361,6 +362,7 @@ typedef enum { ERASE_32K = 0x52, ERASE4_32K = 0x5c, ERASE_SECTOR = 0xd8, +<<<<<<< HEAD ERASE4_SECTOR = 0xdc, EN_4BYTE_ADDR = 0xB7, @@ -389,6 +391,11 @@ typedef enum { WEVCR = 0x61, DIE_ERASE = 0xC4, +======= + + SLEEP = 0xb9, + WAKE = 0xab, +>>>>>>> 919b29ba7d... Pebble Qemu } FlashCMD; typedef enum { @@ -1068,6 +1075,8 @@ static void decode_new_cmd(Flash *s, uint32_t value) } break; case NOP: + case SLEEP: + case WAKE: break; case EN_4BYTE_ADDR: s->four_bytes_address_mode = true; diff --git a/hw/block/mt25q.c b/hw/block/mt25q.c new file mode 100644 index 0000000000000..b00265ef20f6a --- /dev/null +++ b/hw/block/mt25q.c @@ -0,0 +1,512 @@ +/* + * Emulate a QSPI flash device following the mt25q command set. + * Modelled after the m25p80 emulation found in hw/block/m25p80.c + */ + +#include "hw/hw.h" +#include "sysemu/block-backend.h" +#include "sysemu/blockdev.h" +#include "hw/ssi.h" + + +// TODO: These should be made configurable to support different flash parts +#define FLASH_SECTOR_SIZE (64 * 1024) +#define FLASH_NUM_SECTORS (256) +#define FLASH_PAGE_SIZE (256) +const uint8_t MT25Q_ID[] = { 0x20, 0xbb, 0x19 }; + +#ifndef MT25Q_ERR_DEBUG +#define MT25Q_ERR_DEBUG 0 +#endif + +// The usleep() helps MacOS stdout from freezing when printing a lot +#define DB_PRINT_L(level, ...) do { \ + if (MT25Q_ERR_DEBUG > (level)) { \ + fprintf(stderr, "%d: %s: ", level, __func__); \ + fprintf(stderr, ## __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + usleep(1000); \ + } \ +} while (0); + + +typedef enum { + READ_EVCR = 0x65, + WRITE_EVCR = 0x61, + + RESET_ENABLE = 0x66, + RESET = 0x99, + + WRITE_ENABLE = 0x06, + WRITE_DISABLE = 0x04, + + READ_STATUS_REG = 0x05, + READ_FLAG_STATUS_REG = 0x70, + + FAST_READ = 0x0b, + FAST_READ_DDR = 0x0d, + READ_QID = 0xaf, + + PAGE_PROGRAM = 0x02, + + ERASE_SUBSECTOR = 0x20, // Erase 4k sector + ERASE_BLOCK = 0xd8, // Erase 64k block + + ERASE_SUSPEND = 0x75, + ERASE_RESUME = 0x7a, + + DEEP_SLEEP = 0xb9, + WAKE = 0xab, + + QUAD_ENABLE = 0x35, +} FlashCmd; + +typedef enum { + STATE_IDLE, + + STATE_COLLECT_CMD_DATA, + + STATE_WRITE, + STATE_READ, + STATE_READ_QID, + STATE_READ_REGISTER, +} CMDState; + +#define R_STATUS_BUSY (1 << 0) +#define R_STATUS_WRITE_ENABLE (1 << 1) + +#define R_FLAG_STATUS_ERASE_SUSPEND (1 << 6) + +typedef struct { + SSISlave parent_obj; + + //--- Storage --- + BlockBackend *blk; + uint8_t *storage; + uint32_t size; + int page_size; + + int64_t dirty_page; + + //--- Registers --- + uint8_t EVCR; + uint8_t STATUS_REG; + uint8_t FLAG_STATUS_REG; + + //--- Command state --- + CMDState state; + FlashCmd cmd_in_progress; + uint8_t cmd_data[4]; //! Commands can require up to 4 bytes of additional data + uint8_t cmd_bytes; //! Number of bytes required by command [0,4] + uint32_t len; + uint32_t pos; + uint64_t current_address; + + uint8_t *current_register; + uint8_t register_read_mask; //! mask to apply after reading current_register + + bool reset_enabled; +} Flash; + +typedef struct { + SSISlaveClass parent_class; +} MT25QClass; + +#define TYPE_MT25Q "mt25q-generic" +#define MT25Q(obj) \ + OBJECT_CHECK(Flash, (obj), TYPE_MT25Q) +#define MT25Q_CLASS(klass) \ + OBJECT_CLASS_CHECK(MT25QClass, (klass), TYPE_MT25Q) +#define MT25Q_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MT25QClass, (obj), TYPE_MT25Q) + +static void blk_sync_complete(void *opaque, int ret) +{ + /* do nothing. Masters do not directly interact with the backing store, + * only the working copy so no mutexing required. + */ +} + +static void mt25q_flash_sync_page(Flash *s, int page) +{ + int blk_sector, nb_sectors; + QEMUIOVector iov; + + if (!s->blk || blk_is_read_only(s->blk)) { + return; + } + + blk_sector = (page * s->page_size) / BDRV_SECTOR_SIZE; + nb_sectors = DIV_ROUND_UP(s->page_size, BDRV_SECTOR_SIZE); + qemu_iovec_init(&iov, 1); + qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE, + nb_sectors * BDRV_SECTOR_SIZE); + blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete, + NULL); +} + +static inline void mt25q_flash_sync_area(Flash *s, int64_t off, int64_t len) +{ + int64_t start, end, nb_sectors; + QEMUIOVector iov; + + if (!s->blk || blk_is_read_only(s->blk)) { + return; + } + + assert(!(len % BDRV_SECTOR_SIZE)); + start = off / BDRV_SECTOR_SIZE; + end = (off + len) / BDRV_SECTOR_SIZE; + nb_sectors = end - start; + qemu_iovec_init(&iov, 1); + qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), + nb_sectors * BDRV_SECTOR_SIZE); + blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL); +} + +static inline void flash_sync_dirty(Flash *s, int64_t newpage) +{ + if (s->dirty_page >= 0 && s->dirty_page != newpage) { + mt25q_flash_sync_page(s, s->dirty_page); + s->dirty_page = newpage; + } +} + +static void mt25q_flash_erase(Flash *s, uint32_t offset, FlashCmd cmd) +{ + uint32_t len; + + switch (cmd) { + case ERASE_SUBSECTOR: // Erase 4k sector + len = 4 << 10; + break; + case ERASE_BLOCK: // Erase 64k block + len = 64 << 10; + break; + default: + abort(); + } + + DB_PRINT_L(0, "erase offset = %#x, len = %d", offset, len); + + if (!(s->STATUS_REG & R_STATUS_WRITE_ENABLE)) { + DB_PRINT_L(-1, "erase with write protect!\n"); + qemu_log_mask(LOG_GUEST_ERROR, "MT25Q: erase with write protect!\n"); + return; + } + + memset(s->storage + offset, 0xff, len); + mt25q_flash_sync_area(s, offset, len); +} + +static void mt25q_decode_new_cmd(Flash *s, uint32_t value) +{ + s->cmd_in_progress = value; + DB_PRINT_L(2, "decoding new command: 0x%x", value); + + switch (value) { + case RESET_ENABLE: + // handled below + break; + + case RESET: + assert(s->reset_enabled); + break; + + case WRITE_ENABLE: + s->STATUS_REG |= R_STATUS_WRITE_ENABLE; + s->state = STATE_IDLE; + break; + case WRITE_DISABLE: + s->STATUS_REG &= ~R_STATUS_WRITE_ENABLE; + s->state = STATE_IDLE; + break; + + case WRITE_EVCR: + s->pos = 0; + s->cmd_bytes = 1; + s->state = STATE_COLLECT_CMD_DATA; + break; + case READ_EVCR: + s->current_register = &s->EVCR; + s->state = STATE_READ_REGISTER; + break; + case READ_STATUS_REG: + s->current_register = &s->STATUS_REG; + s->state = STATE_READ_REGISTER; + break; + case READ_FLAG_STATUS_REG: + s->current_register = &s->FLAG_STATUS_REG; + s->state = STATE_READ_REGISTER; + break; + + case FAST_READ: + case FAST_READ_DDR: + s->cmd_bytes = 3; + s->pos = 0; + s->state = STATE_COLLECT_CMD_DATA; + break; + + case READ_QID: + s->cmd_bytes = 0; + s->state = STATE_READ_QID; + s->len = 3; + s->pos = 0; + break; + + case PAGE_PROGRAM: + s->pos = 0; + s->cmd_bytes = 3; + s->state = STATE_COLLECT_CMD_DATA; + break; + + case ERASE_SUBSECTOR: + case ERASE_BLOCK: + s->pos = 0; + s->cmd_bytes = 3; + s->state = STATE_COLLECT_CMD_DATA; + break; + + case ERASE_SUSPEND: + case ERASE_RESUME: + break; + + case DEEP_SLEEP: + case WAKE: + break; + + case QUAD_ENABLE: + break; + + default: + DB_PRINT_L(-1, "Unknown cmd 0x%x\n", value); + qemu_log_mask(LOG_GUEST_ERROR, "MT25Q: Unknown cmd 0x%x\n", value); + } + + s->reset_enabled = (value == RESET_ENABLE); +} + +static void mt25q_handle_cmd_data(Flash *s) +{ + s->state = STATE_IDLE; + + switch (s->cmd_in_progress) { + case WRITE_EVCR: + s->EVCR = s->cmd_data[0]; + s->current_address = 0; + break; + case READ_EVCR: + assert(false); + break; + case PAGE_PROGRAM: + s->current_address = (s->cmd_data[2] << 16) | (s->cmd_data[1] << 8) | (s->cmd_data[0]); + s->state = STATE_WRITE; + break; + case READ_STATUS_REG: + case READ_FLAG_STATUS_REG: + assert(false); + break; + case FAST_READ: + case FAST_READ_DDR: + s->current_address = (s->cmd_data[2] << 16) | (s->cmd_data[1] << 8) | (s->cmd_data[0]); + DB_PRINT_L(2, "Read From: 0x%"PRIu64, s->current_address); + s->state = STATE_READ; + break; + case ERASE_SUBSECTOR: + case ERASE_BLOCK: + s->current_address = (s->cmd_data[2] << 16) | (s->cmd_data[1] << 8) | (s->cmd_data[0]); + mt25q_flash_erase(s, s->current_address, s->cmd_in_progress); + s->STATUS_REG |= R_STATUS_BUSY; + s->register_read_mask = R_STATUS_BUSY; + break; + + case ERASE_SUSPEND: + case ERASE_RESUME: + s->current_address = (s->cmd_data[2] << 16) | (s->cmd_data[1] << 8) | (s->cmd_data[0]); + break; + + default: + s->current_address = (s->cmd_data[2] << 16) | (s->cmd_data[1] << 8) | (s->cmd_data[0]); + DB_PRINT_L(-1, "Unknown cmd data 0x%x\n", s->cmd_in_progress); + qemu_log_mask(LOG_GUEST_ERROR, "MT25Q: Unknown cmd data 0x%x\n", s->cmd_in_progress); + break; + } +} + +static void mt25q_write8(Flash *s, uint8_t value) +{ + int64_t page = s->current_address / s->page_size; + + // TODO: Write protection + + uint8_t current = s->storage[s->current_address]; + if (value & ~current) { + DB_PRINT_L(-1, "Flipping bit from 0 => 1 (addr=0x%llx, value=0x%x, current=0x%x)\n", + s->current_address, value, current); + qemu_log_mask(LOG_GUEST_ERROR, "MT25Q: Flipping bit from 0 => 1\n"); + // if a bit in the flash is already a 0, leave it as a 0 + value &= current; + } + DB_PRINT_L(2, "Write 0x%"PRIx8" = 0x%"PRIx64, (uint8_t)value, s->current_address); + s->storage[s->current_address] = (uint8_t)value; + + flash_sync_dirty(s, page); + s->dirty_page = page; +} + +static uint32_t mt25q_transfer8(SSISlave *ss, uint32_t tx) +{ + Flash *s = MT25Q(ss); + uint32_t r = 0; + + switch (s->state) { + case STATE_COLLECT_CMD_DATA: + DB_PRINT_L(2, "Collected: 0x%"PRIx32, (uint32_t)tx); + s->cmd_data[s->pos++] = (uint8_t)tx; + if (s->pos == s->cmd_bytes) { + mt25q_handle_cmd_data(s); + } + break; + case STATE_WRITE: + if (s->current_address > s->size) { + DB_PRINT_L(-1, "MT25Q: Out of bounds flash write to 0x%"PRIx64"\n", s->current_address); + qemu_log_mask(LOG_GUEST_ERROR, + "MT25Q: Out of bounds flash write to 0x%"PRIx64"\n", s->current_address); + } else { + mt25q_write8(s, tx); + s->current_address += 1; + } + break; + case STATE_READ: + if (s->current_address > s->size) { + DB_PRINT_L(-1, "MT25Q: Out of bounds flash read from 0x%"PRIx64"\n", s->current_address); + qemu_log_mask(LOG_GUEST_ERROR, + "MT25Q: Out of bounds flash read from 0x%"PRIx64"\n", s->current_address); + } else { + DB_PRINT_L(2, "Read 0x%"PRIx64" = 0x%"PRIx8, s->current_address, (uint8_t)r); + r = s->storage[s->current_address]; + s->current_address = (s->current_address + 1) % s->size; + } + break; + case STATE_READ_QID: + r = MT25Q_ID[s->pos]; + DB_PRINT_L(1, "Read QID 0x%x (pos 0x%x)", (uint8_t)r, s->pos); + ++s->pos; + if (s->pos == s->len) { + s->pos = 0; + s->state = STATE_IDLE; + } + break; + case STATE_READ_REGISTER: + r = *s->current_register; + *s->current_register &= ~s->register_read_mask; + s->register_read_mask = 0; + s->state = STATE_IDLE; + DB_PRINT_L(2, "Read register"); + break; + case STATE_IDLE: + mt25q_decode_new_cmd(s, tx); + break; + } + + return r; +} + +static int mt25q_init(SSISlave *ss) +{ + DriveInfo *dinfo; + Flash *s = MT25Q(ss); + + s->state = STATE_IDLE; + s->size = FLASH_SECTOR_SIZE * FLASH_NUM_SECTORS; + s->page_size = FLASH_PAGE_SIZE; + s->dirty_page = -1; + s->STATUS_REG = 0; + + /* FIXME use a qdev drive property instead of drive_get() */ + dinfo = drive_get(IF_PFLASH, 0, 1); /* Use the 2nd -pflash drive */ + + if (dinfo) { + DB_PRINT_L(0, "Binding to IF_MTD drive"); + s->blk = blk_by_legacy_dinfo(dinfo); + blk_attach_dev_nofail(s->blk, s); + + s->storage = blk_blockalign(s->blk, s->size); + + int r = blk_read(s->blk, 0, s->storage, DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE)); + if (r < 0) { + fprintf(stderr, "Failed to initialize SPI flash (%d)!\n", r); + return 1; + } + } else { + DB_PRINT_L(-1, "No BDRV - binding to RAM"); + s->storage = blk_blockalign(NULL, s->size); + memset(s->storage, 0xFF, s->size); + } + return 0; +} + +static int mt25q_cs(SSISlave *ss, bool select) +{ + Flash *s = MT25Q(ss); + + if (select) { + s->len = 0; + s->pos = 0; + s->state = STATE_IDLE; + flash_sync_dirty(s, -1); + } + + DB_PRINT_L(2, "CS %s", select ? "HIGH" : "LOW"); + + return 0; +} + +static void mt25q_pre_save(void *opaque) +{ + flash_sync_dirty((Flash *)opaque, -1); +} + +static const VMStateDescription vmstate_mt25q = { + .name = "mt25q", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = mt25q_pre_save, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + } +}; + +static void mt25q_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(class); + SSISlaveClass *c = SSI_SLAVE_CLASS(class); + + c->init = mt25q_init; + c->transfer = mt25q_transfer8; + c->set_cs = mt25q_cs; + c->cs_polarity = SSI_CS_LOW; + dc->vmsd = &vmstate_mt25q; +} + +static const TypeInfo mt25q_info = { + .name = TYPE_MT25Q, + .parent = TYPE_SSI_SLAVE, + .instance_size = sizeof(Flash), + .class_size = sizeof(MT25QClass), + .abstract = true, +}; + +static void mt25q_register_types(void) +{ + type_register_static(&mt25q_info); + + TypeInfo ti = { + .name = "mt25q256", + .parent = TYPE_MT25Q, + .class_init = mt25q_class_init, + }; + type_register(&ti); +} + +type_init(mt25q_register_types) diff --git a/hw/block/mx25u.c b/hw/block/mx25u.c new file mode 100644 index 0000000000000..d27c498bd1b3d --- /dev/null +++ b/hw/block/mx25u.c @@ -0,0 +1,533 @@ +/* + * Emulate a QSPI flash device following the mx25u command set. + * Modelled after the m25p80 emulation found in hw/block/m25p80.c + */ + +#include "hw/hw.h" +#include "sysemu/block-backend.h" +#include "sysemu/blockdev.h" +#include "hw/ssi.h" + + +// TODO: These should be made configurable to support different flash parts +#define FLASH_SECTOR_SIZE (64 << 10) +#define FLASH_NUM_SECTORS (128) +#define FLASH_PAGE_SIZE (256) +const uint8_t MX25U_ID[] = { 0xc2, 0x25, 0x37 }; + +#ifndef MX25U_ERR_DEBUG +#define MX25U_ERR_DEBUG 0 +#endif + +// The usleep() helps MacOS stdout from freezing when printing a lot +#define DB_PRINT_L(level, ...) do { \ + if (MX25U_ERR_DEBUG > (level)) { \ + fprintf(stderr, "%d: %s: ", level, __func__); \ + fprintf(stderr, ## __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + usleep(1000); \ + } \ +} while (0); + +typedef enum { + WRITE_ENABLE = 0x06, + WRITE_DISABLE = 0x04, + + READ_STATUS_REG = 0x05, + READ_SCUR_REG = 0x2b, + + READ = 0x03, + FAST_READ = 0x0b, + QREAD = 0x6b, + READ_ID = 0x9f, + READ_QID = 0xaf, + + PAGE_PROGRAM = 0x02, + QPAGE_PROGRAM = 0x38, + + ERASE_SUBSECTOR = 0x20, // Erase 4k sector + ERASE_SECTOR = 0x52, // Erase 32k sector + ERASE_BLOCK = 0xd8, // Erase 64k block + ERASE_CHIP = 0xc7, + + ERASE_SUSPEND = 0xB0, + ERASE_RESUME = 0x30, + + DEEP_SLEEP = 0xb9, + WAKE = 0xab, + + QUAD_ENABLE = 0x35, + QUAD_DISABLE = 0xf5, +} FlashCmd; + +typedef enum { + STATE_IDLE, + + STATE_COLLECT_CMD_DATA, + + STATE_WRITE, + STATE_READ, + STATE_READ_ID, + STATE_READ_REGISTER, +} CMDState; + +#define R_SR_WIP (1 << 0) +#define R_SR_WEL (1 << 1) +#define R_SR_BP0 (1 << 2) +#define R_SR_BP1 (1 << 3) +#define R_SR_BP2 (1 << 4) +#define R_SR_BP3 (1 << 5) +#define R_SR_QE (1 << 6) +#define R_SR_SRWD (1 << 7) + +#define R_SCUR_SOTP (1 << 0) +#define R_SCUR_LDSO (1 << 1) +#define R_SCUR_PSB (1 << 2) +#define R_SCUR_ESB (1 << 3) +#define R_SCUR_PFAIL (1 << 5) +#define R_SCUR_EFAIL (1 << 6) +#define R_SCUR_WPSEL (1 << 7) + +typedef struct FLASH { + SSISlave parent_obj; + + //--- Storage --- + BlockBackend *blk; + uint8_t *storage; + uint32_t size; + int page_size; + + int64_t dirty_page; + + //--- Registers --- + uint8_t SR; + uint8_t SCUR; + + //--- Command state --- + CMDState state; + FlashCmd cmd_in_progress; + uint8_t cmd_data[4]; //! Commands can require up to 4 bytes of additional data + uint8_t cmd_bytes; //! Number of bytes required by command [0,4] + uint32_t len; + uint32_t pos; + uint64_t current_address; + + uint8_t *current_register; + uint8_t register_read_mask; //! mask to apply after reading current_register +} Flash; + +typedef struct M25P80Class { + SSISlaveClass parent_class; + //FlashPartInfo *pi; +} MX25UClass; + +#define TYPE_MX25U "mx25u-generic" +#define MX25U(obj) \ + OBJECT_CHECK(Flash, (obj), TYPE_MX25U) +#define MX25U_CLASS(klass) \ + OBJECT_CLASS_CHECK(MX25UClass, (klass), TYPE_MX25U) +#define MX25U_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MX25UClass, (obj), TYPE_MX25U) + +static void +blk_sync_complete(void *opaque, int ret) +{ + /* do nothing. Masters do not directly interact with the backing store, + * only the working copy so no mutexing required. + */ +} + +static void +mx25u_flash_sync_page(Flash *s, int page) +{ + int blk_sector, nb_sectors; + QEMUIOVector iov; + + if (!s->blk || blk_is_read_only(s->blk)) { + return; + } + + blk_sector = (page * s->page_size) / BDRV_SECTOR_SIZE; + nb_sectors = DIV_ROUND_UP(s->page_size, BDRV_SECTOR_SIZE); + qemu_iovec_init(&iov, 1); + qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE, + nb_sectors * BDRV_SECTOR_SIZE); + blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete, + NULL); +} + +static inline void +mx25u_flash_sync_area(Flash *s, int64_t off, int64_t len) +{ + int64_t start, end, nb_sectors; + QEMUIOVector iov; + + if (!s->blk || blk_is_read_only(s->blk)) { + return; + } + + assert(!(len % BDRV_SECTOR_SIZE)); + start = off / BDRV_SECTOR_SIZE; + end = (off + len) / BDRV_SECTOR_SIZE; + nb_sectors = end - start; + qemu_iovec_init(&iov, 1); + qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), + nb_sectors * BDRV_SECTOR_SIZE); + blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL); +} + +static inline void +flash_sync_dirty(Flash *s, int64_t newpage) +{ + if (s->dirty_page >= 0 && s->dirty_page != newpage) { + mx25u_flash_sync_page(s, s->dirty_page); + s->dirty_page = newpage; + } +} + +static void +mx25u_flash_erase(Flash *s, uint32_t offset, FlashCmd cmd) +{ + uint32_t len; + + switch (cmd) { + case ERASE_SUBSECTOR: // Erase 4k sector + len = 4 << 10; + break; + case ERASE_SECTOR: // Erase 32k sector + len = 32 << 10; + break; + case ERASE_BLOCK: // Erase 64k block + len = 64 << 10; + break; + case ERASE_CHIP: + len = s->size; + break; + default: + abort(); + } + + DB_PRINT_L(0, "erase offset = %#x, len = %d", offset, len); + + if (!(s->SR & R_SR_WEL)) { + qemu_log_mask(LOG_GUEST_ERROR, "MX25U: erase with write protect!\n"); + return; + } + + memset(s->storage + offset, 0xff, len); + mx25u_flash_sync_area(s, offset, len); +} + +static void +mx25u_decode_new_cmd(Flash *s, uint32_t value) +{ + s->cmd_in_progress = value; + DB_PRINT_L(0, "decoding new command: 0x%x", value); + + switch (value) { + case WRITE_ENABLE: + s->SR |= R_SR_WEL; + s->state = STATE_IDLE; + break; + case WRITE_DISABLE: + s->SR &= ~R_SR_WEL; + s->state = STATE_IDLE; + break; + + case READ_STATUS_REG: + s->current_register = &s->SR; + s->state = STATE_READ_REGISTER; + break; + case READ_SCUR_REG: + s->current_register = &s->SCUR; + s->state = STATE_READ_REGISTER; + break; + + case READ: + case FAST_READ: + case QREAD: + s->cmd_bytes = 3; + s->pos = 0; + s->state = STATE_COLLECT_CMD_DATA; + break; + + case READ_ID: + case READ_QID: + s->cmd_bytes = 0; + s->state = STATE_READ_ID; + s->len = 3; + s->pos = 0; + break; + + case PAGE_PROGRAM: + case QPAGE_PROGRAM: + s->pos = 0; + s->cmd_bytes = 3; + s->state = STATE_COLLECT_CMD_DATA; + break; + + case ERASE_SUBSECTOR: + case ERASE_SECTOR: + case ERASE_BLOCK: + s->pos = 0; + s->cmd_bytes = 3; + s->state = STATE_COLLECT_CMD_DATA; + break; + + case ERASE_CHIP: + mx25u_flash_erase(s, 0, ERASE_CHIP); + s->SR |= R_SR_WIP; + s->register_read_mask = R_SR_WIP; + s->state = STATE_IDLE; + break; + + case ERASE_SUSPEND: + case ERASE_RESUME: + break; + + case DEEP_SLEEP: + case WAKE: + break; + + case QUAD_ENABLE: + case QUAD_DISABLE: + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, "MX25U: Unknown cmd 0x%x\n", value); + } +} + +static void +mx25u_handle_cmd_data(Flash *s) +{ + s->current_address = (s->cmd_data[2] << 16) | (s->cmd_data[1] << 8) | (s->cmd_data[0]); + s->state = STATE_IDLE; + + switch (s->cmd_in_progress) { + case PAGE_PROGRAM: + case QPAGE_PROGRAM: + s->state = STATE_WRITE; + break; + case READ_STATUS_REG: + case READ_SCUR_REG: + assert(false); + break; + case READ: + case FAST_READ: + case QREAD: + DB_PRINT_L(1, "Read From: 0x%"PRIu64, s->current_address); + s->state = STATE_READ; + break; + case ERASE_SUBSECTOR: + case ERASE_SECTOR: + case ERASE_BLOCK: + mx25u_flash_erase(s, s->current_address, s->cmd_in_progress); + s->SR |= R_SR_WIP; + s->register_read_mask = R_SR_WIP; + break; + + case ERASE_SUSPEND: + case ERASE_RESUME: + break; + + case ERASE_CHIP: + default: + break; + } +} + +static void +mx25u_write8(Flash *s, uint8_t value) +{ + int64_t page = s->current_address / s->page_size; + + // TODO: Write protection + + uint8_t current = s->storage[s->current_address]; + if (value & ~current) { + qemu_log_mask(LOG_GUEST_ERROR, "MX25U: Flipping bit from 0 => 1\n"); + // if a bit in the flash is already a 0, leave it as a 0 + value &= current; + } + DB_PRINT_L(1, "Write 0x%"PRIx8" = 0x%"PRIx64, (uint8_t)value, s->current_address); + s->storage[s->current_address] = (uint8_t)value; + + flash_sync_dirty(s, page); + s->dirty_page = page; +} + +static uint32_t +mx25u_transfer8(SSISlave *ss, uint32_t tx) +{ + Flash *s = MX25U(ss); + uint32_t r = 0; + + switch (s->state) { + case STATE_COLLECT_CMD_DATA: + DB_PRINT_L(2, "Collected: 0x%"PRIx32, (uint32_t)tx); + s->cmd_data[s->pos++] = (uint8_t)tx; + if (s->pos == s->cmd_bytes) { + mx25u_handle_cmd_data(s); + } + break; + case STATE_WRITE: + if (s->current_address > s->size) { + qemu_log_mask(LOG_GUEST_ERROR, + "MX25U: Out of bounds flash write to 0x%"PRIx64"\n", s->current_address); + } else { + mx25u_write8(s, tx); + s->current_address += 1; + } + break; + case STATE_READ: + if (s->current_address > s->size) { + qemu_log_mask(LOG_GUEST_ERROR, + "MX25U: Out of bounds flash read from 0x%"PRIx64"\n", s->current_address); + } else { + DB_PRINT_L(1, "Read 0x%"PRIx64" = 0x%"PRIx8, s->current_address, (uint8_t)r); + r = s->storage[s->current_address]; + s->current_address = (s->current_address + 1) % s->size; + } + break; + case STATE_READ_ID: + r = MX25U_ID[s->pos]; + DB_PRINT_L(2, "Read ID 0x%x (pos 0x%x)", (uint8_t)r, s->pos); + ++s->pos; + if (s->pos == s->len) { + s->pos = 0; + s->state = STATE_IDLE; + } + break; + case STATE_READ_REGISTER: + r = *s->current_register; + *s->current_register &= ~s->register_read_mask; + s->register_read_mask = 0; + s->state = STATE_IDLE; + DB_PRINT_L(1, "Read register"); + break; + case STATE_IDLE: + mx25u_decode_new_cmd(s, tx); + break; + } + + return r; +} + +static int +mx25u_init(SSISlave *ss) +{ + DriveInfo *dinfo; + Flash *s = MX25U(ss); + + s->state = STATE_IDLE; + s->size = FLASH_SECTOR_SIZE * FLASH_NUM_SECTORS; + s->page_size = FLASH_PAGE_SIZE; + s->dirty_page = -1; + s->SR = 0; + + /* FIXME use a qdev drive property instead of drive_get_next() */ + dinfo = drive_get_next(IF_MTD); + + if (dinfo) { + DB_PRINT_L(0, "Binding to IF_MTD drive"); + s->blk = blk_by_legacy_dinfo(dinfo); + blk_attach_dev_nofail(s->blk, s); + + s->storage = blk_blockalign(s->blk, s->size); + + /* FIXME: Move to late init */ + if (blk_read(s->blk, 0, s->storage, + DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE))) { + fprintf(stderr, "Failed to initialize SPI flash!\n"); + return 1; + } + } else { + DB_PRINT_L(0, "No BDRV - binding to RAM"); + s->storage = blk_blockalign(NULL, s->size); + memset(s->storage, 0xFF, s->size); + } + return 0; +} + +static int +mx25u_cs(SSISlave *ss, bool select) +{ + Flash *s = MX25U(ss); + + if (select) { + s->len = 0; + s->pos = 0; + s->state = STATE_IDLE; + flash_sync_dirty(s, -1); + } + + DB_PRINT_L(0, "CS %s", select ? "HIGH" : "LOW"); + + return 0; +} + +static void +mx25u_pre_save(void *opaque) +{ + flash_sync_dirty((Flash *)opaque, -1); +} + +static const VMStateDescription vmstate_mx25u = { + .name = "mx25u", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = mx25u_pre_save, + .fields = (VMStateField[]) { +#if 0 + VMSTATE_UINT8(SR, Flash), + VMSTATE_UINT8(SCUR, Flash), + VMSTATE_UINT8(state, Flash), + VMSTATE_UINT8_ARRAY(cmd_data, Flash, 4), + VMSTATE_UINT8(cmd_bytes, Flash), + VMSTATE_UINT32(len, Flash), + VMSTATE_UINT32(pos, Flash), + VMSTATE_UINT32(current_address, Flash), + VMSTATE_UINT8(cmd_in_progress, Flash), +#endif + VMSTATE_END_OF_LIST() + } +}; + +static void +mx25u_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(class); + SSISlaveClass *c = SSI_SLAVE_CLASS(class); + + c->init = mx25u_init; + c->transfer = mx25u_transfer8; + c->set_cs = mx25u_cs; + c->cs_polarity = SSI_CS_LOW; + dc->vmsd = &vmstate_mx25u; + //mc->pi = data; +} + +static const TypeInfo mx25u_info = { + .name = TYPE_MX25U, + .parent = TYPE_SSI_SLAVE, + .instance_size = sizeof(Flash), + .class_size = sizeof(MX25UClass), + .abstract = true, +}; + +static void +mx25u_register_types(void) +{ + type_register_static(&mx25u_info); + + TypeInfo ti = { + .name = "mx25u6435f", + .parent = TYPE_MX25U, + .class_init = mx25u_class_init, + //.class_data = (void *) + }; + type_register(&ti); +} + +type_init(mx25u_register_types) diff --git a/hw/block/pflash_jedec_424.c b/hw/block/pflash_jedec_424.c new file mode 100644 index 0000000000000..8313e84570b9d --- /dev/null +++ b/hw/block/pflash_jedec_424.c @@ -0,0 +1,1073 @@ +/* + * CFI parallel flash with Jedec (42.4) command set emulation + * + * Copyright (c) 2006 Thorsten Zitterell + * Copyright (c) 2005 Jocelyn Mayer + * + * 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 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 . + */ + +/* + * For now, this code can emulate flashes of 1, 2 or 4 bytes width. + * Supported commands/modes are: + * - flash read + * - flash write + * - flash ID read + * - sector erase + * - CFI queries + * + * It does not support timings + * It does not support flash interleaving + * It does not implement software data protection as found in many real chips + * It does not implement erase suspend/resume commands + * It does not implement multiple sectors erase + * + * It does not implement much more ... + */ + +#include "hw/hw.h" +#include "hw/block/flash.h" +#include "block/block.h" +#include "block/block_int.h" +#include "sysemu/block-backend.h" +#include "qemu/bitops.h" +#include "exec/address-spaces.h" +#include "qemu/host-utils.h" +#include "hw/sysbus.h" + +#define PFLASH_BUG(fmt, ...) \ +do { \ + fprintf(stderr, "PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \ + exit(1); \ +} while(0) + +//#define PFLASH_DEBUG +#ifdef PFLASH_DEBUG +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ +do { \ + printf("PFLASH: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ +} while (0) +#else +#define DPRINTF(fmt, ...) do { } while (0) +#endif + +#define TYPE_CFI_PFLASH_JEDEC_424 "cfi.pflash.jedec-42.4" +#define CFI_PFLASH_JEDEC(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH_JEDEC_424) + +#define PFLASH_MAX_BANKS 8 + +struct pflash_t { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + BlockBackend *blk; + uint32_t nb_blocs; + uint64_t sector_len; + uint8_t bank_width; + uint8_t device_width; /* If 0, device width not specified. */ + uint8_t max_device_width; /* max device width in bytes */ + uint32_t bank_size; /* size of each bank */ + uint8_t be; + int ro; + uint8_t wcycle[PFLASH_MAX_BANKS]; // which write-cycle this bank is in + uint8_t cmd[PFLASH_MAX_BANKS]; // which command we're processing + uint8_t global_cmd; // some operations don't have separate bank states + uint8_t status; + uint16_t ident0; + uint16_t ident1; + uint16_t ident2; + uint16_t ident3; + uint8_t cfi_len; + uint8_t cfi_table[0x60]; + uint64_t counter; + unsigned int writeblock_size; + MemoryRegion mem; + char *name; + void *storage; + uint16_t configuration_register; +}; + +static const VMStateDescription vmstate_pflash = { + .name = "pflash_jedec_424", + .version_id = 2, + .minimum_version_id = 2, + .fields = (VMStateField[]) { + VMSTATE_UINT8_ARRAY(wcycle, pflash_t, PFLASH_MAX_BANKS), + VMSTATE_UINT8_ARRAY(cmd, pflash_t, PFLASH_MAX_BANKS), + VMSTATE_UINT8(global_cmd, pflash_t), + VMSTATE_UINT8(status, pflash_t), + VMSTATE_UINT64(counter, pflash_t), + VMSTATE_END_OF_LIST() + } +}; + +static void pflash_reset_state(struct pflash_t* pfl) +{ + memset(pfl->wcycle, 0, sizeof(pfl->wcycle)); + memset(pfl->cmd, 0, sizeof(pfl->cmd)); + pfl->global_cmd = 0; +} + +/* Perform a CFI query based on the bank width of the flash. + * If this code is called we know we have a device_width set for + * this flash. + */ +static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) +{ + int i; + uint32_t resp = 0; + hwaddr boff; + + /* Adjust incoming offset to match expected device-width + * addressing. CFI query addresses are always specified in terms of + * the maximum supported width of the device. This means that x8 + * devices and x8/x16 devices in x8 mode behave differently. For + * devices that are not used at their max width, we will be + * provided with addresses that use higher address bits than + * expected (based on the max width), so we will shift them lower + * so that they will match the addresses used when + * device_width==max_device_width. + */ + boff = offset >> (ctz32(pfl->bank_width) + + ctz32(pfl->max_device_width) - ctz32(pfl->device_width)); + + if (boff > pfl->cfi_len) { + return 0; + } + /* Now we will construct the CFI response generated by a single + * device, then replicate that for all devices that make up the + * bus. For wide parts used in x8 mode, CFI query responses + * are different than native byte-wide parts. + */ + resp = pfl->cfi_table[boff]; + if (pfl->device_width != pfl->max_device_width) { + /* The only case currently supported is x8 mode for a + * wider part. + */ + if (pfl->device_width != 1 || pfl->bank_width > 4) { + DPRINTF("%s: Unsupported device configuration: " + "device_width=%d, max_device_width=%d\n", + __func__, pfl->device_width, + pfl->max_device_width); + return 0; + } + /* CFI query data is repeated, rather than zero padded for + * wide devices used in x8 mode. + */ + for (i = 1; i < pfl->max_device_width; i++) { + resp = deposit32(resp, 8 * i, 8, pfl->cfi_table[boff]); + } + } + /* Replicate responses for each device in bank. */ + if (pfl->device_width < pfl->bank_width) { + for (i = pfl->device_width; + i < pfl->bank_width; i += pfl->device_width) { + resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp); + } + } + + return resp; +} + + + +/* Perform a device id query based on the bank width of the flash. */ +static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) +{ + int i; + uint32_t resp; + hwaddr boff; + + /* Adjust incoming offset to match expected device-width + * addressing. Device ID read addresses are always specified in + * terms of the maximum supported width of the device. This means + * that x8 devices and x8/x16 devices in x8 mode behave + * differently. For devices that are not used at their max width, + * we will be provided with addresses that use higher address bits + * than expected (based on the max width), so we will shift them + * lower so that they will match the addresses used when + * device_width==max_device_width. + */ + boff = offset >> (ctz32(pfl->bank_width) + + ctz32(pfl->max_device_width) - ctz32(pfl->device_width)); + + /* Mask off upper bits which may be used in to query block + * or sector lock status at other addresses. + * Offsets 2/3 are block lock status, is not emulated. + */ + switch (boff & 0xFF) { + case 0: + resp = pfl->ident0; + DPRINTF("%s: Manufacturer Code %04x\n", __func__, resp); + break; + case 1: + resp = pfl->ident1; + DPRINTF("%s: Device ID Code %04x\n", __func__, resp); + break; + default: + DPRINTF("%s: Read Device Information offset=%x\n", __func__, + (unsigned)offset); + return 0; + break; + } + /* Replicate responses for each device in bank. */ + if (pfl->device_width < pfl->bank_width) { + for (i = pfl->device_width; + i < pfl->bank_width; i += pfl->device_width) { + resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp); + } + } + + return resp; +} + +static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, + int width, int be) +{ + hwaddr boff; + uint32_t ret; + uint8_t *p; + + ret = -1; + + uint8_t bank = offset / pfl->bank_size; + + //DPRINTF("%s: reading offset " TARGET_FMT_plx " under cmd %02x width %d\n", + // __func__, offset, pfl->cmd[bank], width); + + switch (pfl->cmd[bank]) { + default: + /* This should never happen : reset state & treat it as a read */ + fprintf(stderr, "%s: unknown command state: %x\n", __func__, pfl->cmd[bank]); + pfl->wcycle[bank] = 0; + pfl->cmd[bank] = 0; + pfl->global_cmd = 0; + /* fall through to read code */ + case 0x00: + /* Flash area read */ + p = pfl->storage; + switch (width) { + case 1: + ret = p[offset]; + //DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n", + // __func__, offset, ret); + break; + case 2: + if (be) { + ret = p[offset] << 8; + ret |= p[offset + 1]; + } else { + ret = p[offset]; + ret |= p[offset + 1] << 8; + } + //DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n", + // __func__, offset, ret); + break; + case 4: + if (be) { + ret = p[offset] << 24; + ret |= p[offset + 1] << 16; + ret |= p[offset + 2] << 8; + ret |= p[offset + 3]; + } else { + ret = p[offset]; + ret |= p[offset + 1] << 8; + ret |= p[offset + 2] << 16; + ret |= p[offset + 3] << 24; + } + //DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n", + // __func__, offset, ret); + break; + default: + DPRINTF("BUG in %s\n", __func__); + } + + break; + case 0x70: /* Status Register */ + /* Status register read. Return status from each device in + * bank. + */ + ret = pfl->status; + if (pfl->device_width && width > pfl->device_width) { + int shift = pfl->device_width * 8; + while (shift + pfl->device_width * 8 <= width * 8) { + ret |= pfl->status << shift; + shift += pfl->device_width * 8; + } + } else if (!pfl->device_width && width > 2) { + /* Handle 32 bit flash cases where device width is not + * set. (Existing behavior before device width added.) + */ + ret |= pfl->status << 16; + } + DPRINTF("%s: status %x\n", __func__, ret); + pfl->cmd[bank] = 0; + break; + case 0x90: + if (!pfl->device_width) { + /* Preserve old behavior if device width not specified */ + boff = offset & 0xFF; + if (pfl->bank_width == 2) { + boff = boff >> 1; + } else if (pfl->bank_width == 4) { + boff = boff >> 2; + } + + switch (boff) { + case 0: + ret = pfl->ident0 << 8 | pfl->ident1; + DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret); + break; + case 1: + ret = pfl->ident2 << 8 | pfl->ident3; + DPRINTF("%s: Device ID Code %04x\n", __func__, ret); + break; + default: + DPRINTF("%s: Read Device Information boff=%x\n", __func__, + (unsigned)boff); + ret = 0; + break; + } + } else { + /* If we have a read larger than the bank_width, combine multiple + * manufacturer/device ID queries into a single response. + */ + int i; + for (i = 0; i < width; i += pfl->bank_width) { + ret = deposit32(ret, i * 8, pfl->bank_width * 8, + pflash_devid_query(pfl, + offset + i * pfl->bank_width)); + } + } + break; + case 0x98: /* Query mode */ + if (!pfl->device_width) { + /* Preserve old behavior if device width not specified */ + boff = offset & 0xFF; + if (pfl->bank_width == 2) { + boff = boff >> 1; + } else if (pfl->bank_width == 4) { + boff = boff >> 2; + } + + if (boff > pfl->cfi_len) { + ret = 0; + } else { + ret = pfl->cfi_table[boff]; + } + } else { + /* If we have a read larger than the bank_width, combine multiple + * CFI queries into a single response. + */ + int i; + for (i = 0; i < width; i += pfl->bank_width) { + ret = deposit32(ret, i * 8, pfl->bank_width * 8, + pflash_cfi_query(pfl, + offset + i * pfl->bank_width)); + } + } + + break; + + case 0xd0: /* Configuration register */ + ret = pfl->configuration_register; /* default configuration */ + break; + } + + //DPRINTF("%s: returning 0x%x\n", __func__, ret); + return ret; +} + +/* update flash content on disk */ +static void pflash_update(pflash_t *pfl, int offset, + int size) +{ + int offset_end; + if (pfl->blk) { + offset_end = offset + size; + /* round to sectors */ + offset = offset >> 9; + offset_end = (offset_end + 511) >> 9; + blk_write(pfl->blk, offset, pfl->storage + (offset << 9), + offset_end - offset); + } +} + +static inline void pflash_data_write(pflash_t *pfl, hwaddr offset, + uint32_t value, int width, int be) +{ + uint8_t *p = pfl->storage; + + DPRINTF("%s: block write offset " TARGET_FMT_plx + " value %x width %d counter %016" PRIx64 "\n", + __func__, offset, value, width, pfl->counter); + + // NOTE: Flash can only flip 1's to 0's, so use a &= operation to update the + // flash contents. This is critical because some drivers assume they can write + // 0xFF to preserve the original value. + switch (width) { + case 1: + p[offset] &= value; + break; + case 2: + if (be) { + p[offset] &= value >> 8; + p[offset + 1] &= value; + } else { + p[offset] &= value; + p[offset + 1] &= value >> 8; + } + break; + case 4: + if (be) { + p[offset] &= value >> 24; + p[offset + 1] &= value >> 16; + p[offset + 2] &= value >> 8; + p[offset + 3] &= value; + } else { + p[offset] &= value; + p[offset + 1] &= value >> 8; + p[offset + 2] &= value >> 16; + p[offset + 3] &= value >> 24; + } + break; + } + +} + +static void pflash_write(pflash_t *pfl, hwaddr offset, + uint32_t value, int width, int be) +{ + uint8_t cmd; + int i; + uint8_t *p; + + cmd = value; + + uint8_t bank = pfl->global_cmd ? 0 : offset / pfl->bank_size; + uint32_t sector_offset = offset & (pfl->sector_len - 1); + sector_offset = sector_offset >> (pfl->bank_width - 1); + + DPRINTF("%s: writing offset 0x%llx sector offset 0x%x value 0x%x width %d " + "pfl->wcycle %d pfl->cmd 0x%x\n", __func__, offset, sector_offset, value, width, + pfl->wcycle[bank], pfl->cmd[bank]); + + if (!pfl->wcycle[bank]) { + /* Set the device in I/O access mode */ + memory_region_rom_device_set_romd(&pfl->mem, false); + } + + switch (pfl->wcycle[bank]) { + case 0: + /* read mode */ + switch (cmd) { + case 0x00: /* ??? */ + goto reset_bank; + case 0x25: + DPRINTF("%s: Program to buffer\n", __func__); + pfl->status |= 0x80; /* Ready! */ + break; + // Not implemented: 0x29 Buffer to Flash + // Not implemented: 0x30 Erase Resume + case 0x33: + DPRINTF("%s: Blank check\n", __func__); + // Is it blank? + pfl->status |= 0x80; /* Ready! */ + pfl->status &= ~0x20; /* clear non-erased bit */ + uint8_t *p = pfl->storage; + offset &= ~(pfl->sector_len - 1); + p += offset; + for (i=0; isector_len; i++) { + if (p[i] != 0xFF) { + pfl->status |= 0x20; // Not erased + break; + } + } + goto reset_bank; + // Not implemented: 0x40 SSR Lock Entry + // Not implemented: 0x50 Program Resume + // Not implemented: 0x51 Program Suspend + case 0x60: /* Sector Lock/Unlock */ + pfl->global_cmd = 0x60; + bank = 0; + DPRINTF("%s: Sector Lock/Unlock\n", __func__); + break; + case 0x70: /* Status Register */ + DPRINTF("%s: Read status register\n", __func__); + pfl->cmd[bank] = cmd; + return; + case 0x71: /* Clear status bits */ + DPRINTF("%s: Clear status bits\n", __func__); + pfl->status = 0x80; // set device ready bit + goto reset_bank; + case 0x80: /* Erase setup */ + DPRINTF("%s: Erase setup\n", __func__); + break; + // Not implemented: 0x88 Secure Silicon Region Entry + case 0x90: /* Read Device ID */ + DPRINTF("%s: Read Device information\n", __func__); + pfl->cmd[bank] = cmd; + return; + case 0x98: /* CFI query */ + DPRINTF("%s: CFI query\n", __func__); + break; + // Not implemented: 0xB0 Erase Suspend + case 0xd0: /* Enter configuration register */ + DPRINTF("%s: Configuration register enter\n", __func__); + break; + case 0xf0: /* Reset */ + DPRINTF("%s: Reset\n", __func__); + pflash_reset_state(pfl); + goto reset_bank; + case 0xff: /* Read array mode */ + DPRINTF("%s: Read array mode\n", __func__); + goto reset_bank; + default: + goto error_flash; + } + pfl->wcycle[bank]++; + pfl->cmd[bank] = cmd; + break; + + case 1: + switch (pfl->cmd[bank]) { + case 0x25: + /* Mask writeblock size based on device width, or bank width if + * device width not specified. + */ + pfl->counter = value + 1; + DPRINTF("%s: Program to buffer of %lld words\n", __func__, pfl->counter); + pfl->wcycle[bank]++; + break; + case 0x60: /* Sector Lock... Expecting 0x288 = 60 */ + if (cmd == 0x60) { + pfl->cmd[bank] = 0x60; + pfl->wcycle[bank]++; + } else { + goto reset_bank; + } + break; + case 0x80: + if (sector_offset == 0x2aa && cmd == 0x30) { + // sector erase + offset &= ~(pfl->sector_len - 1); + DPRINTF("%s: sector erase at " TARGET_FMT_plx " bytes %x\n", + __func__, offset, (unsigned)pfl->sector_len); + + if (!pfl->ro) { + p = pfl->storage; + memset(p + offset, 0xff, pfl->sector_len); + pflash_update(pfl, offset, pfl->sector_len); + pfl->status &= ~0x20; /* clear non-erased bit */ + } else { + pfl->status |= 0x20; /* Block erase error */ + } + pfl->status |= 0x80; /* Ready! */ + } else if (sector_offset == 0x2aa && cmd == 0x10) { + DPRINTF("%s: chip erase", __func__); + if (!pfl->ro) { + memset(pfl->storage, 0xff, pfl->sector_len * pfl->nb_blocs); + pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs); + pfl->status &= ~0x20; /* clear non-erased bit */ + } else { + pfl->status |= 0x20; /* Block erase error */ + } + pfl->status |= 0x80; /* Ready! */ + } else { + DPRINTF("%s: Unexpected command byte: 0x%x\n", __func__, cmd); + } + goto reset_bank; + break; + case 0x98: + if (cmd == 0xf0) { + DPRINTF("%s: leaving query mode\n", __func__); + goto reset_bank; + } else { + DPRINTF("%s: Unexpected command byte: 0x%x\n", __func__, cmd); + goto reset_bank; + } + case 0xd0: + if (cmd == 0xf0) { + DPRINTF("%s: leaving configuration register mode\n", __func__); + pfl->status |= 0x80; + goto reset_bank; + } else if (cmd == 0x25) { + /* program to buffer */ + DPRINTF("%s: 2nd byte of program to config register buffer\n", __func__); + pfl->wcycle[bank]++; + } else if (cmd == 0x29) { + DPRINTF("%s: program config register buffer to flash \n", __func__); + pfl->wcycle[bank] = 1; + } else { + DPRINTF("%s: Unexpected command byte: 0x%x\n", __func__, cmd); + goto reset_bank; + } + break; + default: + goto error_flash; + } + break; + + case 2: + switch (pfl->cmd[bank]) { + case 0x25: /* Program to buffer */ + if (!pfl->ro) { + DPRINTF("%s: Programming %d bytes at " TARGET_FMT_plx " to 0x%x\n", __func__, + width, offset, value); + pflash_data_write(pfl, offset, value, width, be); + } else { + pfl->status |= 0x10; /* Programming error */ + } + pfl->status |= 0x80; + + pfl->counter--; + if (!pfl->counter) { + hwaddr mask = pfl->writeblock_size - 1; + mask = ~mask; + + DPRINTF("%s: Programming finished\n", __func__); + pfl->wcycle[bank]++; + if (!pfl->ro) { + /* Flush the entire write buffer onto backing storage. */ + pflash_update(pfl, offset & mask, pfl->writeblock_size); + } else { + pfl->status |= 0x10; /* Programming error */ + } + } + + break; + case 0xd0: + if (sector_offset == 0x2aa && cmd == 0) { + DPRINTF("%s: 3rd byte of program to config register buffer\n", __func__); + pfl->wcycle[bank]++; + } else { + DPRINTF("%s: Unexpected command byte: 0x%x\n", __func__, cmd); + goto reset_bank; + } + break; + case 0x60: /* Sector Lock... expecting SLA = 0x60 (lock/unlock) or SLA = 0x61 (range) */ + // we don't implement locking but we should at least accept the command + if (cmd == 0x60) { + DPRINTF("%s: 3rd byte of Sector Lock\n", __func__); + goto reset_bank; // command is finished + } else if (cmd == 0x61) { // 0X61 multi sector lock + pfl->wcycle[bank]++; + pfl->cmd[bank] = 0x61; + } else { + goto error_flash; + } + break; + default: + goto error_flash; + } + break; + + case 3: /* Confirm mode */ + switch (pfl->cmd[bank]) { + case 0x25: /* Block write */ + if (cmd == 0x29 && sector_offset == 0x555) { + pfl->wcycle[bank] = 0; + pfl->status |= 0x80; + } else { + PFLASH_BUG("%s: unknown command for Programming\n", __func__); + goto reset_bank; + } + break; + case 0x61: /* Sector Lock... expecting SLA = 0x61 */ + // we don't implement locking but we should at least accept the command + if (cmd == 0x61) { + DPRINTF("%s: 4th byte of Sector Lock\n", __func__); + goto reset_bank; // command is finished + } + goto error_flash; + break; + case 0xd0: + if (sector_offset == 0) { + pfl->configuration_register = value; + DPRINTF("%s: setting new config regsistr: 0x%x\n", __func__, value); + pfl->wcycle[bank] = 1; + } else { + DPRINTF("%s: Unexpected command byte: 0x%x\n", __func__, cmd); + goto reset_bank; + } + break; + default: + goto error_flash; + } + break; + default: + /* Should never happen */ + DPRINTF("%s: invalid write state\n", __func__); + goto reset_bank; + } + return; + + error_flash: + fprintf(stderr, "PFLASH %s: Unimplemented flash cmd sequence " + "(offset 0x%llx sector offset 0x%x, bank %u pfl->wcycle %d pfl->cmd 0x%x value 0x%x)" + "\n", __func__, offset, sector_offset, bank, pfl->wcycle[bank], pfl->cmd[bank], value); + + reset_bank: + memory_region_rom_device_set_romd(&pfl->mem, true); + + pfl->wcycle[bank] = 0; + pfl->cmd[bank] = 0; + pfl->global_cmd = 0; +} + + +static uint32_t pflash_readb_be(void *opaque, hwaddr addr) +{ + return pflash_read(opaque, addr, 1, 1); +} + +static uint32_t pflash_readb_le(void *opaque, hwaddr addr) +{ + return pflash_read(opaque, addr, 1, 0); +} + +static uint32_t pflash_readw_be(void *opaque, hwaddr addr) +{ + pflash_t *pfl = opaque; + + return pflash_read(pfl, addr, 2, 1); +} + +static uint32_t pflash_readw_le(void *opaque, hwaddr addr) +{ + pflash_t *pfl = opaque; + + return pflash_read(pfl, addr, 2, 0); +} + +static uint32_t pflash_readl_be(void *opaque, hwaddr addr) +{ + pflash_t *pfl = opaque; + + return pflash_read(pfl, addr, 4, 1); +} + +static uint32_t pflash_readl_le(void *opaque, hwaddr addr) +{ + pflash_t *pfl = opaque; + + return pflash_read(pfl, addr, 4, 0); +} + +static void pflash_writeb_be(void *opaque, hwaddr addr, + uint32_t value) +{ + pflash_write(opaque, addr, value, 1, 1); +} + +static void pflash_writeb_le(void *opaque, hwaddr addr, + uint32_t value) +{ + pflash_write(opaque, addr, value, 1, 0); +} + +static void pflash_writew_be(void *opaque, hwaddr addr, + uint32_t value) +{ + pflash_t *pfl = opaque; + + pflash_write(pfl, addr, value, 2, 1); +} + +static void pflash_writew_le(void *opaque, hwaddr addr, + uint32_t value) +{ + pflash_t *pfl = opaque; + + pflash_write(pfl, addr, value, 2, 0); +} + +static void pflash_writel_be(void *opaque, hwaddr addr, + uint32_t value) +{ + pflash_t *pfl = opaque; + + pflash_write(pfl, addr, value, 4, 1); +} + +static void pflash_writel_le(void *opaque, hwaddr addr, + uint32_t value) +{ + pflash_t *pfl = opaque; + + pflash_write(pfl, addr, value, 4, 0); +} + +static const MemoryRegionOps pflash_jedec_ops_be = { + .old_mmio = { + .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, + .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static const MemoryRegionOps pflash_jedec_ops_le = { + .old_mmio = { + .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, + .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void pflash_jedec_realize(DeviceState *dev, Error **errp) +{ + pflash_t *pfl = CFI_PFLASH_JEDEC(dev); + uint64_t total_len; + int ret; + uint64_t blocks_per_device, device_len; + int num_devices; + + total_len = pfl->sector_len * pfl->nb_blocs; + + /* These are only used to expose the parameters of each device + * in the cfi_table[]. + */ + num_devices = pfl->device_width ? (pfl->bank_width / pfl->device_width) : 1; + blocks_per_device = pfl->nb_blocs / num_devices; + device_len = pfl->sector_len * blocks_per_device; + + memory_region_init_rom_device( + &pfl->mem, OBJECT(dev), + pfl->be ? &pflash_jedec_ops_be : &pflash_jedec_ops_le, pfl, + pfl->name, total_len, errp); + vmstate_register_ram(&pfl->mem, DEVICE(pfl)); + pfl->storage = memory_region_get_ram_ptr(&pfl->mem); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem); + + if (pfl->blk) { + /* read the initial flash content */ + ret = blk_read(pfl->blk, 0, pfl->storage, total_len >> 9); + + if (ret < 0) { + vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); + error_setg(errp, "failed to read the initial flash content"); + return; + } + } + + if (pfl->blk) { + pfl->ro = blk_is_read_only(pfl->blk); + } else { + pfl->ro = 0; + } + + /* Default to devices being used at their maximum device width. This was + * assumed before the device_width support was added. + */ + if (!pfl->max_device_width) { + pfl->max_device_width = pfl->device_width; + } + + pfl->configuration_register = 0xdf48; + + pflash_reset_state(pfl); + pfl->status = 0; + /* Hardcoded CFI table */ + pfl->cfi_len = 0x52; + /* Standard "QRY" string */ + pfl->cfi_table[0x10] = 'Q'; + pfl->cfi_table[0x11] = 'R'; + pfl->cfi_table[0x12] = 'Y'; + /* Command set (JEDEC 42.4) */ + pfl->cfi_table[0x13] = 0x02; + pfl->cfi_table[0x14] = 0x00; + /* Primary extended table address (none) */ + pfl->cfi_table[0x15] = 0x40; + pfl->cfi_table[0x16] = 0x00; + /* Alternate command set (none) */ + pfl->cfi_table[0x17] = 0x00; + pfl->cfi_table[0x18] = 0x00; + /* Alternate extended table (none) */ + pfl->cfi_table[0x19] = 0x00; + pfl->cfi_table[0x1A] = 0x00; + /* Vcc min */ + pfl->cfi_table[0x1B] = 0x17; + /* Vcc max */ + pfl->cfi_table[0x1C] = 0x19; + /* Vpp min (no Vpp pin) */ + pfl->cfi_table[0x1D] = 0x00; + /* Vpp max (no Vpp pin) */ + pfl->cfi_table[0x1E] = 0x00; + /* Reserved */ + pfl->cfi_table[0x1F] = 0x04; + /* Timeout for min size buffer write */ + pfl->cfi_table[0x20] = 0x09; + /* Typical timeout for block erase */ + pfl->cfi_table[0x21] = 0x0a; + /* Typical timeout for full chip erase (4096 ms) */ + pfl->cfi_table[0x22] = 0x11; + /* Reserved */ + pfl->cfi_table[0x23] = 0x04; + /* Max timeout for buffer write */ + pfl->cfi_table[0x24] = 0x02; + /* Max timeout for block erase */ + pfl->cfi_table[0x25] = 0x03; + /* Max timeout for chip erase */ + pfl->cfi_table[0x26] = 0x00; + /* Device size */ + pfl->cfi_table[0x27] = ctz32(device_len); /* + 1; */ + /* Flash device interface (8 & 16 bits) */ + pfl->cfi_table[0x28] = 0x01; + pfl->cfi_table[0x29] = 0x00; + /* Max number of bytes in multi-bytes write */ + if (pfl->bank_width == 1) { + pfl->cfi_table[0x2A] = 0x06; + } else { + pfl->cfi_table[0x2A] = 0x06; + } + pfl->writeblock_size = 1 << pfl->cfi_table[0x2A]; + + pfl->cfi_table[0x2B] = 0x00; + /* Number of erase block regions (uniform) */ + pfl->cfi_table[0x2C] = 0x02; + /* Erase block region 1 */ + pfl->cfi_table[0x2D] = 3; + pfl->cfi_table[0x2E] = 0; + pfl->cfi_table[0x2F] = pfl->sector_len >> 8; + pfl->cfi_table[0x30] = pfl->sector_len >> 16; + /* Erase block region 2 */ + pfl->cfi_table[0x31] = 0x7e; + pfl->cfi_table[0x32] = 0; + pfl->cfi_table[0x33] = 0; + pfl->cfi_table[0x34] = 0x02; + + + /* Extended */ + pfl->cfi_table[0x40] = 'P'; + pfl->cfi_table[0x41] = 'R'; + pfl->cfi_table[0x42] = 'I'; + + pfl->cfi_table[0x43] = '1'; + pfl->cfi_table[0x44] = '3'; + + pfl->cfi_table[0x45] = 0x00; + pfl->cfi_table[0x46] = 0x02; + pfl->cfi_table[0x47] = 0x01; + pfl->cfi_table[0x48] = 0x00; + + pfl->cfi_table[0x49] = 0x08; + pfl->cfi_table[0x4a] = 0x00; + pfl->cfi_table[0x4b] = 0x01; + pfl->cfi_table[0x4c] = 0x00; + pfl->cfi_table[0x4d] = 0x85; + pfl->cfi_table[0x4e] = 0x95; + pfl->cfi_table[0x4f] = 0x02; + pfl->cfi_table[0x50] = 0x01; + +} + +static Property pflash_jedec_properties[] = { + DEFINE_PROP_DRIVE("drive", struct pflash_t, blk), + /* num-blocks is the number of blocks actually visible to the guest, + * ie the total size of the device divided by the sector length. + * If we're emulating flash devices wired in parallel the actual + * number of blocks per indvidual device will differ. + */ + DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0), + DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0), + /* width here is the overall width of this QEMU device in bytes. + * The QEMU device may be emulating a number of flash devices + * wired up in parallel; the width of each individual flash + * device should be specified via device-width. If the individual + * devices have a maximum width which is greater than the width + * they are being used for, this maximum width should be set via + * max-device-width (which otherwise defaults to device-width). + * So for instance a 32-bit wide QEMU flash device made from four + * 16-bit flash devices used in 8-bit wide mode would be configured + * with width = 4, device-width = 1, max-device-width = 2. + * + * If device-width is not specified we default to backwards + * compatible behaviour which is a bad emulation of two + * 16 bit devices making up a 32 bit wide QEMU device. This + * is deprecated for new uses of this device. + */ + DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0), + DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0), + DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0), + DEFINE_PROP_UINT32("bank-size", struct pflash_t, bank_size, 0), + DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0), + DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0), + DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0), + DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0), + DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0), + DEFINE_PROP_STRING("name", struct pflash_t, name), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pflash_jedec_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = pflash_jedec_realize; + dc->props = pflash_jedec_properties; + dc->vmsd = &vmstate_pflash; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + + +static const TypeInfo pflash_jedec_info = { + .name = TYPE_CFI_PFLASH_JEDEC_424, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct pflash_t), + .class_init = pflash_jedec_class_init, +}; + +static void pflash_jedec_register_types(void) +{ + type_register_static(&pflash_jedec_info); +} + +type_init(pflash_jedec_register_types) + +pflash_t *pflash_jedec_424_register(hwaddr base, + DeviceState *qdev, const char *name, + hwaddr size, + BlockBackend *blk, + uint32_t sector_len, int nb_blocs, uint32_t bank_size, + int bank_width, uint16_t id0, uint16_t id1, + uint16_t id2, uint16_t id3, int be) +{ + DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH_JEDEC_424); + + if (blk) { + qdev_prop_set_drive_nofail(dev, "drive", blk); + } + qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); + qdev_prop_set_uint64(dev, "sector-length", sector_len); + qdev_prop_set_uint8(dev, "width", bank_width); + qdev_prop_set_uint32(dev, "bank-size", bank_size); + qdev_prop_set_uint8(dev, "big-endian", !!be); + qdev_prop_set_uint16(dev, "id0", id0); + qdev_prop_set_uint16(dev, "id1", id1); + qdev_prop_set_uint16(dev, "id2", id2); + qdev_prop_set_uint16(dev, "id3", id3); + qdev_prop_set_string(dev, "name", name); + qdev_init_nofail(dev); + + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); + return CFI_PFLASH_JEDEC(dev); +} + +MemoryRegion *pflash_jedec_424_get_memory(pflash_t *fl) +{ + return &fl->mem; +} diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs index 9e9a6c1affb6b..1e5cb30e65b06 100644 --- a/hw/char/Makefile.objs +++ b/hw/char/Makefile.objs @@ -32,5 +32,11 @@ common-obj-$(CONFIG_MILKYMIST) += milkymist-uart.o common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o sclpconsole-lm.o obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o +<<<<<<< HEAD obj-$(CONFIG_PSERIES) += spapr_vty.o obj-$(CONFIG_TERMINAL3270) += terminal3270.o +======= + +obj-$(CONFIG_STM32) += stm32_uart.o +obj-$(CONFIG_STM32) += stm32f7xx_uart.o +>>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/char/stm32_uart.c b/hw/char/stm32_uart.c new file mode 100644 index 0000000000000..5915bf0e1fd0d --- /dev/null +++ b/hw/char/stm32_uart.c @@ -0,0 +1,851 @@ +/* + * STM32 Microcontroller UART module + * + * Copyright (C) 2010 Andre Beckus + * + * Source code based on pl011.c + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/arm/stm32f1xx.h" +#include "sysemu/char.h" +#include "qemu/bitops.h" + + + +/* DEFINITIONS*/ + +/* See the README file for details on these settings. */ +//#define DEBUG_STM32_UART +//#define STM32_UART_NO_BAUD_DELAY +//#define STM32_UART_ENABLE_OVERRUN + +#ifdef DEBUG_STM32_UART +#define DPRINTF(fmt, ...) \ + do { printf("STM32_UART: " fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define USART_SR_OFFSET 0x00 +#define USART_SR_TXE_BIT 7 +#define USART_SR_TC_BIT 6 +#define USART_SR_RXNE_BIT 5 +#define USART_SR_ORE_BIT 3 + +#define USART_DR_OFFSET 0x04 + +#define USART_BRR_OFFSET 0x08 + +#define USART_CR1_OFFSET 0x0c +#define USART_CR1_UE_BIT 13 +#define USART_CR1_M_BIT 12 +#define USART_CR1_PCE_BIT 10 +#define USART_CR1_PS_BIT 9 +#define USART_CR1_TXEIE_BIT 7 +#define USART_CR1_TCIE_BIT 6 +#define USART_CR1_RXNEIE_BIT 5 +#define USART_CR1_TE_BIT 3 +#define USART_CR1_RE_BIT 2 + +#define USART_CR2_OFFSET 0x10 +#define USART_CR2_STOP_START 12 +#define USART_CR2_STOP_MASK 0x00003000 + +#define USART_CR3_OFFSET 0x14 +#define USART_CR3_CTSE_BIT 9 +#define USART_CR3_RTSE_BIT 8 + +#define USART_GTPR_OFFSET 0x18 + +#define USART_RCV_BUF_LEN 256 + +struct Stm32Uart { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + stm32_periph_t periph; + void *stm32_rcc_prop; + void *stm32_gpio_prop; + void *stm32_afio_prop; + + /* Checks the USART transmit pin's GPIO settings. If the GPIO is not configured + * properly, a hardware error is triggered. + */ + union { + void *check_tx_pin_prop; + void (*check_tx_pin_callback)(Stm32Uart *); + }; + + /* Private */ + MemoryRegion iomem; + + Stm32Rcc *stm32_rcc; + Stm32Gpio **stm32_gpio; + Stm32Afio *stm32_afio; + + int uart_index; + + uint32_t bits_per_sec; + int64_t ns_per_char; + + /* Register Values */ + uint32_t + USART_RDR, + USART_TDR, + USART_BRR, + USART_CR1, + USART_CR2, + USART_CR3; + + /* Register Field Values */ + uint32_t + USART_SR_TXE, + USART_SR_TC, + USART_SR_RXNE, + USART_SR_ORE, + USART_CR1_UE, + USART_CR1_TXEIE, + USART_CR1_TCIE, + USART_CR1_RXNEIE, + USART_CR1_TE, + USART_CR1_RE; + + bool sr_read_since_ore_set; + + /* Indicates whether the USART is currently receiving a byte. */ + bool receiving; + + /* Timers used to simulate a delay corresponding to the baud rate. */ + struct QEMUTimer *rx_timer; + struct QEMUTimer *tx_timer; + + void *chr_write_obj; + int (*chr_write)(void *chr_write_obj, const uint8_t *buf, int len); + + /* Stores the USART pin mapping used by the board. This is used to check + * the AFIO's USARTx_REMAP register to make sure the software has set + * the correct mapping. + */ + uint32_t afio_board_map; + + qemu_irq irq; + int curr_irq_level; + + /* We buffer the characters we receive from our qemu_chr receive handler in here + * to increase our overall throughput. This allows us to tell the target that + * another character is ready immediately after it does a read. + */ + uint8_t rcv_char_buf[USART_RCV_BUF_LEN]; + uint32_t rcv_char_bytes; /* number of bytes avaialable in rcv_char_buf */ +}; + + + +/* STM32F1XX Specific stuff */ + +/* Checks the USART transmit pin's GPIO settings. If the GPIO is not configured + * properly, a hardware error is triggered. + */ +void stm32_afio_uart_check_tx_pin_callback(Stm32Uart *s) +{ + int tx_periph, tx_pin; + int config; + + switch(s->periph) { + case STM32F1XX_UART1: + switch(stm32_afio_get_periph_map(s->stm32_afio, s->periph)) { + case STM32_USART1_NO_REMAP: + tx_periph = STM32F1XX_GPIOA; + tx_pin = 9; + break; + case STM32_USART1_REMAP: + tx_periph = STM32F1XX_GPIOB; + tx_pin = 6; + break; + default: + assert(false); + break; + } + break; + case STM32F1XX_UART2: + switch(stm32_afio_get_periph_map(s->stm32_afio, s->periph)) { + case STM32_USART2_NO_REMAP: + tx_periph = STM32F1XX_GPIOA; + tx_pin = 2; + break; + case STM32_USART2_REMAP: + tx_periph = STM32F1XX_GPIOD; + tx_pin = 5; + break; + default: + assert(false); + break; + } + break; + case STM32F1XX_UART3: + switch(stm32_afio_get_periph_map(s->stm32_afio, s->periph)) { + case STM32_USART3_NO_REMAP: + tx_periph = STM32F1XX_GPIOB; + tx_pin = 10; + break; + case STM32_USART3_PARTIAL_REMAP: + tx_periph = STM32F1XX_GPIOC; + tx_pin = 10; + break; + case STM32_USART3_FULL_REMAP: + tx_periph = STM32F1XX_GPIOD; + tx_pin = 8; + break; + default: + assert(false); + break; + } + break; + default: + assert(false); + break; + } + + Stm32Gpio *gpio_dev = s->stm32_gpio[tx_periph - STM32F1XX_GPIOA]; + + if(stm32_gpio_get_mode_bits(gpio_dev, tx_pin) == STM32_GPIO_MODE_IN) { + hw_error("UART TX pin needs to be configured as output"); + } + + config = stm32_gpio_get_config_bits(gpio_dev, tx_pin); + if((config != STM32_GPIO_OUT_ALT_PUSHPULL) && + (config != STM32_GPIO_OUT_ALT_OPEN)) { + hw_error("UART TX pin needs to be configured as " + "alternate function output"); + } +} + + +/* HELPER FUNCTIONS */ + +/* Update the baud rate based on the USART's peripheral clock frequency. */ +static void stm32_uart_baud_update(Stm32Uart *s) +{ + uint32_t clk_freq = stm32_rcc_get_periph_freq(s->stm32_rcc, s->periph); + uint64_t ns_per_bit; + + if((s->USART_BRR == 0) || (clk_freq == 0)) { + s->bits_per_sec = 0; + } else { + s->bits_per_sec = clk_freq / s->USART_BRR; + ns_per_bit = 1000000000LL / s->bits_per_sec; + + /* We assume 10 bits per character. This may not be exactly + * accurate depending on settings, but it should be good enough. */ + s->ns_per_char = ns_per_bit * 10; + } + +#ifdef DEBUG_STM32_UART + const char *periph_name = s->busdev.parent_obj.id; + DPRINTF("%s clock is set to %lu Hz.\n", + periph_name, + (unsigned long)clk_freq); + DPRINTF("%s BRR set to %lu.\n", + periph_name, + (unsigned long)s->USART_BRR); + DPRINTF("%s Baud is set to %lu bits per sec.\n", + periph_name, + (unsigned long)s->bits_per_sec); +#endif +} + +/* Handle a change in the peripheral clock. */ +static void stm32_uart_clk_irq_handler(void *opaque, int n, int level) +{ + Stm32Uart *s = (Stm32Uart *)opaque; + + assert(n == 0); + + /* Only update the BAUD rate if the IRQ is being set. */ + if(level) { + stm32_uart_baud_update(s); + } +} + +/* Routine which updates the USART's IRQ. This should be called whenever + * an interrupt-related flag is updated. + */ +static void stm32_uart_update_irq(Stm32Uart *s) { + /* Note that we are not checking the ORE flag, but we should be. */ + int new_irq_level = + (s->USART_CR1_TCIE & s->USART_SR_TC) | + (s->USART_CR1_TXEIE & s->USART_SR_TXE) | + (s->USART_CR1_RXNEIE & + (s->USART_SR_ORE | s->USART_SR_RXNE)); + + /* Only trigger an interrupt if the IRQ level changes. We probably could + * set the level regardless, but we will just check for good measure. + */ + if(new_irq_level ^ s->curr_irq_level) { + qemu_set_irq(s->irq, new_irq_level); + s->curr_irq_level = new_irq_level; + } +} + + +static void stm32_uart_start_tx(Stm32Uart *s, uint32_t value); + +/* Routine to be called when a transmit is complete. */ +static void stm32_uart_tx_complete(Stm32Uart *s) +{ + if(s->USART_SR_TXE == 1) { + /* If the buffer is empty, there is nothing waiting to be transmitted. + * Mark the transmit complete. */ + s->USART_SR_TC = 1; + stm32_uart_update_irq(s); + } else { + /* Otherwise, mark the transmit buffer as empty and + * start transmitting the value stored there. + */ + s->USART_SR_TXE = 1; + stm32_uart_update_irq(s); + stm32_uart_start_tx(s, s->USART_TDR); + } +} + +/* Start transmitting a character. */ +static void stm32_uart_start_tx(Stm32Uart *s, uint32_t value) +{ + uint8_t ch = value; //This will truncate the ninth bit + + /* Reset the Transmission Complete flag to indicate a transmit is in + * progress. + */ + s->USART_SR_TC = 0; + + /* Write the character out. */ + if (s->chr_write_obj) { + s->chr_write(s->chr_write_obj, &ch, 1); + } +#ifdef STM32_UART_NO_BAUD_DELAY + /* If BAUD delays are not being simulated, then immediately mark the + * transmission as complete. + */ + stm32_uart_tx_complete(s); +#else + /* Otherwise, start the transmit delay timer. */ + timer_mod(s->tx_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->ns_per_char); +#endif +} + + +/* Put byte into the receive data register, if we have one and the target is + * ready for it. */ +static void stm32_uart_fill_receive_data_register(Stm32Uart *s) +{ + bool enabled = (s->USART_CR1_UE && s->USART_CR1_RE); + + /* If we have no more data, or we are emulating baud delay and it's not + * time yet for the next byte, return without filling the RDR */ + if (!s->rcv_char_bytes || s->receiving) { + return; + } + +#ifndef STM32_UART_ENABLE_OVERRUN + /* If overrun is not enabled, don't overwrite the current byte in the RDR */ + if (enabled && s->USART_SR_RXNE) { + return; + } +#endif + + /* Pull the byte out of our buffer */ + uint8_t byte = s->rcv_char_buf[0]; + memmove(&s->rcv_char_buf[0], &s->rcv_char_buf[1], --(s->rcv_char_bytes)); + + /* Only handle the received character if the module is enabled, */ + if (enabled) { + if(s->USART_SR_RXNE) { + DPRINTF("stm32_uart_receive: overrun error\n"); + s->USART_SR_ORE = 1; + s->sr_read_since_ore_set = false; + stm32_uart_update_irq(s); + } + + /* Receive the character and mark the buffer as not empty. */ + s->USART_RDR = byte; + s->USART_SR_RXNE = 1; + stm32_uart_update_irq(s); + } + +#ifndef STM32_UART_NO_BAUD_DELAY + /* Indicate the module is receiving and start the delay. */ + s->receiving = true; + timer_mod(s->rx_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->ns_per_char); +#endif +} + + + +/* TIMER HANDLERS */ +/* Once the receive delay is finished, indicate the USART is finished receiving. + * This will allow it to receive the next character. The current character was + * already received before starting the delay. + */ +static void stm32_uart_rx_timer_expire(void *opaque) { + Stm32Uart *s = (Stm32Uart *)opaque; + + s->receiving = false; + + /* Put next byte into the receive data register, if we have one ready */ + stm32_uart_fill_receive_data_register(s); +} + +/* When the transmit delay is complete, mark the transmit as complete + * (the character was already sent before starting the delay). */ +static void stm32_uart_tx_timer_expire(void *opaque) { + Stm32Uart *s = (Stm32Uart *)opaque; + + stm32_uart_tx_complete(s); +} + + + + + +/* CHAR DEVICE HANDLERS */ + +static int stm32_uart_can_receive(void *opaque) +{ + Stm32Uart *s = (Stm32Uart *)opaque; + + /* How much space do we have in our buffer? */ + return (USART_RCV_BUF_LEN - s->rcv_char_bytes); +} + +static void stm32_uart_event(void *opaque, int event) +{ + /* Do nothing */ +} + +static void stm32_uart_receive(void *opaque, const uint8_t *buf, int size) +{ + Stm32Uart *s = (Stm32Uart *)opaque; + + assert(size > 0); + + /* Copy the characters into our buffer first */ + assert (size <= USART_RCV_BUF_LEN - s->rcv_char_bytes); + memmove(s->rcv_char_buf + s->rcv_char_bytes, buf, size); + s->rcv_char_bytes += size; + + /* Put next byte into RDR if the target is ready for it */ + stm32_uart_fill_receive_data_register(s); +} + + + + +/* REGISTER IMPLEMENTATION */ + +static uint32_t stm32_uart_USART_SR_read(Stm32Uart *s) +{ + /* If the Overflow flag is set, reading the SR register is the first step + * to resetting the flag. + */ + if(s->USART_SR_ORE) { + s->sr_read_since_ore_set = true; + } + + return (s->USART_SR_TXE << USART_SR_TXE_BIT) | + (s->USART_SR_TC << USART_SR_TC_BIT) | + (s->USART_SR_RXNE << USART_SR_RXNE_BIT) | + (s->USART_SR_ORE << USART_SR_ORE_BIT); +} + + + + + +static void stm32_uart_USART_SR_write(Stm32Uart *s, uint32_t new_value) +{ + uint32_t new_TC, new_RXNE; + + new_TC = extract32(new_value, USART_SR_TC_BIT, 1); + /* The Transmit Complete flag can be cleared, but not set. */ + if(new_TC) { + hw_error("Software attempted to set USART TC bit\n"); + } + s->USART_SR_TC = new_TC; + + new_RXNE = extract32(new_value, USART_SR_RXNE_BIT, 1); + /* The Read Data Register Not Empty flag can be cleared, but not set. */ + if(new_RXNE) { + hw_error("Software attempted to set USART RXNE bit\n"); + } + s->USART_SR_RXNE = new_RXNE; + + stm32_uart_update_irq(s); +} + + +static void stm32_uart_USART_DR_read(Stm32Uart *s, uint32_t *read_value) +{ + /* If the Overflow flag is set, then it should be cleared if the software + * performs an SR read followed by a DR read. + */ + if(s->USART_SR_ORE) { + if(s->sr_read_since_ore_set) { + s->USART_SR_ORE = 0; + + } + } + + if(!s->USART_CR1_UE) { + hw_error("Attempted to read from USART_DR while UART was disabled."); + } + + if(!s->USART_CR1_RE) { + hw_error("Attempted to read from USART_DR while UART receiver " + "was disabled."); + } + + if(s->USART_SR_RXNE) { + /* If the receive buffer is not empty, return the value. and mark the + * buffer as empty. + */ + (*read_value) = s->USART_RDR; + s->USART_SR_RXNE = 0; + + /* Put next character into the RDR if we have one */ + stm32_uart_fill_receive_data_register(s); + } else { + printf("STM32_UART WARNING: Read value from USART_DR while it was empty.\n"); + } + + stm32_uart_update_irq(s); +} + + +static void stm32_uart_USART_DR_write(Stm32Uart *s, uint32_t new_value) +{ + uint32_t write_value = new_value & 0x000001ff; + + if(!s->USART_CR1_UE) { + hw_error("Attempted to write to USART_DR while UART was disabled."); + } + + if(!s->USART_CR1_TE) { + hw_error("Attempted to write to USART_DR while UART transmitter " + "was disabled."); + } + + if (s->check_tx_pin_callback) { + s->check_tx_pin_callback(s); + } + + if(s->USART_SR_TC) { + /* If the Transmission Complete bit is set, it means the USART is not + * currently transmitting. This means, a transmission can immediately + * start. + */ + stm32_uart_start_tx(s, write_value); + } else { + /* Otherwise check to see if the buffer is empty. + * If it is, then store the new character there and mark it as not empty. + * If it is not empty, trigger a hardware error. Software should check + * to make sure it is empty before writing to the Data Register. + */ + if(s->USART_SR_TXE) { + s->USART_TDR = write_value; + s->USART_SR_TXE = 0; + } else { + hw_error("Wrote new value to USART_DR while it was non-empty."); + } + } + + stm32_uart_update_irq(s); +} + +/* Update the Baud Rate Register. */ +static void stm32_uart_USART_BRR_write(Stm32Uart *s, uint32_t new_value, + bool init) +{ + s->USART_BRR = new_value & 0x0000ffff; + + stm32_uart_baud_update(s); +} + +static void stm32_uart_USART_CR1_write(Stm32Uart *s, uint32_t new_value, + bool init) +{ + s->USART_CR1_UE = extract32(new_value, USART_CR1_UE_BIT, 1); +#if 0 /* XXX Does not work with f2xx yet */ + if(s->USART_CR1_UE) { + /* Check to make sure the correct mapping is selected when enabling the + * USART. + */ + if(s->afio_board_map != stm32_afio_get_periph_map(s->stm32_afio, s->periph)) { + hw_error("Bad AFIO mapping for %s", s->busdev.parent_obj.id); + } + } +#endif + + s->USART_CR1_TXEIE = extract32(new_value, USART_CR1_TXEIE_BIT, 1); + s->USART_CR1_TCIE = extract32(new_value, USART_CR1_TCIE_BIT, 1); + s->USART_CR1_RXNEIE = extract32(new_value, USART_CR1_RXNEIE_BIT, 1); + + s->USART_CR1_TE = extract32(new_value, USART_CR1_TE_BIT, 1); + s->USART_CR1_RE = extract32(new_value, USART_CR1_RE_BIT, 1); + + s->USART_CR1 = new_value & 0x00003fff; + + stm32_uart_update_irq(s); +} + +static void stm32_uart_USART_CR2_write(Stm32Uart *s, uint32_t new_value, + bool init) +{ + s->USART_CR2 = new_value & 0x00007f7f; +} + +static void stm32_uart_USART_CR3_write(Stm32Uart *s, uint32_t new_value, + bool init) +{ + s->USART_CR3 = new_value & 0x000007ff; +} + +static void stm32_uart_reset(DeviceState *dev) +{ + Stm32Uart *s = STM32_UART(dev); + + /* Initialize the status registers. These are mostly + * read-only, so we do not call the "write" routine + * like normal. + */ + s->USART_SR_TXE = 1; + s->USART_SR_TC = 1; + s->USART_SR_RXNE = 0; + s->USART_SR_ORE = 0; + + // Do not initialize USART_DR - it is documented as undefined at reset + // and does not behave like normal registers. + stm32_uart_USART_BRR_write(s, 0x00000000, true); + stm32_uart_USART_CR1_write(s, 0x00000000, true); + stm32_uart_USART_CR2_write(s, 0x00000000, true); + stm32_uart_USART_CR3_write(s, 0x00000000, true); + + stm32_uart_update_irq(s); +} + +static uint64_t stm32_uart_read(void *opaque, hwaddr offset, + unsigned size) +{ + Stm32Uart *s = (Stm32Uart *)opaque; + uint32_t value; + int start = (offset & 3) * 8; + int length = size * 8; + + switch (offset & 0xfffffffc) { + case USART_SR_OFFSET: + return extract64(stm32_uart_USART_SR_read(s), start, length); + case USART_DR_OFFSET: + stm32_uart_USART_DR_read(s, &value); + return extract64(value, start, length); + case USART_BRR_OFFSET: + return extract64(s->USART_BRR, start, length); + case USART_CR1_OFFSET: + return extract64(s->USART_CR1, start, length); + case USART_CR2_OFFSET: + return extract64(s->USART_CR2, start, length); + case USART_CR3_OFFSET: + return extract64(s->USART_CR3, start, length); + case USART_GTPR_OFFSET: + STM32_NOT_IMPL_REG(offset, size); + return 0; + default: + STM32_BAD_REG(offset, size); + return 0; + } +} + +static void stm32_uart_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + Stm32Uart *s = (Stm32Uart *)opaque; + int start = (offset & 3) * 8; + int length = size * 8; + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, s->periph); + + switch (offset & 0xfffffffc) { + case USART_SR_OFFSET: + stm32_uart_USART_SR_write(s, + deposit64(stm32_uart_USART_SR_read(s), start, length, value)); + break; + case USART_DR_OFFSET: + stm32_uart_USART_DR_write(s, + deposit64(0, start, length, value)); + break; + case USART_BRR_OFFSET: + stm32_uart_USART_BRR_write(s, + deposit64(s->USART_BRR, start, length, value), false); + break; + case USART_CR1_OFFSET: + stm32_uart_USART_CR1_write(s, + deposit64(s->USART_CR1, start, length, value), false); + break; + case USART_CR2_OFFSET: + stm32_uart_USART_CR2_write(s, + deposit64(s->USART_CR2, start, length, value), false); + break; + case USART_CR3_OFFSET: + stm32_uart_USART_CR3_write(s, + deposit64(s->USART_CR3, start, length, value), false); + break; + case USART_GTPR_OFFSET: + STM32_NOT_IMPL_REG(offset, 2); + break; + default: + STM32_BAD_REG(offset, 2); + break; + } +} + +static const MemoryRegionOps stm32_uart_ops = { + .read = stm32_uart_read, + .write = stm32_uart_write, + .valid.min_access_size = 2, + .valid.max_access_size = 4, + .endianness = DEVICE_NATIVE_ENDIAN +}; + + + + + +/* PUBLIC FUNCTIONS */ + +void stm32_uart_set_write_handler(Stm32Uart *s, void *obj, + int (*chr_write_handler)(void *chr_write_obj, const uint8_t *buf, int len)) +{ + s->chr_write_obj = obj; + s->chr_write = chr_write_handler; +} + + +void stm32_uart_get_rcv_handlers(Stm32Uart *s, IOCanReadHandler **can_read, + IOReadHandler **read, IOEventHandler **event) +{ + *can_read = stm32_uart_can_receive; + *read = stm32_uart_receive; + *event = stm32_uart_event; +} + + +// Stub used to typecast the generic write handler prototype to a +// qemu_chr write handler. +static int stm32_uart_chr_fe_write_stub(void *s, const uint8_t *buf, int len) +{ + return qemu_chr_fe_write((CharDriverState *)s, buf, len); +} + + +// Helper method that connects this UART device's receive handlers to a qemu_chr instance. +void stm32_uart_connect(Stm32Uart *s, CharDriverState *chr, uint32_t afio_board_map) +{ + s->chr_write_obj = chr; + if (chr) { + stm32_uart_set_write_handler(s, chr, stm32_uart_chr_fe_write_stub); + IOCanReadHandler *can_read_cb; + IOReadHandler *read_cb; + IOEventHandler *event_cb; + stm32_uart_get_rcv_handlers(s, &can_read_cb, &read_cb, &event_cb); + qemu_chr_add_handlers(chr, can_read_cb, read_cb, event_cb, s); + } + + s->afio_board_map = afio_board_map; +} + + + + +/* DEVICE INITIALIZATION */ + +static int stm32_uart_init(SysBusDevice *dev) +{ + qemu_irq *clk_irq; + Stm32Uart *s = STM32_UART(dev); + + s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; + s->stm32_gpio = (Stm32Gpio **)s->stm32_gpio_prop; + s->stm32_afio = (Stm32Afio *)s->stm32_afio_prop; + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_uart_ops, s, + "uart", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + sysbus_init_irq(dev, &s->irq); + + s->rx_timer = + timer_new_ns(QEMU_CLOCK_VIRTUAL, + (QEMUTimerCB *)stm32_uart_rx_timer_expire, s); + s->tx_timer = + timer_new_ns(QEMU_CLOCK_VIRTUAL, + (QEMUTimerCB *)stm32_uart_tx_timer_expire, s); + + /* Register handlers to handle updates to the USART's peripheral clock. */ + clk_irq = + qemu_allocate_irqs(stm32_uart_clk_irq_handler, (void *)s, 1); + stm32_rcc_set_periph_clk_irq(s->stm32_rcc, s->periph, clk_irq[0]); + + s->rcv_char_bytes = 0; + + stm32_uart_reset((DeviceState *)s); + + return 0; +} + +static Property stm32_uart_properties[] = { + DEFINE_PROP_PERIPH_T("periph", Stm32Uart, periph, STM32_PERIPH_UNDEFINED), + DEFINE_PROP_PTR("stm32_rcc", Stm32Uart, stm32_rcc_prop), + DEFINE_PROP_PTR("stm32_gpio", Stm32Uart, stm32_gpio_prop), + DEFINE_PROP_PTR("stm32_afio", Stm32Uart, stm32_afio_prop), + DEFINE_PROP_PTR("stm32_check_tx_pin_callback", Stm32Uart, check_tx_pin_prop), + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32_uart_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_uart_init; + dc->reset = stm32_uart_reset; + dc->props = stm32_uart_properties; +} + +static TypeInfo stm32_uart_info = { + .name = "stm32-uart", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Uart), + .class_init = stm32_uart_class_init +}; + +static void stm32_uart_register_types(void) +{ + type_register_static(&stm32_uart_info); +} + +type_init(stm32_uart_register_types) diff --git a/hw/char/stm32f7xx_uart.c b/hw/char/stm32f7xx_uart.c new file mode 100644 index 0000000000000..024d22ed54b32 --- /dev/null +++ b/hw/char/stm32f7xx_uart.c @@ -0,0 +1,737 @@ +/* + * STM32F7xx Microcontroller UART module + * + * Copyright (C) 2010 Andre Beckus + * Copyright (C) 2016 Pebble + * + * Source code based on stm32_uart.c + * + * 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 . + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "sysemu/char.h" +#include "qemu/bitops.h" + + + +/* DEFINITIONS*/ + +/* See the README file for details on these settings. */ +//#define DEBUG_STM32_UART +//#define STM32_UART_NO_BAUD_DELAY +//#define STM32_UART_ENABLE_OVERRUN + +#ifdef DEBUG_STM32_UART +#define DPRINTF(fmt, ...) \ + do { printf("STM32F7XX_UART: " fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define USART_CR1_OFFSET 0x00 +#define USART_CR1_UE_BIT 0 +#define USART_CR1_RE_BIT 2 +#define USART_CR1_TE_BIT 3 +#define USART_CR1_RXNEIE_BIT 5 +#define USART_CR1_TCIE_BIT 6 +#define USART_CR1_TXEIE_BIT 7 + +#define USART_CR2_OFFSET 0x04 + +#define USART_CR3_OFFSET 0x08 + +#define USART_BRR_OFFSET 0x0C + +#define USART_GTPR_OFFSET 0x10 + +#define USART_RTOR_OFFSET 0x14 + +#define USART_RQR_OFFSET 0x18 +#define USART_RQR_RXFRQ_BIT 3 + +#define USART_ISR_OFFSET 0x1C +#define USART_ISR_ORE_BIT 3 +#define USART_ISR_RXNE_BIT 5 +#define USART_ISR_TC_BIT 6 +#define USART_ISR_TXE_BIT 7 + +#define USART_ICR_OFFSET 0x20 +#define USART_ICR_ORECF_BIT 3 + +#define USART_RDR_OFFSET 0x24 + +#define USART_TDR_OFFSET 0x28 + +#define USART_RCV_BUF_LEN 256 + +struct Stm32F7xxUart { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + stm32_periph_t periph; + void *stm32_rcc_prop; + void *stm32_gpio_prop; + void *stm32_afio_prop; + + /* Checks the USART transmit pin's GPIO settings. If the GPIO is not configured + * properly, a hardware error is triggered. + */ + union { + void *check_tx_pin_prop; + void (*check_tx_pin_callback)(Stm32F7xxUart *); + }; + + /* Private */ + MemoryRegion iomem; + + Stm32Rcc *stm32_rcc; + Stm32Gpio **stm32_gpio; + Stm32Afio *stm32_afio; + + int uart_index; + + uint32_t bits_per_sec; + int64_t ns_per_char; + + /* Register Values */ + uint32_t USART_RDR; + uint32_t USART_TDR; + uint32_t USART_BRR; + uint32_t USART_CR1; + uint32_t USART_CR2; + uint32_t USART_CR3; + + /* Register Field Values */ + uint32_t USART_ISR_TXE; + uint32_t USART_ISR_TC; + uint32_t USART_ISR_RXNE; + uint32_t USART_ISR_ORE; + uint32_t USART_CR1_UE; + uint32_t USART_CR1_TXEIE; + uint32_t USART_CR1_TCIE; + uint32_t USART_CR1_RXNEIE; + uint32_t USART_CR1_TE; + uint32_t USART_CR1_RE; + + /* Indicates whether the USART is currently receiving a byte. */ + bool receiving; + + /* Timers used to simulate a delay corresponding to the baud rate. */ + struct QEMUTimer *rx_timer; + struct QEMUTimer *tx_timer; + + void *chr_write_obj; + int (*chr_write)(void *chr_write_obj, const uint8_t *buf, int len); + + /* Stores the USART pin mapping used by the board. This is used to check + * the AFIO's USARTx_REMAP register to make sure the software has set + * the correct mapping. + */ + uint32_t afio_board_map; + + qemu_irq irq; + int curr_irq_level; + + /* We buffer the characters we receive from our qemu_chr receive handler in here + * to increase our overall throughput. This allows us to tell the target that + * another character is ready immediately after it does a read. + */ + uint8_t rcv_char_buf[USART_RCV_BUF_LEN]; + uint32_t rcv_char_bytes; /* number of bytes avaialable in rcv_char_buf */ +}; + + +/* HELPER FUNCTIONS */ + +/* Update the baud rate based on the USART's peripheral clock frequency. */ +static void stm32f7xx_uart_baud_update(Stm32F7xxUart *s) +{ + uint32_t clk_freq = stm32_rcc_get_periph_freq(s->stm32_rcc, s->periph); + uint64_t ns_per_bit; + + if ((s->USART_BRR == 0) || (clk_freq == 0)) { + s->bits_per_sec = 0; + } else { + s->bits_per_sec = clk_freq / s->USART_BRR; + ns_per_bit = 1000000000LL / s->bits_per_sec; + + /* We assume 10 bits per character. This may not be exactly + * accurate depending on settings, but it should be good enough. */ + s->ns_per_char = ns_per_bit * 10; + } + +#ifdef DEBUG_STM32_UART + const char *periph_name = s->busdev.parent_obj.id; + DPRINTF("%s clock is set to %lu Hz.\n", + periph_name, + (unsigned long)clk_freq); + DPRINTF("%s BRR set to %lu.\n", + periph_name, + (unsigned long)s->USART_BRR); + DPRINTF("%s Baud is set to %lu bits per sec.\n", + periph_name, + (unsigned long)s->bits_per_sec); +#endif +} + +/* Handle a change in the peripheral clock. */ +static void stm32f7xx_uart_clk_irq_handler(void *opaque, int n, int level) +{ + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + + assert(n == 0); + + /* Only update the BAUD rate if the IRQ is being set. */ + if (level) { + stm32f7xx_uart_baud_update(s); + } +} + +/* Routine which updates the USART's IRQ. This should be called whenever + * an interrupt-related flag is updated. + */ +static void stm32f7xx_uart_update_irq(Stm32F7xxUart *s) { + /* Note that we are not checking the ORE flag, but we should be. */ + int new_irq_level = + (s->USART_CR1_TCIE & s->USART_ISR_TC) | + (s->USART_CR1_TXEIE & s->USART_ISR_TXE) | + (s->USART_CR1_RXNEIE & (s->USART_ISR_ORE | s->USART_ISR_RXNE)); + + /* Only trigger an interrupt if the IRQ level changes. We probably could + * set the level regardless, but we will just check for good measure. + */ + if (new_irq_level ^ s->curr_irq_level) { + qemu_set_irq(s->irq, new_irq_level); + s->curr_irq_level = new_irq_level; + } +} + + +static void stm32f7xx_uart_start_tx(Stm32F7xxUart *s, uint32_t value); + +/* Routine to be called when a transmit is complete. */ +static void stm32f7xx_uart_tx_complete(Stm32F7xxUart *s) +{ + if (s->USART_ISR_TXE == 1) { + /* If the buffer is empty, there is nothing waiting to be transmitted. + * Mark the transmit complete. */ + s->USART_ISR_TC = 1; + stm32f7xx_uart_update_irq(s); + } else { + /* Otherwise, mark the transmit buffer as empty and + * start transmitting the value stored there. + */ + s->USART_ISR_TXE = 1; + stm32f7xx_uart_update_irq(s); + stm32f7xx_uart_start_tx(s, s->USART_TDR); + } +} + +/* Start transmitting a character. */ +static void stm32f7xx_uart_start_tx(Stm32F7xxUart *s, uint32_t value) +{ + uint8_t ch = value; //This will truncate the ninth bit + + /* Reset the Transmission Complete flag to indicate a transmit is in + * progress. + */ + s->USART_ISR_TC = 0; + + /* Write the character out. */ + if (s->chr_write_obj) { + s->chr_write(s->chr_write_obj, &ch, 1); + } +#ifdef STM32_UART_NO_BAUD_DELAY + /* If BAUD delays are not being simulated, then immediately mark the + * transmission as complete. + */ + stm32f7xx_uart_tx_complete(s); +#else + /* Otherwise, start the transmit delay timer. */ + timer_mod(s->tx_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->ns_per_char); +#endif +} + + +/* Put byte into the receive data register, if we have one and the target is ready for it. */ +static void stm32f7xx_uart_fill_receive_data_register(Stm32F7xxUart *s) +{ + bool enabled = (s->USART_CR1_UE && s->USART_CR1_RE); + + /* If we have no more data, or we are emulating baud delay and it's not + * time yet for the next byte, return without filling the RDR */ + if (!s->rcv_char_bytes || s->receiving) { + return; + } + +#ifndef STM32_UART_ENABLE_OVERRUN + /* If overrun is not enabled, don't overwrite the current byte in the RDR */ + if (enabled && s->USART_ISR_RXNE) { + return; + } +#endif + + /* Pull the byte out of our buffer */ + uint8_t byte = s->rcv_char_buf[0]; + memmove(&s->rcv_char_buf[0], &s->rcv_char_buf[1], --(s->rcv_char_bytes)); + + /* Only handle the received character if the module is enabled, */ + if (enabled) { + if (s->USART_ISR_RXNE) { + DPRINTF("stm32f7xx_uart_receive: overrun error\n"); + s->USART_ISR_ORE = 1; + stm32f7xx_uart_update_irq(s); + } + + /* Receive the character and mark the buffer as not empty. */ + s->USART_RDR = byte; + s->USART_ISR_RXNE = 1; + stm32f7xx_uart_update_irq(s); + } + +#ifndef STM32_UART_NO_BAUD_DELAY + /* Indicate the module is receiving and start the delay. */ + s->receiving = true; + timer_mod(s->rx_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->ns_per_char); +#endif +} + + + +/* TIMER HANDLERS */ +/* Once the receive delay is finished, indicate the USART is finished receiving. + * This will allow it to receive the next character. The current character was + * already received before starting the delay. + */ +static void stm32f7xx_uart_rx_timer_expire(void *opaque) { + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + + s->receiving = false; + + /* Put next byte into the receive data register, if we have one ready */ + stm32f7xx_uart_fill_receive_data_register(s); +} + +/* When the transmit delay is complete, mark the transmit as complete + * (the character was already sent before starting the delay). */ +static void stm32f7xx_uart_tx_timer_expire(void *opaque) { + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + + stm32f7xx_uart_tx_complete(s); +} + + + + + +/* CHAR DEVICE HANDLERS */ + +static int stm32f7xx_uart_can_receive(void *opaque) +{ + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + + /* How much space do we have in our buffer? */ + return (USART_RCV_BUF_LEN - s->rcv_char_bytes); +} + +static void stm32f7xx_uart_event(void *opaque, int event) +{ + /* Do nothing */ +} + +static void stm32f7xx_uart_receive(void *opaque, const uint8_t *buf, int size) +{ + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + + assert(size > 0); + + /* Copy the characters into our buffer first */ + assert (size <= USART_RCV_BUF_LEN - s->rcv_char_bytes); + memmove(s->rcv_char_buf + s->rcv_char_bytes, buf, size); + s->rcv_char_bytes += size; + + /* Put next byte into RDR if the target is ready for it */ + stm32f7xx_uart_fill_receive_data_register(s); +} + + + + +/* REGISTER IMPLEMENTATION */ + +static uint32_t stm32f7xx_uart_USART_ISR_read(Stm32F7xxUart *s) +{ + return (s->USART_ISR_TXE << USART_ISR_TXE_BIT) | + (s->USART_ISR_TC << USART_ISR_TC_BIT) | + (s->USART_ISR_RXNE << USART_ISR_RXNE_BIT) | + (s->USART_ISR_ORE << USART_ISR_ORE_BIT); +} + + +static void stm32f7xx_uart_USART_ICR_write(Stm32F7xxUart *s, uint32_t new_value) +{ + if (new_value & USART_ICR_ORECF_BIT) { + s->USART_ISR_ORE = 0; + } + + stm32f7xx_uart_update_irq(s); +} + + +static uint32_t stm32f7xx_uart_USART_RDR_read(Stm32F7xxUart *s) +{ + uint32_t read_value = 0; + if (!s->USART_CR1_UE) { + hw_error("Attempted to read from USART_RDR while UART was disabled."); + } + + if (!s->USART_CR1_RE) { + hw_error("Attempted to read from USART_RDR while UART receiver was disabled."); + } + + if (s->USART_ISR_RXNE) { + /* If the receive buffer is not empty, return the value. and mark the + * buffer as empty. + */ + read_value = s->USART_RDR; + s->USART_ISR_RXNE = 0; + + /* Put next character into the RDR if we have one */ + stm32f7xx_uart_fill_receive_data_register(s); + } else { + printf("STM32_UART WARNING: Read value from USART_RDR while it was empty.\n"); + } + + stm32f7xx_uart_update_irq(s); + return read_value; +} + + +static void stm32f7xx_uart_USART_TDR_write(Stm32F7xxUart *s, uint32_t new_value) +{ + uint32_t write_value = new_value & 0x000001ff; + + if (!s->USART_CR1_UE) { + hw_error("Attempted to write to USART_TDR while UART was disabled."); + } + + if (!s->USART_CR1_TE) { + hw_error("Attempted to write to USART_TDR while UART transmitter was disabled."); + } + + if (s->check_tx_pin_callback) { + s->check_tx_pin_callback(s); + } + + DPRINTF("Writing to TDR (value=0x%x, ISR_TC=%d, ISR_TXE=%d)\n", write_value, s->USART_ISR_TC, + s->USART_ISR_TXE); + if (s->USART_ISR_TC) { + /* If the Transmission Complete bit is set, it means the USART is not + * currently transmitting. This means, a transmission can immediately + * start. + */ + stm32f7xx_uart_start_tx(s, write_value); + } else { + /* Otherwise check to see if the buffer is empty. + * If it is, then store the new character there and mark it as not empty. + * If it is not empty, trigger a hardware error. Software should check + * to make sure it is empty before writing to the Data Register. + */ + if (s->USART_ISR_TXE) { + s->USART_TDR = write_value; + s->USART_ISR_TXE = 0; + } else { + hw_error("Wrote new value to USART_TDR while it was non-empty."); + } + } + + stm32f7xx_uart_update_irq(s); +} + +/* Update the Baud Rate Register. */ +static void stm32f7xx_uart_USART_BRR_write(Stm32F7xxUart *s, uint32_t new_value, bool init) +{ + s->USART_BRR = new_value & 0x0000ffff; + + stm32f7xx_uart_baud_update(s); +} + +static void stm32f7xx_uart_USART_CR1_write(Stm32F7xxUart *s, uint32_t new_value, bool init) +{ + s->USART_CR1_UE = extract32(new_value, USART_CR1_UE_BIT, 1); +#if 0 + if (s->USART_CR1_UE) { + /* Check to make sure the correct mapping is selected when enabling the + * USART. + */ + if (s->afio_board_map != stm32_afio_get_periph_map(s->stm32_afio, s->periph)) { + hw_error("Bad AFIO mapping for %s", s->busdev.parent_obj.id); + } + } +#endif + + s->USART_CR1_TXEIE = extract32(new_value, USART_CR1_TXEIE_BIT, 1); + s->USART_CR1_TCIE = extract32(new_value, USART_CR1_TCIE_BIT, 1); + s->USART_CR1_RXNEIE = extract32(new_value, USART_CR1_RXNEIE_BIT, 1); + + s->USART_CR1_TE = extract32(new_value, USART_CR1_TE_BIT, 1); + s->USART_CR1_RE = extract32(new_value, USART_CR1_RE_BIT, 1); + + s->USART_CR1 = new_value & 0x1ffffffd; + + stm32f7xx_uart_update_irq(s); +} + +static void stm32f7xx_uart_USART_CR2_write(Stm32F7xxUart *s, uint32_t new_value, bool init) +{ + s->USART_CR2 = new_value & 0xffffff70; +} + +static void stm32f7xx_uart_USART_CR3_write(Stm32F7xxUart *s, uint32_t new_value, bool init) +{ + s->USART_CR3 = new_value & 0x0000e7ff; +} + +static void stm32f7xx_uart_reset(DeviceState *dev) +{ + Stm32F7xxUart *s = STM32F7XX_UART(dev); + + /* Initialize the status registers. These are mostly + * read-only, so we do not call the "write" routine + * like normal. + */ + s->USART_ISR_TXE = 1; + s->USART_ISR_TC = 1; + s->USART_ISR_RXNE = 0; + s->USART_ISR_ORE = 0; + + // Do not initialize USART_RDR/USART_TDR - it is documented as undefined at reset + // and does not behave like normal registers. + stm32f7xx_uart_USART_BRR_write(s, 0x00000000, true); + stm32f7xx_uart_USART_CR1_write(s, 0x00000000, true); + stm32f7xx_uart_USART_CR2_write(s, 0x00000000, true); + stm32f7xx_uart_USART_CR3_write(s, 0x00000000, true); + + stm32f7xx_uart_update_irq(s); +} + +static uint64_t stm32f7xx_uart_read(void *opaque, hwaddr offset, unsigned size) +{ + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + uint64_t value = 0; + int start = (offset & 3) * 8; + int length = size * 8; + + switch (offset & 0xfffffffc) { + case USART_ISR_OFFSET: + value = stm32f7xx_uart_USART_ISR_read(s); + break; + case USART_RDR_OFFSET: + value = stm32f7xx_uart_USART_RDR_read(s); + break; + case USART_BRR_OFFSET: + value = s->USART_BRR; + break; + case USART_CR1_OFFSET: + value = s->USART_CR1; + break; + case USART_CR2_OFFSET: + value = s->USART_CR2; + break; + case USART_CR3_OFFSET: + value = s->USART_CR3; + break; + case USART_GTPR_OFFSET: + case USART_RTOR_OFFSET: + case USART_RQR_OFFSET: + case USART_ICR_OFFSET: + // always reads as 0 + break; + default: + STM32_BAD_REG(offset, size); + break; + } + + return extract64(value, start, length); +} + +static void stm32f7xx_uart_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) +{ + Stm32F7xxUart *s = (Stm32F7xxUart *)opaque; + int start = (offset & 3) * 8; + int length = size * 8; + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, s->periph); + + switch (offset & 0xfffffffc) { + case USART_ICR_OFFSET: + stm32f7xx_uart_USART_ICR_write(s, deposit64(0, start, length, value)); + break; + case USART_ISR_OFFSET: + STM32_WARN_RO_REG(offset); + break; + case USART_TDR_OFFSET: + stm32f7xx_uart_USART_TDR_write(s, deposit64(0, start, length, value)); + break; + case USART_BRR_OFFSET: + stm32f7xx_uart_USART_BRR_write(s, deposit64(s->USART_BRR, start, length, value), false); + break; + case USART_CR1_OFFSET: + stm32f7xx_uart_USART_CR1_write(s, deposit64(s->USART_CR1, start, length, value), false); + break; + case USART_CR2_OFFSET: + stm32f7xx_uart_USART_CR2_write(s, deposit64(s->USART_CR2, start, length, value), false); + break; + case USART_CR3_OFFSET: + stm32f7xx_uart_USART_CR3_write(s, deposit64(s->USART_CR3, start, length, value), false); + break; + case USART_RQR_OFFSET: + if (extract32(value, USART_RQR_RXFRQ_BIT, 1) == 1) { + s->USART_ISR_RXNE = 0; + } + break; + case USART_GTPR_OFFSET: + case USART_RTOR_OFFSET: + STM32_NOT_IMPL_REG(offset, size); + break; + default: + STM32_BAD_REG(offset, size); + break; + } +} + +static const MemoryRegionOps stm32f7xx_uart_ops = { + .read = stm32f7xx_uart_read, + .write = stm32f7xx_uart_write, + .valid.min_access_size = 2, + .valid.max_access_size = 4, + .endianness = DEVICE_NATIVE_ENDIAN +}; + + + + + +/* PUBLIC FUNCTIONS */ + +void stm32f7xx_uart_set_write_handler(Stm32F7xxUart *s, void *obj, + int (*chr_write_handler)(void *chr_write_obj, const uint8_t *buf, int len)) +{ + s->chr_write_obj = obj; + s->chr_write = chr_write_handler; +} + + +void stm32f7xx_uart_get_rcv_handlers(Stm32F7xxUart *s, IOCanReadHandler **can_read, + IOReadHandler **read, IOEventHandler **event) +{ + *can_read = stm32f7xx_uart_can_receive; + *read = stm32f7xx_uart_receive; + *event = stm32f7xx_uart_event; +} + + +// Stub used to typecast the generic write handler prototype to a qemu_chr write handler. +static int stm32f7xx_uart_chr_fe_write_stub(void *s, const uint8_t *buf, int len) +{ + return qemu_chr_fe_write((CharDriverState *)s, buf, len); +} + + +// Helper method that connects this UART device's receive handlers to a qemu_chr instance. +void stm32f7xx_uart_connect(Stm32F7xxUart *s, CharDriverState *chr, uint32_t afio_board_map) +{ + s->chr_write_obj = chr; + if (chr) { + stm32f7xx_uart_set_write_handler(s, chr, stm32f7xx_uart_chr_fe_write_stub); + IOCanReadHandler *can_read_cb; + IOReadHandler *read_cb; + IOEventHandler *event_cb; + stm32f7xx_uart_get_rcv_handlers(s, &can_read_cb, &read_cb, &event_cb); + qemu_chr_add_handlers(chr, can_read_cb, read_cb, event_cb, s); + } + + s->afio_board_map = afio_board_map; +} + + + + +/* DEVICE INITIALIZATION */ + +static int stm32f7xx_uart_init(SysBusDevice *dev) +{ + qemu_irq *clk_irq; + Stm32F7xxUart *s = STM32F7XX_UART(dev); + + s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; + s->stm32_gpio = (Stm32Gpio **)s->stm32_gpio_prop; + s->stm32_afio = (Stm32Afio *)s->stm32_afio_prop; + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32f7xx_uart_ops, s, "uart", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + sysbus_init_irq(dev, &s->irq); + + s->rx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + (QEMUTimerCB *)stm32f7xx_uart_rx_timer_expire, s); + s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + (QEMUTimerCB *)stm32f7xx_uart_tx_timer_expire, s); + + /* Register handlers to handle updates to the USART's peripheral clock. */ + clk_irq = qemu_allocate_irqs(stm32f7xx_uart_clk_irq_handler, (void *)s, 1); + stm32_rcc_set_periph_clk_irq(s->stm32_rcc, s->periph, clk_irq[0]); + + s->rcv_char_bytes = 0; + + stm32f7xx_uart_reset((DeviceState *)s); + + return 0; +} + +static Property stm32f7xx_uart_properties[] = { + DEFINE_PROP_PERIPH_T("periph", Stm32F7xxUart, periph, STM32_PERIPH_UNDEFINED), + DEFINE_PROP_PTR("stm32_rcc", Stm32F7xxUart, stm32_rcc_prop), + DEFINE_PROP_PTR("stm32_gpio", Stm32F7xxUart, stm32_gpio_prop), + DEFINE_PROP_PTR("stm32_afio", Stm32F7xxUart, stm32_afio_prop), + DEFINE_PROP_PTR("stm32_check_tx_pin_callback", Stm32F7xxUart, check_tx_pin_prop), + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32f7xx_uart_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32f7xx_uart_init; + dc->reset = stm32f7xx_uart_reset; + dc->props = stm32f7xx_uart_properties; +} + +static TypeInfo stm32f7xx_uart_info = { + .name = "stm32f7xx-uart", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32F7xxUart), + .class_init = stm32f7xx_uart_class_init +}; + +static void stm32f7xx_uart_register_types(void) +{ + type_register_static(&stm32f7xx_uart_info); +} + +type_init(stm32f7xx_uart_register_types) diff --git a/hw/core/irq.c b/hw/core/irq.c index fb3045b912e9b..cdb02f95a82a4 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -120,17 +120,50 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2) return qemu_allocate_irq(qemu_splitirq, s, 0); } +<<<<<<< HEAD void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) +======= +static void proxy_irq_handler(void *opaque, int n, int level) +{ + qemu_irq **target = opaque; + + if (*target) { + qemu_set_irq((*target)[n], level); + } +} + +qemu_irq *qemu_irq_proxy(qemu_irq **target, int n) +{ + return qemu_allocate_irqs(proxy_irq_handler, target, n); +} + + +void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, + int id, int n) +>>>>>>> 919b29ba7d... Pebble Qemu { int i; + IRQInterceptData *intercept_data = g_malloc0(sizeof(IRQInterceptData)); qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n); + intercept_data->id = id; + intercept_data->old_irqs = old_irqs; for (i = 0; i < n; i++) { *old_irqs[i] = *gpio_in[i]; gpio_in[i]->handler = handler; - gpio_in[i]->opaque = &old_irqs[i]; + gpio_in[i]->opaque = intercept_data; } } +void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, + int id, int n) +{ + IRQInterceptData *intercept_data = g_malloc0(sizeof(IRQInterceptData)); + qemu_irq *old_irqs = *gpio_out; + intercept_data->id = id; + intercept_data->old_irqs = old_irqs; + *gpio_out = qemu_allocate_irqs(handler, intercept_data, n); +} + static const TypeInfo irq_type_info = { .name = TYPE_IRQ, .parent = TYPE_OBJECT, diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 85f062def72b5..414521a3f28ff 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -499,12 +499,21 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); assert(gpio_list->num_in == 0 || !name); + // + // update the out array... + // + int old = gpio_list->num_out; + gpio_list->out = old ? g_renew(qemu_irq, gpio_list->out, old + n) : g_new(qemu_irq, n); + for (i = 0; i < n; ++i) { + gpio_list->out[old + i] = pins[i]; + } if (!name) { name = "unnamed-gpio-out"; } memset(pins, 0, sizeof(*pins) * n); for (i = 0; i < n; ++i) { + memset(&pins[i], 0, sizeof(*pins)); gchar *propname = g_strdup_printf("%s[%u]", name, gpio_list->num_out + i); diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index 77a7d622bd2da..7c38300b1917d 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -13,7 +13,13 @@ common-obj-$(CONFIG_PL110) += pl110.o common-obj-$(CONFIG_SII9022) += sii9022.o common-obj-$(CONFIG_SSD0303) += ssd0303.o common-obj-$(CONFIG_SSD0323) += ssd0323.o +<<<<<<< HEAD common-obj-$(CONFIG_XEN) += xenfb.o +======= +common-obj-$(CONFIG_XEN_BACKEND) += xenfb.o +common-obj-$(CONFIG_LS013B7DH01) += ls013b7dh01.o +common-obj-$(CONFIG_PEBBLE_SNOWY_DISPLAY) += pebble_snowy_display.o +>>>>>>> 919b29ba7d... Pebble Qemu common-obj-$(CONFIG_VGA_PCI) += vga-pci.o common-obj-$(CONFIG_VGA_ISA) += vga-isa.o diff --git a/hw/display/ls013b7dh01.c b/hw/display/ls013b7dh01.c new file mode 100644 index 0000000000000..7799bb9286bf1 --- /dev/null +++ b/hw/display/ls013b7dh01.c @@ -0,0 +1,379 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ + +/* + * QEMU Sharp LS013B7DH01 Memory LCD device model. + */ + +/* + * TODO: + * Add part number attribute and set ROWS/COLS appropriately. + * Add attribute for 'off' bit colour for simulating backlight. + * Add display rotation attribute. + * Handle 24bpp host displays. + */ + +#include "qemu-common.h" +#include "ui/console.h" +#include "ui/pixel_ops.h" +#include "hw/ssi.h" + +#define NUM_ROWS 168 +#define NUM_COLS 144 // 18 bytes +#define NUM_COL_BYTES (NUM_COLS / 8) + +typedef enum { + COMMAND, + LINENO, + DATA, + TRAILER +} xfer_state_t; + +typedef struct { + SSISlave ssidev; + QemuConsole *con; + bool redraw; + uint8_t framebuffer[NUM_ROWS * NUM_COL_BYTES]; + int fbindex; + xfer_state_t state; + + bool backlight_enabled; + float brightness; + + bool vibrate_on; + int vibrate_offset; + + bool power_on; + + /* Tintin display was installed 'upside-down'. + * Use the "rotate_display" property to flip it. + */ + bool rotate_display; +} lcd_state; + +static uint8_t +bitswap(uint8_t val) +{ + return ((val * 0x0802LU & 0x22110LU) | (val * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; +} + +static uint32_t +sm_lcd_transfer(SSISlave *dev, uint32_t data) +{ + lcd_state *s = FROM_SSI_SLAVE(lcd_state, dev); + /* XXX QEMU's SPI infrastructure is implicitly MSB-first */ + data = bitswap(data); + + switch(s->state) { + case COMMAND: + data &= 0xfd; /* Mask VCOM bit */ + switch(data) { + case 0x01: /* Write Line */ + s->state = LINENO; + break; + case 0x04: /* Clear Screen */ + memset(s->framebuffer, 0, sizeof(*s->framebuffer)); + s->redraw = true; + break; + case 0x00: /* Toggle VCOM */ + break; + default: + /* Simulate confused display controller. */ + memset(s->framebuffer, 0x55, sizeof(*s->framebuffer)); + s->redraw = true; + break; + } + break; + case LINENO: + if (data == 0) { + s->state = COMMAND; + } else { + s->fbindex = (data - 1) * NUM_COL_BYTES; + s->state = DATA; + } + break; + case DATA: + s->framebuffer[s->fbindex++] = data; + if (s->fbindex % NUM_COL_BYTES == 0) { + s->state = TRAILER; + } + break; + case TRAILER: + if (data != 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "ls013 memory lcd received non-zero data in TRAILER\n"); + } + s->state = LINENO; + s->redraw = true; + break; + } + return 0; +} + +static void sm_lcd_update_display(void *arg) +{ + lcd_state *s = arg; + + uint8_t *d; + uint32_t colour_on, colour_off, colour; + int x, y, bpp; + + DisplaySurface *surface = qemu_console_surface(s->con); + bpp = surface_bits_per_pixel(surface); + d = surface_data(surface); + + + // If vibrate is on, simply jiggle the display + if (s->vibrate_on) { + if (s->vibrate_offset == 0) { + s->vibrate_offset = 2; + } + int bytes_per_pixel; + switch (bpp) { + case 8: + bytes_per_pixel = 1; + break; + case 15: + case 16: + bytes_per_pixel = 2; + break; + case 32: + bytes_per_pixel = 4; + break; + default: + abort(); + } + int total_bytes = NUM_ROWS * NUM_COLS * bytes_per_pixel + - abs(s->vibrate_offset) * bytes_per_pixel; + if (s->vibrate_offset > 0) { + memmove(d, d + s->vibrate_offset * bytes_per_pixel, total_bytes); + } else { + memmove(d - s->vibrate_offset * bytes_per_pixel, d, total_bytes); + } + s->vibrate_offset *= -1; + dpy_gfx_update(s->con, 0, 0, NUM_COLS, NUM_ROWS); + return; + } + + if (!s->redraw) { + return; + } + + // Adjust the white level to compensate for the set brightness. + // brightness = 0: 255 in maps to 170 out + // brightness = 1.0: 255 in maps to 255 out + float brightness = s->backlight_enabled ? s->brightness : 0.0; + int max_val = 170 + (255 - 170) * brightness; + + /* set colours according to bpp */ + switch (bpp) { + case 8: + colour_on = rgb_to_pixel8(max_val, max_val, max_val); + colour_off = rgb_to_pixel8(0x00, 0x00, 0x00); + break; + case 15: + colour_on = rgb_to_pixel15(max_val, max_val, max_val); + colour_off = rgb_to_pixel15(0x00, 0x00, 0x00); + break; + case 16: + colour_on = rgb_to_pixel16(max_val, max_val, max_val); + colour_off = rgb_to_pixel16(0x00, 0x00, 0x00); + case 24: + colour_on = rgb_to_pixel24(max_val, max_val, max_val); + colour_off = rgb_to_pixel24(0x00, 0x00, 0x00); + break; + case 32: + colour_on = rgb_to_pixel32(max_val, max_val, max_val); + colour_off = rgb_to_pixel32(0x00, 0x00, 0x00); + break; + default: + return; + } + + for (y = 0; y < NUM_ROWS; y++) { + for (x = 0; x < NUM_COLS; x++) { + /* Rotate the display if necessary */ + int xr = (s->rotate_display) ? NUM_COLS - 1 - x : x; + int yr = (s->rotate_display) ? NUM_ROWS - 1 - y : y; + bool on = s->framebuffer[yr * NUM_COL_BYTES + xr / 8] & 1 << (xr % 8); + colour = on ? colour_on : colour_off; + switch(bpp) { + case 8: + *((uint8_t *)d) = colour; + d++; + break; + case 15: + case 16: + *((uint16_t *)d) = colour; + d += 2; + break; + case 24: + abort(); + case 32: + *((uint32_t *)d) = colour; + d += 4; + break; + } + } + } + + dpy_gfx_update(s->con, 0, 0, NUM_COLS, NUM_ROWS); + s->redraw = false; +} + +static void sm_lcd_invalidate_display(void *arg) +{ + lcd_state *s = arg; + s->redraw = true; +} + + +// ----------------------------------------------------------------------------- +static void sm_lcd_backlight_enable_cb(void *opaque, int n, int level) +{ + lcd_state *s = (lcd_state *)opaque; + assert(n == 0); + + bool enable = (level != 0); + if (s->backlight_enabled != enable) { + s->backlight_enabled = enable; + s->redraw = true; + } +} + + +// ----------------------------------------------------------------------------- +// Set brightness, from 0 to 255 +static void sm_lcd_set_backlight_level_cb(void *opaque, int n, int level) +{ + lcd_state *s = (lcd_state *)opaque; + assert(n == 0); + + float bright_f = (float)level / 255; + + // Temp hack - the Pebble sets the PWM to 25% for max brightness + float new_setting = MIN(1.0, bright_f * 4); + if (new_setting != s->brightness) { + s->brightness = MIN(1.0, bright_f * 4); + if (s->backlight_enabled) { + s->redraw = true; + } + } +} + + +// ----------------------------------------------------------------------------- +static void sm_lcd_vibe_ctl(void *opaque, int n, int level) +{ + lcd_state *s = (lcd_state *)opaque; + assert(n == 0); + + s->vibrate_on = (level != 0); +} + +// ----------------------------------------------------------------------------- +static void sm_lcd_power_ctl(void *opaque, int n, int level) +{ + lcd_state *s = (lcd_state *)opaque; + assert(n == 0); + + if (!level && s->power_on) { + memset(&s->framebuffer, 0, sizeof(s->framebuffer)); + s->redraw = true; + s->power_on = false; + } + s->power_on = !!level; +} + + +static void sm_lcd_reset(DeviceState *dev) +{ + lcd_state *s = (lcd_state *)dev; + memset(&s->framebuffer, 0, sizeof(s->framebuffer)); + s->redraw = true; +} + + +// ----------------------------------------------------------------------------- +static const GraphicHwOps sm_lcd_ops = { + .gfx_update = sm_lcd_update_display, + .invalidate = sm_lcd_invalidate_display, +}; + +static int sm_lcd_init(SSISlave *dev) +{ + lcd_state *s = FROM_SSI_SLAVE(lcd_state, dev); + + s->brightness = 0.0; + + s->con = graphic_console_init(DEVICE(dev), 0, &sm_lcd_ops, s); + qemu_console_resize(s->con, NUM_COLS, NUM_ROWS); + + /* This callback informs us that brightness control is enabled */ + qdev_init_gpio_in_named(DEVICE(dev), sm_lcd_backlight_enable_cb, + "backlight_enable", 1); + + /* This callback informs us of the brightness level (from 0 to 255) */ + qdev_init_gpio_in_named(DEVICE(dev), sm_lcd_set_backlight_level_cb, + "backlight_level", 1); + + /* This callback informs us that the vibrate is on/orr */ + qdev_init_gpio_in_named(DEVICE(dev), sm_lcd_vibe_ctl, + "vibe_ctl", 1); + + /* This callback informs us that power is on/off */ + qdev_init_gpio_in_named(DEVICE(dev), sm_lcd_power_ctl, + "power_ctl", 1); + + return 0; +} + +static Property sm_lcd_init_properties[] = { + DEFINE_PROP_BOOL("rotate_display", lcd_state, rotate_display, true), + DEFINE_PROP_END_OF_LIST() +}; + +static void sm_lcd_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SSISlaveClass *k = SSI_SLAVE_CLASS(klass); + + k->init = sm_lcd_init; + k->transfer = sm_lcd_transfer; + k->cs_polarity = SSI_CS_LOW; + k->parent_class.reset = sm_lcd_reset; + dc->props = sm_lcd_init_properties; +} + +static const TypeInfo sm_lcd_info = { + .name = "sm-lcd", + .parent = TYPE_SSI_SLAVE, + .instance_size = sizeof(lcd_state), + .class_init = sm_lcd_class_init, +}; + +static void sm_lcd_register(void) +{ + type_register_static(&sm_lcd_info); +} + +type_init(sm_lcd_register); diff --git a/hw/display/pebble_snowy_display.c b/hw/display/pebble_snowy_display.c new file mode 100644 index 0000000000000..80baecf153fbf --- /dev/null +++ b/hw/display/pebble_snowy_display.c @@ -0,0 +1,2185 @@ +/*- + * Copyright (c) 2014 + * + * 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. + */ + +/* + * 8-bit color display connected through SPI bus. The 8 bits are organized as (starting from MSB): + * 2 bits red, 2 bits green, 2 bits blue, 2 bits of 0. + * + * This display is used in the Pebble Snowy platform and actually represents an FPGA connected + * to a LPM012A220A display. The FPGA implements the SPI interface. + * + * Some example colors: + * black: 0x00 + * white: 0xFC + * red: 0xC0 + * green: 0x30 + * blue: 0x0C + * + * + * This device implements various versions of the FPGA programming, identified by the + * PDisplayCmdSet enum: + * + * PDISPLAY_CMD_SET_0: + * ------------------- + * This is used by the boot loader and has cmd IDs that tell the FPGA to display pre-canned + * images + * + * + * PDISPLAY_CMD_SET_1: + * ------------------- + * The display expects complete frames to be setn through the SPI bus, one column at a time + * starting from the left-most column, each column sent from bottom to top. The bits and bytes + * in each column are scrambled however and need to be unscrambled before placing them into the + * framebuffer. + */ + +#include + +#include "qemu-common.h" +#include "ui/console.h" +#include "ui/pixel_ops.h" +#include "hw/ssi.h" +#include "pebble_snowy_display.h" +#include "pebble_snowy_display_overlays.h" + +//#define DEBUG_PEBBLE_SNOWY_DISPLAY +#ifdef DEBUG_PEBBLE_SNOWY_DISPLAY +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("PEBBLE_SNOWY_DISPLAY: " fmt , ## __VA_ARGS__); \ + usleep(1000); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + +// Colors +#define SNOWY_COLOR_BLACK 0 +#define SNOWY_COLOR_WHITE 0xFC +#define SNOWY_COLOR_RED 0xC0 +#define SNOWY_COLOR_GREEN 0x30 +#define SNOWY_COLOR_BLUE 0x0C + + +/* Various states the Display can be in */ +typedef enum { + PSDISPLAYSTATE_PROGRAMMING, + PSDISPLAYSTATE_ACCEPTING_CMD, + PSDISPLAYSTATE_ACCEPTING_PARAM, + PSDISPLAYSTATE_ACCEPTING_SCENE_BYTE, + PSDISPLAYSTATE_ACCEPTING_FRAME_DATA, // used in PSDISPLAY_CMD_SET_1 command set +} PSDisplayState; + +#ifdef DEBUG_PEBBLE_SNOWY_DISPLAY +static const char *s_display_state[] = { + "PSDISPLAYSTATE_PROGRAMMING", + "PSDISPLAYSTATE_ACCEPTING_CMD", + "PSDISPLAYSTATE_ACCEPTING_PARAM", + "PSDISPLAYSTATE_ACCEPTING_SCENE_BYTE", + "PSDISPLAYSTATE_ACCEPTING_FRAME_DATA" +}; +#endif + +// Which command set the FPGA is implementing +typedef enum { + PSDISPLAY_CMD_SET_UNKNOWN, + PSDISPLAY_CMD_SET_0, // Boot ROM built on Dec 10, 2014 + PSDISPLAY_CMD_SET_1, // FW ROM built on Jan 9, 2015 +} PDisplayCmdSet; + + +/* Commands for PSDISPLAY_CMD_SET_0. We accept these while in the + * PSDISPLAYSTATE_ACCEPTING_CMD state. These are implemented in the first boot loader + * ROM built Dec 2014 */ +typedef enum { + PSDISPLAYCMD0_NULL = 0, + PSDISPLAYCMD0_SET_PARAMETER = 1, + PSDISPLAYCMD0_DISPLAY_OFF = 2, + PSDISPLAYCMD0_DISPLAY_ON = 3, + PSDISPLAYCMD0_DRAW_SCENE = 4 +} PDisplayCmd0; + + +/* Commands for PSDISPLAY_CMD_SET_1. We accept these while in the + * PSDISPLAYSTATE_ACCEPTING_CMD state. These are implemented in the firmware + * buit Jan 2015 */ +typedef enum { + PSDISPLAYCMD1_FRAME_BEGIN = 5, +} PDisplayCmd1; + + +// Scene numbers put into cmd_parameter and used by the PSDISPLAYCMD0_DRAW_SCENE command. +typedef enum { + PSDISPLAYSCENE_BLACK = 0, + PSDISPLAYSCENE_SPLASH = 1, // splash screen + PSDISPLAYSCENE_UPDATE = 2, // firmware update + PSDISPLAYSCENE_ERROR = 3 // display error code +} PDisplayScene; + + +typedef struct { + SSISlave ssidev; + + // ----------------------------------------------------------------- + // Properties + union { + void *vdone_output; + qemu_irq done_output; + }; + + // This output line gets asserted (low) when we are done processing a drawing command. + // It is generally to an IRQ + union { + void *vintn_output; + qemu_irq intn_output; + }; + + uint32_t num_rows; + uint32_t num_cols; + int32_t num_border_rows; + int32_t num_border_cols; + uint8_t row_major; + uint8_t row_inverted; + uint8_t col_inverted; + uint8_t round_mask; + + // ------------------------------------------------------------------- + // Other state variables + QemuConsole *con; + bool redraw; + uint32_t bytes_per_row; + uint32_t bytes_per_frame; + uint8_t *framebuffer; + uint8_t *framebuffer_copy; + int col_index; + int row_index; + bool backlight_enabled; + float brightness; + bool power_on; + + /* State variables */ + PSDisplayState state; + uint8_t cmd; + uint32_t parameter; + uint32_t parameter_byte_offset; + PDisplayScene scene; + + bool sclk_value; + bool cs_value; // low means asserted + + bool vibrate_on; + int vibrate_offset; + + /* We capture the first 256 bytes of the programming and inspect it to try and figure + * out which command set to expect */ + uint8_t prog_header[256]; + uint32_t prog_byte_offset; + + // Which command set we are emulating + PDisplayCmdSet cmd_set; + +} PSDisplayGlobals; + +static uint8_t *get_pebble_logo_4colors_image(int *width, int *height); +static uint8_t *get_dead_face_image(int *width, int *height); +static uint8_t *get_small_pebble_logo_image(int *width, int *height); +static uint8_t *get_url_image(int *width, int *height); +static uint8_t *get_pixel_mask(void); + +static uint32_t display_bytes = 0; +static uint32_t frameno = 0; + +static void ps_set_state(PSDisplayGlobals *s, PSDisplayState new_state) { + DPRINTF("state change from %u (%s) to %u (%s) frame: %u - bytes: %u\n", + s->state, s_display_state[s->state], new_state, s_display_state[new_state], frameno, display_bytes); + s->state = new_state; +} + +// ----------------------------------------------------------------------------- +static void ps_set_redraw(PSDisplayGlobals *s) { + s->redraw = true; + memmove(s->framebuffer_copy, s->framebuffer, s->bytes_per_frame); +} + + +// ----------------------------------------------------------------------------- +static void ps_display_set_pixel(PSDisplayGlobals *s, uint32_t x, uint32_t y, + uint8_t pixel_byte) { + s->framebuffer[y * s->bytes_per_row + x] = pixel_byte; +} + + +// ----------------------------------------------------------------------------- +// Draw an 8-bits per pixel bitmap to the framebuffer +static void ps_display_draw_8bpp_bitmap(PSDisplayGlobals *s, uint8_t *bytes, + uint32_t x_offset, uint32_t y_offset, uint32_t width, uint32_t height) +{ + uint32_t pixels = width * height; + + int i; + for (i = 0; i < pixels; ++i) { + uint8_t value = bytes[i]; + uint8_t x = x_offset + (i % width); + uint8_t y = y_offset + (i / width); + ps_display_set_pixel(s, x, y, value); + } +} + +/* +// ----------------------------------------------------------------------------- +// Draw a 1-bit per pixel bitmap to the framebuffer +static void ps_display_draw_1bpp_bitmap(PSDisplayGlobals *s, uint8_t *bits, + uint32_t x_offset, uint32_t y_offset, uint32_t width, uint32_t height) { + uint32_t pixels = width * height; + + for (int i = 0; i < pixels; ++i) { + bool value = bits[i / 8] & (1 << (i % 8)); + uint8_t x = x_offset + (i % width); + uint8_t y = y_offset + (i / width); + if (value) { + ps_display_set_pixel(s, x, y, 0xFC); + } else { + ps_display_set_pixel(s, x, y, 0x00); + } + } +} +*/ + +/* ----------------------------------------------------------------------------- + Scan through the first part of the programming data and try and determine which + command set the FPGA is implementing. Here is an example of the data comprising + the programming for PSDISPLAY_CMD_SET_BOOT_0: + + 39F0: FF 00 4C 61 74 74 69 63 65 00 69 43 45 63 pG..Lattice.iCEc + 3A00: 75 62 65 32 20 32 30 31 34 2E 30 38 2E 32 36 37 ube2 2014.08.267 + 3A10: 32 33 00 50 61 72 74 3A 20 69 43 45 34 30 4C 50 23.Part: iCE40LP + 3A20: 31 4B 2D 43 4D 33 36 00 44 61 74 65 3A 20 44 65 1K-CM36.Date: De + 3A30: 63 20 31 30 20 32 30 31 34 20 30 38 3A 33 30 3A c 10 2014 08:30: + 3A40: 00 FF 31 38 00 7E AA 99 7E 51 00 01 05 92 00 20 ..18.~..~Q..... + 3A50: 62 01 4B 72 00 90 82 00 00 11 00 01 01 00 00 00 b.Kr........... */ +static void ps_display_determine_command_set(PSDisplayGlobals *s) +{ + // Table of programming header dates and command sets + typedef struct { + const char *date_str; + PDisplayCmdSet cmd_set; + } CommandSetInfo; + static const CommandSetInfo cmd_sets[] = { + {"Date: Dec 10 2014 08:30", PSDISPLAY_CMD_SET_0}, + {"Date: Jan 9 2015 10:49:47", PSDISPLAY_CMD_SET_1}, + {"Date: Jan 30 2015 15:11:", PSDISPLAY_CMD_SET_1}, + {"Date: Jan 30 2015 15:10:", PSDISPLAY_CMD_SET_1}, + }; + + + // Make sure prog_header is null terminated + if (s->prog_byte_offset >= sizeof(s->prog_header)) { + s->prog_byte_offset = sizeof(s->prog_header) - 1; + } + s->prog_header[s->prog_byte_offset] = 0; + + // Default one to use + s->cmd_set = PSDISPLAY_CMD_SET_1; + + // Skip first two bytes which contain 0xFF 00 + int i; + for (i=2; iprog_byte_offset; i++) { + const char *str_p = (const char *)s->prog_header + i; + + DPRINTF("%s: found '%s' string in programming header\n", __func__, str_p); + + // Look for a string that starts with "Date:" + if (!strncmp(str_p, "Date:", 5)) { + int n_cmd_sets = sizeof(cmd_sets) / sizeof(cmd_sets[0]); + int n; + for (n=0; ncmd_set = cmd_sets[n].cmd_set; + DPRINTF("%s: determined command set as %d\n", __func__, s->cmd_set); + return; + } + } + + // We didn't find the command set, bail + DPRINTF("PEBBLE_SNOWY_DISPLAY: Unknown FPGA programming with a date" + " stamp of '%s'. Defaulting to command set %d\n", str_p, s->cmd_set); + return; + } else { + // Skip this string + i += strlen(str_p); + } + + } + + // Couldn't find the "Date:" string + DPRINTF("PEBBLE_SNOWY_DISPLAY: Error parsing FPGA programming data to" + " determine command set. Defaulting to command set %d\n", s->cmd_set); + return; +} + + +// ----------------------------------------------------------------------------- +static void ps_display_reset_state(PSDisplayGlobals *s, bool assert_done) +{ + // If we are resetting because we done with the previous command, assert done + if (assert_done) { + DPRINTF("Asserting done interrupt\n"); + qemu_set_irq(s->intn_output, false); + } + + DPRINTF("Resetting state to accept command\n"); + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_CMD); + s->parameter_byte_offset = 0; +} + +// ----------------------------------------------------------------------------- +// Implements command PSDISPLAY_CMD_SET_0, used in the first boot ROM, built Dec 2014 +static void ps_display_execute_current_cmd_set0(PSDisplayGlobals *s) +{ + int width, height, x_offset, y_offset; + uint8_t *pixels; + + DPRINTF("ps_display_execute_current_cmd_set0: cmd: %u -- cs: %s\n", s->cmd, s->cs_value ? "Not CS" : "CS"); + switch (s->cmd) { + case PSDISPLAYCMD0_NULL: + DPRINTF("Executing command: NULL\n"); + ps_display_reset_state(s, true /*assert_done*/); + break; + + case PSDISPLAYCMD0_SET_PARAMETER: + DPRINTF("Executing command: SET_PARAMETER\n"); + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_PARAM); + s->parameter_byte_offset = 0; + break; + + case PSDISPLAYCMD0_DISPLAY_OFF: + DPRINTF("Executing command: DISPLAY_OFF\n"); + ps_display_reset_state(s, true /*assert_done*/); + break; + + case PSDISPLAYCMD0_DISPLAY_ON: + DPRINTF("Executing command: DISPLAY_ON\n"); + ps_display_reset_state(s, true /*assert_done*/); + break; + + case PSDISPLAYCMD0_DRAW_SCENE: + if (s->state == PSDISPLAYSTATE_ACCEPTING_CMD) { + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_SCENE_BYTE); + } else if (s->state == PSDISPLAYSTATE_ACCEPTING_SCENE_BYTE) { + DPRINTF("Executing command: DRAW_SCENE: %d\n", s->scene); + switch (s->scene) { + case PSDISPLAYSCENE_BLACK: + memset(s->framebuffer, SNOWY_COLOR_BLACK, s->bytes_per_frame); + break; + case PSDISPLAYSCENE_SPLASH: + pixels = get_pebble_logo_4colors_image(&width, &height); + x_offset = (s->num_cols - width)/2; + y_offset = (s->num_rows - height)/2; + ps_display_draw_8bpp_bitmap(s, pixels, x_offset, y_offset, width, height); + break; + case PSDISPLAYSCENE_UPDATE: + // NOTE: We do not yet support showing the progress bar, which should show + // the progress percent as indicated by s->parameter + pixels = get_small_pebble_logo_image(&width, &height); + x_offset = (s->num_cols - width)/2; + y_offset = s->num_rows - height - 88; + ps_display_draw_8bpp_bitmap(s, pixels, x_offset, y_offset, width, height); + break; + case PSDISPLAYSCENE_ERROR: + // NOTE: We do not yet support showing the error code, which should show + // the error in hex as indicated by s->parameter + pixels = get_dead_face_image(&width, &height); + x_offset = (s->num_cols - width)/2; + y_offset = s->num_rows - height - 92; + ps_display_draw_8bpp_bitmap(s, pixels, x_offset, y_offset, width, height); + + pixels = get_url_image(&width, &height); + x_offset = (s->num_cols - width)/2; + y_offset = (s->num_rows - height - 10); + ps_display_draw_8bpp_bitmap(s, pixels, x_offset, y_offset, width, height); + break; + default: + DPRINTF("PEBBLE_SNOWY_DISPLAY: Unsupported scene: %d\n", s->scene); + break; + } + ps_display_reset_state(s, true /*assert_done*/); + ps_set_redraw(s); + } else { + DPRINTF("PEBBLE_SNOWY_DISPLAY: Tried to execute draw scene in " + "wrong state: %d\n", s->state); + ps_display_reset_state(s, true /*assert_done*/); + } + break; + + default: + DPRINTF("PEBBLE_SNOWY_DISPLAY: Unsupported cmd: %d\n", s->cmd); + ps_display_reset_state(s, true /*assert_done*/); + break; + } +} + +// ----------------------------------------------------------------------------- +// Implements command set PSDISPLAY_CMD_SET_1, used in the firmware, built Jan 2015 +static void ps_display_execute_current_cmd_set1(PSDisplayGlobals *s) +{ + + DPRINTF("ps_display_execute_current_cmd_set1: cmd: %u -- cs: %s\n", s->cmd, s->cs_value ? "Not CS" : "CS"); + switch (s->cmd) { + case PSDISPLAYCMD1_FRAME_BEGIN: + DPRINTF("Executing command: FRAME_BEGIN\n"); + if (s->row_major) { + if (s->row_inverted) { + // Expect to be sent rows, bottom to top + s->row_index = s->num_rows - s->num_border_rows - 1; + s->col_index = s->num_border_cols; + } else { + // Expect to be sent rows, top to bottom + s->row_index = s->num_border_rows; + s->col_index = s->num_border_cols; + } + } else { + // Expect to be sent columns, left to right + s->row_index = s->num_rows - s->num_border_rows - 1; + s->col_index = s->num_border_cols; + } + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_FRAME_DATA); + // Just say we are done immediately. We can accept more data right away. + qemu_set_irq(s->intn_output, false); + break; + + default: + DPRINTF("PEBBLE_SNOWY_DISPLAY: Unsupported cmd: %d\n", s->cmd); + ps_display_reset_state(s, true /*assert_done*/); + break; + } +} + + +// ----------------------------------------------------------------------------- +static void ps_display_cmd_set_2_unscramble_column(PSDisplayGlobals *s, uint32_t col_index) +{ + int row_idx; + const int line_bytes = s->num_rows - 2 * s->num_border_rows; + uint8_t col_buffer[line_bytes]; + + // Copy the column into temp buffer first, without border pixels + for (row_idx = 0; row_idx < line_bytes; row_idx++) { + col_buffer[row_idx] = s->framebuffer[(row_idx + s->num_border_rows) * s->bytes_per_row + + col_index]; + } + + // Unscramble the bytes in the scanline. + // + // In the desription below, the bits in the first pixel in a column are + // identified as follows: + // r0_msb r0_lsb g0_msb g0_lsb b0_msb b0_lsb 0 0 + // The second pixel: + // r1_msb r1_lsb g1_msb g1_lsb b1_msb b1_lsb 0 0 + // + // Each scan line contains N bytes of data for the N pixels. + // [LSB0 LSB2 .................LSBN MSB0 MSB2 ....................MSBN] + // + // LSB0 contains the following bits: + // 0 0 r1_lsb r0_lsb g1_lsb g0_lsb b1_lsb b0_lsb + // MSB0 contains the following bits: + // 0 0 r1_msb r0_msb g1_msb g0_msb b1_msb b0_msb + + // LSB2 contains the following bits: + // 0 0 r3_lsb r2_lsb g3_lsb g2_lsb b3_lsb b2_lsb + // MSB2 contains the following bits: + // 0 0 r3_msb r2_msb g3_msb g2_msb b3_msb b2_msb + // + uint8_t ms_bits, ls_bits; + for (row_idx = 0; row_idx < line_bytes; row_idx += 2) { + ls_bits = col_buffer[row_idx/2]; + ms_bits = col_buffer[row_idx/2 + line_bytes/2]; + + // Form the 2 pixels whose data is found in ls_bits and ms_bits + uint8_t pixel_0, pixel_1; + pixel_0 = ((ms_bits & 0b00010101) << 1) | (ls_bits & 0b00010101); + pixel_0 <<= 2; + pixel_1 = (ms_bits & 0b00101010) | ((ls_bits & 0b00101010) >> 1); + pixel_1 <<= 2; + + // Write them to the frame buffer + s->framebuffer[(row_idx + s->num_border_rows) * s->bytes_per_row + + col_index] = pixel_0; + s->framebuffer[(row_idx + s->num_border_rows + 1) * s->bytes_per_row + + col_index] = pixel_1; + } +} + + +// ----------------------------------------------------------------------------- +static void ps_display_cmd_set_2_unscramble_row(PSDisplayGlobals *s, uint32_t row_index) +{ + const int line_bytes = s->num_cols - 2 * s->num_border_cols; + uint8_t row_buffer[line_bytes]; + uint8_t *fb = &s->framebuffer[row_index * s->bytes_per_row + s->num_border_cols]; + + // Copy the row into temp buffer first, without border pixels + memcpy(row_buffer, fb, line_bytes); + + // Unscramble the bytes in the scanline. + // + // In the desription below, the bits in the first pixel in a column are + // identified as follows: + // r0_msb r0_lsb g0_msb g0_lsb b0_msb b0_lsb 0 0 + // The second pixel: + // r1_msb r1_lsb g1_msb g1_lsb b1_msb b1_lsb 0 0 + // + // Each scan line contains N bytes of data for the N pixels. + // [LSB0 LSB2 .................LSBN MSB0 MSB2 ....................MSBN] + // + // LSB0 contains the following bits: + // 0 0 r1_lsb r0_lsb g1_lsb g0_lsb b1_lsb b0_lsb + // MSB0 contains the following bits: + // 0 0 r1_msb r0_msb g1_msb g0_msb b1_msb b0_msb + + // LSB2 contains the following bits: + // 0 0 r3_lsb r2_lsb g3_lsb g2_lsb b3_lsb b2_lsb + // MSB2 contains the following bits: + // 0 0 r3_msb r2_msb g3_msb g2_msb b3_msb b2_msb + // + for (int col_idx = 0; col_idx < line_bytes; col_idx += 2) { + const uint8_t ms_bits = row_buffer[col_idx / 2]; + const uint8_t ls_bits = row_buffer[col_idx / 2 + line_bytes / 2]; + + // Form the 2 pixels whose data is found in ls_bits and ms_bits + uint8_t pixel_0, pixel_1; + pixel_0 = ((ms_bits & 0b00010101) << 1) | (ls_bits & 0b00010101); + pixel_0 <<= 2; + pixel_1 = (ms_bits & 0b00101010) | ((ls_bits & 0b00101010) >> 1); + pixel_1 <<= 2; + + // Write them to the frame buffer + if (s->col_inverted) { + fb[line_bytes - col_idx - 2] = pixel_0; + fb[line_bytes - col_idx - 1] = pixel_1; + } else { + fb[col_idx] = pixel_1; + fb[col_idx + 1] = pixel_0; + } + } +} + +static bool newdisp = true; + +// ----------------------------------------------------------------------------- +static uint32_t ps_display_transfer(SSISlave *dev, uint32_t data) +{ + ++display_bytes; + PSDisplayGlobals *s = FROM_SSI_SLAVE(PSDisplayGlobals, dev); + uint32_t data_byte = data & 0x00FF; + + //DPRINTF("rcv byte: 0x%02x\n", data_byte); + + /* Ignore incoming data if our chip select is not asserted */ + if (s->cs_value) { + if (s->state != PSDISPLAYSTATE_PROGRAMMING) { + DPRINTF("PEBBLE_SNOWY_DISPLAY: received data without CS asserted"); + } + return 0; + } + + switch(s->state) { + case PSDISPLAYSTATE_PROGRAMMING: + // Capture the start of the programming data + if (s->prog_byte_offset < sizeof(s->prog_header)) { + s->prog_header[s->prog_byte_offset++] = data_byte; + } + break; + + case PSDISPLAYSTATE_ACCEPTING_CMD: + s->cmd = data_byte; + DPRINTF("received command %d, deasserting done interrupt\n", s->cmd); + + // Start of a command. Deassert done interrupt, it will get asserted again when + // ps_display_reset_state() is called at the end of the command + qemu_set_irq(s->intn_output, true); + + if (s->cmd_set == PSDISPLAY_CMD_SET_0) { + ps_display_execute_current_cmd_set0(s); + } else if (s->cmd_set == PSDISPLAY_CMD_SET_1) { + ps_display_execute_current_cmd_set1(s); + } else { + DPRINTF("Unimplemeneted command set\n"); + abort(); + } + break; + + case PSDISPLAYSTATE_ACCEPTING_PARAM: + + DPRINTF("received param byte %d\n", data_byte); + /* Params are sent low byte first */ + if (s->parameter_byte_offset == 0) { + s->parameter = (s->parameter & 0xFFFFFF00) | data_byte; + } else if (s->parameter_byte_offset == 1) { + s->parameter = (s->parameter & 0xFFFF00FF) | (data_byte << 8); + } else if (s->parameter_byte_offset == 2) { + s->parameter = (s->parameter & 0xFF00FFFF) | (data_byte << 16); + } else if (s->parameter_byte_offset == 3) { + s->parameter = (s->parameter & 0x00FFFFFF) | (data_byte << 24); + } else { + DPRINTF("PEBBLE_SNOWY_DISPLAY: received more than 4 bytes of parameter"); + } + + s->parameter_byte_offset++; + if (s->parameter_byte_offset >= 4) { + DPRINTF("assembled complete param value of %d\n", s->parameter); + ps_display_reset_state(s, true /*assert_done*/); + } + break; + + case PSDISPLAYSTATE_ACCEPTING_SCENE_BYTE: + s->scene = data_byte; + DPRINTF("received scene ID: %d\n", s->scene); + ps_display_execute_current_cmd_set0(s); + break; + + case PSDISPLAYSTATE_ACCEPTING_FRAME_DATA: + if (newdisp) { + DPRINTF("New frame? -- 0x%02X, row %d, col %d -- bytes: %u -- cs: %s\n", data, s->row_index, s->col_index, display_bytes, s->cs_value ? "Not CS" : "CS"); + newdisp = false; + } + s->framebuffer[s->row_index * s->bytes_per_row + s->col_index] = data; + if (s->row_major) { + // We get sent one row at a time + s->col_index++; + if (s->col_index >= s->num_cols - s->num_border_cols) { + // Reached end of row, unscramble the one we just received and go onto the + // next row + ps_display_cmd_set_2_unscramble_row(s, s->row_index); + s->col_index = s->num_border_cols; + bool got_last_byte; + if (s->row_inverted) { + s->row_index--; + got_last_byte = (s->row_index < s->num_border_rows); + } else { + s->row_index++; + got_last_byte = (s->row_index >= s->num_rows - s->num_border_rows); + } + if (got_last_byte) { + DPRINTF("Got last byte in frame (row) row %d, col %d -- bytes: %u\n", + s->row_index, s->col_index, display_bytes); + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_CMD); + ps_set_redraw(s); + newdisp = true; + ++frameno; + } + } + } else { + // We get sent one column at a time + s->row_index--; + if (s->row_index < s->num_border_rows) { + // Reached top of column, unscramble the one we just received and go onto the + // next column + ps_display_cmd_set_2_unscramble_column(s, s->col_index); + s->row_index = s->num_rows - s->num_border_rows - 1; + s->col_index += 1; + if (s->col_index >= s->num_cols - s->num_border_cols) { + DPRINTF("Got last byte in frame (col) row %d, col %d\n", s->row_index, s->col_index); + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_CMD); + ps_set_redraw(s); + newdisp = true; + ++frameno; + } + } + } + break; + } + return 0; +} + + +// ----------------------------------------------------------------------------- +// This function maps an 8 bit value from the frame buffer into red, green, and blue +// components +static PSDisplayPixelColor ps_display_get_rgb(PSDisplayGlobals *s, uint8_t pixel_value) { + + PSDisplayPixelColor c; + c.red = ((pixel_value & 0xC0) >> 6) * 255 / 3; + c.green = ((pixel_value & 0x30) >> 4) * 255 / 3; + c.blue = ((pixel_value & 0x0C) >> 2) * 255 / 3; + + // Adjust the pixel RGB to compensate for the set brightness. + // brightness = 0: 255 in maps to 170 out + // brightness = 1.0: 255 in maps to 255 out + float brightness = s->backlight_enabled ? s->brightness : 0.0; + int max_val = 170 + (255 - 170) * brightness; + c.red = (int)c.red * max_val/255; + c.green = (int)c.green * max_val/255; + c.blue = (int)c.blue * max_val/255; + + return c; + + /* + static PSDisplayPixelColors[256] = { + {0, 0, 0 }, + }; + + return PSDisplayPixelColors[pixel_value]; + */ +} + + +// ----------------------------------------------------------------------------- +static void ps_display_update_display(void *arg) +{ + PSDisplayGlobals *s = arg; + uint8_t *d; + int x, y, bpp, rgb_value; + + DisplaySurface *surface = qemu_console_surface(s->con); + bpp = surface_bits_per_pixel(surface); + d = surface_data(surface); + + + // If vibrate is on, simply jiggle the display + if (s->vibrate_on) { + if (s->vibrate_offset == 0) { + s->vibrate_offset = 2; + } + int bytes_per_pixel; + switch (bpp) { + case 8: + bytes_per_pixel = 1; + break; + case 15: + case 16: + bytes_per_pixel = 2; + break; + case 32: + bytes_per_pixel = 4; + break; + default: + abort(); + } + int total_bytes = s->num_rows * s->num_cols * bytes_per_pixel + - abs(s->vibrate_offset) * bytes_per_pixel; + if (s->vibrate_offset > 0) { + memmove(d, d + s->vibrate_offset * bytes_per_pixel, total_bytes); + } else { + memmove(d - s->vibrate_offset * bytes_per_pixel, d, total_bytes); + } + s->vibrate_offset *= -1; + dpy_gfx_update(s->con, 0, 0, s->num_cols, s->num_rows); + return; + } + + if (!s->redraw) { + return; + } + + const bool is_spalding = s->round_mask; + const PSDisplayPixelColorWithAlpha *overlay = is_spalding ? g_spalding_overlay : NULL; + uint8_t *pixel_mask = get_pixel_mask(); + for (y = 0; y < s->num_rows; y++) { + for (x = 0; x < s->num_cols; x++) { + uint32_t offset = y * s->bytes_per_row + x; + uint8_t pixel = s->framebuffer_copy[offset]; + if (s->round_mask) { + // Compute the vertical distance from top or bottom edge, whichever is closest + int vert_distance = y; + if (vert_distance >= s->num_rows/2) { + vert_distance = s->num_rows - 1 - y ; + } + int mask_width = pixel_mask[vert_distance]; + if (x < mask_width || x >= s->num_cols - mask_width) { + pixel = 0; + } + } + + PSDisplayPixelColor color = ps_display_get_rgb(s, pixel); + if (overlay) { + const PSDisplayPixelColorWithAlpha blend_color = overlay[offset]; + const int32_t factor_over = blend_color.alpha; + const int32_t factor_dest = 255 - blend_color.alpha; + color.red = MIN(255, (factor_over * blend_color.color.red + factor_dest * color.red) / 255); + color.green = MIN(255,(factor_over * blend_color.color.green + factor_dest * color.green) / 255); + color.blue = MIN(255, (factor_over * blend_color.color.blue + factor_dest * color.blue) / 255); + } + + switch(bpp) { + case 8: + *((uint8_t *)d) = rgb_to_pixel8(color.red, color.green, color.blue); + d++; + break; + case 15: + *((uint16_t *)d) = rgb_to_pixel15(color.red, color.green, color.blue);; + d += 2; + break; + case 16: + *((uint16_t *)d) = rgb_to_pixel16(color.red, color.green, color.blue);; + d += 2; + break; + case 24: + rgb_value = rgb_to_pixel24(color.red, color.green, color.blue); + *d++ = (rgb_value & 0x00FF0000) >> 16; + *d++ = (rgb_value & 0x0000FF00) >> 8; + *d++ = (rgb_value & 0x000000FF); + break; + case 32: + *((uint32_t *)d) = rgb_to_pixel32(color.red, color.green, color.blue);; + d += 4; + break; + } + } + } + + dpy_gfx_update(s->con, 0, 0, s->num_cols, s->num_rows); + s->redraw = false; +} + +// ----------------------------------------------------------------------------- +static int ps_display_set_cs(SSISlave *dev, bool value) +{ + PSDisplayGlobals *s = FROM_SSI_SLAVE(PSDisplayGlobals, dev); + + DPRINTF("CS changed to %d\n", value); + s->cs_value = value; + + // When CS goes up (unasserted), we are done programming + if (value && s->state == PSDISPLAYSTATE_PROGRAMMING) { + DPRINTF("Exiting programming mode\n"); + ps_display_reset_state(s, true /*assert_done*/); + + // Try and figure out which command set the FPGA expects by parsing the + // programming data + ps_display_determine_command_set(s); + } + + return 0; +} + +// ----------------------------------------------------------------------------- +static void ps_display_set_reset_pin_cb(void *opaque, int n, int level) +{ + PSDisplayGlobals *s = FROM_SSI_SLAVE(PSDisplayGlobals, opaque); + bool value = !!level; + assert(n == 0); + + DPRINTF("RESET changed to %d\n", value); + qemu_set_irq(s->done_output, false); + + // When reset goes high, sample the CS input to see what state we should be in + // if CS is low, expect new FPGA programming to arrive + // if CS is high, assume we will be using the bootloader configuration + if (value) { + // After a reset, we are not done. De-assert our interrupt (asserted low). + qemu_set_irq(s->intn_output, true); + + if (s->cs_value) { + // Assume we are using the bootloader configuration + s->cmd_set = PSDISPLAY_CMD_SET_0; + ps_display_reset_state(s, true); + } else { + ps_set_state(s, PSDISPLAYSTATE_PROGRAMMING); + s->prog_byte_offset = 0; + } + } +} + +// ----------------------------------------------------------------------------- +static void ps_display_set_sclk_pin_cb(void *opaque, int n, int level) +{ + PSDisplayGlobals *s = FROM_SSI_SLAVE(PSDisplayGlobals, opaque); + assert(n == 0); + + /* Save new value */ + s->sclk_value = !!level; +} + + +// ----------------------------------------------------------------------------- +static void ps_display_invalidate_display(void *arg) +{ + PSDisplayGlobals *s = arg; + s->redraw = true; +} + +// ----------------------------------------------------------------------------- +static const GraphicHwOps ps_display_ops = +{ + .gfx_update = ps_display_update_display, + .invalidate = ps_display_invalidate_display, +}; + + +// ----------------------------------------------------------------------------- +static void ps_display_backlight_enable_cb(void *opaque, int n, int level) +{ + PSDisplayGlobals *s = (PSDisplayGlobals *)opaque; + assert(n == 0); + + bool enable = (level != 0); + if (s->backlight_enabled != enable) { + s->backlight_enabled = enable; + s->redraw = true; + } +} + + +// ----------------------------------------------------------------------------- +// Set brightness, from 0 to 255 +static void ps_display_set_backlight_level_cb(void *opaque, int n, int level) +{ + PSDisplayGlobals *s = (PSDisplayGlobals *)opaque; + assert(n == 0); + + float bright_f = (float)level / 255; + + // Temp hack - the Pebble sets the PWM to 25% for max brightness + float new_setting = MIN(1.0, bright_f * 4); + if (new_setting != s->brightness) { + s->brightness = MIN(1.0, bright_f * 4); + if (s->backlight_enabled) { + s->redraw = true; + } + } +} + +// ----------------------------------------------------------------------------- +static void ps_display_vibe_ctl(void *opaque, int n, int level) +{ + PSDisplayGlobals *s = (PSDisplayGlobals *)opaque; + assert(n == 0); + + s->vibrate_on = (level != 0); + s->redraw = true; +} + + +// ----------------------------------------------------------------------------- +static void ps_display_power_ctl(void *opaque, int n, int level) +{ + PSDisplayGlobals *s = (PSDisplayGlobals *)opaque; + assert(n == 0); + + if (!level && s->power_on) { + memset(s->framebuffer, 0, s->bytes_per_frame); + ps_set_redraw(s); + s->power_on = false; + } + s->power_on = !!level; +} + + +// ----------------------------------------------------------------------------- +static void ps_display_reset(DeviceState *dev) +{ + PSDisplayGlobals *s = (PSDisplayGlobals *)dev; + memset(s->framebuffer, 0, s->bytes_per_frame); + ps_set_redraw(s); +} + + +// ----------------------------------------------------------------------------- +static int ps_display_init(SSISlave *dev) +{ + PSDisplayGlobals *s = FROM_SSI_SLAVE(PSDisplayGlobals, dev); + + s->brightness = 0.0; + s->backlight_enabled = false; + s->cmd_set = PSDISPLAY_CMD_SET_0; + ps_set_state(s, PSDISPLAYSTATE_ACCEPTING_CMD); + + // Allocate the frame buffer + s->bytes_per_row = s->num_cols; + s->bytes_per_frame = s->bytes_per_row * s->num_rows; + s->framebuffer = g_malloc(s->num_rows * s->bytes_per_row); + s->framebuffer_copy = g_malloc(s->num_rows * s->bytes_per_row); + + s->con = graphic_console_init(DEVICE(dev), 0, &ps_display_ops, s); + qemu_console_resize(s->con, s->num_cols, s->num_rows); + + /* Create our inputs that will be connected to GPIOs from the STM32 */ + qdev_init_gpio_in_named(DEVICE(dev), ps_display_set_reset_pin_cb, + "reset", 1); + + /* Create our inputs that will be connected to GPIOs from the STM32 */ + qdev_init_gpio_in_named(DEVICE(dev), ps_display_set_sclk_pin_cb, + "sclk", 1); + + /* This callback informs us that brightness control is enabled */ + qdev_init_gpio_in_named(DEVICE(dev), ps_display_backlight_enable_cb, + "backlight_enable", 1); + + /* This callback informs us of the brightness level (from 0 to 255) */ + qdev_init_gpio_in_named(DEVICE(dev), ps_display_set_backlight_level_cb, + "backlight_level", 1); + + /* This callback informs us that the vibrate is on/orr */ + qdev_init_gpio_in_named(DEVICE(dev), ps_display_vibe_ctl, + "vibe_ctl", 1); + + /* This callback informs us that power is on/orr */ + qdev_init_gpio_in_named(DEVICE(dev), ps_display_power_ctl, + "power_ctl", 1); + + return 0; +} + +// ----------------------------------------------------------------------------- +static Property ps_display_init_properties[] = { + DEFINE_PROP_PTR("done_output", PSDisplayGlobals, vdone_output), + + // NOTE: The "done" flag, asserted low. If unasserted (high), the MPU asssumes the + // display is busy. + DEFINE_PROP_PTR("intn_output", PSDisplayGlobals, vintn_output), + + DEFINE_PROP_UINT32("num_rows", PSDisplayGlobals, num_rows, 172), + DEFINE_PROP_UINT32("num_cols", PSDisplayGlobals, num_cols, 168), + DEFINE_PROP_INT32("num_border_rows", PSDisplayGlobals, num_border_rows, 2), + DEFINE_PROP_INT32("num_border_cols", PSDisplayGlobals, num_border_cols, 2), + DEFINE_PROP_UINT8("row_major", PSDisplayGlobals, row_major, 0), + DEFINE_PROP_UINT8("row_inverted", PSDisplayGlobals, row_inverted, 0), + DEFINE_PROP_UINT8("col_inverted", PSDisplayGlobals, col_inverted, 0), + DEFINE_PROP_UINT8("round_mask", PSDisplayGlobals, round_mask, 0), + + DEFINE_PROP_END_OF_LIST() +}; + + +// ----------------------------------------------------------------------------- +static void ps_display_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SSISlaveClass *k = SSI_SLAVE_CLASS(klass); + + dc->props = ps_display_init_properties; + k->init = ps_display_init; + k->transfer = ps_display_transfer; + k->cs_polarity = SSI_CS_LOW; + k->set_cs = ps_display_set_cs; + k->parent_class.reset = ps_display_reset; +} + +// ----------------------------------------------------------------------------- +static const TypeInfo ps_display_info = { + .name = "pebble-snowy-display", + .parent = TYPE_SSI_SLAVE, + .instance_size = sizeof(PSDisplayGlobals), + .class_init = ps_display_class_init, +}; + +// ----------------------------------------------------------------------------- +static void ps_display_register(void) +{ + type_register_static(&ps_display_info); +} + +// ----------------------------------------------------------------------------- +type_init(ps_display_register); + + +// ------------------------------------------------------------------------- +// The Spalding round display is logically a square 180x180 display with +// some of the pixels hidden under a mask or missing entirely. The mask +// is symmetrical both horizontally and vertically: the masks on the +// left and right side of a line are equal, and the mask on the top half +// of the display is a mirror image of the bottom half. +// +// This array maps the number of pixels masked off for one quadrant of +// the display. Array element zero is the number of masked pixels from +// a display corner inwards. Subsequent array elements contain the mask +// for the adjacent rows or columns moving inwards towards the center +// of the display. +static uint8_t *get_pixel_mask(void) { + + static uint8_t pixel_mask[] = { + 76, 71, 66, 63, 60, 57, 55, 52, 50, 48, 46, 45, 43, 41, 40, 38, 37, + 36, 34, 33, 32, 31, 29, 28, 27, 26, 25, 24, 23, 22, 22, 21, 20, 19, + 18, 18, 17, 16, 15, 15, 14, 13, 13, 12, 12, 11, 10, 10, 9, 9, 8, 8, 7, + 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + return pixel_mask; +} + + +static uint8_t *get_pebble_logo_4colors_image(int *width, int *height) { + + // C struct format image converted from 'pebble_logo_4colors.png using png_to_cstruct.py' + *width = 110; + *height = 30; + static uint8_t pebble_logo_4colors[3300] = { + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, 0xa8, 0xa8, 0xa8, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xa8, 0xa8, 0xa8, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, + 0xa8, 0xa8, 0xa8, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0xfc, 0xfc, 0xfc, 0xa8, 0xa8, 0xa8, 0xfc, 0xfc, 0xfc, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0xa8, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x54, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xfc, 0xfc, 0xfc, 0xa8, 0xa8, 0xa8, 0xfc, 0xfc, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, + + 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xa8, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, + 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0xfc, 0xfc, + 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0xa8, 0xfc, 0xfc, 0xa8, 0x54, + 0x00, 0x00, 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, + 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0x54, + 0x00, 0x00, + + 0x00, 0x00, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0xfc, 0xfc, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, + 0x00, 0x00, + + 0x00, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, + 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x54, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, + 0xa8, 0x00, + + 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, + 0x54, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0x54, + + 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xfc, 0xa8, + + 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, + 0xa8, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, 0xa8, + 0xfc, 0xfc, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0xa8, 0xa8, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0x54, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x54, 0xa8, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xa8, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, 0x00, 0xfc, 0xfc, 0x54, + 0x54, 0xa8, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0xa8, 0x54, + 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xfc, 0x54, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x54, 0xa8, + 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0xa8, 0x54, 0x54, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xa8, 0xa8, 0x54, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0x54, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xa8, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x54, + + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xa8, + 0x54, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x54, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xa8, + + 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xa8, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xfc, 0xa8, + + 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, + 0x54, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0x00, + + 0xfc, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, + 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x54, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, + 0xa8, 0x00, + + 0xfc, 0xa8, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa8, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, + 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xa8, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0xa8, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xa8, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, + 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0xa8, 0x54, + 0x00, 0x00, 0x00, 0x54, 0xa8, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xfc, + 0xfc, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, 0xa8, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x54, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa8, 0xfc, 0xfc, 0x54, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xa8, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, 0xa8, 0xa8, 0xa8, 0x54, + 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0xa8, 0xa8, 0xfc, 0xa8, 0xa8, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xa8, 0xa8, 0xa8, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xa8, + 0xa8, 0xa8, 0xa8, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xa8, 0xa8, 0xfc, 0xa8, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + 0xfc, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + }; + return pebble_logo_4colors; +} + + +// C struct format image converted from 'dead_face.png' using png_to_cstruct.py +static uint8_t *get_dead_face_image(int *width, int *height) { + + *width = 88; + *height = 44; + static uint8_t dead_face[3872] = { + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0x00, + + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, + + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xfc, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, + + }; + return dead_face; +} + +// C struct format image converted from 'small_pebble_logo.png' using png_to_cstruct.py +static uint8_t *get_small_pebble_logo_image(int *width, int *height) { + + *width = 67; + *height = 18; + static uint8_t small_pebble_logo[1206] = { + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + }; + return small_pebble_logo; +} + + +// C struct format image converted from 'url.png' using png_to_cstruct.py +static uint8_t *get_url_image(int *width, int *height) { + + *width = 125; + *height = 14; + static uint8_t url[1750] = { + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, + 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, + + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + + 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0x00, + + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0x00, + + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0x00, + + 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0x00, + + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, + 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0x00, + + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, + 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, + 0xfc, 0xfc, 0x00, 0x00, 0x00, + + 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + + }; + return url; +} diff --git a/hw/display/pebble_snowy_display.h b/hw/display/pebble_snowy_display.h new file mode 100644 index 0000000000000..80a091472b325 --- /dev/null +++ b/hw/display/pebble_snowy_display.h @@ -0,0 +1,12 @@ +#pragma once + +#include "qemu-common.h" + +typedef struct { + uint8_t red, green, blue; +} PSDisplayPixelColor; + +typedef struct { + uint8_t alpha; + PSDisplayPixelColor color; +} PSDisplayPixelColorWithAlpha; diff --git a/hw/display/pebble_snowy_display_overlays.h b/hw/display/pebble_snowy_display_overlays.h new file mode 100644 index 0000000000000..4741665551f04 --- /dev/null +++ b/hw/display/pebble_snowy_display_overlays.h @@ -0,0 +1,32416 @@ +#pragma once + +#include "pebble_snowy_display.h" + +// from PIL import Image +// im = Image.open('qemu-spalding-overlay.png') +// px = im.load() +// print "const PSDisplayPixelColorWithAlpha *g_spalding_overlay = (PSDisplayPixelColorWithAlpha[]){" +// for y in range(im.size[1]): +// for x in range(im.size[0]): +// color = px[x, y] +// print " {%3d, {%3d, %3d, %3d}}, // (%3d, %3d)" % (color[3], color[0], color[1], color[2], x, y) +// print "};" + +const PSDisplayPixelColorWithAlpha *g_spalding_overlay = (PSDisplayPixelColorWithAlpha[]){ + {128, { 0, 0, 0}}, // ( 0, 0) + {128, { 0, 0, 0}}, // ( 1, 0) + {128, { 0, 0, 0}}, // ( 2, 0) + {128, { 0, 0, 0}}, // ( 3, 0) + {128, { 0, 0, 0}}, // ( 4, 0) + {128, { 0, 0, 0}}, // ( 5, 0) + {128, { 0, 0, 0}}, // ( 6, 0) + {128, { 0, 0, 0}}, // ( 7, 0) + {128, { 0, 0, 0}}, // ( 8, 0) + {128, { 0, 0, 0}}, // ( 9, 0) + {128, { 0, 0, 0}}, // ( 10, 0) + {128, { 0, 0, 0}}, // ( 11, 0) + {128, { 0, 0, 0}}, // ( 12, 0) + {128, { 0, 0, 0}}, // ( 13, 0) + {128, { 0, 0, 0}}, // ( 14, 0) + {128, { 0, 0, 0}}, // ( 15, 0) + {128, { 0, 0, 0}}, // ( 16, 0) + {128, { 0, 0, 0}}, // ( 17, 0) + {128, { 0, 0, 0}}, // ( 18, 0) + {128, { 0, 0, 0}}, // ( 19, 0) + {128, { 0, 0, 0}}, // ( 20, 0) + {128, { 0, 0, 0}}, // ( 21, 0) + {128, { 0, 0, 0}}, // ( 22, 0) + {128, { 0, 0, 0}}, // ( 23, 0) + {128, { 0, 0, 0}}, // ( 24, 0) + {128, { 0, 0, 0}}, // ( 25, 0) + {128, { 0, 0, 0}}, // ( 26, 0) + {128, { 0, 0, 0}}, // ( 27, 0) + {128, { 0, 0, 0}}, // ( 28, 0) + {128, { 0, 0, 0}}, // ( 29, 0) + {128, { 0, 0, 0}}, // ( 30, 0) + {128, { 0, 0, 0}}, // ( 31, 0) + {128, { 0, 0, 0}}, // ( 32, 0) + {128, { 0, 0, 0}}, // ( 33, 0) + {128, { 0, 0, 0}}, // ( 34, 0) + {128, { 0, 0, 0}}, // ( 35, 0) + {128, { 0, 0, 0}}, // ( 36, 0) + {128, { 0, 0, 0}}, // ( 37, 0) + {128, { 0, 0, 0}}, // ( 38, 0) + {128, { 0, 0, 0}}, // ( 39, 0) + {128, { 0, 0, 0}}, // ( 40, 0) + {128, { 0, 0, 0}}, // ( 41, 0) + {128, { 0, 0, 0}}, // ( 42, 0) + {128, { 0, 0, 0}}, // ( 43, 0) + {128, { 0, 0, 0}}, // ( 44, 0) + {128, { 0, 0, 0}}, // ( 45, 0) + {128, { 0, 0, 0}}, // ( 46, 0) + {128, { 0, 0, 0}}, // ( 47, 0) + {128, { 0, 0, 0}}, // ( 48, 0) + {128, { 0, 0, 0}}, // ( 49, 0) + {128, { 0, 0, 0}}, // ( 50, 0) + {128, { 0, 0, 0}}, // ( 51, 0) + {128, { 0, 0, 0}}, // ( 52, 0) + {128, { 0, 0, 0}}, // ( 53, 0) + {128, { 0, 0, 0}}, // ( 54, 0) + {128, { 0, 0, 0}}, // ( 55, 0) + {128, { 0, 0, 0}}, // ( 56, 0) + {128, { 0, 0, 0}}, // ( 57, 0) + {128, { 0, 0, 0}}, // ( 58, 0) + {128, { 0, 0, 0}}, // ( 59, 0) + {128, { 0, 0, 0}}, // ( 60, 0) + {128, { 0, 0, 0}}, // ( 61, 0) + {128, { 0, 0, 0}}, // ( 62, 0) + {128, { 0, 0, 0}}, // ( 63, 0) + {128, { 0, 0, 0}}, // ( 64, 0) + {128, { 0, 0, 0}}, // ( 65, 0) + {128, { 0, 0, 0}}, // ( 66, 0) + {128, { 0, 0, 0}}, // ( 67, 0) + {128, { 0, 0, 0}}, // ( 68, 0) + {128, { 0, 0, 0}}, // ( 69, 0) + {128, { 0, 0, 0}}, // ( 70, 0) + {128, { 0, 0, 0}}, // ( 71, 0) + {128, { 0, 0, 0}}, // ( 72, 0) + {128, { 0, 0, 0}}, // ( 73, 0) + {128, { 0, 0, 0}}, // ( 74, 0) + {128, { 0, 0, 0}}, // ( 75, 0) + {128, { 0, 0, 0}}, // ( 76, 0) + {128, { 0, 0, 0}}, // ( 77, 0) + {128, { 0, 0, 0}}, // ( 78, 0) + {128, { 0, 0, 0}}, // ( 79, 0) + {128, { 0, 0, 0}}, // ( 80, 0) + {128, { 0, 0, 0}}, // ( 81, 0) + {128, { 0, 0, 0}}, // ( 82, 0) + {128, { 0, 0, 0}}, // ( 83, 0) + {128, { 0, 0, 0}}, // ( 84, 0) + {128, { 0, 0, 0}}, // ( 85, 0) + {128, { 0, 0, 0}}, // ( 86, 0) + {128, { 0, 0, 0}}, // ( 87, 0) + {128, { 0, 0, 0}}, // ( 88, 0) + {128, { 0, 0, 0}}, // ( 89, 0) + {128, { 0, 0, 0}}, // ( 90, 0) + {128, { 0, 0, 0}}, // ( 91, 0) + {128, { 0, 0, 0}}, // ( 92, 0) + {128, { 0, 0, 0}}, // ( 93, 0) + {128, { 0, 0, 0}}, // ( 94, 0) + {128, { 0, 0, 0}}, // ( 95, 0) + {128, { 0, 0, 0}}, // ( 96, 0) + {128, { 0, 0, 0}}, // ( 97, 0) + {128, { 0, 0, 0}}, // ( 98, 0) + {128, { 0, 0, 0}}, // ( 99, 0) + {128, { 0, 0, 0}}, // (100, 0) + {128, { 0, 0, 0}}, // (101, 0) + {128, { 0, 0, 0}}, // (102, 0) + {128, { 0, 0, 0}}, // (103, 0) + {128, { 0, 0, 0}}, // (104, 0) + {128, { 0, 0, 0}}, // (105, 0) + {128, { 0, 0, 0}}, // (106, 0) + {128, { 0, 0, 0}}, // (107, 0) + {128, { 0, 0, 0}}, // (108, 0) + {128, { 0, 0, 0}}, // (109, 0) + {128, { 0, 0, 0}}, // (110, 0) + {128, { 0, 0, 0}}, // (111, 0) + {128, { 0, 0, 0}}, // (112, 0) + {128, { 0, 0, 0}}, // (113, 0) + {128, { 0, 0, 0}}, // (114, 0) + {128, { 0, 0, 0}}, // (115, 0) + {128, { 0, 0, 0}}, // (116, 0) + {128, { 0, 0, 0}}, // (117, 0) + {128, { 0, 0, 0}}, // (118, 0) + {128, { 0, 0, 0}}, // (119, 0) + {128, { 0, 0, 0}}, // (120, 0) + {128, { 0, 0, 0}}, // (121, 0) + {128, { 0, 0, 0}}, // (122, 0) + {128, { 0, 0, 0}}, // (123, 0) + {128, { 0, 0, 0}}, // (124, 0) + {128, { 0, 0, 0}}, // (125, 0) + {128, { 0, 0, 0}}, // (126, 0) + {128, { 0, 0, 0}}, // (127, 0) + {128, { 0, 0, 0}}, // (128, 0) + {128, { 0, 0, 0}}, // (129, 0) + {128, { 0, 0, 0}}, // (130, 0) + {128, { 0, 0, 0}}, // (131, 0) + {128, { 0, 0, 0}}, // (132, 0) + {128, { 0, 0, 0}}, // (133, 0) + {128, { 0, 0, 0}}, // (134, 0) + {128, { 0, 0, 0}}, // (135, 0) + {128, { 0, 0, 0}}, // (136, 0) + {128, { 0, 0, 0}}, // (137, 0) + {128, { 0, 0, 0}}, // (138, 0) + {128, { 0, 0, 0}}, // (139, 0) + {128, { 0, 0, 0}}, // (140, 0) + {128, { 0, 0, 0}}, // (141, 0) + {128, { 0, 0, 0}}, // (142, 0) + {128, { 0, 0, 0}}, // (143, 0) + {128, { 0, 0, 0}}, // (144, 0) + {128, { 0, 0, 0}}, // (145, 0) + {128, { 0, 0, 0}}, // (146, 0) + {128, { 0, 0, 0}}, // (147, 0) + {128, { 0, 0, 0}}, // (148, 0) + {128, { 0, 0, 0}}, // (149, 0) + {128, { 0, 0, 0}}, // (150, 0) + {128, { 0, 0, 0}}, // (151, 0) + {128, { 0, 0, 0}}, // (152, 0) + {128, { 0, 0, 0}}, // (153, 0) + {128, { 0, 0, 0}}, // (154, 0) + {128, { 0, 0, 0}}, // (155, 0) + {128, { 0, 0, 0}}, // (156, 0) + {128, { 0, 0, 0}}, // (157, 0) + {128, { 0, 0, 0}}, // (158, 0) + {128, { 0, 0, 0}}, // (159, 0) + {128, { 0, 0, 0}}, // (160, 0) + {128, { 0, 0, 0}}, // (161, 0) + {128, { 0, 0, 0}}, // (162, 0) + {128, { 0, 0, 0}}, // (163, 0) + {128, { 0, 0, 0}}, // (164, 0) + {128, { 0, 0, 0}}, // (165, 0) + {128, { 0, 0, 0}}, // (166, 0) + {128, { 0, 0, 0}}, // (167, 0) + {128, { 0, 0, 0}}, // (168, 0) + {128, { 0, 0, 0}}, // (169, 0) + {128, { 0, 0, 0}}, // (170, 0) + {128, { 0, 0, 0}}, // (171, 0) + {128, { 0, 0, 0}}, // (172, 0) + {128, { 0, 0, 0}}, // (173, 0) + {128, { 0, 0, 0}}, // (174, 0) + {128, { 0, 0, 0}}, // (175, 0) + {128, { 0, 0, 0}}, // (176, 0) + {128, { 0, 0, 0}}, // (177, 0) + {128, { 0, 0, 0}}, // (178, 0) + {128, { 0, 0, 0}}, // (179, 0) + {128, { 0, 0, 0}}, // ( 0, 1) + {128, { 0, 0, 0}}, // ( 1, 1) + {128, { 0, 0, 0}}, // ( 2, 1) + {128, { 0, 0, 0}}, // ( 3, 1) + {128, { 0, 0, 0}}, // ( 4, 1) + {128, { 0, 0, 0}}, // ( 5, 1) + {128, { 0, 0, 0}}, // ( 6, 1) + {128, { 0, 0, 0}}, // ( 7, 1) + {128, { 0, 0, 0}}, // ( 8, 1) + {128, { 0, 0, 0}}, // ( 9, 1) + {128, { 0, 0, 0}}, // ( 10, 1) + {128, { 0, 0, 0}}, // ( 11, 1) + {128, { 0, 0, 0}}, // ( 12, 1) + {128, { 0, 0, 0}}, // ( 13, 1) + {128, { 0, 0, 0}}, // ( 14, 1) + {128, { 0, 0, 0}}, // ( 15, 1) + {128, { 0, 0, 0}}, // ( 16, 1) + {128, { 0, 0, 0}}, // ( 17, 1) + {128, { 0, 0, 0}}, // ( 18, 1) + {128, { 0, 0, 0}}, // ( 19, 1) + {128, { 0, 0, 0}}, // ( 20, 1) + {128, { 0, 0, 0}}, // ( 21, 1) + {128, { 0, 0, 0}}, // ( 22, 1) + {128, { 0, 0, 0}}, // ( 23, 1) + {128, { 0, 0, 0}}, // ( 24, 1) + {128, { 0, 0, 0}}, // ( 25, 1) + {128, { 0, 0, 0}}, // ( 26, 1) + {128, { 0, 0, 0}}, // ( 27, 1) + {128, { 0, 0, 0}}, // ( 28, 1) + {128, { 0, 0, 0}}, // ( 29, 1) + {128, { 0, 0, 0}}, // ( 30, 1) + {128, { 0, 0, 0}}, // ( 31, 1) + {128, { 0, 0, 0}}, // ( 32, 1) + {128, { 0, 0, 0}}, // ( 33, 1) + {128, { 0, 0, 0}}, // ( 34, 1) + {128, { 0, 0, 0}}, // ( 35, 1) + {128, { 0, 0, 0}}, // ( 36, 1) + {128, { 0, 0, 0}}, // ( 37, 1) + {128, { 0, 0, 0}}, // ( 38, 1) + {128, { 0, 0, 0}}, // ( 39, 1) + {128, { 0, 0, 0}}, // ( 40, 1) + {128, { 0, 0, 0}}, // ( 41, 1) + {128, { 0, 0, 0}}, // ( 42, 1) + {128, { 0, 0, 0}}, // ( 43, 1) + {128, { 0, 0, 0}}, // ( 44, 1) + {128, { 0, 0, 0}}, // ( 45, 1) + {128, { 0, 0, 0}}, // ( 46, 1) + {128, { 0, 0, 0}}, // ( 47, 1) + {128, { 0, 0, 0}}, // ( 48, 1) + {128, { 0, 0, 0}}, // ( 49, 1) + {128, { 0, 0, 0}}, // ( 50, 1) + {128, { 0, 0, 0}}, // ( 51, 1) + {128, { 0, 0, 0}}, // ( 52, 1) + {128, { 0, 0, 0}}, // ( 53, 1) + {128, { 0, 0, 0}}, // ( 54, 1) + {128, { 0, 0, 0}}, // ( 55, 1) + {128, { 0, 0, 0}}, // ( 56, 1) + {128, { 0, 0, 0}}, // ( 57, 1) + {128, { 0, 0, 0}}, // ( 58, 1) + {128, { 0, 0, 0}}, // ( 59, 1) + {128, { 0, 0, 0}}, // ( 60, 1) + {128, { 0, 0, 0}}, // ( 61, 1) + {128, { 0, 0, 0}}, // ( 62, 1) + {128, { 0, 0, 0}}, // ( 63, 1) + {128, { 0, 0, 0}}, // ( 64, 1) + {128, { 0, 0, 0}}, // ( 65, 1) + {128, { 0, 0, 0}}, // ( 66, 1) + {128, { 0, 0, 0}}, // ( 67, 1) + {128, { 0, 0, 0}}, // ( 68, 1) + {128, { 0, 0, 0}}, // ( 69, 1) + {128, { 0, 0, 0}}, // ( 70, 1) + {128, { 0, 0, 0}}, // ( 71, 1) + {128, { 0, 0, 0}}, // ( 72, 1) + {128, { 0, 0, 0}}, // ( 73, 1) + {128, { 0, 0, 0}}, // ( 74, 1) + {128, { 0, 0, 0}}, // ( 75, 1) + {128, { 0, 0, 0}}, // ( 76, 1) + {128, { 0, 0, 0}}, // ( 77, 1) + {128, { 0, 0, 0}}, // ( 78, 1) + {128, { 0, 0, 0}}, // ( 79, 1) + {128, { 0, 0, 0}}, // ( 80, 1) + {128, { 0, 0, 0}}, // ( 81, 1) + {128, { 0, 0, 0}}, // ( 82, 1) + {128, { 0, 0, 0}}, // ( 83, 1) + {128, { 0, 0, 0}}, // ( 84, 1) + {128, { 0, 0, 0}}, // ( 85, 1) + {128, { 0, 0, 0}}, // ( 86, 1) + {128, { 0, 0, 0}}, // ( 87, 1) + {128, { 0, 0, 0}}, // ( 88, 1) + {128, { 0, 0, 0}}, // ( 89, 1) + {128, { 0, 0, 0}}, // ( 90, 1) + {128, { 0, 0, 0}}, // ( 91, 1) + {128, { 0, 0, 0}}, // ( 92, 1) + {128, { 0, 0, 0}}, // ( 93, 1) + {128, { 0, 0, 0}}, // ( 94, 1) + {128, { 0, 0, 0}}, // ( 95, 1) + {128, { 0, 0, 0}}, // ( 96, 1) + {128, { 0, 0, 0}}, // ( 97, 1) + {128, { 0, 0, 0}}, // ( 98, 1) + {128, { 0, 0, 0}}, // ( 99, 1) + {128, { 0, 0, 0}}, // (100, 1) + {128, { 0, 0, 0}}, // (101, 1) + {128, { 0, 0, 0}}, // (102, 1) + {128, { 0, 0, 0}}, // (103, 1) + {128, { 0, 0, 0}}, // (104, 1) + {128, { 0, 0, 0}}, // (105, 1) + {128, { 0, 0, 0}}, // (106, 1) + {128, { 0, 0, 0}}, // (107, 1) + {128, { 0, 0, 0}}, // (108, 1) + {128, { 0, 0, 0}}, // (109, 1) + {128, { 0, 0, 0}}, // (110, 1) + {128, { 0, 0, 0}}, // (111, 1) + {128, { 0, 0, 0}}, // (112, 1) + {128, { 0, 0, 0}}, // (113, 1) + {128, { 0, 0, 0}}, // (114, 1) + {128, { 0, 0, 0}}, // (115, 1) + {128, { 0, 0, 0}}, // (116, 1) + {128, { 0, 0, 0}}, // (117, 1) + {128, { 0, 0, 0}}, // (118, 1) + {128, { 0, 0, 0}}, // (119, 1) + {128, { 0, 0, 0}}, // (120, 1) + {128, { 0, 0, 0}}, // (121, 1) + {128, { 0, 0, 0}}, // (122, 1) + {128, { 0, 0, 0}}, // (123, 1) + {128, { 0, 0, 0}}, // (124, 1) + {128, { 0, 0, 0}}, // (125, 1) + {128, { 0, 0, 0}}, // (126, 1) + {128, { 0, 0, 0}}, // (127, 1) + {128, { 0, 0, 0}}, // (128, 1) + {128, { 0, 0, 0}}, // (129, 1) + {128, { 0, 0, 0}}, // (130, 1) + {128, { 0, 0, 0}}, // (131, 1) + {128, { 0, 0, 0}}, // (132, 1) + {128, { 0, 0, 0}}, // (133, 1) + {128, { 0, 0, 0}}, // (134, 1) + {128, { 0, 0, 0}}, // (135, 1) + {128, { 0, 0, 0}}, // (136, 1) + {128, { 0, 0, 0}}, // (137, 1) + {128, { 0, 0, 0}}, // (138, 1) + {128, { 0, 0, 0}}, // (139, 1) + {128, { 0, 0, 0}}, // (140, 1) + {128, { 0, 0, 0}}, // (141, 1) + {128, { 0, 0, 0}}, // (142, 1) + {128, { 0, 0, 0}}, // (143, 1) + {128, { 0, 0, 0}}, // (144, 1) + {128, { 0, 0, 0}}, // (145, 1) + {128, { 0, 0, 0}}, // (146, 1) + {128, { 0, 0, 0}}, // (147, 1) + {128, { 0, 0, 0}}, // (148, 1) + {128, { 0, 0, 0}}, // (149, 1) + {128, { 0, 0, 0}}, // (150, 1) + {128, { 0, 0, 0}}, // (151, 1) + {128, { 0, 0, 0}}, // (152, 1) + {128, { 0, 0, 0}}, // (153, 1) + {128, { 0, 0, 0}}, // (154, 1) + {128, { 0, 0, 0}}, // (155, 1) + {128, { 0, 0, 0}}, // (156, 1) + {128, { 0, 0, 0}}, // (157, 1) + {128, { 0, 0, 0}}, // (158, 1) + {128, { 0, 0, 0}}, // (159, 1) + {128, { 0, 0, 0}}, // (160, 1) + {128, { 0, 0, 0}}, // (161, 1) + {128, { 0, 0, 0}}, // (162, 1) + {128, { 0, 0, 0}}, // (163, 1) + {128, { 0, 0, 0}}, // (164, 1) + {128, { 0, 0, 0}}, // (165, 1) + {128, { 0, 0, 0}}, // (166, 1) + {128, { 0, 0, 0}}, // (167, 1) + {128, { 0, 0, 0}}, // (168, 1) + {128, { 0, 0, 0}}, // (169, 1) + {128, { 0, 0, 0}}, // (170, 1) + {128, { 0, 0, 0}}, // (171, 1) + {128, { 0, 0, 0}}, // (172, 1) + {128, { 0, 0, 0}}, // (173, 1) + {128, { 0, 0, 0}}, // (174, 1) + {128, { 0, 0, 0}}, // (175, 1) + {128, { 0, 0, 0}}, // (176, 1) + {128, { 0, 0, 0}}, // (177, 1) + {128, { 0, 0, 0}}, // (178, 1) + {128, { 0, 0, 0}}, // (179, 1) + {128, { 0, 0, 0}}, // ( 0, 2) + {128, { 0, 0, 0}}, // ( 1, 2) + {128, { 0, 0, 0}}, // ( 2, 2) + {128, { 0, 0, 0}}, // ( 3, 2) + {128, { 0, 0, 0}}, // ( 4, 2) + {128, { 0, 0, 0}}, // ( 5, 2) + {128, { 0, 0, 0}}, // ( 6, 2) + {128, { 0, 0, 0}}, // ( 7, 2) + {128, { 0, 0, 0}}, // ( 8, 2) + {128, { 0, 0, 0}}, // ( 9, 2) + {128, { 0, 0, 0}}, // ( 10, 2) + {128, { 0, 0, 0}}, // ( 11, 2) + {128, { 0, 0, 0}}, // ( 12, 2) + {128, { 0, 0, 0}}, // ( 13, 2) + {128, { 0, 0, 0}}, // ( 14, 2) + {128, { 0, 0, 0}}, // ( 15, 2) + {128, { 0, 0, 0}}, // ( 16, 2) + {128, { 0, 0, 0}}, // ( 17, 2) + {128, { 0, 0, 0}}, // ( 18, 2) + {128, { 0, 0, 0}}, // ( 19, 2) + {128, { 0, 0, 0}}, // ( 20, 2) + {128, { 0, 0, 0}}, // ( 21, 2) + {128, { 0, 0, 0}}, // ( 22, 2) + {128, { 0, 0, 0}}, // ( 23, 2) + {128, { 0, 0, 0}}, // ( 24, 2) + {128, { 0, 0, 0}}, // ( 25, 2) + {128, { 0, 0, 0}}, // ( 26, 2) + {128, { 0, 0, 0}}, // ( 27, 2) + {128, { 0, 0, 0}}, // ( 28, 2) + {128, { 0, 0, 0}}, // ( 29, 2) + {128, { 0, 0, 0}}, // ( 30, 2) + {128, { 0, 0, 0}}, // ( 31, 2) + {128, { 0, 0, 0}}, // ( 32, 2) + {128, { 0, 0, 0}}, // ( 33, 2) + {128, { 0, 0, 0}}, // ( 34, 2) + {128, { 0, 0, 0}}, // ( 35, 2) + {128, { 0, 0, 0}}, // ( 36, 2) + {128, { 0, 0, 0}}, // ( 37, 2) + {128, { 0, 0, 0}}, // ( 38, 2) + {128, { 0, 0, 0}}, // ( 39, 2) + {128, { 0, 0, 0}}, // ( 40, 2) + {128, { 0, 0, 0}}, // ( 41, 2) + {128, { 0, 0, 0}}, // ( 42, 2) + {128, { 0, 0, 0}}, // ( 43, 2) + {128, { 0, 0, 0}}, // ( 44, 2) + {128, { 0, 0, 0}}, // ( 45, 2) + {128, { 0, 0, 0}}, // ( 46, 2) + {128, { 0, 0, 0}}, // ( 47, 2) + {128, { 0, 0, 0}}, // ( 48, 2) + {128, { 0, 0, 0}}, // ( 49, 2) + {128, { 0, 0, 0}}, // ( 50, 2) + {128, { 0, 0, 0}}, // ( 51, 2) + {128, { 0, 0, 0}}, // ( 52, 2) + {128, { 0, 0, 0}}, // ( 53, 2) + {128, { 0, 0, 0}}, // ( 54, 2) + {128, { 0, 0, 0}}, // ( 55, 2) + {128, { 0, 0, 0}}, // ( 56, 2) + {128, { 0, 0, 0}}, // ( 57, 2) + {128, { 0, 0, 0}}, // ( 58, 2) + {128, { 0, 0, 0}}, // ( 59, 2) + {128, { 0, 0, 0}}, // ( 60, 2) + {128, { 0, 0, 0}}, // ( 61, 2) + {128, { 0, 0, 0}}, // ( 62, 2) + {128, { 0, 0, 0}}, // ( 63, 2) + {128, { 0, 0, 0}}, // ( 64, 2) + {128, { 0, 0, 0}}, // ( 65, 2) + {128, { 0, 0, 0}}, // ( 66, 2) + {128, { 0, 0, 0}}, // ( 67, 2) + {128, { 0, 0, 0}}, // ( 68, 2) + {128, { 0, 0, 0}}, // ( 69, 2) + {128, { 0, 0, 0}}, // ( 70, 2) + {128, { 0, 0, 0}}, // ( 71, 2) + {128, { 0, 0, 0}}, // ( 72, 2) + {128, { 0, 0, 0}}, // ( 73, 2) + {128, { 0, 0, 0}}, // ( 74, 2) + {128, { 0, 0, 0}}, // ( 75, 2) + {127, { 0, 0, 0}}, // ( 76, 2) + {113, { 0, 0, 0}}, // ( 77, 2) + { 96, { 0, 0, 0}}, // ( 78, 2) + { 81, { 0, 0, 0}}, // ( 79, 2) + { 66, { 0, 0, 0}}, // ( 80, 2) + { 54, { 0, 0, 0}}, // ( 81, 2) + { 44, { 0, 0, 0}}, // ( 82, 2) + { 34, { 0, 0, 0}}, // ( 83, 2) + { 24, { 0, 0, 0}}, // ( 84, 2) + { 17, { 0, 0, 0}}, // ( 85, 2) + { 9, { 0, 0, 0}}, // ( 86, 2) + { 9, { 0, 0, 0}}, // ( 87, 2) + { 7, { 0, 0, 0}}, // ( 88, 2) + { 0, { 0, 0, 0}}, // ( 89, 2) + { 0, { 0, 0, 0}}, // ( 90, 2) + { 7, { 0, 0, 0}}, // ( 91, 2) + { 9, { 0, 0, 0}}, // ( 92, 2) + { 9, { 0, 0, 0}}, // ( 93, 2) + { 17, { 0, 0, 0}}, // ( 94, 2) + { 24, { 0, 0, 0}}, // ( 95, 2) + { 34, { 0, 0, 0}}, // ( 96, 2) + { 44, { 0, 0, 0}}, // ( 97, 2) + { 54, { 0, 0, 0}}, // ( 98, 2) + { 66, { 0, 0, 0}}, // ( 99, 2) + { 81, { 0, 0, 0}}, // (100, 2) + { 96, { 0, 0, 0}}, // (101, 2) + {113, { 0, 0, 0}}, // (102, 2) + {127, { 0, 0, 0}}, // (103, 2) + {128, { 0, 0, 0}}, // (104, 2) + {128, { 0, 0, 0}}, // (105, 2) + {128, { 0, 0, 0}}, // (106, 2) + {128, { 0, 0, 0}}, // (107, 2) + {128, { 0, 0, 0}}, // (108, 2) + {128, { 0, 0, 0}}, // (109, 2) + {128, { 0, 0, 0}}, // (110, 2) + {128, { 0, 0, 0}}, // (111, 2) + {128, { 0, 0, 0}}, // (112, 2) + {128, { 0, 0, 0}}, // (113, 2) + {128, { 0, 0, 0}}, // (114, 2) + {128, { 0, 0, 0}}, // (115, 2) + {128, { 0, 0, 0}}, // (116, 2) + {128, { 0, 0, 0}}, // (117, 2) + {128, { 0, 0, 0}}, // (118, 2) + {128, { 0, 0, 0}}, // (119, 2) + {128, { 0, 0, 0}}, // (120, 2) + {128, { 0, 0, 0}}, // (121, 2) + {128, { 0, 0, 0}}, // (122, 2) + {128, { 0, 0, 0}}, // (123, 2) + {128, { 0, 0, 0}}, // (124, 2) + {128, { 0, 0, 0}}, // (125, 2) + {128, { 0, 0, 0}}, // (126, 2) + {128, { 0, 0, 0}}, // (127, 2) + {128, { 0, 0, 0}}, // (128, 2) + {128, { 0, 0, 0}}, // (129, 2) + {128, { 0, 0, 0}}, // (130, 2) + {128, { 0, 0, 0}}, // (131, 2) + {128, { 0, 0, 0}}, // (132, 2) + {128, { 0, 0, 0}}, // (133, 2) + {128, { 0, 0, 0}}, // (134, 2) + {128, { 0, 0, 0}}, // (135, 2) + {128, { 0, 0, 0}}, // (136, 2) + {128, { 0, 0, 0}}, // (137, 2) + {128, { 0, 0, 0}}, // (138, 2) + {128, { 0, 0, 0}}, // (139, 2) + {128, { 0, 0, 0}}, // (140, 2) + {128, { 0, 0, 0}}, // (141, 2) + {128, { 0, 0, 0}}, // (142, 2) + {128, { 0, 0, 0}}, // (143, 2) + {128, { 0, 0, 0}}, // (144, 2) + {128, { 0, 0, 0}}, // (145, 2) + {128, { 0, 0, 0}}, // (146, 2) + {128, { 0, 0, 0}}, // (147, 2) + {128, { 0, 0, 0}}, // (148, 2) + {128, { 0, 0, 0}}, // (149, 2) + {128, { 0, 0, 0}}, // (150, 2) + {128, { 0, 0, 0}}, // (151, 2) + {128, { 0, 0, 0}}, // (152, 2) + {128, { 0, 0, 0}}, // (153, 2) + {128, { 0, 0, 0}}, // (154, 2) + {128, { 0, 0, 0}}, // (155, 2) + {128, { 0, 0, 0}}, // (156, 2) + {128, { 0, 0, 0}}, // (157, 2) + {128, { 0, 0, 0}}, // (158, 2) + {128, { 0, 0, 0}}, // (159, 2) + {128, { 0, 0, 0}}, // (160, 2) + {128, { 0, 0, 0}}, // (161, 2) + {128, { 0, 0, 0}}, // (162, 2) + {128, { 0, 0, 0}}, // (163, 2) + {128, { 0, 0, 0}}, // (164, 2) + {128, { 0, 0, 0}}, // (165, 2) + {128, { 0, 0, 0}}, // (166, 2) + {128, { 0, 0, 0}}, // (167, 2) + {128, { 0, 0, 0}}, // (168, 2) + {128, { 0, 0, 0}}, // (169, 2) + {128, { 0, 0, 0}}, // (170, 2) + {128, { 0, 0, 0}}, // (171, 2) + {128, { 0, 0, 0}}, // (172, 2) + {128, { 0, 0, 0}}, // (173, 2) + {128, { 0, 0, 0}}, // (174, 2) + {128, { 0, 0, 0}}, // (175, 2) + {128, { 0, 0, 0}}, // (176, 2) + {128, { 0, 0, 0}}, // (177, 2) + {128, { 0, 0, 0}}, // (178, 2) + {128, { 0, 0, 0}}, // (179, 2) + {128, { 0, 0, 0}}, // ( 0, 3) + {128, { 0, 0, 0}}, // ( 1, 3) + {128, { 0, 0, 0}}, // ( 2, 3) + {128, { 0, 0, 0}}, // ( 3, 3) + {128, { 0, 0, 0}}, // ( 4, 3) + {128, { 0, 0, 0}}, // ( 5, 3) + {128, { 0, 0, 0}}, // ( 6, 3) + {128, { 0, 0, 0}}, // ( 7, 3) + {128, { 0, 0, 0}}, // ( 8, 3) + {128, { 0, 0, 0}}, // ( 9, 3) + {128, { 0, 0, 0}}, // ( 10, 3) + {128, { 0, 0, 0}}, // ( 11, 3) + {128, { 0, 0, 0}}, // ( 12, 3) + {128, { 0, 0, 0}}, // ( 13, 3) + {128, { 0, 0, 0}}, // ( 14, 3) + {128, { 0, 0, 0}}, // ( 15, 3) + {128, { 0, 0, 0}}, // ( 16, 3) + {128, { 0, 0, 0}}, // ( 17, 3) + {128, { 0, 0, 0}}, // ( 18, 3) + {128, { 0, 0, 0}}, // ( 19, 3) + {128, { 0, 0, 0}}, // ( 20, 3) + {128, { 0, 0, 0}}, // ( 21, 3) + {128, { 0, 0, 0}}, // ( 22, 3) + {128, { 0, 0, 0}}, // ( 23, 3) + {128, { 0, 0, 0}}, // ( 24, 3) + {128, { 0, 0, 0}}, // ( 25, 3) + {128, { 0, 0, 0}}, // ( 26, 3) + {128, { 0, 0, 0}}, // ( 27, 3) + {128, { 0, 0, 0}}, // ( 28, 3) + {128, { 0, 0, 0}}, // ( 29, 3) + {128, { 0, 0, 0}}, // ( 30, 3) + {128, { 0, 0, 0}}, // ( 31, 3) + {128, { 0, 0, 0}}, // ( 32, 3) + {128, { 0, 0, 0}}, // ( 33, 3) + {128, { 0, 0, 0}}, // ( 34, 3) + {128, { 0, 0, 0}}, // ( 35, 3) + {128, { 0, 0, 0}}, // ( 36, 3) + {128, { 0, 0, 0}}, // ( 37, 3) + {128, { 0, 0, 0}}, // ( 38, 3) + {128, { 0, 0, 0}}, // ( 39, 3) + {128, { 0, 0, 0}}, // ( 40, 3) + {128, { 0, 0, 0}}, // ( 41, 3) + {128, { 0, 0, 0}}, // ( 42, 3) + {128, { 0, 0, 0}}, // ( 43, 3) + {128, { 0, 0, 0}}, // ( 44, 3) + {128, { 0, 0, 0}}, // ( 45, 3) + {128, { 0, 0, 0}}, // ( 46, 3) + {128, { 0, 0, 0}}, // ( 47, 3) + {128, { 0, 0, 0}}, // ( 48, 3) + {128, { 0, 0, 0}}, // ( 49, 3) + {128, { 0, 0, 0}}, // ( 50, 3) + {128, { 0, 0, 0}}, // ( 51, 3) + {128, { 0, 0, 0}}, // ( 52, 3) + {128, { 0, 0, 0}}, // ( 53, 3) + {128, { 0, 0, 0}}, // ( 54, 3) + {128, { 0, 0, 0}}, // ( 55, 3) + {128, { 0, 0, 0}}, // ( 56, 3) + {128, { 0, 0, 0}}, // ( 57, 3) + {128, { 0, 0, 0}}, // ( 58, 3) + {128, { 0, 0, 0}}, // ( 59, 3) + {128, { 0, 0, 0}}, // ( 60, 3) + {128, { 0, 0, 0}}, // ( 61, 3) + {128, { 0, 0, 0}}, // ( 62, 3) + {128, { 0, 0, 0}}, // ( 63, 3) + {128, { 0, 0, 0}}, // ( 64, 3) + {128, { 0, 0, 0}}, // ( 65, 3) + {128, { 0, 0, 0}}, // ( 66, 3) + {128, { 0, 0, 0}}, // ( 67, 3) + {128, { 0, 0, 0}}, // ( 68, 3) + {128, { 0, 0, 0}}, // ( 69, 3) + {128, { 0, 0, 0}}, // ( 70, 3) + {121, { 0, 0, 0}}, // ( 71, 3) + { 96, { 0, 0, 0}}, // ( 72, 3) + { 73, { 0, 0, 0}}, // ( 73, 3) + { 50, { 0, 0, 0}}, // ( 74, 3) + { 27, { 0, 0, 0}}, // ( 75, 3) + { 5, { 0, 0, 0}}, // ( 76, 3) + { 0, { 0, 0, 0}}, // ( 77, 3) + { 0, { 0, 0, 0}}, // ( 78, 3) + { 0, { 0, 0, 0}}, // ( 79, 3) + { 0, { 0, 0, 0}}, // ( 80, 3) + { 0, { 0, 0, 0}}, // ( 81, 3) + { 0, { 0, 0, 0}}, // ( 82, 3) + { 0, { 0, 0, 0}}, // ( 83, 3) + { 0, { 0, 0, 0}}, // ( 84, 3) + { 0, { 0, 0, 0}}, // ( 85, 3) + { 0, { 0, 0, 0}}, // ( 86, 3) + { 0, { 0, 0, 0}}, // ( 87, 3) + { 0, { 0, 0, 0}}, // ( 88, 3) + { 0, { 0, 0, 0}}, // ( 89, 3) + { 0, { 0, 0, 0}}, // ( 90, 3) + { 0, { 0, 0, 0}}, // ( 91, 3) + { 0, { 0, 0, 0}}, // ( 92, 3) + { 0, { 0, 0, 0}}, // ( 93, 3) + { 0, { 0, 0, 0}}, // ( 94, 3) + { 0, { 0, 0, 0}}, // ( 95, 3) + { 0, { 0, 0, 0}}, // ( 96, 3) + { 0, { 0, 0, 0}}, // ( 97, 3) + { 0, { 0, 0, 0}}, // ( 98, 3) + { 0, { 0, 0, 0}}, // ( 99, 3) + { 0, { 0, 0, 0}}, // (100, 3) + { 0, { 0, 0, 0}}, // (101, 3) + { 0, { 0, 0, 0}}, // (102, 3) + { 5, { 0, 0, 0}}, // (103, 3) + { 27, { 0, 0, 0}}, // (104, 3) + { 50, { 0, 0, 0}}, // (105, 3) + { 73, { 0, 0, 0}}, // (106, 3) + { 96, { 0, 0, 0}}, // (107, 3) + {121, { 0, 0, 0}}, // (108, 3) + {128, { 0, 0, 0}}, // (109, 3) + {128, { 0, 0, 0}}, // (110, 3) + {128, { 0, 0, 0}}, // (111, 3) + {128, { 0, 0, 0}}, // (112, 3) + {128, { 0, 0, 0}}, // (113, 3) + {128, { 0, 0, 0}}, // (114, 3) + {128, { 0, 0, 0}}, // (115, 3) + {128, { 0, 0, 0}}, // (116, 3) + {128, { 0, 0, 0}}, // (117, 3) + {128, { 0, 0, 0}}, // (118, 3) + {128, { 0, 0, 0}}, // (119, 3) + {128, { 0, 0, 0}}, // (120, 3) + {128, { 0, 0, 0}}, // (121, 3) + {128, { 0, 0, 0}}, // (122, 3) + {128, { 0, 0, 0}}, // (123, 3) + {128, { 0, 0, 0}}, // (124, 3) + {128, { 0, 0, 0}}, // (125, 3) + {128, { 0, 0, 0}}, // (126, 3) + {128, { 0, 0, 0}}, // (127, 3) + {128, { 0, 0, 0}}, // (128, 3) + {128, { 0, 0, 0}}, // (129, 3) + {128, { 0, 0, 0}}, // (130, 3) + {128, { 0, 0, 0}}, // (131, 3) + {128, { 0, 0, 0}}, // (132, 3) + {128, { 0, 0, 0}}, // (133, 3) + {128, { 0, 0, 0}}, // (134, 3) + {128, { 0, 0, 0}}, // (135, 3) + {128, { 0, 0, 0}}, // (136, 3) + {128, { 0, 0, 0}}, // (137, 3) + {128, { 0, 0, 0}}, // (138, 3) + {128, { 0, 0, 0}}, // (139, 3) + {128, { 0, 0, 0}}, // (140, 3) + {128, { 0, 0, 0}}, // (141, 3) + {128, { 0, 0, 0}}, // (142, 3) + {128, { 0, 0, 0}}, // (143, 3) + {128, { 0, 0, 0}}, // (144, 3) + {128, { 0, 0, 0}}, // (145, 3) + {128, { 0, 0, 0}}, // (146, 3) + {128, { 0, 0, 0}}, // (147, 3) + {128, { 0, 0, 0}}, // (148, 3) + {128, { 0, 0, 0}}, // (149, 3) + {128, { 0, 0, 0}}, // (150, 3) + {128, { 0, 0, 0}}, // (151, 3) + {128, { 0, 0, 0}}, // (152, 3) + {128, { 0, 0, 0}}, // (153, 3) + {128, { 0, 0, 0}}, // (154, 3) + {128, { 0, 0, 0}}, // (155, 3) + {128, { 0, 0, 0}}, // (156, 3) + {128, { 0, 0, 0}}, // (157, 3) + {128, { 0, 0, 0}}, // (158, 3) + {128, { 0, 0, 0}}, // (159, 3) + {128, { 0, 0, 0}}, // (160, 3) + {128, { 0, 0, 0}}, // (161, 3) + {128, { 0, 0, 0}}, // (162, 3) + {128, { 0, 0, 0}}, // (163, 3) + {128, { 0, 0, 0}}, // (164, 3) + {128, { 0, 0, 0}}, // (165, 3) + {128, { 0, 0, 0}}, // (166, 3) + {128, { 0, 0, 0}}, // (167, 3) + {128, { 0, 0, 0}}, // (168, 3) + {128, { 0, 0, 0}}, // (169, 3) + {128, { 0, 0, 0}}, // (170, 3) + {128, { 0, 0, 0}}, // (171, 3) + {128, { 0, 0, 0}}, // (172, 3) + {128, { 0, 0, 0}}, // (173, 3) + {128, { 0, 0, 0}}, // (174, 3) + {128, { 0, 0, 0}}, // (175, 3) + {128, { 0, 0, 0}}, // (176, 3) + {128, { 0, 0, 0}}, // (177, 3) + {128, { 0, 0, 0}}, // (178, 3) + {128, { 0, 0, 0}}, // (179, 3) + {128, { 0, 0, 0}}, // ( 0, 4) + {128, { 0, 0, 0}}, // ( 1, 4) + {128, { 0, 0, 0}}, // ( 2, 4) + {128, { 0, 0, 0}}, // ( 3, 4) + {128, { 0, 0, 0}}, // ( 4, 4) + {128, { 0, 0, 0}}, // ( 5, 4) + {128, { 0, 0, 0}}, // ( 6, 4) + {128, { 0, 0, 0}}, // ( 7, 4) + {128, { 0, 0, 0}}, // ( 8, 4) + {128, { 0, 0, 0}}, // ( 9, 4) + {128, { 0, 0, 0}}, // ( 10, 4) + {128, { 0, 0, 0}}, // ( 11, 4) + {128, { 0, 0, 0}}, // ( 12, 4) + {128, { 0, 0, 0}}, // ( 13, 4) + {128, { 0, 0, 0}}, // ( 14, 4) + {128, { 0, 0, 0}}, // ( 15, 4) + {128, { 0, 0, 0}}, // ( 16, 4) + {128, { 0, 0, 0}}, // ( 17, 4) + {128, { 0, 0, 0}}, // ( 18, 4) + {128, { 0, 0, 0}}, // ( 19, 4) + {128, { 0, 0, 0}}, // ( 20, 4) + {128, { 0, 0, 0}}, // ( 21, 4) + {128, { 0, 0, 0}}, // ( 22, 4) + {128, { 0, 0, 0}}, // ( 23, 4) + {128, { 0, 0, 0}}, // ( 24, 4) + {128, { 0, 0, 0}}, // ( 25, 4) + {128, { 0, 0, 0}}, // ( 26, 4) + {128, { 0, 0, 0}}, // ( 27, 4) + {128, { 0, 0, 0}}, // ( 28, 4) + {128, { 0, 0, 0}}, // ( 29, 4) + {128, { 0, 0, 0}}, // ( 30, 4) + {128, { 0, 0, 0}}, // ( 31, 4) + {128, { 0, 0, 0}}, // ( 32, 4) + {128, { 0, 0, 0}}, // ( 33, 4) + {128, { 0, 0, 0}}, // ( 34, 4) + {128, { 0, 0, 0}}, // ( 35, 4) + {128, { 0, 0, 0}}, // ( 36, 4) + {128, { 0, 0, 0}}, // ( 37, 4) + {128, { 0, 0, 0}}, // ( 38, 4) + {128, { 0, 0, 0}}, // ( 39, 4) + {128, { 0, 0, 0}}, // ( 40, 4) + {128, { 0, 0, 0}}, // ( 41, 4) + {128, { 0, 0, 0}}, // ( 42, 4) + {128, { 0, 0, 0}}, // ( 43, 4) + {128, { 0, 0, 0}}, // ( 44, 4) + {128, { 0, 0, 0}}, // ( 45, 4) + {128, { 0, 0, 0}}, // ( 46, 4) + {128, { 0, 0, 0}}, // ( 47, 4) + {128, { 0, 0, 0}}, // ( 48, 4) + {128, { 0, 0, 0}}, // ( 49, 4) + {128, { 0, 0, 0}}, // ( 50, 4) + {128, { 0, 0, 0}}, // ( 51, 4) + {128, { 0, 0, 0}}, // ( 52, 4) + {128, { 0, 0, 0}}, // ( 53, 4) + {128, { 0, 0, 0}}, // ( 54, 4) + {128, { 0, 0, 0}}, // ( 55, 4) + {128, { 0, 0, 0}}, // ( 56, 4) + {128, { 0, 0, 0}}, // ( 57, 4) + {128, { 0, 0, 0}}, // ( 58, 4) + {128, { 0, 0, 0}}, // ( 59, 4) + {128, { 0, 0, 0}}, // ( 60, 4) + {128, { 0, 0, 0}}, // ( 61, 4) + {128, { 0, 0, 0}}, // ( 62, 4) + {128, { 0, 0, 0}}, // ( 63, 4) + {128, { 0, 0, 0}}, // ( 64, 4) + {128, { 0, 0, 0}}, // ( 65, 4) + {128, { 0, 0, 0}}, // ( 66, 4) + {116, { 0, 0, 0}}, // ( 67, 4) + { 84, { 0, 0, 0}}, // ( 68, 4) + { 55, { 0, 0, 0}}, // ( 69, 4) + { 26, { 0, 0, 0}}, // ( 70, 4) + { 2, { 0, 0, 0}}, // ( 71, 4) + { 0, { 0, 0, 0}}, // ( 72, 4) + { 0, { 0, 0, 0}}, // ( 73, 4) + { 0, { 0, 0, 0}}, // ( 74, 4) + { 0, { 0, 0, 0}}, // ( 75, 4) + { 0, { 0, 0, 0}}, // ( 76, 4) + { 0, { 0, 0, 0}}, // ( 77, 4) + { 0, { 0, 0, 0}}, // ( 78, 4) + { 0, { 0, 0, 0}}, // ( 79, 4) + { 0, { 0, 0, 0}}, // ( 80, 4) + { 0, { 0, 0, 0}}, // ( 81, 4) + { 0, { 0, 0, 0}}, // ( 82, 4) + { 0, { 0, 0, 0}}, // ( 83, 4) + { 0, { 0, 0, 0}}, // ( 84, 4) + { 0, { 0, 0, 0}}, // ( 85, 4) + { 0, { 0, 0, 0}}, // ( 86, 4) + { 0, { 0, 0, 0}}, // ( 87, 4) + { 0, { 0, 0, 0}}, // ( 88, 4) + { 0, { 0, 0, 0}}, // ( 89, 4) + { 0, { 0, 0, 0}}, // ( 90, 4) + { 0, { 0, 0, 0}}, // ( 91, 4) + { 0, { 0, 0, 0}}, // ( 92, 4) + { 0, { 0, 0, 0}}, // ( 93, 4) + { 0, { 0, 0, 0}}, // ( 94, 4) + { 0, { 0, 0, 0}}, // ( 95, 4) + { 0, { 0, 0, 0}}, // ( 96, 4) + { 0, { 0, 0, 0}}, // ( 97, 4) + { 0, { 0, 0, 0}}, // ( 98, 4) + { 0, { 0, 0, 0}}, // ( 99, 4) + { 0, { 0, 0, 0}}, // (100, 4) + { 0, { 0, 0, 0}}, // (101, 4) + { 0, { 0, 0, 0}}, // (102, 4) + { 0, { 0, 0, 0}}, // (103, 4) + { 0, { 0, 0, 0}}, // (104, 4) + { 0, { 0, 0, 0}}, // (105, 4) + { 0, { 0, 0, 0}}, // (106, 4) + { 0, { 0, 0, 0}}, // (107, 4) + { 2, { 0, 0, 0}}, // (108, 4) + { 26, { 0, 0, 0}}, // (109, 4) + { 55, { 0, 0, 0}}, // (110, 4) + { 84, { 0, 0, 0}}, // (111, 4) + {116, { 0, 0, 0}}, // (112, 4) + {128, { 0, 0, 0}}, // (113, 4) + {128, { 0, 0, 0}}, // (114, 4) + {128, { 0, 0, 0}}, // (115, 4) + {128, { 0, 0, 0}}, // (116, 4) + {128, { 0, 0, 0}}, // (117, 4) + {128, { 0, 0, 0}}, // (118, 4) + {128, { 0, 0, 0}}, // (119, 4) + {128, { 0, 0, 0}}, // (120, 4) + {128, { 0, 0, 0}}, // (121, 4) + {128, { 0, 0, 0}}, // (122, 4) + {128, { 0, 0, 0}}, // (123, 4) + {128, { 0, 0, 0}}, // (124, 4) + {128, { 0, 0, 0}}, // (125, 4) + {128, { 0, 0, 0}}, // (126, 4) + {128, { 0, 0, 0}}, // (127, 4) + {128, { 0, 0, 0}}, // (128, 4) + {128, { 0, 0, 0}}, // (129, 4) + {128, { 0, 0, 0}}, // (130, 4) + {128, { 0, 0, 0}}, // (131, 4) + {128, { 0, 0, 0}}, // (132, 4) + {128, { 0, 0, 0}}, // (133, 4) + {128, { 0, 0, 0}}, // (134, 4) + {128, { 0, 0, 0}}, // (135, 4) + {128, { 0, 0, 0}}, // (136, 4) + {128, { 0, 0, 0}}, // (137, 4) + {128, { 0, 0, 0}}, // (138, 4) + {128, { 0, 0, 0}}, // (139, 4) + {128, { 0, 0, 0}}, // (140, 4) + {128, { 0, 0, 0}}, // (141, 4) + {128, { 0, 0, 0}}, // (142, 4) + {128, { 0, 0, 0}}, // (143, 4) + {128, { 0, 0, 0}}, // (144, 4) + {128, { 0, 0, 0}}, // (145, 4) + {128, { 0, 0, 0}}, // (146, 4) + {128, { 0, 0, 0}}, // (147, 4) + {128, { 0, 0, 0}}, // (148, 4) + {128, { 0, 0, 0}}, // (149, 4) + {128, { 0, 0, 0}}, // (150, 4) + {128, { 0, 0, 0}}, // (151, 4) + {128, { 0, 0, 0}}, // (152, 4) + {128, { 0, 0, 0}}, // (153, 4) + {128, { 0, 0, 0}}, // (154, 4) + {128, { 0, 0, 0}}, // (155, 4) + {128, { 0, 0, 0}}, // (156, 4) + {128, { 0, 0, 0}}, // (157, 4) + {128, { 0, 0, 0}}, // (158, 4) + {128, { 0, 0, 0}}, // (159, 4) + {128, { 0, 0, 0}}, // (160, 4) + {128, { 0, 0, 0}}, // (161, 4) + {128, { 0, 0, 0}}, // (162, 4) + {128, { 0, 0, 0}}, // (163, 4) + {128, { 0, 0, 0}}, // (164, 4) + {128, { 0, 0, 0}}, // (165, 4) + {128, { 0, 0, 0}}, // (166, 4) + {128, { 0, 0, 0}}, // (167, 4) + {128, { 0, 0, 0}}, // (168, 4) + {128, { 0, 0, 0}}, // (169, 4) + {128, { 0, 0, 0}}, // (170, 4) + {128, { 0, 0, 0}}, // (171, 4) + {128, { 0, 0, 0}}, // (172, 4) + {128, { 0, 0, 0}}, // (173, 4) + {128, { 0, 0, 0}}, // (174, 4) + {128, { 0, 0, 0}}, // (175, 4) + {128, { 0, 0, 0}}, // (176, 4) + {128, { 0, 0, 0}}, // (177, 4) + {128, { 0, 0, 0}}, // (178, 4) + {128, { 0, 0, 0}}, // (179, 4) + {128, { 0, 0, 0}}, // ( 0, 5) + {128, { 0, 0, 0}}, // ( 1, 5) + {128, { 0, 0, 0}}, // ( 2, 5) + {128, { 0, 0, 0}}, // ( 3, 5) + {128, { 0, 0, 0}}, // ( 4, 5) + {128, { 0, 0, 0}}, // ( 5, 5) + {128, { 0, 0, 0}}, // ( 6, 5) + {128, { 0, 0, 0}}, // ( 7, 5) + {128, { 0, 0, 0}}, // ( 8, 5) + {128, { 0, 0, 0}}, // ( 9, 5) + {128, { 0, 0, 0}}, // ( 10, 5) + {128, { 0, 0, 0}}, // ( 11, 5) + {128, { 0, 0, 0}}, // ( 12, 5) + {128, { 0, 0, 0}}, // ( 13, 5) + {128, { 0, 0, 0}}, // ( 14, 5) + {128, { 0, 0, 0}}, // ( 15, 5) + {128, { 0, 0, 0}}, // ( 16, 5) + {128, { 0, 0, 0}}, // ( 17, 5) + {128, { 0, 0, 0}}, // ( 18, 5) + {128, { 0, 0, 0}}, // ( 19, 5) + {128, { 0, 0, 0}}, // ( 20, 5) + {128, { 0, 0, 0}}, // ( 21, 5) + {128, { 0, 0, 0}}, // ( 22, 5) + {128, { 0, 0, 0}}, // ( 23, 5) + {128, { 0, 0, 0}}, // ( 24, 5) + {128, { 0, 0, 0}}, // ( 25, 5) + {128, { 0, 0, 0}}, // ( 26, 5) + {128, { 0, 0, 0}}, // ( 27, 5) + {128, { 0, 0, 0}}, // ( 28, 5) + {128, { 0, 0, 0}}, // ( 29, 5) + {128, { 0, 0, 0}}, // ( 30, 5) + {128, { 0, 0, 0}}, // ( 31, 5) + {128, { 0, 0, 0}}, // ( 32, 5) + {128, { 0, 0, 0}}, // ( 33, 5) + {128, { 0, 0, 0}}, // ( 34, 5) + {128, { 0, 0, 0}}, // ( 35, 5) + {128, { 0, 0, 0}}, // ( 36, 5) + {128, { 0, 0, 0}}, // ( 37, 5) + {128, { 0, 0, 0}}, // ( 38, 5) + {128, { 0, 0, 0}}, // ( 39, 5) + {128, { 0, 0, 0}}, // ( 40, 5) + {128, { 0, 0, 0}}, // ( 41, 5) + {128, { 0, 0, 0}}, // ( 42, 5) + {128, { 0, 0, 0}}, // ( 43, 5) + {128, { 0, 0, 0}}, // ( 44, 5) + {128, { 0, 0, 0}}, // ( 45, 5) + {128, { 0, 0, 0}}, // ( 46, 5) + {128, { 0, 0, 0}}, // ( 47, 5) + {128, { 0, 0, 0}}, // ( 48, 5) + {128, { 0, 0, 0}}, // ( 49, 5) + {128, { 0, 0, 0}}, // ( 50, 5) + {128, { 0, 0, 0}}, // ( 51, 5) + {128, { 0, 0, 0}}, // ( 52, 5) + {128, { 0, 0, 0}}, // ( 53, 5) + {128, { 0, 0, 0}}, // ( 54, 5) + {128, { 0, 0, 0}}, // ( 55, 5) + {128, { 0, 0, 0}}, // ( 56, 5) + {128, { 0, 0, 0}}, // ( 57, 5) + {128, { 0, 0, 0}}, // ( 58, 5) + {128, { 0, 0, 0}}, // ( 59, 5) + {128, { 0, 0, 0}}, // ( 60, 5) + {128, { 0, 0, 0}}, // ( 61, 5) + {128, { 0, 0, 0}}, // ( 62, 5) + {126, { 0, 0, 0}}, // ( 63, 5) + { 97, { 0, 0, 0}}, // ( 64, 5) + { 59, { 0, 0, 0}}, // ( 65, 5) + { 23, { 0, 0, 0}}, // ( 66, 5) + { 1, { 0, 0, 0}}, // ( 67, 5) + { 0, { 0, 0, 0}}, // ( 68, 5) + { 0, { 0, 0, 0}}, // ( 69, 5) + { 0, { 0, 0, 0}}, // ( 70, 5) + { 0, { 0, 0, 0}}, // ( 71, 5) + { 0, { 0, 0, 0}}, // ( 72, 5) + { 0, { 0, 0, 0}}, // ( 73, 5) + { 0, { 0, 0, 0}}, // ( 74, 5) + { 0, { 0, 0, 0}}, // ( 75, 5) + { 0, { 0, 0, 0}}, // ( 76, 5) + { 0, { 0, 0, 0}}, // ( 77, 5) + { 0, { 0, 0, 0}}, // ( 78, 5) + { 0, { 0, 0, 0}}, // ( 79, 5) + { 0, { 0, 0, 0}}, // ( 80, 5) + { 0, { 0, 0, 0}}, // ( 81, 5) + { 0, { 0, 0, 0}}, // ( 82, 5) + { 0, { 0, 0, 0}}, // ( 83, 5) + { 0, { 0, 0, 0}}, // ( 84, 5) + { 0, { 0, 0, 0}}, // ( 85, 5) + { 0, { 0, 0, 0}}, // ( 86, 5) + { 0, { 0, 0, 0}}, // ( 87, 5) + { 0, { 0, 0, 0}}, // ( 88, 5) + { 0, { 0, 0, 0}}, // ( 89, 5) + { 0, { 0, 0, 0}}, // ( 90, 5) + { 0, { 0, 0, 0}}, // ( 91, 5) + { 0, { 0, 0, 0}}, // ( 92, 5) + { 0, { 0, 0, 0}}, // ( 93, 5) + { 0, { 0, 0, 0}}, // ( 94, 5) + { 0, { 0, 0, 0}}, // ( 95, 5) + { 0, { 0, 0, 0}}, // ( 96, 5) + { 0, { 0, 0, 0}}, // ( 97, 5) + { 0, { 0, 0, 0}}, // ( 98, 5) + { 0, { 0, 0, 0}}, // ( 99, 5) + { 0, { 0, 0, 0}}, // (100, 5) + { 0, { 0, 0, 0}}, // (101, 5) + { 0, { 0, 0, 0}}, // (102, 5) + { 0, { 0, 0, 0}}, // (103, 5) + { 0, { 0, 0, 0}}, // (104, 5) + { 0, { 0, 0, 0}}, // (105, 5) + { 0, { 0, 0, 0}}, // (106, 5) + { 0, { 0, 0, 0}}, // (107, 5) + { 0, { 0, 0, 0}}, // (108, 5) + { 0, { 0, 0, 0}}, // (109, 5) + { 0, { 0, 0, 0}}, // (110, 5) + { 0, { 0, 0, 0}}, // (111, 5) + { 1, { 0, 0, 0}}, // (112, 5) + { 23, { 0, 0, 0}}, // (113, 5) + { 59, { 0, 0, 0}}, // (114, 5) + { 97, { 0, 0, 0}}, // (115, 5) + {126, { 0, 0, 0}}, // (116, 5) + {128, { 0, 0, 0}}, // (117, 5) + {128, { 0, 0, 0}}, // (118, 5) + {128, { 0, 0, 0}}, // (119, 5) + {128, { 0, 0, 0}}, // (120, 5) + {128, { 0, 0, 0}}, // (121, 5) + {128, { 0, 0, 0}}, // (122, 5) + {128, { 0, 0, 0}}, // (123, 5) + {128, { 0, 0, 0}}, // (124, 5) + {128, { 0, 0, 0}}, // (125, 5) + {128, { 0, 0, 0}}, // (126, 5) + {128, { 0, 0, 0}}, // (127, 5) + {128, { 0, 0, 0}}, // (128, 5) + {128, { 0, 0, 0}}, // (129, 5) + {128, { 0, 0, 0}}, // (130, 5) + {128, { 0, 0, 0}}, // (131, 5) + {128, { 0, 0, 0}}, // (132, 5) + {128, { 0, 0, 0}}, // (133, 5) + {128, { 0, 0, 0}}, // (134, 5) + {128, { 0, 0, 0}}, // (135, 5) + {128, { 0, 0, 0}}, // (136, 5) + {128, { 0, 0, 0}}, // (137, 5) + {128, { 0, 0, 0}}, // (138, 5) + {128, { 0, 0, 0}}, // (139, 5) + {128, { 0, 0, 0}}, // (140, 5) + {128, { 0, 0, 0}}, // (141, 5) + {128, { 0, 0, 0}}, // (142, 5) + {128, { 0, 0, 0}}, // (143, 5) + {128, { 0, 0, 0}}, // (144, 5) + {128, { 0, 0, 0}}, // (145, 5) + {128, { 0, 0, 0}}, // (146, 5) + {128, { 0, 0, 0}}, // (147, 5) + {128, { 0, 0, 0}}, // (148, 5) + {128, { 0, 0, 0}}, // (149, 5) + {128, { 0, 0, 0}}, // (150, 5) + {128, { 0, 0, 0}}, // (151, 5) + {128, { 0, 0, 0}}, // (152, 5) + {128, { 0, 0, 0}}, // (153, 5) + {128, { 0, 0, 0}}, // (154, 5) + {128, { 0, 0, 0}}, // (155, 5) + {128, { 0, 0, 0}}, // (156, 5) + {128, { 0, 0, 0}}, // (157, 5) + {128, { 0, 0, 0}}, // (158, 5) + {128, { 0, 0, 0}}, // (159, 5) + {128, { 0, 0, 0}}, // (160, 5) + {128, { 0, 0, 0}}, // (161, 5) + {128, { 0, 0, 0}}, // (162, 5) + {128, { 0, 0, 0}}, // (163, 5) + {128, { 0, 0, 0}}, // (164, 5) + {128, { 0, 0, 0}}, // (165, 5) + {128, { 0, 0, 0}}, // (166, 5) + {128, { 0, 0, 0}}, // (167, 5) + {128, { 0, 0, 0}}, // (168, 5) + {128, { 0, 0, 0}}, // (169, 5) + {128, { 0, 0, 0}}, // (170, 5) + {128, { 0, 0, 0}}, // (171, 5) + {128, { 0, 0, 0}}, // (172, 5) + {128, { 0, 0, 0}}, // (173, 5) + {128, { 0, 0, 0}}, // (174, 5) + {128, { 0, 0, 0}}, // (175, 5) + {128, { 0, 0, 0}}, // (176, 5) + {128, { 0, 0, 0}}, // (177, 5) + {128, { 0, 0, 0}}, // (178, 5) + {128, { 0, 0, 0}}, // (179, 5) + {128, { 0, 0, 0}}, // ( 0, 6) + {128, { 0, 0, 0}}, // ( 1, 6) + {128, { 0, 0, 0}}, // ( 2, 6) + {128, { 0, 0, 0}}, // ( 3, 6) + {128, { 0, 0, 0}}, // ( 4, 6) + {128, { 0, 0, 0}}, // ( 5, 6) + {128, { 0, 0, 0}}, // ( 6, 6) + {128, { 0, 0, 0}}, // ( 7, 6) + {128, { 0, 0, 0}}, // ( 8, 6) + {128, { 0, 0, 0}}, // ( 9, 6) + {128, { 0, 0, 0}}, // ( 10, 6) + {128, { 0, 0, 0}}, // ( 11, 6) + {128, { 0, 0, 0}}, // ( 12, 6) + {128, { 0, 0, 0}}, // ( 13, 6) + {128, { 0, 0, 0}}, // ( 14, 6) + {128, { 0, 0, 0}}, // ( 15, 6) + {128, { 0, 0, 0}}, // ( 16, 6) + {128, { 0, 0, 0}}, // ( 17, 6) + {128, { 0, 0, 0}}, // ( 18, 6) + {128, { 0, 0, 0}}, // ( 19, 6) + {128, { 0, 0, 0}}, // ( 20, 6) + {128, { 0, 0, 0}}, // ( 21, 6) + {128, { 0, 0, 0}}, // ( 22, 6) + {128, { 0, 0, 0}}, // ( 23, 6) + {128, { 0, 0, 0}}, // ( 24, 6) + {128, { 0, 0, 0}}, // ( 25, 6) + {128, { 0, 0, 0}}, // ( 26, 6) + {128, { 0, 0, 0}}, // ( 27, 6) + {128, { 0, 0, 0}}, // ( 28, 6) + {128, { 0, 0, 0}}, // ( 29, 6) + {128, { 0, 0, 0}}, // ( 30, 6) + {128, { 0, 0, 0}}, // ( 31, 6) + {128, { 0, 0, 0}}, // ( 32, 6) + {128, { 0, 0, 0}}, // ( 33, 6) + {128, { 0, 0, 0}}, // ( 34, 6) + {128, { 0, 0, 0}}, // ( 35, 6) + {128, { 0, 0, 0}}, // ( 36, 6) + {128, { 0, 0, 0}}, // ( 37, 6) + {128, { 0, 0, 0}}, // ( 38, 6) + {128, { 0, 0, 0}}, // ( 39, 6) + {128, { 0, 0, 0}}, // ( 40, 6) + {128, { 0, 0, 0}}, // ( 41, 6) + {128, { 0, 0, 0}}, // ( 42, 6) + {128, { 0, 0, 0}}, // ( 43, 6) + {128, { 0, 0, 0}}, // ( 44, 6) + {128, { 0, 0, 0}}, // ( 45, 6) + {128, { 0, 0, 0}}, // ( 46, 6) + {128, { 0, 0, 0}}, // ( 47, 6) + {128, { 0, 0, 0}}, // ( 48, 6) + {128, { 0, 0, 0}}, // ( 49, 6) + {128, { 0, 0, 0}}, // ( 50, 6) + {128, { 0, 0, 0}}, // ( 51, 6) + {128, { 0, 0, 0}}, // ( 52, 6) + {128, { 0, 0, 0}}, // ( 53, 6) + {128, { 0, 0, 0}}, // ( 54, 6) + {128, { 0, 0, 0}}, // ( 55, 6) + {128, { 0, 0, 0}}, // ( 56, 6) + {128, { 0, 0, 0}}, // ( 57, 6) + {128, { 0, 0, 0}}, // ( 58, 6) + {128, { 0, 0, 0}}, // ( 59, 6) + {126, { 0, 0, 0}}, // ( 60, 6) + { 92, { 0, 0, 0}}, // ( 61, 6) + { 50, { 0, 0, 0}}, // ( 62, 6) + { 10, { 0, 0, 0}}, // ( 63, 6) + { 0, { 0, 0, 0}}, // ( 64, 6) + { 0, { 0, 0, 0}}, // ( 65, 6) + { 0, { 0, 0, 0}}, // ( 66, 6) + { 0, { 0, 0, 0}}, // ( 67, 6) + { 0, { 0, 0, 0}}, // ( 68, 6) + { 0, { 0, 0, 0}}, // ( 69, 6) + { 0, { 0, 0, 0}}, // ( 70, 6) + { 0, { 0, 0, 0}}, // ( 71, 6) + { 0, { 0, 0, 0}}, // ( 72, 6) + { 0, { 0, 0, 0}}, // ( 73, 6) + { 0, { 0, 0, 0}}, // ( 74, 6) + { 0, { 0, 0, 0}}, // ( 75, 6) + { 0, { 0, 0, 0}}, // ( 76, 6) + { 0, { 0, 0, 0}}, // ( 77, 6) + { 0, { 0, 0, 0}}, // ( 78, 6) + { 0, { 0, 0, 0}}, // ( 79, 6) + { 0, { 0, 0, 0}}, // ( 80, 6) + { 0, { 0, 0, 0}}, // ( 81, 6) + { 0, { 0, 0, 0}}, // ( 82, 6) + { 0, { 0, 0, 0}}, // ( 83, 6) + { 0, { 0, 0, 0}}, // ( 84, 6) + { 0, { 0, 0, 0}}, // ( 85, 6) + { 0, { 0, 0, 0}}, // ( 86, 6) + { 0, { 0, 0, 0}}, // ( 87, 6) + { 0, { 0, 0, 0}}, // ( 88, 6) + { 0, { 0, 0, 0}}, // ( 89, 6) + { 0, { 0, 0, 0}}, // ( 90, 6) + { 0, { 0, 0, 0}}, // ( 91, 6) + { 0, { 0, 0, 0}}, // ( 92, 6) + { 0, { 0, 0, 0}}, // ( 93, 6) + { 0, { 0, 0, 0}}, // ( 94, 6) + { 0, { 0, 0, 0}}, // ( 95, 6) + { 0, { 0, 0, 0}}, // ( 96, 6) + { 0, { 0, 0, 0}}, // ( 97, 6) + { 0, { 0, 0, 0}}, // ( 98, 6) + { 0, { 0, 0, 0}}, // ( 99, 6) + { 0, { 0, 0, 0}}, // (100, 6) + { 0, { 0, 0, 0}}, // (101, 6) + { 0, { 0, 0, 0}}, // (102, 6) + { 0, { 0, 0, 0}}, // (103, 6) + { 0, { 0, 0, 0}}, // (104, 6) + { 0, { 0, 0, 0}}, // (105, 6) + { 0, { 0, 0, 0}}, // (106, 6) + { 0, { 0, 0, 0}}, // (107, 6) + { 0, { 0, 0, 0}}, // (108, 6) + { 0, { 0, 0, 0}}, // (109, 6) + { 0, { 0, 0, 0}}, // (110, 6) + { 0, { 0, 0, 0}}, // (111, 6) + { 0, { 0, 0, 0}}, // (112, 6) + { 0, { 0, 0, 0}}, // (113, 6) + { 0, { 0, 0, 0}}, // (114, 6) + { 0, { 0, 0, 0}}, // (115, 6) + { 10, { 0, 0, 0}}, // (116, 6) + { 50, { 0, 0, 0}}, // (117, 6) + { 92, { 0, 0, 0}}, // (118, 6) + {126, { 0, 0, 0}}, // (119, 6) + {128, { 0, 0, 0}}, // (120, 6) + {128, { 0, 0, 0}}, // (121, 6) + {128, { 0, 0, 0}}, // (122, 6) + {128, { 0, 0, 0}}, // (123, 6) + {128, { 0, 0, 0}}, // (124, 6) + {128, { 0, 0, 0}}, // (125, 6) + {128, { 0, 0, 0}}, // (126, 6) + {128, { 0, 0, 0}}, // (127, 6) + {128, { 0, 0, 0}}, // (128, 6) + {128, { 0, 0, 0}}, // (129, 6) + {128, { 0, 0, 0}}, // (130, 6) + {128, { 0, 0, 0}}, // (131, 6) + {128, { 0, 0, 0}}, // (132, 6) + {128, { 0, 0, 0}}, // (133, 6) + {128, { 0, 0, 0}}, // (134, 6) + {128, { 0, 0, 0}}, // (135, 6) + {128, { 0, 0, 0}}, // (136, 6) + {128, { 0, 0, 0}}, // (137, 6) + {128, { 0, 0, 0}}, // (138, 6) + {128, { 0, 0, 0}}, // (139, 6) + {128, { 0, 0, 0}}, // (140, 6) + {128, { 0, 0, 0}}, // (141, 6) + {128, { 0, 0, 0}}, // (142, 6) + {128, { 0, 0, 0}}, // (143, 6) + {128, { 0, 0, 0}}, // (144, 6) + {128, { 0, 0, 0}}, // (145, 6) + {128, { 0, 0, 0}}, // (146, 6) + {128, { 0, 0, 0}}, // (147, 6) + {128, { 0, 0, 0}}, // (148, 6) + {128, { 0, 0, 0}}, // (149, 6) + {128, { 0, 0, 0}}, // (150, 6) + {128, { 0, 0, 0}}, // (151, 6) + {128, { 0, 0, 0}}, // (152, 6) + {128, { 0, 0, 0}}, // (153, 6) + {128, { 0, 0, 0}}, // (154, 6) + {128, { 0, 0, 0}}, // (155, 6) + {128, { 0, 0, 0}}, // (156, 6) + {128, { 0, 0, 0}}, // (157, 6) + {128, { 0, 0, 0}}, // (158, 6) + {128, { 0, 0, 0}}, // (159, 6) + {128, { 0, 0, 0}}, // (160, 6) + {128, { 0, 0, 0}}, // (161, 6) + {128, { 0, 0, 0}}, // (162, 6) + {128, { 0, 0, 0}}, // (163, 6) + {128, { 0, 0, 0}}, // (164, 6) + {128, { 0, 0, 0}}, // (165, 6) + {128, { 0, 0, 0}}, // (166, 6) + {128, { 0, 0, 0}}, // (167, 6) + {128, { 0, 0, 0}}, // (168, 6) + {128, { 0, 0, 0}}, // (169, 6) + {128, { 0, 0, 0}}, // (170, 6) + {128, { 0, 0, 0}}, // (171, 6) + {128, { 0, 0, 0}}, // (172, 6) + {128, { 0, 0, 0}}, // (173, 6) + {128, { 0, 0, 0}}, // (174, 6) + {128, { 0, 0, 0}}, // (175, 6) + {128, { 0, 0, 0}}, // (176, 6) + {128, { 0, 0, 0}}, // (177, 6) + {128, { 0, 0, 0}}, // (178, 6) + {128, { 0, 0, 0}}, // (179, 6) + {128, { 0, 0, 0}}, // ( 0, 7) + {128, { 0, 0, 0}}, // ( 1, 7) + {128, { 0, 0, 0}}, // ( 2, 7) + {128, { 0, 0, 0}}, // ( 3, 7) + {128, { 0, 0, 0}}, // ( 4, 7) + {128, { 0, 0, 0}}, // ( 5, 7) + {128, { 0, 0, 0}}, // ( 6, 7) + {128, { 0, 0, 0}}, // ( 7, 7) + {128, { 0, 0, 0}}, // ( 8, 7) + {128, { 0, 0, 0}}, // ( 9, 7) + {128, { 0, 0, 0}}, // ( 10, 7) + {128, { 0, 0, 0}}, // ( 11, 7) + {128, { 0, 0, 0}}, // ( 12, 7) + {128, { 0, 0, 0}}, // ( 13, 7) + {128, { 0, 0, 0}}, // ( 14, 7) + {128, { 0, 0, 0}}, // ( 15, 7) + {128, { 0, 0, 0}}, // ( 16, 7) + {128, { 0, 0, 0}}, // ( 17, 7) + {128, { 0, 0, 0}}, // ( 18, 7) + {128, { 0, 0, 0}}, // ( 19, 7) + {128, { 0, 0, 0}}, // ( 20, 7) + {128, { 0, 0, 0}}, // ( 21, 7) + {128, { 0, 0, 0}}, // ( 22, 7) + {128, { 0, 0, 0}}, // ( 23, 7) + {128, { 0, 0, 0}}, // ( 24, 7) + {128, { 0, 0, 0}}, // ( 25, 7) + {128, { 0, 0, 0}}, // ( 26, 7) + {128, { 0, 0, 0}}, // ( 27, 7) + {128, { 0, 0, 0}}, // ( 28, 7) + {128, { 0, 0, 0}}, // ( 29, 7) + {128, { 0, 0, 0}}, // ( 30, 7) + {128, { 0, 0, 0}}, // ( 31, 7) + {128, { 0, 0, 0}}, // ( 32, 7) + {128, { 0, 0, 0}}, // ( 33, 7) + {128, { 0, 0, 0}}, // ( 34, 7) + {128, { 0, 0, 0}}, // ( 35, 7) + {128, { 0, 0, 0}}, // ( 36, 7) + {128, { 0, 0, 0}}, // ( 37, 7) + {128, { 0, 0, 0}}, // ( 38, 7) + {128, { 0, 0, 0}}, // ( 39, 7) + {128, { 0, 0, 0}}, // ( 40, 7) + {128, { 0, 0, 0}}, // ( 41, 7) + {128, { 0, 0, 0}}, // ( 42, 7) + {128, { 0, 0, 0}}, // ( 43, 7) + {128, { 0, 0, 0}}, // ( 44, 7) + {128, { 0, 0, 0}}, // ( 45, 7) + {128, { 0, 0, 0}}, // ( 46, 7) + {128, { 0, 0, 0}}, // ( 47, 7) + {128, { 0, 0, 0}}, // ( 48, 7) + {128, { 0, 0, 0}}, // ( 49, 7) + {128, { 0, 0, 0}}, // ( 50, 7) + {128, { 0, 0, 0}}, // ( 51, 7) + {128, { 0, 0, 0}}, // ( 52, 7) + {128, { 0, 0, 0}}, // ( 53, 7) + {128, { 0, 0, 0}}, // ( 54, 7) + {128, { 0, 0, 0}}, // ( 55, 7) + {128, { 0, 0, 0}}, // ( 56, 7) + {128, { 0, 0, 0}}, // ( 57, 7) + {107, { 0, 0, 0}}, // ( 58, 7) + { 57, { 0, 0, 0}}, // ( 59, 7) + { 12, { 0, 0, 0}}, // ( 60, 7) + { 0, { 0, 0, 0}}, // ( 61, 7) + { 0, { 0, 0, 0}}, // ( 62, 7) + { 0, { 0, 0, 0}}, // ( 63, 7) + { 0, { 0, 0, 0}}, // ( 64, 7) + { 0, { 0, 0, 0}}, // ( 65, 7) + { 0, { 0, 0, 0}}, // ( 66, 7) + { 0, { 0, 0, 0}}, // ( 67, 7) + { 0, { 0, 0, 0}}, // ( 68, 7) + { 0, { 0, 0, 0}}, // ( 69, 7) + { 0, { 0, 0, 0}}, // ( 70, 7) + { 0, { 0, 0, 0}}, // ( 71, 7) + { 0, { 0, 0, 0}}, // ( 72, 7) + { 0, { 0, 0, 0}}, // ( 73, 7) + { 0, { 0, 0, 0}}, // ( 74, 7) + { 0, { 0, 0, 0}}, // ( 75, 7) + { 0, { 0, 0, 0}}, // ( 76, 7) + { 0, { 0, 0, 0}}, // ( 77, 7) + { 0, { 0, 0, 0}}, // ( 78, 7) + { 0, { 0, 0, 0}}, // ( 79, 7) + { 0, { 0, 0, 0}}, // ( 80, 7) + { 0, { 0, 0, 0}}, // ( 81, 7) + { 0, { 0, 0, 0}}, // ( 82, 7) + { 0, { 0, 0, 0}}, // ( 83, 7) + { 0, { 0, 0, 0}}, // ( 84, 7) + { 0, { 0, 0, 0}}, // ( 85, 7) + { 0, { 0, 0, 0}}, // ( 86, 7) + { 0, { 0, 0, 0}}, // ( 87, 7) + { 0, { 0, 0, 0}}, // ( 88, 7) + { 0, { 0, 0, 0}}, // ( 89, 7) + { 0, { 0, 0, 0}}, // ( 90, 7) + { 0, { 0, 0, 0}}, // ( 91, 7) + { 0, { 0, 0, 0}}, // ( 92, 7) + { 0, { 0, 0, 0}}, // ( 93, 7) + { 0, { 0, 0, 0}}, // ( 94, 7) + { 0, { 0, 0, 0}}, // ( 95, 7) + { 0, { 0, 0, 0}}, // ( 96, 7) + { 0, { 0, 0, 0}}, // ( 97, 7) + { 0, { 0, 0, 0}}, // ( 98, 7) + { 0, { 0, 0, 0}}, // ( 99, 7) + { 0, { 0, 0, 0}}, // (100, 7) + { 0, { 0, 0, 0}}, // (101, 7) + { 0, { 0, 0, 0}}, // (102, 7) + { 0, { 0, 0, 0}}, // (103, 7) + { 0, { 0, 0, 0}}, // (104, 7) + { 0, { 0, 0, 0}}, // (105, 7) + { 0, { 0, 0, 0}}, // (106, 7) + { 0, { 0, 0, 0}}, // (107, 7) + { 0, { 0, 0, 0}}, // (108, 7) + { 0, { 0, 0, 0}}, // (109, 7) + { 0, { 0, 0, 0}}, // (110, 7) + { 0, { 0, 0, 0}}, // (111, 7) + { 0, { 0, 0, 0}}, // (112, 7) + { 0, { 0, 0, 0}}, // (113, 7) + { 0, { 0, 0, 0}}, // (114, 7) + { 0, { 0, 0, 0}}, // (115, 7) + { 0, { 0, 0, 0}}, // (116, 7) + { 0, { 0, 0, 0}}, // (117, 7) + { 0, { 0, 0, 0}}, // (118, 7) + { 12, { 0, 0, 0}}, // (119, 7) + { 57, { 0, 0, 0}}, // (120, 7) + {106, { 0, 0, 0}}, // (121, 7) + {128, { 0, 0, 0}}, // (122, 7) + {128, { 0, 0, 0}}, // (123, 7) + {128, { 0, 0, 0}}, // (124, 7) + {128, { 0, 0, 0}}, // (125, 7) + {128, { 0, 0, 0}}, // (126, 7) + {128, { 0, 0, 0}}, // (127, 7) + {128, { 0, 0, 0}}, // (128, 7) + {128, { 0, 0, 0}}, // (129, 7) + {128, { 0, 0, 0}}, // (130, 7) + {128, { 0, 0, 0}}, // (131, 7) + {128, { 0, 0, 0}}, // (132, 7) + {128, { 0, 0, 0}}, // (133, 7) + {128, { 0, 0, 0}}, // (134, 7) + {128, { 0, 0, 0}}, // (135, 7) + {128, { 0, 0, 0}}, // (136, 7) + {128, { 0, 0, 0}}, // (137, 7) + {128, { 0, 0, 0}}, // (138, 7) + {128, { 0, 0, 0}}, // (139, 7) + {128, { 0, 0, 0}}, // (140, 7) + {128, { 0, 0, 0}}, // (141, 7) + {128, { 0, 0, 0}}, // (142, 7) + {128, { 0, 0, 0}}, // (143, 7) + {128, { 0, 0, 0}}, // (144, 7) + {128, { 0, 0, 0}}, // (145, 7) + {128, { 0, 0, 0}}, // (146, 7) + {128, { 0, 0, 0}}, // (147, 7) + {128, { 0, 0, 0}}, // (148, 7) + {128, { 0, 0, 0}}, // (149, 7) + {128, { 0, 0, 0}}, // (150, 7) + {128, { 0, 0, 0}}, // (151, 7) + {128, { 0, 0, 0}}, // (152, 7) + {128, { 0, 0, 0}}, // (153, 7) + {128, { 0, 0, 0}}, // (154, 7) + {128, { 0, 0, 0}}, // (155, 7) + {128, { 0, 0, 0}}, // (156, 7) + {128, { 0, 0, 0}}, // (157, 7) + {128, { 0, 0, 0}}, // (158, 7) + {128, { 0, 0, 0}}, // (159, 7) + {128, { 0, 0, 0}}, // (160, 7) + {128, { 0, 0, 0}}, // (161, 7) + {128, { 0, 0, 0}}, // (162, 7) + {128, { 0, 0, 0}}, // (163, 7) + {128, { 0, 0, 0}}, // (164, 7) + {128, { 0, 0, 0}}, // (165, 7) + {128, { 0, 0, 0}}, // (166, 7) + {128, { 0, 0, 0}}, // (167, 7) + {128, { 0, 0, 0}}, // (168, 7) + {128, { 0, 0, 0}}, // (169, 7) + {128, { 0, 0, 0}}, // (170, 7) + {128, { 0, 0, 0}}, // (171, 7) + {128, { 0, 0, 0}}, // (172, 7) + {128, { 0, 0, 0}}, // (173, 7) + {128, { 0, 0, 0}}, // (174, 7) + {128, { 0, 0, 0}}, // (175, 7) + {128, { 0, 0, 0}}, // (176, 7) + {128, { 0, 0, 0}}, // (177, 7) + {128, { 0, 0, 0}}, // (178, 7) + {128, { 0, 0, 0}}, // (179, 7) + {128, { 0, 0, 0}}, // ( 0, 8) + {128, { 0, 0, 0}}, // ( 1, 8) + {128, { 0, 0, 0}}, // ( 2, 8) + {128, { 0, 0, 0}}, // ( 3, 8) + {128, { 0, 0, 0}}, // ( 4, 8) + {128, { 0, 0, 0}}, // ( 5, 8) + {128, { 0, 0, 0}}, // ( 6, 8) + {128, { 0, 0, 0}}, // ( 7, 8) + {128, { 0, 0, 0}}, // ( 8, 8) + {128, { 0, 0, 0}}, // ( 9, 8) + {128, { 0, 0, 0}}, // ( 10, 8) + {128, { 0, 0, 0}}, // ( 11, 8) + {128, { 0, 0, 0}}, // ( 12, 8) + {128, { 0, 0, 0}}, // ( 13, 8) + {128, { 0, 0, 0}}, // ( 14, 8) + {128, { 0, 0, 0}}, // ( 15, 8) + {128, { 0, 0, 0}}, // ( 16, 8) + {128, { 0, 0, 0}}, // ( 17, 8) + {128, { 0, 0, 0}}, // ( 18, 8) + {128, { 0, 0, 0}}, // ( 19, 8) + {128, { 0, 0, 0}}, // ( 20, 8) + {128, { 0, 0, 0}}, // ( 21, 8) + {128, { 0, 0, 0}}, // ( 22, 8) + {128, { 0, 0, 0}}, // ( 23, 8) + {128, { 0, 0, 0}}, // ( 24, 8) + {128, { 0, 0, 0}}, // ( 25, 8) + {128, { 0, 0, 0}}, // ( 26, 8) + {128, { 0, 0, 0}}, // ( 27, 8) + {128, { 0, 0, 0}}, // ( 28, 8) + {128, { 0, 0, 0}}, // ( 29, 8) + {128, { 0, 0, 0}}, // ( 30, 8) + {128, { 0, 0, 0}}, // ( 31, 8) + {128, { 0, 0, 0}}, // ( 32, 8) + {128, { 0, 0, 0}}, // ( 33, 8) + {128, { 0, 0, 0}}, // ( 34, 8) + {128, { 0, 0, 0}}, // ( 35, 8) + {128, { 0, 0, 0}}, // ( 36, 8) + {128, { 0, 0, 0}}, // ( 37, 8) + {128, { 0, 0, 0}}, // ( 38, 8) + {128, { 0, 0, 0}}, // ( 39, 8) + {128, { 0, 0, 0}}, // ( 40, 8) + {128, { 0, 0, 0}}, // ( 41, 8) + {128, { 0, 0, 0}}, // ( 42, 8) + {128, { 0, 0, 0}}, // ( 43, 8) + {128, { 0, 0, 0}}, // ( 44, 8) + {128, { 0, 0, 0}}, // ( 45, 8) + {128, { 0, 0, 0}}, // ( 46, 8) + {128, { 0, 0, 0}}, // ( 47, 8) + {128, { 0, 0, 0}}, // ( 48, 8) + {128, { 0, 0, 0}}, // ( 49, 8) + {128, { 0, 0, 0}}, // ( 50, 8) + {128, { 0, 0, 0}}, // ( 51, 8) + {128, { 0, 0, 0}}, // ( 52, 8) + {128, { 0, 0, 0}}, // ( 53, 8) + {128, { 0, 0, 0}}, // ( 54, 8) + {122, { 0, 0, 0}}, // ( 55, 8) + { 80, { 0, 0, 0}}, // ( 56, 8) + { 29, { 0, 0, 0}}, // ( 57, 8) + { 0, { 0, 0, 0}}, // ( 58, 8) + { 0, { 0, 0, 0}}, // ( 59, 8) + { 0, { 0, 0, 0}}, // ( 60, 8) + { 0, { 0, 0, 0}}, // ( 61, 8) + { 0, { 0, 0, 0}}, // ( 62, 8) + { 0, { 0, 0, 0}}, // ( 63, 8) + { 0, { 0, 0, 0}}, // ( 64, 8) + { 0, { 0, 0, 0}}, // ( 65, 8) + { 0, { 0, 0, 0}}, // ( 66, 8) + { 0, { 0, 0, 0}}, // ( 67, 8) + { 0, { 0, 0, 0}}, // ( 68, 8) + { 0, { 0, 0, 0}}, // ( 69, 8) + { 0, { 0, 0, 0}}, // ( 70, 8) + { 0, { 0, 0, 0}}, // ( 71, 8) + { 0, { 0, 0, 0}}, // ( 72, 8) + { 0, { 0, 0, 0}}, // ( 73, 8) + { 0, { 0, 0, 0}}, // ( 74, 8) + { 0, { 0, 0, 0}}, // ( 75, 8) + { 0, { 0, 0, 0}}, // ( 76, 8) + { 0, { 0, 0, 0}}, // ( 77, 8) + { 0, { 0, 0, 0}}, // ( 78, 8) + { 0, { 0, 0, 0}}, // ( 79, 8) + { 0, { 0, 0, 0}}, // ( 80, 8) + { 0, { 0, 0, 0}}, // ( 81, 8) + { 0, { 0, 0, 0}}, // ( 82, 8) + { 0, { 0, 0, 0}}, // ( 83, 8) + { 0, { 0, 0, 0}}, // ( 84, 8) + { 0, { 0, 0, 0}}, // ( 85, 8) + { 0, { 0, 0, 0}}, // ( 86, 8) + { 0, { 0, 0, 0}}, // ( 87, 8) + { 0, { 0, 0, 0}}, // ( 88, 8) + { 0, { 0, 0, 0}}, // ( 89, 8) + { 0, { 0, 0, 0}}, // ( 90, 8) + { 0, { 0, 0, 0}}, // ( 91, 8) + { 0, { 0, 0, 0}}, // ( 92, 8) + { 0, { 0, 0, 0}}, // ( 93, 8) + { 0, { 0, 0, 0}}, // ( 94, 8) + { 0, { 0, 0, 0}}, // ( 95, 8) + { 0, { 0, 0, 0}}, // ( 96, 8) + { 0, { 0, 0, 0}}, // ( 97, 8) + { 0, { 0, 0, 0}}, // ( 98, 8) + { 0, { 0, 0, 0}}, // ( 99, 8) + { 0, { 0, 0, 0}}, // (100, 8) + { 0, { 0, 0, 0}}, // (101, 8) + { 0, { 0, 0, 0}}, // (102, 8) + { 0, { 0, 0, 0}}, // (103, 8) + { 0, { 0, 0, 0}}, // (104, 8) + { 0, { 0, 0, 0}}, // (105, 8) + { 0, { 0, 0, 0}}, // (106, 8) + { 0, { 0, 0, 0}}, // (107, 8) + { 0, { 0, 0, 0}}, // (108, 8) + { 0, { 0, 0, 0}}, // (109, 8) + { 0, { 0, 0, 0}}, // (110, 8) + { 0, { 0, 0, 0}}, // (111, 8) + { 0, { 0, 0, 0}}, // (112, 8) + { 0, { 0, 0, 0}}, // (113, 8) + { 0, { 0, 0, 0}}, // (114, 8) + { 0, { 0, 0, 0}}, // (115, 8) + { 0, { 0, 0, 0}}, // (116, 8) + { 0, { 0, 0, 0}}, // (117, 8) + { 0, { 0, 0, 0}}, // (118, 8) + { 0, { 0, 0, 0}}, // (119, 8) + { 0, { 0, 0, 0}}, // (120, 8) + { 0, { 0, 0, 0}}, // (121, 8) + { 29, { 0, 0, 0}}, // (122, 8) + { 80, { 0, 0, 0}}, // (123, 8) + {122, { 0, 0, 0}}, // (124, 8) + {128, { 0, 0, 0}}, // (125, 8) + {128, { 0, 0, 0}}, // (126, 8) + {128, { 0, 0, 0}}, // (127, 8) + {128, { 0, 0, 0}}, // (128, 8) + {128, { 0, 0, 0}}, // (129, 8) + {128, { 0, 0, 0}}, // (130, 8) + {128, { 0, 0, 0}}, // (131, 8) + {128, { 0, 0, 0}}, // (132, 8) + {128, { 0, 0, 0}}, // (133, 8) + {128, { 0, 0, 0}}, // (134, 8) + {128, { 0, 0, 0}}, // (135, 8) + {128, { 0, 0, 0}}, // (136, 8) + {128, { 0, 0, 0}}, // (137, 8) + {128, { 0, 0, 0}}, // (138, 8) + {128, { 0, 0, 0}}, // (139, 8) + {128, { 0, 0, 0}}, // (140, 8) + {128, { 0, 0, 0}}, // (141, 8) + {128, { 0, 0, 0}}, // (142, 8) + {128, { 0, 0, 0}}, // (143, 8) + {128, { 0, 0, 0}}, // (144, 8) + {128, { 0, 0, 0}}, // (145, 8) + {128, { 0, 0, 0}}, // (146, 8) + {128, { 0, 0, 0}}, // (147, 8) + {128, { 0, 0, 0}}, // (148, 8) + {128, { 0, 0, 0}}, // (149, 8) + {128, { 0, 0, 0}}, // (150, 8) + {128, { 0, 0, 0}}, // (151, 8) + {128, { 0, 0, 0}}, // (152, 8) + {128, { 0, 0, 0}}, // (153, 8) + {128, { 0, 0, 0}}, // (154, 8) + {128, { 0, 0, 0}}, // (155, 8) + {128, { 0, 0, 0}}, // (156, 8) + {128, { 0, 0, 0}}, // (157, 8) + {128, { 0, 0, 0}}, // (158, 8) + {128, { 0, 0, 0}}, // (159, 8) + {128, { 0, 0, 0}}, // (160, 8) + {128, { 0, 0, 0}}, // (161, 8) + {128, { 0, 0, 0}}, // (162, 8) + {128, { 0, 0, 0}}, // (163, 8) + {128, { 0, 0, 0}}, // (164, 8) + {128, { 0, 0, 0}}, // (165, 8) + {128, { 0, 0, 0}}, // (166, 8) + {128, { 0, 0, 0}}, // (167, 8) + {128, { 0, 0, 0}}, // (168, 8) + {128, { 0, 0, 0}}, // (169, 8) + {128, { 0, 0, 0}}, // (170, 8) + {128, { 0, 0, 0}}, // (171, 8) + {128, { 0, 0, 0}}, // (172, 8) + {128, { 0, 0, 0}}, // (173, 8) + {128, { 0, 0, 0}}, // (174, 8) + {128, { 0, 0, 0}}, // (175, 8) + {128, { 0, 0, 0}}, // (176, 8) + {128, { 0, 0, 0}}, // (177, 8) + {128, { 0, 0, 0}}, // (178, 8) + {128, { 0, 0, 0}}, // (179, 8) + {128, { 0, 0, 0}}, // ( 0, 9) + {128, { 0, 0, 0}}, // ( 1, 9) + {128, { 0, 0, 0}}, // ( 2, 9) + {128, { 0, 0, 0}}, // ( 3, 9) + {128, { 0, 0, 0}}, // ( 4, 9) + {128, { 0, 0, 0}}, // ( 5, 9) + {128, { 0, 0, 0}}, // ( 6, 9) + {128, { 0, 0, 0}}, // ( 7, 9) + {128, { 0, 0, 0}}, // ( 8, 9) + {128, { 0, 0, 0}}, // ( 9, 9) + {128, { 0, 0, 0}}, // ( 10, 9) + {128, { 0, 0, 0}}, // ( 11, 9) + {128, { 0, 0, 0}}, // ( 12, 9) + {128, { 0, 0, 0}}, // ( 13, 9) + {128, { 0, 0, 0}}, // ( 14, 9) + {128, { 0, 0, 0}}, // ( 15, 9) + {128, { 0, 0, 0}}, // ( 16, 9) + {128, { 0, 0, 0}}, // ( 17, 9) + {128, { 0, 0, 0}}, // ( 18, 9) + {128, { 0, 0, 0}}, // ( 19, 9) + {128, { 0, 0, 0}}, // ( 20, 9) + {128, { 0, 0, 0}}, // ( 21, 9) + {128, { 0, 0, 0}}, // ( 22, 9) + {128, { 0, 0, 0}}, // ( 23, 9) + {128, { 0, 0, 0}}, // ( 24, 9) + {128, { 0, 0, 0}}, // ( 25, 9) + {128, { 0, 0, 0}}, // ( 26, 9) + {128, { 0, 0, 0}}, // ( 27, 9) + {128, { 0, 0, 0}}, // ( 28, 9) + {128, { 0, 0, 0}}, // ( 29, 9) + {128, { 0, 0, 0}}, // ( 30, 9) + {128, { 0, 0, 0}}, // ( 31, 9) + {128, { 0, 0, 0}}, // ( 32, 9) + {128, { 0, 0, 0}}, // ( 33, 9) + {128, { 0, 0, 0}}, // ( 34, 9) + {128, { 0, 0, 0}}, // ( 35, 9) + {128, { 0, 0, 0}}, // ( 36, 9) + {128, { 0, 0, 0}}, // ( 37, 9) + {128, { 0, 0, 0}}, // ( 38, 9) + {128, { 0, 0, 0}}, // ( 39, 9) + {128, { 0, 0, 0}}, // ( 40, 9) + {128, { 0, 0, 0}}, // ( 41, 9) + {128, { 0, 0, 0}}, // ( 42, 9) + {128, { 0, 0, 0}}, // ( 43, 9) + {128, { 0, 0, 0}}, // ( 44, 9) + {128, { 0, 0, 0}}, // ( 45, 9) + {128, { 0, 0, 0}}, // ( 46, 9) + {128, { 0, 0, 0}}, // ( 47, 9) + {128, { 0, 0, 0}}, // ( 48, 9) + {128, { 0, 0, 0}}, // ( 49, 9) + {128, { 0, 0, 0}}, // ( 50, 9) + {128, { 0, 0, 0}}, // ( 51, 9) + {128, { 0, 0, 0}}, // ( 52, 9) + {116, { 0, 0, 0}}, // ( 53, 9) + { 61, { 0, 0, 0}}, // ( 54, 9) + { 9, { 0, 0, 0}}, // ( 55, 9) + { 0, { 0, 0, 0}}, // ( 56, 9) + { 0, { 0, 0, 0}}, // ( 57, 9) + { 0, { 0, 0, 0}}, // ( 58, 9) + { 0, { 0, 0, 0}}, // ( 59, 9) + { 0, { 0, 0, 0}}, // ( 60, 9) + { 0, { 0, 0, 0}}, // ( 61, 9) + { 0, { 0, 0, 0}}, // ( 62, 9) + { 0, { 0, 0, 0}}, // ( 63, 9) + { 0, { 0, 0, 0}}, // ( 64, 9) + { 0, { 0, 0, 0}}, // ( 65, 9) + { 0, { 0, 0, 0}}, // ( 66, 9) + { 0, { 0, 0, 0}}, // ( 67, 9) + { 0, { 0, 0, 0}}, // ( 68, 9) + { 0, { 0, 0, 0}}, // ( 69, 9) + { 0, { 0, 0, 0}}, // ( 70, 9) + { 0, { 0, 0, 0}}, // ( 71, 9) + { 0, { 0, 0, 0}}, // ( 72, 9) + { 0, { 0, 0, 0}}, // ( 73, 9) + { 0, { 0, 0, 0}}, // ( 74, 9) + { 0, { 0, 0, 0}}, // ( 75, 9) + { 0, { 0, 0, 0}}, // ( 76, 9) + { 0, { 0, 0, 0}}, // ( 77, 9) + { 0, { 0, 0, 0}}, // ( 78, 9) + { 0, { 0, 0, 0}}, // ( 79, 9) + { 0, { 0, 0, 0}}, // ( 80, 9) + { 0, { 0, 0, 0}}, // ( 81, 9) + { 0, { 0, 0, 0}}, // ( 82, 9) + { 0, { 0, 0, 0}}, // ( 83, 9) + { 0, { 0, 0, 0}}, // ( 84, 9) + { 0, { 0, 0, 0}}, // ( 85, 9) + { 0, { 0, 0, 0}}, // ( 86, 9) + { 0, { 0, 0, 0}}, // ( 87, 9) + { 0, { 0, 0, 0}}, // ( 88, 9) + { 0, { 0, 0, 0}}, // ( 89, 9) + { 0, { 0, 0, 0}}, // ( 90, 9) + { 0, { 0, 0, 0}}, // ( 91, 9) + { 0, { 0, 0, 0}}, // ( 92, 9) + { 0, { 0, 0, 0}}, // ( 93, 9) + { 0, { 0, 0, 0}}, // ( 94, 9) + { 0, { 0, 0, 0}}, // ( 95, 9) + { 0, { 0, 0, 0}}, // ( 96, 9) + { 0, { 0, 0, 0}}, // ( 97, 9) + { 0, { 0, 0, 0}}, // ( 98, 9) + { 0, { 0, 0, 0}}, // ( 99, 9) + { 0, { 0, 0, 0}}, // (100, 9) + { 0, { 0, 0, 0}}, // (101, 9) + { 0, { 0, 0, 0}}, // (102, 9) + { 0, { 0, 0, 0}}, // (103, 9) + { 0, { 0, 0, 0}}, // (104, 9) + { 0, { 0, 0, 0}}, // (105, 9) + { 0, { 0, 0, 0}}, // (106, 9) + { 0, { 0, 0, 0}}, // (107, 9) + { 0, { 0, 0, 0}}, // (108, 9) + { 0, { 0, 0, 0}}, // (109, 9) + { 0, { 0, 0, 0}}, // (110, 9) + { 0, { 0, 0, 0}}, // (111, 9) + { 0, { 0, 0, 0}}, // (112, 9) + { 0, { 0, 0, 0}}, // (113, 9) + { 0, { 0, 0, 0}}, // (114, 9) + { 0, { 0, 0, 0}}, // (115, 9) + { 0, { 0, 0, 0}}, // (116, 9) + { 0, { 0, 0, 0}}, // (117, 9) + { 0, { 0, 0, 0}}, // (118, 9) + { 0, { 0, 0, 0}}, // (119, 9) + { 0, { 0, 0, 0}}, // (120, 9) + { 0, { 0, 0, 0}}, // (121, 9) + { 0, { 0, 0, 0}}, // (122, 9) + { 0, { 0, 0, 0}}, // (123, 9) + { 9, { 0, 0, 0}}, // (124, 9) + { 61, { 0, 0, 0}}, // (125, 9) + {116, { 0, 0, 0}}, // (126, 9) + {128, { 0, 0, 0}}, // (127, 9) + {128, { 0, 0, 0}}, // (128, 9) + {128, { 0, 0, 0}}, // (129, 9) + {128, { 0, 0, 0}}, // (130, 9) + {128, { 0, 0, 0}}, // (131, 9) + {128, { 0, 0, 0}}, // (132, 9) + {128, { 0, 0, 0}}, // (133, 9) + {128, { 0, 0, 0}}, // (134, 9) + {128, { 0, 0, 0}}, // (135, 9) + {128, { 0, 0, 0}}, // (136, 9) + {128, { 0, 0, 0}}, // (137, 9) + {128, { 0, 0, 0}}, // (138, 9) + {128, { 0, 0, 0}}, // (139, 9) + {128, { 0, 0, 0}}, // (140, 9) + {128, { 0, 0, 0}}, // (141, 9) + {128, { 0, 0, 0}}, // (142, 9) + {128, { 0, 0, 0}}, // (143, 9) + {128, { 0, 0, 0}}, // (144, 9) + {128, { 0, 0, 0}}, // (145, 9) + {128, { 0, 0, 0}}, // (146, 9) + {128, { 0, 0, 0}}, // (147, 9) + {128, { 0, 0, 0}}, // (148, 9) + {128, { 0, 0, 0}}, // (149, 9) + {128, { 0, 0, 0}}, // (150, 9) + {128, { 0, 0, 0}}, // (151, 9) + {128, { 0, 0, 0}}, // (152, 9) + {128, { 0, 0, 0}}, // (153, 9) + {128, { 0, 0, 0}}, // (154, 9) + {128, { 0, 0, 0}}, // (155, 9) + {128, { 0, 0, 0}}, // (156, 9) + {128, { 0, 0, 0}}, // (157, 9) + {128, { 0, 0, 0}}, // (158, 9) + {128, { 0, 0, 0}}, // (159, 9) + {128, { 0, 0, 0}}, // (160, 9) + {128, { 0, 0, 0}}, // (161, 9) + {128, { 0, 0, 0}}, // (162, 9) + {128, { 0, 0, 0}}, // (163, 9) + {128, { 0, 0, 0}}, // (164, 9) + {128, { 0, 0, 0}}, // (165, 9) + {128, { 0, 0, 0}}, // (166, 9) + {128, { 0, 0, 0}}, // (167, 9) + {128, { 0, 0, 0}}, // (168, 9) + {128, { 0, 0, 0}}, // (169, 9) + {128, { 0, 0, 0}}, // (170, 9) + {128, { 0, 0, 0}}, // (171, 9) + {128, { 0, 0, 0}}, // (172, 9) + {128, { 0, 0, 0}}, // (173, 9) + {128, { 0, 0, 0}}, // (174, 9) + {128, { 0, 0, 0}}, // (175, 9) + {128, { 0, 0, 0}}, // (176, 9) + {128, { 0, 0, 0}}, // (177, 9) + {128, { 0, 0, 0}}, // (178, 9) + {128, { 0, 0, 0}}, // (179, 9) + {128, { 0, 0, 0}}, // ( 0, 10) + {128, { 0, 0, 0}}, // ( 1, 10) + {128, { 0, 0, 0}}, // ( 2, 10) + {128, { 0, 0, 0}}, // ( 3, 10) + {128, { 0, 0, 0}}, // ( 4, 10) + {128, { 0, 0, 0}}, // ( 5, 10) + {128, { 0, 0, 0}}, // ( 6, 10) + {128, { 0, 0, 0}}, // ( 7, 10) + {128, { 0, 0, 0}}, // ( 8, 10) + {128, { 0, 0, 0}}, // ( 9, 10) + {128, { 0, 0, 0}}, // ( 10, 10) + {128, { 0, 0, 0}}, // ( 11, 10) + {128, { 0, 0, 0}}, // ( 12, 10) + {128, { 0, 0, 0}}, // ( 13, 10) + {128, { 0, 0, 0}}, // ( 14, 10) + {128, { 0, 0, 0}}, // ( 15, 10) + {128, { 0, 0, 0}}, // ( 16, 10) + {128, { 0, 0, 0}}, // ( 17, 10) + {128, { 0, 0, 0}}, // ( 18, 10) + {128, { 0, 0, 0}}, // ( 19, 10) + {128, { 0, 0, 0}}, // ( 20, 10) + {128, { 0, 0, 0}}, // ( 21, 10) + {128, { 0, 0, 0}}, // ( 22, 10) + {128, { 0, 0, 0}}, // ( 23, 10) + {128, { 0, 0, 0}}, // ( 24, 10) + {128, { 0, 0, 0}}, // ( 25, 10) + {128, { 0, 0, 0}}, // ( 26, 10) + {128, { 0, 0, 0}}, // ( 27, 10) + {128, { 0, 0, 0}}, // ( 28, 10) + {128, { 0, 0, 0}}, // ( 29, 10) + {128, { 0, 0, 0}}, // ( 30, 10) + {128, { 0, 0, 0}}, // ( 31, 10) + {128, { 0, 0, 0}}, // ( 32, 10) + {128, { 0, 0, 0}}, // ( 33, 10) + {128, { 0, 0, 0}}, // ( 34, 10) + {128, { 0, 0, 0}}, // ( 35, 10) + {128, { 0, 0, 0}}, // ( 36, 10) + {128, { 0, 0, 0}}, // ( 37, 10) + {128, { 0, 0, 0}}, // ( 38, 10) + {128, { 0, 0, 0}}, // ( 39, 10) + {128, { 0, 0, 0}}, // ( 40, 10) + {128, { 0, 0, 0}}, // ( 41, 10) + {128, { 0, 0, 0}}, // ( 42, 10) + {128, { 0, 0, 0}}, // ( 43, 10) + {128, { 0, 0, 0}}, // ( 44, 10) + {128, { 0, 0, 0}}, // ( 45, 10) + {128, { 0, 0, 0}}, // ( 46, 10) + {128, { 0, 0, 0}}, // ( 47, 10) + {128, { 0, 0, 0}}, // ( 48, 10) + {128, { 0, 0, 0}}, // ( 49, 10) + {128, { 0, 0, 0}}, // ( 50, 10) + {108, { 0, 0, 0}}, // ( 51, 10) + { 50, { 0, 0, 0}}, // ( 52, 10) + { 4, { 0, 0, 0}}, // ( 53, 10) + { 0, { 0, 0, 0}}, // ( 54, 10) + { 0, { 0, 0, 0}}, // ( 55, 10) + { 0, { 0, 0, 0}}, // ( 56, 10) + { 0, { 0, 0, 0}}, // ( 57, 10) + { 0, { 0, 0, 0}}, // ( 58, 10) + { 0, { 0, 0, 0}}, // ( 59, 10) + { 0, { 0, 0, 0}}, // ( 60, 10) + { 0, { 0, 0, 0}}, // ( 61, 10) + { 0, { 0, 0, 0}}, // ( 62, 10) + { 0, { 0, 0, 0}}, // ( 63, 10) + { 0, { 0, 0, 0}}, // ( 64, 10) + { 0, { 0, 0, 0}}, // ( 65, 10) + { 0, { 0, 0, 0}}, // ( 66, 10) + { 0, { 0, 0, 0}}, // ( 67, 10) + { 0, { 0, 0, 0}}, // ( 68, 10) + { 0, { 0, 0, 0}}, // ( 69, 10) + { 0, { 0, 0, 0}}, // ( 70, 10) + { 0, { 0, 0, 0}}, // ( 71, 10) + { 0, { 0, 0, 0}}, // ( 72, 10) + { 0, { 0, 0, 0}}, // ( 73, 10) + { 0, { 0, 0, 0}}, // ( 74, 10) + { 0, { 0, 0, 0}}, // ( 75, 10) + { 0, { 0, 0, 0}}, // ( 76, 10) + { 0, { 0, 0, 0}}, // ( 77, 10) + { 0, { 0, 0, 0}}, // ( 78, 10) + { 0, { 0, 0, 0}}, // ( 79, 10) + { 0, { 0, 0, 0}}, // ( 80, 10) + { 0, { 0, 0, 0}}, // ( 81, 10) + { 0, { 0, 0, 0}}, // ( 82, 10) + { 0, { 0, 0, 0}}, // ( 83, 10) + { 0, { 0, 0, 0}}, // ( 84, 10) + { 0, { 0, 0, 0}}, // ( 85, 10) + { 0, { 0, 0, 0}}, // ( 86, 10) + { 0, { 0, 0, 0}}, // ( 87, 10) + { 0, { 0, 0, 0}}, // ( 88, 10) + { 0, { 0, 0, 0}}, // ( 89, 10) + { 0, { 0, 0, 0}}, // ( 90, 10) + { 0, { 0, 0, 0}}, // ( 91, 10) + { 0, { 0, 0, 0}}, // ( 92, 10) + { 0, { 0, 0, 0}}, // ( 93, 10) + { 0, { 0, 0, 0}}, // ( 94, 10) + { 0, { 0, 0, 0}}, // ( 95, 10) + { 0, { 0, 0, 0}}, // ( 96, 10) + { 0, { 0, 0, 0}}, // ( 97, 10) + { 0, { 0, 0, 0}}, // ( 98, 10) + { 0, { 0, 0, 0}}, // ( 99, 10) + { 0, { 0, 0, 0}}, // (100, 10) + { 0, { 0, 0, 0}}, // (101, 10) + { 0, { 0, 0, 0}}, // (102, 10) + { 0, { 0, 0, 0}}, // (103, 10) + { 0, { 0, 0, 0}}, // (104, 10) + { 0, { 0, 0, 0}}, // (105, 10) + { 0, { 0, 0, 0}}, // (106, 10) + { 0, { 0, 0, 0}}, // (107, 10) + { 0, { 0, 0, 0}}, // (108, 10) + { 0, { 0, 0, 0}}, // (109, 10) + { 0, { 0, 0, 0}}, // (110, 10) + { 0, { 0, 0, 0}}, // (111, 10) + { 0, { 0, 0, 0}}, // (112, 10) + { 0, { 0, 0, 0}}, // (113, 10) + { 0, { 0, 0, 0}}, // (114, 10) + { 0, { 0, 0, 0}}, // (115, 10) + { 0, { 0, 0, 0}}, // (116, 10) + { 0, { 0, 0, 0}}, // (117, 10) + { 0, { 0, 0, 0}}, // (118, 10) + { 0, { 0, 0, 0}}, // (119, 10) + { 0, { 0, 0, 0}}, // (120, 10) + { 0, { 0, 0, 0}}, // (121, 10) + { 0, { 0, 0, 0}}, // (122, 10) + { 0, { 0, 0, 0}}, // (123, 10) + { 0, { 0, 0, 0}}, // (124, 10) + { 0, { 0, 0, 0}}, // (125, 10) + { 4, { 0, 0, 0}}, // (126, 10) + { 50, { 0, 0, 0}}, // (127, 10) + {108, { 0, 0, 0}}, // (128, 10) + {128, { 0, 0, 0}}, // (129, 10) + {128, { 0, 0, 0}}, // (130, 10) + {128, { 0, 0, 0}}, // (131, 10) + {128, { 0, 0, 0}}, // (132, 10) + {128, { 0, 0, 0}}, // (133, 10) + {128, { 0, 0, 0}}, // (134, 10) + {128, { 0, 0, 0}}, // (135, 10) + {128, { 0, 0, 0}}, // (136, 10) + {128, { 0, 0, 0}}, // (137, 10) + {128, { 0, 0, 0}}, // (138, 10) + {128, { 0, 0, 0}}, // (139, 10) + {128, { 0, 0, 0}}, // (140, 10) + {128, { 0, 0, 0}}, // (141, 10) + {128, { 0, 0, 0}}, // (142, 10) + {128, { 0, 0, 0}}, // (143, 10) + {128, { 0, 0, 0}}, // (144, 10) + {128, { 0, 0, 0}}, // (145, 10) + {128, { 0, 0, 0}}, // (146, 10) + {128, { 0, 0, 0}}, // (147, 10) + {128, { 0, 0, 0}}, // (148, 10) + {128, { 0, 0, 0}}, // (149, 10) + {128, { 0, 0, 0}}, // (150, 10) + {128, { 0, 0, 0}}, // (151, 10) + {128, { 0, 0, 0}}, // (152, 10) + {128, { 0, 0, 0}}, // (153, 10) + {128, { 0, 0, 0}}, // (154, 10) + {128, { 0, 0, 0}}, // (155, 10) + {128, { 0, 0, 0}}, // (156, 10) + {128, { 0, 0, 0}}, // (157, 10) + {128, { 0, 0, 0}}, // (158, 10) + {128, { 0, 0, 0}}, // (159, 10) + {128, { 0, 0, 0}}, // (160, 10) + {128, { 0, 0, 0}}, // (161, 10) + {128, { 0, 0, 0}}, // (162, 10) + {128, { 0, 0, 0}}, // (163, 10) + {128, { 0, 0, 0}}, // (164, 10) + {128, { 0, 0, 0}}, // (165, 10) + {128, { 0, 0, 0}}, // (166, 10) + {128, { 0, 0, 0}}, // (167, 10) + {128, { 0, 0, 0}}, // (168, 10) + {128, { 0, 0, 0}}, // (169, 10) + {128, { 0, 0, 0}}, // (170, 10) + {128, { 0, 0, 0}}, // (171, 10) + {128, { 0, 0, 0}}, // (172, 10) + {128, { 0, 0, 0}}, // (173, 10) + {128, { 0, 0, 0}}, // (174, 10) + {128, { 0, 0, 0}}, // (175, 10) + {128, { 0, 0, 0}}, // (176, 10) + {128, { 0, 0, 0}}, // (177, 10) + {128, { 0, 0, 0}}, // (178, 10) + {128, { 0, 0, 0}}, // (179, 10) + {128, { 0, 0, 0}}, // ( 0, 11) + {128, { 0, 0, 0}}, // ( 1, 11) + {128, { 0, 0, 0}}, // ( 2, 11) + {128, { 0, 0, 0}}, // ( 3, 11) + {128, { 0, 0, 0}}, // ( 4, 11) + {128, { 0, 0, 0}}, // ( 5, 11) + {128, { 0, 0, 0}}, // ( 6, 11) + {128, { 0, 0, 0}}, // ( 7, 11) + {128, { 0, 0, 0}}, // ( 8, 11) + {128, { 0, 0, 0}}, // ( 9, 11) + {128, { 0, 0, 0}}, // ( 10, 11) + {128, { 0, 0, 0}}, // ( 11, 11) + {128, { 0, 0, 0}}, // ( 12, 11) + {128, { 0, 0, 0}}, // ( 13, 11) + {128, { 0, 0, 0}}, // ( 14, 11) + {128, { 0, 0, 0}}, // ( 15, 11) + {128, { 0, 0, 0}}, // ( 16, 11) + {128, { 0, 0, 0}}, // ( 17, 11) + {128, { 0, 0, 0}}, // ( 18, 11) + {128, { 0, 0, 0}}, // ( 19, 11) + {128, { 0, 0, 0}}, // ( 20, 11) + {128, { 0, 0, 0}}, // ( 21, 11) + {128, { 0, 0, 0}}, // ( 22, 11) + {128, { 0, 0, 0}}, // ( 23, 11) + {128, { 0, 0, 0}}, // ( 24, 11) + {128, { 0, 0, 0}}, // ( 25, 11) + {128, { 0, 0, 0}}, // ( 26, 11) + {128, { 0, 0, 0}}, // ( 27, 11) + {128, { 0, 0, 0}}, // ( 28, 11) + {128, { 0, 0, 0}}, // ( 29, 11) + {128, { 0, 0, 0}}, // ( 30, 11) + {128, { 0, 0, 0}}, // ( 31, 11) + {128, { 0, 0, 0}}, // ( 32, 11) + {128, { 0, 0, 0}}, // ( 33, 11) + {128, { 0, 0, 0}}, // ( 34, 11) + {128, { 0, 0, 0}}, // ( 35, 11) + {128, { 0, 0, 0}}, // ( 36, 11) + {128, { 0, 0, 0}}, // ( 37, 11) + {128, { 0, 0, 0}}, // ( 38, 11) + {128, { 0, 0, 0}}, // ( 39, 11) + {128, { 0, 0, 0}}, // ( 40, 11) + {128, { 0, 0, 0}}, // ( 41, 11) + {128, { 0, 0, 0}}, // ( 42, 11) + {128, { 0, 0, 0}}, // ( 43, 11) + {128, { 0, 0, 0}}, // ( 44, 11) + {128, { 0, 0, 0}}, // ( 45, 11) + {128, { 0, 0, 0}}, // ( 46, 11) + {128, { 0, 0, 0}}, // ( 47, 11) + {128, { 0, 0, 0}}, // ( 48, 11) + {111, { 0, 0, 0}}, // ( 49, 11) + { 47, { 0, 0, 0}}, // ( 50, 11) + { 2, { 0, 0, 0}}, // ( 51, 11) + { 0, { 0, 0, 0}}, // ( 52, 11) + { 0, { 0, 0, 0}}, // ( 53, 11) + { 0, { 0, 0, 0}}, // ( 54, 11) + { 0, { 0, 0, 0}}, // ( 55, 11) + { 0, { 0, 0, 0}}, // ( 56, 11) + { 0, { 0, 0, 0}}, // ( 57, 11) + { 0, { 0, 0, 0}}, // ( 58, 11) + { 0, { 0, 0, 0}}, // ( 59, 11) + { 0, { 0, 0, 0}}, // ( 60, 11) + { 0, { 0, 0, 0}}, // ( 61, 11) + { 0, { 0, 0, 0}}, // ( 62, 11) + { 0, { 0, 0, 0}}, // ( 63, 11) + { 0, { 0, 0, 0}}, // ( 64, 11) + { 0, { 0, 0, 0}}, // ( 65, 11) + { 0, { 0, 0, 0}}, // ( 66, 11) + { 0, { 0, 0, 0}}, // ( 67, 11) + { 0, { 0, 0, 0}}, // ( 68, 11) + { 0, { 0, 0, 0}}, // ( 69, 11) + { 0, { 0, 0, 0}}, // ( 70, 11) + { 0, { 0, 0, 0}}, // ( 71, 11) + { 0, { 0, 0, 0}}, // ( 72, 11) + { 0, { 0, 0, 0}}, // ( 73, 11) + { 0, { 0, 0, 0}}, // ( 74, 11) + { 0, { 0, 0, 0}}, // ( 75, 11) + { 0, { 0, 0, 0}}, // ( 76, 11) + { 0, { 0, 0, 0}}, // ( 77, 11) + { 0, { 0, 0, 0}}, // ( 78, 11) + { 0, { 0, 0, 0}}, // ( 79, 11) + { 0, { 0, 0, 0}}, // ( 80, 11) + { 0, { 0, 0, 0}}, // ( 81, 11) + { 0, { 0, 0, 0}}, // ( 82, 11) + { 0, { 0, 0, 0}}, // ( 83, 11) + { 0, { 0, 0, 0}}, // ( 84, 11) + { 0, { 0, 0, 0}}, // ( 85, 11) + { 0, { 0, 0, 0}}, // ( 86, 11) + { 0, { 0, 0, 0}}, // ( 87, 11) + { 0, { 0, 0, 0}}, // ( 88, 11) + { 0, { 0, 0, 0}}, // ( 89, 11) + { 0, { 0, 0, 0}}, // ( 90, 11) + { 0, { 0, 0, 0}}, // ( 91, 11) + { 0, { 0, 0, 0}}, // ( 92, 11) + { 0, { 0, 0, 0}}, // ( 93, 11) + { 0, { 0, 0, 0}}, // ( 94, 11) + { 0, { 0, 0, 0}}, // ( 95, 11) + { 0, { 0, 0, 0}}, // ( 96, 11) + { 0, { 0, 0, 0}}, // ( 97, 11) + { 0, { 0, 0, 0}}, // ( 98, 11) + { 0, { 0, 0, 0}}, // ( 99, 11) + { 0, { 0, 0, 0}}, // (100, 11) + { 0, { 0, 0, 0}}, // (101, 11) + { 0, { 0, 0, 0}}, // (102, 11) + { 0, { 0, 0, 0}}, // (103, 11) + { 0, { 0, 0, 0}}, // (104, 11) + { 0, { 0, 0, 0}}, // (105, 11) + { 0, { 0, 0, 0}}, // (106, 11) + { 0, { 0, 0, 0}}, // (107, 11) + { 0, { 0, 0, 0}}, // (108, 11) + { 0, { 0, 0, 0}}, // (109, 11) + { 0, { 0, 0, 0}}, // (110, 11) + { 0, { 0, 0, 0}}, // (111, 11) + { 0, { 0, 0, 0}}, // (112, 11) + { 0, { 0, 0, 0}}, // (113, 11) + { 0, { 0, 0, 0}}, // (114, 11) + { 0, { 0, 0, 0}}, // (115, 11) + { 0, { 0, 0, 0}}, // (116, 11) + { 0, { 0, 0, 0}}, // (117, 11) + { 0, { 0, 0, 0}}, // (118, 11) + { 0, { 0, 0, 0}}, // (119, 11) + { 0, { 0, 0, 0}}, // (120, 11) + { 0, { 0, 0, 0}}, // (121, 11) + { 0, { 0, 0, 0}}, // (122, 11) + { 0, { 0, 0, 0}}, // (123, 11) + { 0, { 0, 0, 0}}, // (124, 11) + { 0, { 0, 0, 0}}, // (125, 11) + { 0, { 0, 0, 0}}, // (126, 11) + { 0, { 0, 0, 0}}, // (127, 11) + { 2, { 0, 0, 0}}, // (128, 11) + { 47, { 0, 0, 0}}, // (129, 11) + {111, { 0, 0, 0}}, // (130, 11) + {128, { 0, 0, 0}}, // (131, 11) + {128, { 0, 0, 0}}, // (132, 11) + {128, { 0, 0, 0}}, // (133, 11) + {128, { 0, 0, 0}}, // (134, 11) + {128, { 0, 0, 0}}, // (135, 11) + {128, { 0, 0, 0}}, // (136, 11) + {128, { 0, 0, 0}}, // (137, 11) + {128, { 0, 0, 0}}, // (138, 11) + {128, { 0, 0, 0}}, // (139, 11) + {128, { 0, 0, 0}}, // (140, 11) + {128, { 0, 0, 0}}, // (141, 11) + {128, { 0, 0, 0}}, // (142, 11) + {128, { 0, 0, 0}}, // (143, 11) + {128, { 0, 0, 0}}, // (144, 11) + {128, { 0, 0, 0}}, // (145, 11) + {128, { 0, 0, 0}}, // (146, 11) + {128, { 0, 0, 0}}, // (147, 11) + {128, { 0, 0, 0}}, // (148, 11) + {128, { 0, 0, 0}}, // (149, 11) + {128, { 0, 0, 0}}, // (150, 11) + {128, { 0, 0, 0}}, // (151, 11) + {128, { 0, 0, 0}}, // (152, 11) + {128, { 0, 0, 0}}, // (153, 11) + {128, { 0, 0, 0}}, // (154, 11) + {128, { 0, 0, 0}}, // (155, 11) + {128, { 0, 0, 0}}, // (156, 11) + {128, { 0, 0, 0}}, // (157, 11) + {128, { 0, 0, 0}}, // (158, 11) + {128, { 0, 0, 0}}, // (159, 11) + {128, { 0, 0, 0}}, // (160, 11) + {128, { 0, 0, 0}}, // (161, 11) + {128, { 0, 0, 0}}, // (162, 11) + {128, { 0, 0, 0}}, // (163, 11) + {128, { 0, 0, 0}}, // (164, 11) + {128, { 0, 0, 0}}, // (165, 11) + {128, { 0, 0, 0}}, // (166, 11) + {128, { 0, 0, 0}}, // (167, 11) + {128, { 0, 0, 0}}, // (168, 11) + {128, { 0, 0, 0}}, // (169, 11) + {128, { 0, 0, 0}}, // (170, 11) + {128, { 0, 0, 0}}, // (171, 11) + {128, { 0, 0, 0}}, // (172, 11) + {128, { 0, 0, 0}}, // (173, 11) + {128, { 0, 0, 0}}, // (174, 11) + {128, { 0, 0, 0}}, // (175, 11) + {128, { 0, 0, 0}}, // (176, 11) + {128, { 0, 0, 0}}, // (177, 11) + {128, { 0, 0, 0}}, // (178, 11) + {128, { 0, 0, 0}}, // (179, 11) + {128, { 0, 0, 0}}, // ( 0, 12) + {128, { 0, 0, 0}}, // ( 1, 12) + {128, { 0, 0, 0}}, // ( 2, 12) + {128, { 0, 0, 0}}, // ( 3, 12) + {128, { 0, 0, 0}}, // ( 4, 12) + {128, { 0, 0, 0}}, // ( 5, 12) + {128, { 0, 0, 0}}, // ( 6, 12) + {128, { 0, 0, 0}}, // ( 7, 12) + {128, { 0, 0, 0}}, // ( 8, 12) + {128, { 0, 0, 0}}, // ( 9, 12) + {128, { 0, 0, 0}}, // ( 10, 12) + {128, { 0, 0, 0}}, // ( 11, 12) + {128, { 0, 0, 0}}, // ( 12, 12) + {128, { 0, 0, 0}}, // ( 13, 12) + {128, { 0, 0, 0}}, // ( 14, 12) + {128, { 0, 0, 0}}, // ( 15, 12) + {128, { 0, 0, 0}}, // ( 16, 12) + {128, { 0, 0, 0}}, // ( 17, 12) + {128, { 0, 0, 0}}, // ( 18, 12) + {128, { 0, 0, 0}}, // ( 19, 12) + {128, { 0, 0, 0}}, // ( 20, 12) + {128, { 0, 0, 0}}, // ( 21, 12) + {128, { 0, 0, 0}}, // ( 22, 12) + {128, { 0, 0, 0}}, // ( 23, 12) + {128, { 0, 0, 0}}, // ( 24, 12) + {128, { 0, 0, 0}}, // ( 25, 12) + {128, { 0, 0, 0}}, // ( 26, 12) + {128, { 0, 0, 0}}, // ( 27, 12) + {128, { 0, 0, 0}}, // ( 28, 12) + {128, { 0, 0, 0}}, // ( 29, 12) + {128, { 0, 0, 0}}, // ( 30, 12) + {128, { 0, 0, 0}}, // ( 31, 12) + {128, { 0, 0, 0}}, // ( 32, 12) + {128, { 0, 0, 0}}, // ( 33, 12) + {128, { 0, 0, 0}}, // ( 34, 12) + {128, { 0, 0, 0}}, // ( 35, 12) + {128, { 0, 0, 0}}, // ( 36, 12) + {128, { 0, 0, 0}}, // ( 37, 12) + {128, { 0, 0, 0}}, // ( 38, 12) + {128, { 0, 0, 0}}, // ( 39, 12) + {128, { 0, 0, 0}}, // ( 40, 12) + {128, { 0, 0, 0}}, // ( 41, 12) + {128, { 0, 0, 0}}, // ( 42, 12) + {128, { 0, 0, 0}}, // ( 43, 12) + {128, { 0, 0, 0}}, // ( 44, 12) + {128, { 0, 0, 0}}, // ( 45, 12) + {128, { 0, 0, 0}}, // ( 46, 12) + {115, { 0, 0, 0}}, // ( 47, 12) + { 51, { 0, 0, 0}}, // ( 48, 12) + { 3, { 0, 0, 0}}, // ( 49, 12) + { 0, { 0, 0, 0}}, // ( 50, 12) + { 0, { 0, 0, 0}}, // ( 51, 12) + { 0, { 0, 0, 0}}, // ( 52, 12) + { 0, { 0, 0, 0}}, // ( 53, 12) + { 0, { 0, 0, 0}}, // ( 54, 12) + { 0, { 0, 0, 0}}, // ( 55, 12) + { 0, { 0, 0, 0}}, // ( 56, 12) + { 0, { 0, 0, 0}}, // ( 57, 12) + { 0, { 0, 0, 0}}, // ( 58, 12) + { 0, { 0, 0, 0}}, // ( 59, 12) + { 0, { 0, 0, 0}}, // ( 60, 12) + { 0, { 0, 0, 0}}, // ( 61, 12) + { 0, { 0, 0, 0}}, // ( 62, 12) + { 0, { 0, 0, 0}}, // ( 63, 12) + { 0, { 0, 0, 0}}, // ( 64, 12) + { 0, { 0, 0, 0}}, // ( 65, 12) + { 0, { 0, 0, 0}}, // ( 66, 12) + { 0, { 0, 0, 0}}, // ( 67, 12) + { 0, { 0, 0, 0}}, // ( 68, 12) + { 0, { 0, 0, 0}}, // ( 69, 12) + { 0, { 0, 0, 0}}, // ( 70, 12) + { 0, { 0, 0, 0}}, // ( 71, 12) + { 0, { 0, 0, 0}}, // ( 72, 12) + { 0, { 0, 0, 0}}, // ( 73, 12) + { 0, { 0, 0, 0}}, // ( 74, 12) + { 0, { 0, 0, 0}}, // ( 75, 12) + { 0, { 0, 0, 0}}, // ( 76, 12) + { 0, { 0, 0, 0}}, // ( 77, 12) + { 0, { 0, 0, 0}}, // ( 78, 12) + { 0, { 0, 0, 0}}, // ( 79, 12) + { 0, { 0, 0, 0}}, // ( 80, 12) + { 0, { 0, 0, 0}}, // ( 81, 12) + { 0, { 0, 0, 0}}, // ( 82, 12) + { 0, { 0, 0, 0}}, // ( 83, 12) + { 0, { 0, 0, 0}}, // ( 84, 12) + { 0, { 0, 0, 0}}, // ( 85, 12) + { 0, { 0, 0, 0}}, // ( 86, 12) + { 0, { 0, 0, 0}}, // ( 87, 12) + { 0, { 0, 0, 0}}, // ( 88, 12) + { 0, { 0, 0, 0}}, // ( 89, 12) + { 0, { 0, 0, 0}}, // ( 90, 12) + { 0, { 0, 0, 0}}, // ( 91, 12) + { 0, { 0, 0, 0}}, // ( 92, 12) + { 0, { 0, 0, 0}}, // ( 93, 12) + { 0, { 0, 0, 0}}, // ( 94, 12) + { 0, { 0, 0, 0}}, // ( 95, 12) + { 0, { 0, 0, 0}}, // ( 96, 12) + { 0, { 0, 0, 0}}, // ( 97, 12) + { 0, { 0, 0, 0}}, // ( 98, 12) + { 0, { 0, 0, 0}}, // ( 99, 12) + { 0, { 0, 0, 0}}, // (100, 12) + { 0, { 0, 0, 0}}, // (101, 12) + { 0, { 0, 0, 0}}, // (102, 12) + { 0, { 0, 0, 0}}, // (103, 12) + { 0, { 0, 0, 0}}, // (104, 12) + { 0, { 0, 0, 0}}, // (105, 12) + { 0, { 0, 0, 0}}, // (106, 12) + { 0, { 0, 0, 0}}, // (107, 12) + { 0, { 0, 0, 0}}, // (108, 12) + { 0, { 0, 0, 0}}, // (109, 12) + { 0, { 0, 0, 0}}, // (110, 12) + { 0, { 0, 0, 0}}, // (111, 12) + { 0, { 0, 0, 0}}, // (112, 12) + { 0, { 0, 0, 0}}, // (113, 12) + { 0, { 0, 0, 0}}, // (114, 12) + { 0, { 0, 0, 0}}, // (115, 12) + { 0, { 0, 0, 0}}, // (116, 12) + { 0, { 0, 0, 0}}, // (117, 12) + { 0, { 0, 0, 0}}, // (118, 12) + { 0, { 0, 0, 0}}, // (119, 12) + { 0, { 0, 0, 0}}, // (120, 12) + { 0, { 0, 0, 0}}, // (121, 12) + { 0, { 0, 0, 0}}, // (122, 12) + { 0, { 0, 0, 0}}, // (123, 12) + { 0, { 0, 0, 0}}, // (124, 12) + { 0, { 0, 0, 0}}, // (125, 12) + { 0, { 0, 0, 0}}, // (126, 12) + { 0, { 0, 0, 0}}, // (127, 12) + { 0, { 0, 0, 0}}, // (128, 12) + { 0, { 0, 0, 0}}, // (129, 12) + { 3, { 0, 0, 0}}, // (130, 12) + { 51, { 0, 0, 0}}, // (131, 12) + {115, { 0, 0, 0}}, // (132, 12) + {128, { 0, 0, 0}}, // (133, 12) + {128, { 0, 0, 0}}, // (134, 12) + {128, { 0, 0, 0}}, // (135, 12) + {128, { 0, 0, 0}}, // (136, 12) + {128, { 0, 0, 0}}, // (137, 12) + {128, { 0, 0, 0}}, // (138, 12) + {128, { 0, 0, 0}}, // (139, 12) + {128, { 0, 0, 0}}, // (140, 12) + {128, { 0, 0, 0}}, // (141, 12) + {128, { 0, 0, 0}}, // (142, 12) + {128, { 0, 0, 0}}, // (143, 12) + {128, { 0, 0, 0}}, // (144, 12) + {128, { 0, 0, 0}}, // (145, 12) + {128, { 0, 0, 0}}, // (146, 12) + {128, { 0, 0, 0}}, // (147, 12) + {128, { 0, 0, 0}}, // (148, 12) + {128, { 0, 0, 0}}, // (149, 12) + {128, { 0, 0, 0}}, // (150, 12) + {128, { 0, 0, 0}}, // (151, 12) + {128, { 0, 0, 0}}, // (152, 12) + {128, { 0, 0, 0}}, // (153, 12) + {128, { 0, 0, 0}}, // (154, 12) + {128, { 0, 0, 0}}, // (155, 12) + {128, { 0, 0, 0}}, // (156, 12) + {128, { 0, 0, 0}}, // (157, 12) + {128, { 0, 0, 0}}, // (158, 12) + {128, { 0, 0, 0}}, // (159, 12) + {128, { 0, 0, 0}}, // (160, 12) + {128, { 0, 0, 0}}, // (161, 12) + {128, { 0, 0, 0}}, // (162, 12) + {128, { 0, 0, 0}}, // (163, 12) + {128, { 0, 0, 0}}, // (164, 12) + {128, { 0, 0, 0}}, // (165, 12) + {128, { 0, 0, 0}}, // (166, 12) + {128, { 0, 0, 0}}, // (167, 12) + {128, { 0, 0, 0}}, // (168, 12) + {128, { 0, 0, 0}}, // (169, 12) + {128, { 0, 0, 0}}, // (170, 12) + {128, { 0, 0, 0}}, // (171, 12) + {128, { 0, 0, 0}}, // (172, 12) + {128, { 0, 0, 0}}, // (173, 12) + {128, { 0, 0, 0}}, // (174, 12) + {128, { 0, 0, 0}}, // (175, 12) + {128, { 0, 0, 0}}, // (176, 12) + {128, { 0, 0, 0}}, // (177, 12) + {128, { 0, 0, 0}}, // (178, 12) + {128, { 0, 0, 0}}, // (179, 12) + {128, { 0, 0, 0}}, // ( 0, 13) + {128, { 0, 0, 0}}, // ( 1, 13) + {128, { 0, 0, 0}}, // ( 2, 13) + {128, { 0, 0, 0}}, // ( 3, 13) + {128, { 0, 0, 0}}, // ( 4, 13) + {128, { 0, 0, 0}}, // ( 5, 13) + {128, { 0, 0, 0}}, // ( 6, 13) + {128, { 0, 0, 0}}, // ( 7, 13) + {128, { 0, 0, 0}}, // ( 8, 13) + {128, { 0, 0, 0}}, // ( 9, 13) + {128, { 0, 0, 0}}, // ( 10, 13) + {128, { 0, 0, 0}}, // ( 11, 13) + {128, { 0, 0, 0}}, // ( 12, 13) + {128, { 0, 0, 0}}, // ( 13, 13) + {128, { 0, 0, 0}}, // ( 14, 13) + {128, { 0, 0, 0}}, // ( 15, 13) + {128, { 0, 0, 0}}, // ( 16, 13) + {128, { 0, 0, 0}}, // ( 17, 13) + {128, { 0, 0, 0}}, // ( 18, 13) + {128, { 0, 0, 0}}, // ( 19, 13) + {128, { 0, 0, 0}}, // ( 20, 13) + {128, { 0, 0, 0}}, // ( 21, 13) + {128, { 0, 0, 0}}, // ( 22, 13) + {128, { 0, 0, 0}}, // ( 23, 13) + {128, { 0, 0, 0}}, // ( 24, 13) + {128, { 0, 0, 0}}, // ( 25, 13) + {128, { 0, 0, 0}}, // ( 26, 13) + {128, { 0, 0, 0}}, // ( 27, 13) + {128, { 0, 0, 0}}, // ( 28, 13) + {128, { 0, 0, 0}}, // ( 29, 13) + {128, { 0, 0, 0}}, // ( 30, 13) + {128, { 0, 0, 0}}, // ( 31, 13) + {128, { 0, 0, 0}}, // ( 32, 13) + {128, { 0, 0, 0}}, // ( 33, 13) + {128, { 0, 0, 0}}, // ( 34, 13) + {128, { 0, 0, 0}}, // ( 35, 13) + {128, { 0, 0, 0}}, // ( 36, 13) + {128, { 0, 0, 0}}, // ( 37, 13) + {128, { 0, 0, 0}}, // ( 38, 13) + {128, { 0, 0, 0}}, // ( 39, 13) + {128, { 0, 0, 0}}, // ( 40, 13) + {128, { 0, 0, 0}}, // ( 41, 13) + {128, { 0, 0, 0}}, // ( 42, 13) + {128, { 0, 0, 0}}, // ( 43, 13) + {128, { 0, 0, 0}}, // ( 44, 13) + {123, { 0, 0, 0}}, // ( 45, 13) + { 66, { 0, 0, 0}}, // ( 46, 13) + { 6, { 0, 0, 0}}, // ( 47, 13) + { 0, { 0, 0, 0}}, // ( 48, 13) + { 0, { 0, 0, 0}}, // ( 49, 13) + { 0, { 0, 0, 0}}, // ( 50, 13) + { 0, { 0, 0, 0}}, // ( 51, 13) + { 0, { 0, 0, 0}}, // ( 52, 13) + { 0, { 0, 0, 0}}, // ( 53, 13) + { 0, { 0, 0, 0}}, // ( 54, 13) + { 0, { 0, 0, 0}}, // ( 55, 13) + { 0, { 0, 0, 0}}, // ( 56, 13) + { 0, { 0, 0, 0}}, // ( 57, 13) + { 0, { 0, 0, 0}}, // ( 58, 13) + { 0, { 0, 0, 0}}, // ( 59, 13) + { 0, { 0, 0, 0}}, // ( 60, 13) + { 0, { 0, 0, 0}}, // ( 61, 13) + { 0, { 0, 0, 0}}, // ( 62, 13) + { 0, { 0, 0, 0}}, // ( 63, 13) + { 0, { 0, 0, 0}}, // ( 64, 13) + { 0, { 0, 0, 0}}, // ( 65, 13) + { 0, { 0, 0, 0}}, // ( 66, 13) + { 0, { 0, 0, 0}}, // ( 67, 13) + { 0, { 0, 0, 0}}, // ( 68, 13) + { 0, { 0, 0, 0}}, // ( 69, 13) + { 0, { 0, 0, 0}}, // ( 70, 13) + { 0, { 0, 0, 0}}, // ( 71, 13) + { 0, { 0, 0, 0}}, // ( 72, 13) + { 0, { 0, 0, 0}}, // ( 73, 13) + { 0, { 0, 0, 0}}, // ( 74, 13) + { 0, { 0, 0, 0}}, // ( 75, 13) + { 0, { 0, 0, 0}}, // ( 76, 13) + { 0, { 0, 0, 0}}, // ( 77, 13) + { 0, { 0, 0, 0}}, // ( 78, 13) + { 0, { 0, 0, 0}}, // ( 79, 13) + { 0, { 0, 0, 0}}, // ( 80, 13) + { 0, { 0, 0, 0}}, // ( 81, 13) + { 0, { 0, 0, 0}}, // ( 82, 13) + { 0, { 0, 0, 0}}, // ( 83, 13) + { 0, { 0, 0, 0}}, // ( 84, 13) + { 0, { 0, 0, 0}}, // ( 85, 13) + { 0, { 0, 0, 0}}, // ( 86, 13) + { 0, { 0, 0, 0}}, // ( 87, 13) + { 0, { 0, 0, 0}}, // ( 88, 13) + { 0, { 0, 0, 0}}, // ( 89, 13) + { 0, { 0, 0, 0}}, // ( 90, 13) + { 0, { 0, 0, 0}}, // ( 91, 13) + { 0, { 0, 0, 0}}, // ( 92, 13) + { 0, { 0, 0, 0}}, // ( 93, 13) + { 0, { 0, 0, 0}}, // ( 94, 13) + { 0, { 0, 0, 0}}, // ( 95, 13) + { 0, { 0, 0, 0}}, // ( 96, 13) + { 0, { 0, 0, 0}}, // ( 97, 13) + { 0, { 0, 0, 0}}, // ( 98, 13) + { 0, { 0, 0, 0}}, // ( 99, 13) + { 0, { 0, 0, 0}}, // (100, 13) + { 0, { 0, 0, 0}}, // (101, 13) + { 0, { 0, 0, 0}}, // (102, 13) + { 0, { 0, 0, 0}}, // (103, 13) + { 0, { 0, 0, 0}}, // (104, 13) + { 0, { 0, 0, 0}}, // (105, 13) + { 0, { 0, 0, 0}}, // (106, 13) + { 0, { 0, 0, 0}}, // (107, 13) + { 0, { 0, 0, 0}}, // (108, 13) + { 0, { 0, 0, 0}}, // (109, 13) + { 0, { 0, 0, 0}}, // (110, 13) + { 0, { 0, 0, 0}}, // (111, 13) + { 0, { 0, 0, 0}}, // (112, 13) + { 0, { 0, 0, 0}}, // (113, 13) + { 0, { 0, 0, 0}}, // (114, 13) + { 0, { 0, 0, 0}}, // (115, 13) + { 0, { 0, 0, 0}}, // (116, 13) + { 0, { 0, 0, 0}}, // (117, 13) + { 0, { 0, 0, 0}}, // (118, 13) + { 0, { 0, 0, 0}}, // (119, 13) + { 0, { 0, 0, 0}}, // (120, 13) + { 0, { 0, 0, 0}}, // (121, 13) + { 0, { 0, 0, 0}}, // (122, 13) + { 0, { 0, 0, 0}}, // (123, 13) + { 0, { 0, 0, 0}}, // (124, 13) + { 0, { 0, 0, 0}}, // (125, 13) + { 0, { 0, 0, 0}}, // (126, 13) + { 0, { 0, 0, 0}}, // (127, 13) + { 0, { 0, 0, 0}}, // (128, 13) + { 0, { 0, 0, 0}}, // (129, 13) + { 0, { 0, 0, 0}}, // (130, 13) + { 0, { 0, 0, 0}}, // (131, 13) + { 6, { 0, 0, 0}}, // (132, 13) + { 66, { 0, 0, 0}}, // (133, 13) + {123, { 0, 0, 0}}, // (134, 13) + {128, { 0, 0, 0}}, // (135, 13) + {128, { 0, 0, 0}}, // (136, 13) + {128, { 0, 0, 0}}, // (137, 13) + {128, { 0, 0, 0}}, // (138, 13) + {128, { 0, 0, 0}}, // (139, 13) + {128, { 0, 0, 0}}, // (140, 13) + {128, { 0, 0, 0}}, // (141, 13) + {128, { 0, 0, 0}}, // (142, 13) + {128, { 0, 0, 0}}, // (143, 13) + {128, { 0, 0, 0}}, // (144, 13) + {128, { 0, 0, 0}}, // (145, 13) + {128, { 0, 0, 0}}, // (146, 13) + {128, { 0, 0, 0}}, // (147, 13) + {128, { 0, 0, 0}}, // (148, 13) + {128, { 0, 0, 0}}, // (149, 13) + {128, { 0, 0, 0}}, // (150, 13) + {128, { 0, 0, 0}}, // (151, 13) + {128, { 0, 0, 0}}, // (152, 13) + {128, { 0, 0, 0}}, // (153, 13) + {128, { 0, 0, 0}}, // (154, 13) + {128, { 0, 0, 0}}, // (155, 13) + {128, { 0, 0, 0}}, // (156, 13) + {128, { 0, 0, 0}}, // (157, 13) + {128, { 0, 0, 0}}, // (158, 13) + {128, { 0, 0, 0}}, // (159, 13) + {128, { 0, 0, 0}}, // (160, 13) + {128, { 0, 0, 0}}, // (161, 13) + {128, { 0, 0, 0}}, // (162, 13) + {128, { 0, 0, 0}}, // (163, 13) + {128, { 0, 0, 0}}, // (164, 13) + {128, { 0, 0, 0}}, // (165, 13) + {128, { 0, 0, 0}}, // (166, 13) + {128, { 0, 0, 0}}, // (167, 13) + {128, { 0, 0, 0}}, // (168, 13) + {128, { 0, 0, 0}}, // (169, 13) + {128, { 0, 0, 0}}, // (170, 13) + {128, { 0, 0, 0}}, // (171, 13) + {128, { 0, 0, 0}}, // (172, 13) + {128, { 0, 0, 0}}, // (173, 13) + {128, { 0, 0, 0}}, // (174, 13) + {128, { 0, 0, 0}}, // (175, 13) + {128, { 0, 0, 0}}, // (176, 13) + {128, { 0, 0, 0}}, // (177, 13) + {128, { 0, 0, 0}}, // (178, 13) + {128, { 0, 0, 0}}, // (179, 13) + {128, { 0, 0, 0}}, // ( 0, 14) + {128, { 0, 0, 0}}, // ( 1, 14) + {128, { 0, 0, 0}}, // ( 2, 14) + {128, { 0, 0, 0}}, // ( 3, 14) + {128, { 0, 0, 0}}, // ( 4, 14) + {128, { 0, 0, 0}}, // ( 5, 14) + {128, { 0, 0, 0}}, // ( 6, 14) + {128, { 0, 0, 0}}, // ( 7, 14) + {128, { 0, 0, 0}}, // ( 8, 14) + {128, { 0, 0, 0}}, // ( 9, 14) + {128, { 0, 0, 0}}, // ( 10, 14) + {128, { 0, 0, 0}}, // ( 11, 14) + {128, { 0, 0, 0}}, // ( 12, 14) + {128, { 0, 0, 0}}, // ( 13, 14) + {128, { 0, 0, 0}}, // ( 14, 14) + {128, { 0, 0, 0}}, // ( 15, 14) + {128, { 0, 0, 0}}, // ( 16, 14) + {128, { 0, 0, 0}}, // ( 17, 14) + {128, { 0, 0, 0}}, // ( 18, 14) + {128, { 0, 0, 0}}, // ( 19, 14) + {128, { 0, 0, 0}}, // ( 20, 14) + {128, { 0, 0, 0}}, // ( 21, 14) + {128, { 0, 0, 0}}, // ( 22, 14) + {128, { 0, 0, 0}}, // ( 23, 14) + {128, { 0, 0, 0}}, // ( 24, 14) + {128, { 0, 0, 0}}, // ( 25, 14) + {128, { 0, 0, 0}}, // ( 26, 14) + {128, { 0, 0, 0}}, // ( 27, 14) + {128, { 0, 0, 0}}, // ( 28, 14) + {128, { 0, 0, 0}}, // ( 29, 14) + {128, { 0, 0, 0}}, // ( 30, 14) + {128, { 0, 0, 0}}, // ( 31, 14) + {128, { 0, 0, 0}}, // ( 32, 14) + {128, { 0, 0, 0}}, // ( 33, 14) + {128, { 0, 0, 0}}, // ( 34, 14) + {128, { 0, 0, 0}}, // ( 35, 14) + {128, { 0, 0, 0}}, // ( 36, 14) + {128, { 0, 0, 0}}, // ( 37, 14) + {128, { 0, 0, 0}}, // ( 38, 14) + {128, { 0, 0, 0}}, // ( 39, 14) + {128, { 0, 0, 0}}, // ( 40, 14) + {128, { 0, 0, 0}}, // ( 41, 14) + {128, { 0, 0, 0}}, // ( 42, 14) + {128, { 0, 0, 0}}, // ( 43, 14) + { 86, { 0, 0, 0}}, // ( 44, 14) + { 15, { 0, 0, 0}}, // ( 45, 14) + { 0, { 0, 0, 0}}, // ( 46, 14) + { 0, { 0, 0, 0}}, // ( 47, 14) + { 0, { 0, 0, 0}}, // ( 48, 14) + { 0, { 0, 0, 0}}, // ( 49, 14) + { 0, { 0, 0, 0}}, // ( 50, 14) + { 0, { 0, 0, 0}}, // ( 51, 14) + { 0, { 0, 0, 0}}, // ( 52, 14) + { 0, { 0, 0, 0}}, // ( 53, 14) + { 0, { 0, 0, 0}}, // ( 54, 14) + { 0, { 0, 0, 0}}, // ( 55, 14) + { 0, { 0, 0, 0}}, // ( 56, 14) + { 0, { 0, 0, 0}}, // ( 57, 14) + { 0, { 0, 0, 0}}, // ( 58, 14) + { 0, { 0, 0, 0}}, // ( 59, 14) + { 0, { 0, 0, 0}}, // ( 60, 14) + { 0, { 0, 0, 0}}, // ( 61, 14) + { 0, { 0, 0, 0}}, // ( 62, 14) + { 0, { 0, 0, 0}}, // ( 63, 14) + { 0, { 0, 0, 0}}, // ( 64, 14) + { 0, { 0, 0, 0}}, // ( 65, 14) + { 0, { 0, 0, 0}}, // ( 66, 14) + { 0, { 0, 0, 0}}, // ( 67, 14) + { 0, { 0, 0, 0}}, // ( 68, 14) + { 0, { 0, 0, 0}}, // ( 69, 14) + { 0, { 0, 0, 0}}, // ( 70, 14) + { 0, { 0, 0, 0}}, // ( 71, 14) + { 0, { 0, 0, 0}}, // ( 72, 14) + { 0, { 0, 0, 0}}, // ( 73, 14) + { 0, { 0, 0, 0}}, // ( 74, 14) + { 0, { 0, 0, 0}}, // ( 75, 14) + { 0, { 0, 0, 0}}, // ( 76, 14) + { 0, { 0, 0, 0}}, // ( 77, 14) + { 0, { 0, 0, 0}}, // ( 78, 14) + { 0, { 0, 0, 0}}, // ( 79, 14) + { 0, { 0, 0, 0}}, // ( 80, 14) + { 0, { 0, 0, 0}}, // ( 81, 14) + { 0, { 0, 0, 0}}, // ( 82, 14) + { 0, { 0, 0, 0}}, // ( 83, 14) + { 0, { 0, 0, 0}}, // ( 84, 14) + { 0, { 0, 0, 0}}, // ( 85, 14) + { 0, { 0, 0, 0}}, // ( 86, 14) + { 0, { 0, 0, 0}}, // ( 87, 14) + { 0, { 0, 0, 0}}, // ( 88, 14) + { 0, { 0, 0, 0}}, // ( 89, 14) + { 0, { 0, 0, 0}}, // ( 90, 14) + { 0, { 0, 0, 0}}, // ( 91, 14) + { 0, { 0, 0, 0}}, // ( 92, 14) + { 0, { 0, 0, 0}}, // ( 93, 14) + { 0, { 0, 0, 0}}, // ( 94, 14) + { 0, { 0, 0, 0}}, // ( 95, 14) + { 0, { 0, 0, 0}}, // ( 96, 14) + { 0, { 0, 0, 0}}, // ( 97, 14) + { 0, { 0, 0, 0}}, // ( 98, 14) + { 0, { 0, 0, 0}}, // ( 99, 14) + { 0, { 0, 0, 0}}, // (100, 14) + { 0, { 0, 0, 0}}, // (101, 14) + { 0, { 0, 0, 0}}, // (102, 14) + { 0, { 0, 0, 0}}, // (103, 14) + { 0, { 0, 0, 0}}, // (104, 14) + { 0, { 0, 0, 0}}, // (105, 14) + { 0, { 0, 0, 0}}, // (106, 14) + { 0, { 0, 0, 0}}, // (107, 14) + { 0, { 0, 0, 0}}, // (108, 14) + { 0, { 0, 0, 0}}, // (109, 14) + { 0, { 0, 0, 0}}, // (110, 14) + { 0, { 0, 0, 0}}, // (111, 14) + { 0, { 0, 0, 0}}, // (112, 14) + { 0, { 0, 0, 0}}, // (113, 14) + { 0, { 0, 0, 0}}, // (114, 14) + { 0, { 0, 0, 0}}, // (115, 14) + { 0, { 0, 0, 0}}, // (116, 14) + { 0, { 0, 0, 0}}, // (117, 14) + { 0, { 0, 0, 0}}, // (118, 14) + { 0, { 0, 0, 0}}, // (119, 14) + { 0, { 0, 0, 0}}, // (120, 14) + { 0, { 0, 0, 0}}, // (121, 14) + { 0, { 0, 0, 0}}, // (122, 14) + { 0, { 0, 0, 0}}, // (123, 14) + { 0, { 0, 0, 0}}, // (124, 14) + { 0, { 0, 0, 0}}, // (125, 14) + { 0, { 0, 0, 0}}, // (126, 14) + { 0, { 0, 0, 0}}, // (127, 14) + { 0, { 0, 0, 0}}, // (128, 14) + { 0, { 0, 0, 0}}, // (129, 14) + { 0, { 0, 0, 0}}, // (130, 14) + { 0, { 0, 0, 0}}, // (131, 14) + { 0, { 0, 0, 0}}, // (132, 14) + { 0, { 0, 0, 0}}, // (133, 14) + { 15, { 0, 0, 0}}, // (134, 14) + { 85, { 0, 0, 0}}, // (135, 14) + {128, { 0, 0, 0}}, // (136, 14) + {128, { 0, 0, 0}}, // (137, 14) + {128, { 0, 0, 0}}, // (138, 14) + {128, { 0, 0, 0}}, // (139, 14) + {128, { 0, 0, 0}}, // (140, 14) + {128, { 0, 0, 0}}, // (141, 14) + {128, { 0, 0, 0}}, // (142, 14) + {128, { 0, 0, 0}}, // (143, 14) + {128, { 0, 0, 0}}, // (144, 14) + {128, { 0, 0, 0}}, // (145, 14) + {128, { 0, 0, 0}}, // (146, 14) + {128, { 0, 0, 0}}, // (147, 14) + {128, { 0, 0, 0}}, // (148, 14) + {128, { 0, 0, 0}}, // (149, 14) + {128, { 0, 0, 0}}, // (150, 14) + {128, { 0, 0, 0}}, // (151, 14) + {128, { 0, 0, 0}}, // (152, 14) + {128, { 0, 0, 0}}, // (153, 14) + {128, { 0, 0, 0}}, // (154, 14) + {128, { 0, 0, 0}}, // (155, 14) + {128, { 0, 0, 0}}, // (156, 14) + {128, { 0, 0, 0}}, // (157, 14) + {128, { 0, 0, 0}}, // (158, 14) + {128, { 0, 0, 0}}, // (159, 14) + {128, { 0, 0, 0}}, // (160, 14) + {128, { 0, 0, 0}}, // (161, 14) + {128, { 0, 0, 0}}, // (162, 14) + {128, { 0, 0, 0}}, // (163, 14) + {128, { 0, 0, 0}}, // (164, 14) + {128, { 0, 0, 0}}, // (165, 14) + {128, { 0, 0, 0}}, // (166, 14) + {128, { 0, 0, 0}}, // (167, 14) + {128, { 0, 0, 0}}, // (168, 14) + {128, { 0, 0, 0}}, // (169, 14) + {128, { 0, 0, 0}}, // (170, 14) + {128, { 0, 0, 0}}, // (171, 14) + {128, { 0, 0, 0}}, // (172, 14) + {128, { 0, 0, 0}}, // (173, 14) + {128, { 0, 0, 0}}, // (174, 14) + {128, { 0, 0, 0}}, // (175, 14) + {128, { 0, 0, 0}}, // (176, 14) + {128, { 0, 0, 0}}, // (177, 14) + {128, { 0, 0, 0}}, // (178, 14) + {128, { 0, 0, 0}}, // (179, 14) + {128, { 0, 0, 0}}, // ( 0, 15) + {128, { 0, 0, 0}}, // ( 1, 15) + {128, { 0, 0, 0}}, // ( 2, 15) + {128, { 0, 0, 0}}, // ( 3, 15) + {128, { 0, 0, 0}}, // ( 4, 15) + {128, { 0, 0, 0}}, // ( 5, 15) + {128, { 0, 0, 0}}, // ( 6, 15) + {128, { 0, 0, 0}}, // ( 7, 15) + {128, { 0, 0, 0}}, // ( 8, 15) + {128, { 0, 0, 0}}, // ( 9, 15) + {128, { 0, 0, 0}}, // ( 10, 15) + {128, { 0, 0, 0}}, // ( 11, 15) + {128, { 0, 0, 0}}, // ( 12, 15) + {128, { 0, 0, 0}}, // ( 13, 15) + {128, { 0, 0, 0}}, // ( 14, 15) + {128, { 0, 0, 0}}, // ( 15, 15) + {128, { 0, 0, 0}}, // ( 16, 15) + {128, { 0, 0, 0}}, // ( 17, 15) + {128, { 0, 0, 0}}, // ( 18, 15) + {128, { 0, 0, 0}}, // ( 19, 15) + {128, { 0, 0, 0}}, // ( 20, 15) + {128, { 0, 0, 0}}, // ( 21, 15) + {128, { 0, 0, 0}}, // ( 22, 15) + {128, { 0, 0, 0}}, // ( 23, 15) + {128, { 0, 0, 0}}, // ( 24, 15) + {128, { 0, 0, 0}}, // ( 25, 15) + {128, { 0, 0, 0}}, // ( 26, 15) + {128, { 0, 0, 0}}, // ( 27, 15) + {128, { 0, 0, 0}}, // ( 28, 15) + {128, { 0, 0, 0}}, // ( 29, 15) + {128, { 0, 0, 0}}, // ( 30, 15) + {128, { 0, 0, 0}}, // ( 31, 15) + {128, { 0, 0, 0}}, // ( 32, 15) + {128, { 0, 0, 0}}, // ( 33, 15) + {128, { 0, 0, 0}}, // ( 34, 15) + {128, { 0, 0, 0}}, // ( 35, 15) + {128, { 0, 0, 0}}, // ( 36, 15) + {128, { 0, 0, 0}}, // ( 37, 15) + {128, { 0, 0, 0}}, // ( 38, 15) + {128, { 0, 0, 0}}, // ( 39, 15) + {128, { 0, 0, 0}}, // ( 40, 15) + {128, { 0, 0, 0}}, // ( 41, 15) + {114, { 0, 0, 0}}, // ( 42, 15) + { 39, { 0, 0, 0}}, // ( 43, 15) + { 0, { 0, 0, 0}}, // ( 44, 15) + { 0, { 0, 0, 0}}, // ( 45, 15) + { 0, { 0, 0, 0}}, // ( 46, 15) + { 0, { 0, 0, 0}}, // ( 47, 15) + { 0, { 0, 0, 0}}, // ( 48, 15) + { 0, { 0, 0, 0}}, // ( 49, 15) + { 0, { 0, 0, 0}}, // ( 50, 15) + { 0, { 0, 0, 0}}, // ( 51, 15) + { 0, { 0, 0, 0}}, // ( 52, 15) + { 0, { 0, 0, 0}}, // ( 53, 15) + { 0, { 0, 0, 0}}, // ( 54, 15) + { 0, { 0, 0, 0}}, // ( 55, 15) + { 0, { 0, 0, 0}}, // ( 56, 15) + { 0, { 0, 0, 0}}, // ( 57, 15) + { 0, { 0, 0, 0}}, // ( 58, 15) + { 0, { 0, 0, 0}}, // ( 59, 15) + { 0, { 0, 0, 0}}, // ( 60, 15) + { 0, { 0, 0, 0}}, // ( 61, 15) + { 0, { 0, 0, 0}}, // ( 62, 15) + { 0, { 0, 0, 0}}, // ( 63, 15) + { 0, { 0, 0, 0}}, // ( 64, 15) + { 0, { 0, 0, 0}}, // ( 65, 15) + { 0, { 0, 0, 0}}, // ( 66, 15) + { 0, { 0, 0, 0}}, // ( 67, 15) + { 0, { 0, 0, 0}}, // ( 68, 15) + { 0, { 0, 0, 0}}, // ( 69, 15) + { 0, { 0, 0, 0}}, // ( 70, 15) + { 0, { 0, 0, 0}}, // ( 71, 15) + { 0, { 0, 0, 0}}, // ( 72, 15) + { 0, { 0, 0, 0}}, // ( 73, 15) + { 0, { 0, 0, 0}}, // ( 74, 15) + { 0, { 0, 0, 0}}, // ( 75, 15) + { 0, { 0, 0, 0}}, // ( 76, 15) + { 0, { 0, 0, 0}}, // ( 77, 15) + { 0, { 0, 0, 0}}, // ( 78, 15) + { 0, { 0, 0, 0}}, // ( 79, 15) + { 0, { 0, 0, 0}}, // ( 80, 15) + { 0, { 0, 0, 0}}, // ( 81, 15) + { 0, { 0, 0, 0}}, // ( 82, 15) + { 0, { 0, 0, 0}}, // ( 83, 15) + { 0, { 0, 0, 0}}, // ( 84, 15) + { 0, { 0, 0, 0}}, // ( 85, 15) + { 0, { 0, 0, 0}}, // ( 86, 15) + { 0, { 0, 0, 0}}, // ( 87, 15) + { 0, { 0, 0, 0}}, // ( 88, 15) + { 0, { 0, 0, 0}}, // ( 89, 15) + { 0, { 0, 0, 0}}, // ( 90, 15) + { 0, { 0, 0, 0}}, // ( 91, 15) + { 0, { 0, 0, 0}}, // ( 92, 15) + { 0, { 0, 0, 0}}, // ( 93, 15) + { 0, { 0, 0, 0}}, // ( 94, 15) + { 0, { 0, 0, 0}}, // ( 95, 15) + { 0, { 0, 0, 0}}, // ( 96, 15) + { 0, { 0, 0, 0}}, // ( 97, 15) + { 0, { 0, 0, 0}}, // ( 98, 15) + { 0, { 0, 0, 0}}, // ( 99, 15) + { 0, { 0, 0, 0}}, // (100, 15) + { 0, { 0, 0, 0}}, // (101, 15) + { 0, { 0, 0, 0}}, // (102, 15) + { 0, { 0, 0, 0}}, // (103, 15) + { 0, { 0, 0, 0}}, // (104, 15) + { 0, { 0, 0, 0}}, // (105, 15) + { 0, { 0, 0, 0}}, // (106, 15) + { 0, { 0, 0, 0}}, // (107, 15) + { 0, { 0, 0, 0}}, // (108, 15) + { 0, { 0, 0, 0}}, // (109, 15) + { 0, { 0, 0, 0}}, // (110, 15) + { 0, { 0, 0, 0}}, // (111, 15) + { 0, { 0, 0, 0}}, // (112, 15) + { 0, { 0, 0, 0}}, // (113, 15) + { 0, { 0, 0, 0}}, // (114, 15) + { 0, { 0, 0, 0}}, // (115, 15) + { 0, { 0, 0, 0}}, // (116, 15) + { 0, { 0, 0, 0}}, // (117, 15) + { 0, { 0, 0, 0}}, // (118, 15) + { 0, { 0, 0, 0}}, // (119, 15) + { 0, { 0, 0, 0}}, // (120, 15) + { 0, { 0, 0, 0}}, // (121, 15) + { 0, { 0, 0, 0}}, // (122, 15) + { 0, { 0, 0, 0}}, // (123, 15) + { 0, { 0, 0, 0}}, // (124, 15) + { 0, { 0, 0, 0}}, // (125, 15) + { 0, { 0, 0, 0}}, // (126, 15) + { 0, { 0, 0, 0}}, // (127, 15) + { 0, { 0, 0, 0}}, // (128, 15) + { 0, { 0, 0, 0}}, // (129, 15) + { 0, { 0, 0, 0}}, // (130, 15) + { 0, { 0, 0, 0}}, // (131, 15) + { 0, { 0, 0, 0}}, // (132, 15) + { 0, { 0, 0, 0}}, // (133, 15) + { 0, { 0, 0, 0}}, // (134, 15) + { 0, { 0, 0, 0}}, // (135, 15) + { 38, { 0, 0, 0}}, // (136, 15) + {114, { 0, 0, 0}}, // (137, 15) + {128, { 0, 0, 0}}, // (138, 15) + {128, { 0, 0, 0}}, // (139, 15) + {128, { 0, 0, 0}}, // (140, 15) + {128, { 0, 0, 0}}, // (141, 15) + {128, { 0, 0, 0}}, // (142, 15) + {128, { 0, 0, 0}}, // (143, 15) + {128, { 0, 0, 0}}, // (144, 15) + {128, { 0, 0, 0}}, // (145, 15) + {128, { 0, 0, 0}}, // (146, 15) + {128, { 0, 0, 0}}, // (147, 15) + {128, { 0, 0, 0}}, // (148, 15) + {128, { 0, 0, 0}}, // (149, 15) + {128, { 0, 0, 0}}, // (150, 15) + {128, { 0, 0, 0}}, // (151, 15) + {128, { 0, 0, 0}}, // (152, 15) + {128, { 0, 0, 0}}, // (153, 15) + {128, { 0, 0, 0}}, // (154, 15) + {128, { 0, 0, 0}}, // (155, 15) + {128, { 0, 0, 0}}, // (156, 15) + {128, { 0, 0, 0}}, // (157, 15) + {128, { 0, 0, 0}}, // (158, 15) + {128, { 0, 0, 0}}, // (159, 15) + {128, { 0, 0, 0}}, // (160, 15) + {128, { 0, 0, 0}}, // (161, 15) + {128, { 0, 0, 0}}, // (162, 15) + {128, { 0, 0, 0}}, // (163, 15) + {128, { 0, 0, 0}}, // (164, 15) + {128, { 0, 0, 0}}, // (165, 15) + {128, { 0, 0, 0}}, // (166, 15) + {128, { 0, 0, 0}}, // (167, 15) + {128, { 0, 0, 0}}, // (168, 15) + {128, { 0, 0, 0}}, // (169, 15) + {128, { 0, 0, 0}}, // (170, 15) + {128, { 0, 0, 0}}, // (171, 15) + {128, { 0, 0, 0}}, // (172, 15) + {128, { 0, 0, 0}}, // (173, 15) + {128, { 0, 0, 0}}, // (174, 15) + {128, { 0, 0, 0}}, // (175, 15) + {128, { 0, 0, 0}}, // (176, 15) + {128, { 0, 0, 0}}, // (177, 15) + {128, { 0, 0, 0}}, // (178, 15) + {128, { 0, 0, 0}}, // (179, 15) + {128, { 0, 0, 0}}, // ( 0, 16) + {128, { 0, 0, 0}}, // ( 1, 16) + {128, { 0, 0, 0}}, // ( 2, 16) + {128, { 0, 0, 0}}, // ( 3, 16) + {128, { 0, 0, 0}}, // ( 4, 16) + {128, { 0, 0, 0}}, // ( 5, 16) + {128, { 0, 0, 0}}, // ( 6, 16) + {128, { 0, 0, 0}}, // ( 7, 16) + {128, { 0, 0, 0}}, // ( 8, 16) + {128, { 0, 0, 0}}, // ( 9, 16) + {128, { 0, 0, 0}}, // ( 10, 16) + {128, { 0, 0, 0}}, // ( 11, 16) + {128, { 0, 0, 0}}, // ( 12, 16) + {128, { 0, 0, 0}}, // ( 13, 16) + {128, { 0, 0, 0}}, // ( 14, 16) + {128, { 0, 0, 0}}, // ( 15, 16) + {128, { 0, 0, 0}}, // ( 16, 16) + {128, { 0, 0, 0}}, // ( 17, 16) + {128, { 0, 0, 0}}, // ( 18, 16) + {128, { 0, 0, 0}}, // ( 19, 16) + {128, { 0, 0, 0}}, // ( 20, 16) + {128, { 0, 0, 0}}, // ( 21, 16) + {128, { 0, 0, 0}}, // ( 22, 16) + {128, { 0, 0, 0}}, // ( 23, 16) + {128, { 0, 0, 0}}, // ( 24, 16) + {128, { 0, 0, 0}}, // ( 25, 16) + {128, { 0, 0, 0}}, // ( 26, 16) + {128, { 0, 0, 0}}, // ( 27, 16) + {128, { 0, 0, 0}}, // ( 28, 16) + {128, { 0, 0, 0}}, // ( 29, 16) + {128, { 0, 0, 0}}, // ( 30, 16) + {128, { 0, 0, 0}}, // ( 31, 16) + {128, { 0, 0, 0}}, // ( 32, 16) + {128, { 0, 0, 0}}, // ( 33, 16) + {128, { 0, 0, 0}}, // ( 34, 16) + {128, { 0, 0, 0}}, // ( 35, 16) + {128, { 0, 0, 0}}, // ( 36, 16) + {128, { 0, 0, 0}}, // ( 37, 16) + {128, { 0, 0, 0}}, // ( 38, 16) + {128, { 0, 0, 0}}, // ( 39, 16) + {127, { 0, 0, 0}}, // ( 40, 16) + { 74, { 0, 0, 0}}, // ( 41, 16) + { 7, { 0, 0, 0}}, // ( 42, 16) + { 0, { 0, 0, 0}}, // ( 43, 16) + { 0, { 0, 0, 0}}, // ( 44, 16) + { 0, { 0, 0, 0}}, // ( 45, 16) + { 0, { 0, 0, 0}}, // ( 46, 16) + { 0, { 0, 0, 0}}, // ( 47, 16) + { 0, { 0, 0, 0}}, // ( 48, 16) + { 0, { 0, 0, 0}}, // ( 49, 16) + { 0, { 0, 0, 0}}, // ( 50, 16) + { 0, { 0, 0, 0}}, // ( 51, 16) + { 0, { 0, 0, 0}}, // ( 52, 16) + { 0, { 0, 0, 0}}, // ( 53, 16) + { 0, { 0, 0, 0}}, // ( 54, 16) + { 0, { 0, 0, 0}}, // ( 55, 16) + { 0, { 0, 0, 0}}, // ( 56, 16) + { 0, { 0, 0, 0}}, // ( 57, 16) + { 0, { 0, 0, 0}}, // ( 58, 16) + { 0, { 0, 0, 0}}, // ( 59, 16) + { 0, { 0, 0, 0}}, // ( 60, 16) + { 0, { 0, 0, 0}}, // ( 61, 16) + { 0, { 0, 0, 0}}, // ( 62, 16) + { 0, { 0, 0, 0}}, // ( 63, 16) + { 0, { 0, 0, 0}}, // ( 64, 16) + { 0, { 0, 0, 0}}, // ( 65, 16) + { 0, { 0, 0, 0}}, // ( 66, 16) + { 0, { 0, 0, 0}}, // ( 67, 16) + { 0, { 0, 0, 0}}, // ( 68, 16) + { 0, { 0, 0, 0}}, // ( 69, 16) + { 0, { 0, 0, 0}}, // ( 70, 16) + { 0, { 0, 0, 0}}, // ( 71, 16) + { 0, { 0, 0, 0}}, // ( 72, 16) + { 0, { 0, 0, 0}}, // ( 73, 16) + { 0, { 0, 0, 0}}, // ( 74, 16) + { 0, { 0, 0, 0}}, // ( 75, 16) + { 0, { 0, 0, 0}}, // ( 76, 16) + { 0, { 0, 0, 0}}, // ( 77, 16) + { 0, { 0, 0, 0}}, // ( 78, 16) + { 0, { 0, 0, 0}}, // ( 79, 16) + { 0, { 0, 0, 0}}, // ( 80, 16) + { 0, { 0, 0, 0}}, // ( 81, 16) + { 0, { 0, 0, 0}}, // ( 82, 16) + { 0, { 0, 0, 0}}, // ( 83, 16) + { 0, { 0, 0, 0}}, // ( 84, 16) + { 0, { 0, 0, 0}}, // ( 85, 16) + { 0, { 0, 0, 0}}, // ( 86, 16) + { 0, { 0, 0, 0}}, // ( 87, 16) + { 0, { 0, 0, 0}}, // ( 88, 16) + { 0, { 0, 0, 0}}, // ( 89, 16) + { 0, { 0, 0, 0}}, // ( 90, 16) + { 0, { 0, 0, 0}}, // ( 91, 16) + { 0, { 0, 0, 0}}, // ( 92, 16) + { 0, { 0, 0, 0}}, // ( 93, 16) + { 0, { 0, 0, 0}}, // ( 94, 16) + { 0, { 0, 0, 0}}, // ( 95, 16) + { 0, { 0, 0, 0}}, // ( 96, 16) + { 0, { 0, 0, 0}}, // ( 97, 16) + { 0, { 0, 0, 0}}, // ( 98, 16) + { 0, { 0, 0, 0}}, // ( 99, 16) + { 0, { 0, 0, 0}}, // (100, 16) + { 0, { 0, 0, 0}}, // (101, 16) + { 0, { 0, 0, 0}}, // (102, 16) + { 0, { 0, 0, 0}}, // (103, 16) + { 0, { 0, 0, 0}}, // (104, 16) + { 0, { 0, 0, 0}}, // (105, 16) + { 0, { 0, 0, 0}}, // (106, 16) + { 0, { 0, 0, 0}}, // (107, 16) + { 0, { 0, 0, 0}}, // (108, 16) + { 0, { 0, 0, 0}}, // (109, 16) + { 0, { 0, 0, 0}}, // (110, 16) + { 0, { 0, 0, 0}}, // (111, 16) + { 0, { 0, 0, 0}}, // (112, 16) + { 0, { 0, 0, 0}}, // (113, 16) + { 0, { 0, 0, 0}}, // (114, 16) + { 0, { 0, 0, 0}}, // (115, 16) + { 0, { 0, 0, 0}}, // (116, 16) + { 0, { 0, 0, 0}}, // (117, 16) + { 0, { 0, 0, 0}}, // (118, 16) + { 0, { 0, 0, 0}}, // (119, 16) + { 0, { 0, 0, 0}}, // (120, 16) + { 0, { 0, 0, 0}}, // (121, 16) + { 0, { 0, 0, 0}}, // (122, 16) + { 0, { 0, 0, 0}}, // (123, 16) + { 0, { 0, 0, 0}}, // (124, 16) + { 0, { 0, 0, 0}}, // (125, 16) + { 0, { 0, 0, 0}}, // (126, 16) + { 0, { 0, 0, 0}}, // (127, 16) + { 0, { 0, 0, 0}}, // (128, 16) + { 0, { 0, 0, 0}}, // (129, 16) + { 0, { 0, 0, 0}}, // (130, 16) + { 0, { 0, 0, 0}}, // (131, 16) + { 0, { 0, 0, 0}}, // (132, 16) + { 0, { 0, 0, 0}}, // (133, 16) + { 0, { 0, 0, 0}}, // (134, 16) + { 0, { 0, 0, 0}}, // (135, 16) + { 0, { 0, 0, 0}}, // (136, 16) + { 7, { 0, 0, 0}}, // (137, 16) + { 74, { 0, 0, 0}}, // (138, 16) + {127, { 0, 0, 0}}, // (139, 16) + {128, { 0, 0, 0}}, // (140, 16) + {128, { 0, 0, 0}}, // (141, 16) + {128, { 0, 0, 0}}, // (142, 16) + {128, { 0, 0, 0}}, // (143, 16) + {128, { 0, 0, 0}}, // (144, 16) + {128, { 0, 0, 0}}, // (145, 16) + {128, { 0, 0, 0}}, // (146, 16) + {128, { 0, 0, 0}}, // (147, 16) + {128, { 0, 0, 0}}, // (148, 16) + {128, { 0, 0, 0}}, // (149, 16) + {128, { 0, 0, 0}}, // (150, 16) + {128, { 0, 0, 0}}, // (151, 16) + {128, { 0, 0, 0}}, // (152, 16) + {128, { 0, 0, 0}}, // (153, 16) + {128, { 0, 0, 0}}, // (154, 16) + {128, { 0, 0, 0}}, // (155, 16) + {128, { 0, 0, 0}}, // (156, 16) + {128, { 0, 0, 0}}, // (157, 16) + {128, { 0, 0, 0}}, // (158, 16) + {128, { 0, 0, 0}}, // (159, 16) + {128, { 0, 0, 0}}, // (160, 16) + {128, { 0, 0, 0}}, // (161, 16) + {128, { 0, 0, 0}}, // (162, 16) + {128, { 0, 0, 0}}, // (163, 16) + {128, { 0, 0, 0}}, // (164, 16) + {128, { 0, 0, 0}}, // (165, 16) + {128, { 0, 0, 0}}, // (166, 16) + {128, { 0, 0, 0}}, // (167, 16) + {128, { 0, 0, 0}}, // (168, 16) + {128, { 0, 0, 0}}, // (169, 16) + {128, { 0, 0, 0}}, // (170, 16) + {128, { 0, 0, 0}}, // (171, 16) + {128, { 0, 0, 0}}, // (172, 16) + {128, { 0, 0, 0}}, // (173, 16) + {128, { 0, 0, 0}}, // (174, 16) + {128, { 0, 0, 0}}, // (175, 16) + {128, { 0, 0, 0}}, // (176, 16) + {128, { 0, 0, 0}}, // (177, 16) + {128, { 0, 0, 0}}, // (178, 16) + {128, { 0, 0, 0}}, // (179, 16) + {128, { 0, 0, 0}}, // ( 0, 17) + {128, { 0, 0, 0}}, // ( 1, 17) + {128, { 0, 0, 0}}, // ( 2, 17) + {128, { 0, 0, 0}}, // ( 3, 17) + {128, { 0, 0, 0}}, // ( 4, 17) + {128, { 0, 0, 0}}, // ( 5, 17) + {128, { 0, 0, 0}}, // ( 6, 17) + {128, { 0, 0, 0}}, // ( 7, 17) + {128, { 0, 0, 0}}, // ( 8, 17) + {128, { 0, 0, 0}}, // ( 9, 17) + {128, { 0, 0, 0}}, // ( 10, 17) + {128, { 0, 0, 0}}, // ( 11, 17) + {128, { 0, 0, 0}}, // ( 12, 17) + {128, { 0, 0, 0}}, // ( 13, 17) + {128, { 0, 0, 0}}, // ( 14, 17) + {128, { 0, 0, 0}}, // ( 15, 17) + {128, { 0, 0, 0}}, // ( 16, 17) + {128, { 0, 0, 0}}, // ( 17, 17) + {128, { 0, 0, 0}}, // ( 18, 17) + {128, { 0, 0, 0}}, // ( 19, 17) + {128, { 0, 0, 0}}, // ( 20, 17) + {128, { 0, 0, 0}}, // ( 21, 17) + {128, { 0, 0, 0}}, // ( 22, 17) + {128, { 0, 0, 0}}, // ( 23, 17) + {128, { 0, 0, 0}}, // ( 24, 17) + {128, { 0, 0, 0}}, // ( 25, 17) + {128, { 0, 0, 0}}, // ( 26, 17) + {128, { 0, 0, 0}}, // ( 27, 17) + {128, { 0, 0, 0}}, // ( 28, 17) + {128, { 0, 0, 0}}, // ( 29, 17) + {128, { 0, 0, 0}}, // ( 30, 17) + {128, { 0, 0, 0}}, // ( 31, 17) + {128, { 0, 0, 0}}, // ( 32, 17) + {128, { 0, 0, 0}}, // ( 33, 17) + {128, { 0, 0, 0}}, // ( 34, 17) + {128, { 0, 0, 0}}, // ( 35, 17) + {128, { 0, 0, 0}}, // ( 36, 17) + {128, { 0, 0, 0}}, // ( 37, 17) + {128, { 0, 0, 0}}, // ( 38, 17) + {113, { 0, 0, 0}}, // ( 39, 17) + { 33, { 0, 0, 0}}, // ( 40, 17) + { 0, { 0, 0, 0}}, // ( 41, 17) + { 0, { 0, 0, 0}}, // ( 42, 17) + { 0, { 0, 0, 0}}, // ( 43, 17) + { 0, { 0, 0, 0}}, // ( 44, 17) + { 0, { 0, 0, 0}}, // ( 45, 17) + { 0, { 0, 0, 0}}, // ( 46, 17) + { 0, { 0, 0, 0}}, // ( 47, 17) + { 0, { 0, 0, 0}}, // ( 48, 17) + { 0, { 0, 0, 0}}, // ( 49, 17) + { 0, { 0, 0, 0}}, // ( 50, 17) + { 0, { 0, 0, 0}}, // ( 51, 17) + { 0, { 0, 0, 0}}, // ( 52, 17) + { 0, { 0, 0, 0}}, // ( 53, 17) + { 0, { 0, 0, 0}}, // ( 54, 17) + { 0, { 0, 0, 0}}, // ( 55, 17) + { 0, { 0, 0, 0}}, // ( 56, 17) + { 0, { 0, 0, 0}}, // ( 57, 17) + { 0, { 0, 0, 0}}, // ( 58, 17) + { 0, { 0, 0, 0}}, // ( 59, 17) + { 0, { 0, 0, 0}}, // ( 60, 17) + { 0, { 0, 0, 0}}, // ( 61, 17) + { 0, { 0, 0, 0}}, // ( 62, 17) + { 0, { 0, 0, 0}}, // ( 63, 17) + { 0, { 0, 0, 0}}, // ( 64, 17) + { 0, { 0, 0, 0}}, // ( 65, 17) + { 0, { 0, 0, 0}}, // ( 66, 17) + { 0, { 0, 0, 0}}, // ( 67, 17) + { 0, { 0, 0, 0}}, // ( 68, 17) + { 0, { 0, 0, 0}}, // ( 69, 17) + { 0, { 0, 0, 0}}, // ( 70, 17) + { 0, { 0, 0, 0}}, // ( 71, 17) + { 0, { 0, 0, 0}}, // ( 72, 17) + { 0, { 0, 0, 0}}, // ( 73, 17) + { 0, { 0, 0, 0}}, // ( 74, 17) + { 0, { 0, 0, 0}}, // ( 75, 17) + { 0, { 0, 0, 0}}, // ( 76, 17) + { 0, { 0, 0, 0}}, // ( 77, 17) + { 0, { 0, 0, 0}}, // ( 78, 17) + { 0, { 0, 0, 0}}, // ( 79, 17) + { 0, { 0, 0, 0}}, // ( 80, 17) + { 0, { 0, 0, 0}}, // ( 81, 17) + { 0, { 0, 0, 0}}, // ( 82, 17) + { 0, { 0, 0, 0}}, // ( 83, 17) + { 0, { 0, 0, 0}}, // ( 84, 17) + { 0, { 0, 0, 0}}, // ( 85, 17) + { 0, { 0, 0, 0}}, // ( 86, 17) + { 0, { 0, 0, 0}}, // ( 87, 17) + { 0, { 0, 0, 0}}, // ( 88, 17) + { 0, { 0, 0, 0}}, // ( 89, 17) + { 0, { 0, 0, 0}}, // ( 90, 17) + { 0, { 0, 0, 0}}, // ( 91, 17) + { 0, { 0, 0, 0}}, // ( 92, 17) + { 0, { 0, 0, 0}}, // ( 93, 17) + { 0, { 0, 0, 0}}, // ( 94, 17) + { 0, { 0, 0, 0}}, // ( 95, 17) + { 0, { 0, 0, 0}}, // ( 96, 17) + { 0, { 0, 0, 0}}, // ( 97, 17) + { 0, { 0, 0, 0}}, // ( 98, 17) + { 0, { 0, 0, 0}}, // ( 99, 17) + { 0, { 0, 0, 0}}, // (100, 17) + { 0, { 0, 0, 0}}, // (101, 17) + { 0, { 0, 0, 0}}, // (102, 17) + { 0, { 0, 0, 0}}, // (103, 17) + { 0, { 0, 0, 0}}, // (104, 17) + { 0, { 0, 0, 0}}, // (105, 17) + { 0, { 0, 0, 0}}, // (106, 17) + { 0, { 0, 0, 0}}, // (107, 17) + { 0, { 0, 0, 0}}, // (108, 17) + { 0, { 0, 0, 0}}, // (109, 17) + { 0, { 0, 0, 0}}, // (110, 17) + { 0, { 0, 0, 0}}, // (111, 17) + { 0, { 0, 0, 0}}, // (112, 17) + { 0, { 0, 0, 0}}, // (113, 17) + { 0, { 0, 0, 0}}, // (114, 17) + { 0, { 0, 0, 0}}, // (115, 17) + { 0, { 0, 0, 0}}, // (116, 17) + { 0, { 0, 0, 0}}, // (117, 17) + { 0, { 0, 0, 0}}, // (118, 17) + { 0, { 0, 0, 0}}, // (119, 17) + { 0, { 0, 0, 0}}, // (120, 17) + { 0, { 0, 0, 0}}, // (121, 17) + { 0, { 0, 0, 0}}, // (122, 17) + { 0, { 0, 0, 0}}, // (123, 17) + { 0, { 0, 0, 0}}, // (124, 17) + { 0, { 0, 0, 0}}, // (125, 17) + { 0, { 0, 0, 0}}, // (126, 17) + { 0, { 0, 0, 0}}, // (127, 17) + { 0, { 0, 0, 0}}, // (128, 17) + { 0, { 0, 0, 0}}, // (129, 17) + { 0, { 0, 0, 0}}, // (130, 17) + { 0, { 0, 0, 0}}, // (131, 17) + { 0, { 0, 0, 0}}, // (132, 17) + { 0, { 0, 0, 0}}, // (133, 17) + { 0, { 0, 0, 0}}, // (134, 17) + { 0, { 0, 0, 0}}, // (135, 17) + { 0, { 0, 0, 0}}, // (136, 17) + { 0, { 0, 0, 0}}, // (137, 17) + { 0, { 0, 0, 0}}, // (138, 17) + { 33, { 0, 0, 0}}, // (139, 17) + {113, { 0, 0, 0}}, // (140, 17) + {128, { 0, 0, 0}}, // (141, 17) + {128, { 0, 0, 0}}, // (142, 17) + {128, { 0, 0, 0}}, // (143, 17) + {128, { 0, 0, 0}}, // (144, 17) + {128, { 0, 0, 0}}, // (145, 17) + {128, { 0, 0, 0}}, // (146, 17) + {128, { 0, 0, 0}}, // (147, 17) + {128, { 0, 0, 0}}, // (148, 17) + {128, { 0, 0, 0}}, // (149, 17) + {128, { 0, 0, 0}}, // (150, 17) + {128, { 0, 0, 0}}, // (151, 17) + {128, { 0, 0, 0}}, // (152, 17) + {128, { 0, 0, 0}}, // (153, 17) + {128, { 0, 0, 0}}, // (154, 17) + {128, { 0, 0, 0}}, // (155, 17) + {128, { 0, 0, 0}}, // (156, 17) + {128, { 0, 0, 0}}, // (157, 17) + {128, { 0, 0, 0}}, // (158, 17) + {128, { 0, 0, 0}}, // (159, 17) + {128, { 0, 0, 0}}, // (160, 17) + {128, { 0, 0, 0}}, // (161, 17) + {128, { 0, 0, 0}}, // (162, 17) + {128, { 0, 0, 0}}, // (163, 17) + {128, { 0, 0, 0}}, // (164, 17) + {128, { 0, 0, 0}}, // (165, 17) + {128, { 0, 0, 0}}, // (166, 17) + {128, { 0, 0, 0}}, // (167, 17) + {128, { 0, 0, 0}}, // (168, 17) + {128, { 0, 0, 0}}, // (169, 17) + {128, { 0, 0, 0}}, // (170, 17) + {128, { 0, 0, 0}}, // (171, 17) + {128, { 0, 0, 0}}, // (172, 17) + {128, { 0, 0, 0}}, // (173, 17) + {128, { 0, 0, 0}}, // (174, 17) + {128, { 0, 0, 0}}, // (175, 17) + {128, { 0, 0, 0}}, // (176, 17) + {128, { 0, 0, 0}}, // (177, 17) + {128, { 0, 0, 0}}, // (178, 17) + {128, { 0, 0, 0}}, // (179, 17) + {128, { 0, 0, 0}}, // ( 0, 18) + {128, { 0, 0, 0}}, // ( 1, 18) + {128, { 0, 0, 0}}, // ( 2, 18) + {128, { 0, 0, 0}}, // ( 3, 18) + {128, { 0, 0, 0}}, // ( 4, 18) + {128, { 0, 0, 0}}, // ( 5, 18) + {128, { 0, 0, 0}}, // ( 6, 18) + {128, { 0, 0, 0}}, // ( 7, 18) + {128, { 0, 0, 0}}, // ( 8, 18) + {128, { 0, 0, 0}}, // ( 9, 18) + {128, { 0, 0, 0}}, // ( 10, 18) + {128, { 0, 0, 0}}, // ( 11, 18) + {128, { 0, 0, 0}}, // ( 12, 18) + {128, { 0, 0, 0}}, // ( 13, 18) + {128, { 0, 0, 0}}, // ( 14, 18) + {128, { 0, 0, 0}}, // ( 15, 18) + {128, { 0, 0, 0}}, // ( 16, 18) + {128, { 0, 0, 0}}, // ( 17, 18) + {128, { 0, 0, 0}}, // ( 18, 18) + {128, { 0, 0, 0}}, // ( 19, 18) + {128, { 0, 0, 0}}, // ( 20, 18) + {128, { 0, 0, 0}}, // ( 21, 18) + {128, { 0, 0, 0}}, // ( 22, 18) + {128, { 0, 0, 0}}, // ( 23, 18) + {128, { 0, 0, 0}}, // ( 24, 18) + {128, { 0, 0, 0}}, // ( 25, 18) + {128, { 0, 0, 0}}, // ( 26, 18) + {128, { 0, 0, 0}}, // ( 27, 18) + {128, { 0, 0, 0}}, // ( 28, 18) + {128, { 0, 0, 0}}, // ( 29, 18) + {128, { 0, 0, 0}}, // ( 30, 18) + {128, { 0, 0, 0}}, // ( 31, 18) + {128, { 0, 0, 0}}, // ( 32, 18) + {128, { 0, 0, 0}}, // ( 33, 18) + {128, { 0, 0, 0}}, // ( 34, 18) + {128, { 0, 0, 0}}, // ( 35, 18) + {128, { 0, 0, 0}}, // ( 36, 18) + {128, { 0, 0, 0}}, // ( 37, 18) + { 85, { 0, 0, 0}}, // ( 38, 18) + { 9, { 0, 0, 0}}, // ( 39, 18) + { 0, { 0, 0, 0}}, // ( 40, 18) + { 0, { 0, 0, 0}}, // ( 41, 18) + { 0, { 0, 0, 0}}, // ( 42, 18) + { 0, { 0, 0, 0}}, // ( 43, 18) + { 0, { 0, 0, 0}}, // ( 44, 18) + { 0, { 0, 0, 0}}, // ( 45, 18) + { 0, { 0, 0, 0}}, // ( 46, 18) + { 0, { 0, 0, 0}}, // ( 47, 18) + { 0, { 0, 0, 0}}, // ( 48, 18) + { 0, { 0, 0, 0}}, // ( 49, 18) + { 0, { 0, 0, 0}}, // ( 50, 18) + { 0, { 0, 0, 0}}, // ( 51, 18) + { 0, { 0, 0, 0}}, // ( 52, 18) + { 0, { 0, 0, 0}}, // ( 53, 18) + { 0, { 0, 0, 0}}, // ( 54, 18) + { 0, { 0, 0, 0}}, // ( 55, 18) + { 0, { 0, 0, 0}}, // ( 56, 18) + { 0, { 0, 0, 0}}, // ( 57, 18) + { 0, { 0, 0, 0}}, // ( 58, 18) + { 0, { 0, 0, 0}}, // ( 59, 18) + { 0, { 0, 0, 0}}, // ( 60, 18) + { 0, { 0, 0, 0}}, // ( 61, 18) + { 0, { 0, 0, 0}}, // ( 62, 18) + { 0, { 0, 0, 0}}, // ( 63, 18) + { 0, { 0, 0, 0}}, // ( 64, 18) + { 0, { 0, 0, 0}}, // ( 65, 18) + { 0, { 0, 0, 0}}, // ( 66, 18) + { 0, { 0, 0, 0}}, // ( 67, 18) + { 0, { 0, 0, 0}}, // ( 68, 18) + { 0, { 0, 0, 0}}, // ( 69, 18) + { 0, { 0, 0, 0}}, // ( 70, 18) + { 0, { 0, 0, 0}}, // ( 71, 18) + { 0, { 0, 0, 0}}, // ( 72, 18) + { 0, { 0, 0, 0}}, // ( 73, 18) + { 0, { 0, 0, 0}}, // ( 74, 18) + { 0, { 0, 0, 0}}, // ( 75, 18) + { 0, { 0, 0, 0}}, // ( 76, 18) + { 0, { 0, 0, 0}}, // ( 77, 18) + { 0, { 0, 0, 0}}, // ( 78, 18) + { 0, { 0, 0, 0}}, // ( 79, 18) + { 0, { 0, 0, 0}}, // ( 80, 18) + { 0, { 0, 0, 0}}, // ( 81, 18) + { 0, { 0, 0, 0}}, // ( 82, 18) + { 0, { 0, 0, 0}}, // ( 83, 18) + { 0, { 0, 0, 0}}, // ( 84, 18) + { 0, { 0, 0, 0}}, // ( 85, 18) + { 0, { 0, 0, 0}}, // ( 86, 18) + { 0, { 0, 0, 0}}, // ( 87, 18) + { 0, { 0, 0, 0}}, // ( 88, 18) + { 0, { 0, 0, 0}}, // ( 89, 18) + { 0, { 0, 0, 0}}, // ( 90, 18) + { 0, { 0, 0, 0}}, // ( 91, 18) + { 0, { 0, 0, 0}}, // ( 92, 18) + { 0, { 0, 0, 0}}, // ( 93, 18) + { 0, { 0, 0, 0}}, // ( 94, 18) + { 0, { 0, 0, 0}}, // ( 95, 18) + { 0, { 0, 0, 0}}, // ( 96, 18) + { 0, { 0, 0, 0}}, // ( 97, 18) + { 0, { 0, 0, 0}}, // ( 98, 18) + { 0, { 0, 0, 0}}, // ( 99, 18) + { 0, { 0, 0, 0}}, // (100, 18) + { 0, { 0, 0, 0}}, // (101, 18) + { 0, { 0, 0, 0}}, // (102, 18) + { 0, { 0, 0, 0}}, // (103, 18) + { 0, { 0, 0, 0}}, // (104, 18) + { 0, { 0, 0, 0}}, // (105, 18) + { 0, { 0, 0, 0}}, // (106, 18) + { 0, { 0, 0, 0}}, // (107, 18) + { 0, { 0, 0, 0}}, // (108, 18) + { 0, { 0, 0, 0}}, // (109, 18) + { 0, { 0, 0, 0}}, // (110, 18) + { 0, { 0, 0, 0}}, // (111, 18) + { 0, { 0, 0, 0}}, // (112, 18) + { 0, { 0, 0, 0}}, // (113, 18) + { 0, { 0, 0, 0}}, // (114, 18) + { 0, { 0, 0, 0}}, // (115, 18) + { 0, { 0, 0, 0}}, // (116, 18) + { 0, { 0, 0, 0}}, // (117, 18) + { 0, { 0, 0, 0}}, // (118, 18) + { 0, { 0, 0, 0}}, // (119, 18) + { 0, { 0, 0, 0}}, // (120, 18) + { 0, { 0, 0, 0}}, // (121, 18) + { 0, { 0, 0, 0}}, // (122, 18) + { 0, { 0, 0, 0}}, // (123, 18) + { 0, { 0, 0, 0}}, // (124, 18) + { 0, { 0, 0, 0}}, // (125, 18) + { 0, { 0, 0, 0}}, // (126, 18) + { 0, { 0, 0, 0}}, // (127, 18) + { 0, { 0, 0, 0}}, // (128, 18) + { 0, { 0, 0, 0}}, // (129, 18) + { 0, { 0, 0, 0}}, // (130, 18) + { 0, { 0, 0, 0}}, // (131, 18) + { 0, { 0, 0, 0}}, // (132, 18) + { 0, { 0, 0, 0}}, // (133, 18) + { 0, { 0, 0, 0}}, // (134, 18) + { 0, { 0, 0, 0}}, // (135, 18) + { 0, { 0, 0, 0}}, // (136, 18) + { 0, { 0, 0, 0}}, // (137, 18) + { 0, { 0, 0, 0}}, // (138, 18) + { 0, { 0, 0, 0}}, // (139, 18) + { 9, { 0, 0, 0}}, // (140, 18) + { 85, { 0, 0, 0}}, // (141, 18) + {128, { 0, 0, 0}}, // (142, 18) + {128, { 0, 0, 0}}, // (143, 18) + {128, { 0, 0, 0}}, // (144, 18) + {128, { 0, 0, 0}}, // (145, 18) + {128, { 0, 0, 0}}, // (146, 18) + {128, { 0, 0, 0}}, // (147, 18) + {128, { 0, 0, 0}}, // (148, 18) + {128, { 0, 0, 0}}, // (149, 18) + {128, { 0, 0, 0}}, // (150, 18) + {128, { 0, 0, 0}}, // (151, 18) + {128, { 0, 0, 0}}, // (152, 18) + {128, { 0, 0, 0}}, // (153, 18) + {128, { 0, 0, 0}}, // (154, 18) + {128, { 0, 0, 0}}, // (155, 18) + {128, { 0, 0, 0}}, // (156, 18) + {128, { 0, 0, 0}}, // (157, 18) + {128, { 0, 0, 0}}, // (158, 18) + {128, { 0, 0, 0}}, // (159, 18) + {128, { 0, 0, 0}}, // (160, 18) + {128, { 0, 0, 0}}, // (161, 18) + {128, { 0, 0, 0}}, // (162, 18) + {128, { 0, 0, 0}}, // (163, 18) + {128, { 0, 0, 0}}, // (164, 18) + {128, { 0, 0, 0}}, // (165, 18) + {128, { 0, 0, 0}}, // (166, 18) + {128, { 0, 0, 0}}, // (167, 18) + {128, { 0, 0, 0}}, // (168, 18) + {128, { 0, 0, 0}}, // (169, 18) + {128, { 0, 0, 0}}, // (170, 18) + {128, { 0, 0, 0}}, // (171, 18) + {128, { 0, 0, 0}}, // (172, 18) + {128, { 0, 0, 0}}, // (173, 18) + {128, { 0, 0, 0}}, // (174, 18) + {128, { 0, 0, 0}}, // (175, 18) + {128, { 0, 0, 0}}, // (176, 18) + {128, { 0, 0, 0}}, // (177, 18) + {128, { 0, 0, 0}}, // (178, 18) + {128, { 0, 0, 0}}, // (179, 18) + {128, { 0, 0, 0}}, // ( 0, 19) + {128, { 0, 0, 0}}, // ( 1, 19) + {128, { 0, 0, 0}}, // ( 2, 19) + {128, { 0, 0, 0}}, // ( 3, 19) + {128, { 0, 0, 0}}, // ( 4, 19) + {128, { 0, 0, 0}}, // ( 5, 19) + {128, { 0, 0, 0}}, // ( 6, 19) + {128, { 0, 0, 0}}, // ( 7, 19) + {128, { 0, 0, 0}}, // ( 8, 19) + {128, { 0, 0, 0}}, // ( 9, 19) + {128, { 0, 0, 0}}, // ( 10, 19) + {128, { 0, 0, 0}}, // ( 11, 19) + {128, { 0, 0, 0}}, // ( 12, 19) + {128, { 0, 0, 0}}, // ( 13, 19) + {128, { 0, 0, 0}}, // ( 14, 19) + {128, { 0, 0, 0}}, // ( 15, 19) + {128, { 0, 0, 0}}, // ( 16, 19) + {128, { 0, 0, 0}}, // ( 17, 19) + {128, { 0, 0, 0}}, // ( 18, 19) + {128, { 0, 0, 0}}, // ( 19, 19) + {128, { 0, 0, 0}}, // ( 20, 19) + {128, { 0, 0, 0}}, // ( 21, 19) + {128, { 0, 0, 0}}, // ( 22, 19) + {128, { 0, 0, 0}}, // ( 23, 19) + {128, { 0, 0, 0}}, // ( 24, 19) + {128, { 0, 0, 0}}, // ( 25, 19) + {128, { 0, 0, 0}}, // ( 26, 19) + {128, { 0, 0, 0}}, // ( 27, 19) + {128, { 0, 0, 0}}, // ( 28, 19) + {128, { 0, 0, 0}}, // ( 29, 19) + {128, { 0, 0, 0}}, // ( 30, 19) + {128, { 0, 0, 0}}, // ( 31, 19) + {128, { 0, 0, 0}}, // ( 32, 19) + {128, { 0, 0, 0}}, // ( 33, 19) + {128, { 0, 0, 0}}, // ( 34, 19) + {128, { 0, 0, 0}}, // ( 35, 19) + {123, { 0, 0, 0}}, // ( 36, 19) + { 49, { 0, 0, 0}}, // ( 37, 19) + { 0, { 0, 0, 0}}, // ( 38, 19) + { 0, { 0, 0, 0}}, // ( 39, 19) + { 0, { 0, 0, 0}}, // ( 40, 19) + { 0, { 0, 0, 0}}, // ( 41, 19) + { 0, { 0, 0, 0}}, // ( 42, 19) + { 0, { 0, 0, 0}}, // ( 43, 19) + { 0, { 0, 0, 0}}, // ( 44, 19) + { 0, { 0, 0, 0}}, // ( 45, 19) + { 0, { 0, 0, 0}}, // ( 46, 19) + { 0, { 0, 0, 0}}, // ( 47, 19) + { 0, { 0, 0, 0}}, // ( 48, 19) + { 0, { 0, 0, 0}}, // ( 49, 19) + { 0, { 0, 0, 0}}, // ( 50, 19) + { 0, { 0, 0, 0}}, // ( 51, 19) + { 0, { 0, 0, 0}}, // ( 52, 19) + { 0, { 0, 0, 0}}, // ( 53, 19) + { 0, { 0, 0, 0}}, // ( 54, 19) + { 0, { 0, 0, 0}}, // ( 55, 19) + { 0, { 0, 0, 0}}, // ( 56, 19) + { 0, { 0, 0, 0}}, // ( 57, 19) + { 0, { 0, 0, 0}}, // ( 58, 19) + { 0, { 0, 0, 0}}, // ( 59, 19) + { 0, { 0, 0, 0}}, // ( 60, 19) + { 0, { 0, 0, 0}}, // ( 61, 19) + { 0, { 0, 0, 0}}, // ( 62, 19) + { 0, { 0, 0, 0}}, // ( 63, 19) + { 0, { 0, 0, 0}}, // ( 64, 19) + { 0, { 0, 0, 0}}, // ( 65, 19) + { 0, { 0, 0, 0}}, // ( 66, 19) + { 0, { 0, 0, 0}}, // ( 67, 19) + { 0, { 0, 0, 0}}, // ( 68, 19) + { 0, { 0, 0, 0}}, // ( 69, 19) + { 0, { 0, 0, 0}}, // ( 70, 19) + { 0, { 0, 0, 0}}, // ( 71, 19) + { 0, { 0, 0, 0}}, // ( 72, 19) + { 0, { 0, 0, 0}}, // ( 73, 19) + { 0, { 0, 0, 0}}, // ( 74, 19) + { 0, { 0, 0, 0}}, // ( 75, 19) + { 0, { 0, 0, 0}}, // ( 76, 19) + { 0, { 0, 0, 0}}, // ( 77, 19) + { 0, { 0, 0, 0}}, // ( 78, 19) + { 0, { 0, 0, 0}}, // ( 79, 19) + { 0, { 0, 0, 0}}, // ( 80, 19) + { 0, { 0, 0, 0}}, // ( 81, 19) + { 0, { 0, 0, 0}}, // ( 82, 19) + { 0, { 0, 0, 0}}, // ( 83, 19) + { 0, { 0, 0, 0}}, // ( 84, 19) + { 0, { 0, 0, 0}}, // ( 85, 19) + { 0, { 0, 0, 0}}, // ( 86, 19) + { 0, { 0, 0, 0}}, // ( 87, 19) + { 0, { 0, 0, 0}}, // ( 88, 19) + { 0, { 0, 0, 0}}, // ( 89, 19) + { 0, { 0, 0, 0}}, // ( 90, 19) + { 0, { 0, 0, 0}}, // ( 91, 19) + { 0, { 0, 0, 0}}, // ( 92, 19) + { 0, { 0, 0, 0}}, // ( 93, 19) + { 0, { 0, 0, 0}}, // ( 94, 19) + { 0, { 0, 0, 0}}, // ( 95, 19) + { 0, { 0, 0, 0}}, // ( 96, 19) + { 0, { 0, 0, 0}}, // ( 97, 19) + { 0, { 0, 0, 0}}, // ( 98, 19) + { 0, { 0, 0, 0}}, // ( 99, 19) + { 0, { 0, 0, 0}}, // (100, 19) + { 0, { 0, 0, 0}}, // (101, 19) + { 0, { 0, 0, 0}}, // (102, 19) + { 0, { 0, 0, 0}}, // (103, 19) + { 0, { 0, 0, 0}}, // (104, 19) + { 0, { 0, 0, 0}}, // (105, 19) + { 0, { 0, 0, 0}}, // (106, 19) + { 0, { 0, 0, 0}}, // (107, 19) + { 0, { 0, 0, 0}}, // (108, 19) + { 0, { 0, 0, 0}}, // (109, 19) + { 0, { 0, 0, 0}}, // (110, 19) + { 0, { 0, 0, 0}}, // (111, 19) + { 0, { 0, 0, 0}}, // (112, 19) + { 0, { 0, 0, 0}}, // (113, 19) + { 0, { 0, 0, 0}}, // (114, 19) + { 0, { 0, 0, 0}}, // (115, 19) + { 0, { 0, 0, 0}}, // (116, 19) + { 0, { 0, 0, 0}}, // (117, 19) + { 0, { 0, 0, 0}}, // (118, 19) + { 0, { 0, 0, 0}}, // (119, 19) + { 0, { 0, 0, 0}}, // (120, 19) + { 0, { 0, 0, 0}}, // (121, 19) + { 0, { 0, 0, 0}}, // (122, 19) + { 0, { 0, 0, 0}}, // (123, 19) + { 0, { 0, 0, 0}}, // (124, 19) + { 0, { 0, 0, 0}}, // (125, 19) + { 0, { 0, 0, 0}}, // (126, 19) + { 0, { 0, 0, 0}}, // (127, 19) + { 0, { 0, 0, 0}}, // (128, 19) + { 0, { 0, 0, 0}}, // (129, 19) + { 0, { 0, 0, 0}}, // (130, 19) + { 0, { 0, 0, 0}}, // (131, 19) + { 0, { 0, 0, 0}}, // (132, 19) + { 0, { 0, 0, 0}}, // (133, 19) + { 0, { 0, 0, 0}}, // (134, 19) + { 0, { 0, 0, 0}}, // (135, 19) + { 0, { 0, 0, 0}}, // (136, 19) + { 0, { 0, 0, 0}}, // (137, 19) + { 0, { 0, 0, 0}}, // (138, 19) + { 0, { 0, 0, 0}}, // (139, 19) + { 0, { 0, 0, 0}}, // (140, 19) + { 0, { 0, 0, 0}}, // (141, 19) + { 49, { 0, 0, 0}}, // (142, 19) + {123, { 0, 0, 0}}, // (143, 19) + {128, { 0, 0, 0}}, // (144, 19) + {128, { 0, 0, 0}}, // (145, 19) + {128, { 0, 0, 0}}, // (146, 19) + {128, { 0, 0, 0}}, // (147, 19) + {128, { 0, 0, 0}}, // (148, 19) + {128, { 0, 0, 0}}, // (149, 19) + {128, { 0, 0, 0}}, // (150, 19) + {128, { 0, 0, 0}}, // (151, 19) + {128, { 0, 0, 0}}, // (152, 19) + {128, { 0, 0, 0}}, // (153, 19) + {128, { 0, 0, 0}}, // (154, 19) + {128, { 0, 0, 0}}, // (155, 19) + {128, { 0, 0, 0}}, // (156, 19) + {128, { 0, 0, 0}}, // (157, 19) + {128, { 0, 0, 0}}, // (158, 19) + {128, { 0, 0, 0}}, // (159, 19) + {128, { 0, 0, 0}}, // (160, 19) + {128, { 0, 0, 0}}, // (161, 19) + {128, { 0, 0, 0}}, // (162, 19) + {128, { 0, 0, 0}}, // (163, 19) + {128, { 0, 0, 0}}, // (164, 19) + {128, { 0, 0, 0}}, // (165, 19) + {128, { 0, 0, 0}}, // (166, 19) + {128, { 0, 0, 0}}, // (167, 19) + {128, { 0, 0, 0}}, // (168, 19) + {128, { 0, 0, 0}}, // (169, 19) + {128, { 0, 0, 0}}, // (170, 19) + {128, { 0, 0, 0}}, // (171, 19) + {128, { 0, 0, 0}}, // (172, 19) + {128, { 0, 0, 0}}, // (173, 19) + {128, { 0, 0, 0}}, // (174, 19) + {128, { 0, 0, 0}}, // (175, 19) + {128, { 0, 0, 0}}, // (176, 19) + {128, { 0, 0, 0}}, // (177, 19) + {128, { 0, 0, 0}}, // (178, 19) + {128, { 0, 0, 0}}, // (179, 19) + {128, { 0, 0, 0}}, // ( 0, 20) + {128, { 0, 0, 0}}, // ( 1, 20) + {128, { 0, 0, 0}}, // ( 2, 20) + {128, { 0, 0, 0}}, // ( 3, 20) + {128, { 0, 0, 0}}, // ( 4, 20) + {128, { 0, 0, 0}}, // ( 5, 20) + {128, { 0, 0, 0}}, // ( 6, 20) + {128, { 0, 0, 0}}, // ( 7, 20) + {128, { 0, 0, 0}}, // ( 8, 20) + {128, { 0, 0, 0}}, // ( 9, 20) + {128, { 0, 0, 0}}, // ( 10, 20) + {128, { 0, 0, 0}}, // ( 11, 20) + {128, { 0, 0, 0}}, // ( 12, 20) + {128, { 0, 0, 0}}, // ( 13, 20) + {128, { 0, 0, 0}}, // ( 14, 20) + {128, { 0, 0, 0}}, // ( 15, 20) + {128, { 0, 0, 0}}, // ( 16, 20) + {128, { 0, 0, 0}}, // ( 17, 20) + {128, { 0, 0, 0}}, // ( 18, 20) + {128, { 0, 0, 0}}, // ( 19, 20) + {128, { 0, 0, 0}}, // ( 20, 20) + {128, { 0, 0, 0}}, // ( 21, 20) + {128, { 0, 0, 0}}, // ( 22, 20) + {128, { 0, 0, 0}}, // ( 23, 20) + {128, { 0, 0, 0}}, // ( 24, 20) + {128, { 0, 0, 0}}, // ( 25, 20) + {128, { 0, 0, 0}}, // ( 26, 20) + {128, { 0, 0, 0}}, // ( 27, 20) + {128, { 0, 0, 0}}, // ( 28, 20) + {128, { 0, 0, 0}}, // ( 29, 20) + {128, { 0, 0, 0}}, // ( 30, 20) + {128, { 0, 0, 0}}, // ( 31, 20) + {128, { 0, 0, 0}}, // ( 32, 20) + {128, { 0, 0, 0}}, // ( 33, 20) + {128, { 0, 0, 0}}, // ( 34, 20) + {111, { 0, 0, 0}}, // ( 35, 20) + { 24, { 0, 0, 0}}, // ( 36, 20) + { 0, { 0, 0, 0}}, // ( 37, 20) + { 0, { 0, 0, 0}}, // ( 38, 20) + { 0, { 0, 0, 0}}, // ( 39, 20) + { 0, { 0, 0, 0}}, // ( 40, 20) + { 0, { 0, 0, 0}}, // ( 41, 20) + { 0, { 0, 0, 0}}, // ( 42, 20) + { 0, { 0, 0, 0}}, // ( 43, 20) + { 0, { 0, 0, 0}}, // ( 44, 20) + { 0, { 0, 0, 0}}, // ( 45, 20) + { 0, { 0, 0, 0}}, // ( 46, 20) + { 0, { 0, 0, 0}}, // ( 47, 20) + { 0, { 0, 0, 0}}, // ( 48, 20) + { 0, { 0, 0, 0}}, // ( 49, 20) + { 0, { 0, 0, 0}}, // ( 50, 20) + { 0, { 0, 0, 0}}, // ( 51, 20) + { 0, { 0, 0, 0}}, // ( 52, 20) + { 0, { 0, 0, 0}}, // ( 53, 20) + { 0, { 0, 0, 0}}, // ( 54, 20) + { 0, { 0, 0, 0}}, // ( 55, 20) + { 0, { 0, 0, 0}}, // ( 56, 20) + { 0, { 0, 0, 0}}, // ( 57, 20) + { 0, { 0, 0, 0}}, // ( 58, 20) + { 0, { 0, 0, 0}}, // ( 59, 20) + { 0, { 0, 0, 0}}, // ( 60, 20) + { 0, { 0, 0, 0}}, // ( 61, 20) + { 0, { 0, 0, 0}}, // ( 62, 20) + { 0, { 0, 0, 0}}, // ( 63, 20) + { 0, { 0, 0, 0}}, // ( 64, 20) + { 0, { 0, 0, 0}}, // ( 65, 20) + { 0, { 0, 0, 0}}, // ( 66, 20) + { 0, { 0, 0, 0}}, // ( 67, 20) + { 0, { 0, 0, 0}}, // ( 68, 20) + { 0, { 0, 0, 0}}, // ( 69, 20) + { 0, { 0, 0, 0}}, // ( 70, 20) + { 0, { 0, 0, 0}}, // ( 71, 20) + { 0, { 0, 0, 0}}, // ( 72, 20) + { 0, { 0, 0, 0}}, // ( 73, 20) + { 0, { 0, 0, 0}}, // ( 74, 20) + { 0, { 0, 0, 0}}, // ( 75, 20) + { 0, { 0, 0, 0}}, // ( 76, 20) + { 0, { 0, 0, 0}}, // ( 77, 20) + { 0, { 0, 0, 0}}, // ( 78, 20) + { 0, { 0, 0, 0}}, // ( 79, 20) + { 0, { 0, 0, 0}}, // ( 80, 20) + { 0, { 0, 0, 0}}, // ( 81, 20) + { 0, { 0, 0, 0}}, // ( 82, 20) + { 0, { 0, 0, 0}}, // ( 83, 20) + { 0, { 0, 0, 0}}, // ( 84, 20) + { 0, { 0, 0, 0}}, // ( 85, 20) + { 0, { 0, 0, 0}}, // ( 86, 20) + { 0, { 0, 0, 0}}, // ( 87, 20) + { 0, { 0, 0, 0}}, // ( 88, 20) + { 0, { 0, 0, 0}}, // ( 89, 20) + { 0, { 0, 0, 0}}, // ( 90, 20) + { 0, { 0, 0, 0}}, // ( 91, 20) + { 0, { 0, 0, 0}}, // ( 92, 20) + { 0, { 0, 0, 0}}, // ( 93, 20) + { 0, { 0, 0, 0}}, // ( 94, 20) + { 0, { 0, 0, 0}}, // ( 95, 20) + { 0, { 0, 0, 0}}, // ( 96, 20) + { 0, { 0, 0, 0}}, // ( 97, 20) + { 0, { 0, 0, 0}}, // ( 98, 20) + { 0, { 0, 0, 0}}, // ( 99, 20) + { 0, { 0, 0, 0}}, // (100, 20) + { 0, { 0, 0, 0}}, // (101, 20) + { 0, { 0, 0, 0}}, // (102, 20) + { 0, { 0, 0, 0}}, // (103, 20) + { 0, { 0, 0, 0}}, // (104, 20) + { 0, { 0, 0, 0}}, // (105, 20) + { 0, { 0, 0, 0}}, // (106, 20) + { 0, { 0, 0, 0}}, // (107, 20) + { 0, { 0, 0, 0}}, // (108, 20) + { 0, { 0, 0, 0}}, // (109, 20) + { 0, { 0, 0, 0}}, // (110, 20) + { 0, { 0, 0, 0}}, // (111, 20) + { 0, { 0, 0, 0}}, // (112, 20) + { 0, { 0, 0, 0}}, // (113, 20) + { 0, { 0, 0, 0}}, // (114, 20) + { 0, { 0, 0, 0}}, // (115, 20) + { 0, { 0, 0, 0}}, // (116, 20) + { 0, { 0, 0, 0}}, // (117, 20) + { 0, { 0, 0, 0}}, // (118, 20) + { 0, { 0, 0, 0}}, // (119, 20) + { 0, { 0, 0, 0}}, // (120, 20) + { 0, { 0, 0, 0}}, // (121, 20) + { 0, { 0, 0, 0}}, // (122, 20) + { 0, { 0, 0, 0}}, // (123, 20) + { 0, { 0, 0, 0}}, // (124, 20) + { 0, { 0, 0, 0}}, // (125, 20) + { 0, { 0, 0, 0}}, // (126, 20) + { 0, { 0, 0, 0}}, // (127, 20) + { 0, { 0, 0, 0}}, // (128, 20) + { 0, { 0, 0, 0}}, // (129, 20) + { 0, { 0, 0, 0}}, // (130, 20) + { 0, { 0, 0, 0}}, // (131, 20) + { 0, { 0, 0, 0}}, // (132, 20) + { 0, { 0, 0, 0}}, // (133, 20) + { 0, { 0, 0, 0}}, // (134, 20) + { 0, { 0, 0, 0}}, // (135, 20) + { 0, { 0, 0, 0}}, // (136, 20) + { 0, { 0, 0, 0}}, // (137, 20) + { 0, { 0, 0, 0}}, // (138, 20) + { 0, { 0, 0, 0}}, // (139, 20) + { 0, { 0, 0, 0}}, // (140, 20) + { 0, { 0, 0, 0}}, // (141, 20) + { 0, { 0, 0, 0}}, // (142, 20) + { 24, { 0, 0, 0}}, // (143, 20) + {111, { 0, 0, 0}}, // (144, 20) + {128, { 0, 0, 0}}, // (145, 20) + {128, { 0, 0, 0}}, // (146, 20) + {128, { 0, 0, 0}}, // (147, 20) + {128, { 0, 0, 0}}, // (148, 20) + {128, { 0, 0, 0}}, // (149, 20) + {128, { 0, 0, 0}}, // (150, 20) + {128, { 0, 0, 0}}, // (151, 20) + {128, { 0, 0, 0}}, // (152, 20) + {128, { 0, 0, 0}}, // (153, 20) + {128, { 0, 0, 0}}, // (154, 20) + {128, { 0, 0, 0}}, // (155, 20) + {128, { 0, 0, 0}}, // (156, 20) + {128, { 0, 0, 0}}, // (157, 20) + {128, { 0, 0, 0}}, // (158, 20) + {128, { 0, 0, 0}}, // (159, 20) + {128, { 0, 0, 0}}, // (160, 20) + {128, { 0, 0, 0}}, // (161, 20) + {128, { 0, 0, 0}}, // (162, 20) + {128, { 0, 0, 0}}, // (163, 20) + {128, { 0, 0, 0}}, // (164, 20) + {128, { 0, 0, 0}}, // (165, 20) + {128, { 0, 0, 0}}, // (166, 20) + {128, { 0, 0, 0}}, // (167, 20) + {128, { 0, 0, 0}}, // (168, 20) + {128, { 0, 0, 0}}, // (169, 20) + {128, { 0, 0, 0}}, // (170, 20) + {128, { 0, 0, 0}}, // (171, 20) + {128, { 0, 0, 0}}, // (172, 20) + {128, { 0, 0, 0}}, // (173, 20) + {128, { 0, 0, 0}}, // (174, 20) + {128, { 0, 0, 0}}, // (175, 20) + {128, { 0, 0, 0}}, // (176, 20) + {128, { 0, 0, 0}}, // (177, 20) + {128, { 0, 0, 0}}, // (178, 20) + {128, { 0, 0, 0}}, // (179, 20) + {128, { 0, 0, 0}}, // ( 0, 21) + {128, { 0, 0, 0}}, // ( 1, 21) + {128, { 0, 0, 0}}, // ( 2, 21) + {128, { 0, 0, 0}}, // ( 3, 21) + {128, { 0, 0, 0}}, // ( 4, 21) + {128, { 0, 0, 0}}, // ( 5, 21) + {128, { 0, 0, 0}}, // ( 6, 21) + {128, { 0, 0, 0}}, // ( 7, 21) + {128, { 0, 0, 0}}, // ( 8, 21) + {128, { 0, 0, 0}}, // ( 9, 21) + {128, { 0, 0, 0}}, // ( 10, 21) + {128, { 0, 0, 0}}, // ( 11, 21) + {128, { 0, 0, 0}}, // ( 12, 21) + {128, { 0, 0, 0}}, // ( 13, 21) + {128, { 0, 0, 0}}, // ( 14, 21) + {128, { 0, 0, 0}}, // ( 15, 21) + {128, { 0, 0, 0}}, // ( 16, 21) + {128, { 0, 0, 0}}, // ( 17, 21) + {128, { 0, 0, 0}}, // ( 18, 21) + {128, { 0, 0, 0}}, // ( 19, 21) + {128, { 0, 0, 0}}, // ( 20, 21) + {128, { 0, 0, 0}}, // ( 21, 21) + {128, { 0, 0, 0}}, // ( 22, 21) + {128, { 0, 0, 0}}, // ( 23, 21) + {128, { 0, 0, 0}}, // ( 24, 21) + {128, { 0, 0, 0}}, // ( 25, 21) + {128, { 0, 0, 0}}, // ( 26, 21) + {128, { 0, 0, 0}}, // ( 27, 21) + {128, { 0, 0, 0}}, // ( 28, 21) + {128, { 0, 0, 0}}, // ( 29, 21) + {128, { 0, 0, 0}}, // ( 30, 21) + {128, { 0, 0, 0}}, // ( 31, 21) + {128, { 0, 0, 0}}, // ( 32, 21) + {128, { 0, 0, 0}}, // ( 33, 21) + { 91, { 0, 0, 0}}, // ( 34, 21) + { 9, { 0, 0, 0}}, // ( 35, 21) + { 0, { 0, 0, 0}}, // ( 36, 21) + { 0, { 0, 0, 0}}, // ( 37, 21) + { 0, { 0, 0, 0}}, // ( 38, 21) + { 0, { 0, 0, 0}}, // ( 39, 21) + { 0, { 0, 0, 0}}, // ( 40, 21) + { 0, { 0, 0, 0}}, // ( 41, 21) + { 0, { 0, 0, 0}}, // ( 42, 21) + { 0, { 0, 0, 0}}, // ( 43, 21) + { 0, { 0, 0, 0}}, // ( 44, 21) + { 0, { 0, 0, 0}}, // ( 45, 21) + { 0, { 0, 0, 0}}, // ( 46, 21) + { 0, { 0, 0, 0}}, // ( 47, 21) + { 0, { 0, 0, 0}}, // ( 48, 21) + { 0, { 0, 0, 0}}, // ( 49, 21) + { 0, { 0, 0, 0}}, // ( 50, 21) + { 0, { 0, 0, 0}}, // ( 51, 21) + { 0, { 0, 0, 0}}, // ( 52, 21) + { 0, { 0, 0, 0}}, // ( 53, 21) + { 0, { 0, 0, 0}}, // ( 54, 21) + { 0, { 0, 0, 0}}, // ( 55, 21) + { 0, { 0, 0, 0}}, // ( 56, 21) + { 0, { 0, 0, 0}}, // ( 57, 21) + { 0, { 0, 0, 0}}, // ( 58, 21) + { 0, { 0, 0, 0}}, // ( 59, 21) + { 0, { 0, 0, 0}}, // ( 60, 21) + { 0, { 0, 0, 0}}, // ( 61, 21) + { 0, { 0, 0, 0}}, // ( 62, 21) + { 0, { 0, 0, 0}}, // ( 63, 21) + { 0, { 0, 0, 0}}, // ( 64, 21) + { 0, { 0, 0, 0}}, // ( 65, 21) + { 0, { 0, 0, 0}}, // ( 66, 21) + { 0, { 0, 0, 0}}, // ( 67, 21) + { 0, { 0, 0, 0}}, // ( 68, 21) + { 0, { 0, 0, 0}}, // ( 69, 21) + { 0, { 0, 0, 0}}, // ( 70, 21) + { 0, { 0, 0, 0}}, // ( 71, 21) + { 0, { 0, 0, 0}}, // ( 72, 21) + { 0, { 0, 0, 0}}, // ( 73, 21) + { 0, { 0, 0, 0}}, // ( 74, 21) + { 0, { 0, 0, 0}}, // ( 75, 21) + { 0, { 0, 0, 0}}, // ( 76, 21) + { 0, { 0, 0, 0}}, // ( 77, 21) + { 0, { 0, 0, 0}}, // ( 78, 21) + { 0, { 0, 0, 0}}, // ( 79, 21) + { 0, { 0, 0, 0}}, // ( 80, 21) + { 0, { 0, 0, 0}}, // ( 81, 21) + { 0, { 0, 0, 0}}, // ( 82, 21) + { 0, { 0, 0, 0}}, // ( 83, 21) + { 0, { 0, 0, 0}}, // ( 84, 21) + { 0, { 0, 0, 0}}, // ( 85, 21) + { 0, { 0, 0, 0}}, // ( 86, 21) + { 0, { 0, 0, 0}}, // ( 87, 21) + { 0, { 0, 0, 0}}, // ( 88, 21) + { 0, { 0, 0, 0}}, // ( 89, 21) + { 0, { 0, 0, 0}}, // ( 90, 21) + { 0, { 0, 0, 0}}, // ( 91, 21) + { 0, { 0, 0, 0}}, // ( 92, 21) + { 0, { 0, 0, 0}}, // ( 93, 21) + { 0, { 0, 0, 0}}, // ( 94, 21) + { 0, { 0, 0, 0}}, // ( 95, 21) + { 0, { 0, 0, 0}}, // ( 96, 21) + { 0, { 0, 0, 0}}, // ( 97, 21) + { 0, { 0, 0, 0}}, // ( 98, 21) + { 0, { 0, 0, 0}}, // ( 99, 21) + { 0, { 0, 0, 0}}, // (100, 21) + { 0, { 0, 0, 0}}, // (101, 21) + { 0, { 0, 0, 0}}, // (102, 21) + { 0, { 0, 0, 0}}, // (103, 21) + { 0, { 0, 0, 0}}, // (104, 21) + { 0, { 0, 0, 0}}, // (105, 21) + { 0, { 0, 0, 0}}, // (106, 21) + { 0, { 0, 0, 0}}, // (107, 21) + { 0, { 0, 0, 0}}, // (108, 21) + { 0, { 0, 0, 0}}, // (109, 21) + { 0, { 0, 0, 0}}, // (110, 21) + { 0, { 0, 0, 0}}, // (111, 21) + { 0, { 0, 0, 0}}, // (112, 21) + { 0, { 0, 0, 0}}, // (113, 21) + { 0, { 0, 0, 0}}, // (114, 21) + { 0, { 0, 0, 0}}, // (115, 21) + { 0, { 0, 0, 0}}, // (116, 21) + { 0, { 0, 0, 0}}, // (117, 21) + { 0, { 0, 0, 0}}, // (118, 21) + { 0, { 0, 0, 0}}, // (119, 21) + { 0, { 0, 0, 0}}, // (120, 21) + { 0, { 0, 0, 0}}, // (121, 21) + { 0, { 0, 0, 0}}, // (122, 21) + { 0, { 0, 0, 0}}, // (123, 21) + { 0, { 0, 0, 0}}, // (124, 21) + { 0, { 0, 0, 0}}, // (125, 21) + { 0, { 0, 0, 0}}, // (126, 21) + { 0, { 0, 0, 0}}, // (127, 21) + { 0, { 0, 0, 0}}, // (128, 21) + { 0, { 0, 0, 0}}, // (129, 21) + { 0, { 0, 0, 0}}, // (130, 21) + { 0, { 0, 0, 0}}, // (131, 21) + { 0, { 0, 0, 0}}, // (132, 21) + { 0, { 0, 0, 0}}, // (133, 21) + { 0, { 0, 0, 0}}, // (134, 21) + { 0, { 0, 0, 0}}, // (135, 21) + { 0, { 0, 0, 0}}, // (136, 21) + { 0, { 0, 0, 0}}, // (137, 21) + { 0, { 0, 0, 0}}, // (138, 21) + { 0, { 0, 0, 0}}, // (139, 21) + { 0, { 0, 0, 0}}, // (140, 21) + { 0, { 0, 0, 0}}, // (141, 21) + { 0, { 0, 0, 0}}, // (142, 21) + { 0, { 0, 0, 0}}, // (143, 21) + { 9, { 0, 0, 0}}, // (144, 21) + { 91, { 0, 0, 0}}, // (145, 21) + {128, { 0, 0, 0}}, // (146, 21) + {128, { 0, 0, 0}}, // (147, 21) + {128, { 0, 0, 0}}, // (148, 21) + {128, { 0, 0, 0}}, // (149, 21) + {128, { 0, 0, 0}}, // (150, 21) + {128, { 0, 0, 0}}, // (151, 21) + {128, { 0, 0, 0}}, // (152, 21) + {128, { 0, 0, 0}}, // (153, 21) + {128, { 0, 0, 0}}, // (154, 21) + {128, { 0, 0, 0}}, // (155, 21) + {128, { 0, 0, 0}}, // (156, 21) + {128, { 0, 0, 0}}, // (157, 21) + {128, { 0, 0, 0}}, // (158, 21) + {128, { 0, 0, 0}}, // (159, 21) + {128, { 0, 0, 0}}, // (160, 21) + {128, { 0, 0, 0}}, // (161, 21) + {128, { 0, 0, 0}}, // (162, 21) + {128, { 0, 0, 0}}, // (163, 21) + {128, { 0, 0, 0}}, // (164, 21) + {128, { 0, 0, 0}}, // (165, 21) + {128, { 0, 0, 0}}, // (166, 21) + {128, { 0, 0, 0}}, // (167, 21) + {128, { 0, 0, 0}}, // (168, 21) + {128, { 0, 0, 0}}, // (169, 21) + {128, { 0, 0, 0}}, // (170, 21) + {128, { 0, 0, 0}}, // (171, 21) + {128, { 0, 0, 0}}, // (172, 21) + {128, { 0, 0, 0}}, // (173, 21) + {128, { 0, 0, 0}}, // (174, 21) + {128, { 0, 0, 0}}, // (175, 21) + {128, { 0, 0, 0}}, // (176, 21) + {128, { 0, 0, 0}}, // (177, 21) + {128, { 0, 0, 0}}, // (178, 21) + {128, { 0, 0, 0}}, // (179, 21) + {128, { 0, 0, 0}}, // ( 0, 22) + {128, { 0, 0, 0}}, // ( 1, 22) + {128, { 0, 0, 0}}, // ( 2, 22) + {128, { 0, 0, 0}}, // ( 3, 22) + {128, { 0, 0, 0}}, // ( 4, 22) + {128, { 0, 0, 0}}, // ( 5, 22) + {128, { 0, 0, 0}}, // ( 6, 22) + {128, { 0, 0, 0}}, // ( 7, 22) + {128, { 0, 0, 0}}, // ( 8, 22) + {128, { 0, 0, 0}}, // ( 9, 22) + {128, { 0, 0, 0}}, // ( 10, 22) + {128, { 0, 0, 0}}, // ( 11, 22) + {128, { 0, 0, 0}}, // ( 12, 22) + {128, { 0, 0, 0}}, // ( 13, 22) + {128, { 0, 0, 0}}, // ( 14, 22) + {128, { 0, 0, 0}}, // ( 15, 22) + {128, { 0, 0, 0}}, // ( 16, 22) + {128, { 0, 0, 0}}, // ( 17, 22) + {128, { 0, 0, 0}}, // ( 18, 22) + {128, { 0, 0, 0}}, // ( 19, 22) + {128, { 0, 0, 0}}, // ( 20, 22) + {128, { 0, 0, 0}}, // ( 21, 22) + {128, { 0, 0, 0}}, // ( 22, 22) + {128, { 0, 0, 0}}, // ( 23, 22) + {128, { 0, 0, 0}}, // ( 24, 22) + {128, { 0, 0, 0}}, // ( 25, 22) + {128, { 0, 0, 0}}, // ( 26, 22) + {128, { 0, 0, 0}}, // ( 27, 22) + {128, { 0, 0, 0}}, // ( 28, 22) + {128, { 0, 0, 0}}, // ( 29, 22) + {128, { 0, 0, 0}}, // ( 30, 22) + {128, { 0, 0, 0}}, // ( 31, 22) + {128, { 0, 0, 0}}, // ( 32, 22) + { 69, { 0, 0, 0}}, // ( 33, 22) + { 1, { 0, 0, 0}}, // ( 34, 22) + { 0, { 0, 0, 0}}, // ( 35, 22) + { 0, { 0, 0, 0}}, // ( 36, 22) + { 0, { 0, 0, 0}}, // ( 37, 22) + { 0, { 0, 0, 0}}, // ( 38, 22) + { 0, { 0, 0, 0}}, // ( 39, 22) + { 0, { 0, 0, 0}}, // ( 40, 22) + { 0, { 0, 0, 0}}, // ( 41, 22) + { 0, { 0, 0, 0}}, // ( 42, 22) + { 0, { 0, 0, 0}}, // ( 43, 22) + { 0, { 0, 0, 0}}, // ( 44, 22) + { 0, { 0, 0, 0}}, // ( 45, 22) + { 0, { 0, 0, 0}}, // ( 46, 22) + { 0, { 0, 0, 0}}, // ( 47, 22) + { 0, { 0, 0, 0}}, // ( 48, 22) + { 0, { 0, 0, 0}}, // ( 49, 22) + { 0, { 0, 0, 0}}, // ( 50, 22) + { 0, { 0, 0, 0}}, // ( 51, 22) + { 0, { 0, 0, 0}}, // ( 52, 22) + { 0, { 0, 0, 0}}, // ( 53, 22) + { 0, { 0, 0, 0}}, // ( 54, 22) + { 0, { 0, 0, 0}}, // ( 55, 22) + { 0, { 0, 0, 0}}, // ( 56, 22) + { 0, { 0, 0, 0}}, // ( 57, 22) + { 0, { 0, 0, 0}}, // ( 58, 22) + { 0, { 0, 0, 0}}, // ( 59, 22) + { 0, { 0, 0, 0}}, // ( 60, 22) + { 0, { 0, 0, 0}}, // ( 61, 22) + { 0, { 0, 0, 0}}, // ( 62, 22) + { 0, { 0, 0, 0}}, // ( 63, 22) + { 0, { 0, 0, 0}}, // ( 64, 22) + { 0, { 0, 0, 0}}, // ( 65, 22) + { 0, { 0, 0, 0}}, // ( 66, 22) + { 0, { 0, 0, 0}}, // ( 67, 22) + { 0, { 0, 0, 0}}, // ( 68, 22) + { 0, { 0, 0, 0}}, // ( 69, 22) + { 0, { 0, 0, 0}}, // ( 70, 22) + { 0, { 0, 0, 0}}, // ( 71, 22) + { 0, { 0, 0, 0}}, // ( 72, 22) + { 0, { 0, 0, 0}}, // ( 73, 22) + { 0, { 0, 0, 0}}, // ( 74, 22) + { 0, { 0, 0, 0}}, // ( 75, 22) + { 0, { 0, 0, 0}}, // ( 76, 22) + { 0, { 0, 0, 0}}, // ( 77, 22) + { 0, { 0, 0, 0}}, // ( 78, 22) + { 0, { 0, 0, 0}}, // ( 79, 22) + { 0, { 0, 0, 0}}, // ( 80, 22) + { 0, { 0, 0, 0}}, // ( 81, 22) + { 0, { 0, 0, 0}}, // ( 82, 22) + { 0, { 0, 0, 0}}, // ( 83, 22) + { 0, { 0, 0, 0}}, // ( 84, 22) + { 0, { 0, 0, 0}}, // ( 85, 22) + { 0, { 0, 0, 0}}, // ( 86, 22) + { 0, { 0, 0, 0}}, // ( 87, 22) + { 0, { 0, 0, 0}}, // ( 88, 22) + { 0, { 0, 0, 0}}, // ( 89, 22) + { 0, { 0, 0, 0}}, // ( 90, 22) + { 0, { 0, 0, 0}}, // ( 91, 22) + { 0, { 0, 0, 0}}, // ( 92, 22) + { 0, { 0, 0, 0}}, // ( 93, 22) + { 0, { 0, 0, 0}}, // ( 94, 22) + { 0, { 0, 0, 0}}, // ( 95, 22) + { 0, { 0, 0, 0}}, // ( 96, 22) + { 0, { 0, 0, 0}}, // ( 97, 22) + { 0, { 0, 0, 0}}, // ( 98, 22) + { 0, { 0, 0, 0}}, // ( 99, 22) + { 0, { 0, 0, 0}}, // (100, 22) + { 0, { 0, 0, 0}}, // (101, 22) + { 0, { 0, 0, 0}}, // (102, 22) + { 0, { 0, 0, 0}}, // (103, 22) + { 0, { 0, 0, 0}}, // (104, 22) + { 0, { 0, 0, 0}}, // (105, 22) + { 0, { 0, 0, 0}}, // (106, 22) + { 0, { 0, 0, 0}}, // (107, 22) + { 0, { 0, 0, 0}}, // (108, 22) + { 0, { 0, 0, 0}}, // (109, 22) + { 0, { 0, 0, 0}}, // (110, 22) + { 0, { 0, 0, 0}}, // (111, 22) + { 0, { 0, 0, 0}}, // (112, 22) + { 0, { 0, 0, 0}}, // (113, 22) + { 0, { 0, 0, 0}}, // (114, 22) + { 0, { 0, 0, 0}}, // (115, 22) + { 0, { 0, 0, 0}}, // (116, 22) + { 0, { 0, 0, 0}}, // (117, 22) + { 0, { 0, 0, 0}}, // (118, 22) + { 0, { 0, 0, 0}}, // (119, 22) + { 0, { 0, 0, 0}}, // (120, 22) + { 0, { 0, 0, 0}}, // (121, 22) + { 0, { 0, 0, 0}}, // (122, 22) + { 0, { 0, 0, 0}}, // (123, 22) + { 0, { 0, 0, 0}}, // (124, 22) + { 0, { 0, 0, 0}}, // (125, 22) + { 0, { 0, 0, 0}}, // (126, 22) + { 0, { 0, 0, 0}}, // (127, 22) + { 0, { 0, 0, 0}}, // (128, 22) + { 0, { 0, 0, 0}}, // (129, 22) + { 0, { 0, 0, 0}}, // (130, 22) + { 0, { 0, 0, 0}}, // (131, 22) + { 0, { 0, 0, 0}}, // (132, 22) + { 0, { 0, 0, 0}}, // (133, 22) + { 0, { 0, 0, 0}}, // (134, 22) + { 0, { 0, 0, 0}}, // (135, 22) + { 0, { 0, 0, 0}}, // (136, 22) + { 0, { 0, 0, 0}}, // (137, 22) + { 0, { 0, 0, 0}}, // (138, 22) + { 0, { 0, 0, 0}}, // (139, 22) + { 0, { 0, 0, 0}}, // (140, 22) + { 0, { 0, 0, 0}}, // (141, 22) + { 0, { 0, 0, 0}}, // (142, 22) + { 0, { 0, 0, 0}}, // (143, 22) + { 0, { 0, 0, 0}}, // (144, 22) + { 1, { 0, 0, 0}}, // (145, 22) + { 69, { 0, 0, 0}}, // (146, 22) + {128, { 0, 0, 0}}, // (147, 22) + {128, { 0, 0, 0}}, // (148, 22) + {128, { 0, 0, 0}}, // (149, 22) + {128, { 0, 0, 0}}, // (150, 22) + {128, { 0, 0, 0}}, // (151, 22) + {128, { 0, 0, 0}}, // (152, 22) + {128, { 0, 0, 0}}, // (153, 22) + {128, { 0, 0, 0}}, // (154, 22) + {128, { 0, 0, 0}}, // (155, 22) + {128, { 0, 0, 0}}, // (156, 22) + {128, { 0, 0, 0}}, // (157, 22) + {128, { 0, 0, 0}}, // (158, 22) + {128, { 0, 0, 0}}, // (159, 22) + {128, { 0, 0, 0}}, // (160, 22) + {128, { 0, 0, 0}}, // (161, 22) + {128, { 0, 0, 0}}, // (162, 22) + {128, { 0, 0, 0}}, // (163, 22) + {128, { 0, 0, 0}}, // (164, 22) + {128, { 0, 0, 0}}, // (165, 22) + {128, { 0, 0, 0}}, // (166, 22) + {128, { 0, 0, 0}}, // (167, 22) + {128, { 0, 0, 0}}, // (168, 22) + {128, { 0, 0, 0}}, // (169, 22) + {128, { 0, 0, 0}}, // (170, 22) + {128, { 0, 0, 0}}, // (171, 22) + {128, { 0, 0, 0}}, // (172, 22) + {128, { 0, 0, 0}}, // (173, 22) + {128, { 0, 0, 0}}, // (174, 22) + {128, { 0, 0, 0}}, // (175, 22) + {128, { 0, 0, 0}}, // (176, 22) + {128, { 0, 0, 0}}, // (177, 22) + {128, { 0, 0, 0}}, // (178, 22) + {128, { 0, 0, 0}}, // (179, 22) + {128, { 0, 0, 0}}, // ( 0, 23) + {128, { 0, 0, 0}}, // ( 1, 23) + {128, { 0, 0, 0}}, // ( 2, 23) + {128, { 0, 0, 0}}, // ( 3, 23) + {128, { 0, 0, 0}}, // ( 4, 23) + {128, { 0, 0, 0}}, // ( 5, 23) + {128, { 0, 0, 0}}, // ( 6, 23) + {128, { 0, 0, 0}}, // ( 7, 23) + {128, { 0, 0, 0}}, // ( 8, 23) + {128, { 0, 0, 0}}, // ( 9, 23) + {128, { 0, 0, 0}}, // ( 10, 23) + {128, { 0, 0, 0}}, // ( 11, 23) + {128, { 0, 0, 0}}, // ( 12, 23) + {128, { 0, 0, 0}}, // ( 13, 23) + {128, { 0, 0, 0}}, // ( 14, 23) + {128, { 0, 0, 0}}, // ( 15, 23) + {128, { 0, 0, 0}}, // ( 16, 23) + {128, { 0, 0, 0}}, // ( 17, 23) + {128, { 0, 0, 0}}, // ( 18, 23) + {128, { 0, 0, 0}}, // ( 19, 23) + {128, { 0, 0, 0}}, // ( 20, 23) + {128, { 0, 0, 0}}, // ( 21, 23) + {128, { 0, 0, 0}}, // ( 22, 23) + {128, { 0, 0, 0}}, // ( 23, 23) + {128, { 0, 0, 0}}, // ( 24, 23) + {128, { 0, 0, 0}}, // ( 25, 23) + {128, { 0, 0, 0}}, // ( 26, 23) + {128, { 0, 0, 0}}, // ( 27, 23) + {128, { 0, 0, 0}}, // ( 28, 23) + {128, { 0, 0, 0}}, // ( 29, 23) + {128, { 0, 0, 0}}, // ( 30, 23) + {126, { 0, 0, 0}}, // ( 31, 23) + { 50, { 0, 0, 0}}, // ( 32, 23) + { 0, { 0, 0, 0}}, // ( 33, 23) + { 0, { 0, 0, 0}}, // ( 34, 23) + { 0, { 0, 0, 0}}, // ( 35, 23) + { 0, { 0, 0, 0}}, // ( 36, 23) + { 0, { 0, 0, 0}}, // ( 37, 23) + { 0, { 0, 0, 0}}, // ( 38, 23) + { 0, { 0, 0, 0}}, // ( 39, 23) + { 0, { 0, 0, 0}}, // ( 40, 23) + { 0, { 0, 0, 0}}, // ( 41, 23) + { 0, { 0, 0, 0}}, // ( 42, 23) + { 0, { 0, 0, 0}}, // ( 43, 23) + { 0, { 0, 0, 0}}, // ( 44, 23) + { 0, { 0, 0, 0}}, // ( 45, 23) + { 0, { 0, 0, 0}}, // ( 46, 23) + { 0, { 0, 0, 0}}, // ( 47, 23) + { 0, { 0, 0, 0}}, // ( 48, 23) + { 0, { 0, 0, 0}}, // ( 49, 23) + { 0, { 0, 0, 0}}, // ( 50, 23) + { 0, { 0, 0, 0}}, // ( 51, 23) + { 0, { 0, 0, 0}}, // ( 52, 23) + { 0, { 0, 0, 0}}, // ( 53, 23) + { 0, { 0, 0, 0}}, // ( 54, 23) + { 0, { 0, 0, 0}}, // ( 55, 23) + { 0, { 0, 0, 0}}, // ( 56, 23) + { 0, { 0, 0, 0}}, // ( 57, 23) + { 0, { 0, 0, 0}}, // ( 58, 23) + { 0, { 0, 0, 0}}, // ( 59, 23) + { 0, { 0, 0, 0}}, // ( 60, 23) + { 0, { 0, 0, 0}}, // ( 61, 23) + { 0, { 0, 0, 0}}, // ( 62, 23) + { 0, { 0, 0, 0}}, // ( 63, 23) + { 0, { 0, 0, 0}}, // ( 64, 23) + { 0, { 0, 0, 0}}, // ( 65, 23) + { 0, { 0, 0, 0}}, // ( 66, 23) + { 0, { 0, 0, 0}}, // ( 67, 23) + { 0, { 0, 0, 0}}, // ( 68, 23) + { 0, { 0, 0, 0}}, // ( 69, 23) + { 0, { 0, 0, 0}}, // ( 70, 23) + { 0, { 0, 0, 0}}, // ( 71, 23) + { 0, { 0, 0, 0}}, // ( 72, 23) + { 0, { 0, 0, 0}}, // ( 73, 23) + { 0, { 0, 0, 0}}, // ( 74, 23) + { 0, { 0, 0, 0}}, // ( 75, 23) + { 0, { 0, 0, 0}}, // ( 76, 23) + { 0, { 0, 0, 0}}, // ( 77, 23) + { 0, { 0, 0, 0}}, // ( 78, 23) + { 0, { 0, 0, 0}}, // ( 79, 23) + { 0, { 0, 0, 0}}, // ( 80, 23) + { 0, { 0, 0, 0}}, // ( 81, 23) + { 0, { 0, 0, 0}}, // ( 82, 23) + { 0, { 0, 0, 0}}, // ( 83, 23) + { 0, { 0, 0, 0}}, // ( 84, 23) + { 0, { 0, 0, 0}}, // ( 85, 23) + { 0, { 0, 0, 0}}, // ( 86, 23) + { 0, { 0, 0, 0}}, // ( 87, 23) + { 0, { 0, 0, 0}}, // ( 88, 23) + { 0, { 0, 0, 0}}, // ( 89, 23) + { 0, { 0, 0, 0}}, // ( 90, 23) + { 0, { 0, 0, 0}}, // ( 91, 23) + { 0, { 0, 0, 0}}, // ( 92, 23) + { 0, { 0, 0, 0}}, // ( 93, 23) + { 0, { 0, 0, 0}}, // ( 94, 23) + { 0, { 0, 0, 0}}, // ( 95, 23) + { 0, { 0, 0, 0}}, // ( 96, 23) + { 0, { 0, 0, 0}}, // ( 97, 23) + { 0, { 0, 0, 0}}, // ( 98, 23) + { 0, { 0, 0, 0}}, // ( 99, 23) + { 0, { 0, 0, 0}}, // (100, 23) + { 0, { 0, 0, 0}}, // (101, 23) + { 0, { 0, 0, 0}}, // (102, 23) + { 0, { 0, 0, 0}}, // (103, 23) + { 0, { 0, 0, 0}}, // (104, 23) + { 0, { 0, 0, 0}}, // (105, 23) + { 0, { 0, 0, 0}}, // (106, 23) + { 0, { 0, 0, 0}}, // (107, 23) + { 0, { 0, 0, 0}}, // (108, 23) + { 0, { 0, 0, 0}}, // (109, 23) + { 0, { 0, 0, 0}}, // (110, 23) + { 0, { 0, 0, 0}}, // (111, 23) + { 0, { 0, 0, 0}}, // (112, 23) + { 0, { 0, 0, 0}}, // (113, 23) + { 0, { 0, 0, 0}}, // (114, 23) + { 0, { 0, 0, 0}}, // (115, 23) + { 0, { 0, 0, 0}}, // (116, 23) + { 0, { 0, 0, 0}}, // (117, 23) + { 0, { 0, 0, 0}}, // (118, 23) + { 0, { 0, 0, 0}}, // (119, 23) + { 0, { 0, 0, 0}}, // (120, 23) + { 0, { 0, 0, 0}}, // (121, 23) + { 0, { 0, 0, 0}}, // (122, 23) + { 0, { 0, 0, 0}}, // (123, 23) + { 0, { 0, 0, 0}}, // (124, 23) + { 0, { 0, 0, 0}}, // (125, 23) + { 0, { 0, 0, 0}}, // (126, 23) + { 0, { 0, 0, 0}}, // (127, 23) + { 0, { 0, 0, 0}}, // (128, 23) + { 0, { 0, 0, 0}}, // (129, 23) + { 0, { 0, 0, 0}}, // (130, 23) + { 0, { 0, 0, 0}}, // (131, 23) + { 0, { 0, 0, 0}}, // (132, 23) + { 0, { 0, 0, 0}}, // (133, 23) + { 0, { 0, 0, 0}}, // (134, 23) + { 0, { 0, 0, 0}}, // (135, 23) + { 0, { 0, 0, 0}}, // (136, 23) + { 0, { 0, 0, 0}}, // (137, 23) + { 0, { 0, 0, 0}}, // (138, 23) + { 0, { 0, 0, 0}}, // (139, 23) + { 0, { 0, 0, 0}}, // (140, 23) + { 0, { 0, 0, 0}}, // (141, 23) + { 0, { 0, 0, 0}}, // (142, 23) + { 0, { 0, 0, 0}}, // (143, 23) + { 0, { 0, 0, 0}}, // (144, 23) + { 0, { 0, 0, 0}}, // (145, 23) + { 0, { 0, 0, 0}}, // (146, 23) + { 49, { 0, 0, 0}}, // (147, 23) + {126, { 0, 0, 0}}, // (148, 23) + {128, { 0, 0, 0}}, // (149, 23) + {128, { 0, 0, 0}}, // (150, 23) + {128, { 0, 0, 0}}, // (151, 23) + {128, { 0, 0, 0}}, // (152, 23) + {128, { 0, 0, 0}}, // (153, 23) + {128, { 0, 0, 0}}, // (154, 23) + {128, { 0, 0, 0}}, // (155, 23) + {128, { 0, 0, 0}}, // (156, 23) + {128, { 0, 0, 0}}, // (157, 23) + {128, { 0, 0, 0}}, // (158, 23) + {128, { 0, 0, 0}}, // (159, 23) + {128, { 0, 0, 0}}, // (160, 23) + {128, { 0, 0, 0}}, // (161, 23) + {128, { 0, 0, 0}}, // (162, 23) + {128, { 0, 0, 0}}, // (163, 23) + {128, { 0, 0, 0}}, // (164, 23) + {128, { 0, 0, 0}}, // (165, 23) + {128, { 0, 0, 0}}, // (166, 23) + {128, { 0, 0, 0}}, // (167, 23) + {128, { 0, 0, 0}}, // (168, 23) + {128, { 0, 0, 0}}, // (169, 23) + {128, { 0, 0, 0}}, // (170, 23) + {128, { 0, 0, 0}}, // (171, 23) + {128, { 0, 0, 0}}, // (172, 23) + {128, { 0, 0, 0}}, // (173, 23) + {128, { 0, 0, 0}}, // (174, 23) + {128, { 0, 0, 0}}, // (175, 23) + {128, { 0, 0, 0}}, // (176, 23) + {128, { 0, 0, 0}}, // (177, 23) + {128, { 0, 0, 0}}, // (178, 23) + {128, { 0, 0, 0}}, // (179, 23) + {128, { 0, 0, 0}}, // ( 0, 24) + {128, { 0, 0, 0}}, // ( 1, 24) + {128, { 0, 0, 0}}, // ( 2, 24) + {128, { 0, 0, 0}}, // ( 3, 24) + {128, { 0, 0, 0}}, // ( 4, 24) + {128, { 0, 0, 0}}, // ( 5, 24) + {128, { 0, 0, 0}}, // ( 6, 24) + {128, { 0, 0, 0}}, // ( 7, 24) + {128, { 0, 0, 0}}, // ( 8, 24) + {128, { 0, 0, 0}}, // ( 9, 24) + {128, { 0, 0, 0}}, // ( 10, 24) + {128, { 0, 0, 0}}, // ( 11, 24) + {128, { 0, 0, 0}}, // ( 12, 24) + {128, { 0, 0, 0}}, // ( 13, 24) + {128, { 0, 0, 0}}, // ( 14, 24) + {128, { 0, 0, 0}}, // ( 15, 24) + {128, { 0, 0, 0}}, // ( 16, 24) + {128, { 0, 0, 0}}, // ( 17, 24) + {128, { 0, 0, 0}}, // ( 18, 24) + {128, { 0, 0, 0}}, // ( 19, 24) + {128, { 0, 0, 0}}, // ( 20, 24) + {128, { 0, 0, 0}}, // ( 21, 24) + {128, { 0, 0, 0}}, // ( 22, 24) + {128, { 0, 0, 0}}, // ( 23, 24) + {128, { 0, 0, 0}}, // ( 24, 24) + {128, { 0, 0, 0}}, // ( 25, 24) + {128, { 0, 0, 0}}, // ( 26, 24) + {128, { 0, 0, 0}}, // ( 27, 24) + {128, { 0, 0, 0}}, // ( 28, 24) + {128, { 0, 0, 0}}, // ( 29, 24) + {122, { 0, 0, 0}}, // ( 30, 24) + { 37, { 0, 0, 0}}, // ( 31, 24) + { 0, { 0, 0, 0}}, // ( 32, 24) + { 0, { 0, 0, 0}}, // ( 33, 24) + { 0, { 0, 0, 0}}, // ( 34, 24) + { 0, { 0, 0, 0}}, // ( 35, 24) + { 0, { 0, 0, 0}}, // ( 36, 24) + { 0, { 0, 0, 0}}, // ( 37, 24) + { 0, { 0, 0, 0}}, // ( 38, 24) + { 0, { 0, 0, 0}}, // ( 39, 24) + { 0, { 0, 0, 0}}, // ( 40, 24) + { 0, { 0, 0, 0}}, // ( 41, 24) + { 0, { 0, 0, 0}}, // ( 42, 24) + { 0, { 0, 0, 0}}, // ( 43, 24) + { 0, { 0, 0, 0}}, // ( 44, 24) + { 0, { 0, 0, 0}}, // ( 45, 24) + { 0, { 0, 0, 0}}, // ( 46, 24) + { 0, { 0, 0, 0}}, // ( 47, 24) + { 0, { 0, 0, 0}}, // ( 48, 24) + { 0, { 0, 0, 0}}, // ( 49, 24) + { 0, { 0, 0, 0}}, // ( 50, 24) + { 0, { 0, 0, 0}}, // ( 51, 24) + { 0, { 0, 0, 0}}, // ( 52, 24) + { 0, { 0, 0, 0}}, // ( 53, 24) + { 0, { 0, 0, 0}}, // ( 54, 24) + { 0, { 0, 0, 0}}, // ( 55, 24) + { 0, { 0, 0, 0}}, // ( 56, 24) + { 0, { 0, 0, 0}}, // ( 57, 24) + { 0, { 0, 0, 0}}, // ( 58, 24) + { 0, { 0, 0, 0}}, // ( 59, 24) + { 0, { 0, 0, 0}}, // ( 60, 24) + { 0, { 0, 0, 0}}, // ( 61, 24) + { 0, { 0, 0, 0}}, // ( 62, 24) + { 0, { 0, 0, 0}}, // ( 63, 24) + { 0, { 0, 0, 0}}, // ( 64, 24) + { 0, { 0, 0, 0}}, // ( 65, 24) + { 0, { 0, 0, 0}}, // ( 66, 24) + { 0, { 0, 0, 0}}, // ( 67, 24) + { 0, { 0, 0, 0}}, // ( 68, 24) + { 0, { 0, 0, 0}}, // ( 69, 24) + { 0, { 0, 0, 0}}, // ( 70, 24) + { 0, { 0, 0, 0}}, // ( 71, 24) + { 0, { 0, 0, 0}}, // ( 72, 24) + { 0, { 0, 0, 0}}, // ( 73, 24) + { 0, { 0, 0, 0}}, // ( 74, 24) + { 0, { 0, 0, 0}}, // ( 75, 24) + { 0, { 0, 0, 0}}, // ( 76, 24) + { 0, { 0, 0, 0}}, // ( 77, 24) + { 0, { 0, 0, 0}}, // ( 78, 24) + { 0, { 0, 0, 0}}, // ( 79, 24) + { 0, { 0, 0, 0}}, // ( 80, 24) + { 0, { 0, 0, 0}}, // ( 81, 24) + { 0, { 0, 0, 0}}, // ( 82, 24) + { 0, { 0, 0, 0}}, // ( 83, 24) + { 0, { 0, 0, 0}}, // ( 84, 24) + { 0, { 0, 0, 0}}, // ( 85, 24) + { 0, { 0, 0, 0}}, // ( 86, 24) + { 0, { 0, 0, 0}}, // ( 87, 24) + { 0, { 0, 0, 0}}, // ( 88, 24) + { 0, { 0, 0, 0}}, // ( 89, 24) + { 0, { 0, 0, 0}}, // ( 90, 24) + { 0, { 0, 0, 0}}, // ( 91, 24) + { 0, { 0, 0, 0}}, // ( 92, 24) + { 0, { 0, 0, 0}}, // ( 93, 24) + { 0, { 0, 0, 0}}, // ( 94, 24) + { 0, { 0, 0, 0}}, // ( 95, 24) + { 0, { 0, 0, 0}}, // ( 96, 24) + { 0, { 0, 0, 0}}, // ( 97, 24) + { 0, { 0, 0, 0}}, // ( 98, 24) + { 0, { 0, 0, 0}}, // ( 99, 24) + { 0, { 0, 0, 0}}, // (100, 24) + { 0, { 0, 0, 0}}, // (101, 24) + { 0, { 0, 0, 0}}, // (102, 24) + { 0, { 0, 0, 0}}, // (103, 24) + { 0, { 0, 0, 0}}, // (104, 24) + { 0, { 0, 0, 0}}, // (105, 24) + { 0, { 0, 0, 0}}, // (106, 24) + { 0, { 0, 0, 0}}, // (107, 24) + { 0, { 0, 0, 0}}, // (108, 24) + { 0, { 0, 0, 0}}, // (109, 24) + { 0, { 0, 0, 0}}, // (110, 24) + { 0, { 0, 0, 0}}, // (111, 24) + { 0, { 0, 0, 0}}, // (112, 24) + { 0, { 0, 0, 0}}, // (113, 24) + { 0, { 0, 0, 0}}, // (114, 24) + { 0, { 0, 0, 0}}, // (115, 24) + { 0, { 0, 0, 0}}, // (116, 24) + { 0, { 0, 0, 0}}, // (117, 24) + { 0, { 0, 0, 0}}, // (118, 24) + { 0, { 0, 0, 0}}, // (119, 24) + { 0, { 0, 0, 0}}, // (120, 24) + { 0, { 0, 0, 0}}, // (121, 24) + { 0, { 0, 0, 0}}, // (122, 24) + { 0, { 0, 0, 0}}, // (123, 24) + { 0, { 0, 0, 0}}, // (124, 24) + { 0, { 0, 0, 0}}, // (125, 24) + { 0, { 0, 0, 0}}, // (126, 24) + { 0, { 0, 0, 0}}, // (127, 24) + { 0, { 0, 0, 0}}, // (128, 24) + { 0, { 0, 0, 0}}, // (129, 24) + { 0, { 0, 0, 0}}, // (130, 24) + { 0, { 0, 0, 0}}, // (131, 24) + { 0, { 0, 0, 0}}, // (132, 24) + { 0, { 0, 0, 0}}, // (133, 24) + { 0, { 0, 0, 0}}, // (134, 24) + { 0, { 0, 0, 0}}, // (135, 24) + { 0, { 0, 0, 0}}, // (136, 24) + { 0, { 0, 0, 0}}, // (137, 24) + { 0, { 0, 0, 0}}, // (138, 24) + { 0, { 0, 0, 0}}, // (139, 24) + { 0, { 0, 0, 0}}, // (140, 24) + { 0, { 0, 0, 0}}, // (141, 24) + { 0, { 0, 0, 0}}, // (142, 24) + { 0, { 0, 0, 0}}, // (143, 24) + { 0, { 0, 0, 0}}, // (144, 24) + { 0, { 0, 0, 0}}, // (145, 24) + { 0, { 0, 0, 0}}, // (146, 24) + { 0, { 0, 0, 0}}, // (147, 24) + { 37, { 0, 0, 0}}, // (148, 24) + {122, { 0, 0, 0}}, // (149, 24) + {128, { 0, 0, 0}}, // (150, 24) + {128, { 0, 0, 0}}, // (151, 24) + {128, { 0, 0, 0}}, // (152, 24) + {128, { 0, 0, 0}}, // (153, 24) + {128, { 0, 0, 0}}, // (154, 24) + {128, { 0, 0, 0}}, // (155, 24) + {128, { 0, 0, 0}}, // (156, 24) + {128, { 0, 0, 0}}, // (157, 24) + {128, { 0, 0, 0}}, // (158, 24) + {128, { 0, 0, 0}}, // (159, 24) + {128, { 0, 0, 0}}, // (160, 24) + {128, { 0, 0, 0}}, // (161, 24) + {128, { 0, 0, 0}}, // (162, 24) + {128, { 0, 0, 0}}, // (163, 24) + {128, { 0, 0, 0}}, // (164, 24) + {128, { 0, 0, 0}}, // (165, 24) + {128, { 0, 0, 0}}, // (166, 24) + {128, { 0, 0, 0}}, // (167, 24) + {128, { 0, 0, 0}}, // (168, 24) + {128, { 0, 0, 0}}, // (169, 24) + {128, { 0, 0, 0}}, // (170, 24) + {128, { 0, 0, 0}}, // (171, 24) + {128, { 0, 0, 0}}, // (172, 24) + {128, { 0, 0, 0}}, // (173, 24) + {128, { 0, 0, 0}}, // (174, 24) + {128, { 0, 0, 0}}, // (175, 24) + {128, { 0, 0, 0}}, // (176, 24) + {128, { 0, 0, 0}}, // (177, 24) + {128, { 0, 0, 0}}, // (178, 24) + {128, { 0, 0, 0}}, // (179, 24) + {128, { 0, 0, 0}}, // ( 0, 25) + {128, { 0, 0, 0}}, // ( 1, 25) + {128, { 0, 0, 0}}, // ( 2, 25) + {128, { 0, 0, 0}}, // ( 3, 25) + {128, { 0, 0, 0}}, // ( 4, 25) + {128, { 0, 0, 0}}, // ( 5, 25) + {128, { 0, 0, 0}}, // ( 6, 25) + {128, { 0, 0, 0}}, // ( 7, 25) + {128, { 0, 0, 0}}, // ( 8, 25) + {128, { 0, 0, 0}}, // ( 9, 25) + {128, { 0, 0, 0}}, // ( 10, 25) + {128, { 0, 0, 0}}, // ( 11, 25) + {128, { 0, 0, 0}}, // ( 12, 25) + {128, { 0, 0, 0}}, // ( 13, 25) + {128, { 0, 0, 0}}, // ( 14, 25) + {128, { 0, 0, 0}}, // ( 15, 25) + {128, { 0, 0, 0}}, // ( 16, 25) + {128, { 0, 0, 0}}, // ( 17, 25) + {128, { 0, 0, 0}}, // ( 18, 25) + {128, { 0, 0, 0}}, // ( 19, 25) + {128, { 0, 0, 0}}, // ( 20, 25) + {128, { 0, 0, 0}}, // ( 21, 25) + {128, { 0, 0, 0}}, // ( 22, 25) + {128, { 0, 0, 0}}, // ( 23, 25) + {128, { 0, 0, 0}}, // ( 24, 25) + {128, { 0, 0, 0}}, // ( 25, 25) + {128, { 0, 0, 0}}, // ( 26, 25) + {128, { 0, 0, 0}}, // ( 27, 25) + {128, { 0, 0, 0}}, // ( 28, 25) + {120, { 0, 0, 0}}, // ( 29, 25) + { 29, { 0, 0, 0}}, // ( 30, 25) + { 0, { 0, 0, 0}}, // ( 31, 25) + { 0, { 0, 0, 0}}, // ( 32, 25) + { 0, { 0, 0, 0}}, // ( 33, 25) + { 0, { 0, 0, 0}}, // ( 34, 25) + { 0, { 0, 0, 0}}, // ( 35, 25) + { 0, { 0, 0, 0}}, // ( 36, 25) + { 0, { 0, 0, 0}}, // ( 37, 25) + { 0, { 0, 0, 0}}, // ( 38, 25) + { 0, { 0, 0, 0}}, // ( 39, 25) + { 0, { 0, 0, 0}}, // ( 40, 25) + { 0, { 0, 0, 0}}, // ( 41, 25) + { 0, { 0, 0, 0}}, // ( 42, 25) + { 0, { 0, 0, 0}}, // ( 43, 25) + { 0, { 0, 0, 0}}, // ( 44, 25) + { 0, { 0, 0, 0}}, // ( 45, 25) + { 0, { 0, 0, 0}}, // ( 46, 25) + { 0, { 0, 0, 0}}, // ( 47, 25) + { 0, { 0, 0, 0}}, // ( 48, 25) + { 0, { 0, 0, 0}}, // ( 49, 25) + { 0, { 0, 0, 0}}, // ( 50, 25) + { 0, { 0, 0, 0}}, // ( 51, 25) + { 0, { 0, 0, 0}}, // ( 52, 25) + { 0, { 0, 0, 0}}, // ( 53, 25) + { 0, { 0, 0, 0}}, // ( 54, 25) + { 0, { 0, 0, 0}}, // ( 55, 25) + { 0, { 0, 0, 0}}, // ( 56, 25) + { 0, { 0, 0, 0}}, // ( 57, 25) + { 0, { 0, 0, 0}}, // ( 58, 25) + { 0, { 0, 0, 0}}, // ( 59, 25) + { 0, { 0, 0, 0}}, // ( 60, 25) + { 0, { 0, 0, 0}}, // ( 61, 25) + { 0, { 0, 0, 0}}, // ( 62, 25) + { 0, { 0, 0, 0}}, // ( 63, 25) + { 0, { 0, 0, 0}}, // ( 64, 25) + { 0, { 0, 0, 0}}, // ( 65, 25) + { 0, { 0, 0, 0}}, // ( 66, 25) + { 0, { 0, 0, 0}}, // ( 67, 25) + { 0, { 0, 0, 0}}, // ( 68, 25) + { 0, { 0, 0, 0}}, // ( 69, 25) + { 0, { 0, 0, 0}}, // ( 70, 25) + { 0, { 0, 0, 0}}, // ( 71, 25) + { 0, { 0, 0, 0}}, // ( 72, 25) + { 0, { 0, 0, 0}}, // ( 73, 25) + { 0, { 0, 0, 0}}, // ( 74, 25) + { 0, { 0, 0, 0}}, // ( 75, 25) + { 0, { 0, 0, 0}}, // ( 76, 25) + { 0, { 0, 0, 0}}, // ( 77, 25) + { 0, { 0, 0, 0}}, // ( 78, 25) + { 0, { 0, 0, 0}}, // ( 79, 25) + { 0, { 0, 0, 0}}, // ( 80, 25) + { 0, { 0, 0, 0}}, // ( 81, 25) + { 0, { 0, 0, 0}}, // ( 82, 25) + { 0, { 0, 0, 0}}, // ( 83, 25) + { 0, { 0, 0, 0}}, // ( 84, 25) + { 0, { 0, 0, 0}}, // ( 85, 25) + { 0, { 0, 0, 0}}, // ( 86, 25) + { 0, { 0, 0, 0}}, // ( 87, 25) + { 0, { 0, 0, 0}}, // ( 88, 25) + { 0, { 0, 0, 0}}, // ( 89, 25) + { 0, { 0, 0, 0}}, // ( 90, 25) + { 0, { 0, 0, 0}}, // ( 91, 25) + { 0, { 0, 0, 0}}, // ( 92, 25) + { 0, { 0, 0, 0}}, // ( 93, 25) + { 0, { 0, 0, 0}}, // ( 94, 25) + { 0, { 0, 0, 0}}, // ( 95, 25) + { 0, { 0, 0, 0}}, // ( 96, 25) + { 0, { 0, 0, 0}}, // ( 97, 25) + { 0, { 0, 0, 0}}, // ( 98, 25) + { 0, { 0, 0, 0}}, // ( 99, 25) + { 0, { 0, 0, 0}}, // (100, 25) + { 0, { 0, 0, 0}}, // (101, 25) + { 0, { 0, 0, 0}}, // (102, 25) + { 0, { 0, 0, 0}}, // (103, 25) + { 0, { 0, 0, 0}}, // (104, 25) + { 0, { 0, 0, 0}}, // (105, 25) + { 0, { 0, 0, 0}}, // (106, 25) + { 0, { 0, 0, 0}}, // (107, 25) + { 0, { 0, 0, 0}}, // (108, 25) + { 0, { 0, 0, 0}}, // (109, 25) + { 0, { 0, 0, 0}}, // (110, 25) + { 0, { 0, 0, 0}}, // (111, 25) + { 0, { 0, 0, 0}}, // (112, 25) + { 0, { 0, 0, 0}}, // (113, 25) + { 0, { 0, 0, 0}}, // (114, 25) + { 0, { 0, 0, 0}}, // (115, 25) + { 0, { 0, 0, 0}}, // (116, 25) + { 0, { 0, 0, 0}}, // (117, 25) + { 0, { 0, 0, 0}}, // (118, 25) + { 0, { 0, 0, 0}}, // (119, 25) + { 0, { 0, 0, 0}}, // (120, 25) + { 0, { 0, 0, 0}}, // (121, 25) + { 0, { 0, 0, 0}}, // (122, 25) + { 0, { 0, 0, 0}}, // (123, 25) + { 0, { 0, 0, 0}}, // (124, 25) + { 0, { 0, 0, 0}}, // (125, 25) + { 0, { 0, 0, 0}}, // (126, 25) + { 0, { 0, 0, 0}}, // (127, 25) + { 0, { 0, 0, 0}}, // (128, 25) + { 0, { 0, 0, 0}}, // (129, 25) + { 0, { 0, 0, 0}}, // (130, 25) + { 0, { 0, 0, 0}}, // (131, 25) + { 0, { 0, 0, 0}}, // (132, 25) + { 0, { 0, 0, 0}}, // (133, 25) + { 0, { 0, 0, 0}}, // (134, 25) + { 0, { 0, 0, 0}}, // (135, 25) + { 0, { 0, 0, 0}}, // (136, 25) + { 0, { 0, 0, 0}}, // (137, 25) + { 0, { 0, 0, 0}}, // (138, 25) + { 0, { 0, 0, 0}}, // (139, 25) + { 0, { 0, 0, 0}}, // (140, 25) + { 0, { 0, 0, 0}}, // (141, 25) + { 0, { 0, 0, 0}}, // (142, 25) + { 0, { 0, 0, 0}}, // (143, 25) + { 0, { 0, 0, 0}}, // (144, 25) + { 0, { 0, 0, 0}}, // (145, 25) + { 0, { 0, 0, 0}}, // (146, 25) + { 0, { 0, 0, 0}}, // (147, 25) + { 0, { 0, 0, 0}}, // (148, 25) + { 29, { 0, 0, 0}}, // (149, 25) + {120, { 0, 0, 0}}, // (150, 25) + {128, { 0, 0, 0}}, // (151, 25) + {128, { 0, 0, 0}}, // (152, 25) + {128, { 0, 0, 0}}, // (153, 25) + {128, { 0, 0, 0}}, // (154, 25) + {128, { 0, 0, 0}}, // (155, 25) + {128, { 0, 0, 0}}, // (156, 25) + {128, { 0, 0, 0}}, // (157, 25) + {128, { 0, 0, 0}}, // (158, 25) + {128, { 0, 0, 0}}, // (159, 25) + {128, { 0, 0, 0}}, // (160, 25) + {128, { 0, 0, 0}}, // (161, 25) + {128, { 0, 0, 0}}, // (162, 25) + {128, { 0, 0, 0}}, // (163, 25) + {128, { 0, 0, 0}}, // (164, 25) + {128, { 0, 0, 0}}, // (165, 25) + {128, { 0, 0, 0}}, // (166, 25) + {128, { 0, 0, 0}}, // (167, 25) + {128, { 0, 0, 0}}, // (168, 25) + {128, { 0, 0, 0}}, // (169, 25) + {128, { 0, 0, 0}}, // (170, 25) + {128, { 0, 0, 0}}, // (171, 25) + {128, { 0, 0, 0}}, // (172, 25) + {128, { 0, 0, 0}}, // (173, 25) + {128, { 0, 0, 0}}, // (174, 25) + {128, { 0, 0, 0}}, // (175, 25) + {128, { 0, 0, 0}}, // (176, 25) + {128, { 0, 0, 0}}, // (177, 25) + {128, { 0, 0, 0}}, // (178, 25) + {128, { 0, 0, 0}}, // (179, 25) + {128, { 0, 0, 0}}, // ( 0, 26) + {128, { 0, 0, 0}}, // ( 1, 26) + {128, { 0, 0, 0}}, // ( 2, 26) + {128, { 0, 0, 0}}, // ( 3, 26) + {128, { 0, 0, 0}}, // ( 4, 26) + {128, { 0, 0, 0}}, // ( 5, 26) + {128, { 0, 0, 0}}, // ( 6, 26) + {128, { 0, 0, 0}}, // ( 7, 26) + {128, { 0, 0, 0}}, // ( 8, 26) + {128, { 0, 0, 0}}, // ( 9, 26) + {128, { 0, 0, 0}}, // ( 10, 26) + {128, { 0, 0, 0}}, // ( 11, 26) + {128, { 0, 0, 0}}, // ( 12, 26) + {128, { 0, 0, 0}}, // ( 13, 26) + {128, { 0, 0, 0}}, // ( 14, 26) + {128, { 0, 0, 0}}, // ( 15, 26) + {128, { 0, 0, 0}}, // ( 16, 26) + {128, { 0, 0, 0}}, // ( 17, 26) + {128, { 0, 0, 0}}, // ( 18, 26) + {128, { 0, 0, 0}}, // ( 19, 26) + {128, { 0, 0, 0}}, // ( 20, 26) + {128, { 0, 0, 0}}, // ( 21, 26) + {128, { 0, 0, 0}}, // ( 22, 26) + {128, { 0, 0, 0}}, // ( 23, 26) + {128, { 0, 0, 0}}, // ( 24, 26) + {128, { 0, 0, 0}}, // ( 25, 26) + {128, { 0, 0, 0}}, // ( 26, 26) + {128, { 0, 0, 0}}, // ( 27, 26) + {118, { 0, 0, 0}}, // ( 28, 26) + { 25, { 0, 0, 0}}, // ( 29, 26) + { 0, { 0, 0, 0}}, // ( 30, 26) + { 0, { 0, 0, 0}}, // ( 31, 26) + { 0, { 0, 0, 0}}, // ( 32, 26) + { 0, { 0, 0, 0}}, // ( 33, 26) + { 0, { 0, 0, 0}}, // ( 34, 26) + { 0, { 0, 0, 0}}, // ( 35, 26) + { 0, { 0, 0, 0}}, // ( 36, 26) + { 0, { 0, 0, 0}}, // ( 37, 26) + { 0, { 0, 0, 0}}, // ( 38, 26) + { 0, { 0, 0, 0}}, // ( 39, 26) + { 0, { 0, 0, 0}}, // ( 40, 26) + { 0, { 0, 0, 0}}, // ( 41, 26) + { 0, { 0, 0, 0}}, // ( 42, 26) + { 0, { 0, 0, 0}}, // ( 43, 26) + { 0, { 0, 0, 0}}, // ( 44, 26) + { 0, { 0, 0, 0}}, // ( 45, 26) + { 0, { 0, 0, 0}}, // ( 46, 26) + { 0, { 0, 0, 0}}, // ( 47, 26) + { 0, { 0, 0, 0}}, // ( 48, 26) + { 0, { 0, 0, 0}}, // ( 49, 26) + { 0, { 0, 0, 0}}, // ( 50, 26) + { 0, { 0, 0, 0}}, // ( 51, 26) + { 0, { 0, 0, 0}}, // ( 52, 26) + { 0, { 0, 0, 0}}, // ( 53, 26) + { 0, { 0, 0, 0}}, // ( 54, 26) + { 0, { 0, 0, 0}}, // ( 55, 26) + { 0, { 0, 0, 0}}, // ( 56, 26) + { 0, { 0, 0, 0}}, // ( 57, 26) + { 0, { 0, 0, 0}}, // ( 58, 26) + { 0, { 0, 0, 0}}, // ( 59, 26) + { 0, { 0, 0, 0}}, // ( 60, 26) + { 0, { 0, 0, 0}}, // ( 61, 26) + { 0, { 0, 0, 0}}, // ( 62, 26) + { 0, { 0, 0, 0}}, // ( 63, 26) + { 0, { 0, 0, 0}}, // ( 64, 26) + { 0, { 0, 0, 0}}, // ( 65, 26) + { 0, { 0, 0, 0}}, // ( 66, 26) + { 0, { 0, 0, 0}}, // ( 67, 26) + { 0, { 0, 0, 0}}, // ( 68, 26) + { 0, { 0, 0, 0}}, // ( 69, 26) + { 0, { 0, 0, 0}}, // ( 70, 26) + { 0, { 0, 0, 0}}, // ( 71, 26) + { 0, { 0, 0, 0}}, // ( 72, 26) + { 0, { 0, 0, 0}}, // ( 73, 26) + { 0, { 0, 0, 0}}, // ( 74, 26) + { 0, { 0, 0, 0}}, // ( 75, 26) + { 0, { 0, 0, 0}}, // ( 76, 26) + { 0, { 0, 0, 0}}, // ( 77, 26) + { 0, { 0, 0, 0}}, // ( 78, 26) + { 0, { 0, 0, 0}}, // ( 79, 26) + { 0, { 0, 0, 0}}, // ( 80, 26) + { 0, { 0, 0, 0}}, // ( 81, 26) + { 0, { 0, 0, 0}}, // ( 82, 26) + { 0, { 0, 0, 0}}, // ( 83, 26) + { 0, { 0, 0, 0}}, // ( 84, 26) + { 0, { 0, 0, 0}}, // ( 85, 26) + { 0, { 0, 0, 0}}, // ( 86, 26) + { 0, { 0, 0, 0}}, // ( 87, 26) + { 0, { 0, 0, 0}}, // ( 88, 26) + { 0, { 0, 0, 0}}, // ( 89, 26) + { 0, { 0, 0, 0}}, // ( 90, 26) + { 0, { 0, 0, 0}}, // ( 91, 26) + { 0, { 0, 0, 0}}, // ( 92, 26) + { 0, { 0, 0, 0}}, // ( 93, 26) + { 0, { 0, 0, 0}}, // ( 94, 26) + { 0, { 0, 0, 0}}, // ( 95, 26) + { 0, { 0, 0, 0}}, // ( 96, 26) + { 0, { 0, 0, 0}}, // ( 97, 26) + { 0, { 0, 0, 0}}, // ( 98, 26) + { 0, { 0, 0, 0}}, // ( 99, 26) + { 0, { 0, 0, 0}}, // (100, 26) + { 0, { 0, 0, 0}}, // (101, 26) + { 0, { 0, 0, 0}}, // (102, 26) + { 0, { 0, 0, 0}}, // (103, 26) + { 0, { 0, 0, 0}}, // (104, 26) + { 0, { 0, 0, 0}}, // (105, 26) + { 0, { 0, 0, 0}}, // (106, 26) + { 0, { 0, 0, 0}}, // (107, 26) + { 0, { 0, 0, 0}}, // (108, 26) + { 0, { 0, 0, 0}}, // (109, 26) + { 0, { 0, 0, 0}}, // (110, 26) + { 0, { 0, 0, 0}}, // (111, 26) + { 0, { 0, 0, 0}}, // (112, 26) + { 0, { 0, 0, 0}}, // (113, 26) + { 0, { 0, 0, 0}}, // (114, 26) + { 0, { 0, 0, 0}}, // (115, 26) + { 0, { 0, 0, 0}}, // (116, 26) + { 0, { 0, 0, 0}}, // (117, 26) + { 0, { 0, 0, 0}}, // (118, 26) + { 0, { 0, 0, 0}}, // (119, 26) + { 0, { 0, 0, 0}}, // (120, 26) + { 0, { 0, 0, 0}}, // (121, 26) + { 0, { 0, 0, 0}}, // (122, 26) + { 0, { 0, 0, 0}}, // (123, 26) + { 0, { 0, 0, 0}}, // (124, 26) + { 0, { 0, 0, 0}}, // (125, 26) + { 0, { 0, 0, 0}}, // (126, 26) + { 0, { 0, 0, 0}}, // (127, 26) + { 0, { 0, 0, 0}}, // (128, 26) + { 0, { 0, 0, 0}}, // (129, 26) + { 0, { 0, 0, 0}}, // (130, 26) + { 0, { 0, 0, 0}}, // (131, 26) + { 0, { 0, 0, 0}}, // (132, 26) + { 0, { 0, 0, 0}}, // (133, 26) + { 0, { 0, 0, 0}}, // (134, 26) + { 0, { 0, 0, 0}}, // (135, 26) + { 0, { 0, 0, 0}}, // (136, 26) + { 0, { 0, 0, 0}}, // (137, 26) + { 0, { 0, 0, 0}}, // (138, 26) + { 0, { 0, 0, 0}}, // (139, 26) + { 0, { 0, 0, 0}}, // (140, 26) + { 0, { 0, 0, 0}}, // (141, 26) + { 0, { 0, 0, 0}}, // (142, 26) + { 0, { 0, 0, 0}}, // (143, 26) + { 0, { 0, 0, 0}}, // (144, 26) + { 0, { 0, 0, 0}}, // (145, 26) + { 0, { 0, 0, 0}}, // (146, 26) + { 0, { 0, 0, 0}}, // (147, 26) + { 0, { 0, 0, 0}}, // (148, 26) + { 0, { 0, 0, 0}}, // (149, 26) + { 25, { 0, 0, 0}}, // (150, 26) + {118, { 0, 0, 0}}, // (151, 26) + {128, { 0, 0, 0}}, // (152, 26) + {128, { 0, 0, 0}}, // (153, 26) + {128, { 0, 0, 0}}, // (154, 26) + {128, { 0, 0, 0}}, // (155, 26) + {128, { 0, 0, 0}}, // (156, 26) + {128, { 0, 0, 0}}, // (157, 26) + {128, { 0, 0, 0}}, // (158, 26) + {128, { 0, 0, 0}}, // (159, 26) + {128, { 0, 0, 0}}, // (160, 26) + {128, { 0, 0, 0}}, // (161, 26) + {128, { 0, 0, 0}}, // (162, 26) + {128, { 0, 0, 0}}, // (163, 26) + {128, { 0, 0, 0}}, // (164, 26) + {128, { 0, 0, 0}}, // (165, 26) + {128, { 0, 0, 0}}, // (166, 26) + {128, { 0, 0, 0}}, // (167, 26) + {128, { 0, 0, 0}}, // (168, 26) + {128, { 0, 0, 0}}, // (169, 26) + {128, { 0, 0, 0}}, // (170, 26) + {128, { 0, 0, 0}}, // (171, 26) + {128, { 0, 0, 0}}, // (172, 26) + {128, { 0, 0, 0}}, // (173, 26) + {128, { 0, 0, 0}}, // (174, 26) + {128, { 0, 0, 0}}, // (175, 26) + {128, { 0, 0, 0}}, // (176, 26) + {128, { 0, 0, 0}}, // (177, 26) + {128, { 0, 0, 0}}, // (178, 26) + {128, { 0, 0, 0}}, // (179, 26) + {128, { 0, 0, 0}}, // ( 0, 27) + {128, { 0, 0, 0}}, // ( 1, 27) + {128, { 0, 0, 0}}, // ( 2, 27) + {128, { 0, 0, 0}}, // ( 3, 27) + {128, { 0, 0, 0}}, // ( 4, 27) + {128, { 0, 0, 0}}, // ( 5, 27) + {128, { 0, 0, 0}}, // ( 6, 27) + {128, { 0, 0, 0}}, // ( 7, 27) + {128, { 0, 0, 0}}, // ( 8, 27) + {128, { 0, 0, 0}}, // ( 9, 27) + {128, { 0, 0, 0}}, // ( 10, 27) + {128, { 0, 0, 0}}, // ( 11, 27) + {128, { 0, 0, 0}}, // ( 12, 27) + {128, { 0, 0, 0}}, // ( 13, 27) + {128, { 0, 0, 0}}, // ( 14, 27) + {128, { 0, 0, 0}}, // ( 15, 27) + {128, { 0, 0, 0}}, // ( 16, 27) + {128, { 0, 0, 0}}, // ( 17, 27) + {128, { 0, 0, 0}}, // ( 18, 27) + {128, { 0, 0, 0}}, // ( 19, 27) + {128, { 0, 0, 0}}, // ( 20, 27) + {128, { 0, 0, 0}}, // ( 21, 27) + {128, { 0, 0, 0}}, // ( 22, 27) + {128, { 0, 0, 0}}, // ( 23, 27) + {128, { 0, 0, 0}}, // ( 24, 27) + {128, { 0, 0, 0}}, // ( 25, 27) + {128, { 0, 0, 0}}, // ( 26, 27) + {115, { 0, 0, 0}}, // ( 27, 27) + { 21, { 0, 0, 0}}, // ( 28, 27) + { 0, { 0, 0, 0}}, // ( 29, 27) + { 0, { 0, 0, 0}}, // ( 30, 27) + { 0, { 0, 0, 0}}, // ( 31, 27) + { 0, { 0, 0, 0}}, // ( 32, 27) + { 0, { 0, 0, 0}}, // ( 33, 27) + { 0, { 0, 0, 0}}, // ( 34, 27) + { 0, { 0, 0, 0}}, // ( 35, 27) + { 0, { 0, 0, 0}}, // ( 36, 27) + { 0, { 0, 0, 0}}, // ( 37, 27) + { 0, { 0, 0, 0}}, // ( 38, 27) + { 0, { 0, 0, 0}}, // ( 39, 27) + { 0, { 0, 0, 0}}, // ( 40, 27) + { 0, { 0, 0, 0}}, // ( 41, 27) + { 0, { 0, 0, 0}}, // ( 42, 27) + { 0, { 0, 0, 0}}, // ( 43, 27) + { 0, { 0, 0, 0}}, // ( 44, 27) + { 0, { 0, 0, 0}}, // ( 45, 27) + { 0, { 0, 0, 0}}, // ( 46, 27) + { 0, { 0, 0, 0}}, // ( 47, 27) + { 0, { 0, 0, 0}}, // ( 48, 27) + { 0, { 0, 0, 0}}, // ( 49, 27) + { 0, { 0, 0, 0}}, // ( 50, 27) + { 0, { 0, 0, 0}}, // ( 51, 27) + { 0, { 0, 0, 0}}, // ( 52, 27) + { 0, { 0, 0, 0}}, // ( 53, 27) + { 0, { 0, 0, 0}}, // ( 54, 27) + { 0, { 0, 0, 0}}, // ( 55, 27) + { 0, { 0, 0, 0}}, // ( 56, 27) + { 0, { 0, 0, 0}}, // ( 57, 27) + { 0, { 0, 0, 0}}, // ( 58, 27) + { 0, { 0, 0, 0}}, // ( 59, 27) + { 0, { 0, 0, 0}}, // ( 60, 27) + { 0, { 0, 0, 0}}, // ( 61, 27) + { 0, { 0, 0, 0}}, // ( 62, 27) + { 0, { 0, 0, 0}}, // ( 63, 27) + { 0, { 0, 0, 0}}, // ( 64, 27) + { 0, { 0, 0, 0}}, // ( 65, 27) + { 0, { 0, 0, 0}}, // ( 66, 27) + { 0, { 0, 0, 0}}, // ( 67, 27) + { 0, { 0, 0, 0}}, // ( 68, 27) + { 0, { 0, 0, 0}}, // ( 69, 27) + { 0, { 0, 0, 0}}, // ( 70, 27) + { 0, { 0, 0, 0}}, // ( 71, 27) + { 0, { 0, 0, 0}}, // ( 72, 27) + { 0, { 0, 0, 0}}, // ( 73, 27) + { 0, { 0, 0, 0}}, // ( 74, 27) + { 0, { 0, 0, 0}}, // ( 75, 27) + { 0, { 0, 0, 0}}, // ( 76, 27) + { 0, { 0, 0, 0}}, // ( 77, 27) + { 0, { 0, 0, 0}}, // ( 78, 27) + { 0, { 0, 0, 0}}, // ( 79, 27) + { 0, { 0, 0, 0}}, // ( 80, 27) + { 0, { 0, 0, 0}}, // ( 81, 27) + { 0, { 0, 0, 0}}, // ( 82, 27) + { 0, { 0, 0, 0}}, // ( 83, 27) + { 0, { 0, 0, 0}}, // ( 84, 27) + { 0, { 0, 0, 0}}, // ( 85, 27) + { 0, { 0, 0, 0}}, // ( 86, 27) + { 0, { 0, 0, 0}}, // ( 87, 27) + { 0, { 0, 0, 0}}, // ( 88, 27) + { 0, { 0, 0, 0}}, // ( 89, 27) + { 0, { 0, 0, 0}}, // ( 90, 27) + { 0, { 0, 0, 0}}, // ( 91, 27) + { 0, { 0, 0, 0}}, // ( 92, 27) + { 0, { 0, 0, 0}}, // ( 93, 27) + { 0, { 0, 0, 0}}, // ( 94, 27) + { 0, { 0, 0, 0}}, // ( 95, 27) + { 0, { 0, 0, 0}}, // ( 96, 27) + { 0, { 0, 0, 0}}, // ( 97, 27) + { 0, { 0, 0, 0}}, // ( 98, 27) + { 0, { 0, 0, 0}}, // ( 99, 27) + { 0, { 0, 0, 0}}, // (100, 27) + { 0, { 0, 0, 0}}, // (101, 27) + { 0, { 0, 0, 0}}, // (102, 27) + { 0, { 0, 0, 0}}, // (103, 27) + { 0, { 0, 0, 0}}, // (104, 27) + { 0, { 0, 0, 0}}, // (105, 27) + { 0, { 0, 0, 0}}, // (106, 27) + { 0, { 0, 0, 0}}, // (107, 27) + { 0, { 0, 0, 0}}, // (108, 27) + { 0, { 0, 0, 0}}, // (109, 27) + { 0, { 0, 0, 0}}, // (110, 27) + { 0, { 0, 0, 0}}, // (111, 27) + { 0, { 0, 0, 0}}, // (112, 27) + { 0, { 0, 0, 0}}, // (113, 27) + { 0, { 0, 0, 0}}, // (114, 27) + { 0, { 0, 0, 0}}, // (115, 27) + { 0, { 0, 0, 0}}, // (116, 27) + { 0, { 0, 0, 0}}, // (117, 27) + { 0, { 0, 0, 0}}, // (118, 27) + { 0, { 0, 0, 0}}, // (119, 27) + { 0, { 0, 0, 0}}, // (120, 27) + { 0, { 0, 0, 0}}, // (121, 27) + { 0, { 0, 0, 0}}, // (122, 27) + { 0, { 0, 0, 0}}, // (123, 27) + { 0, { 0, 0, 0}}, // (124, 27) + { 0, { 0, 0, 0}}, // (125, 27) + { 0, { 0, 0, 0}}, // (126, 27) + { 0, { 0, 0, 0}}, // (127, 27) + { 0, { 0, 0, 0}}, // (128, 27) + { 0, { 0, 0, 0}}, // (129, 27) + { 0, { 0, 0, 0}}, // (130, 27) + { 0, { 0, 0, 0}}, // (131, 27) + { 0, { 0, 0, 0}}, // (132, 27) + { 0, { 0, 0, 0}}, // (133, 27) + { 0, { 0, 0, 0}}, // (134, 27) + { 0, { 0, 0, 0}}, // (135, 27) + { 0, { 0, 0, 0}}, // (136, 27) + { 0, { 0, 0, 0}}, // (137, 27) + { 0, { 0, 0, 0}}, // (138, 27) + { 0, { 0, 0, 0}}, // (139, 27) + { 0, { 0, 0, 0}}, // (140, 27) + { 0, { 0, 0, 0}}, // (141, 27) + { 0, { 0, 0, 0}}, // (142, 27) + { 0, { 0, 0, 0}}, // (143, 27) + { 0, { 0, 0, 0}}, // (144, 27) + { 0, { 0, 0, 0}}, // (145, 27) + { 0, { 0, 0, 0}}, // (146, 27) + { 0, { 0, 0, 0}}, // (147, 27) + { 0, { 0, 0, 0}}, // (148, 27) + { 0, { 0, 0, 0}}, // (149, 27) + { 0, { 0, 0, 0}}, // (150, 27) + { 21, { 0, 0, 0}}, // (151, 27) + {115, { 0, 0, 0}}, // (152, 27) + {128, { 0, 0, 0}}, // (153, 27) + {128, { 0, 0, 0}}, // (154, 27) + {128, { 0, 0, 0}}, // (155, 27) + {128, { 0, 0, 0}}, // (156, 27) + {128, { 0, 0, 0}}, // (157, 27) + {128, { 0, 0, 0}}, // (158, 27) + {128, { 0, 0, 0}}, // (159, 27) + {128, { 0, 0, 0}}, // (160, 27) + {128, { 0, 0, 0}}, // (161, 27) + {128, { 0, 0, 0}}, // (162, 27) + {128, { 0, 0, 0}}, // (163, 27) + {128, { 0, 0, 0}}, // (164, 27) + {128, { 0, 0, 0}}, // (165, 27) + {128, { 0, 0, 0}}, // (166, 27) + {128, { 0, 0, 0}}, // (167, 27) + {128, { 0, 0, 0}}, // (168, 27) + {128, { 0, 0, 0}}, // (169, 27) + {128, { 0, 0, 0}}, // (170, 27) + {128, { 0, 0, 0}}, // (171, 27) + {128, { 0, 0, 0}}, // (172, 27) + {128, { 0, 0, 0}}, // (173, 27) + {128, { 0, 0, 0}}, // (174, 27) + {128, { 0, 0, 0}}, // (175, 27) + {128, { 0, 0, 0}}, // (176, 27) + {128, { 0, 0, 0}}, // (177, 27) + {128, { 0, 0, 0}}, // (178, 27) + {128, { 0, 0, 0}}, // (179, 27) + {128, { 0, 0, 0}}, // ( 0, 28) + {128, { 0, 0, 0}}, // ( 1, 28) + {128, { 0, 0, 0}}, // ( 2, 28) + {128, { 0, 0, 0}}, // ( 3, 28) + {128, { 0, 0, 0}}, // ( 4, 28) + {128, { 0, 0, 0}}, // ( 5, 28) + {128, { 0, 0, 0}}, // ( 6, 28) + {128, { 0, 0, 0}}, // ( 7, 28) + {128, { 0, 0, 0}}, // ( 8, 28) + {128, { 0, 0, 0}}, // ( 9, 28) + {128, { 0, 0, 0}}, // ( 10, 28) + {128, { 0, 0, 0}}, // ( 11, 28) + {128, { 0, 0, 0}}, // ( 12, 28) + {128, { 0, 0, 0}}, // ( 13, 28) + {128, { 0, 0, 0}}, // ( 14, 28) + {128, { 0, 0, 0}}, // ( 15, 28) + {128, { 0, 0, 0}}, // ( 16, 28) + {128, { 0, 0, 0}}, // ( 17, 28) + {128, { 0, 0, 0}}, // ( 18, 28) + {128, { 0, 0, 0}}, // ( 19, 28) + {128, { 0, 0, 0}}, // ( 20, 28) + {128, { 0, 0, 0}}, // ( 21, 28) + {128, { 0, 0, 0}}, // ( 22, 28) + {128, { 0, 0, 0}}, // ( 23, 28) + {128, { 0, 0, 0}}, // ( 24, 28) + {128, { 0, 0, 0}}, // ( 25, 28) + {117, { 0, 0, 0}}, // ( 26, 28) + { 22, { 0, 0, 0}}, // ( 27, 28) + { 0, { 0, 0, 0}}, // ( 28, 28) + { 0, { 0, 0, 0}}, // ( 29, 28) + { 0, { 0, 0, 0}}, // ( 30, 28) + { 0, { 0, 0, 0}}, // ( 31, 28) + { 0, { 0, 0, 0}}, // ( 32, 28) + { 0, { 0, 0, 0}}, // ( 33, 28) + { 0, { 0, 0, 0}}, // ( 34, 28) + { 0, { 0, 0, 0}}, // ( 35, 28) + { 0, { 0, 0, 0}}, // ( 36, 28) + { 0, { 0, 0, 0}}, // ( 37, 28) + { 0, { 0, 0, 0}}, // ( 38, 28) + { 0, { 0, 0, 0}}, // ( 39, 28) + { 0, { 0, 0, 0}}, // ( 40, 28) + { 0, { 0, 0, 0}}, // ( 41, 28) + { 0, { 0, 0, 0}}, // ( 42, 28) + { 0, { 0, 0, 0}}, // ( 43, 28) + { 0, { 0, 0, 0}}, // ( 44, 28) + { 0, { 0, 0, 0}}, // ( 45, 28) + { 0, { 0, 0, 0}}, // ( 46, 28) + { 0, { 0, 0, 0}}, // ( 47, 28) + { 0, { 0, 0, 0}}, // ( 48, 28) + { 0, { 0, 0, 0}}, // ( 49, 28) + { 0, { 0, 0, 0}}, // ( 50, 28) + { 0, { 0, 0, 0}}, // ( 51, 28) + { 0, { 0, 0, 0}}, // ( 52, 28) + { 0, { 0, 0, 0}}, // ( 53, 28) + { 0, { 0, 0, 0}}, // ( 54, 28) + { 0, { 0, 0, 0}}, // ( 55, 28) + { 0, { 0, 0, 0}}, // ( 56, 28) + { 0, { 0, 0, 0}}, // ( 57, 28) + { 0, { 0, 0, 0}}, // ( 58, 28) + { 0, { 0, 0, 0}}, // ( 59, 28) + { 0, { 0, 0, 0}}, // ( 60, 28) + { 0, { 0, 0, 0}}, // ( 61, 28) + { 0, { 0, 0, 0}}, // ( 62, 28) + { 0, { 0, 0, 0}}, // ( 63, 28) + { 0, { 0, 0, 0}}, // ( 64, 28) + { 0, { 0, 0, 0}}, // ( 65, 28) + { 0, { 0, 0, 0}}, // ( 66, 28) + { 0, { 0, 0, 0}}, // ( 67, 28) + { 0, { 0, 0, 0}}, // ( 68, 28) + { 0, { 0, 0, 0}}, // ( 69, 28) + { 0, { 0, 0, 0}}, // ( 70, 28) + { 0, { 0, 0, 0}}, // ( 71, 28) + { 0, { 0, 0, 0}}, // ( 72, 28) + { 0, { 0, 0, 0}}, // ( 73, 28) + { 0, { 0, 0, 0}}, // ( 74, 28) + { 0, { 0, 0, 0}}, // ( 75, 28) + { 0, { 0, 0, 0}}, // ( 76, 28) + { 0, { 0, 0, 0}}, // ( 77, 28) + { 0, { 0, 0, 0}}, // ( 78, 28) + { 0, { 0, 0, 0}}, // ( 79, 28) + { 0, { 0, 0, 0}}, // ( 80, 28) + { 0, { 0, 0, 0}}, // ( 81, 28) + { 0, { 0, 0, 0}}, // ( 82, 28) + { 0, { 0, 0, 0}}, // ( 83, 28) + { 0, { 0, 0, 0}}, // ( 84, 28) + { 0, { 0, 0, 0}}, // ( 85, 28) + { 0, { 0, 0, 0}}, // ( 86, 28) + { 0, { 0, 0, 0}}, // ( 87, 28) + { 0, { 0, 0, 0}}, // ( 88, 28) + { 0, { 0, 0, 0}}, // ( 89, 28) + { 0, { 0, 0, 0}}, // ( 90, 28) + { 0, { 0, 0, 0}}, // ( 91, 28) + { 0, { 0, 0, 0}}, // ( 92, 28) + { 0, { 0, 0, 0}}, // ( 93, 28) + { 0, { 0, 0, 0}}, // ( 94, 28) + { 0, { 0, 0, 0}}, // ( 95, 28) + { 0, { 0, 0, 0}}, // ( 96, 28) + { 0, { 0, 0, 0}}, // ( 97, 28) + { 0, { 0, 0, 0}}, // ( 98, 28) + { 0, { 0, 0, 0}}, // ( 99, 28) + { 0, { 0, 0, 0}}, // (100, 28) + { 0, { 0, 0, 0}}, // (101, 28) + { 0, { 0, 0, 0}}, // (102, 28) + { 0, { 0, 0, 0}}, // (103, 28) + { 0, { 0, 0, 0}}, // (104, 28) + { 0, { 0, 0, 0}}, // (105, 28) + { 0, { 0, 0, 0}}, // (106, 28) + { 0, { 0, 0, 0}}, // (107, 28) + { 0, { 0, 0, 0}}, // (108, 28) + { 0, { 0, 0, 0}}, // (109, 28) + { 0, { 0, 0, 0}}, // (110, 28) + { 0, { 0, 0, 0}}, // (111, 28) + { 0, { 0, 0, 0}}, // (112, 28) + { 0, { 0, 0, 0}}, // (113, 28) + { 0, { 0, 0, 0}}, // (114, 28) + { 0, { 0, 0, 0}}, // (115, 28) + { 0, { 0, 0, 0}}, // (116, 28) + { 0, { 0, 0, 0}}, // (117, 28) + { 0, { 0, 0, 0}}, // (118, 28) + { 0, { 0, 0, 0}}, // (119, 28) + { 0, { 0, 0, 0}}, // (120, 28) + { 0, { 0, 0, 0}}, // (121, 28) + { 0, { 0, 0, 0}}, // (122, 28) + { 0, { 0, 0, 0}}, // (123, 28) + { 0, { 0, 0, 0}}, // (124, 28) + { 0, { 0, 0, 0}}, // (125, 28) + { 0, { 0, 0, 0}}, // (126, 28) + { 0, { 0, 0, 0}}, // (127, 28) + { 0, { 0, 0, 0}}, // (128, 28) + { 0, { 0, 0, 0}}, // (129, 28) + { 0, { 0, 0, 0}}, // (130, 28) + { 0, { 0, 0, 0}}, // (131, 28) + { 0, { 0, 0, 0}}, // (132, 28) + { 0, { 0, 0, 0}}, // (133, 28) + { 0, { 0, 0, 0}}, // (134, 28) + { 0, { 0, 0, 0}}, // (135, 28) + { 0, { 0, 0, 0}}, // (136, 28) + { 0, { 0, 0, 0}}, // (137, 28) + { 0, { 0, 0, 0}}, // (138, 28) + { 0, { 0, 0, 0}}, // (139, 28) + { 0, { 0, 0, 0}}, // (140, 28) + { 0, { 0, 0, 0}}, // (141, 28) + { 0, { 0, 0, 0}}, // (142, 28) + { 0, { 0, 0, 0}}, // (143, 28) + { 0, { 0, 0, 0}}, // (144, 28) + { 0, { 0, 0, 0}}, // (145, 28) + { 0, { 0, 0, 0}}, // (146, 28) + { 0, { 0, 0, 0}}, // (147, 28) + { 0, { 0, 0, 0}}, // (148, 28) + { 0, { 0, 0, 0}}, // (149, 28) + { 0, { 0, 0, 0}}, // (150, 28) + { 0, { 0, 0, 0}}, // (151, 28) + { 22, { 0, 0, 0}}, // (152, 28) + {117, { 0, 0, 0}}, // (153, 28) + {128, { 0, 0, 0}}, // (154, 28) + {128, { 0, 0, 0}}, // (155, 28) + {128, { 0, 0, 0}}, // (156, 28) + {128, { 0, 0, 0}}, // (157, 28) + {128, { 0, 0, 0}}, // (158, 28) + {128, { 0, 0, 0}}, // (159, 28) + {128, { 0, 0, 0}}, // (160, 28) + {128, { 0, 0, 0}}, // (161, 28) + {128, { 0, 0, 0}}, // (162, 28) + {128, { 0, 0, 0}}, // (163, 28) + {128, { 0, 0, 0}}, // (164, 28) + {128, { 0, 0, 0}}, // (165, 28) + {128, { 0, 0, 0}}, // (166, 28) + {128, { 0, 0, 0}}, // (167, 28) + {128, { 0, 0, 0}}, // (168, 28) + {128, { 0, 0, 0}}, // (169, 28) + {128, { 0, 0, 0}}, // (170, 28) + {128, { 0, 0, 0}}, // (171, 28) + {128, { 0, 0, 0}}, // (172, 28) + {128, { 0, 0, 0}}, // (173, 28) + {128, { 0, 0, 0}}, // (174, 28) + {128, { 0, 0, 0}}, // (175, 28) + {128, { 0, 0, 0}}, // (176, 28) + {128, { 0, 0, 0}}, // (177, 28) + {128, { 0, 0, 0}}, // (178, 28) + {128, { 0, 0, 0}}, // (179, 28) + {128, { 0, 0, 0}}, // ( 0, 29) + {128, { 0, 0, 0}}, // ( 1, 29) + {128, { 0, 0, 0}}, // ( 2, 29) + {128, { 0, 0, 0}}, // ( 3, 29) + {128, { 0, 0, 0}}, // ( 4, 29) + {128, { 0, 0, 0}}, // ( 5, 29) + {128, { 0, 0, 0}}, // ( 6, 29) + {128, { 0, 0, 0}}, // ( 7, 29) + {128, { 0, 0, 0}}, // ( 8, 29) + {128, { 0, 0, 0}}, // ( 9, 29) + {128, { 0, 0, 0}}, // ( 10, 29) + {128, { 0, 0, 0}}, // ( 11, 29) + {128, { 0, 0, 0}}, // ( 12, 29) + {128, { 0, 0, 0}}, // ( 13, 29) + {128, { 0, 0, 0}}, // ( 14, 29) + {128, { 0, 0, 0}}, // ( 15, 29) + {128, { 0, 0, 0}}, // ( 16, 29) + {128, { 0, 0, 0}}, // ( 17, 29) + {128, { 0, 0, 0}}, // ( 18, 29) + {128, { 0, 0, 0}}, // ( 19, 29) + {128, { 0, 0, 0}}, // ( 20, 29) + {128, { 0, 0, 0}}, // ( 21, 29) + {128, { 0, 0, 0}}, // ( 22, 29) + {128, { 0, 0, 0}}, // ( 23, 29) + {128, { 0, 0, 0}}, // ( 24, 29) + {120, { 0, 0, 0}}, // ( 25, 29) + { 25, { 0, 0, 0}}, // ( 26, 29) + { 0, { 0, 0, 0}}, // ( 27, 29) + { 0, { 0, 0, 0}}, // ( 28, 29) + { 0, { 0, 0, 0}}, // ( 29, 29) + { 0, { 0, 0, 0}}, // ( 30, 29) + { 0, { 0, 0, 0}}, // ( 31, 29) + { 0, { 0, 0, 0}}, // ( 32, 29) + { 0, { 0, 0, 0}}, // ( 33, 29) + { 0, { 0, 0, 0}}, // ( 34, 29) + { 0, { 0, 0, 0}}, // ( 35, 29) + { 0, { 0, 0, 0}}, // ( 36, 29) + { 0, { 0, 0, 0}}, // ( 37, 29) + { 0, { 0, 0, 0}}, // ( 38, 29) + { 0, { 0, 0, 0}}, // ( 39, 29) + { 0, { 0, 0, 0}}, // ( 40, 29) + { 0, { 0, 0, 0}}, // ( 41, 29) + { 0, { 0, 0, 0}}, // ( 42, 29) + { 0, { 0, 0, 0}}, // ( 43, 29) + { 0, { 0, 0, 0}}, // ( 44, 29) + { 0, { 0, 0, 0}}, // ( 45, 29) + { 0, { 0, 0, 0}}, // ( 46, 29) + { 0, { 0, 0, 0}}, // ( 47, 29) + { 0, { 0, 0, 0}}, // ( 48, 29) + { 0, { 0, 0, 0}}, // ( 49, 29) + { 0, { 0, 0, 0}}, // ( 50, 29) + { 0, { 0, 0, 0}}, // ( 51, 29) + { 0, { 0, 0, 0}}, // ( 52, 29) + { 0, { 0, 0, 0}}, // ( 53, 29) + { 0, { 0, 0, 0}}, // ( 54, 29) + { 0, { 0, 0, 0}}, // ( 55, 29) + { 0, { 0, 0, 0}}, // ( 56, 29) + { 0, { 0, 0, 0}}, // ( 57, 29) + { 0, { 0, 0, 0}}, // ( 58, 29) + { 0, { 0, 0, 0}}, // ( 59, 29) + { 0, { 0, 0, 0}}, // ( 60, 29) + { 0, { 0, 0, 0}}, // ( 61, 29) + { 0, { 0, 0, 0}}, // ( 62, 29) + { 0, { 0, 0, 0}}, // ( 63, 29) + { 0, { 0, 0, 0}}, // ( 64, 29) + { 0, { 0, 0, 0}}, // ( 65, 29) + { 0, { 0, 0, 0}}, // ( 66, 29) + { 0, { 0, 0, 0}}, // ( 67, 29) + { 0, { 0, 0, 0}}, // ( 68, 29) + { 0, { 0, 0, 0}}, // ( 69, 29) + { 0, { 0, 0, 0}}, // ( 70, 29) + { 0, { 0, 0, 0}}, // ( 71, 29) + { 0, { 0, 0, 0}}, // ( 72, 29) + { 0, { 0, 0, 0}}, // ( 73, 29) + { 0, { 0, 0, 0}}, // ( 74, 29) + { 0, { 0, 0, 0}}, // ( 75, 29) + { 0, { 0, 0, 0}}, // ( 76, 29) + { 0, { 0, 0, 0}}, // ( 77, 29) + { 0, { 0, 0, 0}}, // ( 78, 29) + { 0, { 0, 0, 0}}, // ( 79, 29) + { 0, { 0, 0, 0}}, // ( 80, 29) + { 0, { 0, 0, 0}}, // ( 81, 29) + { 0, { 0, 0, 0}}, // ( 82, 29) + { 0, { 0, 0, 0}}, // ( 83, 29) + { 0, { 0, 0, 0}}, // ( 84, 29) + { 0, { 0, 0, 0}}, // ( 85, 29) + { 0, { 0, 0, 0}}, // ( 86, 29) + { 0, { 0, 0, 0}}, // ( 87, 29) + { 0, { 0, 0, 0}}, // ( 88, 29) + { 0, { 0, 0, 0}}, // ( 89, 29) + { 0, { 0, 0, 0}}, // ( 90, 29) + { 0, { 0, 0, 0}}, // ( 91, 29) + { 0, { 0, 0, 0}}, // ( 92, 29) + { 0, { 0, 0, 0}}, // ( 93, 29) + { 0, { 0, 0, 0}}, // ( 94, 29) + { 0, { 0, 0, 0}}, // ( 95, 29) + { 0, { 0, 0, 0}}, // ( 96, 29) + { 0, { 0, 0, 0}}, // ( 97, 29) + { 0, { 0, 0, 0}}, // ( 98, 29) + { 0, { 0, 0, 0}}, // ( 99, 29) + { 0, { 0, 0, 0}}, // (100, 29) + { 0, { 0, 0, 0}}, // (101, 29) + { 0, { 0, 0, 0}}, // (102, 29) + { 0, { 0, 0, 0}}, // (103, 29) + { 0, { 0, 0, 0}}, // (104, 29) + { 0, { 0, 0, 0}}, // (105, 29) + { 0, { 0, 0, 0}}, // (106, 29) + { 0, { 0, 0, 0}}, // (107, 29) + { 0, { 0, 0, 0}}, // (108, 29) + { 0, { 0, 0, 0}}, // (109, 29) + { 0, { 0, 0, 0}}, // (110, 29) + { 0, { 0, 0, 0}}, // (111, 29) + { 0, { 0, 0, 0}}, // (112, 29) + { 0, { 0, 0, 0}}, // (113, 29) + { 0, { 0, 0, 0}}, // (114, 29) + { 0, { 0, 0, 0}}, // (115, 29) + { 0, { 0, 0, 0}}, // (116, 29) + { 0, { 0, 0, 0}}, // (117, 29) + { 0, { 0, 0, 0}}, // (118, 29) + { 0, { 0, 0, 0}}, // (119, 29) + { 0, { 0, 0, 0}}, // (120, 29) + { 0, { 0, 0, 0}}, // (121, 29) + { 0, { 0, 0, 0}}, // (122, 29) + { 0, { 0, 0, 0}}, // (123, 29) + { 0, { 0, 0, 0}}, // (124, 29) + { 0, { 0, 0, 0}}, // (125, 29) + { 0, { 0, 0, 0}}, // (126, 29) + { 0, { 0, 0, 0}}, // (127, 29) + { 0, { 0, 0, 0}}, // (128, 29) + { 0, { 0, 0, 0}}, // (129, 29) + { 0, { 0, 0, 0}}, // (130, 29) + { 0, { 0, 0, 0}}, // (131, 29) + { 0, { 0, 0, 0}}, // (132, 29) + { 0, { 0, 0, 0}}, // (133, 29) + { 0, { 0, 0, 0}}, // (134, 29) + { 0, { 0, 0, 0}}, // (135, 29) + { 0, { 0, 0, 0}}, // (136, 29) + { 0, { 0, 0, 0}}, // (137, 29) + { 0, { 0, 0, 0}}, // (138, 29) + { 0, { 0, 0, 0}}, // (139, 29) + { 0, { 0, 0, 0}}, // (140, 29) + { 0, { 0, 0, 0}}, // (141, 29) + { 0, { 0, 0, 0}}, // (142, 29) + { 0, { 0, 0, 0}}, // (143, 29) + { 0, { 0, 0, 0}}, // (144, 29) + { 0, { 0, 0, 0}}, // (145, 29) + { 0, { 0, 0, 0}}, // (146, 29) + { 0, { 0, 0, 0}}, // (147, 29) + { 0, { 0, 0, 0}}, // (148, 29) + { 0, { 0, 0, 0}}, // (149, 29) + { 0, { 0, 0, 0}}, // (150, 29) + { 0, { 0, 0, 0}}, // (151, 29) + { 0, { 0, 0, 0}}, // (152, 29) + { 25, { 0, 0, 0}}, // (153, 29) + {120, { 0, 0, 0}}, // (154, 29) + {128, { 0, 0, 0}}, // (155, 29) + {128, { 0, 0, 0}}, // (156, 29) + {128, { 0, 0, 0}}, // (157, 29) + {128, { 0, 0, 0}}, // (158, 29) + {128, { 0, 0, 0}}, // (159, 29) + {128, { 0, 0, 0}}, // (160, 29) + {128, { 0, 0, 0}}, // (161, 29) + {128, { 0, 0, 0}}, // (162, 29) + {128, { 0, 0, 0}}, // (163, 29) + {128, { 0, 0, 0}}, // (164, 29) + {128, { 0, 0, 0}}, // (165, 29) + {128, { 0, 0, 0}}, // (166, 29) + {128, { 0, 0, 0}}, // (167, 29) + {128, { 0, 0, 0}}, // (168, 29) + {128, { 0, 0, 0}}, // (169, 29) + {128, { 0, 0, 0}}, // (170, 29) + {128, { 0, 0, 0}}, // (171, 29) + {128, { 0, 0, 0}}, // (172, 29) + {128, { 0, 0, 0}}, // (173, 29) + {128, { 0, 0, 0}}, // (174, 29) + {128, { 0, 0, 0}}, // (175, 29) + {128, { 0, 0, 0}}, // (176, 29) + {128, { 0, 0, 0}}, // (177, 29) + {128, { 0, 0, 0}}, // (178, 29) + {128, { 0, 0, 0}}, // (179, 29) + {128, { 0, 0, 0}}, // ( 0, 30) + {128, { 0, 0, 0}}, // ( 1, 30) + {128, { 0, 0, 0}}, // ( 2, 30) + {128, { 0, 0, 0}}, // ( 3, 30) + {128, { 0, 0, 0}}, // ( 4, 30) + {128, { 0, 0, 0}}, // ( 5, 30) + {128, { 0, 0, 0}}, // ( 6, 30) + {128, { 0, 0, 0}}, // ( 7, 30) + {128, { 0, 0, 0}}, // ( 8, 30) + {128, { 0, 0, 0}}, // ( 9, 30) + {128, { 0, 0, 0}}, // ( 10, 30) + {128, { 0, 0, 0}}, // ( 11, 30) + {128, { 0, 0, 0}}, // ( 12, 30) + {128, { 0, 0, 0}}, // ( 13, 30) + {128, { 0, 0, 0}}, // ( 14, 30) + {128, { 0, 0, 0}}, // ( 15, 30) + {128, { 0, 0, 0}}, // ( 16, 30) + {128, { 0, 0, 0}}, // ( 17, 30) + {128, { 0, 0, 0}}, // ( 18, 30) + {128, { 0, 0, 0}}, // ( 19, 30) + {128, { 0, 0, 0}}, // ( 20, 30) + {128, { 0, 0, 0}}, // ( 21, 30) + {128, { 0, 0, 0}}, // ( 22, 30) + {128, { 0, 0, 0}}, // ( 23, 30) + {123, { 0, 0, 0}}, // ( 24, 30) + { 28, { 0, 0, 0}}, // ( 25, 30) + { 0, { 0, 0, 0}}, // ( 26, 30) + { 0, { 0, 0, 0}}, // ( 27, 30) + { 0, { 0, 0, 0}}, // ( 28, 30) + { 0, { 0, 0, 0}}, // ( 29, 30) + { 0, { 0, 0, 0}}, // ( 30, 30) + { 0, { 0, 0, 0}}, // ( 31, 30) + { 0, { 0, 0, 0}}, // ( 32, 30) + { 0, { 0, 0, 0}}, // ( 33, 30) + { 0, { 0, 0, 0}}, // ( 34, 30) + { 0, { 0, 0, 0}}, // ( 35, 30) + { 0, { 0, 0, 0}}, // ( 36, 30) + { 0, { 0, 0, 0}}, // ( 37, 30) + { 0, { 0, 0, 0}}, // ( 38, 30) + { 0, { 0, 0, 0}}, // ( 39, 30) + { 0, { 0, 0, 0}}, // ( 40, 30) + { 0, { 0, 0, 0}}, // ( 41, 30) + { 0, { 0, 0, 0}}, // ( 42, 30) + { 0, { 0, 0, 0}}, // ( 43, 30) + { 0, { 0, 0, 0}}, // ( 44, 30) + { 0, { 0, 0, 0}}, // ( 45, 30) + { 0, { 0, 0, 0}}, // ( 46, 30) + { 0, { 0, 0, 0}}, // ( 47, 30) + { 0, { 0, 0, 0}}, // ( 48, 30) + { 0, { 0, 0, 0}}, // ( 49, 30) + { 0, { 0, 0, 0}}, // ( 50, 30) + { 0, { 0, 0, 0}}, // ( 51, 30) + { 0, { 0, 0, 0}}, // ( 52, 30) + { 0, { 0, 0, 0}}, // ( 53, 30) + { 0, { 0, 0, 0}}, // ( 54, 30) + { 0, { 0, 0, 0}}, // ( 55, 30) + { 0, { 0, 0, 0}}, // ( 56, 30) + { 0, { 0, 0, 0}}, // ( 57, 30) + { 0, { 0, 0, 0}}, // ( 58, 30) + { 0, { 0, 0, 0}}, // ( 59, 30) + { 0, { 0, 0, 0}}, // ( 60, 30) + { 0, { 0, 0, 0}}, // ( 61, 30) + { 0, { 0, 0, 0}}, // ( 62, 30) + { 0, { 0, 0, 0}}, // ( 63, 30) + { 0, { 0, 0, 0}}, // ( 64, 30) + { 0, { 0, 0, 0}}, // ( 65, 30) + { 0, { 0, 0, 0}}, // ( 66, 30) + { 0, { 0, 0, 0}}, // ( 67, 30) + { 0, { 0, 0, 0}}, // ( 68, 30) + { 0, { 0, 0, 0}}, // ( 69, 30) + { 0, { 0, 0, 0}}, // ( 70, 30) + { 0, { 0, 0, 0}}, // ( 71, 30) + { 0, { 0, 0, 0}}, // ( 72, 30) + { 0, { 0, 0, 0}}, // ( 73, 30) + { 0, { 0, 0, 0}}, // ( 74, 30) + { 0, { 0, 0, 0}}, // ( 75, 30) + { 0, { 0, 0, 0}}, // ( 76, 30) + { 0, { 0, 0, 0}}, // ( 77, 30) + { 0, { 0, 0, 0}}, // ( 78, 30) + { 0, { 0, 0, 0}}, // ( 79, 30) + { 0, { 0, 0, 0}}, // ( 80, 30) + { 0, { 0, 0, 0}}, // ( 81, 30) + { 0, { 0, 0, 0}}, // ( 82, 30) + { 0, { 0, 0, 0}}, // ( 83, 30) + { 0, { 0, 0, 0}}, // ( 84, 30) + { 0, { 0, 0, 0}}, // ( 85, 30) + { 0, { 0, 0, 0}}, // ( 86, 30) + { 0, { 0, 0, 0}}, // ( 87, 30) + { 0, { 0, 0, 0}}, // ( 88, 30) + { 0, { 0, 0, 0}}, // ( 89, 30) + { 0, { 0, 0, 0}}, // ( 90, 30) + { 0, { 0, 0, 0}}, // ( 91, 30) + { 0, { 0, 0, 0}}, // ( 92, 30) + { 0, { 0, 0, 0}}, // ( 93, 30) + { 0, { 0, 0, 0}}, // ( 94, 30) + { 0, { 0, 0, 0}}, // ( 95, 30) + { 0, { 0, 0, 0}}, // ( 96, 30) + { 0, { 0, 0, 0}}, // ( 97, 30) + { 0, { 0, 0, 0}}, // ( 98, 30) + { 0, { 0, 0, 0}}, // ( 99, 30) + { 0, { 0, 0, 0}}, // (100, 30) + { 0, { 0, 0, 0}}, // (101, 30) + { 0, { 0, 0, 0}}, // (102, 30) + { 0, { 0, 0, 0}}, // (103, 30) + { 0, { 0, 0, 0}}, // (104, 30) + { 0, { 0, 0, 0}}, // (105, 30) + { 0, { 0, 0, 0}}, // (106, 30) + { 0, { 0, 0, 0}}, // (107, 30) + { 0, { 0, 0, 0}}, // (108, 30) + { 0, { 0, 0, 0}}, // (109, 30) + { 0, { 0, 0, 0}}, // (110, 30) + { 0, { 0, 0, 0}}, // (111, 30) + { 0, { 0, 0, 0}}, // (112, 30) + { 0, { 0, 0, 0}}, // (113, 30) + { 0, { 0, 0, 0}}, // (114, 30) + { 0, { 0, 0, 0}}, // (115, 30) + { 0, { 0, 0, 0}}, // (116, 30) + { 0, { 0, 0, 0}}, // (117, 30) + { 0, { 0, 0, 0}}, // (118, 30) + { 0, { 0, 0, 0}}, // (119, 30) + { 0, { 0, 0, 0}}, // (120, 30) + { 0, { 0, 0, 0}}, // (121, 30) + { 0, { 0, 0, 0}}, // (122, 30) + { 0, { 0, 0, 0}}, // (123, 30) + { 0, { 0, 0, 0}}, // (124, 30) + { 0, { 0, 0, 0}}, // (125, 30) + { 0, { 0, 0, 0}}, // (126, 30) + { 0, { 0, 0, 0}}, // (127, 30) + { 0, { 0, 0, 0}}, // (128, 30) + { 0, { 0, 0, 0}}, // (129, 30) + { 0, { 0, 0, 0}}, // (130, 30) + { 0, { 0, 0, 0}}, // (131, 30) + { 0, { 0, 0, 0}}, // (132, 30) + { 0, { 0, 0, 0}}, // (133, 30) + { 0, { 0, 0, 0}}, // (134, 30) + { 0, { 0, 0, 0}}, // (135, 30) + { 0, { 0, 0, 0}}, // (136, 30) + { 0, { 0, 0, 0}}, // (137, 30) + { 0, { 0, 0, 0}}, // (138, 30) + { 0, { 0, 0, 0}}, // (139, 30) + { 0, { 0, 0, 0}}, // (140, 30) + { 0, { 0, 0, 0}}, // (141, 30) + { 0, { 0, 0, 0}}, // (142, 30) + { 0, { 0, 0, 0}}, // (143, 30) + { 0, { 0, 0, 0}}, // (144, 30) + { 0, { 0, 0, 0}}, // (145, 30) + { 0, { 0, 0, 0}}, // (146, 30) + { 0, { 0, 0, 0}}, // (147, 30) + { 0, { 0, 0, 0}}, // (148, 30) + { 0, { 0, 0, 0}}, // (149, 30) + { 0, { 0, 0, 0}}, // (150, 30) + { 0, { 0, 0, 0}}, // (151, 30) + { 0, { 0, 0, 0}}, // (152, 30) + { 0, { 0, 0, 0}}, // (153, 30) + { 28, { 0, 0, 0}}, // (154, 30) + {123, { 0, 0, 0}}, // (155, 30) + {128, { 0, 0, 0}}, // (156, 30) + {128, { 0, 0, 0}}, // (157, 30) + {128, { 0, 0, 0}}, // (158, 30) + {128, { 0, 0, 0}}, // (159, 30) + {128, { 0, 0, 0}}, // (160, 30) + {128, { 0, 0, 0}}, // (161, 30) + {128, { 0, 0, 0}}, // (162, 30) + {128, { 0, 0, 0}}, // (163, 30) + {128, { 0, 0, 0}}, // (164, 30) + {128, { 0, 0, 0}}, // (165, 30) + {128, { 0, 0, 0}}, // (166, 30) + {128, { 0, 0, 0}}, // (167, 30) + {128, { 0, 0, 0}}, // (168, 30) + {128, { 0, 0, 0}}, // (169, 30) + {128, { 0, 0, 0}}, // (170, 30) + {128, { 0, 0, 0}}, // (171, 30) + {128, { 0, 0, 0}}, // (172, 30) + {128, { 0, 0, 0}}, // (173, 30) + {128, { 0, 0, 0}}, // (174, 30) + {128, { 0, 0, 0}}, // (175, 30) + {128, { 0, 0, 0}}, // (176, 30) + {128, { 0, 0, 0}}, // (177, 30) + {128, { 0, 0, 0}}, // (178, 30) + {128, { 0, 0, 0}}, // (179, 30) + {128, { 0, 0, 0}}, // ( 0, 31) + {128, { 0, 0, 0}}, // ( 1, 31) + {128, { 0, 0, 0}}, // ( 2, 31) + {128, { 0, 0, 0}}, // ( 3, 31) + {128, { 0, 0, 0}}, // ( 4, 31) + {128, { 0, 0, 0}}, // ( 5, 31) + {128, { 0, 0, 0}}, // ( 6, 31) + {128, { 0, 0, 0}}, // ( 7, 31) + {128, { 0, 0, 0}}, // ( 8, 31) + {128, { 0, 0, 0}}, // ( 9, 31) + {128, { 0, 0, 0}}, // ( 10, 31) + {128, { 0, 0, 0}}, // ( 11, 31) + {128, { 0, 0, 0}}, // ( 12, 31) + {128, { 0, 0, 0}}, // ( 13, 31) + {128, { 0, 0, 0}}, // ( 14, 31) + {128, { 0, 0, 0}}, // ( 15, 31) + {128, { 0, 0, 0}}, // ( 16, 31) + {128, { 0, 0, 0}}, // ( 17, 31) + {128, { 0, 0, 0}}, // ( 18, 31) + {128, { 0, 0, 0}}, // ( 19, 31) + {128, { 0, 0, 0}}, // ( 20, 31) + {128, { 0, 0, 0}}, // ( 21, 31) + {128, { 0, 0, 0}}, // ( 22, 31) + {126, { 0, 0, 0}}, // ( 23, 31) + { 39, { 0, 0, 0}}, // ( 24, 31) + { 0, { 0, 0, 0}}, // ( 25, 31) + { 0, { 0, 0, 0}}, // ( 26, 31) + { 0, { 0, 0, 0}}, // ( 27, 31) + { 0, { 0, 0, 0}}, // ( 28, 31) + { 0, { 0, 0, 0}}, // ( 29, 31) + { 0, { 0, 0, 0}}, // ( 30, 31) + { 0, { 0, 0, 0}}, // ( 31, 31) + { 0, { 0, 0, 0}}, // ( 32, 31) + { 0, { 0, 0, 0}}, // ( 33, 31) + { 0, { 0, 0, 0}}, // ( 34, 31) + { 0, { 0, 0, 0}}, // ( 35, 31) + { 0, { 0, 0, 0}}, // ( 36, 31) + { 0, { 0, 0, 0}}, // ( 37, 31) + { 0, { 0, 0, 0}}, // ( 38, 31) + { 0, { 0, 0, 0}}, // ( 39, 31) + { 0, { 0, 0, 0}}, // ( 40, 31) + { 0, { 0, 0, 0}}, // ( 41, 31) + { 0, { 0, 0, 0}}, // ( 42, 31) + { 0, { 0, 0, 0}}, // ( 43, 31) + { 0, { 0, 0, 0}}, // ( 44, 31) + { 0, { 0, 0, 0}}, // ( 45, 31) + { 0, { 0, 0, 0}}, // ( 46, 31) + { 0, { 0, 0, 0}}, // ( 47, 31) + { 0, { 0, 0, 0}}, // ( 48, 31) + { 0, { 0, 0, 0}}, // ( 49, 31) + { 0, { 0, 0, 0}}, // ( 50, 31) + { 0, { 0, 0, 0}}, // ( 51, 31) + { 0, { 0, 0, 0}}, // ( 52, 31) + { 0, { 0, 0, 0}}, // ( 53, 31) + { 0, { 0, 0, 0}}, // ( 54, 31) + { 0, { 0, 0, 0}}, // ( 55, 31) + { 0, { 0, 0, 0}}, // ( 56, 31) + { 0, { 0, 0, 0}}, // ( 57, 31) + { 0, { 0, 0, 0}}, // ( 58, 31) + { 0, { 0, 0, 0}}, // ( 59, 31) + { 0, { 0, 0, 0}}, // ( 60, 31) + { 0, { 0, 0, 0}}, // ( 61, 31) + { 0, { 0, 0, 0}}, // ( 62, 31) + { 0, { 0, 0, 0}}, // ( 63, 31) + { 0, { 0, 0, 0}}, // ( 64, 31) + { 0, { 0, 0, 0}}, // ( 65, 31) + { 0, { 0, 0, 0}}, // ( 66, 31) + { 0, { 0, 0, 0}}, // ( 67, 31) + { 0, { 0, 0, 0}}, // ( 68, 31) + { 0, { 0, 0, 0}}, // ( 69, 31) + { 0, { 0, 0, 0}}, // ( 70, 31) + { 0, { 0, 0, 0}}, // ( 71, 31) + { 0, { 0, 0, 0}}, // ( 72, 31) + { 0, { 0, 0, 0}}, // ( 73, 31) + { 0, { 0, 0, 0}}, // ( 74, 31) + { 0, { 0, 0, 0}}, // ( 75, 31) + { 0, { 0, 0, 0}}, // ( 76, 31) + { 0, { 0, 0, 0}}, // ( 77, 31) + { 0, { 0, 0, 0}}, // ( 78, 31) + { 0, { 0, 0, 0}}, // ( 79, 31) + { 0, { 0, 0, 0}}, // ( 80, 31) + { 0, { 0, 0, 0}}, // ( 81, 31) + { 0, { 0, 0, 0}}, // ( 82, 31) + { 0, { 0, 0, 0}}, // ( 83, 31) + { 0, { 0, 0, 0}}, // ( 84, 31) + { 0, { 0, 0, 0}}, // ( 85, 31) + { 0, { 0, 0, 0}}, // ( 86, 31) + { 0, { 0, 0, 0}}, // ( 87, 31) + { 0, { 0, 0, 0}}, // ( 88, 31) + { 0, { 0, 0, 0}}, // ( 89, 31) + { 0, { 0, 0, 0}}, // ( 90, 31) + { 0, { 0, 0, 0}}, // ( 91, 31) + { 0, { 0, 0, 0}}, // ( 92, 31) + { 0, { 0, 0, 0}}, // ( 93, 31) + { 0, { 0, 0, 0}}, // ( 94, 31) + { 0, { 0, 0, 0}}, // ( 95, 31) + { 0, { 0, 0, 0}}, // ( 96, 31) + { 0, { 0, 0, 0}}, // ( 97, 31) + { 0, { 0, 0, 0}}, // ( 98, 31) + { 0, { 0, 0, 0}}, // ( 99, 31) + { 0, { 0, 0, 0}}, // (100, 31) + { 0, { 0, 0, 0}}, // (101, 31) + { 0, { 0, 0, 0}}, // (102, 31) + { 0, { 0, 0, 0}}, // (103, 31) + { 0, { 0, 0, 0}}, // (104, 31) + { 0, { 0, 0, 0}}, // (105, 31) + { 0, { 0, 0, 0}}, // (106, 31) + { 0, { 0, 0, 0}}, // (107, 31) + { 0, { 0, 0, 0}}, // (108, 31) + { 0, { 0, 0, 0}}, // (109, 31) + { 0, { 0, 0, 0}}, // (110, 31) + { 0, { 0, 0, 0}}, // (111, 31) + { 0, { 0, 0, 0}}, // (112, 31) + { 0, { 0, 0, 0}}, // (113, 31) + { 0, { 0, 0, 0}}, // (114, 31) + { 0, { 0, 0, 0}}, // (115, 31) + { 0, { 0, 0, 0}}, // (116, 31) + { 0, { 0, 0, 0}}, // (117, 31) + { 0, { 0, 0, 0}}, // (118, 31) + { 0, { 0, 0, 0}}, // (119, 31) + { 0, { 0, 0, 0}}, // (120, 31) + { 0, { 0, 0, 0}}, // (121, 31) + { 0, { 0, 0, 0}}, // (122, 31) + { 0, { 0, 0, 0}}, // (123, 31) + { 0, { 0, 0, 0}}, // (124, 31) + { 0, { 0, 0, 0}}, // (125, 31) + { 0, { 0, 0, 0}}, // (126, 31) + { 0, { 0, 0, 0}}, // (127, 31) + { 0, { 0, 0, 0}}, // (128, 31) + { 0, { 0, 0, 0}}, // (129, 31) + { 0, { 0, 0, 0}}, // (130, 31) + { 0, { 0, 0, 0}}, // (131, 31) + { 0, { 0, 0, 0}}, // (132, 31) + { 0, { 0, 0, 0}}, // (133, 31) + { 0, { 0, 0, 0}}, // (134, 31) + { 0, { 0, 0, 0}}, // (135, 31) + { 0, { 0, 0, 0}}, // (136, 31) + { 0, { 0, 0, 0}}, // (137, 31) + { 0, { 0, 0, 0}}, // (138, 31) + { 0, { 0, 0, 0}}, // (139, 31) + { 0, { 0, 0, 0}}, // (140, 31) + { 0, { 0, 0, 0}}, // (141, 31) + { 0, { 0, 0, 0}}, // (142, 31) + { 0, { 0, 0, 0}}, // (143, 31) + { 0, { 0, 0, 0}}, // (144, 31) + { 0, { 0, 0, 0}}, // (145, 31) + { 0, { 0, 0, 0}}, // (146, 31) + { 0, { 0, 0, 0}}, // (147, 31) + { 0, { 0, 0, 0}}, // (148, 31) + { 0, { 0, 0, 0}}, // (149, 31) + { 0, { 0, 0, 0}}, // (150, 31) + { 0, { 0, 0, 0}}, // (151, 31) + { 0, { 0, 0, 0}}, // (152, 31) + { 0, { 0, 0, 0}}, // (153, 31) + { 0, { 0, 0, 0}}, // (154, 31) + { 39, { 0, 0, 0}}, // (155, 31) + {126, { 0, 0, 0}}, // (156, 31) + {128, { 0, 0, 0}}, // (157, 31) + {128, { 0, 0, 0}}, // (158, 31) + {128, { 0, 0, 0}}, // (159, 31) + {128, { 0, 0, 0}}, // (160, 31) + {128, { 0, 0, 0}}, // (161, 31) + {128, { 0, 0, 0}}, // (162, 31) + {128, { 0, 0, 0}}, // (163, 31) + {128, { 0, 0, 0}}, // (164, 31) + {128, { 0, 0, 0}}, // (165, 31) + {128, { 0, 0, 0}}, // (166, 31) + {128, { 0, 0, 0}}, // (167, 31) + {128, { 0, 0, 0}}, // (168, 31) + {128, { 0, 0, 0}}, // (169, 31) + {128, { 0, 0, 0}}, // (170, 31) + {128, { 0, 0, 0}}, // (171, 31) + {128, { 0, 0, 0}}, // (172, 31) + {128, { 0, 0, 0}}, // (173, 31) + {128, { 0, 0, 0}}, // (174, 31) + {128, { 0, 0, 0}}, // (175, 31) + {128, { 0, 0, 0}}, // (176, 31) + {128, { 0, 0, 0}}, // (177, 31) + {128, { 0, 0, 0}}, // (178, 31) + {128, { 0, 0, 0}}, // (179, 31) + {128, { 0, 0, 0}}, // ( 0, 32) + {128, { 0, 0, 0}}, // ( 1, 32) + {128, { 0, 0, 0}}, // ( 2, 32) + {128, { 0, 0, 0}}, // ( 3, 32) + {128, { 0, 0, 0}}, // ( 4, 32) + {128, { 0, 0, 0}}, // ( 5, 32) + {128, { 0, 0, 0}}, // ( 6, 32) + {128, { 0, 0, 0}}, // ( 7, 32) + {128, { 0, 0, 0}}, // ( 8, 32) + {128, { 0, 0, 0}}, // ( 9, 32) + {128, { 0, 0, 0}}, // ( 10, 32) + {128, { 0, 0, 0}}, // ( 11, 32) + {128, { 0, 0, 0}}, // ( 12, 32) + {128, { 0, 0, 0}}, // ( 13, 32) + {128, { 0, 0, 0}}, // ( 14, 32) + {128, { 0, 0, 0}}, // ( 15, 32) + {128, { 0, 0, 0}}, // ( 16, 32) + {128, { 0, 0, 0}}, // ( 17, 32) + {128, { 0, 0, 0}}, // ( 18, 32) + {128, { 0, 0, 0}}, // ( 19, 32) + {128, { 0, 0, 0}}, // ( 20, 32) + {128, { 0, 0, 0}}, // ( 21, 32) + {128, { 0, 0, 0}}, // ( 22, 32) + { 53, { 0, 0, 0}}, // ( 23, 32) + { 0, { 0, 0, 0}}, // ( 24, 32) + { 0, { 0, 0, 0}}, // ( 25, 32) + { 0, { 0, 0, 0}}, // ( 26, 32) + { 0, { 0, 0, 0}}, // ( 27, 32) + { 0, { 0, 0, 0}}, // ( 28, 32) + { 0, { 0, 0, 0}}, // ( 29, 32) + { 0, { 0, 0, 0}}, // ( 30, 32) + { 0, { 0, 0, 0}}, // ( 31, 32) + { 0, { 0, 0, 0}}, // ( 32, 32) + { 0, { 0, 0, 0}}, // ( 33, 32) + { 0, { 0, 0, 0}}, // ( 34, 32) + { 0, { 0, 0, 0}}, // ( 35, 32) + { 0, { 0, 0, 0}}, // ( 36, 32) + { 0, { 0, 0, 0}}, // ( 37, 32) + { 0, { 0, 0, 0}}, // ( 38, 32) + { 0, { 0, 0, 0}}, // ( 39, 32) + { 0, { 0, 0, 0}}, // ( 40, 32) + { 0, { 0, 0, 0}}, // ( 41, 32) + { 0, { 0, 0, 0}}, // ( 42, 32) + { 0, { 0, 0, 0}}, // ( 43, 32) + { 0, { 0, 0, 0}}, // ( 44, 32) + { 0, { 0, 0, 0}}, // ( 45, 32) + { 0, { 0, 0, 0}}, // ( 46, 32) + { 0, { 0, 0, 0}}, // ( 47, 32) + { 0, { 0, 0, 0}}, // ( 48, 32) + { 0, { 0, 0, 0}}, // ( 49, 32) + { 0, { 0, 0, 0}}, // ( 50, 32) + { 0, { 0, 0, 0}}, // ( 51, 32) + { 0, { 0, 0, 0}}, // ( 52, 32) + { 0, { 0, 0, 0}}, // ( 53, 32) + { 0, { 0, 0, 0}}, // ( 54, 32) + { 0, { 0, 0, 0}}, // ( 55, 32) + { 0, { 0, 0, 0}}, // ( 56, 32) + { 0, { 0, 0, 0}}, // ( 57, 32) + { 0, { 0, 0, 0}}, // ( 58, 32) + { 0, { 0, 0, 0}}, // ( 59, 32) + { 0, { 0, 0, 0}}, // ( 60, 32) + { 0, { 0, 0, 0}}, // ( 61, 32) + { 0, { 0, 0, 0}}, // ( 62, 32) + { 0, { 0, 0, 0}}, // ( 63, 32) + { 0, { 0, 0, 0}}, // ( 64, 32) + { 0, { 0, 0, 0}}, // ( 65, 32) + { 0, { 0, 0, 0}}, // ( 66, 32) + { 0, { 0, 0, 0}}, // ( 67, 32) + { 0, { 0, 0, 0}}, // ( 68, 32) + { 0, { 0, 0, 0}}, // ( 69, 32) + { 0, { 0, 0, 0}}, // ( 70, 32) + { 0, { 0, 0, 0}}, // ( 71, 32) + { 0, { 0, 0, 0}}, // ( 72, 32) + { 0, { 0, 0, 0}}, // ( 73, 32) + { 0, { 0, 0, 0}}, // ( 74, 32) + { 0, { 0, 0, 0}}, // ( 75, 32) + { 0, { 0, 0, 0}}, // ( 76, 32) + { 0, { 0, 0, 0}}, // ( 77, 32) + { 0, { 0, 0, 0}}, // ( 78, 32) + { 0, { 0, 0, 0}}, // ( 79, 32) + { 0, { 0, 0, 0}}, // ( 80, 32) + { 0, { 0, 0, 0}}, // ( 81, 32) + { 0, { 0, 0, 0}}, // ( 82, 32) + { 0, { 0, 0, 0}}, // ( 83, 32) + { 0, { 0, 0, 0}}, // ( 84, 32) + { 0, { 0, 0, 0}}, // ( 85, 32) + { 0, { 0, 0, 0}}, // ( 86, 32) + { 0, { 0, 0, 0}}, // ( 87, 32) + { 0, { 0, 0, 0}}, // ( 88, 32) + { 0, { 0, 0, 0}}, // ( 89, 32) + { 0, { 0, 0, 0}}, // ( 90, 32) + { 0, { 0, 0, 0}}, // ( 91, 32) + { 0, { 0, 0, 0}}, // ( 92, 32) + { 0, { 0, 0, 0}}, // ( 93, 32) + { 0, { 0, 0, 0}}, // ( 94, 32) + { 0, { 0, 0, 0}}, // ( 95, 32) + { 0, { 0, 0, 0}}, // ( 96, 32) + { 0, { 0, 0, 0}}, // ( 97, 32) + { 0, { 0, 0, 0}}, // ( 98, 32) + { 0, { 0, 0, 0}}, // ( 99, 32) + { 0, { 0, 0, 0}}, // (100, 32) + { 0, { 0, 0, 0}}, // (101, 32) + { 0, { 0, 0, 0}}, // (102, 32) + { 0, { 0, 0, 0}}, // (103, 32) + { 0, { 0, 0, 0}}, // (104, 32) + { 0, { 0, 0, 0}}, // (105, 32) + { 0, { 0, 0, 0}}, // (106, 32) + { 0, { 0, 0, 0}}, // (107, 32) + { 0, { 0, 0, 0}}, // (108, 32) + { 0, { 0, 0, 0}}, // (109, 32) + { 0, { 0, 0, 0}}, // (110, 32) + { 0, { 0, 0, 0}}, // (111, 32) + { 0, { 0, 0, 0}}, // (112, 32) + { 0, { 0, 0, 0}}, // (113, 32) + { 0, { 0, 0, 0}}, // (114, 32) + { 0, { 0, 0, 0}}, // (115, 32) + { 0, { 0, 0, 0}}, // (116, 32) + { 0, { 0, 0, 0}}, // (117, 32) + { 0, { 0, 0, 0}}, // (118, 32) + { 0, { 0, 0, 0}}, // (119, 32) + { 0, { 0, 0, 0}}, // (120, 32) + { 0, { 0, 0, 0}}, // (121, 32) + { 0, { 0, 0, 0}}, // (122, 32) + { 0, { 0, 0, 0}}, // (123, 32) + { 0, { 0, 0, 0}}, // (124, 32) + { 0, { 0, 0, 0}}, // (125, 32) + { 0, { 0, 0, 0}}, // (126, 32) + { 0, { 0, 0, 0}}, // (127, 32) + { 0, { 0, 0, 0}}, // (128, 32) + { 0, { 0, 0, 0}}, // (129, 32) + { 0, { 0, 0, 0}}, // (130, 32) + { 0, { 0, 0, 0}}, // (131, 32) + { 0, { 0, 0, 0}}, // (132, 32) + { 0, { 0, 0, 0}}, // (133, 32) + { 0, { 0, 0, 0}}, // (134, 32) + { 0, { 0, 0, 0}}, // (135, 32) + { 0, { 0, 0, 0}}, // (136, 32) + { 0, { 0, 0, 0}}, // (137, 32) + { 0, { 0, 0, 0}}, // (138, 32) + { 0, { 0, 0, 0}}, // (139, 32) + { 0, { 0, 0, 0}}, // (140, 32) + { 0, { 0, 0, 0}}, // (141, 32) + { 0, { 0, 0, 0}}, // (142, 32) + { 0, { 0, 0, 0}}, // (143, 32) + { 0, { 0, 0, 0}}, // (144, 32) + { 0, { 0, 0, 0}}, // (145, 32) + { 0, { 0, 0, 0}}, // (146, 32) + { 0, { 0, 0, 0}}, // (147, 32) + { 0, { 0, 0, 0}}, // (148, 32) + { 0, { 0, 0, 0}}, // (149, 32) + { 0, { 0, 0, 0}}, // (150, 32) + { 0, { 0, 0, 0}}, // (151, 32) + { 0, { 0, 0, 0}}, // (152, 32) + { 0, { 0, 0, 0}}, // (153, 32) + { 0, { 0, 0, 0}}, // (154, 32) + { 0, { 0, 0, 0}}, // (155, 32) + { 53, { 0, 0, 0}}, // (156, 32) + {128, { 0, 0, 0}}, // (157, 32) + {128, { 0, 0, 0}}, // (158, 32) + {128, { 0, 0, 0}}, // (159, 32) + {128, { 0, 0, 0}}, // (160, 32) + {128, { 0, 0, 0}}, // (161, 32) + {128, { 0, 0, 0}}, // (162, 32) + {128, { 0, 0, 0}}, // (163, 32) + {128, { 0, 0, 0}}, // (164, 32) + {128, { 0, 0, 0}}, // (165, 32) + {128, { 0, 0, 0}}, // (166, 32) + {128, { 0, 0, 0}}, // (167, 32) + {128, { 0, 0, 0}}, // (168, 32) + {128, { 0, 0, 0}}, // (169, 32) + {128, { 0, 0, 0}}, // (170, 32) + {128, { 0, 0, 0}}, // (171, 32) + {128, { 0, 0, 0}}, // (172, 32) + {128, { 0, 0, 0}}, // (173, 32) + {128, { 0, 0, 0}}, // (174, 32) + {128, { 0, 0, 0}}, // (175, 32) + {128, { 0, 0, 0}}, // (176, 32) + {128, { 0, 0, 0}}, // (177, 32) + {128, { 0, 0, 0}}, // (178, 32) + {128, { 0, 0, 0}}, // (179, 32) + {128, { 0, 0, 0}}, // ( 0, 33) + {128, { 0, 0, 0}}, // ( 1, 33) + {128, { 0, 0, 0}}, // ( 2, 33) + {128, { 0, 0, 0}}, // ( 3, 33) + {128, { 0, 0, 0}}, // ( 4, 33) + {128, { 0, 0, 0}}, // ( 5, 33) + {128, { 0, 0, 0}}, // ( 6, 33) + {128, { 0, 0, 0}}, // ( 7, 33) + {128, { 0, 0, 0}}, // ( 8, 33) + {128, { 0, 0, 0}}, // ( 9, 33) + {128, { 0, 0, 0}}, // ( 10, 33) + {128, { 0, 0, 0}}, // ( 11, 33) + {128, { 0, 0, 0}}, // ( 12, 33) + {128, { 0, 0, 0}}, // ( 13, 33) + {128, { 0, 0, 0}}, // ( 14, 33) + {128, { 0, 0, 0}}, // ( 15, 33) + {128, { 0, 0, 0}}, // ( 16, 33) + {128, { 0, 0, 0}}, // ( 17, 33) + {128, { 0, 0, 0}}, // ( 18, 33) + {128, { 0, 0, 0}}, // ( 19, 33) + {128, { 0, 0, 0}}, // ( 20, 33) + {128, { 0, 0, 0}}, // ( 21, 33) + { 68, { 0, 0, 0}}, // ( 22, 33) + { 0, { 0, 0, 0}}, // ( 23, 33) + { 0, { 0, 0, 0}}, // ( 24, 33) + { 0, { 0, 0, 0}}, // ( 25, 33) + { 0, { 0, 0, 0}}, // ( 26, 33) + { 0, { 0, 0, 0}}, // ( 27, 33) + { 0, { 0, 0, 0}}, // ( 28, 33) + { 0, { 0, 0, 0}}, // ( 29, 33) + { 0, { 0, 0, 0}}, // ( 30, 33) + { 0, { 0, 0, 0}}, // ( 31, 33) + { 0, { 0, 0, 0}}, // ( 32, 33) + { 0, { 0, 0, 0}}, // ( 33, 33) + { 0, { 0, 0, 0}}, // ( 34, 33) + { 0, { 0, 0, 0}}, // ( 35, 33) + { 0, { 0, 0, 0}}, // ( 36, 33) + { 0, { 0, 0, 0}}, // ( 37, 33) + { 0, { 0, 0, 0}}, // ( 38, 33) + { 0, { 0, 0, 0}}, // ( 39, 33) + { 0, { 0, 0, 0}}, // ( 40, 33) + { 0, { 0, 0, 0}}, // ( 41, 33) + { 0, { 0, 0, 0}}, // ( 42, 33) + { 0, { 0, 0, 0}}, // ( 43, 33) + { 0, { 0, 0, 0}}, // ( 44, 33) + { 0, { 0, 0, 0}}, // ( 45, 33) + { 0, { 0, 0, 0}}, // ( 46, 33) + { 0, { 0, 0, 0}}, // ( 47, 33) + { 0, { 0, 0, 0}}, // ( 48, 33) + { 0, { 0, 0, 0}}, // ( 49, 33) + { 0, { 0, 0, 0}}, // ( 50, 33) + { 0, { 0, 0, 0}}, // ( 51, 33) + { 0, { 0, 0, 0}}, // ( 52, 33) + { 0, { 0, 0, 0}}, // ( 53, 33) + { 0, { 0, 0, 0}}, // ( 54, 33) + { 0, { 0, 0, 0}}, // ( 55, 33) + { 0, { 0, 0, 0}}, // ( 56, 33) + { 0, { 0, 0, 0}}, // ( 57, 33) + { 0, { 0, 0, 0}}, // ( 58, 33) + { 0, { 0, 0, 0}}, // ( 59, 33) + { 0, { 0, 0, 0}}, // ( 60, 33) + { 0, { 0, 0, 0}}, // ( 61, 33) + { 0, { 0, 0, 0}}, // ( 62, 33) + { 0, { 0, 0, 0}}, // ( 63, 33) + { 0, { 0, 0, 0}}, // ( 64, 33) + { 0, { 0, 0, 0}}, // ( 65, 33) + { 0, { 0, 0, 0}}, // ( 66, 33) + { 0, { 0, 0, 0}}, // ( 67, 33) + { 0, { 0, 0, 0}}, // ( 68, 33) + { 0, { 0, 0, 0}}, // ( 69, 33) + { 0, { 0, 0, 0}}, // ( 70, 33) + { 0, { 0, 0, 0}}, // ( 71, 33) + { 0, { 0, 0, 0}}, // ( 72, 33) + { 0, { 0, 0, 0}}, // ( 73, 33) + { 0, { 0, 0, 0}}, // ( 74, 33) + { 0, { 0, 0, 0}}, // ( 75, 33) + { 0, { 0, 0, 0}}, // ( 76, 33) + { 0, { 0, 0, 0}}, // ( 77, 33) + { 0, { 0, 0, 0}}, // ( 78, 33) + { 0, { 0, 0, 0}}, // ( 79, 33) + { 0, { 0, 0, 0}}, // ( 80, 33) + { 0, { 0, 0, 0}}, // ( 81, 33) + { 0, { 0, 0, 0}}, // ( 82, 33) + { 0, { 0, 0, 0}}, // ( 83, 33) + { 0, { 0, 0, 0}}, // ( 84, 33) + { 0, { 0, 0, 0}}, // ( 85, 33) + { 0, { 0, 0, 0}}, // ( 86, 33) + { 0, { 0, 0, 0}}, // ( 87, 33) + { 0, { 0, 0, 0}}, // ( 88, 33) + { 0, { 0, 0, 0}}, // ( 89, 33) + { 0, { 0, 0, 0}}, // ( 90, 33) + { 0, { 0, 0, 0}}, // ( 91, 33) + { 0, { 0, 0, 0}}, // ( 92, 33) + { 0, { 0, 0, 0}}, // ( 93, 33) + { 0, { 0, 0, 0}}, // ( 94, 33) + { 0, { 0, 0, 0}}, // ( 95, 33) + { 0, { 0, 0, 0}}, // ( 96, 33) + { 0, { 0, 0, 0}}, // ( 97, 33) + { 0, { 0, 0, 0}}, // ( 98, 33) + { 0, { 0, 0, 0}}, // ( 99, 33) + { 0, { 0, 0, 0}}, // (100, 33) + { 0, { 0, 0, 0}}, // (101, 33) + { 0, { 0, 0, 0}}, // (102, 33) + { 0, { 0, 0, 0}}, // (103, 33) + { 0, { 0, 0, 0}}, // (104, 33) + { 0, { 0, 0, 0}}, // (105, 33) + { 0, { 0, 0, 0}}, // (106, 33) + { 0, { 0, 0, 0}}, // (107, 33) + { 0, { 0, 0, 0}}, // (108, 33) + { 0, { 0, 0, 0}}, // (109, 33) + { 0, { 0, 0, 0}}, // (110, 33) + { 0, { 0, 0, 0}}, // (111, 33) + { 0, { 0, 0, 0}}, // (112, 33) + { 0, { 0, 0, 0}}, // (113, 33) + { 0, { 0, 0, 0}}, // (114, 33) + { 0, { 0, 0, 0}}, // (115, 33) + { 0, { 0, 0, 0}}, // (116, 33) + { 0, { 0, 0, 0}}, // (117, 33) + { 0, { 0, 0, 0}}, // (118, 33) + { 0, { 0, 0, 0}}, // (119, 33) + { 0, { 0, 0, 0}}, // (120, 33) + { 0, { 0, 0, 0}}, // (121, 33) + { 0, { 0, 0, 0}}, // (122, 33) + { 0, { 0, 0, 0}}, // (123, 33) + { 0, { 0, 0, 0}}, // (124, 33) + { 0, { 0, 0, 0}}, // (125, 33) + { 0, { 0, 0, 0}}, // (126, 33) + { 0, { 0, 0, 0}}, // (127, 33) + { 0, { 0, 0, 0}}, // (128, 33) + { 0, { 0, 0, 0}}, // (129, 33) + { 0, { 0, 0, 0}}, // (130, 33) + { 0, { 0, 0, 0}}, // (131, 33) + { 0, { 0, 0, 0}}, // (132, 33) + { 0, { 0, 0, 0}}, // (133, 33) + { 0, { 0, 0, 0}}, // (134, 33) + { 0, { 0, 0, 0}}, // (135, 33) + { 0, { 0, 0, 0}}, // (136, 33) + { 0, { 0, 0, 0}}, // (137, 33) + { 0, { 0, 0, 0}}, // (138, 33) + { 0, { 0, 0, 0}}, // (139, 33) + { 0, { 0, 0, 0}}, // (140, 33) + { 0, { 0, 0, 0}}, // (141, 33) + { 0, { 0, 0, 0}}, // (142, 33) + { 0, { 0, 0, 0}}, // (143, 33) + { 0, { 0, 0, 0}}, // (144, 33) + { 0, { 0, 0, 0}}, // (145, 33) + { 0, { 0, 0, 0}}, // (146, 33) + { 0, { 0, 0, 0}}, // (147, 33) + { 0, { 0, 0, 0}}, // (148, 33) + { 0, { 0, 0, 0}}, // (149, 33) + { 0, { 0, 0, 0}}, // (150, 33) + { 0, { 0, 0, 0}}, // (151, 33) + { 0, { 0, 0, 0}}, // (152, 33) + { 0, { 0, 0, 0}}, // (153, 33) + { 0, { 0, 0, 0}}, // (154, 33) + { 0, { 0, 0, 0}}, // (155, 33) + { 0, { 0, 0, 0}}, // (156, 33) + { 68, { 0, 0, 0}}, // (157, 33) + {128, { 0, 0, 0}}, // (158, 33) + {128, { 0, 0, 0}}, // (159, 33) + {128, { 0, 0, 0}}, // (160, 33) + {128, { 0, 0, 0}}, // (161, 33) + {128, { 0, 0, 0}}, // (162, 33) + {128, { 0, 0, 0}}, // (163, 33) + {128, { 0, 0, 0}}, // (164, 33) + {128, { 0, 0, 0}}, // (165, 33) + {128, { 0, 0, 0}}, // (166, 33) + {128, { 0, 0, 0}}, // (167, 33) + {128, { 0, 0, 0}}, // (168, 33) + {128, { 0, 0, 0}}, // (169, 33) + {128, { 0, 0, 0}}, // (170, 33) + {128, { 0, 0, 0}}, // (171, 33) + {128, { 0, 0, 0}}, // (172, 33) + {128, { 0, 0, 0}}, // (173, 33) + {128, { 0, 0, 0}}, // (174, 33) + {128, { 0, 0, 0}}, // (175, 33) + {128, { 0, 0, 0}}, // (176, 33) + {128, { 0, 0, 0}}, // (177, 33) + {128, { 0, 0, 0}}, // (178, 33) + {128, { 0, 0, 0}}, // (179, 33) + {128, { 0, 0, 0}}, // ( 0, 34) + {128, { 0, 0, 0}}, // ( 1, 34) + {128, { 0, 0, 0}}, // ( 2, 34) + {128, { 0, 0, 0}}, // ( 3, 34) + {128, { 0, 0, 0}}, // ( 4, 34) + {128, { 0, 0, 0}}, // ( 5, 34) + {128, { 0, 0, 0}}, // ( 6, 34) + {128, { 0, 0, 0}}, // ( 7, 34) + {128, { 0, 0, 0}}, // ( 8, 34) + {128, { 0, 0, 0}}, // ( 9, 34) + {128, { 0, 0, 0}}, // ( 10, 34) + {128, { 0, 0, 0}}, // ( 11, 34) + {128, { 0, 0, 0}}, // ( 12, 34) + {128, { 0, 0, 0}}, // ( 13, 34) + {128, { 0, 0, 0}}, // ( 14, 34) + {128, { 0, 0, 0}}, // ( 15, 34) + {128, { 0, 0, 0}}, // ( 16, 34) + {128, { 0, 0, 0}}, // ( 17, 34) + {128, { 0, 0, 0}}, // ( 18, 34) + {128, { 0, 0, 0}}, // ( 19, 34) + {128, { 0, 0, 0}}, // ( 20, 34) + { 92, { 0, 0, 0}}, // ( 21, 34) + { 2, { 0, 0, 0}}, // ( 22, 34) + { 0, { 0, 0, 0}}, // ( 23, 34) + { 0, { 0, 0, 0}}, // ( 24, 34) + { 0, { 0, 0, 0}}, // ( 25, 34) + { 0, { 0, 0, 0}}, // ( 26, 34) + { 0, { 0, 0, 0}}, // ( 27, 34) + { 0, { 0, 0, 0}}, // ( 28, 34) + { 0, { 0, 0, 0}}, // ( 29, 34) + { 0, { 0, 0, 0}}, // ( 30, 34) + { 0, { 0, 0, 0}}, // ( 31, 34) + { 0, { 0, 0, 0}}, // ( 32, 34) + { 0, { 0, 0, 0}}, // ( 33, 34) + { 0, { 0, 0, 0}}, // ( 34, 34) + { 0, { 0, 0, 0}}, // ( 35, 34) + { 0, { 0, 0, 0}}, // ( 36, 34) + { 0, { 0, 0, 0}}, // ( 37, 34) + { 0, { 0, 0, 0}}, // ( 38, 34) + { 0, { 0, 0, 0}}, // ( 39, 34) + { 0, { 0, 0, 0}}, // ( 40, 34) + { 0, { 0, 0, 0}}, // ( 41, 34) + { 0, { 0, 0, 0}}, // ( 42, 34) + { 0, { 0, 0, 0}}, // ( 43, 34) + { 0, { 0, 0, 0}}, // ( 44, 34) + { 0, { 0, 0, 0}}, // ( 45, 34) + { 0, { 0, 0, 0}}, // ( 46, 34) + { 0, { 0, 0, 0}}, // ( 47, 34) + { 0, { 0, 0, 0}}, // ( 48, 34) + { 0, { 0, 0, 0}}, // ( 49, 34) + { 0, { 0, 0, 0}}, // ( 50, 34) + { 0, { 0, 0, 0}}, // ( 51, 34) + { 0, { 0, 0, 0}}, // ( 52, 34) + { 0, { 0, 0, 0}}, // ( 53, 34) + { 0, { 0, 0, 0}}, // ( 54, 34) + { 0, { 0, 0, 0}}, // ( 55, 34) + { 0, { 0, 0, 0}}, // ( 56, 34) + { 0, { 0, 0, 0}}, // ( 57, 34) + { 0, { 0, 0, 0}}, // ( 58, 34) + { 0, { 0, 0, 0}}, // ( 59, 34) + { 0, { 0, 0, 0}}, // ( 60, 34) + { 0, { 0, 0, 0}}, // ( 61, 34) + { 0, { 0, 0, 0}}, // ( 62, 34) + { 0, { 0, 0, 0}}, // ( 63, 34) + { 0, { 0, 0, 0}}, // ( 64, 34) + { 0, { 0, 0, 0}}, // ( 65, 34) + { 0, { 0, 0, 0}}, // ( 66, 34) + { 0, { 0, 0, 0}}, // ( 67, 34) + { 0, { 0, 0, 0}}, // ( 68, 34) + { 0, { 0, 0, 0}}, // ( 69, 34) + { 0, { 0, 0, 0}}, // ( 70, 34) + { 0, { 0, 0, 0}}, // ( 71, 34) + { 0, { 0, 0, 0}}, // ( 72, 34) + { 0, { 0, 0, 0}}, // ( 73, 34) + { 0, { 0, 0, 0}}, // ( 74, 34) + { 0, { 0, 0, 0}}, // ( 75, 34) + { 0, { 0, 0, 0}}, // ( 76, 34) + { 0, { 0, 0, 0}}, // ( 77, 34) + { 0, { 0, 0, 0}}, // ( 78, 34) + { 0, { 0, 0, 0}}, // ( 79, 34) + { 0, { 0, 0, 0}}, // ( 80, 34) + { 0, { 0, 0, 0}}, // ( 81, 34) + { 0, { 0, 0, 0}}, // ( 82, 34) + { 0, { 0, 0, 0}}, // ( 83, 34) + { 0, { 0, 0, 0}}, // ( 84, 34) + { 0, { 0, 0, 0}}, // ( 85, 34) + { 0, { 0, 0, 0}}, // ( 86, 34) + { 0, { 0, 0, 0}}, // ( 87, 34) + { 0, { 0, 0, 0}}, // ( 88, 34) + { 0, { 0, 0, 0}}, // ( 89, 34) + { 0, { 0, 0, 0}}, // ( 90, 34) + { 0, { 0, 0, 0}}, // ( 91, 34) + { 0, { 0, 0, 0}}, // ( 92, 34) + { 0, { 0, 0, 0}}, // ( 93, 34) + { 0, { 0, 0, 0}}, // ( 94, 34) + { 0, { 0, 0, 0}}, // ( 95, 34) + { 0, { 0, 0, 0}}, // ( 96, 34) + { 0, { 0, 0, 0}}, // ( 97, 34) + { 0, { 0, 0, 0}}, // ( 98, 34) + { 0, { 0, 0, 0}}, // ( 99, 34) + { 0, { 0, 0, 0}}, // (100, 34) + { 0, { 0, 0, 0}}, // (101, 34) + { 0, { 0, 0, 0}}, // (102, 34) + { 0, { 0, 0, 0}}, // (103, 34) + { 0, { 0, 0, 0}}, // (104, 34) + { 0, { 0, 0, 0}}, // (105, 34) + { 0, { 0, 0, 0}}, // (106, 34) + { 0, { 0, 0, 0}}, // (107, 34) + { 0, { 0, 0, 0}}, // (108, 34) + { 0, { 0, 0, 0}}, // (109, 34) + { 0, { 0, 0, 0}}, // (110, 34) + { 0, { 0, 0, 0}}, // (111, 34) + { 0, { 0, 0, 0}}, // (112, 34) + { 0, { 0, 0, 0}}, // (113, 34) + { 0, { 0, 0, 0}}, // (114, 34) + { 0, { 0, 0, 0}}, // (115, 34) + { 0, { 0, 0, 0}}, // (116, 34) + { 0, { 0, 0, 0}}, // (117, 34) + { 0, { 0, 0, 0}}, // (118, 34) + { 0, { 0, 0, 0}}, // (119, 34) + { 0, { 0, 0, 0}}, // (120, 34) + { 0, { 0, 0, 0}}, // (121, 34) + { 0, { 0, 0, 0}}, // (122, 34) + { 0, { 0, 0, 0}}, // (123, 34) + { 0, { 0, 0, 0}}, // (124, 34) + { 0, { 0, 0, 0}}, // (125, 34) + { 0, { 0, 0, 0}}, // (126, 34) + { 0, { 0, 0, 0}}, // (127, 34) + { 0, { 0, 0, 0}}, // (128, 34) + { 0, { 0, 0, 0}}, // (129, 34) + { 0, { 0, 0, 0}}, // (130, 34) + { 0, { 0, 0, 0}}, // (131, 34) + { 0, { 0, 0, 0}}, // (132, 34) + { 0, { 0, 0, 0}}, // (133, 34) + { 0, { 0, 0, 0}}, // (134, 34) + { 0, { 0, 0, 0}}, // (135, 34) + { 0, { 0, 0, 0}}, // (136, 34) + { 0, { 0, 0, 0}}, // (137, 34) + { 0, { 0, 0, 0}}, // (138, 34) + { 0, { 0, 0, 0}}, // (139, 34) + { 0, { 0, 0, 0}}, // (140, 34) + { 0, { 0, 0, 0}}, // (141, 34) + { 0, { 0, 0, 0}}, // (142, 34) + { 0, { 0, 0, 0}}, // (143, 34) + { 0, { 0, 0, 0}}, // (144, 34) + { 0, { 0, 0, 0}}, // (145, 34) + { 0, { 0, 0, 0}}, // (146, 34) + { 0, { 0, 0, 0}}, // (147, 34) + { 0, { 0, 0, 0}}, // (148, 34) + { 0, { 0, 0, 0}}, // (149, 34) + { 0, { 0, 0, 0}}, // (150, 34) + { 0, { 0, 0, 0}}, // (151, 34) + { 0, { 0, 0, 0}}, // (152, 34) + { 0, { 0, 0, 0}}, // (153, 34) + { 0, { 0, 0, 0}}, // (154, 34) + { 0, { 0, 0, 0}}, // (155, 34) + { 0, { 0, 0, 0}}, // (156, 34) + { 2, { 0, 0, 0}}, // (157, 34) + { 92, { 0, 0, 0}}, // (158, 34) + {128, { 0, 0, 0}}, // (159, 34) + {128, { 0, 0, 0}}, // (160, 34) + {128, { 0, 0, 0}}, // (161, 34) + {128, { 0, 0, 0}}, // (162, 34) + {128, { 0, 0, 0}}, // (163, 34) + {128, { 0, 0, 0}}, // (164, 34) + {128, { 0, 0, 0}}, // (165, 34) + {128, { 0, 0, 0}}, // (166, 34) + {128, { 0, 0, 0}}, // (167, 34) + {128, { 0, 0, 0}}, // (168, 34) + {128, { 0, 0, 0}}, // (169, 34) + {128, { 0, 0, 0}}, // (170, 34) + {128, { 0, 0, 0}}, // (171, 34) + {128, { 0, 0, 0}}, // (172, 34) + {128, { 0, 0, 0}}, // (173, 34) + {128, { 0, 0, 0}}, // (174, 34) + {128, { 0, 0, 0}}, // (175, 34) + {128, { 0, 0, 0}}, // (176, 34) + {128, { 0, 0, 0}}, // (177, 34) + {128, { 0, 0, 0}}, // (178, 34) + {128, { 0, 0, 0}}, // (179, 34) + {128, { 0, 0, 0}}, // ( 0, 35) + {128, { 0, 0, 0}}, // ( 1, 35) + {128, { 0, 0, 0}}, // ( 2, 35) + {128, { 0, 0, 0}}, // ( 3, 35) + {128, { 0, 0, 0}}, // ( 4, 35) + {128, { 0, 0, 0}}, // ( 5, 35) + {128, { 0, 0, 0}}, // ( 6, 35) + {128, { 0, 0, 0}}, // ( 7, 35) + {128, { 0, 0, 0}}, // ( 8, 35) + {128, { 0, 0, 0}}, // ( 9, 35) + {128, { 0, 0, 0}}, // ( 10, 35) + {128, { 0, 0, 0}}, // ( 11, 35) + {128, { 0, 0, 0}}, // ( 12, 35) + {128, { 0, 0, 0}}, // ( 13, 35) + {128, { 0, 0, 0}}, // ( 14, 35) + {128, { 0, 0, 0}}, // ( 15, 35) + {128, { 0, 0, 0}}, // ( 16, 35) + {128, { 0, 0, 0}}, // ( 17, 35) + {128, { 0, 0, 0}}, // ( 18, 35) + {128, { 0, 0, 0}}, // ( 19, 35) + {111, { 0, 0, 0}}, // ( 20, 35) + { 9, { 0, 0, 0}}, // ( 21, 35) + { 0, { 0, 0, 0}}, // ( 22, 35) + { 0, { 0, 0, 0}}, // ( 23, 35) + { 0, { 0, 0, 0}}, // ( 24, 35) + { 0, { 0, 0, 0}}, // ( 25, 35) + { 0, { 0, 0, 0}}, // ( 26, 35) + { 0, { 0, 0, 0}}, // ( 27, 35) + { 0, { 0, 0, 0}}, // ( 28, 35) + { 0, { 0, 0, 0}}, // ( 29, 35) + { 0, { 0, 0, 0}}, // ( 30, 35) + { 0, { 0, 0, 0}}, // ( 31, 35) + { 0, { 0, 0, 0}}, // ( 32, 35) + { 0, { 0, 0, 0}}, // ( 33, 35) + { 0, { 0, 0, 0}}, // ( 34, 35) + { 0, { 0, 0, 0}}, // ( 35, 35) + { 0, { 0, 0, 0}}, // ( 36, 35) + { 0, { 0, 0, 0}}, // ( 37, 35) + { 0, { 0, 0, 0}}, // ( 38, 35) + { 0, { 0, 0, 0}}, // ( 39, 35) + { 0, { 0, 0, 0}}, // ( 40, 35) + { 0, { 0, 0, 0}}, // ( 41, 35) + { 0, { 0, 0, 0}}, // ( 42, 35) + { 0, { 0, 0, 0}}, // ( 43, 35) + { 0, { 0, 0, 0}}, // ( 44, 35) + { 0, { 0, 0, 0}}, // ( 45, 35) + { 0, { 0, 0, 0}}, // ( 46, 35) + { 0, { 0, 0, 0}}, // ( 47, 35) + { 0, { 0, 0, 0}}, // ( 48, 35) + { 0, { 0, 0, 0}}, // ( 49, 35) + { 0, { 0, 0, 0}}, // ( 50, 35) + { 0, { 0, 0, 0}}, // ( 51, 35) + { 0, { 0, 0, 0}}, // ( 52, 35) + { 0, { 0, 0, 0}}, // ( 53, 35) + { 0, { 0, 0, 0}}, // ( 54, 35) + { 0, { 0, 0, 0}}, // ( 55, 35) + { 0, { 0, 0, 0}}, // ( 56, 35) + { 0, { 0, 0, 0}}, // ( 57, 35) + { 0, { 0, 0, 0}}, // ( 58, 35) + { 0, { 0, 0, 0}}, // ( 59, 35) + { 0, { 0, 0, 0}}, // ( 60, 35) + { 0, { 0, 0, 0}}, // ( 61, 35) + { 0, { 0, 0, 0}}, // ( 62, 35) + { 0, { 0, 0, 0}}, // ( 63, 35) + { 0, { 0, 0, 0}}, // ( 64, 35) + { 0, { 0, 0, 0}}, // ( 65, 35) + { 0, { 0, 0, 0}}, // ( 66, 35) + { 0, { 0, 0, 0}}, // ( 67, 35) + { 0, { 0, 0, 0}}, // ( 68, 35) + { 0, { 0, 0, 0}}, // ( 69, 35) + { 0, { 0, 0, 0}}, // ( 70, 35) + { 0, { 0, 0, 0}}, // ( 71, 35) + { 0, { 0, 0, 0}}, // ( 72, 35) + { 0, { 0, 0, 0}}, // ( 73, 35) + { 0, { 0, 0, 0}}, // ( 74, 35) + { 0, { 0, 0, 0}}, // ( 75, 35) + { 0, { 0, 0, 0}}, // ( 76, 35) + { 0, { 0, 0, 0}}, // ( 77, 35) + { 0, { 0, 0, 0}}, // ( 78, 35) + { 0, { 0, 0, 0}}, // ( 79, 35) + { 0, { 0, 0, 0}}, // ( 80, 35) + { 0, { 0, 0, 0}}, // ( 81, 35) + { 0, { 0, 0, 0}}, // ( 82, 35) + { 0, { 0, 0, 0}}, // ( 83, 35) + { 0, { 0, 0, 0}}, // ( 84, 35) + { 0, { 0, 0, 0}}, // ( 85, 35) + { 0, { 0, 0, 0}}, // ( 86, 35) + { 0, { 0, 0, 0}}, // ( 87, 35) + { 0, { 0, 0, 0}}, // ( 88, 35) + { 0, { 0, 0, 0}}, // ( 89, 35) + { 0, { 0, 0, 0}}, // ( 90, 35) + { 0, { 0, 0, 0}}, // ( 91, 35) + { 0, { 0, 0, 0}}, // ( 92, 35) + { 0, { 0, 0, 0}}, // ( 93, 35) + { 0, { 0, 0, 0}}, // ( 94, 35) + { 0, { 0, 0, 0}}, // ( 95, 35) + { 0, { 0, 0, 0}}, // ( 96, 35) + { 0, { 0, 0, 0}}, // ( 97, 35) + { 0, { 0, 0, 0}}, // ( 98, 35) + { 0, { 0, 0, 0}}, // ( 99, 35) + { 0, { 0, 0, 0}}, // (100, 35) + { 0, { 0, 0, 0}}, // (101, 35) + { 0, { 0, 0, 0}}, // (102, 35) + { 0, { 0, 0, 0}}, // (103, 35) + { 0, { 0, 0, 0}}, // (104, 35) + { 0, { 0, 0, 0}}, // (105, 35) + { 0, { 0, 0, 0}}, // (106, 35) + { 0, { 0, 0, 0}}, // (107, 35) + { 0, { 0, 0, 0}}, // (108, 35) + { 0, { 0, 0, 0}}, // (109, 35) + { 0, { 0, 0, 0}}, // (110, 35) + { 0, { 0, 0, 0}}, // (111, 35) + { 0, { 0, 0, 0}}, // (112, 35) + { 0, { 0, 0, 0}}, // (113, 35) + { 0, { 0, 0, 0}}, // (114, 35) + { 0, { 0, 0, 0}}, // (115, 35) + { 0, { 0, 0, 0}}, // (116, 35) + { 0, { 0, 0, 0}}, // (117, 35) + { 0, { 0, 0, 0}}, // (118, 35) + { 0, { 0, 0, 0}}, // (119, 35) + { 0, { 0, 0, 0}}, // (120, 35) + { 0, { 0, 0, 0}}, // (121, 35) + { 0, { 0, 0, 0}}, // (122, 35) + { 0, { 0, 0, 0}}, // (123, 35) + { 0, { 0, 0, 0}}, // (124, 35) + { 0, { 0, 0, 0}}, // (125, 35) + { 0, { 0, 0, 0}}, // (126, 35) + { 0, { 0, 0, 0}}, // (127, 35) + { 0, { 0, 0, 0}}, // (128, 35) + { 0, { 0, 0, 0}}, // (129, 35) + { 0, { 0, 0, 0}}, // (130, 35) + { 0, { 0, 0, 0}}, // (131, 35) + { 0, { 0, 0, 0}}, // (132, 35) + { 0, { 0, 0, 0}}, // (133, 35) + { 0, { 0, 0, 0}}, // (134, 35) + { 0, { 0, 0, 0}}, // (135, 35) + { 0, { 0, 0, 0}}, // (136, 35) + { 0, { 0, 0, 0}}, // (137, 35) + { 0, { 0, 0, 0}}, // (138, 35) + { 0, { 0, 0, 0}}, // (139, 35) + { 0, { 0, 0, 0}}, // (140, 35) + { 0, { 0, 0, 0}}, // (141, 35) + { 0, { 0, 0, 0}}, // (142, 35) + { 0, { 0, 0, 0}}, // (143, 35) + { 0, { 0, 0, 0}}, // (144, 35) + { 0, { 0, 0, 0}}, // (145, 35) + { 0, { 0, 0, 0}}, // (146, 35) + { 0, { 0, 0, 0}}, // (147, 35) + { 0, { 0, 0, 0}}, // (148, 35) + { 0, { 0, 0, 0}}, // (149, 35) + { 0, { 0, 0, 0}}, // (150, 35) + { 0, { 0, 0, 0}}, // (151, 35) + { 0, { 0, 0, 0}}, // (152, 35) + { 0, { 0, 0, 0}}, // (153, 35) + { 0, { 0, 0, 0}}, // (154, 35) + { 0, { 0, 0, 0}}, // (155, 35) + { 0, { 0, 0, 0}}, // (156, 35) + { 0, { 0, 0, 0}}, // (157, 35) + { 9, { 0, 0, 0}}, // (158, 35) + {111, { 0, 0, 0}}, // (159, 35) + {128, { 0, 0, 0}}, // (160, 35) + {128, { 0, 0, 0}}, // (161, 35) + {128, { 0, 0, 0}}, // (162, 35) + {128, { 0, 0, 0}}, // (163, 35) + {128, { 0, 0, 0}}, // (164, 35) + {128, { 0, 0, 0}}, // (165, 35) + {128, { 0, 0, 0}}, // (166, 35) + {128, { 0, 0, 0}}, // (167, 35) + {128, { 0, 0, 0}}, // (168, 35) + {128, { 0, 0, 0}}, // (169, 35) + {128, { 0, 0, 0}}, // (170, 35) + {128, { 0, 0, 0}}, // (171, 35) + {128, { 0, 0, 0}}, // (172, 35) + {128, { 0, 0, 0}}, // (173, 35) + {128, { 0, 0, 0}}, // (174, 35) + {128, { 0, 0, 0}}, // (175, 35) + {128, { 0, 0, 0}}, // (176, 35) + {128, { 0, 0, 0}}, // (177, 35) + {128, { 0, 0, 0}}, // (178, 35) + {128, { 0, 0, 0}}, // (179, 35) + {128, { 0, 0, 0}}, // ( 0, 36) + {128, { 0, 0, 0}}, // ( 1, 36) + {128, { 0, 0, 0}}, // ( 2, 36) + {128, { 0, 0, 0}}, // ( 3, 36) + {128, { 0, 0, 0}}, // ( 4, 36) + {128, { 0, 0, 0}}, // ( 5, 36) + {128, { 0, 0, 0}}, // ( 6, 36) + {128, { 0, 0, 0}}, // ( 7, 36) + {128, { 0, 0, 0}}, // ( 8, 36) + {128, { 0, 0, 0}}, // ( 9, 36) + {128, { 0, 0, 0}}, // ( 10, 36) + {128, { 0, 0, 0}}, // ( 11, 36) + {128, { 0, 0, 0}}, // ( 12, 36) + {128, { 0, 0, 0}}, // ( 13, 36) + {128, { 0, 0, 0}}, // ( 14, 36) + {128, { 0, 0, 0}}, // ( 15, 36) + {128, { 0, 0, 0}}, // ( 16, 36) + {128, { 0, 0, 0}}, // ( 17, 36) + {128, { 0, 0, 0}}, // ( 18, 36) + {123, { 0, 0, 0}}, // ( 19, 36) + { 24, { 0, 0, 0}}, // ( 20, 36) + { 0, { 0, 0, 0}}, // ( 21, 36) + { 0, { 0, 0, 0}}, // ( 22, 36) + { 0, { 0, 0, 0}}, // ( 23, 36) + { 0, { 0, 0, 0}}, // ( 24, 36) + { 0, { 0, 0, 0}}, // ( 25, 36) + { 0, { 0, 0, 0}}, // ( 26, 36) + { 0, { 0, 0, 0}}, // ( 27, 36) + { 0, { 0, 0, 0}}, // ( 28, 36) + { 0, { 0, 0, 0}}, // ( 29, 36) + { 0, { 0, 0, 0}}, // ( 30, 36) + { 0, { 0, 0, 0}}, // ( 31, 36) + { 0, { 0, 0, 0}}, // ( 32, 36) + { 0, { 0, 0, 0}}, // ( 33, 36) + { 0, { 0, 0, 0}}, // ( 34, 36) + { 0, { 0, 0, 0}}, // ( 35, 36) + { 0, { 0, 0, 0}}, // ( 36, 36) + { 0, { 0, 0, 0}}, // ( 37, 36) + { 0, { 0, 0, 0}}, // ( 38, 36) + { 0, { 0, 0, 0}}, // ( 39, 36) + { 0, { 0, 0, 0}}, // ( 40, 36) + { 0, { 0, 0, 0}}, // ( 41, 36) + { 0, { 0, 0, 0}}, // ( 42, 36) + { 0, { 0, 0, 0}}, // ( 43, 36) + { 0, { 0, 0, 0}}, // ( 44, 36) + { 0, { 0, 0, 0}}, // ( 45, 36) + { 0, { 0, 0, 0}}, // ( 46, 36) + { 0, { 0, 0, 0}}, // ( 47, 36) + { 0, { 0, 0, 0}}, // ( 48, 36) + { 0, { 0, 0, 0}}, // ( 49, 36) + { 0, { 0, 0, 0}}, // ( 50, 36) + { 0, { 0, 0, 0}}, // ( 51, 36) + { 0, { 0, 0, 0}}, // ( 52, 36) + { 0, { 0, 0, 0}}, // ( 53, 36) + { 0, { 0, 0, 0}}, // ( 54, 36) + { 0, { 0, 0, 0}}, // ( 55, 36) + { 0, { 0, 0, 0}}, // ( 56, 36) + { 0, { 0, 0, 0}}, // ( 57, 36) + { 0, { 0, 0, 0}}, // ( 58, 36) + { 0, { 0, 0, 0}}, // ( 59, 36) + { 0, { 0, 0, 0}}, // ( 60, 36) + { 0, { 0, 0, 0}}, // ( 61, 36) + { 0, { 0, 0, 0}}, // ( 62, 36) + { 0, { 0, 0, 0}}, // ( 63, 36) + { 0, { 0, 0, 0}}, // ( 64, 36) + { 0, { 0, 0, 0}}, // ( 65, 36) + { 0, { 0, 0, 0}}, // ( 66, 36) + { 0, { 0, 0, 0}}, // ( 67, 36) + { 0, { 0, 0, 0}}, // ( 68, 36) + { 0, { 0, 0, 0}}, // ( 69, 36) + { 0, { 0, 0, 0}}, // ( 70, 36) + { 0, { 0, 0, 0}}, // ( 71, 36) + { 0, { 0, 0, 0}}, // ( 72, 36) + { 0, { 0, 0, 0}}, // ( 73, 36) + { 0, { 0, 0, 0}}, // ( 74, 36) + { 0, { 0, 0, 0}}, // ( 75, 36) + { 0, { 0, 0, 0}}, // ( 76, 36) + { 0, { 0, 0, 0}}, // ( 77, 36) + { 0, { 0, 0, 0}}, // ( 78, 36) + { 0, { 0, 0, 0}}, // ( 79, 36) + { 0, { 0, 0, 0}}, // ( 80, 36) + { 0, { 0, 0, 0}}, // ( 81, 36) + { 0, { 0, 0, 0}}, // ( 82, 36) + { 0, { 0, 0, 0}}, // ( 83, 36) + { 0, { 0, 0, 0}}, // ( 84, 36) + { 0, { 0, 0, 0}}, // ( 85, 36) + { 0, { 0, 0, 0}}, // ( 86, 36) + { 0, { 0, 0, 0}}, // ( 87, 36) + { 0, { 0, 0, 0}}, // ( 88, 36) + { 0, { 0, 0, 0}}, // ( 89, 36) + { 0, { 0, 0, 0}}, // ( 90, 36) + { 0, { 0, 0, 0}}, // ( 91, 36) + { 0, { 0, 0, 0}}, // ( 92, 36) + { 0, { 0, 0, 0}}, // ( 93, 36) + { 0, { 0, 0, 0}}, // ( 94, 36) + { 0, { 0, 0, 0}}, // ( 95, 36) + { 0, { 0, 0, 0}}, // ( 96, 36) + { 0, { 0, 0, 0}}, // ( 97, 36) + { 0, { 0, 0, 0}}, // ( 98, 36) + { 0, { 0, 0, 0}}, // ( 99, 36) + { 0, { 0, 0, 0}}, // (100, 36) + { 0, { 0, 0, 0}}, // (101, 36) + { 0, { 0, 0, 0}}, // (102, 36) + { 0, { 0, 0, 0}}, // (103, 36) + { 0, { 0, 0, 0}}, // (104, 36) + { 0, { 0, 0, 0}}, // (105, 36) + { 0, { 0, 0, 0}}, // (106, 36) + { 0, { 0, 0, 0}}, // (107, 36) + { 0, { 0, 0, 0}}, // (108, 36) + { 0, { 0, 0, 0}}, // (109, 36) + { 0, { 0, 0, 0}}, // (110, 36) + { 0, { 0, 0, 0}}, // (111, 36) + { 0, { 0, 0, 0}}, // (112, 36) + { 0, { 0, 0, 0}}, // (113, 36) + { 0, { 0, 0, 0}}, // (114, 36) + { 0, { 0, 0, 0}}, // (115, 36) + { 0, { 0, 0, 0}}, // (116, 36) + { 0, { 0, 0, 0}}, // (117, 36) + { 0, { 0, 0, 0}}, // (118, 36) + { 0, { 0, 0, 0}}, // (119, 36) + { 0, { 0, 0, 0}}, // (120, 36) + { 0, { 0, 0, 0}}, // (121, 36) + { 0, { 0, 0, 0}}, // (122, 36) + { 0, { 0, 0, 0}}, // (123, 36) + { 0, { 0, 0, 0}}, // (124, 36) + { 0, { 0, 0, 0}}, // (125, 36) + { 0, { 0, 0, 0}}, // (126, 36) + { 0, { 0, 0, 0}}, // (127, 36) + { 0, { 0, 0, 0}}, // (128, 36) + { 0, { 0, 0, 0}}, // (129, 36) + { 0, { 0, 0, 0}}, // (130, 36) + { 0, { 0, 0, 0}}, // (131, 36) + { 0, { 0, 0, 0}}, // (132, 36) + { 0, { 0, 0, 0}}, // (133, 36) + { 0, { 0, 0, 0}}, // (134, 36) + { 0, { 0, 0, 0}}, // (135, 36) + { 0, { 0, 0, 0}}, // (136, 36) + { 0, { 0, 0, 0}}, // (137, 36) + { 0, { 0, 0, 0}}, // (138, 36) + { 0, { 0, 0, 0}}, // (139, 36) + { 0, { 0, 0, 0}}, // (140, 36) + { 0, { 0, 0, 0}}, // (141, 36) + { 0, { 0, 0, 0}}, // (142, 36) + { 0, { 0, 0, 0}}, // (143, 36) + { 0, { 0, 0, 0}}, // (144, 36) + { 0, { 0, 0, 0}}, // (145, 36) + { 0, { 0, 0, 0}}, // (146, 36) + { 0, { 0, 0, 0}}, // (147, 36) + { 0, { 0, 0, 0}}, // (148, 36) + { 0, { 0, 0, 0}}, // (149, 36) + { 0, { 0, 0, 0}}, // (150, 36) + { 0, { 0, 0, 0}}, // (151, 36) + { 0, { 0, 0, 0}}, // (152, 36) + { 0, { 0, 0, 0}}, // (153, 36) + { 0, { 0, 0, 0}}, // (154, 36) + { 0, { 0, 0, 0}}, // (155, 36) + { 0, { 0, 0, 0}}, // (156, 36) + { 0, { 0, 0, 0}}, // (157, 36) + { 0, { 0, 0, 0}}, // (158, 36) + { 24, { 0, 0, 0}}, // (159, 36) + {123, { 0, 0, 0}}, // (160, 36) + {128, { 0, 0, 0}}, // (161, 36) + {128, { 0, 0, 0}}, // (162, 36) + {128, { 0, 0, 0}}, // (163, 36) + {128, { 0, 0, 0}}, // (164, 36) + {128, { 0, 0, 0}}, // (165, 36) + {128, { 0, 0, 0}}, // (166, 36) + {128, { 0, 0, 0}}, // (167, 36) + {128, { 0, 0, 0}}, // (168, 36) + {128, { 0, 0, 0}}, // (169, 36) + {128, { 0, 0, 0}}, // (170, 36) + {128, { 0, 0, 0}}, // (171, 36) + {128, { 0, 0, 0}}, // (172, 36) + {128, { 0, 0, 0}}, // (173, 36) + {128, { 0, 0, 0}}, // (174, 36) + {128, { 0, 0, 0}}, // (175, 36) + {128, { 0, 0, 0}}, // (176, 36) + {128, { 0, 0, 0}}, // (177, 36) + {128, { 0, 0, 0}}, // (178, 36) + {128, { 0, 0, 0}}, // (179, 36) + {128, { 0, 0, 0}}, // ( 0, 37) + {128, { 0, 0, 0}}, // ( 1, 37) + {128, { 0, 0, 0}}, // ( 2, 37) + {128, { 0, 0, 0}}, // ( 3, 37) + {128, { 0, 0, 0}}, // ( 4, 37) + {128, { 0, 0, 0}}, // ( 5, 37) + {128, { 0, 0, 0}}, // ( 6, 37) + {128, { 0, 0, 0}}, // ( 7, 37) + {128, { 0, 0, 0}}, // ( 8, 37) + {128, { 0, 0, 0}}, // ( 9, 37) + {128, { 0, 0, 0}}, // ( 10, 37) + {128, { 0, 0, 0}}, // ( 11, 37) + {128, { 0, 0, 0}}, // ( 12, 37) + {128, { 0, 0, 0}}, // ( 13, 37) + {128, { 0, 0, 0}}, // ( 14, 37) + {128, { 0, 0, 0}}, // ( 15, 37) + {128, { 0, 0, 0}}, // ( 16, 37) + {128, { 0, 0, 0}}, // ( 17, 37) + {128, { 0, 0, 0}}, // ( 18, 37) + { 49, { 0, 0, 0}}, // ( 19, 37) + { 0, { 0, 0, 0}}, // ( 20, 37) + { 0, { 0, 0, 0}}, // ( 21, 37) + { 0, { 0, 0, 0}}, // ( 22, 37) + { 0, { 0, 0, 0}}, // ( 23, 37) + { 0, { 0, 0, 0}}, // ( 24, 37) + { 0, { 0, 0, 0}}, // ( 25, 37) + { 0, { 0, 0, 0}}, // ( 26, 37) + { 0, { 0, 0, 0}}, // ( 27, 37) + { 0, { 0, 0, 0}}, // ( 28, 37) + { 0, { 0, 0, 0}}, // ( 29, 37) + { 0, { 0, 0, 0}}, // ( 30, 37) + { 0, { 0, 0, 0}}, // ( 31, 37) + { 0, { 0, 0, 0}}, // ( 32, 37) + { 0, { 0, 0, 0}}, // ( 33, 37) + { 0, { 0, 0, 0}}, // ( 34, 37) + { 0, { 0, 0, 0}}, // ( 35, 37) + { 0, { 0, 0, 0}}, // ( 36, 37) + { 0, { 0, 0, 0}}, // ( 37, 37) + { 0, { 0, 0, 0}}, // ( 38, 37) + { 0, { 0, 0, 0}}, // ( 39, 37) + { 0, { 0, 0, 0}}, // ( 40, 37) + { 0, { 0, 0, 0}}, // ( 41, 37) + { 0, { 0, 0, 0}}, // ( 42, 37) + { 0, { 0, 0, 0}}, // ( 43, 37) + { 0, { 0, 0, 0}}, // ( 44, 37) + { 0, { 0, 0, 0}}, // ( 45, 37) + { 0, { 0, 0, 0}}, // ( 46, 37) + { 0, { 0, 0, 0}}, // ( 47, 37) + { 0, { 0, 0, 0}}, // ( 48, 37) + { 0, { 0, 0, 0}}, // ( 49, 37) + { 0, { 0, 0, 0}}, // ( 50, 37) + { 0, { 0, 0, 0}}, // ( 51, 37) + { 0, { 0, 0, 0}}, // ( 52, 37) + { 0, { 0, 0, 0}}, // ( 53, 37) + { 0, { 0, 0, 0}}, // ( 54, 37) + { 0, { 0, 0, 0}}, // ( 55, 37) + { 0, { 0, 0, 0}}, // ( 56, 37) + { 0, { 0, 0, 0}}, // ( 57, 37) + { 0, { 0, 0, 0}}, // ( 58, 37) + { 0, { 0, 0, 0}}, // ( 59, 37) + { 0, { 0, 0, 0}}, // ( 60, 37) + { 0, { 0, 0, 0}}, // ( 61, 37) + { 0, { 0, 0, 0}}, // ( 62, 37) + { 0, { 0, 0, 0}}, // ( 63, 37) + { 0, { 0, 0, 0}}, // ( 64, 37) + { 0, { 0, 0, 0}}, // ( 65, 37) + { 0, { 0, 0, 0}}, // ( 66, 37) + { 0, { 0, 0, 0}}, // ( 67, 37) + { 0, { 0, 0, 0}}, // ( 68, 37) + { 0, { 0, 0, 0}}, // ( 69, 37) + { 0, { 0, 0, 0}}, // ( 70, 37) + { 0, { 0, 0, 0}}, // ( 71, 37) + { 0, { 0, 0, 0}}, // ( 72, 37) + { 0, { 0, 0, 0}}, // ( 73, 37) + { 0, { 0, 0, 0}}, // ( 74, 37) + { 0, { 0, 0, 0}}, // ( 75, 37) + { 0, { 0, 0, 0}}, // ( 76, 37) + { 0, { 0, 0, 0}}, // ( 77, 37) + { 0, { 0, 0, 0}}, // ( 78, 37) + { 0, { 0, 0, 0}}, // ( 79, 37) + { 0, { 0, 0, 0}}, // ( 80, 37) + { 0, { 0, 0, 0}}, // ( 81, 37) + { 0, { 0, 0, 0}}, // ( 82, 37) + { 0, { 0, 0, 0}}, // ( 83, 37) + { 0, { 0, 0, 0}}, // ( 84, 37) + { 0, { 0, 0, 0}}, // ( 85, 37) + { 0, { 0, 0, 0}}, // ( 86, 37) + { 0, { 0, 0, 0}}, // ( 87, 37) + { 0, { 0, 0, 0}}, // ( 88, 37) + { 0, { 0, 0, 0}}, // ( 89, 37) + { 0, { 0, 0, 0}}, // ( 90, 37) + { 0, { 0, 0, 0}}, // ( 91, 37) + { 0, { 0, 0, 0}}, // ( 92, 37) + { 0, { 0, 0, 0}}, // ( 93, 37) + { 0, { 0, 0, 0}}, // ( 94, 37) + { 0, { 0, 0, 0}}, // ( 95, 37) + { 0, { 0, 0, 0}}, // ( 96, 37) + { 0, { 0, 0, 0}}, // ( 97, 37) + { 0, { 0, 0, 0}}, // ( 98, 37) + { 0, { 0, 0, 0}}, // ( 99, 37) + { 0, { 0, 0, 0}}, // (100, 37) + { 0, { 0, 0, 0}}, // (101, 37) + { 0, { 0, 0, 0}}, // (102, 37) + { 0, { 0, 0, 0}}, // (103, 37) + { 0, { 0, 0, 0}}, // (104, 37) + { 0, { 0, 0, 0}}, // (105, 37) + { 0, { 0, 0, 0}}, // (106, 37) + { 0, { 0, 0, 0}}, // (107, 37) + { 0, { 0, 0, 0}}, // (108, 37) + { 0, { 0, 0, 0}}, // (109, 37) + { 0, { 0, 0, 0}}, // (110, 37) + { 0, { 0, 0, 0}}, // (111, 37) + { 0, { 0, 0, 0}}, // (112, 37) + { 0, { 0, 0, 0}}, // (113, 37) + { 0, { 0, 0, 0}}, // (114, 37) + { 0, { 0, 0, 0}}, // (115, 37) + { 0, { 0, 0, 0}}, // (116, 37) + { 0, { 0, 0, 0}}, // (117, 37) + { 0, { 0, 0, 0}}, // (118, 37) + { 0, { 0, 0, 0}}, // (119, 37) + { 0, { 0, 0, 0}}, // (120, 37) + { 0, { 0, 0, 0}}, // (121, 37) + { 0, { 0, 0, 0}}, // (122, 37) + { 0, { 0, 0, 0}}, // (123, 37) + { 0, { 0, 0, 0}}, // (124, 37) + { 0, { 0, 0, 0}}, // (125, 37) + { 0, { 0, 0, 0}}, // (126, 37) + { 0, { 0, 0, 0}}, // (127, 37) + { 0, { 0, 0, 0}}, // (128, 37) + { 0, { 0, 0, 0}}, // (129, 37) + { 0, { 0, 0, 0}}, // (130, 37) + { 0, { 0, 0, 0}}, // (131, 37) + { 0, { 0, 0, 0}}, // (132, 37) + { 0, { 0, 0, 0}}, // (133, 37) + { 0, { 0, 0, 0}}, // (134, 37) + { 0, { 0, 0, 0}}, // (135, 37) + { 0, { 0, 0, 0}}, // (136, 37) + { 0, { 0, 0, 0}}, // (137, 37) + { 0, { 0, 0, 0}}, // (138, 37) + { 0, { 0, 0, 0}}, // (139, 37) + { 0, { 0, 0, 0}}, // (140, 37) + { 0, { 0, 0, 0}}, // (141, 37) + { 0, { 0, 0, 0}}, // (142, 37) + { 0, { 0, 0, 0}}, // (143, 37) + { 0, { 0, 0, 0}}, // (144, 37) + { 0, { 0, 0, 0}}, // (145, 37) + { 0, { 0, 0, 0}}, // (146, 37) + { 0, { 0, 0, 0}}, // (147, 37) + { 0, { 0, 0, 0}}, // (148, 37) + { 0, { 0, 0, 0}}, // (149, 37) + { 0, { 0, 0, 0}}, // (150, 37) + { 0, { 0, 0, 0}}, // (151, 37) + { 0, { 0, 0, 0}}, // (152, 37) + { 0, { 0, 0, 0}}, // (153, 37) + { 0, { 0, 0, 0}}, // (154, 37) + { 0, { 0, 0, 0}}, // (155, 37) + { 0, { 0, 0, 0}}, // (156, 37) + { 0, { 0, 0, 0}}, // (157, 37) + { 0, { 0, 0, 0}}, // (158, 37) + { 0, { 0, 0, 0}}, // (159, 37) + { 49, { 0, 0, 0}}, // (160, 37) + {128, { 0, 0, 0}}, // (161, 37) + {128, { 0, 0, 0}}, // (162, 37) + {128, { 0, 0, 0}}, // (163, 37) + {128, { 0, 0, 0}}, // (164, 37) + {128, { 0, 0, 0}}, // (165, 37) + {128, { 0, 0, 0}}, // (166, 37) + {128, { 0, 0, 0}}, // (167, 37) + {128, { 0, 0, 0}}, // (168, 37) + {128, { 0, 0, 0}}, // (169, 37) + {128, { 0, 0, 0}}, // (170, 37) + {128, { 0, 0, 0}}, // (171, 37) + {128, { 0, 0, 0}}, // (172, 37) + {128, { 0, 0, 0}}, // (173, 37) + {128, { 0, 0, 0}}, // (174, 37) + {128, { 0, 0, 0}}, // (175, 37) + {128, { 0, 0, 0}}, // (176, 37) + {128, { 0, 0, 0}}, // (177, 37) + {128, { 0, 0, 0}}, // (178, 37) + {128, { 0, 0, 0}}, // (179, 37) + {128, { 0, 0, 0}}, // ( 0, 38) + {128, { 0, 0, 0}}, // ( 1, 38) + {128, { 0, 0, 0}}, // ( 2, 38) + {128, { 0, 0, 0}}, // ( 3, 38) + {128, { 0, 0, 0}}, // ( 4, 38) + {128, { 0, 0, 0}}, // ( 5, 38) + {128, { 0, 0, 0}}, // ( 6, 38) + {128, { 0, 0, 0}}, // ( 7, 38) + {128, { 0, 0, 0}}, // ( 8, 38) + {128, { 0, 0, 0}}, // ( 9, 38) + {128, { 0, 0, 0}}, // ( 10, 38) + {128, { 0, 0, 0}}, // ( 11, 38) + {128, { 0, 0, 0}}, // ( 12, 38) + {128, { 0, 0, 0}}, // ( 13, 38) + {128, { 0, 0, 0}}, // ( 14, 38) + {128, { 0, 0, 0}}, // ( 15, 38) + {128, { 0, 0, 0}}, // ( 16, 38) + {128, { 0, 0, 0}}, // ( 17, 38) + { 82, { 0, 0, 0}}, // ( 18, 38) + { 0, { 0, 0, 0}}, // ( 19, 38) + { 0, { 0, 0, 0}}, // ( 20, 38) + { 0, { 0, 0, 0}}, // ( 21, 38) + { 0, { 0, 0, 0}}, // ( 22, 38) + { 0, { 0, 0, 0}}, // ( 23, 38) + { 0, { 0, 0, 0}}, // ( 24, 38) + { 0, { 0, 0, 0}}, // ( 25, 38) + { 0, { 0, 0, 0}}, // ( 26, 38) + { 0, { 0, 0, 0}}, // ( 27, 38) + { 0, { 0, 0, 0}}, // ( 28, 38) + { 0, { 0, 0, 0}}, // ( 29, 38) + { 0, { 0, 0, 0}}, // ( 30, 38) + { 0, { 0, 0, 0}}, // ( 31, 38) + { 0, { 0, 0, 0}}, // ( 32, 38) + { 0, { 0, 0, 0}}, // ( 33, 38) + { 0, { 0, 0, 0}}, // ( 34, 38) + { 0, { 0, 0, 0}}, // ( 35, 38) + { 0, { 0, 0, 0}}, // ( 36, 38) + { 0, { 0, 0, 0}}, // ( 37, 38) + { 0, { 0, 0, 0}}, // ( 38, 38) + { 0, { 0, 0, 0}}, // ( 39, 38) + { 0, { 0, 0, 0}}, // ( 40, 38) + { 0, { 0, 0, 0}}, // ( 41, 38) + { 0, { 0, 0, 0}}, // ( 42, 38) + { 0, { 0, 0, 0}}, // ( 43, 38) + { 0, { 0, 0, 0}}, // ( 44, 38) + { 0, { 0, 0, 0}}, // ( 45, 38) + { 0, { 0, 0, 0}}, // ( 46, 38) + { 0, { 0, 0, 0}}, // ( 47, 38) + { 0, { 0, 0, 0}}, // ( 48, 38) + { 0, { 0, 0, 0}}, // ( 49, 38) + { 0, { 0, 0, 0}}, // ( 50, 38) + { 0, { 0, 0, 0}}, // ( 51, 38) + { 0, { 0, 0, 0}}, // ( 52, 38) + { 0, { 0, 0, 0}}, // ( 53, 38) + { 0, { 0, 0, 0}}, // ( 54, 38) + { 0, { 0, 0, 0}}, // ( 55, 38) + { 0, { 0, 0, 0}}, // ( 56, 38) + { 0, { 0, 0, 0}}, // ( 57, 38) + { 0, { 0, 0, 0}}, // ( 58, 38) + { 0, { 0, 0, 0}}, // ( 59, 38) + { 0, { 0, 0, 0}}, // ( 60, 38) + { 0, { 0, 0, 0}}, // ( 61, 38) + { 0, { 0, 0, 0}}, // ( 62, 38) + { 0, { 0, 0, 0}}, // ( 63, 38) + { 0, { 0, 0, 0}}, // ( 64, 38) + { 0, { 0, 0, 0}}, // ( 65, 38) + { 0, { 0, 0, 0}}, // ( 66, 38) + { 0, { 0, 0, 0}}, // ( 67, 38) + { 0, { 0, 0, 0}}, // ( 68, 38) + { 0, { 0, 0, 0}}, // ( 69, 38) + { 0, { 0, 0, 0}}, // ( 70, 38) + { 0, { 0, 0, 0}}, // ( 71, 38) + { 0, { 0, 0, 0}}, // ( 72, 38) + { 0, { 0, 0, 0}}, // ( 73, 38) + { 0, { 0, 0, 0}}, // ( 74, 38) + { 0, { 0, 0, 0}}, // ( 75, 38) + { 0, { 0, 0, 0}}, // ( 76, 38) + { 0, { 0, 0, 0}}, // ( 77, 38) + { 0, { 0, 0, 0}}, // ( 78, 38) + { 0, { 0, 0, 0}}, // ( 79, 38) + { 0, { 0, 0, 0}}, // ( 80, 38) + { 0, { 0, 0, 0}}, // ( 81, 38) + { 0, { 0, 0, 0}}, // ( 82, 38) + { 0, { 0, 0, 0}}, // ( 83, 38) + { 0, { 0, 0, 0}}, // ( 84, 38) + { 0, { 0, 0, 0}}, // ( 85, 38) + { 0, { 0, 0, 0}}, // ( 86, 38) + { 0, { 0, 0, 0}}, // ( 87, 38) + { 0, { 0, 0, 0}}, // ( 88, 38) + { 0, { 0, 0, 0}}, // ( 89, 38) + { 0, { 0, 0, 0}}, // ( 90, 38) + { 0, { 0, 0, 0}}, // ( 91, 38) + { 0, { 0, 0, 0}}, // ( 92, 38) + { 0, { 0, 0, 0}}, // ( 93, 38) + { 0, { 0, 0, 0}}, // ( 94, 38) + { 0, { 0, 0, 0}}, // ( 95, 38) + { 0, { 0, 0, 0}}, // ( 96, 38) + { 0, { 0, 0, 0}}, // ( 97, 38) + { 0, { 0, 0, 0}}, // ( 98, 38) + { 0, { 0, 0, 0}}, // ( 99, 38) + { 0, { 0, 0, 0}}, // (100, 38) + { 0, { 0, 0, 0}}, // (101, 38) + { 0, { 0, 0, 0}}, // (102, 38) + { 0, { 0, 0, 0}}, // (103, 38) + { 0, { 0, 0, 0}}, // (104, 38) + { 0, { 0, 0, 0}}, // (105, 38) + { 0, { 0, 0, 0}}, // (106, 38) + { 0, { 0, 0, 0}}, // (107, 38) + { 0, { 0, 0, 0}}, // (108, 38) + { 0, { 0, 0, 0}}, // (109, 38) + { 0, { 0, 0, 0}}, // (110, 38) + { 0, { 0, 0, 0}}, // (111, 38) + { 0, { 0, 0, 0}}, // (112, 38) + { 0, { 0, 0, 0}}, // (113, 38) + { 0, { 0, 0, 0}}, // (114, 38) + { 0, { 0, 0, 0}}, // (115, 38) + { 0, { 0, 0, 0}}, // (116, 38) + { 0, { 0, 0, 0}}, // (117, 38) + { 0, { 0, 0, 0}}, // (118, 38) + { 0, { 0, 0, 0}}, // (119, 38) + { 0, { 0, 0, 0}}, // (120, 38) + { 0, { 0, 0, 0}}, // (121, 38) + { 0, { 0, 0, 0}}, // (122, 38) + { 0, { 0, 0, 0}}, // (123, 38) + { 0, { 0, 0, 0}}, // (124, 38) + { 0, { 0, 0, 0}}, // (125, 38) + { 0, { 0, 0, 0}}, // (126, 38) + { 0, { 0, 0, 0}}, // (127, 38) + { 0, { 0, 0, 0}}, // (128, 38) + { 0, { 0, 0, 0}}, // (129, 38) + { 0, { 0, 0, 0}}, // (130, 38) + { 0, { 0, 0, 0}}, // (131, 38) + { 0, { 0, 0, 0}}, // (132, 38) + { 0, { 0, 0, 0}}, // (133, 38) + { 0, { 0, 0, 0}}, // (134, 38) + { 0, { 0, 0, 0}}, // (135, 38) + { 0, { 0, 0, 0}}, // (136, 38) + { 0, { 0, 0, 0}}, // (137, 38) + { 0, { 0, 0, 0}}, // (138, 38) + { 0, { 0, 0, 0}}, // (139, 38) + { 0, { 0, 0, 0}}, // (140, 38) + { 0, { 0, 0, 0}}, // (141, 38) + { 0, { 0, 0, 0}}, // (142, 38) + { 0, { 0, 0, 0}}, // (143, 38) + { 0, { 0, 0, 0}}, // (144, 38) + { 0, { 0, 0, 0}}, // (145, 38) + { 0, { 0, 0, 0}}, // (146, 38) + { 0, { 0, 0, 0}}, // (147, 38) + { 0, { 0, 0, 0}}, // (148, 38) + { 0, { 0, 0, 0}}, // (149, 38) + { 0, { 0, 0, 0}}, // (150, 38) + { 0, { 0, 0, 0}}, // (151, 38) + { 0, { 0, 0, 0}}, // (152, 38) + { 0, { 0, 0, 0}}, // (153, 38) + { 0, { 0, 0, 0}}, // (154, 38) + { 0, { 0, 0, 0}}, // (155, 38) + { 0, { 0, 0, 0}}, // (156, 38) + { 0, { 0, 0, 0}}, // (157, 38) + { 0, { 0, 0, 0}}, // (158, 38) + { 0, { 0, 0, 0}}, // (159, 38) + { 0, { 0, 0, 0}}, // (160, 38) + { 82, { 0, 0, 0}}, // (161, 38) + {128, { 0, 0, 0}}, // (162, 38) + {128, { 0, 0, 0}}, // (163, 38) + {128, { 0, 0, 0}}, // (164, 38) + {128, { 0, 0, 0}}, // (165, 38) + {128, { 0, 0, 0}}, // (166, 38) + {128, { 0, 0, 0}}, // (167, 38) + {128, { 0, 0, 0}}, // (168, 38) + {128, { 0, 0, 0}}, // (169, 38) + {128, { 0, 0, 0}}, // (170, 38) + {128, { 0, 0, 0}}, // (171, 38) + {128, { 0, 0, 0}}, // (172, 38) + {128, { 0, 0, 0}}, // (173, 38) + {128, { 0, 0, 0}}, // (174, 38) + {128, { 0, 0, 0}}, // (175, 38) + {128, { 0, 0, 0}}, // (176, 38) + {128, { 0, 0, 0}}, // (177, 38) + {128, { 0, 0, 0}}, // (178, 38) + {128, { 0, 0, 0}}, // (179, 38) + {128, { 0, 0, 0}}, // ( 0, 39) + {128, { 0, 0, 0}}, // ( 1, 39) + {128, { 0, 0, 0}}, // ( 2, 39) + {128, { 0, 0, 0}}, // ( 3, 39) + {128, { 0, 0, 0}}, // ( 4, 39) + {128, { 0, 0, 0}}, // ( 5, 39) + {128, { 0, 0, 0}}, // ( 6, 39) + {128, { 0, 0, 0}}, // ( 7, 39) + {128, { 0, 0, 0}}, // ( 8, 39) + {128, { 0, 0, 0}}, // ( 9, 39) + {128, { 0, 0, 0}}, // ( 10, 39) + {128, { 0, 0, 0}}, // ( 11, 39) + {128, { 0, 0, 0}}, // ( 12, 39) + {128, { 0, 0, 0}}, // ( 13, 39) + {128, { 0, 0, 0}}, // ( 14, 39) + {128, { 0, 0, 0}}, // ( 15, 39) + {128, { 0, 0, 0}}, // ( 16, 39) + {112, { 0, 0, 0}}, // ( 17, 39) + { 7, { 0, 0, 0}}, // ( 18, 39) + { 0, { 0, 0, 0}}, // ( 19, 39) + { 0, { 0, 0, 0}}, // ( 20, 39) + { 0, { 0, 0, 0}}, // ( 21, 39) + { 0, { 0, 0, 0}}, // ( 22, 39) + { 0, { 0, 0, 0}}, // ( 23, 39) + { 0, { 0, 0, 0}}, // ( 24, 39) + { 0, { 0, 0, 0}}, // ( 25, 39) + { 0, { 0, 0, 0}}, // ( 26, 39) + { 0, { 0, 0, 0}}, // ( 27, 39) + { 0, { 0, 0, 0}}, // ( 28, 39) + { 0, { 0, 0, 0}}, // ( 29, 39) + { 0, { 0, 0, 0}}, // ( 30, 39) + { 0, { 0, 0, 0}}, // ( 31, 39) + { 0, { 0, 0, 0}}, // ( 32, 39) + { 0, { 0, 0, 0}}, // ( 33, 39) + { 0, { 0, 0, 0}}, // ( 34, 39) + { 0, { 0, 0, 0}}, // ( 35, 39) + { 0, { 0, 0, 0}}, // ( 36, 39) + { 0, { 0, 0, 0}}, // ( 37, 39) + { 0, { 0, 0, 0}}, // ( 38, 39) + { 0, { 0, 0, 0}}, // ( 39, 39) + { 0, { 0, 0, 0}}, // ( 40, 39) + { 0, { 0, 0, 0}}, // ( 41, 39) + { 0, { 0, 0, 0}}, // ( 42, 39) + { 0, { 0, 0, 0}}, // ( 43, 39) + { 0, { 0, 0, 0}}, // ( 44, 39) + { 0, { 0, 0, 0}}, // ( 45, 39) + { 0, { 0, 0, 0}}, // ( 46, 39) + { 0, { 0, 0, 0}}, // ( 47, 39) + { 0, { 0, 0, 0}}, // ( 48, 39) + { 0, { 0, 0, 0}}, // ( 49, 39) + { 0, { 0, 0, 0}}, // ( 50, 39) + { 0, { 0, 0, 0}}, // ( 51, 39) + { 0, { 0, 0, 0}}, // ( 52, 39) + { 0, { 0, 0, 0}}, // ( 53, 39) + { 0, { 0, 0, 0}}, // ( 54, 39) + { 0, { 0, 0, 0}}, // ( 55, 39) + { 0, { 0, 0, 0}}, // ( 56, 39) + { 0, { 0, 0, 0}}, // ( 57, 39) + { 0, { 0, 0, 0}}, // ( 58, 39) + { 0, { 0, 0, 0}}, // ( 59, 39) + { 0, { 0, 0, 0}}, // ( 60, 39) + { 0, { 0, 0, 0}}, // ( 61, 39) + { 0, { 0, 0, 0}}, // ( 62, 39) + { 0, { 0, 0, 0}}, // ( 63, 39) + { 0, { 0, 0, 0}}, // ( 64, 39) + { 0, { 0, 0, 0}}, // ( 65, 39) + { 0, { 0, 0, 0}}, // ( 66, 39) + { 0, { 0, 0, 0}}, // ( 67, 39) + { 0, { 0, 0, 0}}, // ( 68, 39) + { 0, { 0, 0, 0}}, // ( 69, 39) + { 0, { 0, 0, 0}}, // ( 70, 39) + { 0, { 0, 0, 0}}, // ( 71, 39) + { 0, { 0, 0, 0}}, // ( 72, 39) + { 0, { 0, 0, 0}}, // ( 73, 39) + { 0, { 0, 0, 0}}, // ( 74, 39) + { 0, { 0, 0, 0}}, // ( 75, 39) + { 0, { 0, 0, 0}}, // ( 76, 39) + { 0, { 0, 0, 0}}, // ( 77, 39) + { 0, { 0, 0, 0}}, // ( 78, 39) + { 0, { 0, 0, 0}}, // ( 79, 39) + { 0, { 0, 0, 0}}, // ( 80, 39) + { 0, { 0, 0, 0}}, // ( 81, 39) + { 0, { 0, 0, 0}}, // ( 82, 39) + { 0, { 0, 0, 0}}, // ( 83, 39) + { 0, { 0, 0, 0}}, // ( 84, 39) + { 0, { 0, 0, 0}}, // ( 85, 39) + { 0, { 0, 0, 0}}, // ( 86, 39) + { 0, { 0, 0, 0}}, // ( 87, 39) + { 0, { 0, 0, 0}}, // ( 88, 39) + { 0, { 0, 0, 0}}, // ( 89, 39) + { 0, { 0, 0, 0}}, // ( 90, 39) + { 0, { 0, 0, 0}}, // ( 91, 39) + { 0, { 0, 0, 0}}, // ( 92, 39) + { 0, { 0, 0, 0}}, // ( 93, 39) + { 0, { 0, 0, 0}}, // ( 94, 39) + { 0, { 0, 0, 0}}, // ( 95, 39) + { 0, { 0, 0, 0}}, // ( 96, 39) + { 0, { 0, 0, 0}}, // ( 97, 39) + { 0, { 0, 0, 0}}, // ( 98, 39) + { 0, { 0, 0, 0}}, // ( 99, 39) + { 0, { 0, 0, 0}}, // (100, 39) + { 0, { 0, 0, 0}}, // (101, 39) + { 0, { 0, 0, 0}}, // (102, 39) + { 0, { 0, 0, 0}}, // (103, 39) + { 0, { 0, 0, 0}}, // (104, 39) + { 0, { 0, 0, 0}}, // (105, 39) + { 0, { 0, 0, 0}}, // (106, 39) + { 0, { 0, 0, 0}}, // (107, 39) + { 0, { 0, 0, 0}}, // (108, 39) + { 0, { 0, 0, 0}}, // (109, 39) + { 0, { 0, 0, 0}}, // (110, 39) + { 0, { 0, 0, 0}}, // (111, 39) + { 0, { 0, 0, 0}}, // (112, 39) + { 0, { 0, 0, 0}}, // (113, 39) + { 0, { 0, 0, 0}}, // (114, 39) + { 0, { 0, 0, 0}}, // (115, 39) + { 0, { 0, 0, 0}}, // (116, 39) + { 0, { 0, 0, 0}}, // (117, 39) + { 0, { 0, 0, 0}}, // (118, 39) + { 0, { 0, 0, 0}}, // (119, 39) + { 0, { 0, 0, 0}}, // (120, 39) + { 0, { 0, 0, 0}}, // (121, 39) + { 0, { 0, 0, 0}}, // (122, 39) + { 0, { 0, 0, 0}}, // (123, 39) + { 0, { 0, 0, 0}}, // (124, 39) + { 0, { 0, 0, 0}}, // (125, 39) + { 0, { 0, 0, 0}}, // (126, 39) + { 0, { 0, 0, 0}}, // (127, 39) + { 0, { 0, 0, 0}}, // (128, 39) + { 0, { 0, 0, 0}}, // (129, 39) + { 0, { 0, 0, 0}}, // (130, 39) + { 0, { 0, 0, 0}}, // (131, 39) + { 0, { 0, 0, 0}}, // (132, 39) + { 0, { 0, 0, 0}}, // (133, 39) + { 0, { 0, 0, 0}}, // (134, 39) + { 0, { 0, 0, 0}}, // (135, 39) + { 0, { 0, 0, 0}}, // (136, 39) + { 0, { 0, 0, 0}}, // (137, 39) + { 0, { 0, 0, 0}}, // (138, 39) + { 0, { 0, 0, 0}}, // (139, 39) + { 0, { 0, 0, 0}}, // (140, 39) + { 0, { 0, 0, 0}}, // (141, 39) + { 0, { 0, 0, 0}}, // (142, 39) + { 0, { 0, 0, 0}}, // (143, 39) + { 0, { 0, 0, 0}}, // (144, 39) + { 0, { 0, 0, 0}}, // (145, 39) + { 0, { 0, 0, 0}}, // (146, 39) + { 0, { 0, 0, 0}}, // (147, 39) + { 0, { 0, 0, 0}}, // (148, 39) + { 0, { 0, 0, 0}}, // (149, 39) + { 0, { 0, 0, 0}}, // (150, 39) + { 0, { 0, 0, 0}}, // (151, 39) + { 0, { 0, 0, 0}}, // (152, 39) + { 0, { 0, 0, 0}}, // (153, 39) + { 0, { 0, 0, 0}}, // (154, 39) + { 0, { 0, 0, 0}}, // (155, 39) + { 0, { 0, 0, 0}}, // (156, 39) + { 0, { 0, 0, 0}}, // (157, 39) + { 0, { 0, 0, 0}}, // (158, 39) + { 0, { 0, 0, 0}}, // (159, 39) + { 0, { 0, 0, 0}}, // (160, 39) + { 7, { 0, 0, 0}}, // (161, 39) + {112, { 0, 0, 0}}, // (162, 39) + {128, { 0, 0, 0}}, // (163, 39) + {128, { 0, 0, 0}}, // (164, 39) + {128, { 0, 0, 0}}, // (165, 39) + {128, { 0, 0, 0}}, // (166, 39) + {128, { 0, 0, 0}}, // (167, 39) + {128, { 0, 0, 0}}, // (168, 39) + {128, { 0, 0, 0}}, // (169, 39) + {128, { 0, 0, 0}}, // (170, 39) + {128, { 0, 0, 0}}, // (171, 39) + {128, { 0, 0, 0}}, // (172, 39) + {128, { 0, 0, 0}}, // (173, 39) + {128, { 0, 0, 0}}, // (174, 39) + {128, { 0, 0, 0}}, // (175, 39) + {128, { 0, 0, 0}}, // (176, 39) + {128, { 0, 0, 0}}, // (177, 39) + {128, { 0, 0, 0}}, // (178, 39) + {128, { 0, 0, 0}}, // (179, 39) + {128, { 0, 0, 0}}, // ( 0, 40) + {128, { 0, 0, 0}}, // ( 1, 40) + {128, { 0, 0, 0}}, // ( 2, 40) + {128, { 0, 0, 0}}, // ( 3, 40) + {128, { 0, 0, 0}}, // ( 4, 40) + {128, { 0, 0, 0}}, // ( 5, 40) + {128, { 0, 0, 0}}, // ( 6, 40) + {128, { 0, 0, 0}}, // ( 7, 40) + {128, { 0, 0, 0}}, // ( 8, 40) + {128, { 0, 0, 0}}, // ( 9, 40) + {128, { 0, 0, 0}}, // ( 10, 40) + {128, { 0, 0, 0}}, // ( 11, 40) + {128, { 0, 0, 0}}, // ( 12, 40) + {128, { 0, 0, 0}}, // ( 13, 40) + {128, { 0, 0, 0}}, // ( 14, 40) + {128, { 0, 0, 0}}, // ( 15, 40) + {127, { 0, 0, 0}}, // ( 16, 40) + { 32, { 0, 0, 0}}, // ( 17, 40) + { 0, { 0, 0, 0}}, // ( 18, 40) + { 0, { 0, 0, 0}}, // ( 19, 40) + { 0, { 0, 0, 0}}, // ( 20, 40) + { 0, { 0, 0, 0}}, // ( 21, 40) + { 0, { 0, 0, 0}}, // ( 22, 40) + { 0, { 0, 0, 0}}, // ( 23, 40) + { 0, { 0, 0, 0}}, // ( 24, 40) + { 0, { 0, 0, 0}}, // ( 25, 40) + { 0, { 0, 0, 0}}, // ( 26, 40) + { 0, { 0, 0, 0}}, // ( 27, 40) + { 0, { 0, 0, 0}}, // ( 28, 40) + { 0, { 0, 0, 0}}, // ( 29, 40) + { 0, { 0, 0, 0}}, // ( 30, 40) + { 0, { 0, 0, 0}}, // ( 31, 40) + { 0, { 0, 0, 0}}, // ( 32, 40) + { 0, { 0, 0, 0}}, // ( 33, 40) + { 0, { 0, 0, 0}}, // ( 34, 40) + { 0, { 0, 0, 0}}, // ( 35, 40) + { 0, { 0, 0, 0}}, // ( 36, 40) + { 0, { 0, 0, 0}}, // ( 37, 40) + { 0, { 0, 0, 0}}, // ( 38, 40) + { 0, { 0, 0, 0}}, // ( 39, 40) + { 0, { 0, 0, 0}}, // ( 40, 40) + { 0, { 0, 0, 0}}, // ( 41, 40) + { 0, { 0, 0, 0}}, // ( 42, 40) + { 0, { 0, 0, 0}}, // ( 43, 40) + { 0, { 0, 0, 0}}, // ( 44, 40) + { 0, { 0, 0, 0}}, // ( 45, 40) + { 0, { 0, 0, 0}}, // ( 46, 40) + { 0, { 0, 0, 0}}, // ( 47, 40) + { 0, { 0, 0, 0}}, // ( 48, 40) + { 0, { 0, 0, 0}}, // ( 49, 40) + { 0, { 0, 0, 0}}, // ( 50, 40) + { 0, { 0, 0, 0}}, // ( 51, 40) + { 0, { 0, 0, 0}}, // ( 52, 40) + { 0, { 0, 0, 0}}, // ( 53, 40) + { 0, { 0, 0, 0}}, // ( 54, 40) + { 0, { 0, 0, 0}}, // ( 55, 40) + { 0, { 0, 0, 0}}, // ( 56, 40) + { 0, { 0, 0, 0}}, // ( 57, 40) + { 0, { 0, 0, 0}}, // ( 58, 40) + { 0, { 0, 0, 0}}, // ( 59, 40) + { 0, { 0, 0, 0}}, // ( 60, 40) + { 0, { 0, 0, 0}}, // ( 61, 40) + { 0, { 0, 0, 0}}, // ( 62, 40) + { 0, { 0, 0, 0}}, // ( 63, 40) + { 0, { 0, 0, 0}}, // ( 64, 40) + { 0, { 0, 0, 0}}, // ( 65, 40) + { 0, { 0, 0, 0}}, // ( 66, 40) + { 0, { 0, 0, 0}}, // ( 67, 40) + { 0, { 0, 0, 0}}, // ( 68, 40) + { 0, { 0, 0, 0}}, // ( 69, 40) + { 0, { 0, 0, 0}}, // ( 70, 40) + { 0, { 0, 0, 0}}, // ( 71, 40) + { 0, { 0, 0, 0}}, // ( 72, 40) + { 0, { 0, 0, 0}}, // ( 73, 40) + { 0, { 0, 0, 0}}, // ( 74, 40) + { 0, { 0, 0, 0}}, // ( 75, 40) + { 0, { 0, 0, 0}}, // ( 76, 40) + { 0, { 0, 0, 0}}, // ( 77, 40) + { 0, { 0, 0, 0}}, // ( 78, 40) + { 0, { 0, 0, 0}}, // ( 79, 40) + { 0, { 0, 0, 0}}, // ( 80, 40) + { 0, { 0, 0, 0}}, // ( 81, 40) + { 0, { 0, 0, 0}}, // ( 82, 40) + { 0, { 0, 0, 0}}, // ( 83, 40) + { 0, { 0, 0, 0}}, // ( 84, 40) + { 0, { 0, 0, 0}}, // ( 85, 40) + { 0, { 0, 0, 0}}, // ( 86, 40) + { 0, { 0, 0, 0}}, // ( 87, 40) + { 0, { 0, 0, 0}}, // ( 88, 40) + { 0, { 0, 0, 0}}, // ( 89, 40) + { 0, { 0, 0, 0}}, // ( 90, 40) + { 0, { 0, 0, 0}}, // ( 91, 40) + { 0, { 0, 0, 0}}, // ( 92, 40) + { 0, { 0, 0, 0}}, // ( 93, 40) + { 0, { 0, 0, 0}}, // ( 94, 40) + { 0, { 0, 0, 0}}, // ( 95, 40) + { 0, { 0, 0, 0}}, // ( 96, 40) + { 0, { 0, 0, 0}}, // ( 97, 40) + { 0, { 0, 0, 0}}, // ( 98, 40) + { 0, { 0, 0, 0}}, // ( 99, 40) + { 0, { 0, 0, 0}}, // (100, 40) + { 0, { 0, 0, 0}}, // (101, 40) + { 0, { 0, 0, 0}}, // (102, 40) + { 0, { 0, 0, 0}}, // (103, 40) + { 0, { 0, 0, 0}}, // (104, 40) + { 0, { 0, 0, 0}}, // (105, 40) + { 0, { 0, 0, 0}}, // (106, 40) + { 0, { 0, 0, 0}}, // (107, 40) + { 0, { 0, 0, 0}}, // (108, 40) + { 0, { 0, 0, 0}}, // (109, 40) + { 0, { 0, 0, 0}}, // (110, 40) + { 0, { 0, 0, 0}}, // (111, 40) + { 0, { 0, 0, 0}}, // (112, 40) + { 0, { 0, 0, 0}}, // (113, 40) + { 0, { 0, 0, 0}}, // (114, 40) + { 0, { 0, 0, 0}}, // (115, 40) + { 0, { 0, 0, 0}}, // (116, 40) + { 0, { 0, 0, 0}}, // (117, 40) + { 0, { 0, 0, 0}}, // (118, 40) + { 0, { 0, 0, 0}}, // (119, 40) + { 0, { 0, 0, 0}}, // (120, 40) + { 0, { 0, 0, 0}}, // (121, 40) + { 0, { 0, 0, 0}}, // (122, 40) + { 0, { 0, 0, 0}}, // (123, 40) + { 0, { 0, 0, 0}}, // (124, 40) + { 0, { 0, 0, 0}}, // (125, 40) + { 0, { 0, 0, 0}}, // (126, 40) + { 0, { 0, 0, 0}}, // (127, 40) + { 0, { 0, 0, 0}}, // (128, 40) + { 0, { 0, 0, 0}}, // (129, 40) + { 0, { 0, 0, 0}}, // (130, 40) + { 0, { 0, 0, 0}}, // (131, 40) + { 0, { 0, 0, 0}}, // (132, 40) + { 0, { 0, 0, 0}}, // (133, 40) + { 0, { 0, 0, 0}}, // (134, 40) + { 0, { 0, 0, 0}}, // (135, 40) + { 0, { 0, 0, 0}}, // (136, 40) + { 0, { 0, 0, 0}}, // (137, 40) + { 0, { 0, 0, 0}}, // (138, 40) + { 0, { 0, 0, 0}}, // (139, 40) + { 0, { 0, 0, 0}}, // (140, 40) + { 0, { 0, 0, 0}}, // (141, 40) + { 0, { 0, 0, 0}}, // (142, 40) + { 0, { 0, 0, 0}}, // (143, 40) + { 0, { 0, 0, 0}}, // (144, 40) + { 0, { 0, 0, 0}}, // (145, 40) + { 0, { 0, 0, 0}}, // (146, 40) + { 0, { 0, 0, 0}}, // (147, 40) + { 0, { 0, 0, 0}}, // (148, 40) + { 0, { 0, 0, 0}}, // (149, 40) + { 0, { 0, 0, 0}}, // (150, 40) + { 0, { 0, 0, 0}}, // (151, 40) + { 0, { 0, 0, 0}}, // (152, 40) + { 0, { 0, 0, 0}}, // (153, 40) + { 0, { 0, 0, 0}}, // (154, 40) + { 0, { 0, 0, 0}}, // (155, 40) + { 0, { 0, 0, 0}}, // (156, 40) + { 0, { 0, 0, 0}}, // (157, 40) + { 0, { 0, 0, 0}}, // (158, 40) + { 0, { 0, 0, 0}}, // (159, 40) + { 0, { 0, 0, 0}}, // (160, 40) + { 0, { 0, 0, 0}}, // (161, 40) + { 32, { 0, 0, 0}}, // (162, 40) + {127, { 0, 0, 0}}, // (163, 40) + {128, { 0, 0, 0}}, // (164, 40) + {128, { 0, 0, 0}}, // (165, 40) + {128, { 0, 0, 0}}, // (166, 40) + {128, { 0, 0, 0}}, // (167, 40) + {128, { 0, 0, 0}}, // (168, 40) + {128, { 0, 0, 0}}, // (169, 40) + {128, { 0, 0, 0}}, // (170, 40) + {128, { 0, 0, 0}}, // (171, 40) + {128, { 0, 0, 0}}, // (172, 40) + {128, { 0, 0, 0}}, // (173, 40) + {128, { 0, 0, 0}}, // (174, 40) + {128, { 0, 0, 0}}, // (175, 40) + {128, { 0, 0, 0}}, // (176, 40) + {128, { 0, 0, 0}}, // (177, 40) + {128, { 0, 0, 0}}, // (178, 40) + {128, { 0, 0, 0}}, // (179, 40) + {128, { 0, 0, 0}}, // ( 0, 41) + {128, { 0, 0, 0}}, // ( 1, 41) + {128, { 0, 0, 0}}, // ( 2, 41) + {128, { 0, 0, 0}}, // ( 3, 41) + {128, { 0, 0, 0}}, // ( 4, 41) + {128, { 0, 0, 0}}, // ( 5, 41) + {128, { 0, 0, 0}}, // ( 6, 41) + {128, { 0, 0, 0}}, // ( 7, 41) + {128, { 0, 0, 0}}, // ( 8, 41) + {128, { 0, 0, 0}}, // ( 9, 41) + {128, { 0, 0, 0}}, // ( 10, 41) + {128, { 0, 0, 0}}, // ( 11, 41) + {128, { 0, 0, 0}}, // ( 12, 41) + {128, { 0, 0, 0}}, // ( 13, 41) + {128, { 0, 0, 0}}, // ( 14, 41) + {128, { 0, 0, 0}}, // ( 15, 41) + { 75, { 0, 0, 0}}, // ( 16, 41) + { 0, { 0, 0, 0}}, // ( 17, 41) + { 0, { 0, 0, 0}}, // ( 18, 41) + { 0, { 0, 0, 0}}, // ( 19, 41) + { 0, { 0, 0, 0}}, // ( 20, 41) + { 0, { 0, 0, 0}}, // ( 21, 41) + { 0, { 0, 0, 0}}, // ( 22, 41) + { 0, { 0, 0, 0}}, // ( 23, 41) + { 0, { 0, 0, 0}}, // ( 24, 41) + { 0, { 0, 0, 0}}, // ( 25, 41) + { 0, { 0, 0, 0}}, // ( 26, 41) + { 0, { 0, 0, 0}}, // ( 27, 41) + { 0, { 0, 0, 0}}, // ( 28, 41) + { 0, { 0, 0, 0}}, // ( 29, 41) + { 0, { 0, 0, 0}}, // ( 30, 41) + { 0, { 0, 0, 0}}, // ( 31, 41) + { 0, { 0, 0, 0}}, // ( 32, 41) + { 0, { 0, 0, 0}}, // ( 33, 41) + { 0, { 0, 0, 0}}, // ( 34, 41) + { 0, { 0, 0, 0}}, // ( 35, 41) + { 0, { 0, 0, 0}}, // ( 36, 41) + { 0, { 0, 0, 0}}, // ( 37, 41) + { 0, { 0, 0, 0}}, // ( 38, 41) + { 0, { 0, 0, 0}}, // ( 39, 41) + { 0, { 0, 0, 0}}, // ( 40, 41) + { 0, { 0, 0, 0}}, // ( 41, 41) + { 0, { 0, 0, 0}}, // ( 42, 41) + { 0, { 0, 0, 0}}, // ( 43, 41) + { 0, { 0, 0, 0}}, // ( 44, 41) + { 0, { 0, 0, 0}}, // ( 45, 41) + { 0, { 0, 0, 0}}, // ( 46, 41) + { 0, { 0, 0, 0}}, // ( 47, 41) + { 0, { 0, 0, 0}}, // ( 48, 41) + { 0, { 0, 0, 0}}, // ( 49, 41) + { 0, { 0, 0, 0}}, // ( 50, 41) + { 0, { 0, 0, 0}}, // ( 51, 41) + { 0, { 0, 0, 0}}, // ( 52, 41) + { 0, { 0, 0, 0}}, // ( 53, 41) + { 0, { 0, 0, 0}}, // ( 54, 41) + { 0, { 0, 0, 0}}, // ( 55, 41) + { 0, { 0, 0, 0}}, // ( 56, 41) + { 0, { 0, 0, 0}}, // ( 57, 41) + { 0, { 0, 0, 0}}, // ( 58, 41) + { 0, { 0, 0, 0}}, // ( 59, 41) + { 0, { 0, 0, 0}}, // ( 60, 41) + { 0, { 0, 0, 0}}, // ( 61, 41) + { 0, { 0, 0, 0}}, // ( 62, 41) + { 0, { 0, 0, 0}}, // ( 63, 41) + { 0, { 0, 0, 0}}, // ( 64, 41) + { 0, { 0, 0, 0}}, // ( 65, 41) + { 0, { 0, 0, 0}}, // ( 66, 41) + { 0, { 0, 0, 0}}, // ( 67, 41) + { 0, { 0, 0, 0}}, // ( 68, 41) + { 0, { 0, 0, 0}}, // ( 69, 41) + { 0, { 0, 0, 0}}, // ( 70, 41) + { 0, { 0, 0, 0}}, // ( 71, 41) + { 0, { 0, 0, 0}}, // ( 72, 41) + { 0, { 0, 0, 0}}, // ( 73, 41) + { 0, { 0, 0, 0}}, // ( 74, 41) + { 0, { 0, 0, 0}}, // ( 75, 41) + { 0, { 0, 0, 0}}, // ( 76, 41) + { 0, { 0, 0, 0}}, // ( 77, 41) + { 0, { 0, 0, 0}}, // ( 78, 41) + { 0, { 0, 0, 0}}, // ( 79, 41) + { 0, { 0, 0, 0}}, // ( 80, 41) + { 0, { 0, 0, 0}}, // ( 81, 41) + { 0, { 0, 0, 0}}, // ( 82, 41) + { 0, { 0, 0, 0}}, // ( 83, 41) + { 0, { 0, 0, 0}}, // ( 84, 41) + { 0, { 0, 0, 0}}, // ( 85, 41) + { 0, { 0, 0, 0}}, // ( 86, 41) + { 0, { 0, 0, 0}}, // ( 87, 41) + { 0, { 0, 0, 0}}, // ( 88, 41) + { 0, { 0, 0, 0}}, // ( 89, 41) + { 0, { 0, 0, 0}}, // ( 90, 41) + { 0, { 0, 0, 0}}, // ( 91, 41) + { 0, { 0, 0, 0}}, // ( 92, 41) + { 0, { 0, 0, 0}}, // ( 93, 41) + { 0, { 0, 0, 0}}, // ( 94, 41) + { 0, { 0, 0, 0}}, // ( 95, 41) + { 0, { 0, 0, 0}}, // ( 96, 41) + { 0, { 0, 0, 0}}, // ( 97, 41) + { 0, { 0, 0, 0}}, // ( 98, 41) + { 0, { 0, 0, 0}}, // ( 99, 41) + { 0, { 0, 0, 0}}, // (100, 41) + { 0, { 0, 0, 0}}, // (101, 41) + { 0, { 0, 0, 0}}, // (102, 41) + { 0, { 0, 0, 0}}, // (103, 41) + { 0, { 0, 0, 0}}, // (104, 41) + { 0, { 0, 0, 0}}, // (105, 41) + { 0, { 0, 0, 0}}, // (106, 41) + { 0, { 0, 0, 0}}, // (107, 41) + { 0, { 0, 0, 0}}, // (108, 41) + { 0, { 0, 0, 0}}, // (109, 41) + { 0, { 0, 0, 0}}, // (110, 41) + { 0, { 0, 0, 0}}, // (111, 41) + { 0, { 0, 0, 0}}, // (112, 41) + { 0, { 0, 0, 0}}, // (113, 41) + { 0, { 0, 0, 0}}, // (114, 41) + { 0, { 0, 0, 0}}, // (115, 41) + { 0, { 0, 0, 0}}, // (116, 41) + { 0, { 0, 0, 0}}, // (117, 41) + { 0, { 0, 0, 0}}, // (118, 41) + { 0, { 0, 0, 0}}, // (119, 41) + { 0, { 0, 0, 0}}, // (120, 41) + { 0, { 0, 0, 0}}, // (121, 41) + { 0, { 0, 0, 0}}, // (122, 41) + { 0, { 0, 0, 0}}, // (123, 41) + { 0, { 0, 0, 0}}, // (124, 41) + { 0, { 0, 0, 0}}, // (125, 41) + { 0, { 0, 0, 0}}, // (126, 41) + { 0, { 0, 0, 0}}, // (127, 41) + { 0, { 0, 0, 0}}, // (128, 41) + { 0, { 0, 0, 0}}, // (129, 41) + { 0, { 0, 0, 0}}, // (130, 41) + { 0, { 0, 0, 0}}, // (131, 41) + { 0, { 0, 0, 0}}, // (132, 41) + { 0, { 0, 0, 0}}, // (133, 41) + { 0, { 0, 0, 0}}, // (134, 41) + { 0, { 0, 0, 0}}, // (135, 41) + { 0, { 0, 0, 0}}, // (136, 41) + { 0, { 0, 0, 0}}, // (137, 41) + { 0, { 0, 0, 0}}, // (138, 41) + { 0, { 0, 0, 0}}, // (139, 41) + { 0, { 0, 0, 0}}, // (140, 41) + { 0, { 0, 0, 0}}, // (141, 41) + { 0, { 0, 0, 0}}, // (142, 41) + { 0, { 0, 0, 0}}, // (143, 41) + { 0, { 0, 0, 0}}, // (144, 41) + { 0, { 0, 0, 0}}, // (145, 41) + { 0, { 0, 0, 0}}, // (146, 41) + { 0, { 0, 0, 0}}, // (147, 41) + { 0, { 0, 0, 0}}, // (148, 41) + { 0, { 0, 0, 0}}, // (149, 41) + { 0, { 0, 0, 0}}, // (150, 41) + { 0, { 0, 0, 0}}, // (151, 41) + { 0, { 0, 0, 0}}, // (152, 41) + { 0, { 0, 0, 0}}, // (153, 41) + { 0, { 0, 0, 0}}, // (154, 41) + { 0, { 0, 0, 0}}, // (155, 41) + { 0, { 0, 0, 0}}, // (156, 41) + { 0, { 0, 0, 0}}, // (157, 41) + { 0, { 0, 0, 0}}, // (158, 41) + { 0, { 0, 0, 0}}, // (159, 41) + { 0, { 0, 0, 0}}, // (160, 41) + { 0, { 0, 0, 0}}, // (161, 41) + { 0, { 0, 0, 0}}, // (162, 41) + { 75, { 0, 0, 0}}, // (163, 41) + {128, { 0, 0, 0}}, // (164, 41) + {128, { 0, 0, 0}}, // (165, 41) + {128, { 0, 0, 0}}, // (166, 41) + {128, { 0, 0, 0}}, // (167, 41) + {128, { 0, 0, 0}}, // (168, 41) + {128, { 0, 0, 0}}, // (169, 41) + {128, { 0, 0, 0}}, // (170, 41) + {128, { 0, 0, 0}}, // (171, 41) + {128, { 0, 0, 0}}, // (172, 41) + {128, { 0, 0, 0}}, // (173, 41) + {128, { 0, 0, 0}}, // (174, 41) + {128, { 0, 0, 0}}, // (175, 41) + {128, { 0, 0, 0}}, // (176, 41) + {128, { 0, 0, 0}}, // (177, 41) + {128, { 0, 0, 0}}, // (178, 41) + {128, { 0, 0, 0}}, // (179, 41) + {128, { 0, 0, 0}}, // ( 0, 42) + {128, { 0, 0, 0}}, // ( 1, 42) + {128, { 0, 0, 0}}, // ( 2, 42) + {128, { 0, 0, 0}}, // ( 3, 42) + {128, { 0, 0, 0}}, // ( 4, 42) + {128, { 0, 0, 0}}, // ( 5, 42) + {128, { 0, 0, 0}}, // ( 6, 42) + {128, { 0, 0, 0}}, // ( 7, 42) + {128, { 0, 0, 0}}, // ( 8, 42) + {128, { 0, 0, 0}}, // ( 9, 42) + {128, { 0, 0, 0}}, // ( 10, 42) + {128, { 0, 0, 0}}, // ( 11, 42) + {128, { 0, 0, 0}}, // ( 12, 42) + {128, { 0, 0, 0}}, // ( 13, 42) + {128, { 0, 0, 0}}, // ( 14, 42) + {114, { 0, 0, 0}}, // ( 15, 42) + { 7, { 0, 0, 0}}, // ( 16, 42) + { 0, { 0, 0, 0}}, // ( 17, 42) + { 0, { 0, 0, 0}}, // ( 18, 42) + { 0, { 0, 0, 0}}, // ( 19, 42) + { 0, { 0, 0, 0}}, // ( 20, 42) + { 0, { 0, 0, 0}}, // ( 21, 42) + { 0, { 0, 0, 0}}, // ( 22, 42) + { 0, { 0, 0, 0}}, // ( 23, 42) + { 0, { 0, 0, 0}}, // ( 24, 42) + { 0, { 0, 0, 0}}, // ( 25, 42) + { 0, { 0, 0, 0}}, // ( 26, 42) + { 0, { 0, 0, 0}}, // ( 27, 42) + { 0, { 0, 0, 0}}, // ( 28, 42) + { 0, { 0, 0, 0}}, // ( 29, 42) + { 0, { 0, 0, 0}}, // ( 30, 42) + { 0, { 0, 0, 0}}, // ( 31, 42) + { 0, { 0, 0, 0}}, // ( 32, 42) + { 0, { 0, 0, 0}}, // ( 33, 42) + { 0, { 0, 0, 0}}, // ( 34, 42) + { 0, { 0, 0, 0}}, // ( 35, 42) + { 0, { 0, 0, 0}}, // ( 36, 42) + { 0, { 0, 0, 0}}, // ( 37, 42) + { 0, { 0, 0, 0}}, // ( 38, 42) + { 0, { 0, 0, 0}}, // ( 39, 42) + { 0, { 0, 0, 0}}, // ( 40, 42) + { 0, { 0, 0, 0}}, // ( 41, 42) + { 0, { 0, 0, 0}}, // ( 42, 42) + { 0, { 0, 0, 0}}, // ( 43, 42) + { 0, { 0, 0, 0}}, // ( 44, 42) + { 0, { 0, 0, 0}}, // ( 45, 42) + { 0, { 0, 0, 0}}, // ( 46, 42) + { 0, { 0, 0, 0}}, // ( 47, 42) + { 0, { 0, 0, 0}}, // ( 48, 42) + { 0, { 0, 0, 0}}, // ( 49, 42) + { 0, { 0, 0, 0}}, // ( 50, 42) + { 0, { 0, 0, 0}}, // ( 51, 42) + { 0, { 0, 0, 0}}, // ( 52, 42) + { 0, { 0, 0, 0}}, // ( 53, 42) + { 0, { 0, 0, 0}}, // ( 54, 42) + { 0, { 0, 0, 0}}, // ( 55, 42) + { 0, { 0, 0, 0}}, // ( 56, 42) + { 0, { 0, 0, 0}}, // ( 57, 42) + { 0, { 0, 0, 0}}, // ( 58, 42) + { 0, { 0, 0, 0}}, // ( 59, 42) + { 0, { 0, 0, 0}}, // ( 60, 42) + { 0, { 0, 0, 0}}, // ( 61, 42) + { 0, { 0, 0, 0}}, // ( 62, 42) + { 0, { 0, 0, 0}}, // ( 63, 42) + { 0, { 0, 0, 0}}, // ( 64, 42) + { 0, { 0, 0, 0}}, // ( 65, 42) + { 0, { 0, 0, 0}}, // ( 66, 42) + { 0, { 0, 0, 0}}, // ( 67, 42) + { 0, { 0, 0, 0}}, // ( 68, 42) + { 0, { 0, 0, 0}}, // ( 69, 42) + { 0, { 0, 0, 0}}, // ( 70, 42) + { 0, { 0, 0, 0}}, // ( 71, 42) + { 0, { 0, 0, 0}}, // ( 72, 42) + { 0, { 0, 0, 0}}, // ( 73, 42) + { 0, { 0, 0, 0}}, // ( 74, 42) + { 0, { 0, 0, 0}}, // ( 75, 42) + { 0, { 0, 0, 0}}, // ( 76, 42) + { 0, { 0, 0, 0}}, // ( 77, 42) + { 0, { 0, 0, 0}}, // ( 78, 42) + { 0, { 0, 0, 0}}, // ( 79, 42) + { 0, { 0, 0, 0}}, // ( 80, 42) + { 0, { 0, 0, 0}}, // ( 81, 42) + { 0, { 0, 0, 0}}, // ( 82, 42) + { 0, { 0, 0, 0}}, // ( 83, 42) + { 0, { 0, 0, 0}}, // ( 84, 42) + { 0, { 0, 0, 0}}, // ( 85, 42) + { 0, { 0, 0, 0}}, // ( 86, 42) + { 0, { 0, 0, 0}}, // ( 87, 42) + { 0, { 0, 0, 0}}, // ( 88, 42) + { 0, { 0, 0, 0}}, // ( 89, 42) + { 0, { 0, 0, 0}}, // ( 90, 42) + { 0, { 0, 0, 0}}, // ( 91, 42) + { 0, { 0, 0, 0}}, // ( 92, 42) + { 0, { 0, 0, 0}}, // ( 93, 42) + { 0, { 0, 0, 0}}, // ( 94, 42) + { 0, { 0, 0, 0}}, // ( 95, 42) + { 0, { 0, 0, 0}}, // ( 96, 42) + { 0, { 0, 0, 0}}, // ( 97, 42) + { 0, { 0, 0, 0}}, // ( 98, 42) + { 0, { 0, 0, 0}}, // ( 99, 42) + { 0, { 0, 0, 0}}, // (100, 42) + { 0, { 0, 0, 0}}, // (101, 42) + { 0, { 0, 0, 0}}, // (102, 42) + { 0, { 0, 0, 0}}, // (103, 42) + { 0, { 0, 0, 0}}, // (104, 42) + { 0, { 0, 0, 0}}, // (105, 42) + { 0, { 0, 0, 0}}, // (106, 42) + { 0, { 0, 0, 0}}, // (107, 42) + { 0, { 0, 0, 0}}, // (108, 42) + { 0, { 0, 0, 0}}, // (109, 42) + { 0, { 0, 0, 0}}, // (110, 42) + { 0, { 0, 0, 0}}, // (111, 42) + { 0, { 0, 0, 0}}, // (112, 42) + { 0, { 0, 0, 0}}, // (113, 42) + { 0, { 0, 0, 0}}, // (114, 42) + { 0, { 0, 0, 0}}, // (115, 42) + { 0, { 0, 0, 0}}, // (116, 42) + { 0, { 0, 0, 0}}, // (117, 42) + { 0, { 0, 0, 0}}, // (118, 42) + { 0, { 0, 0, 0}}, // (119, 42) + { 0, { 0, 0, 0}}, // (120, 42) + { 0, { 0, 0, 0}}, // (121, 42) + { 0, { 0, 0, 0}}, // (122, 42) + { 0, { 0, 0, 0}}, // (123, 42) + { 0, { 0, 0, 0}}, // (124, 42) + { 0, { 0, 0, 0}}, // (125, 42) + { 0, { 0, 0, 0}}, // (126, 42) + { 0, { 0, 0, 0}}, // (127, 42) + { 0, { 0, 0, 0}}, // (128, 42) + { 0, { 0, 0, 0}}, // (129, 42) + { 0, { 0, 0, 0}}, // (130, 42) + { 0, { 0, 0, 0}}, // (131, 42) + { 0, { 0, 0, 0}}, // (132, 42) + { 0, { 0, 0, 0}}, // (133, 42) + { 0, { 0, 0, 0}}, // (134, 42) + { 0, { 0, 0, 0}}, // (135, 42) + { 0, { 0, 0, 0}}, // (136, 42) + { 0, { 0, 0, 0}}, // (137, 42) + { 0, { 0, 0, 0}}, // (138, 42) + { 0, { 0, 0, 0}}, // (139, 42) + { 0, { 0, 0, 0}}, // (140, 42) + { 0, { 0, 0, 0}}, // (141, 42) + { 0, { 0, 0, 0}}, // (142, 42) + { 0, { 0, 0, 0}}, // (143, 42) + { 0, { 0, 0, 0}}, // (144, 42) + { 0, { 0, 0, 0}}, // (145, 42) + { 0, { 0, 0, 0}}, // (146, 42) + { 0, { 0, 0, 0}}, // (147, 42) + { 0, { 0, 0, 0}}, // (148, 42) + { 0, { 0, 0, 0}}, // (149, 42) + { 0, { 0, 0, 0}}, // (150, 42) + { 0, { 0, 0, 0}}, // (151, 42) + { 0, { 0, 0, 0}}, // (152, 42) + { 0, { 0, 0, 0}}, // (153, 42) + { 0, { 0, 0, 0}}, // (154, 42) + { 0, { 0, 0, 0}}, // (155, 42) + { 0, { 0, 0, 0}}, // (156, 42) + { 0, { 0, 0, 0}}, // (157, 42) + { 0, { 0, 0, 0}}, // (158, 42) + { 0, { 0, 0, 0}}, // (159, 42) + { 0, { 0, 0, 0}}, // (160, 42) + { 0, { 0, 0, 0}}, // (161, 42) + { 0, { 0, 0, 0}}, // (162, 42) + { 7, { 0, 0, 0}}, // (163, 42) + {114, { 0, 0, 0}}, // (164, 42) + {128, { 0, 0, 0}}, // (165, 42) + {128, { 0, 0, 0}}, // (166, 42) + {128, { 0, 0, 0}}, // (167, 42) + {128, { 0, 0, 0}}, // (168, 42) + {128, { 0, 0, 0}}, // (169, 42) + {128, { 0, 0, 0}}, // (170, 42) + {128, { 0, 0, 0}}, // (171, 42) + {128, { 0, 0, 0}}, // (172, 42) + {128, { 0, 0, 0}}, // (173, 42) + {128, { 0, 0, 0}}, // (174, 42) + {128, { 0, 0, 0}}, // (175, 42) + {128, { 0, 0, 0}}, // (176, 42) + {128, { 0, 0, 0}}, // (177, 42) + {128, { 0, 0, 0}}, // (178, 42) + {128, { 0, 0, 0}}, // (179, 42) + {128, { 0, 0, 0}}, // ( 0, 43) + {128, { 0, 0, 0}}, // ( 1, 43) + {128, { 0, 0, 0}}, // ( 2, 43) + {128, { 0, 0, 0}}, // ( 3, 43) + {128, { 0, 0, 0}}, // ( 4, 43) + {128, { 0, 0, 0}}, // ( 5, 43) + {128, { 0, 0, 0}}, // ( 6, 43) + {128, { 0, 0, 0}}, // ( 7, 43) + {128, { 0, 0, 0}}, // ( 8, 43) + {128, { 0, 0, 0}}, // ( 9, 43) + {128, { 0, 0, 0}}, // ( 10, 43) + {128, { 0, 0, 0}}, // ( 11, 43) + {128, { 0, 0, 0}}, // ( 12, 43) + {128, { 0, 0, 0}}, // ( 13, 43) + {128, { 0, 0, 0}}, // ( 14, 43) + { 38, { 0, 0, 0}}, // ( 15, 43) + { 0, { 0, 0, 0}}, // ( 16, 43) + { 0, { 0, 0, 0}}, // ( 17, 43) + { 0, { 0, 0, 0}}, // ( 18, 43) + { 0, { 0, 0, 0}}, // ( 19, 43) + { 0, { 0, 0, 0}}, // ( 20, 43) + { 0, { 0, 0, 0}}, // ( 21, 43) + { 0, { 0, 0, 0}}, // ( 22, 43) + { 0, { 0, 0, 0}}, // ( 23, 43) + { 0, { 0, 0, 0}}, // ( 24, 43) + { 0, { 0, 0, 0}}, // ( 25, 43) + { 0, { 0, 0, 0}}, // ( 26, 43) + { 0, { 0, 0, 0}}, // ( 27, 43) + { 0, { 0, 0, 0}}, // ( 28, 43) + { 0, { 0, 0, 0}}, // ( 29, 43) + { 0, { 0, 0, 0}}, // ( 30, 43) + { 0, { 0, 0, 0}}, // ( 31, 43) + { 0, { 0, 0, 0}}, // ( 32, 43) + { 0, { 0, 0, 0}}, // ( 33, 43) + { 0, { 0, 0, 0}}, // ( 34, 43) + { 0, { 0, 0, 0}}, // ( 35, 43) + { 0, { 0, 0, 0}}, // ( 36, 43) + { 0, { 0, 0, 0}}, // ( 37, 43) + { 0, { 0, 0, 0}}, // ( 38, 43) + { 0, { 0, 0, 0}}, // ( 39, 43) + { 0, { 0, 0, 0}}, // ( 40, 43) + { 0, { 0, 0, 0}}, // ( 41, 43) + { 0, { 0, 0, 0}}, // ( 42, 43) + { 0, { 0, 0, 0}}, // ( 43, 43) + { 0, { 0, 0, 0}}, // ( 44, 43) + { 0, { 0, 0, 0}}, // ( 45, 43) + { 0, { 0, 0, 0}}, // ( 46, 43) + { 0, { 0, 0, 0}}, // ( 47, 43) + { 0, { 0, 0, 0}}, // ( 48, 43) + { 0, { 0, 0, 0}}, // ( 49, 43) + { 0, { 0, 0, 0}}, // ( 50, 43) + { 0, { 0, 0, 0}}, // ( 51, 43) + { 0, { 0, 0, 0}}, // ( 52, 43) + { 0, { 0, 0, 0}}, // ( 53, 43) + { 0, { 0, 0, 0}}, // ( 54, 43) + { 0, { 0, 0, 0}}, // ( 55, 43) + { 0, { 0, 0, 0}}, // ( 56, 43) + { 0, { 0, 0, 0}}, // ( 57, 43) + { 0, { 0, 0, 0}}, // ( 58, 43) + { 0, { 0, 0, 0}}, // ( 59, 43) + { 0, { 0, 0, 0}}, // ( 60, 43) + { 0, { 0, 0, 0}}, // ( 61, 43) + { 0, { 0, 0, 0}}, // ( 62, 43) + { 0, { 0, 0, 0}}, // ( 63, 43) + { 0, { 0, 0, 0}}, // ( 64, 43) + { 0, { 0, 0, 0}}, // ( 65, 43) + { 0, { 0, 0, 0}}, // ( 66, 43) + { 0, { 0, 0, 0}}, // ( 67, 43) + { 0, { 0, 0, 0}}, // ( 68, 43) + { 0, { 0, 0, 0}}, // ( 69, 43) + { 0, { 0, 0, 0}}, // ( 70, 43) + { 0, { 0, 0, 0}}, // ( 71, 43) + { 0, { 0, 0, 0}}, // ( 72, 43) + { 0, { 0, 0, 0}}, // ( 73, 43) + { 0, { 0, 0, 0}}, // ( 74, 43) + { 0, { 0, 0, 0}}, // ( 75, 43) + { 0, { 0, 0, 0}}, // ( 76, 43) + { 0, { 0, 0, 0}}, // ( 77, 43) + { 0, { 0, 0, 0}}, // ( 78, 43) + { 0, { 0, 0, 0}}, // ( 79, 43) + { 0, { 0, 0, 0}}, // ( 80, 43) + { 0, { 0, 0, 0}}, // ( 81, 43) + { 0, { 0, 0, 0}}, // ( 82, 43) + { 0, { 0, 0, 0}}, // ( 83, 43) + { 0, { 0, 0, 0}}, // ( 84, 43) + { 0, { 0, 0, 0}}, // ( 85, 43) + { 0, { 0, 0, 0}}, // ( 86, 43) + { 0, { 0, 0, 0}}, // ( 87, 43) + { 0, { 0, 0, 0}}, // ( 88, 43) + { 0, { 0, 0, 0}}, // ( 89, 43) + { 0, { 0, 0, 0}}, // ( 90, 43) + { 0, { 0, 0, 0}}, // ( 91, 43) + { 0, { 0, 0, 0}}, // ( 92, 43) + { 0, { 0, 0, 0}}, // ( 93, 43) + { 0, { 0, 0, 0}}, // ( 94, 43) + { 0, { 0, 0, 0}}, // ( 95, 43) + { 0, { 0, 0, 0}}, // ( 96, 43) + { 0, { 0, 0, 0}}, // ( 97, 43) + { 0, { 0, 0, 0}}, // ( 98, 43) + { 0, { 0, 0, 0}}, // ( 99, 43) + { 0, { 0, 0, 0}}, // (100, 43) + { 0, { 0, 0, 0}}, // (101, 43) + { 0, { 0, 0, 0}}, // (102, 43) + { 0, { 0, 0, 0}}, // (103, 43) + { 0, { 0, 0, 0}}, // (104, 43) + { 0, { 0, 0, 0}}, // (105, 43) + { 0, { 0, 0, 0}}, // (106, 43) + { 0, { 0, 0, 0}}, // (107, 43) + { 0, { 0, 0, 0}}, // (108, 43) + { 0, { 0, 0, 0}}, // (109, 43) + { 0, { 0, 0, 0}}, // (110, 43) + { 0, { 0, 0, 0}}, // (111, 43) + { 0, { 0, 0, 0}}, // (112, 43) + { 0, { 0, 0, 0}}, // (113, 43) + { 0, { 0, 0, 0}}, // (114, 43) + { 0, { 0, 0, 0}}, // (115, 43) + { 0, { 0, 0, 0}}, // (116, 43) + { 0, { 0, 0, 0}}, // (117, 43) + { 0, { 0, 0, 0}}, // (118, 43) + { 0, { 0, 0, 0}}, // (119, 43) + { 0, { 0, 0, 0}}, // (120, 43) + { 0, { 0, 0, 0}}, // (121, 43) + { 0, { 0, 0, 0}}, // (122, 43) + { 0, { 0, 0, 0}}, // (123, 43) + { 0, { 0, 0, 0}}, // (124, 43) + { 0, { 0, 0, 0}}, // (125, 43) + { 0, { 0, 0, 0}}, // (126, 43) + { 0, { 0, 0, 0}}, // (127, 43) + { 0, { 0, 0, 0}}, // (128, 43) + { 0, { 0, 0, 0}}, // (129, 43) + { 0, { 0, 0, 0}}, // (130, 43) + { 0, { 0, 0, 0}}, // (131, 43) + { 0, { 0, 0, 0}}, // (132, 43) + { 0, { 0, 0, 0}}, // (133, 43) + { 0, { 0, 0, 0}}, // (134, 43) + { 0, { 0, 0, 0}}, // (135, 43) + { 0, { 0, 0, 0}}, // (136, 43) + { 0, { 0, 0, 0}}, // (137, 43) + { 0, { 0, 0, 0}}, // (138, 43) + { 0, { 0, 0, 0}}, // (139, 43) + { 0, { 0, 0, 0}}, // (140, 43) + { 0, { 0, 0, 0}}, // (141, 43) + { 0, { 0, 0, 0}}, // (142, 43) + { 0, { 0, 0, 0}}, // (143, 43) + { 0, { 0, 0, 0}}, // (144, 43) + { 0, { 0, 0, 0}}, // (145, 43) + { 0, { 0, 0, 0}}, // (146, 43) + { 0, { 0, 0, 0}}, // (147, 43) + { 0, { 0, 0, 0}}, // (148, 43) + { 0, { 0, 0, 0}}, // (149, 43) + { 0, { 0, 0, 0}}, // (150, 43) + { 0, { 0, 0, 0}}, // (151, 43) + { 0, { 0, 0, 0}}, // (152, 43) + { 0, { 0, 0, 0}}, // (153, 43) + { 0, { 0, 0, 0}}, // (154, 43) + { 0, { 0, 0, 0}}, // (155, 43) + { 0, { 0, 0, 0}}, // (156, 43) + { 0, { 0, 0, 0}}, // (157, 43) + { 0, { 0, 0, 0}}, // (158, 43) + { 0, { 0, 0, 0}}, // (159, 43) + { 0, { 0, 0, 0}}, // (160, 43) + { 0, { 0, 0, 0}}, // (161, 43) + { 0, { 0, 0, 0}}, // (162, 43) + { 0, { 0, 0, 0}}, // (163, 43) + { 38, { 0, 0, 0}}, // (164, 43) + {128, { 0, 0, 0}}, // (165, 43) + {128, { 0, 0, 0}}, // (166, 43) + {128, { 0, 0, 0}}, // (167, 43) + {128, { 0, 0, 0}}, // (168, 43) + {128, { 0, 0, 0}}, // (169, 43) + {128, { 0, 0, 0}}, // (170, 43) + {128, { 0, 0, 0}}, // (171, 43) + {128, { 0, 0, 0}}, // (172, 43) + {128, { 0, 0, 0}}, // (173, 43) + {128, { 0, 0, 0}}, // (174, 43) + {128, { 0, 0, 0}}, // (175, 43) + {128, { 0, 0, 0}}, // (176, 43) + {128, { 0, 0, 0}}, // (177, 43) + {128, { 0, 0, 0}}, // (178, 43) + {128, { 0, 0, 0}}, // (179, 43) + {128, { 0, 0, 0}}, // ( 0, 44) + {128, { 0, 0, 0}}, // ( 1, 44) + {128, { 0, 0, 0}}, // ( 2, 44) + {128, { 0, 0, 0}}, // ( 3, 44) + {128, { 0, 0, 0}}, // ( 4, 44) + {128, { 0, 0, 0}}, // ( 5, 44) + {128, { 0, 0, 0}}, // ( 6, 44) + {128, { 0, 0, 0}}, // ( 7, 44) + {128, { 0, 0, 0}}, // ( 8, 44) + {128, { 0, 0, 0}}, // ( 9, 44) + {128, { 0, 0, 0}}, // ( 10, 44) + {128, { 0, 0, 0}}, // ( 11, 44) + {128, { 0, 0, 0}}, // ( 12, 44) + {128, { 0, 0, 0}}, // ( 13, 44) + { 86, { 0, 0, 0}}, // ( 14, 44) + { 0, { 0, 0, 0}}, // ( 15, 44) + { 0, { 0, 0, 0}}, // ( 16, 44) + { 0, { 0, 0, 0}}, // ( 17, 44) + { 0, { 0, 0, 0}}, // ( 18, 44) + { 0, { 0, 0, 0}}, // ( 19, 44) + { 0, { 0, 0, 0}}, // ( 20, 44) + { 0, { 0, 0, 0}}, // ( 21, 44) + { 0, { 0, 0, 0}}, // ( 22, 44) + { 0, { 0, 0, 0}}, // ( 23, 44) + { 0, { 0, 0, 0}}, // ( 24, 44) + { 0, { 0, 0, 0}}, // ( 25, 44) + { 0, { 0, 0, 0}}, // ( 26, 44) + { 0, { 0, 0, 0}}, // ( 27, 44) + { 0, { 0, 0, 0}}, // ( 28, 44) + { 0, { 0, 0, 0}}, // ( 29, 44) + { 0, { 0, 0, 0}}, // ( 30, 44) + { 0, { 0, 0, 0}}, // ( 31, 44) + { 0, { 0, 0, 0}}, // ( 32, 44) + { 0, { 0, 0, 0}}, // ( 33, 44) + { 0, { 0, 0, 0}}, // ( 34, 44) + { 0, { 0, 0, 0}}, // ( 35, 44) + { 0, { 0, 0, 0}}, // ( 36, 44) + { 0, { 0, 0, 0}}, // ( 37, 44) + { 0, { 0, 0, 0}}, // ( 38, 44) + { 0, { 0, 0, 0}}, // ( 39, 44) + { 0, { 0, 0, 0}}, // ( 40, 44) + { 0, { 0, 0, 0}}, // ( 41, 44) + { 0, { 0, 0, 0}}, // ( 42, 44) + { 0, { 0, 0, 0}}, // ( 43, 44) + { 0, { 0, 0, 0}}, // ( 44, 44) + { 0, { 0, 0, 0}}, // ( 45, 44) + { 0, { 0, 0, 0}}, // ( 46, 44) + { 0, { 0, 0, 0}}, // ( 47, 44) + { 0, { 0, 0, 0}}, // ( 48, 44) + { 0, { 0, 0, 0}}, // ( 49, 44) + { 0, { 0, 0, 0}}, // ( 50, 44) + { 0, { 0, 0, 0}}, // ( 51, 44) + { 0, { 0, 0, 0}}, // ( 52, 44) + { 0, { 0, 0, 0}}, // ( 53, 44) + { 0, { 0, 0, 0}}, // ( 54, 44) + { 0, { 0, 0, 0}}, // ( 55, 44) + { 0, { 0, 0, 0}}, // ( 56, 44) + { 0, { 0, 0, 0}}, // ( 57, 44) + { 0, { 0, 0, 0}}, // ( 58, 44) + { 0, { 0, 0, 0}}, // ( 59, 44) + { 0, { 0, 0, 0}}, // ( 60, 44) + { 0, { 0, 0, 0}}, // ( 61, 44) + { 0, { 0, 0, 0}}, // ( 62, 44) + { 0, { 0, 0, 0}}, // ( 63, 44) + { 0, { 0, 0, 0}}, // ( 64, 44) + { 0, { 0, 0, 0}}, // ( 65, 44) + { 0, { 0, 0, 0}}, // ( 66, 44) + { 0, { 0, 0, 0}}, // ( 67, 44) + { 0, { 0, 0, 0}}, // ( 68, 44) + { 0, { 0, 0, 0}}, // ( 69, 44) + { 0, { 0, 0, 0}}, // ( 70, 44) + { 0, { 0, 0, 0}}, // ( 71, 44) + { 0, { 0, 0, 0}}, // ( 72, 44) + { 0, { 0, 0, 0}}, // ( 73, 44) + { 0, { 0, 0, 0}}, // ( 74, 44) + { 0, { 0, 0, 0}}, // ( 75, 44) + { 0, { 0, 0, 0}}, // ( 76, 44) + { 0, { 0, 0, 0}}, // ( 77, 44) + { 0, { 0, 0, 0}}, // ( 78, 44) + { 0, { 0, 0, 0}}, // ( 79, 44) + { 0, { 0, 0, 0}}, // ( 80, 44) + { 0, { 0, 0, 0}}, // ( 81, 44) + { 0, { 0, 0, 0}}, // ( 82, 44) + { 0, { 0, 0, 0}}, // ( 83, 44) + { 0, { 0, 0, 0}}, // ( 84, 44) + { 0, { 0, 0, 0}}, // ( 85, 44) + { 0, { 0, 0, 0}}, // ( 86, 44) + { 0, { 0, 0, 0}}, // ( 87, 44) + { 0, { 0, 0, 0}}, // ( 88, 44) + { 0, { 0, 0, 0}}, // ( 89, 44) + { 0, { 0, 0, 0}}, // ( 90, 44) + { 0, { 0, 0, 0}}, // ( 91, 44) + { 0, { 0, 0, 0}}, // ( 92, 44) + { 0, { 0, 0, 0}}, // ( 93, 44) + { 0, { 0, 0, 0}}, // ( 94, 44) + { 0, { 0, 0, 0}}, // ( 95, 44) + { 0, { 0, 0, 0}}, // ( 96, 44) + { 0, { 0, 0, 0}}, // ( 97, 44) + { 0, { 0, 0, 0}}, // ( 98, 44) + { 0, { 0, 0, 0}}, // ( 99, 44) + { 0, { 0, 0, 0}}, // (100, 44) + { 0, { 0, 0, 0}}, // (101, 44) + { 0, { 0, 0, 0}}, // (102, 44) + { 0, { 0, 0, 0}}, // (103, 44) + { 0, { 0, 0, 0}}, // (104, 44) + { 0, { 0, 0, 0}}, // (105, 44) + { 0, { 0, 0, 0}}, // (106, 44) + { 0, { 0, 0, 0}}, // (107, 44) + { 0, { 0, 0, 0}}, // (108, 44) + { 0, { 0, 0, 0}}, // (109, 44) + { 0, { 0, 0, 0}}, // (110, 44) + { 0, { 0, 0, 0}}, // (111, 44) + { 0, { 0, 0, 0}}, // (112, 44) + { 0, { 0, 0, 0}}, // (113, 44) + { 0, { 0, 0, 0}}, // (114, 44) + { 0, { 0, 0, 0}}, // (115, 44) + { 0, { 0, 0, 0}}, // (116, 44) + { 0, { 0, 0, 0}}, // (117, 44) + { 0, { 0, 0, 0}}, // (118, 44) + { 0, { 0, 0, 0}}, // (119, 44) + { 0, { 0, 0, 0}}, // (120, 44) + { 0, { 0, 0, 0}}, // (121, 44) + { 0, { 0, 0, 0}}, // (122, 44) + { 0, { 0, 0, 0}}, // (123, 44) + { 0, { 0, 0, 0}}, // (124, 44) + { 0, { 0, 0, 0}}, // (125, 44) + { 0, { 0, 0, 0}}, // (126, 44) + { 0, { 0, 0, 0}}, // (127, 44) + { 0, { 0, 0, 0}}, // (128, 44) + { 0, { 0, 0, 0}}, // (129, 44) + { 0, { 0, 0, 0}}, // (130, 44) + { 0, { 0, 0, 0}}, // (131, 44) + { 0, { 0, 0, 0}}, // (132, 44) + { 0, { 0, 0, 0}}, // (133, 44) + { 0, { 0, 0, 0}}, // (134, 44) + { 0, { 0, 0, 0}}, // (135, 44) + { 0, { 0, 0, 0}}, // (136, 44) + { 0, { 0, 0, 0}}, // (137, 44) + { 0, { 0, 0, 0}}, // (138, 44) + { 0, { 0, 0, 0}}, // (139, 44) + { 0, { 0, 0, 0}}, // (140, 44) + { 0, { 0, 0, 0}}, // (141, 44) + { 0, { 0, 0, 0}}, // (142, 44) + { 0, { 0, 0, 0}}, // (143, 44) + { 0, { 0, 0, 0}}, // (144, 44) + { 0, { 0, 0, 0}}, // (145, 44) + { 0, { 0, 0, 0}}, // (146, 44) + { 0, { 0, 0, 0}}, // (147, 44) + { 0, { 0, 0, 0}}, // (148, 44) + { 0, { 0, 0, 0}}, // (149, 44) + { 0, { 0, 0, 0}}, // (150, 44) + { 0, { 0, 0, 0}}, // (151, 44) + { 0, { 0, 0, 0}}, // (152, 44) + { 0, { 0, 0, 0}}, // (153, 44) + { 0, { 0, 0, 0}}, // (154, 44) + { 0, { 0, 0, 0}}, // (155, 44) + { 0, { 0, 0, 0}}, // (156, 44) + { 0, { 0, 0, 0}}, // (157, 44) + { 0, { 0, 0, 0}}, // (158, 44) + { 0, { 0, 0, 0}}, // (159, 44) + { 0, { 0, 0, 0}}, // (160, 44) + { 0, { 0, 0, 0}}, // (161, 44) + { 0, { 0, 0, 0}}, // (162, 44) + { 0, { 0, 0, 0}}, // (163, 44) + { 0, { 0, 0, 0}}, // (164, 44) + { 86, { 0, 0, 0}}, // (165, 44) + {128, { 0, 0, 0}}, // (166, 44) + {128, { 0, 0, 0}}, // (167, 44) + {128, { 0, 0, 0}}, // (168, 44) + {128, { 0, 0, 0}}, // (169, 44) + {128, { 0, 0, 0}}, // (170, 44) + {128, { 0, 0, 0}}, // (171, 44) + {128, { 0, 0, 0}}, // (172, 44) + {128, { 0, 0, 0}}, // (173, 44) + {128, { 0, 0, 0}}, // (174, 44) + {128, { 0, 0, 0}}, // (175, 44) + {128, { 0, 0, 0}}, // (176, 44) + {128, { 0, 0, 0}}, // (177, 44) + {128, { 0, 0, 0}}, // (178, 44) + {128, { 0, 0, 0}}, // (179, 44) + {128, { 0, 0, 0}}, // ( 0, 45) + {128, { 0, 0, 0}}, // ( 1, 45) + {128, { 0, 0, 0}}, // ( 2, 45) + {128, { 0, 0, 0}}, // ( 3, 45) + {128, { 0, 0, 0}}, // ( 4, 45) + {128, { 0, 0, 0}}, // ( 5, 45) + {128, { 0, 0, 0}}, // ( 6, 45) + {128, { 0, 0, 0}}, // ( 7, 45) + {128, { 0, 0, 0}}, // ( 8, 45) + {128, { 0, 0, 0}}, // ( 9, 45) + {128, { 0, 0, 0}}, // ( 10, 45) + {128, { 0, 0, 0}}, // ( 11, 45) + {128, { 0, 0, 0}}, // ( 12, 45) + {124, { 0, 0, 0}}, // ( 13, 45) + { 16, { 0, 0, 0}}, // ( 14, 45) + { 0, { 0, 0, 0}}, // ( 15, 45) + { 0, { 0, 0, 0}}, // ( 16, 45) + { 0, { 0, 0, 0}}, // ( 17, 45) + { 0, { 0, 0, 0}}, // ( 18, 45) + { 0, { 0, 0, 0}}, // ( 19, 45) + { 0, { 0, 0, 0}}, // ( 20, 45) + { 0, { 0, 0, 0}}, // ( 21, 45) + { 0, { 0, 0, 0}}, // ( 22, 45) + { 0, { 0, 0, 0}}, // ( 23, 45) + { 0, { 0, 0, 0}}, // ( 24, 45) + { 0, { 0, 0, 0}}, // ( 25, 45) + { 0, { 0, 0, 0}}, // ( 26, 45) + { 0, { 0, 0, 0}}, // ( 27, 45) + { 0, { 0, 0, 0}}, // ( 28, 45) + { 0, { 0, 0, 0}}, // ( 29, 45) + { 0, { 0, 0, 0}}, // ( 30, 45) + { 0, { 0, 0, 0}}, // ( 31, 45) + { 0, { 0, 0, 0}}, // ( 32, 45) + { 0, { 0, 0, 0}}, // ( 33, 45) + { 0, { 0, 0, 0}}, // ( 34, 45) + { 0, { 0, 0, 0}}, // ( 35, 45) + { 0, { 0, 0, 0}}, // ( 36, 45) + { 0, { 0, 0, 0}}, // ( 37, 45) + { 0, { 0, 0, 0}}, // ( 38, 45) + { 0, { 0, 0, 0}}, // ( 39, 45) + { 0, { 0, 0, 0}}, // ( 40, 45) + { 0, { 0, 0, 0}}, // ( 41, 45) + { 0, { 0, 0, 0}}, // ( 42, 45) + { 0, { 0, 0, 0}}, // ( 43, 45) + { 0, { 0, 0, 0}}, // ( 44, 45) + { 0, { 0, 0, 0}}, // ( 45, 45) + { 0, { 0, 0, 0}}, // ( 46, 45) + { 0, { 0, 0, 0}}, // ( 47, 45) + { 0, { 0, 0, 0}}, // ( 48, 45) + { 0, { 0, 0, 0}}, // ( 49, 45) + { 0, { 0, 0, 0}}, // ( 50, 45) + { 0, { 0, 0, 0}}, // ( 51, 45) + { 0, { 0, 0, 0}}, // ( 52, 45) + { 0, { 0, 0, 0}}, // ( 53, 45) + { 0, { 0, 0, 0}}, // ( 54, 45) + { 0, { 0, 0, 0}}, // ( 55, 45) + { 0, { 0, 0, 0}}, // ( 56, 45) + { 0, { 0, 0, 0}}, // ( 57, 45) + { 0, { 0, 0, 0}}, // ( 58, 45) + { 0, { 0, 0, 0}}, // ( 59, 45) + { 0, { 0, 0, 0}}, // ( 60, 45) + { 0, { 0, 0, 0}}, // ( 61, 45) + { 0, { 0, 0, 0}}, // ( 62, 45) + { 0, { 0, 0, 0}}, // ( 63, 45) + { 0, { 0, 0, 0}}, // ( 64, 45) + { 0, { 0, 0, 0}}, // ( 65, 45) + { 0, { 0, 0, 0}}, // ( 66, 45) + { 0, { 0, 0, 0}}, // ( 67, 45) + { 0, { 0, 0, 0}}, // ( 68, 45) + { 0, { 0, 0, 0}}, // ( 69, 45) + { 0, { 0, 0, 0}}, // ( 70, 45) + { 0, { 0, 0, 0}}, // ( 71, 45) + { 0, { 0, 0, 0}}, // ( 72, 45) + { 0, { 0, 0, 0}}, // ( 73, 45) + { 0, { 0, 0, 0}}, // ( 74, 45) + { 0, { 0, 0, 0}}, // ( 75, 45) + { 0, { 0, 0, 0}}, // ( 76, 45) + { 0, { 0, 0, 0}}, // ( 77, 45) + { 0, { 0, 0, 0}}, // ( 78, 45) + { 0, { 0, 0, 0}}, // ( 79, 45) + { 0, { 0, 0, 0}}, // ( 80, 45) + { 0, { 0, 0, 0}}, // ( 81, 45) + { 0, { 0, 0, 0}}, // ( 82, 45) + { 0, { 0, 0, 0}}, // ( 83, 45) + { 0, { 0, 0, 0}}, // ( 84, 45) + { 0, { 0, 0, 0}}, // ( 85, 45) + { 0, { 0, 0, 0}}, // ( 86, 45) + { 0, { 0, 0, 0}}, // ( 87, 45) + { 0, { 0, 0, 0}}, // ( 88, 45) + { 0, { 0, 0, 0}}, // ( 89, 45) + { 0, { 0, 0, 0}}, // ( 90, 45) + { 0, { 0, 0, 0}}, // ( 91, 45) + { 0, { 0, 0, 0}}, // ( 92, 45) + { 0, { 0, 0, 0}}, // ( 93, 45) + { 0, { 0, 0, 0}}, // ( 94, 45) + { 0, { 0, 0, 0}}, // ( 95, 45) + { 0, { 0, 0, 0}}, // ( 96, 45) + { 0, { 0, 0, 0}}, // ( 97, 45) + { 0, { 0, 0, 0}}, // ( 98, 45) + { 0, { 0, 0, 0}}, // ( 99, 45) + { 0, { 0, 0, 0}}, // (100, 45) + { 0, { 0, 0, 0}}, // (101, 45) + { 0, { 0, 0, 0}}, // (102, 45) + { 0, { 0, 0, 0}}, // (103, 45) + { 0, { 0, 0, 0}}, // (104, 45) + { 0, { 0, 0, 0}}, // (105, 45) + { 0, { 0, 0, 0}}, // (106, 45) + { 0, { 0, 0, 0}}, // (107, 45) + { 0, { 0, 0, 0}}, // (108, 45) + { 0, { 0, 0, 0}}, // (109, 45) + { 0, { 0, 0, 0}}, // (110, 45) + { 0, { 0, 0, 0}}, // (111, 45) + { 0, { 0, 0, 0}}, // (112, 45) + { 0, { 0, 0, 0}}, // (113, 45) + { 0, { 0, 0, 0}}, // (114, 45) + { 0, { 0, 0, 0}}, // (115, 45) + { 0, { 0, 0, 0}}, // (116, 45) + { 0, { 0, 0, 0}}, // (117, 45) + { 0, { 0, 0, 0}}, // (118, 45) + { 0, { 0, 0, 0}}, // (119, 45) + { 0, { 0, 0, 0}}, // (120, 45) + { 0, { 0, 0, 0}}, // (121, 45) + { 0, { 0, 0, 0}}, // (122, 45) + { 0, { 0, 0, 0}}, // (123, 45) + { 0, { 0, 0, 0}}, // (124, 45) + { 0, { 0, 0, 0}}, // (125, 45) + { 0, { 0, 0, 0}}, // (126, 45) + { 0, { 0, 0, 0}}, // (127, 45) + { 0, { 0, 0, 0}}, // (128, 45) + { 0, { 0, 0, 0}}, // (129, 45) + { 0, { 0, 0, 0}}, // (130, 45) + { 0, { 0, 0, 0}}, // (131, 45) + { 0, { 0, 0, 0}}, // (132, 45) + { 0, { 0, 0, 0}}, // (133, 45) + { 0, { 0, 0, 0}}, // (134, 45) + { 0, { 0, 0, 0}}, // (135, 45) + { 0, { 0, 0, 0}}, // (136, 45) + { 0, { 0, 0, 0}}, // (137, 45) + { 0, { 0, 0, 0}}, // (138, 45) + { 0, { 0, 0, 0}}, // (139, 45) + { 0, { 0, 0, 0}}, // (140, 45) + { 0, { 0, 0, 0}}, // (141, 45) + { 0, { 0, 0, 0}}, // (142, 45) + { 0, { 0, 0, 0}}, // (143, 45) + { 0, { 0, 0, 0}}, // (144, 45) + { 0, { 0, 0, 0}}, // (145, 45) + { 0, { 0, 0, 0}}, // (146, 45) + { 0, { 0, 0, 0}}, // (147, 45) + { 0, { 0, 0, 0}}, // (148, 45) + { 0, { 0, 0, 0}}, // (149, 45) + { 0, { 0, 0, 0}}, // (150, 45) + { 0, { 0, 0, 0}}, // (151, 45) + { 0, { 0, 0, 0}}, // (152, 45) + { 0, { 0, 0, 0}}, // (153, 45) + { 0, { 0, 0, 0}}, // (154, 45) + { 0, { 0, 0, 0}}, // (155, 45) + { 0, { 0, 0, 0}}, // (156, 45) + { 0, { 0, 0, 0}}, // (157, 45) + { 0, { 0, 0, 0}}, // (158, 45) + { 0, { 0, 0, 0}}, // (159, 45) + { 0, { 0, 0, 0}}, // (160, 45) + { 0, { 0, 0, 0}}, // (161, 45) + { 0, { 0, 0, 0}}, // (162, 45) + { 0, { 0, 0, 0}}, // (163, 45) + { 0, { 0, 0, 0}}, // (164, 45) + { 16, { 0, 0, 0}}, // (165, 45) + {124, { 0, 0, 0}}, // (166, 45) + {128, { 0, 0, 0}}, // (167, 45) + {128, { 0, 0, 0}}, // (168, 45) + {128, { 0, 0, 0}}, // (169, 45) + {128, { 0, 0, 0}}, // (170, 45) + {128, { 0, 0, 0}}, // (171, 45) + {128, { 0, 0, 0}}, // (172, 45) + {128, { 0, 0, 0}}, // (173, 45) + {128, { 0, 0, 0}}, // (174, 45) + {128, { 0, 0, 0}}, // (175, 45) + {128, { 0, 0, 0}}, // (176, 45) + {128, { 0, 0, 0}}, // (177, 45) + {128, { 0, 0, 0}}, // (178, 45) + {128, { 0, 0, 0}}, // (179, 45) + {128, { 0, 0, 0}}, // ( 0, 46) + {128, { 0, 0, 0}}, // ( 1, 46) + {128, { 0, 0, 0}}, // ( 2, 46) + {128, { 0, 0, 0}}, // ( 3, 46) + {128, { 0, 0, 0}}, // ( 4, 46) + {128, { 0, 0, 0}}, // ( 5, 46) + {128, { 0, 0, 0}}, // ( 6, 46) + {128, { 0, 0, 0}}, // ( 7, 46) + {128, { 0, 0, 0}}, // ( 8, 46) + {128, { 0, 0, 0}}, // ( 9, 46) + {128, { 0, 0, 0}}, // ( 10, 46) + {128, { 0, 0, 0}}, // ( 11, 46) + {128, { 0, 0, 0}}, // ( 12, 46) + { 66, { 0, 0, 0}}, // ( 13, 46) + { 0, { 0, 0, 0}}, // ( 14, 46) + { 0, { 0, 0, 0}}, // ( 15, 46) + { 0, { 0, 0, 0}}, // ( 16, 46) + { 0, { 0, 0, 0}}, // ( 17, 46) + { 0, { 0, 0, 0}}, // ( 18, 46) + { 0, { 0, 0, 0}}, // ( 19, 46) + { 0, { 0, 0, 0}}, // ( 20, 46) + { 0, { 0, 0, 0}}, // ( 21, 46) + { 0, { 0, 0, 0}}, // ( 22, 46) + { 0, { 0, 0, 0}}, // ( 23, 46) + { 0, { 0, 0, 0}}, // ( 24, 46) + { 0, { 0, 0, 0}}, // ( 25, 46) + { 0, { 0, 0, 0}}, // ( 26, 46) + { 0, { 0, 0, 0}}, // ( 27, 46) + { 0, { 0, 0, 0}}, // ( 28, 46) + { 0, { 0, 0, 0}}, // ( 29, 46) + { 0, { 0, 0, 0}}, // ( 30, 46) + { 0, { 0, 0, 0}}, // ( 31, 46) + { 0, { 0, 0, 0}}, // ( 32, 46) + { 0, { 0, 0, 0}}, // ( 33, 46) + { 0, { 0, 0, 0}}, // ( 34, 46) + { 0, { 0, 0, 0}}, // ( 35, 46) + { 0, { 0, 0, 0}}, // ( 36, 46) + { 0, { 0, 0, 0}}, // ( 37, 46) + { 0, { 0, 0, 0}}, // ( 38, 46) + { 0, { 0, 0, 0}}, // ( 39, 46) + { 0, { 0, 0, 0}}, // ( 40, 46) + { 0, { 0, 0, 0}}, // ( 41, 46) + { 0, { 0, 0, 0}}, // ( 42, 46) + { 0, { 0, 0, 0}}, // ( 43, 46) + { 0, { 0, 0, 0}}, // ( 44, 46) + { 0, { 0, 0, 0}}, // ( 45, 46) + { 0, { 0, 0, 0}}, // ( 46, 46) + { 0, { 0, 0, 0}}, // ( 47, 46) + { 0, { 0, 0, 0}}, // ( 48, 46) + { 0, { 0, 0, 0}}, // ( 49, 46) + { 0, { 0, 0, 0}}, // ( 50, 46) + { 0, { 0, 0, 0}}, // ( 51, 46) + { 0, { 0, 0, 0}}, // ( 52, 46) + { 0, { 0, 0, 0}}, // ( 53, 46) + { 0, { 0, 0, 0}}, // ( 54, 46) + { 0, { 0, 0, 0}}, // ( 55, 46) + { 0, { 0, 0, 0}}, // ( 56, 46) + { 0, { 0, 0, 0}}, // ( 57, 46) + { 0, { 0, 0, 0}}, // ( 58, 46) + { 0, { 0, 0, 0}}, // ( 59, 46) + { 0, { 0, 0, 0}}, // ( 60, 46) + { 0, { 0, 0, 0}}, // ( 61, 46) + { 0, { 0, 0, 0}}, // ( 62, 46) + { 0, { 0, 0, 0}}, // ( 63, 46) + { 0, { 0, 0, 0}}, // ( 64, 46) + { 0, { 0, 0, 0}}, // ( 65, 46) + { 0, { 0, 0, 0}}, // ( 66, 46) + { 0, { 0, 0, 0}}, // ( 67, 46) + { 0, { 0, 0, 0}}, // ( 68, 46) + { 0, { 0, 0, 0}}, // ( 69, 46) + { 0, { 0, 0, 0}}, // ( 70, 46) + { 0, { 0, 0, 0}}, // ( 71, 46) + { 0, { 0, 0, 0}}, // ( 72, 46) + { 0, { 0, 0, 0}}, // ( 73, 46) + { 0, { 0, 0, 0}}, // ( 74, 46) + { 0, { 0, 0, 0}}, // ( 75, 46) + { 0, { 0, 0, 0}}, // ( 76, 46) + { 0, { 0, 0, 0}}, // ( 77, 46) + { 0, { 0, 0, 0}}, // ( 78, 46) + { 0, { 0, 0, 0}}, // ( 79, 46) + { 0, { 0, 0, 0}}, // ( 80, 46) + { 0, { 0, 0, 0}}, // ( 81, 46) + { 0, { 0, 0, 0}}, // ( 82, 46) + { 0, { 0, 0, 0}}, // ( 83, 46) + { 0, { 0, 0, 0}}, // ( 84, 46) + { 0, { 0, 0, 0}}, // ( 85, 46) + { 0, { 0, 0, 0}}, // ( 86, 46) + { 0, { 0, 0, 0}}, // ( 87, 46) + { 0, { 0, 0, 0}}, // ( 88, 46) + { 0, { 0, 0, 0}}, // ( 89, 46) + { 0, { 0, 0, 0}}, // ( 90, 46) + { 0, { 0, 0, 0}}, // ( 91, 46) + { 0, { 0, 0, 0}}, // ( 92, 46) + { 0, { 0, 0, 0}}, // ( 93, 46) + { 0, { 0, 0, 0}}, // ( 94, 46) + { 0, { 0, 0, 0}}, // ( 95, 46) + { 0, { 0, 0, 0}}, // ( 96, 46) + { 0, { 0, 0, 0}}, // ( 97, 46) + { 0, { 0, 0, 0}}, // ( 98, 46) + { 0, { 0, 0, 0}}, // ( 99, 46) + { 0, { 0, 0, 0}}, // (100, 46) + { 0, { 0, 0, 0}}, // (101, 46) + { 0, { 0, 0, 0}}, // (102, 46) + { 0, { 0, 0, 0}}, // (103, 46) + { 0, { 0, 0, 0}}, // (104, 46) + { 0, { 0, 0, 0}}, // (105, 46) + { 0, { 0, 0, 0}}, // (106, 46) + { 0, { 0, 0, 0}}, // (107, 46) + { 0, { 0, 0, 0}}, // (108, 46) + { 0, { 0, 0, 0}}, // (109, 46) + { 0, { 0, 0, 0}}, // (110, 46) + { 0, { 0, 0, 0}}, // (111, 46) + { 0, { 0, 0, 0}}, // (112, 46) + { 0, { 0, 0, 0}}, // (113, 46) + { 0, { 0, 0, 0}}, // (114, 46) + { 0, { 0, 0, 0}}, // (115, 46) + { 0, { 0, 0, 0}}, // (116, 46) + { 0, { 0, 0, 0}}, // (117, 46) + { 0, { 0, 0, 0}}, // (118, 46) + { 0, { 0, 0, 0}}, // (119, 46) + { 0, { 0, 0, 0}}, // (120, 46) + { 0, { 0, 0, 0}}, // (121, 46) + { 0, { 0, 0, 0}}, // (122, 46) + { 0, { 0, 0, 0}}, // (123, 46) + { 0, { 0, 0, 0}}, // (124, 46) + { 0, { 0, 0, 0}}, // (125, 46) + { 0, { 0, 0, 0}}, // (126, 46) + { 0, { 0, 0, 0}}, // (127, 46) + { 0, { 0, 0, 0}}, // (128, 46) + { 0, { 0, 0, 0}}, // (129, 46) + { 0, { 0, 0, 0}}, // (130, 46) + { 0, { 0, 0, 0}}, // (131, 46) + { 0, { 0, 0, 0}}, // (132, 46) + { 0, { 0, 0, 0}}, // (133, 46) + { 0, { 0, 0, 0}}, // (134, 46) + { 0, { 0, 0, 0}}, // (135, 46) + { 0, { 0, 0, 0}}, // (136, 46) + { 0, { 0, 0, 0}}, // (137, 46) + { 0, { 0, 0, 0}}, // (138, 46) + { 0, { 0, 0, 0}}, // (139, 46) + { 0, { 0, 0, 0}}, // (140, 46) + { 0, { 0, 0, 0}}, // (141, 46) + { 0, { 0, 0, 0}}, // (142, 46) + { 0, { 0, 0, 0}}, // (143, 46) + { 0, { 0, 0, 0}}, // (144, 46) + { 0, { 0, 0, 0}}, // (145, 46) + { 0, { 0, 0, 0}}, // (146, 46) + { 0, { 0, 0, 0}}, // (147, 46) + { 0, { 0, 0, 0}}, // (148, 46) + { 0, { 0, 0, 0}}, // (149, 46) + { 0, { 0, 0, 0}}, // (150, 46) + { 0, { 0, 0, 0}}, // (151, 46) + { 0, { 0, 0, 0}}, // (152, 46) + { 0, { 0, 0, 0}}, // (153, 46) + { 0, { 0, 0, 0}}, // (154, 46) + { 0, { 0, 0, 0}}, // (155, 46) + { 0, { 0, 0, 0}}, // (156, 46) + { 0, { 0, 0, 0}}, // (157, 46) + { 0, { 0, 0, 0}}, // (158, 46) + { 0, { 0, 0, 0}}, // (159, 46) + { 0, { 0, 0, 0}}, // (160, 46) + { 0, { 0, 0, 0}}, // (161, 46) + { 0, { 0, 0, 0}}, // (162, 46) + { 0, { 0, 0, 0}}, // (163, 46) + { 0, { 0, 0, 0}}, // (164, 46) + { 0, { 0, 0, 0}}, // (165, 46) + { 65, { 0, 0, 0}}, // (166, 46) + {128, { 0, 0, 0}}, // (167, 46) + {128, { 0, 0, 0}}, // (168, 46) + {128, { 0, 0, 0}}, // (169, 46) + {128, { 0, 0, 0}}, // (170, 46) + {128, { 0, 0, 0}}, // (171, 46) + {128, { 0, 0, 0}}, // (172, 46) + {128, { 0, 0, 0}}, // (173, 46) + {128, { 0, 0, 0}}, // (174, 46) + {128, { 0, 0, 0}}, // (175, 46) + {128, { 0, 0, 0}}, // (176, 46) + {128, { 0, 0, 0}}, // (177, 46) + {128, { 0, 0, 0}}, // (178, 46) + {128, { 0, 0, 0}}, // (179, 46) + {128, { 0, 0, 0}}, // ( 0, 47) + {128, { 0, 0, 0}}, // ( 1, 47) + {128, { 0, 0, 0}}, // ( 2, 47) + {128, { 0, 0, 0}}, // ( 3, 47) + {128, { 0, 0, 0}}, // ( 4, 47) + {128, { 0, 0, 0}}, // ( 5, 47) + {128, { 0, 0, 0}}, // ( 6, 47) + {128, { 0, 0, 0}}, // ( 7, 47) + {128, { 0, 0, 0}}, // ( 8, 47) + {128, { 0, 0, 0}}, // ( 9, 47) + {128, { 0, 0, 0}}, // ( 10, 47) + {128, { 0, 0, 0}}, // ( 11, 47) + {114, { 0, 0, 0}}, // ( 12, 47) + { 6, { 0, 0, 0}}, // ( 13, 47) + { 0, { 0, 0, 0}}, // ( 14, 47) + { 0, { 0, 0, 0}}, // ( 15, 47) + { 0, { 0, 0, 0}}, // ( 16, 47) + { 0, { 0, 0, 0}}, // ( 17, 47) + { 0, { 0, 0, 0}}, // ( 18, 47) + { 0, { 0, 0, 0}}, // ( 19, 47) + { 0, { 0, 0, 0}}, // ( 20, 47) + { 0, { 0, 0, 0}}, // ( 21, 47) + { 0, { 0, 0, 0}}, // ( 22, 47) + { 0, { 0, 0, 0}}, // ( 23, 47) + { 0, { 0, 0, 0}}, // ( 24, 47) + { 0, { 0, 0, 0}}, // ( 25, 47) + { 0, { 0, 0, 0}}, // ( 26, 47) + { 0, { 0, 0, 0}}, // ( 27, 47) + { 0, { 0, 0, 0}}, // ( 28, 47) + { 0, { 0, 0, 0}}, // ( 29, 47) + { 0, { 0, 0, 0}}, // ( 30, 47) + { 0, { 0, 0, 0}}, // ( 31, 47) + { 0, { 0, 0, 0}}, // ( 32, 47) + { 0, { 0, 0, 0}}, // ( 33, 47) + { 0, { 0, 0, 0}}, // ( 34, 47) + { 0, { 0, 0, 0}}, // ( 35, 47) + { 0, { 0, 0, 0}}, // ( 36, 47) + { 0, { 0, 0, 0}}, // ( 37, 47) + { 0, { 0, 0, 0}}, // ( 38, 47) + { 0, { 0, 0, 0}}, // ( 39, 47) + { 0, { 0, 0, 0}}, // ( 40, 47) + { 0, { 0, 0, 0}}, // ( 41, 47) + { 0, { 0, 0, 0}}, // ( 42, 47) + { 0, { 0, 0, 0}}, // ( 43, 47) + { 0, { 0, 0, 0}}, // ( 44, 47) + { 0, { 0, 0, 0}}, // ( 45, 47) + { 0, { 0, 0, 0}}, // ( 46, 47) + { 0, { 0, 0, 0}}, // ( 47, 47) + { 0, { 0, 0, 0}}, // ( 48, 47) + { 0, { 0, 0, 0}}, // ( 49, 47) + { 0, { 0, 0, 0}}, // ( 50, 47) + { 0, { 0, 0, 0}}, // ( 51, 47) + { 0, { 0, 0, 0}}, // ( 52, 47) + { 0, { 0, 0, 0}}, // ( 53, 47) + { 0, { 0, 0, 0}}, // ( 54, 47) + { 0, { 0, 0, 0}}, // ( 55, 47) + { 0, { 0, 0, 0}}, // ( 56, 47) + { 0, { 0, 0, 0}}, // ( 57, 47) + { 0, { 0, 0, 0}}, // ( 58, 47) + { 0, { 0, 0, 0}}, // ( 59, 47) + { 0, { 0, 0, 0}}, // ( 60, 47) + { 0, { 0, 0, 0}}, // ( 61, 47) + { 0, { 0, 0, 0}}, // ( 62, 47) + { 0, { 0, 0, 0}}, // ( 63, 47) + { 0, { 0, 0, 0}}, // ( 64, 47) + { 0, { 0, 0, 0}}, // ( 65, 47) + { 0, { 0, 0, 0}}, // ( 66, 47) + { 0, { 0, 0, 0}}, // ( 67, 47) + { 0, { 0, 0, 0}}, // ( 68, 47) + { 0, { 0, 0, 0}}, // ( 69, 47) + { 0, { 0, 0, 0}}, // ( 70, 47) + { 0, { 0, 0, 0}}, // ( 71, 47) + { 0, { 0, 0, 0}}, // ( 72, 47) + { 0, { 0, 0, 0}}, // ( 73, 47) + { 0, { 0, 0, 0}}, // ( 74, 47) + { 0, { 0, 0, 0}}, // ( 75, 47) + { 0, { 0, 0, 0}}, // ( 76, 47) + { 0, { 0, 0, 0}}, // ( 77, 47) + { 0, { 0, 0, 0}}, // ( 78, 47) + { 0, { 0, 0, 0}}, // ( 79, 47) + { 0, { 0, 0, 0}}, // ( 80, 47) + { 0, { 0, 0, 0}}, // ( 81, 47) + { 0, { 0, 0, 0}}, // ( 82, 47) + { 0, { 0, 0, 0}}, // ( 83, 47) + { 0, { 0, 0, 0}}, // ( 84, 47) + { 0, { 0, 0, 0}}, // ( 85, 47) + { 0, { 0, 0, 0}}, // ( 86, 47) + { 0, { 0, 0, 0}}, // ( 87, 47) + { 0, { 0, 0, 0}}, // ( 88, 47) + { 0, { 0, 0, 0}}, // ( 89, 47) + { 0, { 0, 0, 0}}, // ( 90, 47) + { 0, { 0, 0, 0}}, // ( 91, 47) + { 0, { 0, 0, 0}}, // ( 92, 47) + { 0, { 0, 0, 0}}, // ( 93, 47) + { 0, { 0, 0, 0}}, // ( 94, 47) + { 0, { 0, 0, 0}}, // ( 95, 47) + { 0, { 0, 0, 0}}, // ( 96, 47) + { 0, { 0, 0, 0}}, // ( 97, 47) + { 0, { 0, 0, 0}}, // ( 98, 47) + { 0, { 0, 0, 0}}, // ( 99, 47) + { 0, { 0, 0, 0}}, // (100, 47) + { 0, { 0, 0, 0}}, // (101, 47) + { 0, { 0, 0, 0}}, // (102, 47) + { 0, { 0, 0, 0}}, // (103, 47) + { 0, { 0, 0, 0}}, // (104, 47) + { 0, { 0, 0, 0}}, // (105, 47) + { 0, { 0, 0, 0}}, // (106, 47) + { 0, { 0, 0, 0}}, // (107, 47) + { 0, { 0, 0, 0}}, // (108, 47) + { 0, { 0, 0, 0}}, // (109, 47) + { 0, { 0, 0, 0}}, // (110, 47) + { 0, { 0, 0, 0}}, // (111, 47) + { 0, { 0, 0, 0}}, // (112, 47) + { 0, { 0, 0, 0}}, // (113, 47) + { 0, { 0, 0, 0}}, // (114, 47) + { 0, { 0, 0, 0}}, // (115, 47) + { 0, { 0, 0, 0}}, // (116, 47) + { 0, { 0, 0, 0}}, // (117, 47) + { 0, { 0, 0, 0}}, // (118, 47) + { 0, { 0, 0, 0}}, // (119, 47) + { 0, { 0, 0, 0}}, // (120, 47) + { 0, { 0, 0, 0}}, // (121, 47) + { 0, { 0, 0, 0}}, // (122, 47) + { 0, { 0, 0, 0}}, // (123, 47) + { 0, { 0, 0, 0}}, // (124, 47) + { 0, { 0, 0, 0}}, // (125, 47) + { 0, { 0, 0, 0}}, // (126, 47) + { 0, { 0, 0, 0}}, // (127, 47) + { 0, { 0, 0, 0}}, // (128, 47) + { 0, { 0, 0, 0}}, // (129, 47) + { 0, { 0, 0, 0}}, // (130, 47) + { 0, { 0, 0, 0}}, // (131, 47) + { 0, { 0, 0, 0}}, // (132, 47) + { 0, { 0, 0, 0}}, // (133, 47) + { 0, { 0, 0, 0}}, // (134, 47) + { 0, { 0, 0, 0}}, // (135, 47) + { 0, { 0, 0, 0}}, // (136, 47) + { 0, { 0, 0, 0}}, // (137, 47) + { 0, { 0, 0, 0}}, // (138, 47) + { 0, { 0, 0, 0}}, // (139, 47) + { 0, { 0, 0, 0}}, // (140, 47) + { 0, { 0, 0, 0}}, // (141, 47) + { 0, { 0, 0, 0}}, // (142, 47) + { 0, { 0, 0, 0}}, // (143, 47) + { 0, { 0, 0, 0}}, // (144, 47) + { 0, { 0, 0, 0}}, // (145, 47) + { 0, { 0, 0, 0}}, // (146, 47) + { 0, { 0, 0, 0}}, // (147, 47) + { 0, { 0, 0, 0}}, // (148, 47) + { 0, { 0, 0, 0}}, // (149, 47) + { 0, { 0, 0, 0}}, // (150, 47) + { 0, { 0, 0, 0}}, // (151, 47) + { 0, { 0, 0, 0}}, // (152, 47) + { 0, { 0, 0, 0}}, // (153, 47) + { 0, { 0, 0, 0}}, // (154, 47) + { 0, { 0, 0, 0}}, // (155, 47) + { 0, { 0, 0, 0}}, // (156, 47) + { 0, { 0, 0, 0}}, // (157, 47) + { 0, { 0, 0, 0}}, // (158, 47) + { 0, { 0, 0, 0}}, // (159, 47) + { 0, { 0, 0, 0}}, // (160, 47) + { 0, { 0, 0, 0}}, // (161, 47) + { 0, { 0, 0, 0}}, // (162, 47) + { 0, { 0, 0, 0}}, // (163, 47) + { 0, { 0, 0, 0}}, // (164, 47) + { 0, { 0, 0, 0}}, // (165, 47) + { 6, { 0, 0, 0}}, // (166, 47) + {114, { 0, 0, 0}}, // (167, 47) + {128, { 0, 0, 0}}, // (168, 47) + {128, { 0, 0, 0}}, // (169, 47) + {128, { 0, 0, 0}}, // (170, 47) + {128, { 0, 0, 0}}, // (171, 47) + {128, { 0, 0, 0}}, // (172, 47) + {128, { 0, 0, 0}}, // (173, 47) + {128, { 0, 0, 0}}, // (174, 47) + {128, { 0, 0, 0}}, // (175, 47) + {128, { 0, 0, 0}}, // (176, 47) + {128, { 0, 0, 0}}, // (177, 47) + {128, { 0, 0, 0}}, // (178, 47) + {128, { 0, 0, 0}}, // (179, 47) + {128, { 0, 0, 0}}, // ( 0, 48) + {128, { 0, 0, 0}}, // ( 1, 48) + {128, { 0, 0, 0}}, // ( 2, 48) + {128, { 0, 0, 0}}, // ( 3, 48) + {128, { 0, 0, 0}}, // ( 4, 48) + {128, { 0, 0, 0}}, // ( 5, 48) + {128, { 0, 0, 0}}, // ( 6, 48) + {128, { 0, 0, 0}}, // ( 7, 48) + {128, { 0, 0, 0}}, // ( 8, 48) + {128, { 0, 0, 0}}, // ( 9, 48) + {128, { 0, 0, 0}}, // ( 10, 48) + {128, { 0, 0, 0}}, // ( 11, 48) + { 51, { 0, 0, 0}}, // ( 12, 48) + { 0, { 0, 0, 0}}, // ( 13, 48) + { 0, { 0, 0, 0}}, // ( 14, 48) + { 0, { 0, 0, 0}}, // ( 15, 48) + { 0, { 0, 0, 0}}, // ( 16, 48) + { 0, { 0, 0, 0}}, // ( 17, 48) + { 0, { 0, 0, 0}}, // ( 18, 48) + { 0, { 0, 0, 0}}, // ( 19, 48) + { 0, { 0, 0, 0}}, // ( 20, 48) + { 0, { 0, 0, 0}}, // ( 21, 48) + { 0, { 0, 0, 0}}, // ( 22, 48) + { 0, { 0, 0, 0}}, // ( 23, 48) + { 0, { 0, 0, 0}}, // ( 24, 48) + { 0, { 0, 0, 0}}, // ( 25, 48) + { 0, { 0, 0, 0}}, // ( 26, 48) + { 0, { 0, 0, 0}}, // ( 27, 48) + { 0, { 0, 0, 0}}, // ( 28, 48) + { 0, { 0, 0, 0}}, // ( 29, 48) + { 0, { 0, 0, 0}}, // ( 30, 48) + { 0, { 0, 0, 0}}, // ( 31, 48) + { 0, { 0, 0, 0}}, // ( 32, 48) + { 0, { 0, 0, 0}}, // ( 33, 48) + { 0, { 0, 0, 0}}, // ( 34, 48) + { 0, { 0, 0, 0}}, // ( 35, 48) + { 0, { 0, 0, 0}}, // ( 36, 48) + { 0, { 0, 0, 0}}, // ( 37, 48) + { 0, { 0, 0, 0}}, // ( 38, 48) + { 0, { 0, 0, 0}}, // ( 39, 48) + { 0, { 0, 0, 0}}, // ( 40, 48) + { 0, { 0, 0, 0}}, // ( 41, 48) + { 0, { 0, 0, 0}}, // ( 42, 48) + { 0, { 0, 0, 0}}, // ( 43, 48) + { 0, { 0, 0, 0}}, // ( 44, 48) + { 0, { 0, 0, 0}}, // ( 45, 48) + { 0, { 0, 0, 0}}, // ( 46, 48) + { 0, { 0, 0, 0}}, // ( 47, 48) + { 0, { 0, 0, 0}}, // ( 48, 48) + { 0, { 0, 0, 0}}, // ( 49, 48) + { 0, { 0, 0, 0}}, // ( 50, 48) + { 0, { 0, 0, 0}}, // ( 51, 48) + { 0, { 0, 0, 0}}, // ( 52, 48) + { 0, { 0, 0, 0}}, // ( 53, 48) + { 0, { 0, 0, 0}}, // ( 54, 48) + { 0, { 0, 0, 0}}, // ( 55, 48) + { 0, { 0, 0, 0}}, // ( 56, 48) + { 0, { 0, 0, 0}}, // ( 57, 48) + { 0, { 0, 0, 0}}, // ( 58, 48) + { 0, { 0, 0, 0}}, // ( 59, 48) + { 0, { 0, 0, 0}}, // ( 60, 48) + { 0, { 0, 0, 0}}, // ( 61, 48) + { 0, { 0, 0, 0}}, // ( 62, 48) + { 0, { 0, 0, 0}}, // ( 63, 48) + { 0, { 0, 0, 0}}, // ( 64, 48) + { 0, { 0, 0, 0}}, // ( 65, 48) + { 0, { 0, 0, 0}}, // ( 66, 48) + { 0, { 0, 0, 0}}, // ( 67, 48) + { 0, { 0, 0, 0}}, // ( 68, 48) + { 0, { 0, 0, 0}}, // ( 69, 48) + { 0, { 0, 0, 0}}, // ( 70, 48) + { 0, { 0, 0, 0}}, // ( 71, 48) + { 0, { 0, 0, 0}}, // ( 72, 48) + { 0, { 0, 0, 0}}, // ( 73, 48) + { 0, { 0, 0, 0}}, // ( 74, 48) + { 0, { 0, 0, 0}}, // ( 75, 48) + { 0, { 0, 0, 0}}, // ( 76, 48) + { 0, { 0, 0, 0}}, // ( 77, 48) + { 0, { 0, 0, 0}}, // ( 78, 48) + { 0, { 0, 0, 0}}, // ( 79, 48) + { 0, { 0, 0, 0}}, // ( 80, 48) + { 0, { 0, 0, 0}}, // ( 81, 48) + { 0, { 0, 0, 0}}, // ( 82, 48) + { 0, { 0, 0, 0}}, // ( 83, 48) + { 0, { 0, 0, 0}}, // ( 84, 48) + { 0, { 0, 0, 0}}, // ( 85, 48) + { 0, { 0, 0, 0}}, // ( 86, 48) + { 0, { 0, 0, 0}}, // ( 87, 48) + { 0, { 0, 0, 0}}, // ( 88, 48) + { 0, { 0, 0, 0}}, // ( 89, 48) + { 0, { 0, 0, 0}}, // ( 90, 48) + { 0, { 0, 0, 0}}, // ( 91, 48) + { 0, { 0, 0, 0}}, // ( 92, 48) + { 0, { 0, 0, 0}}, // ( 93, 48) + { 0, { 0, 0, 0}}, // ( 94, 48) + { 0, { 0, 0, 0}}, // ( 95, 48) + { 0, { 0, 0, 0}}, // ( 96, 48) + { 0, { 0, 0, 0}}, // ( 97, 48) + { 0, { 0, 0, 0}}, // ( 98, 48) + { 0, { 0, 0, 0}}, // ( 99, 48) + { 0, { 0, 0, 0}}, // (100, 48) + { 0, { 0, 0, 0}}, // (101, 48) + { 0, { 0, 0, 0}}, // (102, 48) + { 0, { 0, 0, 0}}, // (103, 48) + { 0, { 0, 0, 0}}, // (104, 48) + { 0, { 0, 0, 0}}, // (105, 48) + { 0, { 0, 0, 0}}, // (106, 48) + { 0, { 0, 0, 0}}, // (107, 48) + { 0, { 0, 0, 0}}, // (108, 48) + { 0, { 0, 0, 0}}, // (109, 48) + { 0, { 0, 0, 0}}, // (110, 48) + { 0, { 0, 0, 0}}, // (111, 48) + { 0, { 0, 0, 0}}, // (112, 48) + { 0, { 0, 0, 0}}, // (113, 48) + { 0, { 0, 0, 0}}, // (114, 48) + { 0, { 0, 0, 0}}, // (115, 48) + { 0, { 0, 0, 0}}, // (116, 48) + { 0, { 0, 0, 0}}, // (117, 48) + { 0, { 0, 0, 0}}, // (118, 48) + { 0, { 0, 0, 0}}, // (119, 48) + { 0, { 0, 0, 0}}, // (120, 48) + { 0, { 0, 0, 0}}, // (121, 48) + { 0, { 0, 0, 0}}, // (122, 48) + { 0, { 0, 0, 0}}, // (123, 48) + { 0, { 0, 0, 0}}, // (124, 48) + { 0, { 0, 0, 0}}, // (125, 48) + { 0, { 0, 0, 0}}, // (126, 48) + { 0, { 0, 0, 0}}, // (127, 48) + { 0, { 0, 0, 0}}, // (128, 48) + { 0, { 0, 0, 0}}, // (129, 48) + { 0, { 0, 0, 0}}, // (130, 48) + { 0, { 0, 0, 0}}, // (131, 48) + { 0, { 0, 0, 0}}, // (132, 48) + { 0, { 0, 0, 0}}, // (133, 48) + { 0, { 0, 0, 0}}, // (134, 48) + { 0, { 0, 0, 0}}, // (135, 48) + { 0, { 0, 0, 0}}, // (136, 48) + { 0, { 0, 0, 0}}, // (137, 48) + { 0, { 0, 0, 0}}, // (138, 48) + { 0, { 0, 0, 0}}, // (139, 48) + { 0, { 0, 0, 0}}, // (140, 48) + { 0, { 0, 0, 0}}, // (141, 48) + { 0, { 0, 0, 0}}, // (142, 48) + { 0, { 0, 0, 0}}, // (143, 48) + { 0, { 0, 0, 0}}, // (144, 48) + { 0, { 0, 0, 0}}, // (145, 48) + { 0, { 0, 0, 0}}, // (146, 48) + { 0, { 0, 0, 0}}, // (147, 48) + { 0, { 0, 0, 0}}, // (148, 48) + { 0, { 0, 0, 0}}, // (149, 48) + { 0, { 0, 0, 0}}, // (150, 48) + { 0, { 0, 0, 0}}, // (151, 48) + { 0, { 0, 0, 0}}, // (152, 48) + { 0, { 0, 0, 0}}, // (153, 48) + { 0, { 0, 0, 0}}, // (154, 48) + { 0, { 0, 0, 0}}, // (155, 48) + { 0, { 0, 0, 0}}, // (156, 48) + { 0, { 0, 0, 0}}, // (157, 48) + { 0, { 0, 0, 0}}, // (158, 48) + { 0, { 0, 0, 0}}, // (159, 48) + { 0, { 0, 0, 0}}, // (160, 48) + { 0, { 0, 0, 0}}, // (161, 48) + { 0, { 0, 0, 0}}, // (162, 48) + { 0, { 0, 0, 0}}, // (163, 48) + { 0, { 0, 0, 0}}, // (164, 48) + { 0, { 0, 0, 0}}, // (165, 48) + { 0, { 0, 0, 0}}, // (166, 48) + { 51, { 0, 0, 0}}, // (167, 48) + {128, { 0, 0, 0}}, // (168, 48) + {128, { 0, 0, 0}}, // (169, 48) + {128, { 0, 0, 0}}, // (170, 48) + {128, { 0, 0, 0}}, // (171, 48) + {128, { 0, 0, 0}}, // (172, 48) + {128, { 0, 0, 0}}, // (173, 48) + {128, { 0, 0, 0}}, // (174, 48) + {128, { 0, 0, 0}}, // (175, 48) + {128, { 0, 0, 0}}, // (176, 48) + {128, { 0, 0, 0}}, // (177, 48) + {128, { 0, 0, 0}}, // (178, 48) + {128, { 0, 0, 0}}, // (179, 48) + {128, { 0, 0, 0}}, // ( 0, 49) + {128, { 0, 0, 0}}, // ( 1, 49) + {128, { 0, 0, 0}}, // ( 2, 49) + {128, { 0, 0, 0}}, // ( 3, 49) + {128, { 0, 0, 0}}, // ( 4, 49) + {128, { 0, 0, 0}}, // ( 5, 49) + {128, { 0, 0, 0}}, // ( 6, 49) + {128, { 0, 0, 0}}, // ( 7, 49) + {128, { 0, 0, 0}}, // ( 8, 49) + {128, { 0, 0, 0}}, // ( 9, 49) + {128, { 0, 0, 0}}, // ( 10, 49) + {111, { 0, 0, 0}}, // ( 11, 49) + { 2, { 0, 0, 0}}, // ( 12, 49) + { 0, { 0, 0, 0}}, // ( 13, 49) + { 0, { 0, 0, 0}}, // ( 14, 49) + { 0, { 0, 0, 0}}, // ( 15, 49) + { 0, { 0, 0, 0}}, // ( 16, 49) + { 0, { 0, 0, 0}}, // ( 17, 49) + { 0, { 0, 0, 0}}, // ( 18, 49) + { 0, { 0, 0, 0}}, // ( 19, 49) + { 0, { 0, 0, 0}}, // ( 20, 49) + { 0, { 0, 0, 0}}, // ( 21, 49) + { 0, { 0, 0, 0}}, // ( 22, 49) + { 0, { 0, 0, 0}}, // ( 23, 49) + { 0, { 0, 0, 0}}, // ( 24, 49) + { 0, { 0, 0, 0}}, // ( 25, 49) + { 0, { 0, 0, 0}}, // ( 26, 49) + { 0, { 0, 0, 0}}, // ( 27, 49) + { 0, { 0, 0, 0}}, // ( 28, 49) + { 0, { 0, 0, 0}}, // ( 29, 49) + { 0, { 0, 0, 0}}, // ( 30, 49) + { 0, { 0, 0, 0}}, // ( 31, 49) + { 0, { 0, 0, 0}}, // ( 32, 49) + { 0, { 0, 0, 0}}, // ( 33, 49) + { 0, { 0, 0, 0}}, // ( 34, 49) + { 0, { 0, 0, 0}}, // ( 35, 49) + { 0, { 0, 0, 0}}, // ( 36, 49) + { 0, { 0, 0, 0}}, // ( 37, 49) + { 0, { 0, 0, 0}}, // ( 38, 49) + { 0, { 0, 0, 0}}, // ( 39, 49) + { 0, { 0, 0, 0}}, // ( 40, 49) + { 0, { 0, 0, 0}}, // ( 41, 49) + { 0, { 0, 0, 0}}, // ( 42, 49) + { 0, { 0, 0, 0}}, // ( 43, 49) + { 0, { 0, 0, 0}}, // ( 44, 49) + { 0, { 0, 0, 0}}, // ( 45, 49) + { 0, { 0, 0, 0}}, // ( 46, 49) + { 0, { 0, 0, 0}}, // ( 47, 49) + { 0, { 0, 0, 0}}, // ( 48, 49) + { 0, { 0, 0, 0}}, // ( 49, 49) + { 0, { 0, 0, 0}}, // ( 50, 49) + { 0, { 0, 0, 0}}, // ( 51, 49) + { 0, { 0, 0, 0}}, // ( 52, 49) + { 0, { 0, 0, 0}}, // ( 53, 49) + { 0, { 0, 0, 0}}, // ( 54, 49) + { 0, { 0, 0, 0}}, // ( 55, 49) + { 0, { 0, 0, 0}}, // ( 56, 49) + { 0, { 0, 0, 0}}, // ( 57, 49) + { 0, { 0, 0, 0}}, // ( 58, 49) + { 0, { 0, 0, 0}}, // ( 59, 49) + { 0, { 0, 0, 0}}, // ( 60, 49) + { 0, { 0, 0, 0}}, // ( 61, 49) + { 0, { 0, 0, 0}}, // ( 62, 49) + { 0, { 0, 0, 0}}, // ( 63, 49) + { 0, { 0, 0, 0}}, // ( 64, 49) + { 0, { 0, 0, 0}}, // ( 65, 49) + { 0, { 0, 0, 0}}, // ( 66, 49) + { 0, { 0, 0, 0}}, // ( 67, 49) + { 0, { 0, 0, 0}}, // ( 68, 49) + { 0, { 0, 0, 0}}, // ( 69, 49) + { 0, { 0, 0, 0}}, // ( 70, 49) + { 0, { 0, 0, 0}}, // ( 71, 49) + { 0, { 0, 0, 0}}, // ( 72, 49) + { 0, { 0, 0, 0}}, // ( 73, 49) + { 0, { 0, 0, 0}}, // ( 74, 49) + { 0, { 0, 0, 0}}, // ( 75, 49) + { 0, { 0, 0, 0}}, // ( 76, 49) + { 0, { 0, 0, 0}}, // ( 77, 49) + { 0, { 0, 0, 0}}, // ( 78, 49) + { 0, { 0, 0, 0}}, // ( 79, 49) + { 0, { 0, 0, 0}}, // ( 80, 49) + { 0, { 0, 0, 0}}, // ( 81, 49) + { 0, { 0, 0, 0}}, // ( 82, 49) + { 0, { 0, 0, 0}}, // ( 83, 49) + { 0, { 0, 0, 0}}, // ( 84, 49) + { 0, { 0, 0, 0}}, // ( 85, 49) + { 0, { 0, 0, 0}}, // ( 86, 49) + { 0, { 0, 0, 0}}, // ( 87, 49) + { 0, { 0, 0, 0}}, // ( 88, 49) + { 0, { 0, 0, 0}}, // ( 89, 49) + { 0, { 0, 0, 0}}, // ( 90, 49) + { 0, { 0, 0, 0}}, // ( 91, 49) + { 0, { 0, 0, 0}}, // ( 92, 49) + { 0, { 0, 0, 0}}, // ( 93, 49) + { 0, { 0, 0, 0}}, // ( 94, 49) + { 0, { 0, 0, 0}}, // ( 95, 49) + { 0, { 0, 0, 0}}, // ( 96, 49) + { 0, { 0, 0, 0}}, // ( 97, 49) + { 0, { 0, 0, 0}}, // ( 98, 49) + { 0, { 0, 0, 0}}, // ( 99, 49) + { 0, { 0, 0, 0}}, // (100, 49) + { 0, { 0, 0, 0}}, // (101, 49) + { 0, { 0, 0, 0}}, // (102, 49) + { 0, { 0, 0, 0}}, // (103, 49) + { 0, { 0, 0, 0}}, // (104, 49) + { 0, { 0, 0, 0}}, // (105, 49) + { 0, { 0, 0, 0}}, // (106, 49) + { 0, { 0, 0, 0}}, // (107, 49) + { 0, { 0, 0, 0}}, // (108, 49) + { 0, { 0, 0, 0}}, // (109, 49) + { 0, { 0, 0, 0}}, // (110, 49) + { 0, { 0, 0, 0}}, // (111, 49) + { 0, { 0, 0, 0}}, // (112, 49) + { 0, { 0, 0, 0}}, // (113, 49) + { 0, { 0, 0, 0}}, // (114, 49) + { 0, { 0, 0, 0}}, // (115, 49) + { 0, { 0, 0, 0}}, // (116, 49) + { 0, { 0, 0, 0}}, // (117, 49) + { 0, { 0, 0, 0}}, // (118, 49) + { 0, { 0, 0, 0}}, // (119, 49) + { 0, { 0, 0, 0}}, // (120, 49) + { 0, { 0, 0, 0}}, // (121, 49) + { 0, { 0, 0, 0}}, // (122, 49) + { 0, { 0, 0, 0}}, // (123, 49) + { 0, { 0, 0, 0}}, // (124, 49) + { 0, { 0, 0, 0}}, // (125, 49) + { 0, { 0, 0, 0}}, // (126, 49) + { 0, { 0, 0, 0}}, // (127, 49) + { 0, { 0, 0, 0}}, // (128, 49) + { 0, { 0, 0, 0}}, // (129, 49) + { 0, { 0, 0, 0}}, // (130, 49) + { 0, { 0, 0, 0}}, // (131, 49) + { 0, { 0, 0, 0}}, // (132, 49) + { 0, { 0, 0, 0}}, // (133, 49) + { 0, { 0, 0, 0}}, // (134, 49) + { 0, { 0, 0, 0}}, // (135, 49) + { 0, { 0, 0, 0}}, // (136, 49) + { 0, { 0, 0, 0}}, // (137, 49) + { 0, { 0, 0, 0}}, // (138, 49) + { 0, { 0, 0, 0}}, // (139, 49) + { 0, { 0, 0, 0}}, // (140, 49) + { 0, { 0, 0, 0}}, // (141, 49) + { 0, { 0, 0, 0}}, // (142, 49) + { 0, { 0, 0, 0}}, // (143, 49) + { 0, { 0, 0, 0}}, // (144, 49) + { 0, { 0, 0, 0}}, // (145, 49) + { 0, { 0, 0, 0}}, // (146, 49) + { 0, { 0, 0, 0}}, // (147, 49) + { 0, { 0, 0, 0}}, // (148, 49) + { 0, { 0, 0, 0}}, // (149, 49) + { 0, { 0, 0, 0}}, // (150, 49) + { 0, { 0, 0, 0}}, // (151, 49) + { 0, { 0, 0, 0}}, // (152, 49) + { 0, { 0, 0, 0}}, // (153, 49) + { 0, { 0, 0, 0}}, // (154, 49) + { 0, { 0, 0, 0}}, // (155, 49) + { 0, { 0, 0, 0}}, // (156, 49) + { 0, { 0, 0, 0}}, // (157, 49) + { 0, { 0, 0, 0}}, // (158, 49) + { 0, { 0, 0, 0}}, // (159, 49) + { 0, { 0, 0, 0}}, // (160, 49) + { 0, { 0, 0, 0}}, // (161, 49) + { 0, { 0, 0, 0}}, // (162, 49) + { 0, { 0, 0, 0}}, // (163, 49) + { 0, { 0, 0, 0}}, // (164, 49) + { 0, { 0, 0, 0}}, // (165, 49) + { 0, { 0, 0, 0}}, // (166, 49) + { 2, { 0, 0, 0}}, // (167, 49) + {110, { 0, 0, 0}}, // (168, 49) + {128, { 0, 0, 0}}, // (169, 49) + {128, { 0, 0, 0}}, // (170, 49) + {128, { 0, 0, 0}}, // (171, 49) + {128, { 0, 0, 0}}, // (172, 49) + {128, { 0, 0, 0}}, // (173, 49) + {128, { 0, 0, 0}}, // (174, 49) + {128, { 0, 0, 0}}, // (175, 49) + {128, { 0, 0, 0}}, // (176, 49) + {128, { 0, 0, 0}}, // (177, 49) + {128, { 0, 0, 0}}, // (178, 49) + {128, { 0, 0, 0}}, // (179, 49) + {128, { 0, 0, 0}}, // ( 0, 50) + {128, { 0, 0, 0}}, // ( 1, 50) + {128, { 0, 0, 0}}, // ( 2, 50) + {128, { 0, 0, 0}}, // ( 3, 50) + {128, { 0, 0, 0}}, // ( 4, 50) + {128, { 0, 0, 0}}, // ( 5, 50) + {128, { 0, 0, 0}}, // ( 6, 50) + {128, { 0, 0, 0}}, // ( 7, 50) + {128, { 0, 0, 0}}, // ( 8, 50) + {128, { 0, 0, 0}}, // ( 9, 50) + {128, { 0, 0, 0}}, // ( 10, 50) + { 47, { 0, 0, 0}}, // ( 11, 50) + { 0, { 0, 0, 0}}, // ( 12, 50) + { 0, { 0, 0, 0}}, // ( 13, 50) + { 0, { 0, 0, 0}}, // ( 14, 50) + { 0, { 0, 0, 0}}, // ( 15, 50) + { 0, { 0, 0, 0}}, // ( 16, 50) + { 0, { 0, 0, 0}}, // ( 17, 50) + { 0, { 0, 0, 0}}, // ( 18, 50) + { 0, { 0, 0, 0}}, // ( 19, 50) + { 0, { 0, 0, 0}}, // ( 20, 50) + { 0, { 0, 0, 0}}, // ( 21, 50) + { 0, { 0, 0, 0}}, // ( 22, 50) + { 0, { 0, 0, 0}}, // ( 23, 50) + { 0, { 0, 0, 0}}, // ( 24, 50) + { 0, { 0, 0, 0}}, // ( 25, 50) + { 0, { 0, 0, 0}}, // ( 26, 50) + { 0, { 0, 0, 0}}, // ( 27, 50) + { 0, { 0, 0, 0}}, // ( 28, 50) + { 0, { 0, 0, 0}}, // ( 29, 50) + { 0, { 0, 0, 0}}, // ( 30, 50) + { 0, { 0, 0, 0}}, // ( 31, 50) + { 0, { 0, 0, 0}}, // ( 32, 50) + { 0, { 0, 0, 0}}, // ( 33, 50) + { 0, { 0, 0, 0}}, // ( 34, 50) + { 0, { 0, 0, 0}}, // ( 35, 50) + { 0, { 0, 0, 0}}, // ( 36, 50) + { 0, { 0, 0, 0}}, // ( 37, 50) + { 0, { 0, 0, 0}}, // ( 38, 50) + { 0, { 0, 0, 0}}, // ( 39, 50) + { 0, { 0, 0, 0}}, // ( 40, 50) + { 0, { 0, 0, 0}}, // ( 41, 50) + { 0, { 0, 0, 0}}, // ( 42, 50) + { 0, { 0, 0, 0}}, // ( 43, 50) + { 0, { 0, 0, 0}}, // ( 44, 50) + { 0, { 0, 0, 0}}, // ( 45, 50) + { 0, { 0, 0, 0}}, // ( 46, 50) + { 0, { 0, 0, 0}}, // ( 47, 50) + { 0, { 0, 0, 0}}, // ( 48, 50) + { 0, { 0, 0, 0}}, // ( 49, 50) + { 0, { 0, 0, 0}}, // ( 50, 50) + { 0, { 0, 0, 0}}, // ( 51, 50) + { 0, { 0, 0, 0}}, // ( 52, 50) + { 0, { 0, 0, 0}}, // ( 53, 50) + { 0, { 0, 0, 0}}, // ( 54, 50) + { 0, { 0, 0, 0}}, // ( 55, 50) + { 0, { 0, 0, 0}}, // ( 56, 50) + { 0, { 0, 0, 0}}, // ( 57, 50) + { 0, { 0, 0, 0}}, // ( 58, 50) + { 0, { 0, 0, 0}}, // ( 59, 50) + { 0, { 0, 0, 0}}, // ( 60, 50) + { 0, { 0, 0, 0}}, // ( 61, 50) + { 0, { 0, 0, 0}}, // ( 62, 50) + { 0, { 0, 0, 0}}, // ( 63, 50) + { 0, { 0, 0, 0}}, // ( 64, 50) + { 0, { 0, 0, 0}}, // ( 65, 50) + { 0, { 0, 0, 0}}, // ( 66, 50) + { 0, { 0, 0, 0}}, // ( 67, 50) + { 0, { 0, 0, 0}}, // ( 68, 50) + { 0, { 0, 0, 0}}, // ( 69, 50) + { 0, { 0, 0, 0}}, // ( 70, 50) + { 0, { 0, 0, 0}}, // ( 71, 50) + { 0, { 0, 0, 0}}, // ( 72, 50) + { 0, { 0, 0, 0}}, // ( 73, 50) + { 0, { 0, 0, 0}}, // ( 74, 50) + { 0, { 0, 0, 0}}, // ( 75, 50) + { 0, { 0, 0, 0}}, // ( 76, 50) + { 0, { 0, 0, 0}}, // ( 77, 50) + { 0, { 0, 0, 0}}, // ( 78, 50) + { 0, { 0, 0, 0}}, // ( 79, 50) + { 0, { 0, 0, 0}}, // ( 80, 50) + { 0, { 0, 0, 0}}, // ( 81, 50) + { 0, { 0, 0, 0}}, // ( 82, 50) + { 0, { 0, 0, 0}}, // ( 83, 50) + { 0, { 0, 0, 0}}, // ( 84, 50) + { 0, { 0, 0, 0}}, // ( 85, 50) + { 0, { 0, 0, 0}}, // ( 86, 50) + { 0, { 0, 0, 0}}, // ( 87, 50) + { 0, { 0, 0, 0}}, // ( 88, 50) + { 0, { 0, 0, 0}}, // ( 89, 50) + { 0, { 0, 0, 0}}, // ( 90, 50) + { 0, { 0, 0, 0}}, // ( 91, 50) + { 0, { 0, 0, 0}}, // ( 92, 50) + { 0, { 0, 0, 0}}, // ( 93, 50) + { 0, { 0, 0, 0}}, // ( 94, 50) + { 0, { 0, 0, 0}}, // ( 95, 50) + { 0, { 0, 0, 0}}, // ( 96, 50) + { 0, { 0, 0, 0}}, // ( 97, 50) + { 0, { 0, 0, 0}}, // ( 98, 50) + { 0, { 0, 0, 0}}, // ( 99, 50) + { 0, { 0, 0, 0}}, // (100, 50) + { 0, { 0, 0, 0}}, // (101, 50) + { 0, { 0, 0, 0}}, // (102, 50) + { 0, { 0, 0, 0}}, // (103, 50) + { 0, { 0, 0, 0}}, // (104, 50) + { 0, { 0, 0, 0}}, // (105, 50) + { 0, { 0, 0, 0}}, // (106, 50) + { 0, { 0, 0, 0}}, // (107, 50) + { 0, { 0, 0, 0}}, // (108, 50) + { 0, { 0, 0, 0}}, // (109, 50) + { 0, { 0, 0, 0}}, // (110, 50) + { 0, { 0, 0, 0}}, // (111, 50) + { 0, { 0, 0, 0}}, // (112, 50) + { 0, { 0, 0, 0}}, // (113, 50) + { 0, { 0, 0, 0}}, // (114, 50) + { 0, { 0, 0, 0}}, // (115, 50) + { 0, { 0, 0, 0}}, // (116, 50) + { 0, { 0, 0, 0}}, // (117, 50) + { 0, { 0, 0, 0}}, // (118, 50) + { 0, { 0, 0, 0}}, // (119, 50) + { 0, { 0, 0, 0}}, // (120, 50) + { 0, { 0, 0, 0}}, // (121, 50) + { 0, { 0, 0, 0}}, // (122, 50) + { 0, { 0, 0, 0}}, // (123, 50) + { 0, { 0, 0, 0}}, // (124, 50) + { 0, { 0, 0, 0}}, // (125, 50) + { 0, { 0, 0, 0}}, // (126, 50) + { 0, { 0, 0, 0}}, // (127, 50) + { 0, { 0, 0, 0}}, // (128, 50) + { 0, { 0, 0, 0}}, // (129, 50) + { 0, { 0, 0, 0}}, // (130, 50) + { 0, { 0, 0, 0}}, // (131, 50) + { 0, { 0, 0, 0}}, // (132, 50) + { 0, { 0, 0, 0}}, // (133, 50) + { 0, { 0, 0, 0}}, // (134, 50) + { 0, { 0, 0, 0}}, // (135, 50) + { 0, { 0, 0, 0}}, // (136, 50) + { 0, { 0, 0, 0}}, // (137, 50) + { 0, { 0, 0, 0}}, // (138, 50) + { 0, { 0, 0, 0}}, // (139, 50) + { 0, { 0, 0, 0}}, // (140, 50) + { 0, { 0, 0, 0}}, // (141, 50) + { 0, { 0, 0, 0}}, // (142, 50) + { 0, { 0, 0, 0}}, // (143, 50) + { 0, { 0, 0, 0}}, // (144, 50) + { 0, { 0, 0, 0}}, // (145, 50) + { 0, { 0, 0, 0}}, // (146, 50) + { 0, { 0, 0, 0}}, // (147, 50) + { 0, { 0, 0, 0}}, // (148, 50) + { 0, { 0, 0, 0}}, // (149, 50) + { 0, { 0, 0, 0}}, // (150, 50) + { 0, { 0, 0, 0}}, // (151, 50) + { 0, { 0, 0, 0}}, // (152, 50) + { 0, { 0, 0, 0}}, // (153, 50) + { 0, { 0, 0, 0}}, // (154, 50) + { 0, { 0, 0, 0}}, // (155, 50) + { 0, { 0, 0, 0}}, // (156, 50) + { 0, { 0, 0, 0}}, // (157, 50) + { 0, { 0, 0, 0}}, // (158, 50) + { 0, { 0, 0, 0}}, // (159, 50) + { 0, { 0, 0, 0}}, // (160, 50) + { 0, { 0, 0, 0}}, // (161, 50) + { 0, { 0, 0, 0}}, // (162, 50) + { 0, { 0, 0, 0}}, // (163, 50) + { 0, { 0, 0, 0}}, // (164, 50) + { 0, { 0, 0, 0}}, // (165, 50) + { 0, { 0, 0, 0}}, // (166, 50) + { 0, { 0, 0, 0}}, // (167, 50) + { 47, { 0, 0, 0}}, // (168, 50) + {128, { 0, 0, 0}}, // (169, 50) + {128, { 0, 0, 0}}, // (170, 50) + {128, { 0, 0, 0}}, // (171, 50) + {128, { 0, 0, 0}}, // (172, 50) + {128, { 0, 0, 0}}, // (173, 50) + {128, { 0, 0, 0}}, // (174, 50) + {128, { 0, 0, 0}}, // (175, 50) + {128, { 0, 0, 0}}, // (176, 50) + {128, { 0, 0, 0}}, // (177, 50) + {128, { 0, 0, 0}}, // (178, 50) + {128, { 0, 0, 0}}, // (179, 50) + {128, { 0, 0, 0}}, // ( 0, 51) + {128, { 0, 0, 0}}, // ( 1, 51) + {128, { 0, 0, 0}}, // ( 2, 51) + {128, { 0, 0, 0}}, // ( 3, 51) + {128, { 0, 0, 0}}, // ( 4, 51) + {128, { 0, 0, 0}}, // ( 5, 51) + {128, { 0, 0, 0}}, // ( 6, 51) + {128, { 0, 0, 0}}, // ( 7, 51) + {128, { 0, 0, 0}}, // ( 8, 51) + {128, { 0, 0, 0}}, // ( 9, 51) + {108, { 0, 0, 0}}, // ( 10, 51) + { 2, { 0, 0, 0}}, // ( 11, 51) + { 0, { 0, 0, 0}}, // ( 12, 51) + { 0, { 0, 0, 0}}, // ( 13, 51) + { 0, { 0, 0, 0}}, // ( 14, 51) + { 0, { 0, 0, 0}}, // ( 15, 51) + { 0, { 0, 0, 0}}, // ( 16, 51) + { 0, { 0, 0, 0}}, // ( 17, 51) + { 0, { 0, 0, 0}}, // ( 18, 51) + { 0, { 0, 0, 0}}, // ( 19, 51) + { 0, { 0, 0, 0}}, // ( 20, 51) + { 0, { 0, 0, 0}}, // ( 21, 51) + { 0, { 0, 0, 0}}, // ( 22, 51) + { 0, { 0, 0, 0}}, // ( 23, 51) + { 0, { 0, 0, 0}}, // ( 24, 51) + { 0, { 0, 0, 0}}, // ( 25, 51) + { 0, { 0, 0, 0}}, // ( 26, 51) + { 0, { 0, 0, 0}}, // ( 27, 51) + { 0, { 0, 0, 0}}, // ( 28, 51) + { 0, { 0, 0, 0}}, // ( 29, 51) + { 0, { 0, 0, 0}}, // ( 30, 51) + { 0, { 0, 0, 0}}, // ( 31, 51) + { 0, { 0, 0, 0}}, // ( 32, 51) + { 0, { 0, 0, 0}}, // ( 33, 51) + { 0, { 0, 0, 0}}, // ( 34, 51) + { 0, { 0, 0, 0}}, // ( 35, 51) + { 0, { 0, 0, 0}}, // ( 36, 51) + { 0, { 0, 0, 0}}, // ( 37, 51) + { 0, { 0, 0, 0}}, // ( 38, 51) + { 0, { 0, 0, 0}}, // ( 39, 51) + { 0, { 0, 0, 0}}, // ( 40, 51) + { 0, { 0, 0, 0}}, // ( 41, 51) + { 0, { 0, 0, 0}}, // ( 42, 51) + { 0, { 0, 0, 0}}, // ( 43, 51) + { 0, { 0, 0, 0}}, // ( 44, 51) + { 0, { 0, 0, 0}}, // ( 45, 51) + { 0, { 0, 0, 0}}, // ( 46, 51) + { 0, { 0, 0, 0}}, // ( 47, 51) + { 0, { 0, 0, 0}}, // ( 48, 51) + { 0, { 0, 0, 0}}, // ( 49, 51) + { 0, { 0, 0, 0}}, // ( 50, 51) + { 0, { 0, 0, 0}}, // ( 51, 51) + { 0, { 0, 0, 0}}, // ( 52, 51) + { 0, { 0, 0, 0}}, // ( 53, 51) + { 0, { 0, 0, 0}}, // ( 54, 51) + { 0, { 0, 0, 0}}, // ( 55, 51) + { 0, { 0, 0, 0}}, // ( 56, 51) + { 0, { 0, 0, 0}}, // ( 57, 51) + { 0, { 0, 0, 0}}, // ( 58, 51) + { 0, { 0, 0, 0}}, // ( 59, 51) + { 0, { 0, 0, 0}}, // ( 60, 51) + { 0, { 0, 0, 0}}, // ( 61, 51) + { 0, { 0, 0, 0}}, // ( 62, 51) + { 0, { 0, 0, 0}}, // ( 63, 51) + { 0, { 0, 0, 0}}, // ( 64, 51) + { 0, { 0, 0, 0}}, // ( 65, 51) + { 0, { 0, 0, 0}}, // ( 66, 51) + { 0, { 0, 0, 0}}, // ( 67, 51) + { 0, { 0, 0, 0}}, // ( 68, 51) + { 0, { 0, 0, 0}}, // ( 69, 51) + { 0, { 0, 0, 0}}, // ( 70, 51) + { 0, { 0, 0, 0}}, // ( 71, 51) + { 0, { 0, 0, 0}}, // ( 72, 51) + { 0, { 0, 0, 0}}, // ( 73, 51) + { 0, { 0, 0, 0}}, // ( 74, 51) + { 0, { 0, 0, 0}}, // ( 75, 51) + { 0, { 0, 0, 0}}, // ( 76, 51) + { 0, { 0, 0, 0}}, // ( 77, 51) + { 0, { 0, 0, 0}}, // ( 78, 51) + { 0, { 0, 0, 0}}, // ( 79, 51) + { 0, { 0, 0, 0}}, // ( 80, 51) + { 0, { 0, 0, 0}}, // ( 81, 51) + { 0, { 0, 0, 0}}, // ( 82, 51) + { 0, { 0, 0, 0}}, // ( 83, 51) + { 0, { 0, 0, 0}}, // ( 84, 51) + { 0, { 0, 0, 0}}, // ( 85, 51) + { 0, { 0, 0, 0}}, // ( 86, 51) + { 0, { 0, 0, 0}}, // ( 87, 51) + { 0, { 0, 0, 0}}, // ( 88, 51) + { 0, { 0, 0, 0}}, // ( 89, 51) + { 0, { 0, 0, 0}}, // ( 90, 51) + { 0, { 0, 0, 0}}, // ( 91, 51) + { 0, { 0, 0, 0}}, // ( 92, 51) + { 0, { 0, 0, 0}}, // ( 93, 51) + { 0, { 0, 0, 0}}, // ( 94, 51) + { 0, { 0, 0, 0}}, // ( 95, 51) + { 0, { 0, 0, 0}}, // ( 96, 51) + { 0, { 0, 0, 0}}, // ( 97, 51) + { 0, { 0, 0, 0}}, // ( 98, 51) + { 0, { 0, 0, 0}}, // ( 99, 51) + { 0, { 0, 0, 0}}, // (100, 51) + { 0, { 0, 0, 0}}, // (101, 51) + { 0, { 0, 0, 0}}, // (102, 51) + { 0, { 0, 0, 0}}, // (103, 51) + { 0, { 0, 0, 0}}, // (104, 51) + { 0, { 0, 0, 0}}, // (105, 51) + { 0, { 0, 0, 0}}, // (106, 51) + { 0, { 0, 0, 0}}, // (107, 51) + { 0, { 0, 0, 0}}, // (108, 51) + { 0, { 0, 0, 0}}, // (109, 51) + { 0, { 0, 0, 0}}, // (110, 51) + { 0, { 0, 0, 0}}, // (111, 51) + { 0, { 0, 0, 0}}, // (112, 51) + { 0, { 0, 0, 0}}, // (113, 51) + { 0, { 0, 0, 0}}, // (114, 51) + { 0, { 0, 0, 0}}, // (115, 51) + { 0, { 0, 0, 0}}, // (116, 51) + { 0, { 0, 0, 0}}, // (117, 51) + { 0, { 0, 0, 0}}, // (118, 51) + { 0, { 0, 0, 0}}, // (119, 51) + { 0, { 0, 0, 0}}, // (120, 51) + { 0, { 0, 0, 0}}, // (121, 51) + { 0, { 0, 0, 0}}, // (122, 51) + { 0, { 0, 0, 0}}, // (123, 51) + { 0, { 0, 0, 0}}, // (124, 51) + { 0, { 0, 0, 0}}, // (125, 51) + { 0, { 0, 0, 0}}, // (126, 51) + { 0, { 0, 0, 0}}, // (127, 51) + { 0, { 0, 0, 0}}, // (128, 51) + { 0, { 0, 0, 0}}, // (129, 51) + { 0, { 0, 0, 0}}, // (130, 51) + { 0, { 0, 0, 0}}, // (131, 51) + { 0, { 0, 0, 0}}, // (132, 51) + { 0, { 0, 0, 0}}, // (133, 51) + { 0, { 0, 0, 0}}, // (134, 51) + { 0, { 0, 0, 0}}, // (135, 51) + { 0, { 0, 0, 0}}, // (136, 51) + { 0, { 0, 0, 0}}, // (137, 51) + { 0, { 0, 0, 0}}, // (138, 51) + { 0, { 0, 0, 0}}, // (139, 51) + { 0, { 0, 0, 0}}, // (140, 51) + { 0, { 0, 0, 0}}, // (141, 51) + { 0, { 0, 0, 0}}, // (142, 51) + { 0, { 0, 0, 0}}, // (143, 51) + { 0, { 0, 0, 0}}, // (144, 51) + { 0, { 0, 0, 0}}, // (145, 51) + { 0, { 0, 0, 0}}, // (146, 51) + { 0, { 0, 0, 0}}, // (147, 51) + { 0, { 0, 0, 0}}, // (148, 51) + { 0, { 0, 0, 0}}, // (149, 51) + { 0, { 0, 0, 0}}, // (150, 51) + { 0, { 0, 0, 0}}, // (151, 51) + { 0, { 0, 0, 0}}, // (152, 51) + { 0, { 0, 0, 0}}, // (153, 51) + { 0, { 0, 0, 0}}, // (154, 51) + { 0, { 0, 0, 0}}, // (155, 51) + { 0, { 0, 0, 0}}, // (156, 51) + { 0, { 0, 0, 0}}, // (157, 51) + { 0, { 0, 0, 0}}, // (158, 51) + { 0, { 0, 0, 0}}, // (159, 51) + { 0, { 0, 0, 0}}, // (160, 51) + { 0, { 0, 0, 0}}, // (161, 51) + { 0, { 0, 0, 0}}, // (162, 51) + { 0, { 0, 0, 0}}, // (163, 51) + { 0, { 0, 0, 0}}, // (164, 51) + { 0, { 0, 0, 0}}, // (165, 51) + { 0, { 0, 0, 0}}, // (166, 51) + { 0, { 0, 0, 0}}, // (167, 51) + { 2, { 0, 0, 0}}, // (168, 51) + {108, { 0, 0, 0}}, // (169, 51) + {128, { 0, 0, 0}}, // (170, 51) + {128, { 0, 0, 0}}, // (171, 51) + {128, { 0, 0, 0}}, // (172, 51) + {128, { 0, 0, 0}}, // (173, 51) + {128, { 0, 0, 0}}, // (174, 51) + {128, { 0, 0, 0}}, // (175, 51) + {128, { 0, 0, 0}}, // (176, 51) + {128, { 0, 0, 0}}, // (177, 51) + {128, { 0, 0, 0}}, // (178, 51) + {128, { 0, 0, 0}}, // (179, 51) + {128, { 0, 0, 0}}, // ( 0, 52) + {128, { 0, 0, 0}}, // ( 1, 52) + {128, { 0, 0, 0}}, // ( 2, 52) + {128, { 0, 0, 0}}, // ( 3, 52) + {128, { 0, 0, 0}}, // ( 4, 52) + {128, { 0, 0, 0}}, // ( 5, 52) + {128, { 0, 0, 0}}, // ( 6, 52) + {128, { 0, 0, 0}}, // ( 7, 52) + {128, { 0, 0, 0}}, // ( 8, 52) + {128, { 0, 0, 0}}, // ( 9, 52) + { 50, { 0, 0, 0}}, // ( 10, 52) + { 0, { 0, 0, 0}}, // ( 11, 52) + { 0, { 0, 0, 0}}, // ( 12, 52) + { 0, { 0, 0, 0}}, // ( 13, 52) + { 0, { 0, 0, 0}}, // ( 14, 52) + { 0, { 0, 0, 0}}, // ( 15, 52) + { 0, { 0, 0, 0}}, // ( 16, 52) + { 0, { 0, 0, 0}}, // ( 17, 52) + { 0, { 0, 0, 0}}, // ( 18, 52) + { 0, { 0, 0, 0}}, // ( 19, 52) + { 0, { 0, 0, 0}}, // ( 20, 52) + { 0, { 0, 0, 0}}, // ( 21, 52) + { 0, { 0, 0, 0}}, // ( 22, 52) + { 0, { 0, 0, 0}}, // ( 23, 52) + { 0, { 0, 0, 0}}, // ( 24, 52) + { 0, { 0, 0, 0}}, // ( 25, 52) + { 0, { 0, 0, 0}}, // ( 26, 52) + { 0, { 0, 0, 0}}, // ( 27, 52) + { 0, { 0, 0, 0}}, // ( 28, 52) + { 0, { 0, 0, 0}}, // ( 29, 52) + { 0, { 0, 0, 0}}, // ( 30, 52) + { 0, { 0, 0, 0}}, // ( 31, 52) + { 0, { 0, 0, 0}}, // ( 32, 52) + { 0, { 0, 0, 0}}, // ( 33, 52) + { 0, { 0, 0, 0}}, // ( 34, 52) + { 0, { 0, 0, 0}}, // ( 35, 52) + { 0, { 0, 0, 0}}, // ( 36, 52) + { 0, { 0, 0, 0}}, // ( 37, 52) + { 0, { 0, 0, 0}}, // ( 38, 52) + { 0, { 0, 0, 0}}, // ( 39, 52) + { 0, { 0, 0, 0}}, // ( 40, 52) + { 0, { 0, 0, 0}}, // ( 41, 52) + { 0, { 0, 0, 0}}, // ( 42, 52) + { 0, { 0, 0, 0}}, // ( 43, 52) + { 0, { 0, 0, 0}}, // ( 44, 52) + { 0, { 0, 0, 0}}, // ( 45, 52) + { 0, { 0, 0, 0}}, // ( 46, 52) + { 0, { 0, 0, 0}}, // ( 47, 52) + { 0, { 0, 0, 0}}, // ( 48, 52) + { 0, { 0, 0, 0}}, // ( 49, 52) + { 0, { 0, 0, 0}}, // ( 50, 52) + { 0, { 0, 0, 0}}, // ( 51, 52) + { 0, { 0, 0, 0}}, // ( 52, 52) + { 0, { 0, 0, 0}}, // ( 53, 52) + { 0, { 0, 0, 0}}, // ( 54, 52) + { 0, { 0, 0, 0}}, // ( 55, 52) + { 0, { 0, 0, 0}}, // ( 56, 52) + { 0, { 0, 0, 0}}, // ( 57, 52) + { 0, { 0, 0, 0}}, // ( 58, 52) + { 0, { 0, 0, 0}}, // ( 59, 52) + { 0, { 0, 0, 0}}, // ( 60, 52) + { 0, { 0, 0, 0}}, // ( 61, 52) + { 0, { 0, 0, 0}}, // ( 62, 52) + { 0, { 0, 0, 0}}, // ( 63, 52) + { 0, { 0, 0, 0}}, // ( 64, 52) + { 0, { 0, 0, 0}}, // ( 65, 52) + { 0, { 0, 0, 0}}, // ( 66, 52) + { 0, { 0, 0, 0}}, // ( 67, 52) + { 0, { 0, 0, 0}}, // ( 68, 52) + { 0, { 0, 0, 0}}, // ( 69, 52) + { 0, { 0, 0, 0}}, // ( 70, 52) + { 0, { 0, 0, 0}}, // ( 71, 52) + { 0, { 0, 0, 0}}, // ( 72, 52) + { 0, { 0, 0, 0}}, // ( 73, 52) + { 0, { 0, 0, 0}}, // ( 74, 52) + { 0, { 0, 0, 0}}, // ( 75, 52) + { 0, { 0, 0, 0}}, // ( 76, 52) + { 0, { 0, 0, 0}}, // ( 77, 52) + { 0, { 0, 0, 0}}, // ( 78, 52) + { 0, { 0, 0, 0}}, // ( 79, 52) + { 0, { 0, 0, 0}}, // ( 80, 52) + { 0, { 0, 0, 0}}, // ( 81, 52) + { 0, { 0, 0, 0}}, // ( 82, 52) + { 0, { 0, 0, 0}}, // ( 83, 52) + { 0, { 0, 0, 0}}, // ( 84, 52) + { 0, { 0, 0, 0}}, // ( 85, 52) + { 0, { 0, 0, 0}}, // ( 86, 52) + { 0, { 0, 0, 0}}, // ( 87, 52) + { 0, { 0, 0, 0}}, // ( 88, 52) + { 0, { 0, 0, 0}}, // ( 89, 52) + { 0, { 0, 0, 0}}, // ( 90, 52) + { 0, { 0, 0, 0}}, // ( 91, 52) + { 0, { 0, 0, 0}}, // ( 92, 52) + { 0, { 0, 0, 0}}, // ( 93, 52) + { 0, { 0, 0, 0}}, // ( 94, 52) + { 0, { 0, 0, 0}}, // ( 95, 52) + { 0, { 0, 0, 0}}, // ( 96, 52) + { 0, { 0, 0, 0}}, // ( 97, 52) + { 0, { 0, 0, 0}}, // ( 98, 52) + { 0, { 0, 0, 0}}, // ( 99, 52) + { 0, { 0, 0, 0}}, // (100, 52) + { 0, { 0, 0, 0}}, // (101, 52) + { 0, { 0, 0, 0}}, // (102, 52) + { 0, { 0, 0, 0}}, // (103, 52) + { 0, { 0, 0, 0}}, // (104, 52) + { 0, { 0, 0, 0}}, // (105, 52) + { 0, { 0, 0, 0}}, // (106, 52) + { 0, { 0, 0, 0}}, // (107, 52) + { 0, { 0, 0, 0}}, // (108, 52) + { 0, { 0, 0, 0}}, // (109, 52) + { 0, { 0, 0, 0}}, // (110, 52) + { 0, { 0, 0, 0}}, // (111, 52) + { 0, { 0, 0, 0}}, // (112, 52) + { 0, { 0, 0, 0}}, // (113, 52) + { 0, { 0, 0, 0}}, // (114, 52) + { 0, { 0, 0, 0}}, // (115, 52) + { 0, { 0, 0, 0}}, // (116, 52) + { 0, { 0, 0, 0}}, // (117, 52) + { 0, { 0, 0, 0}}, // (118, 52) + { 0, { 0, 0, 0}}, // (119, 52) + { 0, { 0, 0, 0}}, // (120, 52) + { 0, { 0, 0, 0}}, // (121, 52) + { 0, { 0, 0, 0}}, // (122, 52) + { 0, { 0, 0, 0}}, // (123, 52) + { 0, { 0, 0, 0}}, // (124, 52) + { 0, { 0, 0, 0}}, // (125, 52) + { 0, { 0, 0, 0}}, // (126, 52) + { 0, { 0, 0, 0}}, // (127, 52) + { 0, { 0, 0, 0}}, // (128, 52) + { 0, { 0, 0, 0}}, // (129, 52) + { 0, { 0, 0, 0}}, // (130, 52) + { 0, { 0, 0, 0}}, // (131, 52) + { 0, { 0, 0, 0}}, // (132, 52) + { 0, { 0, 0, 0}}, // (133, 52) + { 0, { 0, 0, 0}}, // (134, 52) + { 0, { 0, 0, 0}}, // (135, 52) + { 0, { 0, 0, 0}}, // (136, 52) + { 0, { 0, 0, 0}}, // (137, 52) + { 0, { 0, 0, 0}}, // (138, 52) + { 0, { 0, 0, 0}}, // (139, 52) + { 0, { 0, 0, 0}}, // (140, 52) + { 0, { 0, 0, 0}}, // (141, 52) + { 0, { 0, 0, 0}}, // (142, 52) + { 0, { 0, 0, 0}}, // (143, 52) + { 0, { 0, 0, 0}}, // (144, 52) + { 0, { 0, 0, 0}}, // (145, 52) + { 0, { 0, 0, 0}}, // (146, 52) + { 0, { 0, 0, 0}}, // (147, 52) + { 0, { 0, 0, 0}}, // (148, 52) + { 0, { 0, 0, 0}}, // (149, 52) + { 0, { 0, 0, 0}}, // (150, 52) + { 0, { 0, 0, 0}}, // (151, 52) + { 0, { 0, 0, 0}}, // (152, 52) + { 0, { 0, 0, 0}}, // (153, 52) + { 0, { 0, 0, 0}}, // (154, 52) + { 0, { 0, 0, 0}}, // (155, 52) + { 0, { 0, 0, 0}}, // (156, 52) + { 0, { 0, 0, 0}}, // (157, 52) + { 0, { 0, 0, 0}}, // (158, 52) + { 0, { 0, 0, 0}}, // (159, 52) + { 0, { 0, 0, 0}}, // (160, 52) + { 0, { 0, 0, 0}}, // (161, 52) + { 0, { 0, 0, 0}}, // (162, 52) + { 0, { 0, 0, 0}}, // (163, 52) + { 0, { 0, 0, 0}}, // (164, 52) + { 0, { 0, 0, 0}}, // (165, 52) + { 0, { 0, 0, 0}}, // (166, 52) + { 0, { 0, 0, 0}}, // (167, 52) + { 0, { 0, 0, 0}}, // (168, 52) + { 49, { 0, 0, 0}}, // (169, 52) + {128, { 0, 0, 0}}, // (170, 52) + {128, { 0, 0, 0}}, // (171, 52) + {128, { 0, 0, 0}}, // (172, 52) + {128, { 0, 0, 0}}, // (173, 52) + {128, { 0, 0, 0}}, // (174, 52) + {128, { 0, 0, 0}}, // (175, 52) + {128, { 0, 0, 0}}, // (176, 52) + {128, { 0, 0, 0}}, // (177, 52) + {128, { 0, 0, 0}}, // (178, 52) + {128, { 0, 0, 0}}, // (179, 52) + {128, { 0, 0, 0}}, // ( 0, 53) + {128, { 0, 0, 0}}, // ( 1, 53) + {128, { 0, 0, 0}}, // ( 2, 53) + {128, { 0, 0, 0}}, // ( 3, 53) + {128, { 0, 0, 0}}, // ( 4, 53) + {128, { 0, 0, 0}}, // ( 5, 53) + {128, { 0, 0, 0}}, // ( 6, 53) + {128, { 0, 0, 0}}, // ( 7, 53) + {128, { 0, 0, 0}}, // ( 8, 53) + {115, { 0, 0, 0}}, // ( 9, 53) + { 3, { 0, 0, 0}}, // ( 10, 53) + { 0, { 0, 0, 0}}, // ( 11, 53) + { 0, { 0, 0, 0}}, // ( 12, 53) + { 0, { 0, 0, 0}}, // ( 13, 53) + { 0, { 0, 0, 0}}, // ( 14, 53) + { 0, { 0, 0, 0}}, // ( 15, 53) + { 0, { 0, 0, 0}}, // ( 16, 53) + { 0, { 0, 0, 0}}, // ( 17, 53) + { 0, { 0, 0, 0}}, // ( 18, 53) + { 0, { 0, 0, 0}}, // ( 19, 53) + { 0, { 0, 0, 0}}, // ( 20, 53) + { 0, { 0, 0, 0}}, // ( 21, 53) + { 0, { 0, 0, 0}}, // ( 22, 53) + { 0, { 0, 0, 0}}, // ( 23, 53) + { 0, { 0, 0, 0}}, // ( 24, 53) + { 0, { 0, 0, 0}}, // ( 25, 53) + { 0, { 0, 0, 0}}, // ( 26, 53) + { 0, { 0, 0, 0}}, // ( 27, 53) + { 0, { 0, 0, 0}}, // ( 28, 53) + { 0, { 0, 0, 0}}, // ( 29, 53) + { 0, { 0, 0, 0}}, // ( 30, 53) + { 0, { 0, 0, 0}}, // ( 31, 53) + { 0, { 0, 0, 0}}, // ( 32, 53) + { 0, { 0, 0, 0}}, // ( 33, 53) + { 0, { 0, 0, 0}}, // ( 34, 53) + { 0, { 0, 0, 0}}, // ( 35, 53) + { 0, { 0, 0, 0}}, // ( 36, 53) + { 0, { 0, 0, 0}}, // ( 37, 53) + { 0, { 0, 0, 0}}, // ( 38, 53) + { 0, { 0, 0, 0}}, // ( 39, 53) + { 0, { 0, 0, 0}}, // ( 40, 53) + { 0, { 0, 0, 0}}, // ( 41, 53) + { 0, { 0, 0, 0}}, // ( 42, 53) + { 0, { 0, 0, 0}}, // ( 43, 53) + { 0, { 0, 0, 0}}, // ( 44, 53) + { 0, { 0, 0, 0}}, // ( 45, 53) + { 0, { 0, 0, 0}}, // ( 46, 53) + { 0, { 0, 0, 0}}, // ( 47, 53) + { 0, { 0, 0, 0}}, // ( 48, 53) + { 0, { 0, 0, 0}}, // ( 49, 53) + { 0, { 0, 0, 0}}, // ( 50, 53) + { 0, { 0, 0, 0}}, // ( 51, 53) + { 0, { 0, 0, 0}}, // ( 52, 53) + { 0, { 0, 0, 0}}, // ( 53, 53) + { 0, { 0, 0, 0}}, // ( 54, 53) + { 0, { 0, 0, 0}}, // ( 55, 53) + { 0, { 0, 0, 0}}, // ( 56, 53) + { 0, { 0, 0, 0}}, // ( 57, 53) + { 0, { 0, 0, 0}}, // ( 58, 53) + { 0, { 0, 0, 0}}, // ( 59, 53) + { 0, { 0, 0, 0}}, // ( 60, 53) + { 0, { 0, 0, 0}}, // ( 61, 53) + { 0, { 0, 0, 0}}, // ( 62, 53) + { 0, { 0, 0, 0}}, // ( 63, 53) + { 0, { 0, 0, 0}}, // ( 64, 53) + { 0, { 0, 0, 0}}, // ( 65, 53) + { 0, { 0, 0, 0}}, // ( 66, 53) + { 0, { 0, 0, 0}}, // ( 67, 53) + { 0, { 0, 0, 0}}, // ( 68, 53) + { 0, { 0, 0, 0}}, // ( 69, 53) + { 0, { 0, 0, 0}}, // ( 70, 53) + { 0, { 0, 0, 0}}, // ( 71, 53) + { 0, { 0, 0, 0}}, // ( 72, 53) + { 0, { 0, 0, 0}}, // ( 73, 53) + { 0, { 0, 0, 0}}, // ( 74, 53) + { 0, { 0, 0, 0}}, // ( 75, 53) + { 0, { 0, 0, 0}}, // ( 76, 53) + { 0, { 0, 0, 0}}, // ( 77, 53) + { 0, { 0, 0, 0}}, // ( 78, 53) + { 0, { 0, 0, 0}}, // ( 79, 53) + { 0, { 0, 0, 0}}, // ( 80, 53) + { 0, { 0, 0, 0}}, // ( 81, 53) + { 0, { 0, 0, 0}}, // ( 82, 53) + { 0, { 0, 0, 0}}, // ( 83, 53) + { 0, { 0, 0, 0}}, // ( 84, 53) + { 0, { 0, 0, 0}}, // ( 85, 53) + { 0, { 0, 0, 0}}, // ( 86, 53) + { 0, { 0, 0, 0}}, // ( 87, 53) + { 0, { 0, 0, 0}}, // ( 88, 53) + { 0, { 0, 0, 0}}, // ( 89, 53) + { 0, { 0, 0, 0}}, // ( 90, 53) + { 0, { 0, 0, 0}}, // ( 91, 53) + { 0, { 0, 0, 0}}, // ( 92, 53) + { 0, { 0, 0, 0}}, // ( 93, 53) + { 0, { 0, 0, 0}}, // ( 94, 53) + { 0, { 0, 0, 0}}, // ( 95, 53) + { 0, { 0, 0, 0}}, // ( 96, 53) + { 0, { 0, 0, 0}}, // ( 97, 53) + { 0, { 0, 0, 0}}, // ( 98, 53) + { 0, { 0, 0, 0}}, // ( 99, 53) + { 0, { 0, 0, 0}}, // (100, 53) + { 0, { 0, 0, 0}}, // (101, 53) + { 0, { 0, 0, 0}}, // (102, 53) + { 0, { 0, 0, 0}}, // (103, 53) + { 0, { 0, 0, 0}}, // (104, 53) + { 0, { 0, 0, 0}}, // (105, 53) + { 0, { 0, 0, 0}}, // (106, 53) + { 0, { 0, 0, 0}}, // (107, 53) + { 0, { 0, 0, 0}}, // (108, 53) + { 0, { 0, 0, 0}}, // (109, 53) + { 0, { 0, 0, 0}}, // (110, 53) + { 0, { 0, 0, 0}}, // (111, 53) + { 0, { 0, 0, 0}}, // (112, 53) + { 0, { 0, 0, 0}}, // (113, 53) + { 0, { 0, 0, 0}}, // (114, 53) + { 0, { 0, 0, 0}}, // (115, 53) + { 0, { 0, 0, 0}}, // (116, 53) + { 0, { 0, 0, 0}}, // (117, 53) + { 0, { 0, 0, 0}}, // (118, 53) + { 0, { 0, 0, 0}}, // (119, 53) + { 0, { 0, 0, 0}}, // (120, 53) + { 0, { 0, 0, 0}}, // (121, 53) + { 0, { 0, 0, 0}}, // (122, 53) + { 0, { 0, 0, 0}}, // (123, 53) + { 0, { 0, 0, 0}}, // (124, 53) + { 0, { 0, 0, 0}}, // (125, 53) + { 0, { 0, 0, 0}}, // (126, 53) + { 0, { 0, 0, 0}}, // (127, 53) + { 0, { 0, 0, 0}}, // (128, 53) + { 0, { 0, 0, 0}}, // (129, 53) + { 0, { 0, 0, 0}}, // (130, 53) + { 0, { 0, 0, 0}}, // (131, 53) + { 0, { 0, 0, 0}}, // (132, 53) + { 0, { 0, 0, 0}}, // (133, 53) + { 0, { 0, 0, 0}}, // (134, 53) + { 0, { 0, 0, 0}}, // (135, 53) + { 0, { 0, 0, 0}}, // (136, 53) + { 0, { 0, 0, 0}}, // (137, 53) + { 0, { 0, 0, 0}}, // (138, 53) + { 0, { 0, 0, 0}}, // (139, 53) + { 0, { 0, 0, 0}}, // (140, 53) + { 0, { 0, 0, 0}}, // (141, 53) + { 0, { 0, 0, 0}}, // (142, 53) + { 0, { 0, 0, 0}}, // (143, 53) + { 0, { 0, 0, 0}}, // (144, 53) + { 0, { 0, 0, 0}}, // (145, 53) + { 0, { 0, 0, 0}}, // (146, 53) + { 0, { 0, 0, 0}}, // (147, 53) + { 0, { 0, 0, 0}}, // (148, 53) + { 0, { 0, 0, 0}}, // (149, 53) + { 0, { 0, 0, 0}}, // (150, 53) + { 0, { 0, 0, 0}}, // (151, 53) + { 0, { 0, 0, 0}}, // (152, 53) + { 0, { 0, 0, 0}}, // (153, 53) + { 0, { 0, 0, 0}}, // (154, 53) + { 0, { 0, 0, 0}}, // (155, 53) + { 0, { 0, 0, 0}}, // (156, 53) + { 0, { 0, 0, 0}}, // (157, 53) + { 0, { 0, 0, 0}}, // (158, 53) + { 0, { 0, 0, 0}}, // (159, 53) + { 0, { 0, 0, 0}}, // (160, 53) + { 0, { 0, 0, 0}}, // (161, 53) + { 0, { 0, 0, 0}}, // (162, 53) + { 0, { 0, 0, 0}}, // (163, 53) + { 0, { 0, 0, 0}}, // (164, 53) + { 0, { 0, 0, 0}}, // (165, 53) + { 0, { 0, 0, 0}}, // (166, 53) + { 0, { 0, 0, 0}}, // (167, 53) + { 0, { 0, 0, 0}}, // (168, 53) + { 3, { 0, 0, 0}}, // (169, 53) + {115, { 0, 0, 0}}, // (170, 53) + {128, { 0, 0, 0}}, // (171, 53) + {128, { 0, 0, 0}}, // (172, 53) + {128, { 0, 0, 0}}, // (173, 53) + {128, { 0, 0, 0}}, // (174, 53) + {128, { 0, 0, 0}}, // (175, 53) + {128, { 0, 0, 0}}, // (176, 53) + {128, { 0, 0, 0}}, // (177, 53) + {128, { 0, 0, 0}}, // (178, 53) + {128, { 0, 0, 0}}, // (179, 53) + {128, { 0, 0, 0}}, // ( 0, 54) + {128, { 0, 0, 0}}, // ( 1, 54) + {128, { 0, 0, 0}}, // ( 2, 54) + {128, { 0, 0, 0}}, // ( 3, 54) + {128, { 0, 0, 0}}, // ( 4, 54) + {128, { 0, 0, 0}}, // ( 5, 54) + {128, { 0, 0, 0}}, // ( 6, 54) + {128, { 0, 0, 0}}, // ( 7, 54) + {128, { 0, 0, 0}}, // ( 8, 54) + { 62, { 0, 0, 0}}, // ( 9, 54) + { 0, { 0, 0, 0}}, // ( 10, 54) + { 0, { 0, 0, 0}}, // ( 11, 54) + { 0, { 0, 0, 0}}, // ( 12, 54) + { 0, { 0, 0, 0}}, // ( 13, 54) + { 0, { 0, 0, 0}}, // ( 14, 54) + { 0, { 0, 0, 0}}, // ( 15, 54) + { 0, { 0, 0, 0}}, // ( 16, 54) + { 0, { 0, 0, 0}}, // ( 17, 54) + { 0, { 0, 0, 0}}, // ( 18, 54) + { 0, { 0, 0, 0}}, // ( 19, 54) + { 0, { 0, 0, 0}}, // ( 20, 54) + { 0, { 0, 0, 0}}, // ( 21, 54) + { 0, { 0, 0, 0}}, // ( 22, 54) + { 0, { 0, 0, 0}}, // ( 23, 54) + { 0, { 0, 0, 0}}, // ( 24, 54) + { 0, { 0, 0, 0}}, // ( 25, 54) + { 0, { 0, 0, 0}}, // ( 26, 54) + { 0, { 0, 0, 0}}, // ( 27, 54) + { 0, { 0, 0, 0}}, // ( 28, 54) + { 0, { 0, 0, 0}}, // ( 29, 54) + { 0, { 0, 0, 0}}, // ( 30, 54) + { 0, { 0, 0, 0}}, // ( 31, 54) + { 0, { 0, 0, 0}}, // ( 32, 54) + { 0, { 0, 0, 0}}, // ( 33, 54) + { 0, { 0, 0, 0}}, // ( 34, 54) + { 0, { 0, 0, 0}}, // ( 35, 54) + { 0, { 0, 0, 0}}, // ( 36, 54) + { 0, { 0, 0, 0}}, // ( 37, 54) + { 0, { 0, 0, 0}}, // ( 38, 54) + { 0, { 0, 0, 0}}, // ( 39, 54) + { 0, { 0, 0, 0}}, // ( 40, 54) + { 0, { 0, 0, 0}}, // ( 41, 54) + { 0, { 0, 0, 0}}, // ( 42, 54) + { 0, { 0, 0, 0}}, // ( 43, 54) + { 0, { 0, 0, 0}}, // ( 44, 54) + { 0, { 0, 0, 0}}, // ( 45, 54) + { 0, { 0, 0, 0}}, // ( 46, 54) + { 0, { 0, 0, 0}}, // ( 47, 54) + { 0, { 0, 0, 0}}, // ( 48, 54) + { 0, { 0, 0, 0}}, // ( 49, 54) + { 0, { 0, 0, 0}}, // ( 50, 54) + { 0, { 0, 0, 0}}, // ( 51, 54) + { 0, { 0, 0, 0}}, // ( 52, 54) + { 0, { 0, 0, 0}}, // ( 53, 54) + { 0, { 0, 0, 0}}, // ( 54, 54) + { 0, { 0, 0, 0}}, // ( 55, 54) + { 0, { 0, 0, 0}}, // ( 56, 54) + { 0, { 0, 0, 0}}, // ( 57, 54) + { 0, { 0, 0, 0}}, // ( 58, 54) + { 0, { 0, 0, 0}}, // ( 59, 54) + { 0, { 0, 0, 0}}, // ( 60, 54) + { 0, { 0, 0, 0}}, // ( 61, 54) + { 0, { 0, 0, 0}}, // ( 62, 54) + { 0, { 0, 0, 0}}, // ( 63, 54) + { 0, { 0, 0, 0}}, // ( 64, 54) + { 0, { 0, 0, 0}}, // ( 65, 54) + { 0, { 0, 0, 0}}, // ( 66, 54) + { 0, { 0, 0, 0}}, // ( 67, 54) + { 0, { 0, 0, 0}}, // ( 68, 54) + { 0, { 0, 0, 0}}, // ( 69, 54) + { 0, { 0, 0, 0}}, // ( 70, 54) + { 0, { 0, 0, 0}}, // ( 71, 54) + { 0, { 0, 0, 0}}, // ( 72, 54) + { 0, { 0, 0, 0}}, // ( 73, 54) + { 0, { 0, 0, 0}}, // ( 74, 54) + { 0, { 0, 0, 0}}, // ( 75, 54) + { 0, { 0, 0, 0}}, // ( 76, 54) + { 0, { 0, 0, 0}}, // ( 77, 54) + { 0, { 0, 0, 0}}, // ( 78, 54) + { 0, { 0, 0, 0}}, // ( 79, 54) + { 0, { 0, 0, 0}}, // ( 80, 54) + { 0, { 0, 0, 0}}, // ( 81, 54) + { 0, { 0, 0, 0}}, // ( 82, 54) + { 0, { 0, 0, 0}}, // ( 83, 54) + { 0, { 0, 0, 0}}, // ( 84, 54) + { 0, { 0, 0, 0}}, // ( 85, 54) + { 0, { 0, 0, 0}}, // ( 86, 54) + { 0, { 0, 0, 0}}, // ( 87, 54) + { 0, { 0, 0, 0}}, // ( 88, 54) + { 0, { 0, 0, 0}}, // ( 89, 54) + { 0, { 0, 0, 0}}, // ( 90, 54) + { 0, { 0, 0, 0}}, // ( 91, 54) + { 0, { 0, 0, 0}}, // ( 92, 54) + { 0, { 0, 0, 0}}, // ( 93, 54) + { 0, { 0, 0, 0}}, // ( 94, 54) + { 0, { 0, 0, 0}}, // ( 95, 54) + { 0, { 0, 0, 0}}, // ( 96, 54) + { 0, { 0, 0, 0}}, // ( 97, 54) + { 0, { 0, 0, 0}}, // ( 98, 54) + { 0, { 0, 0, 0}}, // ( 99, 54) + { 0, { 0, 0, 0}}, // (100, 54) + { 0, { 0, 0, 0}}, // (101, 54) + { 0, { 0, 0, 0}}, // (102, 54) + { 0, { 0, 0, 0}}, // (103, 54) + { 0, { 0, 0, 0}}, // (104, 54) + { 0, { 0, 0, 0}}, // (105, 54) + { 0, { 0, 0, 0}}, // (106, 54) + { 0, { 0, 0, 0}}, // (107, 54) + { 0, { 0, 0, 0}}, // (108, 54) + { 0, { 0, 0, 0}}, // (109, 54) + { 0, { 0, 0, 0}}, // (110, 54) + { 0, { 0, 0, 0}}, // (111, 54) + { 0, { 0, 0, 0}}, // (112, 54) + { 0, { 0, 0, 0}}, // (113, 54) + { 0, { 0, 0, 0}}, // (114, 54) + { 0, { 0, 0, 0}}, // (115, 54) + { 0, { 0, 0, 0}}, // (116, 54) + { 0, { 0, 0, 0}}, // (117, 54) + { 0, { 0, 0, 0}}, // (118, 54) + { 0, { 0, 0, 0}}, // (119, 54) + { 0, { 0, 0, 0}}, // (120, 54) + { 0, { 0, 0, 0}}, // (121, 54) + { 0, { 0, 0, 0}}, // (122, 54) + { 0, { 0, 0, 0}}, // (123, 54) + { 0, { 0, 0, 0}}, // (124, 54) + { 0, { 0, 0, 0}}, // (125, 54) + { 0, { 0, 0, 0}}, // (126, 54) + { 0, { 0, 0, 0}}, // (127, 54) + { 0, { 0, 0, 0}}, // (128, 54) + { 0, { 0, 0, 0}}, // (129, 54) + { 0, { 0, 0, 0}}, // (130, 54) + { 0, { 0, 0, 0}}, // (131, 54) + { 0, { 0, 0, 0}}, // (132, 54) + { 0, { 0, 0, 0}}, // (133, 54) + { 0, { 0, 0, 0}}, // (134, 54) + { 0, { 0, 0, 0}}, // (135, 54) + { 0, { 0, 0, 0}}, // (136, 54) + { 0, { 0, 0, 0}}, // (137, 54) + { 0, { 0, 0, 0}}, // (138, 54) + { 0, { 0, 0, 0}}, // (139, 54) + { 0, { 0, 0, 0}}, // (140, 54) + { 0, { 0, 0, 0}}, // (141, 54) + { 0, { 0, 0, 0}}, // (142, 54) + { 0, { 0, 0, 0}}, // (143, 54) + { 0, { 0, 0, 0}}, // (144, 54) + { 0, { 0, 0, 0}}, // (145, 54) + { 0, { 0, 0, 0}}, // (146, 54) + { 0, { 0, 0, 0}}, // (147, 54) + { 0, { 0, 0, 0}}, // (148, 54) + { 0, { 0, 0, 0}}, // (149, 54) + { 0, { 0, 0, 0}}, // (150, 54) + { 0, { 0, 0, 0}}, // (151, 54) + { 0, { 0, 0, 0}}, // (152, 54) + { 0, { 0, 0, 0}}, // (153, 54) + { 0, { 0, 0, 0}}, // (154, 54) + { 0, { 0, 0, 0}}, // (155, 54) + { 0, { 0, 0, 0}}, // (156, 54) + { 0, { 0, 0, 0}}, // (157, 54) + { 0, { 0, 0, 0}}, // (158, 54) + { 0, { 0, 0, 0}}, // (159, 54) + { 0, { 0, 0, 0}}, // (160, 54) + { 0, { 0, 0, 0}}, // (161, 54) + { 0, { 0, 0, 0}}, // (162, 54) + { 0, { 0, 0, 0}}, // (163, 54) + { 0, { 0, 0, 0}}, // (164, 54) + { 0, { 0, 0, 0}}, // (165, 54) + { 0, { 0, 0, 0}}, // (166, 54) + { 0, { 0, 0, 0}}, // (167, 54) + { 0, { 0, 0, 0}}, // (168, 54) + { 0, { 0, 0, 0}}, // (169, 54) + { 62, { 0, 0, 0}}, // (170, 54) + {128, { 0, 0, 0}}, // (171, 54) + {128, { 0, 0, 0}}, // (172, 54) + {128, { 0, 0, 0}}, // (173, 54) + {128, { 0, 0, 0}}, // (174, 54) + {128, { 0, 0, 0}}, // (175, 54) + {128, { 0, 0, 0}}, // (176, 54) + {128, { 0, 0, 0}}, // (177, 54) + {128, { 0, 0, 0}}, // (178, 54) + {128, { 0, 0, 0}}, // (179, 54) + {128, { 0, 0, 0}}, // ( 0, 55) + {128, { 0, 0, 0}}, // ( 1, 55) + {128, { 0, 0, 0}}, // ( 2, 55) + {128, { 0, 0, 0}}, // ( 3, 55) + {128, { 0, 0, 0}}, // ( 4, 55) + {128, { 0, 0, 0}}, // ( 5, 55) + {128, { 0, 0, 0}}, // ( 6, 55) + {128, { 0, 0, 0}}, // ( 7, 55) + {122, { 0, 0, 0}}, // ( 8, 55) + { 9, { 0, 0, 0}}, // ( 9, 55) + { 0, { 0, 0, 0}}, // ( 10, 55) + { 0, { 0, 0, 0}}, // ( 11, 55) + { 0, { 0, 0, 0}}, // ( 12, 55) + { 0, { 0, 0, 0}}, // ( 13, 55) + { 0, { 0, 0, 0}}, // ( 14, 55) + { 0, { 0, 0, 0}}, // ( 15, 55) + { 0, { 0, 0, 0}}, // ( 16, 55) + { 0, { 0, 0, 0}}, // ( 17, 55) + { 0, { 0, 0, 0}}, // ( 18, 55) + { 0, { 0, 0, 0}}, // ( 19, 55) + { 0, { 0, 0, 0}}, // ( 20, 55) + { 0, { 0, 0, 0}}, // ( 21, 55) + { 0, { 0, 0, 0}}, // ( 22, 55) + { 0, { 0, 0, 0}}, // ( 23, 55) + { 0, { 0, 0, 0}}, // ( 24, 55) + { 0, { 0, 0, 0}}, // ( 25, 55) + { 0, { 0, 0, 0}}, // ( 26, 55) + { 0, { 0, 0, 0}}, // ( 27, 55) + { 0, { 0, 0, 0}}, // ( 28, 55) + { 0, { 0, 0, 0}}, // ( 29, 55) + { 0, { 0, 0, 0}}, // ( 30, 55) + { 0, { 0, 0, 0}}, // ( 31, 55) + { 0, { 0, 0, 0}}, // ( 32, 55) + { 0, { 0, 0, 0}}, // ( 33, 55) + { 0, { 0, 0, 0}}, // ( 34, 55) + { 0, { 0, 0, 0}}, // ( 35, 55) + { 0, { 0, 0, 0}}, // ( 36, 55) + { 0, { 0, 0, 0}}, // ( 37, 55) + { 0, { 0, 0, 0}}, // ( 38, 55) + { 0, { 0, 0, 0}}, // ( 39, 55) + { 0, { 0, 0, 0}}, // ( 40, 55) + { 0, { 0, 0, 0}}, // ( 41, 55) + { 0, { 0, 0, 0}}, // ( 42, 55) + { 0, { 0, 0, 0}}, // ( 43, 55) + { 0, { 0, 0, 0}}, // ( 44, 55) + { 0, { 0, 0, 0}}, // ( 45, 55) + { 0, { 0, 0, 0}}, // ( 46, 55) + { 0, { 0, 0, 0}}, // ( 47, 55) + { 0, { 0, 0, 0}}, // ( 48, 55) + { 0, { 0, 0, 0}}, // ( 49, 55) + { 0, { 0, 0, 0}}, // ( 50, 55) + { 0, { 0, 0, 0}}, // ( 51, 55) + { 0, { 0, 0, 0}}, // ( 52, 55) + { 0, { 0, 0, 0}}, // ( 53, 55) + { 0, { 0, 0, 0}}, // ( 54, 55) + { 0, { 0, 0, 0}}, // ( 55, 55) + { 0, { 0, 0, 0}}, // ( 56, 55) + { 0, { 0, 0, 0}}, // ( 57, 55) + { 0, { 0, 0, 0}}, // ( 58, 55) + { 0, { 0, 0, 0}}, // ( 59, 55) + { 0, { 0, 0, 0}}, // ( 60, 55) + { 0, { 0, 0, 0}}, // ( 61, 55) + { 0, { 0, 0, 0}}, // ( 62, 55) + { 0, { 0, 0, 0}}, // ( 63, 55) + { 0, { 0, 0, 0}}, // ( 64, 55) + { 0, { 0, 0, 0}}, // ( 65, 55) + { 0, { 0, 0, 0}}, // ( 66, 55) + { 0, { 0, 0, 0}}, // ( 67, 55) + { 0, { 0, 0, 0}}, // ( 68, 55) + { 0, { 0, 0, 0}}, // ( 69, 55) + { 0, { 0, 0, 0}}, // ( 70, 55) + { 0, { 0, 0, 0}}, // ( 71, 55) + { 0, { 0, 0, 0}}, // ( 72, 55) + { 0, { 0, 0, 0}}, // ( 73, 55) + { 0, { 0, 0, 0}}, // ( 74, 55) + { 0, { 0, 0, 0}}, // ( 75, 55) + { 0, { 0, 0, 0}}, // ( 76, 55) + { 0, { 0, 0, 0}}, // ( 77, 55) + { 0, { 0, 0, 0}}, // ( 78, 55) + { 0, { 0, 0, 0}}, // ( 79, 55) + { 0, { 0, 0, 0}}, // ( 80, 55) + { 0, { 0, 0, 0}}, // ( 81, 55) + { 0, { 0, 0, 0}}, // ( 82, 55) + { 0, { 0, 0, 0}}, // ( 83, 55) + { 0, { 0, 0, 0}}, // ( 84, 55) + { 0, { 0, 0, 0}}, // ( 85, 55) + { 0, { 0, 0, 0}}, // ( 86, 55) + { 0, { 0, 0, 0}}, // ( 87, 55) + { 0, { 0, 0, 0}}, // ( 88, 55) + { 0, { 0, 0, 0}}, // ( 89, 55) + { 0, { 0, 0, 0}}, // ( 90, 55) + { 0, { 0, 0, 0}}, // ( 91, 55) + { 0, { 0, 0, 0}}, // ( 92, 55) + { 0, { 0, 0, 0}}, // ( 93, 55) + { 0, { 0, 0, 0}}, // ( 94, 55) + { 0, { 0, 0, 0}}, // ( 95, 55) + { 0, { 0, 0, 0}}, // ( 96, 55) + { 0, { 0, 0, 0}}, // ( 97, 55) + { 0, { 0, 0, 0}}, // ( 98, 55) + { 0, { 0, 0, 0}}, // ( 99, 55) + { 0, { 0, 0, 0}}, // (100, 55) + { 0, { 0, 0, 0}}, // (101, 55) + { 0, { 0, 0, 0}}, // (102, 55) + { 0, { 0, 0, 0}}, // (103, 55) + { 0, { 0, 0, 0}}, // (104, 55) + { 0, { 0, 0, 0}}, // (105, 55) + { 0, { 0, 0, 0}}, // (106, 55) + { 0, { 0, 0, 0}}, // (107, 55) + { 0, { 0, 0, 0}}, // (108, 55) + { 0, { 0, 0, 0}}, // (109, 55) + { 0, { 0, 0, 0}}, // (110, 55) + { 0, { 0, 0, 0}}, // (111, 55) + { 0, { 0, 0, 0}}, // (112, 55) + { 0, { 0, 0, 0}}, // (113, 55) + { 0, { 0, 0, 0}}, // (114, 55) + { 0, { 0, 0, 0}}, // (115, 55) + { 0, { 0, 0, 0}}, // (116, 55) + { 0, { 0, 0, 0}}, // (117, 55) + { 0, { 0, 0, 0}}, // (118, 55) + { 0, { 0, 0, 0}}, // (119, 55) + { 0, { 0, 0, 0}}, // (120, 55) + { 0, { 0, 0, 0}}, // (121, 55) + { 0, { 0, 0, 0}}, // (122, 55) + { 0, { 0, 0, 0}}, // (123, 55) + { 0, { 0, 0, 0}}, // (124, 55) + { 0, { 0, 0, 0}}, // (125, 55) + { 0, { 0, 0, 0}}, // (126, 55) + { 0, { 0, 0, 0}}, // (127, 55) + { 0, { 0, 0, 0}}, // (128, 55) + { 0, { 0, 0, 0}}, // (129, 55) + { 0, { 0, 0, 0}}, // (130, 55) + { 0, { 0, 0, 0}}, // (131, 55) + { 0, { 0, 0, 0}}, // (132, 55) + { 0, { 0, 0, 0}}, // (133, 55) + { 0, { 0, 0, 0}}, // (134, 55) + { 0, { 0, 0, 0}}, // (135, 55) + { 0, { 0, 0, 0}}, // (136, 55) + { 0, { 0, 0, 0}}, // (137, 55) + { 0, { 0, 0, 0}}, // (138, 55) + { 0, { 0, 0, 0}}, // (139, 55) + { 0, { 0, 0, 0}}, // (140, 55) + { 0, { 0, 0, 0}}, // (141, 55) + { 0, { 0, 0, 0}}, // (142, 55) + { 0, { 0, 0, 0}}, // (143, 55) + { 0, { 0, 0, 0}}, // (144, 55) + { 0, { 0, 0, 0}}, // (145, 55) + { 0, { 0, 0, 0}}, // (146, 55) + { 0, { 0, 0, 0}}, // (147, 55) + { 0, { 0, 0, 0}}, // (148, 55) + { 0, { 0, 0, 0}}, // (149, 55) + { 0, { 0, 0, 0}}, // (150, 55) + { 0, { 0, 0, 0}}, // (151, 55) + { 0, { 0, 0, 0}}, // (152, 55) + { 0, { 0, 0, 0}}, // (153, 55) + { 0, { 0, 0, 0}}, // (154, 55) + { 0, { 0, 0, 0}}, // (155, 55) + { 0, { 0, 0, 0}}, // (156, 55) + { 0, { 0, 0, 0}}, // (157, 55) + { 0, { 0, 0, 0}}, // (158, 55) + { 0, { 0, 0, 0}}, // (159, 55) + { 0, { 0, 0, 0}}, // (160, 55) + { 0, { 0, 0, 0}}, // (161, 55) + { 0, { 0, 0, 0}}, // (162, 55) + { 0, { 0, 0, 0}}, // (163, 55) + { 0, { 0, 0, 0}}, // (164, 55) + { 0, { 0, 0, 0}}, // (165, 55) + { 0, { 0, 0, 0}}, // (166, 55) + { 0, { 0, 0, 0}}, // (167, 55) + { 0, { 0, 0, 0}}, // (168, 55) + { 0, { 0, 0, 0}}, // (169, 55) + { 9, { 0, 0, 0}}, // (170, 55) + {122, { 0, 0, 0}}, // (171, 55) + {128, { 0, 0, 0}}, // (172, 55) + {128, { 0, 0, 0}}, // (173, 55) + {128, { 0, 0, 0}}, // (174, 55) + {128, { 0, 0, 0}}, // (175, 55) + {128, { 0, 0, 0}}, // (176, 55) + {128, { 0, 0, 0}}, // (177, 55) + {128, { 0, 0, 0}}, // (178, 55) + {128, { 0, 0, 0}}, // (179, 55) + {128, { 0, 0, 0}}, // ( 0, 56) + {128, { 0, 0, 0}}, // ( 1, 56) + {128, { 0, 0, 0}}, // ( 2, 56) + {128, { 0, 0, 0}}, // ( 3, 56) + {128, { 0, 0, 0}}, // ( 4, 56) + {128, { 0, 0, 0}}, // ( 5, 56) + {128, { 0, 0, 0}}, // ( 6, 56) + {128, { 0, 0, 0}}, // ( 7, 56) + { 79, { 0, 0, 0}}, // ( 8, 56) + { 0, { 0, 0, 0}}, // ( 9, 56) + { 0, { 0, 0, 0}}, // ( 10, 56) + { 0, { 0, 0, 0}}, // ( 11, 56) + { 0, { 0, 0, 0}}, // ( 12, 56) + { 0, { 0, 0, 0}}, // ( 13, 56) + { 0, { 0, 0, 0}}, // ( 14, 56) + { 0, { 0, 0, 0}}, // ( 15, 56) + { 0, { 0, 0, 0}}, // ( 16, 56) + { 0, { 0, 0, 0}}, // ( 17, 56) + { 0, { 0, 0, 0}}, // ( 18, 56) + { 0, { 0, 0, 0}}, // ( 19, 56) + { 0, { 0, 0, 0}}, // ( 20, 56) + { 0, { 0, 0, 0}}, // ( 21, 56) + { 0, { 0, 0, 0}}, // ( 22, 56) + { 0, { 0, 0, 0}}, // ( 23, 56) + { 0, { 0, 0, 0}}, // ( 24, 56) + { 0, { 0, 0, 0}}, // ( 25, 56) + { 0, { 0, 0, 0}}, // ( 26, 56) + { 0, { 0, 0, 0}}, // ( 27, 56) + { 0, { 0, 0, 0}}, // ( 28, 56) + { 0, { 0, 0, 0}}, // ( 29, 56) + { 0, { 0, 0, 0}}, // ( 30, 56) + { 0, { 0, 0, 0}}, // ( 31, 56) + { 0, { 0, 0, 0}}, // ( 32, 56) + { 0, { 0, 0, 0}}, // ( 33, 56) + { 0, { 0, 0, 0}}, // ( 34, 56) + { 0, { 0, 0, 0}}, // ( 35, 56) + { 0, { 0, 0, 0}}, // ( 36, 56) + { 0, { 0, 0, 0}}, // ( 37, 56) + { 0, { 0, 0, 0}}, // ( 38, 56) + { 0, { 0, 0, 0}}, // ( 39, 56) + { 0, { 0, 0, 0}}, // ( 40, 56) + { 0, { 0, 0, 0}}, // ( 41, 56) + { 0, { 0, 0, 0}}, // ( 42, 56) + { 0, { 0, 0, 0}}, // ( 43, 56) + { 0, { 0, 0, 0}}, // ( 44, 56) + { 0, { 0, 0, 0}}, // ( 45, 56) + { 0, { 0, 0, 0}}, // ( 46, 56) + { 0, { 0, 0, 0}}, // ( 47, 56) + { 0, { 0, 0, 0}}, // ( 48, 56) + { 0, { 0, 0, 0}}, // ( 49, 56) + { 0, { 0, 0, 0}}, // ( 50, 56) + { 0, { 0, 0, 0}}, // ( 51, 56) + { 0, { 0, 0, 0}}, // ( 52, 56) + { 0, { 0, 0, 0}}, // ( 53, 56) + { 0, { 0, 0, 0}}, // ( 54, 56) + { 0, { 0, 0, 0}}, // ( 55, 56) + { 0, { 0, 0, 0}}, // ( 56, 56) + { 0, { 0, 0, 0}}, // ( 57, 56) + { 0, { 0, 0, 0}}, // ( 58, 56) + { 0, { 0, 0, 0}}, // ( 59, 56) + { 0, { 0, 0, 0}}, // ( 60, 56) + { 0, { 0, 0, 0}}, // ( 61, 56) + { 0, { 0, 0, 0}}, // ( 62, 56) + { 0, { 0, 0, 0}}, // ( 63, 56) + { 0, { 0, 0, 0}}, // ( 64, 56) + { 0, { 0, 0, 0}}, // ( 65, 56) + { 0, { 0, 0, 0}}, // ( 66, 56) + { 0, { 0, 0, 0}}, // ( 67, 56) + { 0, { 0, 0, 0}}, // ( 68, 56) + { 0, { 0, 0, 0}}, // ( 69, 56) + { 0, { 0, 0, 0}}, // ( 70, 56) + { 0, { 0, 0, 0}}, // ( 71, 56) + { 0, { 0, 0, 0}}, // ( 72, 56) + { 0, { 0, 0, 0}}, // ( 73, 56) + { 0, { 0, 0, 0}}, // ( 74, 56) + { 0, { 0, 0, 0}}, // ( 75, 56) + { 0, { 0, 0, 0}}, // ( 76, 56) + { 0, { 0, 0, 0}}, // ( 77, 56) + { 0, { 0, 0, 0}}, // ( 78, 56) + { 0, { 0, 0, 0}}, // ( 79, 56) + { 0, { 0, 0, 0}}, // ( 80, 56) + { 0, { 0, 0, 0}}, // ( 81, 56) + { 0, { 0, 0, 0}}, // ( 82, 56) + { 0, { 0, 0, 0}}, // ( 83, 56) + { 0, { 0, 0, 0}}, // ( 84, 56) + { 0, { 0, 0, 0}}, // ( 85, 56) + { 0, { 0, 0, 0}}, // ( 86, 56) + { 0, { 0, 0, 0}}, // ( 87, 56) + { 0, { 0, 0, 0}}, // ( 88, 56) + { 0, { 0, 0, 0}}, // ( 89, 56) + { 0, { 0, 0, 0}}, // ( 90, 56) + { 0, { 0, 0, 0}}, // ( 91, 56) + { 0, { 0, 0, 0}}, // ( 92, 56) + { 0, { 0, 0, 0}}, // ( 93, 56) + { 0, { 0, 0, 0}}, // ( 94, 56) + { 0, { 0, 0, 0}}, // ( 95, 56) + { 0, { 0, 0, 0}}, // ( 96, 56) + { 0, { 0, 0, 0}}, // ( 97, 56) + { 0, { 0, 0, 0}}, // ( 98, 56) + { 0, { 0, 0, 0}}, // ( 99, 56) + { 0, { 0, 0, 0}}, // (100, 56) + { 0, { 0, 0, 0}}, // (101, 56) + { 0, { 0, 0, 0}}, // (102, 56) + { 0, { 0, 0, 0}}, // (103, 56) + { 0, { 0, 0, 0}}, // (104, 56) + { 0, { 0, 0, 0}}, // (105, 56) + { 0, { 0, 0, 0}}, // (106, 56) + { 0, { 0, 0, 0}}, // (107, 56) + { 0, { 0, 0, 0}}, // (108, 56) + { 0, { 0, 0, 0}}, // (109, 56) + { 0, { 0, 0, 0}}, // (110, 56) + { 0, { 0, 0, 0}}, // (111, 56) + { 0, { 0, 0, 0}}, // (112, 56) + { 0, { 0, 0, 0}}, // (113, 56) + { 0, { 0, 0, 0}}, // (114, 56) + { 0, { 0, 0, 0}}, // (115, 56) + { 0, { 0, 0, 0}}, // (116, 56) + { 0, { 0, 0, 0}}, // (117, 56) + { 0, { 0, 0, 0}}, // (118, 56) + { 0, { 0, 0, 0}}, // (119, 56) + { 0, { 0, 0, 0}}, // (120, 56) + { 0, { 0, 0, 0}}, // (121, 56) + { 0, { 0, 0, 0}}, // (122, 56) + { 0, { 0, 0, 0}}, // (123, 56) + { 0, { 0, 0, 0}}, // (124, 56) + { 0, { 0, 0, 0}}, // (125, 56) + { 0, { 0, 0, 0}}, // (126, 56) + { 0, { 0, 0, 0}}, // (127, 56) + { 0, { 0, 0, 0}}, // (128, 56) + { 0, { 0, 0, 0}}, // (129, 56) + { 0, { 0, 0, 0}}, // (130, 56) + { 0, { 0, 0, 0}}, // (131, 56) + { 0, { 0, 0, 0}}, // (132, 56) + { 0, { 0, 0, 0}}, // (133, 56) + { 0, { 0, 0, 0}}, // (134, 56) + { 0, { 0, 0, 0}}, // (135, 56) + { 0, { 0, 0, 0}}, // (136, 56) + { 0, { 0, 0, 0}}, // (137, 56) + { 0, { 0, 0, 0}}, // (138, 56) + { 0, { 0, 0, 0}}, // (139, 56) + { 0, { 0, 0, 0}}, // (140, 56) + { 0, { 0, 0, 0}}, // (141, 56) + { 0, { 0, 0, 0}}, // (142, 56) + { 0, { 0, 0, 0}}, // (143, 56) + { 0, { 0, 0, 0}}, // (144, 56) + { 0, { 0, 0, 0}}, // (145, 56) + { 0, { 0, 0, 0}}, // (146, 56) + { 0, { 0, 0, 0}}, // (147, 56) + { 0, { 0, 0, 0}}, // (148, 56) + { 0, { 0, 0, 0}}, // (149, 56) + { 0, { 0, 0, 0}}, // (150, 56) + { 0, { 0, 0, 0}}, // (151, 56) + { 0, { 0, 0, 0}}, // (152, 56) + { 0, { 0, 0, 0}}, // (153, 56) + { 0, { 0, 0, 0}}, // (154, 56) + { 0, { 0, 0, 0}}, // (155, 56) + { 0, { 0, 0, 0}}, // (156, 56) + { 0, { 0, 0, 0}}, // (157, 56) + { 0, { 0, 0, 0}}, // (158, 56) + { 0, { 0, 0, 0}}, // (159, 56) + { 0, { 0, 0, 0}}, // (160, 56) + { 0, { 0, 0, 0}}, // (161, 56) + { 0, { 0, 0, 0}}, // (162, 56) + { 0, { 0, 0, 0}}, // (163, 56) + { 0, { 0, 0, 0}}, // (164, 56) + { 0, { 0, 0, 0}}, // (165, 56) + { 0, { 0, 0, 0}}, // (166, 56) + { 0, { 0, 0, 0}}, // (167, 56) + { 0, { 0, 0, 0}}, // (168, 56) + { 0, { 0, 0, 0}}, // (169, 56) + { 0, { 0, 0, 0}}, // (170, 56) + { 79, { 0, 0, 0}}, // (171, 56) + {128, { 0, 0, 0}}, // (172, 56) + {128, { 0, 0, 0}}, // (173, 56) + {128, { 0, 0, 0}}, // (174, 56) + {128, { 0, 0, 0}}, // (175, 56) + {128, { 0, 0, 0}}, // (176, 56) + {128, { 0, 0, 0}}, // (177, 56) + {128, { 0, 0, 0}}, // (178, 56) + {128, { 0, 0, 0}}, // (179, 56) + {128, { 0, 0, 0}}, // ( 0, 57) + {128, { 0, 0, 0}}, // ( 1, 57) + {128, { 0, 0, 0}}, // ( 2, 57) + {128, { 0, 0, 0}}, // ( 3, 57) + {128, { 0, 0, 0}}, // ( 4, 57) + {128, { 0, 0, 0}}, // ( 5, 57) + {128, { 0, 0, 0}}, // ( 6, 57) + {128, { 0, 0, 0}}, // ( 7, 57) + { 29, { 0, 0, 0}}, // ( 8, 57) + { 0, { 0, 0, 0}}, // ( 9, 57) + { 0, { 0, 0, 0}}, // ( 10, 57) + { 0, { 0, 0, 0}}, // ( 11, 57) + { 0, { 0, 0, 0}}, // ( 12, 57) + { 0, { 0, 0, 0}}, // ( 13, 57) + { 0, { 0, 0, 0}}, // ( 14, 57) + { 0, { 0, 0, 0}}, // ( 15, 57) + { 0, { 0, 0, 0}}, // ( 16, 57) + { 0, { 0, 0, 0}}, // ( 17, 57) + { 0, { 0, 0, 0}}, // ( 18, 57) + { 0, { 0, 0, 0}}, // ( 19, 57) + { 0, { 0, 0, 0}}, // ( 20, 57) + { 0, { 0, 0, 0}}, // ( 21, 57) + { 0, { 0, 0, 0}}, // ( 22, 57) + { 0, { 0, 0, 0}}, // ( 23, 57) + { 0, { 0, 0, 0}}, // ( 24, 57) + { 0, { 0, 0, 0}}, // ( 25, 57) + { 0, { 0, 0, 0}}, // ( 26, 57) + { 0, { 0, 0, 0}}, // ( 27, 57) + { 0, { 0, 0, 0}}, // ( 28, 57) + { 0, { 0, 0, 0}}, // ( 29, 57) + { 0, { 0, 0, 0}}, // ( 30, 57) + { 0, { 0, 0, 0}}, // ( 31, 57) + { 0, { 0, 0, 0}}, // ( 32, 57) + { 0, { 0, 0, 0}}, // ( 33, 57) + { 0, { 0, 0, 0}}, // ( 34, 57) + { 0, { 0, 0, 0}}, // ( 35, 57) + { 0, { 0, 0, 0}}, // ( 36, 57) + { 0, { 0, 0, 0}}, // ( 37, 57) + { 0, { 0, 0, 0}}, // ( 38, 57) + { 0, { 0, 0, 0}}, // ( 39, 57) + { 0, { 0, 0, 0}}, // ( 40, 57) + { 0, { 0, 0, 0}}, // ( 41, 57) + { 0, { 0, 0, 0}}, // ( 42, 57) + { 0, { 0, 0, 0}}, // ( 43, 57) + { 0, { 0, 0, 0}}, // ( 44, 57) + { 0, { 0, 0, 0}}, // ( 45, 57) + { 0, { 0, 0, 0}}, // ( 46, 57) + { 0, { 0, 0, 0}}, // ( 47, 57) + { 0, { 0, 0, 0}}, // ( 48, 57) + { 0, { 0, 0, 0}}, // ( 49, 57) + { 0, { 0, 0, 0}}, // ( 50, 57) + { 0, { 0, 0, 0}}, // ( 51, 57) + { 0, { 0, 0, 0}}, // ( 52, 57) + { 0, { 0, 0, 0}}, // ( 53, 57) + { 0, { 0, 0, 0}}, // ( 54, 57) + { 0, { 0, 0, 0}}, // ( 55, 57) + { 0, { 0, 0, 0}}, // ( 56, 57) + { 0, { 0, 0, 0}}, // ( 57, 57) + { 0, { 0, 0, 0}}, // ( 58, 57) + { 0, { 0, 0, 0}}, // ( 59, 57) + { 0, { 0, 0, 0}}, // ( 60, 57) + { 0, { 0, 0, 0}}, // ( 61, 57) + { 0, { 0, 0, 0}}, // ( 62, 57) + { 0, { 0, 0, 0}}, // ( 63, 57) + { 0, { 0, 0, 0}}, // ( 64, 57) + { 0, { 0, 0, 0}}, // ( 65, 57) + { 0, { 0, 0, 0}}, // ( 66, 57) + { 0, { 0, 0, 0}}, // ( 67, 57) + { 0, { 0, 0, 0}}, // ( 68, 57) + { 0, { 0, 0, 0}}, // ( 69, 57) + { 0, { 0, 0, 0}}, // ( 70, 57) + { 0, { 0, 0, 0}}, // ( 71, 57) + { 0, { 0, 0, 0}}, // ( 72, 57) + { 0, { 0, 0, 0}}, // ( 73, 57) + { 0, { 0, 0, 0}}, // ( 74, 57) + { 0, { 0, 0, 0}}, // ( 75, 57) + { 0, { 0, 0, 0}}, // ( 76, 57) + { 0, { 0, 0, 0}}, // ( 77, 57) + { 0, { 0, 0, 0}}, // ( 78, 57) + { 0, { 0, 0, 0}}, // ( 79, 57) + { 0, { 0, 0, 0}}, // ( 80, 57) + { 0, { 0, 0, 0}}, // ( 81, 57) + { 0, { 0, 0, 0}}, // ( 82, 57) + { 0, { 0, 0, 0}}, // ( 83, 57) + { 0, { 0, 0, 0}}, // ( 84, 57) + { 0, { 0, 0, 0}}, // ( 85, 57) + { 0, { 0, 0, 0}}, // ( 86, 57) + { 0, { 0, 0, 0}}, // ( 87, 57) + { 0, { 0, 0, 0}}, // ( 88, 57) + { 0, { 0, 0, 0}}, // ( 89, 57) + { 0, { 0, 0, 0}}, // ( 90, 57) + { 0, { 0, 0, 0}}, // ( 91, 57) + { 0, { 0, 0, 0}}, // ( 92, 57) + { 0, { 0, 0, 0}}, // ( 93, 57) + { 0, { 0, 0, 0}}, // ( 94, 57) + { 0, { 0, 0, 0}}, // ( 95, 57) + { 0, { 0, 0, 0}}, // ( 96, 57) + { 0, { 0, 0, 0}}, // ( 97, 57) + { 0, { 0, 0, 0}}, // ( 98, 57) + { 0, { 0, 0, 0}}, // ( 99, 57) + { 0, { 0, 0, 0}}, // (100, 57) + { 0, { 0, 0, 0}}, // (101, 57) + { 0, { 0, 0, 0}}, // (102, 57) + { 0, { 0, 0, 0}}, // (103, 57) + { 0, { 0, 0, 0}}, // (104, 57) + { 0, { 0, 0, 0}}, // (105, 57) + { 0, { 0, 0, 0}}, // (106, 57) + { 0, { 0, 0, 0}}, // (107, 57) + { 0, { 0, 0, 0}}, // (108, 57) + { 0, { 0, 0, 0}}, // (109, 57) + { 0, { 0, 0, 0}}, // (110, 57) + { 0, { 0, 0, 0}}, // (111, 57) + { 0, { 0, 0, 0}}, // (112, 57) + { 0, { 0, 0, 0}}, // (113, 57) + { 0, { 0, 0, 0}}, // (114, 57) + { 0, { 0, 0, 0}}, // (115, 57) + { 0, { 0, 0, 0}}, // (116, 57) + { 0, { 0, 0, 0}}, // (117, 57) + { 0, { 0, 0, 0}}, // (118, 57) + { 0, { 0, 0, 0}}, // (119, 57) + { 0, { 0, 0, 0}}, // (120, 57) + { 0, { 0, 0, 0}}, // (121, 57) + { 0, { 0, 0, 0}}, // (122, 57) + { 0, { 0, 0, 0}}, // (123, 57) + { 0, { 0, 0, 0}}, // (124, 57) + { 0, { 0, 0, 0}}, // (125, 57) + { 0, { 0, 0, 0}}, // (126, 57) + { 0, { 0, 0, 0}}, // (127, 57) + { 0, { 0, 0, 0}}, // (128, 57) + { 0, { 0, 0, 0}}, // (129, 57) + { 0, { 0, 0, 0}}, // (130, 57) + { 0, { 0, 0, 0}}, // (131, 57) + { 0, { 0, 0, 0}}, // (132, 57) + { 0, { 0, 0, 0}}, // (133, 57) + { 0, { 0, 0, 0}}, // (134, 57) + { 0, { 0, 0, 0}}, // (135, 57) + { 0, { 0, 0, 0}}, // (136, 57) + { 0, { 0, 0, 0}}, // (137, 57) + { 0, { 0, 0, 0}}, // (138, 57) + { 0, { 0, 0, 0}}, // (139, 57) + { 0, { 0, 0, 0}}, // (140, 57) + { 0, { 0, 0, 0}}, // (141, 57) + { 0, { 0, 0, 0}}, // (142, 57) + { 0, { 0, 0, 0}}, // (143, 57) + { 0, { 0, 0, 0}}, // (144, 57) + { 0, { 0, 0, 0}}, // (145, 57) + { 0, { 0, 0, 0}}, // (146, 57) + { 0, { 0, 0, 0}}, // (147, 57) + { 0, { 0, 0, 0}}, // (148, 57) + { 0, { 0, 0, 0}}, // (149, 57) + { 0, { 0, 0, 0}}, // (150, 57) + { 0, { 0, 0, 0}}, // (151, 57) + { 0, { 0, 0, 0}}, // (152, 57) + { 0, { 0, 0, 0}}, // (153, 57) + { 0, { 0, 0, 0}}, // (154, 57) + { 0, { 0, 0, 0}}, // (155, 57) + { 0, { 0, 0, 0}}, // (156, 57) + { 0, { 0, 0, 0}}, // (157, 57) + { 0, { 0, 0, 0}}, // (158, 57) + { 0, { 0, 0, 0}}, // (159, 57) + { 0, { 0, 0, 0}}, // (160, 57) + { 0, { 0, 0, 0}}, // (161, 57) + { 0, { 0, 0, 0}}, // (162, 57) + { 0, { 0, 0, 0}}, // (163, 57) + { 0, { 0, 0, 0}}, // (164, 57) + { 0, { 0, 0, 0}}, // (165, 57) + { 0, { 0, 0, 0}}, // (166, 57) + { 0, { 0, 0, 0}}, // (167, 57) + { 0, { 0, 0, 0}}, // (168, 57) + { 0, { 0, 0, 0}}, // (169, 57) + { 0, { 0, 0, 0}}, // (170, 57) + { 29, { 0, 0, 0}}, // (171, 57) + {128, { 0, 0, 0}}, // (172, 57) + {128, { 0, 0, 0}}, // (173, 57) + {128, { 0, 0, 0}}, // (174, 57) + {128, { 0, 0, 0}}, // (175, 57) + {128, { 0, 0, 0}}, // (176, 57) + {128, { 0, 0, 0}}, // (177, 57) + {128, { 0, 0, 0}}, // (178, 57) + {128, { 0, 0, 0}}, // (179, 57) + {128, { 0, 0, 0}}, // ( 0, 58) + {128, { 0, 0, 0}}, // ( 1, 58) + {128, { 0, 0, 0}}, // ( 2, 58) + {128, { 0, 0, 0}}, // ( 3, 58) + {128, { 0, 0, 0}}, // ( 4, 58) + {128, { 0, 0, 0}}, // ( 5, 58) + {128, { 0, 0, 0}}, // ( 6, 58) + {106, { 0, 0, 0}}, // ( 7, 58) + { 0, { 0, 0, 0}}, // ( 8, 58) + { 0, { 0, 0, 0}}, // ( 9, 58) + { 0, { 0, 0, 0}}, // ( 10, 58) + { 0, { 0, 0, 0}}, // ( 11, 58) + { 0, { 0, 0, 0}}, // ( 12, 58) + { 0, { 0, 0, 0}}, // ( 13, 58) + { 0, { 0, 0, 0}}, // ( 14, 58) + { 0, { 0, 0, 0}}, // ( 15, 58) + { 0, { 0, 0, 0}}, // ( 16, 58) + { 0, { 0, 0, 0}}, // ( 17, 58) + { 0, { 0, 0, 0}}, // ( 18, 58) + { 0, { 0, 0, 0}}, // ( 19, 58) + { 0, { 0, 0, 0}}, // ( 20, 58) + { 0, { 0, 0, 0}}, // ( 21, 58) + { 0, { 0, 0, 0}}, // ( 22, 58) + { 0, { 0, 0, 0}}, // ( 23, 58) + { 0, { 0, 0, 0}}, // ( 24, 58) + { 0, { 0, 0, 0}}, // ( 25, 58) + { 0, { 0, 0, 0}}, // ( 26, 58) + { 0, { 0, 0, 0}}, // ( 27, 58) + { 0, { 0, 0, 0}}, // ( 28, 58) + { 0, { 0, 0, 0}}, // ( 29, 58) + { 0, { 0, 0, 0}}, // ( 30, 58) + { 0, { 0, 0, 0}}, // ( 31, 58) + { 0, { 0, 0, 0}}, // ( 32, 58) + { 0, { 0, 0, 0}}, // ( 33, 58) + { 0, { 0, 0, 0}}, // ( 34, 58) + { 0, { 0, 0, 0}}, // ( 35, 58) + { 0, { 0, 0, 0}}, // ( 36, 58) + { 0, { 0, 0, 0}}, // ( 37, 58) + { 0, { 0, 0, 0}}, // ( 38, 58) + { 0, { 0, 0, 0}}, // ( 39, 58) + { 0, { 0, 0, 0}}, // ( 40, 58) + { 0, { 0, 0, 0}}, // ( 41, 58) + { 0, { 0, 0, 0}}, // ( 42, 58) + { 0, { 0, 0, 0}}, // ( 43, 58) + { 0, { 0, 0, 0}}, // ( 44, 58) + { 0, { 0, 0, 0}}, // ( 45, 58) + { 0, { 0, 0, 0}}, // ( 46, 58) + { 0, { 0, 0, 0}}, // ( 47, 58) + { 0, { 0, 0, 0}}, // ( 48, 58) + { 0, { 0, 0, 0}}, // ( 49, 58) + { 0, { 0, 0, 0}}, // ( 50, 58) + { 0, { 0, 0, 0}}, // ( 51, 58) + { 0, { 0, 0, 0}}, // ( 52, 58) + { 0, { 0, 0, 0}}, // ( 53, 58) + { 0, { 0, 0, 0}}, // ( 54, 58) + { 0, { 0, 0, 0}}, // ( 55, 58) + { 0, { 0, 0, 0}}, // ( 56, 58) + { 0, { 0, 0, 0}}, // ( 57, 58) + { 0, { 0, 0, 0}}, // ( 58, 58) + { 0, { 0, 0, 0}}, // ( 59, 58) + { 0, { 0, 0, 0}}, // ( 60, 58) + { 0, { 0, 0, 0}}, // ( 61, 58) + { 0, { 0, 0, 0}}, // ( 62, 58) + { 0, { 0, 0, 0}}, // ( 63, 58) + { 0, { 0, 0, 0}}, // ( 64, 58) + { 0, { 0, 0, 0}}, // ( 65, 58) + { 0, { 0, 0, 0}}, // ( 66, 58) + { 0, { 0, 0, 0}}, // ( 67, 58) + { 0, { 0, 0, 0}}, // ( 68, 58) + { 0, { 0, 0, 0}}, // ( 69, 58) + { 0, { 0, 0, 0}}, // ( 70, 58) + { 0, { 0, 0, 0}}, // ( 71, 58) + { 0, { 0, 0, 0}}, // ( 72, 58) + { 0, { 0, 0, 0}}, // ( 73, 58) + { 0, { 0, 0, 0}}, // ( 74, 58) + { 0, { 0, 0, 0}}, // ( 75, 58) + { 0, { 0, 0, 0}}, // ( 76, 58) + { 0, { 0, 0, 0}}, // ( 77, 58) + { 0, { 0, 0, 0}}, // ( 78, 58) + { 0, { 0, 0, 0}}, // ( 79, 58) + { 0, { 0, 0, 0}}, // ( 80, 58) + { 0, { 0, 0, 0}}, // ( 81, 58) + { 0, { 0, 0, 0}}, // ( 82, 58) + { 0, { 0, 0, 0}}, // ( 83, 58) + { 0, { 0, 0, 0}}, // ( 84, 58) + { 0, { 0, 0, 0}}, // ( 85, 58) + { 0, { 0, 0, 0}}, // ( 86, 58) + { 0, { 0, 0, 0}}, // ( 87, 58) + { 0, { 0, 0, 0}}, // ( 88, 58) + { 0, { 0, 0, 0}}, // ( 89, 58) + { 0, { 0, 0, 0}}, // ( 90, 58) + { 0, { 0, 0, 0}}, // ( 91, 58) + { 0, { 0, 0, 0}}, // ( 92, 58) + { 0, { 0, 0, 0}}, // ( 93, 58) + { 0, { 0, 0, 0}}, // ( 94, 58) + { 0, { 0, 0, 0}}, // ( 95, 58) + { 0, { 0, 0, 0}}, // ( 96, 58) + { 0, { 0, 0, 0}}, // ( 97, 58) + { 0, { 0, 0, 0}}, // ( 98, 58) + { 0, { 0, 0, 0}}, // ( 99, 58) + { 0, { 0, 0, 0}}, // (100, 58) + { 0, { 0, 0, 0}}, // (101, 58) + { 0, { 0, 0, 0}}, // (102, 58) + { 0, { 0, 0, 0}}, // (103, 58) + { 0, { 0, 0, 0}}, // (104, 58) + { 0, { 0, 0, 0}}, // (105, 58) + { 0, { 0, 0, 0}}, // (106, 58) + { 0, { 0, 0, 0}}, // (107, 58) + { 0, { 0, 0, 0}}, // (108, 58) + { 0, { 0, 0, 0}}, // (109, 58) + { 0, { 0, 0, 0}}, // (110, 58) + { 0, { 0, 0, 0}}, // (111, 58) + { 0, { 0, 0, 0}}, // (112, 58) + { 0, { 0, 0, 0}}, // (113, 58) + { 0, { 0, 0, 0}}, // (114, 58) + { 0, { 0, 0, 0}}, // (115, 58) + { 0, { 0, 0, 0}}, // (116, 58) + { 0, { 0, 0, 0}}, // (117, 58) + { 0, { 0, 0, 0}}, // (118, 58) + { 0, { 0, 0, 0}}, // (119, 58) + { 0, { 0, 0, 0}}, // (120, 58) + { 0, { 0, 0, 0}}, // (121, 58) + { 0, { 0, 0, 0}}, // (122, 58) + { 0, { 0, 0, 0}}, // (123, 58) + { 0, { 0, 0, 0}}, // (124, 58) + { 0, { 0, 0, 0}}, // (125, 58) + { 0, { 0, 0, 0}}, // (126, 58) + { 0, { 0, 0, 0}}, // (127, 58) + { 0, { 0, 0, 0}}, // (128, 58) + { 0, { 0, 0, 0}}, // (129, 58) + { 0, { 0, 0, 0}}, // (130, 58) + { 0, { 0, 0, 0}}, // (131, 58) + { 0, { 0, 0, 0}}, // (132, 58) + { 0, { 0, 0, 0}}, // (133, 58) + { 0, { 0, 0, 0}}, // (134, 58) + { 0, { 0, 0, 0}}, // (135, 58) + { 0, { 0, 0, 0}}, // (136, 58) + { 0, { 0, 0, 0}}, // (137, 58) + { 0, { 0, 0, 0}}, // (138, 58) + { 0, { 0, 0, 0}}, // (139, 58) + { 0, { 0, 0, 0}}, // (140, 58) + { 0, { 0, 0, 0}}, // (141, 58) + { 0, { 0, 0, 0}}, // (142, 58) + { 0, { 0, 0, 0}}, // (143, 58) + { 0, { 0, 0, 0}}, // (144, 58) + { 0, { 0, 0, 0}}, // (145, 58) + { 0, { 0, 0, 0}}, // (146, 58) + { 0, { 0, 0, 0}}, // (147, 58) + { 0, { 0, 0, 0}}, // (148, 58) + { 0, { 0, 0, 0}}, // (149, 58) + { 0, { 0, 0, 0}}, // (150, 58) + { 0, { 0, 0, 0}}, // (151, 58) + { 0, { 0, 0, 0}}, // (152, 58) + { 0, { 0, 0, 0}}, // (153, 58) + { 0, { 0, 0, 0}}, // (154, 58) + { 0, { 0, 0, 0}}, // (155, 58) + { 0, { 0, 0, 0}}, // (156, 58) + { 0, { 0, 0, 0}}, // (157, 58) + { 0, { 0, 0, 0}}, // (158, 58) + { 0, { 0, 0, 0}}, // (159, 58) + { 0, { 0, 0, 0}}, // (160, 58) + { 0, { 0, 0, 0}}, // (161, 58) + { 0, { 0, 0, 0}}, // (162, 58) + { 0, { 0, 0, 0}}, // (163, 58) + { 0, { 0, 0, 0}}, // (164, 58) + { 0, { 0, 0, 0}}, // (165, 58) + { 0, { 0, 0, 0}}, // (166, 58) + { 0, { 0, 0, 0}}, // (167, 58) + { 0, { 0, 0, 0}}, // (168, 58) + { 0, { 0, 0, 0}}, // (169, 58) + { 0, { 0, 0, 0}}, // (170, 58) + { 0, { 0, 0, 0}}, // (171, 58) + {106, { 0, 0, 0}}, // (172, 58) + {128, { 0, 0, 0}}, // (173, 58) + {128, { 0, 0, 0}}, // (174, 58) + {128, { 0, 0, 0}}, // (175, 58) + {128, { 0, 0, 0}}, // (176, 58) + {128, { 0, 0, 0}}, // (177, 58) + {128, { 0, 0, 0}}, // (178, 58) + {128, { 0, 0, 0}}, // (179, 58) + {128, { 0, 0, 0}}, // ( 0, 59) + {128, { 0, 0, 0}}, // ( 1, 59) + {128, { 0, 0, 0}}, // ( 2, 59) + {128, { 0, 0, 0}}, // ( 3, 59) + {128, { 0, 0, 0}}, // ( 4, 59) + {128, { 0, 0, 0}}, // ( 5, 59) + {128, { 0, 0, 0}}, // ( 6, 59) + { 56, { 0, 0, 0}}, // ( 7, 59) + { 0, { 0, 0, 0}}, // ( 8, 59) + { 0, { 0, 0, 0}}, // ( 9, 59) + { 0, { 0, 0, 0}}, // ( 10, 59) + { 0, { 0, 0, 0}}, // ( 11, 59) + { 0, { 0, 0, 0}}, // ( 12, 59) + { 0, { 0, 0, 0}}, // ( 13, 59) + { 0, { 0, 0, 0}}, // ( 14, 59) + { 0, { 0, 0, 0}}, // ( 15, 59) + { 0, { 0, 0, 0}}, // ( 16, 59) + { 0, { 0, 0, 0}}, // ( 17, 59) + { 0, { 0, 0, 0}}, // ( 18, 59) + { 0, { 0, 0, 0}}, // ( 19, 59) + { 0, { 0, 0, 0}}, // ( 20, 59) + { 0, { 0, 0, 0}}, // ( 21, 59) + { 0, { 0, 0, 0}}, // ( 22, 59) + { 0, { 0, 0, 0}}, // ( 23, 59) + { 0, { 0, 0, 0}}, // ( 24, 59) + { 0, { 0, 0, 0}}, // ( 25, 59) + { 0, { 0, 0, 0}}, // ( 26, 59) + { 0, { 0, 0, 0}}, // ( 27, 59) + { 0, { 0, 0, 0}}, // ( 28, 59) + { 0, { 0, 0, 0}}, // ( 29, 59) + { 0, { 0, 0, 0}}, // ( 30, 59) + { 0, { 0, 0, 0}}, // ( 31, 59) + { 0, { 0, 0, 0}}, // ( 32, 59) + { 0, { 0, 0, 0}}, // ( 33, 59) + { 0, { 0, 0, 0}}, // ( 34, 59) + { 0, { 0, 0, 0}}, // ( 35, 59) + { 0, { 0, 0, 0}}, // ( 36, 59) + { 0, { 0, 0, 0}}, // ( 37, 59) + { 0, { 0, 0, 0}}, // ( 38, 59) + { 0, { 0, 0, 0}}, // ( 39, 59) + { 0, { 0, 0, 0}}, // ( 40, 59) + { 0, { 0, 0, 0}}, // ( 41, 59) + { 0, { 0, 0, 0}}, // ( 42, 59) + { 0, { 0, 0, 0}}, // ( 43, 59) + { 0, { 0, 0, 0}}, // ( 44, 59) + { 0, { 0, 0, 0}}, // ( 45, 59) + { 0, { 0, 0, 0}}, // ( 46, 59) + { 0, { 0, 0, 0}}, // ( 47, 59) + { 0, { 0, 0, 0}}, // ( 48, 59) + { 0, { 0, 0, 0}}, // ( 49, 59) + { 0, { 0, 0, 0}}, // ( 50, 59) + { 0, { 0, 0, 0}}, // ( 51, 59) + { 0, { 0, 0, 0}}, // ( 52, 59) + { 0, { 0, 0, 0}}, // ( 53, 59) + { 0, { 0, 0, 0}}, // ( 54, 59) + { 0, { 0, 0, 0}}, // ( 55, 59) + { 0, { 0, 0, 0}}, // ( 56, 59) + { 0, { 0, 0, 0}}, // ( 57, 59) + { 0, { 0, 0, 0}}, // ( 58, 59) + { 0, { 0, 0, 0}}, // ( 59, 59) + { 0, { 0, 0, 0}}, // ( 60, 59) + { 0, { 0, 0, 0}}, // ( 61, 59) + { 0, { 0, 0, 0}}, // ( 62, 59) + { 0, { 0, 0, 0}}, // ( 63, 59) + { 0, { 0, 0, 0}}, // ( 64, 59) + { 0, { 0, 0, 0}}, // ( 65, 59) + { 0, { 0, 0, 0}}, // ( 66, 59) + { 0, { 0, 0, 0}}, // ( 67, 59) + { 0, { 0, 0, 0}}, // ( 68, 59) + { 0, { 0, 0, 0}}, // ( 69, 59) + { 0, { 0, 0, 0}}, // ( 70, 59) + { 0, { 0, 0, 0}}, // ( 71, 59) + { 0, { 0, 0, 0}}, // ( 72, 59) + { 0, { 0, 0, 0}}, // ( 73, 59) + { 0, { 0, 0, 0}}, // ( 74, 59) + { 0, { 0, 0, 0}}, // ( 75, 59) + { 0, { 0, 0, 0}}, // ( 76, 59) + { 0, { 0, 0, 0}}, // ( 77, 59) + { 0, { 0, 0, 0}}, // ( 78, 59) + { 0, { 0, 0, 0}}, // ( 79, 59) + { 0, { 0, 0, 0}}, // ( 80, 59) + { 0, { 0, 0, 0}}, // ( 81, 59) + { 0, { 0, 0, 0}}, // ( 82, 59) + { 0, { 0, 0, 0}}, // ( 83, 59) + { 0, { 0, 0, 0}}, // ( 84, 59) + { 0, { 0, 0, 0}}, // ( 85, 59) + { 0, { 0, 0, 0}}, // ( 86, 59) + { 0, { 0, 0, 0}}, // ( 87, 59) + { 0, { 0, 0, 0}}, // ( 88, 59) + { 0, { 0, 0, 0}}, // ( 89, 59) + { 0, { 0, 0, 0}}, // ( 90, 59) + { 0, { 0, 0, 0}}, // ( 91, 59) + { 0, { 0, 0, 0}}, // ( 92, 59) + { 0, { 0, 0, 0}}, // ( 93, 59) + { 0, { 0, 0, 0}}, // ( 94, 59) + { 0, { 0, 0, 0}}, // ( 95, 59) + { 0, { 0, 0, 0}}, // ( 96, 59) + { 0, { 0, 0, 0}}, // ( 97, 59) + { 0, { 0, 0, 0}}, // ( 98, 59) + { 0, { 0, 0, 0}}, // ( 99, 59) + { 0, { 0, 0, 0}}, // (100, 59) + { 0, { 0, 0, 0}}, // (101, 59) + { 0, { 0, 0, 0}}, // (102, 59) + { 0, { 0, 0, 0}}, // (103, 59) + { 0, { 0, 0, 0}}, // (104, 59) + { 0, { 0, 0, 0}}, // (105, 59) + { 0, { 0, 0, 0}}, // (106, 59) + { 0, { 0, 0, 0}}, // (107, 59) + { 0, { 0, 0, 0}}, // (108, 59) + { 0, { 0, 0, 0}}, // (109, 59) + { 0, { 0, 0, 0}}, // (110, 59) + { 0, { 0, 0, 0}}, // (111, 59) + { 0, { 0, 0, 0}}, // (112, 59) + { 0, { 0, 0, 0}}, // (113, 59) + { 0, { 0, 0, 0}}, // (114, 59) + { 0, { 0, 0, 0}}, // (115, 59) + { 0, { 0, 0, 0}}, // (116, 59) + { 0, { 0, 0, 0}}, // (117, 59) + { 0, { 0, 0, 0}}, // (118, 59) + { 0, { 0, 0, 0}}, // (119, 59) + { 0, { 0, 0, 0}}, // (120, 59) + { 0, { 0, 0, 0}}, // (121, 59) + { 0, { 0, 0, 0}}, // (122, 59) + { 0, { 0, 0, 0}}, // (123, 59) + { 0, { 0, 0, 0}}, // (124, 59) + { 0, { 0, 0, 0}}, // (125, 59) + { 0, { 0, 0, 0}}, // (126, 59) + { 0, { 0, 0, 0}}, // (127, 59) + { 0, { 0, 0, 0}}, // (128, 59) + { 0, { 0, 0, 0}}, // (129, 59) + { 0, { 0, 0, 0}}, // (130, 59) + { 0, { 0, 0, 0}}, // (131, 59) + { 0, { 0, 0, 0}}, // (132, 59) + { 0, { 0, 0, 0}}, // (133, 59) + { 0, { 0, 0, 0}}, // (134, 59) + { 0, { 0, 0, 0}}, // (135, 59) + { 0, { 0, 0, 0}}, // (136, 59) + { 0, { 0, 0, 0}}, // (137, 59) + { 0, { 0, 0, 0}}, // (138, 59) + { 0, { 0, 0, 0}}, // (139, 59) + { 0, { 0, 0, 0}}, // (140, 59) + { 0, { 0, 0, 0}}, // (141, 59) + { 0, { 0, 0, 0}}, // (142, 59) + { 0, { 0, 0, 0}}, // (143, 59) + { 0, { 0, 0, 0}}, // (144, 59) + { 0, { 0, 0, 0}}, // (145, 59) + { 0, { 0, 0, 0}}, // (146, 59) + { 0, { 0, 0, 0}}, // (147, 59) + { 0, { 0, 0, 0}}, // (148, 59) + { 0, { 0, 0, 0}}, // (149, 59) + { 0, { 0, 0, 0}}, // (150, 59) + { 0, { 0, 0, 0}}, // (151, 59) + { 0, { 0, 0, 0}}, // (152, 59) + { 0, { 0, 0, 0}}, // (153, 59) + { 0, { 0, 0, 0}}, // (154, 59) + { 0, { 0, 0, 0}}, // (155, 59) + { 0, { 0, 0, 0}}, // (156, 59) + { 0, { 0, 0, 0}}, // (157, 59) + { 0, { 0, 0, 0}}, // (158, 59) + { 0, { 0, 0, 0}}, // (159, 59) + { 0, { 0, 0, 0}}, // (160, 59) + { 0, { 0, 0, 0}}, // (161, 59) + { 0, { 0, 0, 0}}, // (162, 59) + { 0, { 0, 0, 0}}, // (163, 59) + { 0, { 0, 0, 0}}, // (164, 59) + { 0, { 0, 0, 0}}, // (165, 59) + { 0, { 0, 0, 0}}, // (166, 59) + { 0, { 0, 0, 0}}, // (167, 59) + { 0, { 0, 0, 0}}, // (168, 59) + { 0, { 0, 0, 0}}, // (169, 59) + { 0, { 0, 0, 0}}, // (170, 59) + { 0, { 0, 0, 0}}, // (171, 59) + { 55, { 0, 0, 0}}, // (172, 59) + {128, { 0, 0, 0}}, // (173, 59) + {128, { 0, 0, 0}}, // (174, 59) + {128, { 0, 0, 0}}, // (175, 59) + {128, { 0, 0, 0}}, // (176, 59) + {128, { 0, 0, 0}}, // (177, 59) + {128, { 0, 0, 0}}, // (178, 59) + {128, { 0, 0, 0}}, // (179, 59) + {128, { 0, 0, 0}}, // ( 0, 60) + {128, { 0, 0, 0}}, // ( 1, 60) + {128, { 0, 0, 0}}, // ( 2, 60) + {128, { 0, 0, 0}}, // ( 3, 60) + {128, { 0, 0, 0}}, // ( 4, 60) + {128, { 0, 0, 0}}, // ( 5, 60) + {127, { 0, 0, 0}}, // ( 6, 60) + { 12, { 0, 0, 0}}, // ( 7, 60) + { 0, { 0, 0, 0}}, // ( 8, 60) + { 0, { 0, 0, 0}}, // ( 9, 60) + { 0, { 0, 0, 0}}, // ( 10, 60) + { 0, { 0, 0, 0}}, // ( 11, 60) + { 0, { 0, 0, 0}}, // ( 12, 60) + { 0, { 0, 0, 0}}, // ( 13, 60) + { 0, { 0, 0, 0}}, // ( 14, 60) + { 0, { 0, 0, 0}}, // ( 15, 60) + { 0, { 0, 0, 0}}, // ( 16, 60) + { 0, { 0, 0, 0}}, // ( 17, 60) + { 0, { 0, 0, 0}}, // ( 18, 60) + { 0, { 0, 0, 0}}, // ( 19, 60) + { 0, { 0, 0, 0}}, // ( 20, 60) + { 0, { 0, 0, 0}}, // ( 21, 60) + { 0, { 0, 0, 0}}, // ( 22, 60) + { 0, { 0, 0, 0}}, // ( 23, 60) + { 0, { 0, 0, 0}}, // ( 24, 60) + { 0, { 0, 0, 0}}, // ( 25, 60) + { 0, { 0, 0, 0}}, // ( 26, 60) + { 0, { 0, 0, 0}}, // ( 27, 60) + { 0, { 0, 0, 0}}, // ( 28, 60) + { 0, { 0, 0, 0}}, // ( 29, 60) + { 0, { 0, 0, 0}}, // ( 30, 60) + { 0, { 0, 0, 0}}, // ( 31, 60) + { 0, { 0, 0, 0}}, // ( 32, 60) + { 0, { 0, 0, 0}}, // ( 33, 60) + { 0, { 0, 0, 0}}, // ( 34, 60) + { 0, { 0, 0, 0}}, // ( 35, 60) + { 0, { 0, 0, 0}}, // ( 36, 60) + { 0, { 0, 0, 0}}, // ( 37, 60) + { 0, { 0, 0, 0}}, // ( 38, 60) + { 0, { 0, 0, 0}}, // ( 39, 60) + { 0, { 0, 0, 0}}, // ( 40, 60) + { 0, { 0, 0, 0}}, // ( 41, 60) + { 0, { 0, 0, 0}}, // ( 42, 60) + { 0, { 0, 0, 0}}, // ( 43, 60) + { 0, { 0, 0, 0}}, // ( 44, 60) + { 0, { 0, 0, 0}}, // ( 45, 60) + { 0, { 0, 0, 0}}, // ( 46, 60) + { 0, { 0, 0, 0}}, // ( 47, 60) + { 0, { 0, 0, 0}}, // ( 48, 60) + { 0, { 0, 0, 0}}, // ( 49, 60) + { 0, { 0, 0, 0}}, // ( 50, 60) + { 0, { 0, 0, 0}}, // ( 51, 60) + { 0, { 0, 0, 0}}, // ( 52, 60) + { 0, { 0, 0, 0}}, // ( 53, 60) + { 0, { 0, 0, 0}}, // ( 54, 60) + { 0, { 0, 0, 0}}, // ( 55, 60) + { 0, { 0, 0, 0}}, // ( 56, 60) + { 0, { 0, 0, 0}}, // ( 57, 60) + { 0, { 0, 0, 0}}, // ( 58, 60) + { 0, { 0, 0, 0}}, // ( 59, 60) + { 0, { 0, 0, 0}}, // ( 60, 60) + { 0, { 0, 0, 0}}, // ( 61, 60) + { 0, { 0, 0, 0}}, // ( 62, 60) + { 0, { 0, 0, 0}}, // ( 63, 60) + { 0, { 0, 0, 0}}, // ( 64, 60) + { 0, { 0, 0, 0}}, // ( 65, 60) + { 0, { 0, 0, 0}}, // ( 66, 60) + { 0, { 0, 0, 0}}, // ( 67, 60) + { 0, { 0, 0, 0}}, // ( 68, 60) + { 0, { 0, 0, 0}}, // ( 69, 60) + { 0, { 0, 0, 0}}, // ( 70, 60) + { 0, { 0, 0, 0}}, // ( 71, 60) + { 0, { 0, 0, 0}}, // ( 72, 60) + { 0, { 0, 0, 0}}, // ( 73, 60) + { 0, { 0, 0, 0}}, // ( 74, 60) + { 0, { 0, 0, 0}}, // ( 75, 60) + { 0, { 0, 0, 0}}, // ( 76, 60) + { 0, { 0, 0, 0}}, // ( 77, 60) + { 0, { 0, 0, 0}}, // ( 78, 60) + { 0, { 0, 0, 0}}, // ( 79, 60) + { 0, { 0, 0, 0}}, // ( 80, 60) + { 0, { 0, 0, 0}}, // ( 81, 60) + { 0, { 0, 0, 0}}, // ( 82, 60) + { 0, { 0, 0, 0}}, // ( 83, 60) + { 0, { 0, 0, 0}}, // ( 84, 60) + { 0, { 0, 0, 0}}, // ( 85, 60) + { 0, { 0, 0, 0}}, // ( 86, 60) + { 0, { 0, 0, 0}}, // ( 87, 60) + { 0, { 0, 0, 0}}, // ( 88, 60) + { 0, { 0, 0, 0}}, // ( 89, 60) + { 0, { 0, 0, 0}}, // ( 90, 60) + { 0, { 0, 0, 0}}, // ( 91, 60) + { 0, { 0, 0, 0}}, // ( 92, 60) + { 0, { 0, 0, 0}}, // ( 93, 60) + { 0, { 0, 0, 0}}, // ( 94, 60) + { 0, { 0, 0, 0}}, // ( 95, 60) + { 0, { 0, 0, 0}}, // ( 96, 60) + { 0, { 0, 0, 0}}, // ( 97, 60) + { 0, { 0, 0, 0}}, // ( 98, 60) + { 0, { 0, 0, 0}}, // ( 99, 60) + { 0, { 0, 0, 0}}, // (100, 60) + { 0, { 0, 0, 0}}, // (101, 60) + { 0, { 0, 0, 0}}, // (102, 60) + { 0, { 0, 0, 0}}, // (103, 60) + { 0, { 0, 0, 0}}, // (104, 60) + { 0, { 0, 0, 0}}, // (105, 60) + { 0, { 0, 0, 0}}, // (106, 60) + { 0, { 0, 0, 0}}, // (107, 60) + { 0, { 0, 0, 0}}, // (108, 60) + { 0, { 0, 0, 0}}, // (109, 60) + { 0, { 0, 0, 0}}, // (110, 60) + { 0, { 0, 0, 0}}, // (111, 60) + { 0, { 0, 0, 0}}, // (112, 60) + { 0, { 0, 0, 0}}, // (113, 60) + { 0, { 0, 0, 0}}, // (114, 60) + { 0, { 0, 0, 0}}, // (115, 60) + { 0, { 0, 0, 0}}, // (116, 60) + { 0, { 0, 0, 0}}, // (117, 60) + { 0, { 0, 0, 0}}, // (118, 60) + { 0, { 0, 0, 0}}, // (119, 60) + { 0, { 0, 0, 0}}, // (120, 60) + { 0, { 0, 0, 0}}, // (121, 60) + { 0, { 0, 0, 0}}, // (122, 60) + { 0, { 0, 0, 0}}, // (123, 60) + { 0, { 0, 0, 0}}, // (124, 60) + { 0, { 0, 0, 0}}, // (125, 60) + { 0, { 0, 0, 0}}, // (126, 60) + { 0, { 0, 0, 0}}, // (127, 60) + { 0, { 0, 0, 0}}, // (128, 60) + { 0, { 0, 0, 0}}, // (129, 60) + { 0, { 0, 0, 0}}, // (130, 60) + { 0, { 0, 0, 0}}, // (131, 60) + { 0, { 0, 0, 0}}, // (132, 60) + { 0, { 0, 0, 0}}, // (133, 60) + { 0, { 0, 0, 0}}, // (134, 60) + { 0, { 0, 0, 0}}, // (135, 60) + { 0, { 0, 0, 0}}, // (136, 60) + { 0, { 0, 0, 0}}, // (137, 60) + { 0, { 0, 0, 0}}, // (138, 60) + { 0, { 0, 0, 0}}, // (139, 60) + { 0, { 0, 0, 0}}, // (140, 60) + { 0, { 0, 0, 0}}, // (141, 60) + { 0, { 0, 0, 0}}, // (142, 60) + { 0, { 0, 0, 0}}, // (143, 60) + { 0, { 0, 0, 0}}, // (144, 60) + { 0, { 0, 0, 0}}, // (145, 60) + { 0, { 0, 0, 0}}, // (146, 60) + { 0, { 0, 0, 0}}, // (147, 60) + { 0, { 0, 0, 0}}, // (148, 60) + { 0, { 0, 0, 0}}, // (149, 60) + { 0, { 0, 0, 0}}, // (150, 60) + { 0, { 0, 0, 0}}, // (151, 60) + { 0, { 0, 0, 0}}, // (152, 60) + { 0, { 0, 0, 0}}, // (153, 60) + { 0, { 0, 0, 0}}, // (154, 60) + { 0, { 0, 0, 0}}, // (155, 60) + { 0, { 0, 0, 0}}, // (156, 60) + { 0, { 0, 0, 0}}, // (157, 60) + { 0, { 0, 0, 0}}, // (158, 60) + { 0, { 0, 0, 0}}, // (159, 60) + { 0, { 0, 0, 0}}, // (160, 60) + { 0, { 0, 0, 0}}, // (161, 60) + { 0, { 0, 0, 0}}, // (162, 60) + { 0, { 0, 0, 0}}, // (163, 60) + { 0, { 0, 0, 0}}, // (164, 60) + { 0, { 0, 0, 0}}, // (165, 60) + { 0, { 0, 0, 0}}, // (166, 60) + { 0, { 0, 0, 0}}, // (167, 60) + { 0, { 0, 0, 0}}, // (168, 60) + { 0, { 0, 0, 0}}, // (169, 60) + { 0, { 0, 0, 0}}, // (170, 60) + { 0, { 0, 0, 0}}, // (171, 60) + { 12, { 0, 0, 0}}, // (172, 60) + {126, { 0, 0, 0}}, // (173, 60) + {128, { 0, 0, 0}}, // (174, 60) + {128, { 0, 0, 0}}, // (175, 60) + {128, { 0, 0, 0}}, // (176, 60) + {128, { 0, 0, 0}}, // (177, 60) + {128, { 0, 0, 0}}, // (178, 60) + {128, { 0, 0, 0}}, // (179, 60) + {128, { 0, 0, 0}}, // ( 0, 61) + {128, { 0, 0, 0}}, // ( 1, 61) + {128, { 0, 0, 0}}, // ( 2, 61) + {128, { 0, 0, 0}}, // ( 3, 61) + {128, { 0, 0, 0}}, // ( 4, 61) + {128, { 0, 0, 0}}, // ( 5, 61) + { 95, { 0, 0, 0}}, // ( 6, 61) + { 0, { 0, 0, 0}}, // ( 7, 61) + { 0, { 0, 0, 0}}, // ( 8, 61) + { 0, { 0, 0, 0}}, // ( 9, 61) + { 0, { 0, 0, 0}}, // ( 10, 61) + { 0, { 0, 0, 0}}, // ( 11, 61) + { 0, { 0, 0, 0}}, // ( 12, 61) + { 0, { 0, 0, 0}}, // ( 13, 61) + { 0, { 0, 0, 0}}, // ( 14, 61) + { 0, { 0, 0, 0}}, // ( 15, 61) + { 0, { 0, 0, 0}}, // ( 16, 61) + { 0, { 0, 0, 0}}, // ( 17, 61) + { 0, { 0, 0, 0}}, // ( 18, 61) + { 0, { 0, 0, 0}}, // ( 19, 61) + { 0, { 0, 0, 0}}, // ( 20, 61) + { 0, { 0, 0, 0}}, // ( 21, 61) + { 0, { 0, 0, 0}}, // ( 22, 61) + { 0, { 0, 0, 0}}, // ( 23, 61) + { 0, { 0, 0, 0}}, // ( 24, 61) + { 0, { 0, 0, 0}}, // ( 25, 61) + { 0, { 0, 0, 0}}, // ( 26, 61) + { 0, { 0, 0, 0}}, // ( 27, 61) + { 0, { 0, 0, 0}}, // ( 28, 61) + { 0, { 0, 0, 0}}, // ( 29, 61) + { 0, { 0, 0, 0}}, // ( 30, 61) + { 0, { 0, 0, 0}}, // ( 31, 61) + { 0, { 0, 0, 0}}, // ( 32, 61) + { 0, { 0, 0, 0}}, // ( 33, 61) + { 0, { 0, 0, 0}}, // ( 34, 61) + { 0, { 0, 0, 0}}, // ( 35, 61) + { 0, { 0, 0, 0}}, // ( 36, 61) + { 0, { 0, 0, 0}}, // ( 37, 61) + { 0, { 0, 0, 0}}, // ( 38, 61) + { 0, { 0, 0, 0}}, // ( 39, 61) + { 0, { 0, 0, 0}}, // ( 40, 61) + { 0, { 0, 0, 0}}, // ( 41, 61) + { 0, { 0, 0, 0}}, // ( 42, 61) + { 0, { 0, 0, 0}}, // ( 43, 61) + { 0, { 0, 0, 0}}, // ( 44, 61) + { 0, { 0, 0, 0}}, // ( 45, 61) + { 0, { 0, 0, 0}}, // ( 46, 61) + { 0, { 0, 0, 0}}, // ( 47, 61) + { 0, { 0, 0, 0}}, // ( 48, 61) + { 0, { 0, 0, 0}}, // ( 49, 61) + { 0, { 0, 0, 0}}, // ( 50, 61) + { 0, { 0, 0, 0}}, // ( 51, 61) + { 0, { 0, 0, 0}}, // ( 52, 61) + { 0, { 0, 0, 0}}, // ( 53, 61) + { 0, { 0, 0, 0}}, // ( 54, 61) + { 0, { 0, 0, 0}}, // ( 55, 61) + { 0, { 0, 0, 0}}, // ( 56, 61) + { 0, { 0, 0, 0}}, // ( 57, 61) + { 0, { 0, 0, 0}}, // ( 58, 61) + { 0, { 0, 0, 0}}, // ( 59, 61) + { 0, { 0, 0, 0}}, // ( 60, 61) + { 0, { 0, 0, 0}}, // ( 61, 61) + { 0, { 0, 0, 0}}, // ( 62, 61) + { 0, { 0, 0, 0}}, // ( 63, 61) + { 0, { 0, 0, 0}}, // ( 64, 61) + { 0, { 0, 0, 0}}, // ( 65, 61) + { 0, { 0, 0, 0}}, // ( 66, 61) + { 0, { 0, 0, 0}}, // ( 67, 61) + { 0, { 0, 0, 0}}, // ( 68, 61) + { 0, { 0, 0, 0}}, // ( 69, 61) + { 0, { 0, 0, 0}}, // ( 70, 61) + { 0, { 0, 0, 0}}, // ( 71, 61) + { 0, { 0, 0, 0}}, // ( 72, 61) + { 0, { 0, 0, 0}}, // ( 73, 61) + { 0, { 0, 0, 0}}, // ( 74, 61) + { 0, { 0, 0, 0}}, // ( 75, 61) + { 0, { 0, 0, 0}}, // ( 76, 61) + { 0, { 0, 0, 0}}, // ( 77, 61) + { 0, { 0, 0, 0}}, // ( 78, 61) + { 0, { 0, 0, 0}}, // ( 79, 61) + { 0, { 0, 0, 0}}, // ( 80, 61) + { 0, { 0, 0, 0}}, // ( 81, 61) + { 0, { 0, 0, 0}}, // ( 82, 61) + { 0, { 0, 0, 0}}, // ( 83, 61) + { 0, { 0, 0, 0}}, // ( 84, 61) + { 0, { 0, 0, 0}}, // ( 85, 61) + { 0, { 0, 0, 0}}, // ( 86, 61) + { 0, { 0, 0, 0}}, // ( 87, 61) + { 0, { 0, 0, 0}}, // ( 88, 61) + { 0, { 0, 0, 0}}, // ( 89, 61) + { 0, { 0, 0, 0}}, // ( 90, 61) + { 0, { 0, 0, 0}}, // ( 91, 61) + { 0, { 0, 0, 0}}, // ( 92, 61) + { 0, { 0, 0, 0}}, // ( 93, 61) + { 0, { 0, 0, 0}}, // ( 94, 61) + { 0, { 0, 0, 0}}, // ( 95, 61) + { 0, { 0, 0, 0}}, // ( 96, 61) + { 0, { 0, 0, 0}}, // ( 97, 61) + { 0, { 0, 0, 0}}, // ( 98, 61) + { 0, { 0, 0, 0}}, // ( 99, 61) + { 0, { 0, 0, 0}}, // (100, 61) + { 0, { 0, 0, 0}}, // (101, 61) + { 0, { 0, 0, 0}}, // (102, 61) + { 0, { 0, 0, 0}}, // (103, 61) + { 0, { 0, 0, 0}}, // (104, 61) + { 0, { 0, 0, 0}}, // (105, 61) + { 0, { 0, 0, 0}}, // (106, 61) + { 0, { 0, 0, 0}}, // (107, 61) + { 0, { 0, 0, 0}}, // (108, 61) + { 0, { 0, 0, 0}}, // (109, 61) + { 0, { 0, 0, 0}}, // (110, 61) + { 0, { 0, 0, 0}}, // (111, 61) + { 0, { 0, 0, 0}}, // (112, 61) + { 0, { 0, 0, 0}}, // (113, 61) + { 0, { 0, 0, 0}}, // (114, 61) + { 0, { 0, 0, 0}}, // (115, 61) + { 0, { 0, 0, 0}}, // (116, 61) + { 0, { 0, 0, 0}}, // (117, 61) + { 0, { 0, 0, 0}}, // (118, 61) + { 0, { 0, 0, 0}}, // (119, 61) + { 0, { 0, 0, 0}}, // (120, 61) + { 0, { 0, 0, 0}}, // (121, 61) + { 0, { 0, 0, 0}}, // (122, 61) + { 0, { 0, 0, 0}}, // (123, 61) + { 0, { 0, 0, 0}}, // (124, 61) + { 0, { 0, 0, 0}}, // (125, 61) + { 0, { 0, 0, 0}}, // (126, 61) + { 0, { 0, 0, 0}}, // (127, 61) + { 0, { 0, 0, 0}}, // (128, 61) + { 0, { 0, 0, 0}}, // (129, 61) + { 0, { 0, 0, 0}}, // (130, 61) + { 0, { 0, 0, 0}}, // (131, 61) + { 0, { 0, 0, 0}}, // (132, 61) + { 0, { 0, 0, 0}}, // (133, 61) + { 0, { 0, 0, 0}}, // (134, 61) + { 0, { 0, 0, 0}}, // (135, 61) + { 0, { 0, 0, 0}}, // (136, 61) + { 0, { 0, 0, 0}}, // (137, 61) + { 0, { 0, 0, 0}}, // (138, 61) + { 0, { 0, 0, 0}}, // (139, 61) + { 0, { 0, 0, 0}}, // (140, 61) + { 0, { 0, 0, 0}}, // (141, 61) + { 0, { 0, 0, 0}}, // (142, 61) + { 0, { 0, 0, 0}}, // (143, 61) + { 0, { 0, 0, 0}}, // (144, 61) + { 0, { 0, 0, 0}}, // (145, 61) + { 0, { 0, 0, 0}}, // (146, 61) + { 0, { 0, 0, 0}}, // (147, 61) + { 0, { 0, 0, 0}}, // (148, 61) + { 0, { 0, 0, 0}}, // (149, 61) + { 0, { 0, 0, 0}}, // (150, 61) + { 0, { 0, 0, 0}}, // (151, 61) + { 0, { 0, 0, 0}}, // (152, 61) + { 0, { 0, 0, 0}}, // (153, 61) + { 0, { 0, 0, 0}}, // (154, 61) + { 0, { 0, 0, 0}}, // (155, 61) + { 0, { 0, 0, 0}}, // (156, 61) + { 0, { 0, 0, 0}}, // (157, 61) + { 0, { 0, 0, 0}}, // (158, 61) + { 0, { 0, 0, 0}}, // (159, 61) + { 0, { 0, 0, 0}}, // (160, 61) + { 0, { 0, 0, 0}}, // (161, 61) + { 0, { 0, 0, 0}}, // (162, 61) + { 0, { 0, 0, 0}}, // (163, 61) + { 0, { 0, 0, 0}}, // (164, 61) + { 0, { 0, 0, 0}}, // (165, 61) + { 0, { 0, 0, 0}}, // (166, 61) + { 0, { 0, 0, 0}}, // (167, 61) + { 0, { 0, 0, 0}}, // (168, 61) + { 0, { 0, 0, 0}}, // (169, 61) + { 0, { 0, 0, 0}}, // (170, 61) + { 0, { 0, 0, 0}}, // (171, 61) + { 0, { 0, 0, 0}}, // (172, 61) + { 95, { 0, 0, 0}}, // (173, 61) + {128, { 0, 0, 0}}, // (174, 61) + {128, { 0, 0, 0}}, // (175, 61) + {128, { 0, 0, 0}}, // (176, 61) + {128, { 0, 0, 0}}, // (177, 61) + {128, { 0, 0, 0}}, // (178, 61) + {128, { 0, 0, 0}}, // (179, 61) + {128, { 0, 0, 0}}, // ( 0, 62) + {128, { 0, 0, 0}}, // ( 1, 62) + {128, { 0, 0, 0}}, // ( 2, 62) + {128, { 0, 0, 0}}, // ( 3, 62) + {128, { 0, 0, 0}}, // ( 4, 62) + {128, { 0, 0, 0}}, // ( 5, 62) + { 52, { 0, 0, 0}}, // ( 6, 62) + { 0, { 0, 0, 0}}, // ( 7, 62) + { 0, { 0, 0, 0}}, // ( 8, 62) + { 0, { 0, 0, 0}}, // ( 9, 62) + { 0, { 0, 0, 0}}, // ( 10, 62) + { 0, { 0, 0, 0}}, // ( 11, 62) + { 0, { 0, 0, 0}}, // ( 12, 62) + { 0, { 0, 0, 0}}, // ( 13, 62) + { 0, { 0, 0, 0}}, // ( 14, 62) + { 0, { 0, 0, 0}}, // ( 15, 62) + { 0, { 0, 0, 0}}, // ( 16, 62) + { 0, { 0, 0, 0}}, // ( 17, 62) + { 0, { 0, 0, 0}}, // ( 18, 62) + { 0, { 0, 0, 0}}, // ( 19, 62) + { 0, { 0, 0, 0}}, // ( 20, 62) + { 0, { 0, 0, 0}}, // ( 21, 62) + { 0, { 0, 0, 0}}, // ( 22, 62) + { 0, { 0, 0, 0}}, // ( 23, 62) + { 0, { 0, 0, 0}}, // ( 24, 62) + { 0, { 0, 0, 0}}, // ( 25, 62) + { 0, { 0, 0, 0}}, // ( 26, 62) + { 0, { 0, 0, 0}}, // ( 27, 62) + { 0, { 0, 0, 0}}, // ( 28, 62) + { 0, { 0, 0, 0}}, // ( 29, 62) + { 0, { 0, 0, 0}}, // ( 30, 62) + { 0, { 0, 0, 0}}, // ( 31, 62) + { 0, { 0, 0, 0}}, // ( 32, 62) + { 0, { 0, 0, 0}}, // ( 33, 62) + { 0, { 0, 0, 0}}, // ( 34, 62) + { 0, { 0, 0, 0}}, // ( 35, 62) + { 0, { 0, 0, 0}}, // ( 36, 62) + { 0, { 0, 0, 0}}, // ( 37, 62) + { 0, { 0, 0, 0}}, // ( 38, 62) + { 0, { 0, 0, 0}}, // ( 39, 62) + { 0, { 0, 0, 0}}, // ( 40, 62) + { 0, { 0, 0, 0}}, // ( 41, 62) + { 0, { 0, 0, 0}}, // ( 42, 62) + { 0, { 0, 0, 0}}, // ( 43, 62) + { 0, { 0, 0, 0}}, // ( 44, 62) + { 0, { 0, 0, 0}}, // ( 45, 62) + { 0, { 0, 0, 0}}, // ( 46, 62) + { 0, { 0, 0, 0}}, // ( 47, 62) + { 0, { 0, 0, 0}}, // ( 48, 62) + { 0, { 0, 0, 0}}, // ( 49, 62) + { 0, { 0, 0, 0}}, // ( 50, 62) + { 0, { 0, 0, 0}}, // ( 51, 62) + { 0, { 0, 0, 0}}, // ( 52, 62) + { 0, { 0, 0, 0}}, // ( 53, 62) + { 0, { 0, 0, 0}}, // ( 54, 62) + { 0, { 0, 0, 0}}, // ( 55, 62) + { 0, { 0, 0, 0}}, // ( 56, 62) + { 0, { 0, 0, 0}}, // ( 57, 62) + { 0, { 0, 0, 0}}, // ( 58, 62) + { 0, { 0, 0, 0}}, // ( 59, 62) + { 0, { 0, 0, 0}}, // ( 60, 62) + { 0, { 0, 0, 0}}, // ( 61, 62) + { 0, { 0, 0, 0}}, // ( 62, 62) + { 0, { 0, 0, 0}}, // ( 63, 62) + { 0, { 0, 0, 0}}, // ( 64, 62) + { 0, { 0, 0, 0}}, // ( 65, 62) + { 0, { 0, 0, 0}}, // ( 66, 62) + { 0, { 0, 0, 0}}, // ( 67, 62) + { 0, { 0, 0, 0}}, // ( 68, 62) + { 0, { 0, 0, 0}}, // ( 69, 62) + { 0, { 0, 0, 0}}, // ( 70, 62) + { 0, { 0, 0, 0}}, // ( 71, 62) + { 0, { 0, 0, 0}}, // ( 72, 62) + { 0, { 0, 0, 0}}, // ( 73, 62) + { 0, { 0, 0, 0}}, // ( 74, 62) + { 0, { 0, 0, 0}}, // ( 75, 62) + { 0, { 0, 0, 0}}, // ( 76, 62) + { 0, { 0, 0, 0}}, // ( 77, 62) + { 0, { 0, 0, 0}}, // ( 78, 62) + { 0, { 0, 0, 0}}, // ( 79, 62) + { 0, { 0, 0, 0}}, // ( 80, 62) + { 0, { 0, 0, 0}}, // ( 81, 62) + { 0, { 0, 0, 0}}, // ( 82, 62) + { 0, { 0, 0, 0}}, // ( 83, 62) + { 0, { 0, 0, 0}}, // ( 84, 62) + { 0, { 0, 0, 0}}, // ( 85, 62) + { 0, { 0, 0, 0}}, // ( 86, 62) + { 0, { 0, 0, 0}}, // ( 87, 62) + { 0, { 0, 0, 0}}, // ( 88, 62) + { 0, { 0, 0, 0}}, // ( 89, 62) + { 0, { 0, 0, 0}}, // ( 90, 62) + { 0, { 0, 0, 0}}, // ( 91, 62) + { 0, { 0, 0, 0}}, // ( 92, 62) + { 0, { 0, 0, 0}}, // ( 93, 62) + { 0, { 0, 0, 0}}, // ( 94, 62) + { 0, { 0, 0, 0}}, // ( 95, 62) + { 0, { 0, 0, 0}}, // ( 96, 62) + { 0, { 0, 0, 0}}, // ( 97, 62) + { 0, { 0, 0, 0}}, // ( 98, 62) + { 0, { 0, 0, 0}}, // ( 99, 62) + { 0, { 0, 0, 0}}, // (100, 62) + { 0, { 0, 0, 0}}, // (101, 62) + { 0, { 0, 0, 0}}, // (102, 62) + { 0, { 0, 0, 0}}, // (103, 62) + { 0, { 0, 0, 0}}, // (104, 62) + { 0, { 0, 0, 0}}, // (105, 62) + { 0, { 0, 0, 0}}, // (106, 62) + { 0, { 0, 0, 0}}, // (107, 62) + { 0, { 0, 0, 0}}, // (108, 62) + { 0, { 0, 0, 0}}, // (109, 62) + { 0, { 0, 0, 0}}, // (110, 62) + { 0, { 0, 0, 0}}, // (111, 62) + { 0, { 0, 0, 0}}, // (112, 62) + { 0, { 0, 0, 0}}, // (113, 62) + { 0, { 0, 0, 0}}, // (114, 62) + { 0, { 0, 0, 0}}, // (115, 62) + { 0, { 0, 0, 0}}, // (116, 62) + { 0, { 0, 0, 0}}, // (117, 62) + { 0, { 0, 0, 0}}, // (118, 62) + { 0, { 0, 0, 0}}, // (119, 62) + { 0, { 0, 0, 0}}, // (120, 62) + { 0, { 0, 0, 0}}, // (121, 62) + { 0, { 0, 0, 0}}, // (122, 62) + { 0, { 0, 0, 0}}, // (123, 62) + { 0, { 0, 0, 0}}, // (124, 62) + { 0, { 0, 0, 0}}, // (125, 62) + { 0, { 0, 0, 0}}, // (126, 62) + { 0, { 0, 0, 0}}, // (127, 62) + { 0, { 0, 0, 0}}, // (128, 62) + { 0, { 0, 0, 0}}, // (129, 62) + { 0, { 0, 0, 0}}, // (130, 62) + { 0, { 0, 0, 0}}, // (131, 62) + { 0, { 0, 0, 0}}, // (132, 62) + { 0, { 0, 0, 0}}, // (133, 62) + { 0, { 0, 0, 0}}, // (134, 62) + { 0, { 0, 0, 0}}, // (135, 62) + { 0, { 0, 0, 0}}, // (136, 62) + { 0, { 0, 0, 0}}, // (137, 62) + { 0, { 0, 0, 0}}, // (138, 62) + { 0, { 0, 0, 0}}, // (139, 62) + { 0, { 0, 0, 0}}, // (140, 62) + { 0, { 0, 0, 0}}, // (141, 62) + { 0, { 0, 0, 0}}, // (142, 62) + { 0, { 0, 0, 0}}, // (143, 62) + { 0, { 0, 0, 0}}, // (144, 62) + { 0, { 0, 0, 0}}, // (145, 62) + { 0, { 0, 0, 0}}, // (146, 62) + { 0, { 0, 0, 0}}, // (147, 62) + { 0, { 0, 0, 0}}, // (148, 62) + { 0, { 0, 0, 0}}, // (149, 62) + { 0, { 0, 0, 0}}, // (150, 62) + { 0, { 0, 0, 0}}, // (151, 62) + { 0, { 0, 0, 0}}, // (152, 62) + { 0, { 0, 0, 0}}, // (153, 62) + { 0, { 0, 0, 0}}, // (154, 62) + { 0, { 0, 0, 0}}, // (155, 62) + { 0, { 0, 0, 0}}, // (156, 62) + { 0, { 0, 0, 0}}, // (157, 62) + { 0, { 0, 0, 0}}, // (158, 62) + { 0, { 0, 0, 0}}, // (159, 62) + { 0, { 0, 0, 0}}, // (160, 62) + { 0, { 0, 0, 0}}, // (161, 62) + { 0, { 0, 0, 0}}, // (162, 62) + { 0, { 0, 0, 0}}, // (163, 62) + { 0, { 0, 0, 0}}, // (164, 62) + { 0, { 0, 0, 0}}, // (165, 62) + { 0, { 0, 0, 0}}, // (166, 62) + { 0, { 0, 0, 0}}, // (167, 62) + { 0, { 0, 0, 0}}, // (168, 62) + { 0, { 0, 0, 0}}, // (169, 62) + { 0, { 0, 0, 0}}, // (170, 62) + { 0, { 0, 0, 0}}, // (171, 62) + { 0, { 0, 0, 0}}, // (172, 62) + { 52, { 0, 0, 0}}, // (173, 62) + {128, { 0, 0, 0}}, // (174, 62) + {128, { 0, 0, 0}}, // (175, 62) + {128, { 0, 0, 0}}, // (176, 62) + {128, { 0, 0, 0}}, // (177, 62) + {128, { 0, 0, 0}}, // (178, 62) + {128, { 0, 0, 0}}, // (179, 62) + {128, { 0, 0, 0}}, // ( 0, 63) + {128, { 0, 0, 0}}, // ( 1, 63) + {128, { 0, 0, 0}}, // ( 2, 63) + {128, { 0, 0, 0}}, // ( 3, 63) + {128, { 0, 0, 0}}, // ( 4, 63) + {126, { 0, 0, 0}}, // ( 5, 63) + { 11, { 0, 0, 0}}, // ( 6, 63) + { 0, { 0, 0, 0}}, // ( 7, 63) + { 0, { 0, 0, 0}}, // ( 8, 63) + { 0, { 0, 0, 0}}, // ( 9, 63) + { 0, { 0, 0, 0}}, // ( 10, 63) + { 0, { 0, 0, 0}}, // ( 11, 63) + { 0, { 0, 0, 0}}, // ( 12, 63) + { 0, { 0, 0, 0}}, // ( 13, 63) + { 0, { 0, 0, 0}}, // ( 14, 63) + { 0, { 0, 0, 0}}, // ( 15, 63) + { 0, { 0, 0, 0}}, // ( 16, 63) + { 0, { 0, 0, 0}}, // ( 17, 63) + { 0, { 0, 0, 0}}, // ( 18, 63) + { 0, { 0, 0, 0}}, // ( 19, 63) + { 0, { 0, 0, 0}}, // ( 20, 63) + { 0, { 0, 0, 0}}, // ( 21, 63) + { 0, { 0, 0, 0}}, // ( 22, 63) + { 0, { 0, 0, 0}}, // ( 23, 63) + { 0, { 0, 0, 0}}, // ( 24, 63) + { 0, { 0, 0, 0}}, // ( 25, 63) + { 0, { 0, 0, 0}}, // ( 26, 63) + { 0, { 0, 0, 0}}, // ( 27, 63) + { 0, { 0, 0, 0}}, // ( 28, 63) + { 0, { 0, 0, 0}}, // ( 29, 63) + { 0, { 0, 0, 0}}, // ( 30, 63) + { 0, { 0, 0, 0}}, // ( 31, 63) + { 0, { 0, 0, 0}}, // ( 32, 63) + { 0, { 0, 0, 0}}, // ( 33, 63) + { 0, { 0, 0, 0}}, // ( 34, 63) + { 0, { 0, 0, 0}}, // ( 35, 63) + { 0, { 0, 0, 0}}, // ( 36, 63) + { 0, { 0, 0, 0}}, // ( 37, 63) + { 0, { 0, 0, 0}}, // ( 38, 63) + { 0, { 0, 0, 0}}, // ( 39, 63) + { 0, { 0, 0, 0}}, // ( 40, 63) + { 0, { 0, 0, 0}}, // ( 41, 63) + { 0, { 0, 0, 0}}, // ( 42, 63) + { 0, { 0, 0, 0}}, // ( 43, 63) + { 0, { 0, 0, 0}}, // ( 44, 63) + { 0, { 0, 0, 0}}, // ( 45, 63) + { 0, { 0, 0, 0}}, // ( 46, 63) + { 0, { 0, 0, 0}}, // ( 47, 63) + { 0, { 0, 0, 0}}, // ( 48, 63) + { 0, { 0, 0, 0}}, // ( 49, 63) + { 0, { 0, 0, 0}}, // ( 50, 63) + { 0, { 0, 0, 0}}, // ( 51, 63) + { 0, { 0, 0, 0}}, // ( 52, 63) + { 0, { 0, 0, 0}}, // ( 53, 63) + { 0, { 0, 0, 0}}, // ( 54, 63) + { 0, { 0, 0, 0}}, // ( 55, 63) + { 0, { 0, 0, 0}}, // ( 56, 63) + { 0, { 0, 0, 0}}, // ( 57, 63) + { 0, { 0, 0, 0}}, // ( 58, 63) + { 0, { 0, 0, 0}}, // ( 59, 63) + { 0, { 0, 0, 0}}, // ( 60, 63) + { 0, { 0, 0, 0}}, // ( 61, 63) + { 0, { 0, 0, 0}}, // ( 62, 63) + { 0, { 0, 0, 0}}, // ( 63, 63) + { 0, { 0, 0, 0}}, // ( 64, 63) + { 0, { 0, 0, 0}}, // ( 65, 63) + { 0, { 0, 0, 0}}, // ( 66, 63) + { 0, { 0, 0, 0}}, // ( 67, 63) + { 0, { 0, 0, 0}}, // ( 68, 63) + { 0, { 0, 0, 0}}, // ( 69, 63) + { 0, { 0, 0, 0}}, // ( 70, 63) + { 0, { 0, 0, 0}}, // ( 71, 63) + { 0, { 0, 0, 0}}, // ( 72, 63) + { 0, { 0, 0, 0}}, // ( 73, 63) + { 0, { 0, 0, 0}}, // ( 74, 63) + { 0, { 0, 0, 0}}, // ( 75, 63) + { 0, { 0, 0, 0}}, // ( 76, 63) + { 0, { 0, 0, 0}}, // ( 77, 63) + { 0, { 0, 0, 0}}, // ( 78, 63) + { 0, { 0, 0, 0}}, // ( 79, 63) + { 0, { 0, 0, 0}}, // ( 80, 63) + { 0, { 0, 0, 0}}, // ( 81, 63) + { 0, { 0, 0, 0}}, // ( 82, 63) + { 0, { 0, 0, 0}}, // ( 83, 63) + { 0, { 0, 0, 0}}, // ( 84, 63) + { 0, { 0, 0, 0}}, // ( 85, 63) + { 0, { 0, 0, 0}}, // ( 86, 63) + { 0, { 0, 0, 0}}, // ( 87, 63) + { 0, { 0, 0, 0}}, // ( 88, 63) + { 0, { 0, 0, 0}}, // ( 89, 63) + { 0, { 0, 0, 0}}, // ( 90, 63) + { 0, { 0, 0, 0}}, // ( 91, 63) + { 0, { 0, 0, 0}}, // ( 92, 63) + { 0, { 0, 0, 0}}, // ( 93, 63) + { 0, { 0, 0, 0}}, // ( 94, 63) + { 0, { 0, 0, 0}}, // ( 95, 63) + { 0, { 0, 0, 0}}, // ( 96, 63) + { 0, { 0, 0, 0}}, // ( 97, 63) + { 0, { 0, 0, 0}}, // ( 98, 63) + { 0, { 0, 0, 0}}, // ( 99, 63) + { 0, { 0, 0, 0}}, // (100, 63) + { 0, { 0, 0, 0}}, // (101, 63) + { 0, { 0, 0, 0}}, // (102, 63) + { 0, { 0, 0, 0}}, // (103, 63) + { 0, { 0, 0, 0}}, // (104, 63) + { 0, { 0, 0, 0}}, // (105, 63) + { 0, { 0, 0, 0}}, // (106, 63) + { 0, { 0, 0, 0}}, // (107, 63) + { 0, { 0, 0, 0}}, // (108, 63) + { 0, { 0, 0, 0}}, // (109, 63) + { 0, { 0, 0, 0}}, // (110, 63) + { 0, { 0, 0, 0}}, // (111, 63) + { 0, { 0, 0, 0}}, // (112, 63) + { 0, { 0, 0, 0}}, // (113, 63) + { 0, { 0, 0, 0}}, // (114, 63) + { 0, { 0, 0, 0}}, // (115, 63) + { 0, { 0, 0, 0}}, // (116, 63) + { 0, { 0, 0, 0}}, // (117, 63) + { 0, { 0, 0, 0}}, // (118, 63) + { 0, { 0, 0, 0}}, // (119, 63) + { 0, { 0, 0, 0}}, // (120, 63) + { 0, { 0, 0, 0}}, // (121, 63) + { 0, { 0, 0, 0}}, // (122, 63) + { 0, { 0, 0, 0}}, // (123, 63) + { 0, { 0, 0, 0}}, // (124, 63) + { 0, { 0, 0, 0}}, // (125, 63) + { 0, { 0, 0, 0}}, // (126, 63) + { 0, { 0, 0, 0}}, // (127, 63) + { 0, { 0, 0, 0}}, // (128, 63) + { 0, { 0, 0, 0}}, // (129, 63) + { 0, { 0, 0, 0}}, // (130, 63) + { 0, { 0, 0, 0}}, // (131, 63) + { 0, { 0, 0, 0}}, // (132, 63) + { 0, { 0, 0, 0}}, // (133, 63) + { 0, { 0, 0, 0}}, // (134, 63) + { 0, { 0, 0, 0}}, // (135, 63) + { 0, { 0, 0, 0}}, // (136, 63) + { 0, { 0, 0, 0}}, // (137, 63) + { 0, { 0, 0, 0}}, // (138, 63) + { 0, { 0, 0, 0}}, // (139, 63) + { 0, { 0, 0, 0}}, // (140, 63) + { 0, { 0, 0, 0}}, // (141, 63) + { 0, { 0, 0, 0}}, // (142, 63) + { 0, { 0, 0, 0}}, // (143, 63) + { 0, { 0, 0, 0}}, // (144, 63) + { 0, { 0, 0, 0}}, // (145, 63) + { 0, { 0, 0, 0}}, // (146, 63) + { 0, { 0, 0, 0}}, // (147, 63) + { 0, { 0, 0, 0}}, // (148, 63) + { 0, { 0, 0, 0}}, // (149, 63) + { 0, { 0, 0, 0}}, // (150, 63) + { 0, { 0, 0, 0}}, // (151, 63) + { 0, { 0, 0, 0}}, // (152, 63) + { 0, { 0, 0, 0}}, // (153, 63) + { 0, { 0, 0, 0}}, // (154, 63) + { 0, { 0, 0, 0}}, // (155, 63) + { 0, { 0, 0, 0}}, // (156, 63) + { 0, { 0, 0, 0}}, // (157, 63) + { 0, { 0, 0, 0}}, // (158, 63) + { 0, { 0, 0, 0}}, // (159, 63) + { 0, { 0, 0, 0}}, // (160, 63) + { 0, { 0, 0, 0}}, // (161, 63) + { 0, { 0, 0, 0}}, // (162, 63) + { 0, { 0, 0, 0}}, // (163, 63) + { 0, { 0, 0, 0}}, // (164, 63) + { 0, { 0, 0, 0}}, // (165, 63) + { 0, { 0, 0, 0}}, // (166, 63) + { 0, { 0, 0, 0}}, // (167, 63) + { 0, { 0, 0, 0}}, // (168, 63) + { 0, { 0, 0, 0}}, // (169, 63) + { 0, { 0, 0, 0}}, // (170, 63) + { 0, { 0, 0, 0}}, // (171, 63) + { 0, { 0, 0, 0}}, // (172, 63) + { 11, { 0, 0, 0}}, // (173, 63) + {126, { 0, 0, 0}}, // (174, 63) + {128, { 0, 0, 0}}, // (175, 63) + {128, { 0, 0, 0}}, // (176, 63) + {128, { 0, 0, 0}}, // (177, 63) + {128, { 0, 0, 0}}, // (178, 63) + {128, { 0, 0, 0}}, // (179, 63) + {128, { 0, 0, 0}}, // ( 0, 64) + {128, { 0, 0, 0}}, // ( 1, 64) + {128, { 0, 0, 0}}, // ( 2, 64) + {128, { 0, 0, 0}}, // ( 3, 64) + {128, { 0, 0, 0}}, // ( 4, 64) + { 98, { 0, 0, 0}}, // ( 5, 64) + { 0, { 0, 0, 0}}, // ( 6, 64) + { 0, { 0, 0, 0}}, // ( 7, 64) + { 0, { 0, 0, 0}}, // ( 8, 64) + { 0, { 0, 0, 0}}, // ( 9, 64) + { 0, { 0, 0, 0}}, // ( 10, 64) + { 0, { 0, 0, 0}}, // ( 11, 64) + { 0, { 0, 0, 0}}, // ( 12, 64) + { 0, { 0, 0, 0}}, // ( 13, 64) + { 0, { 0, 0, 0}}, // ( 14, 64) + { 0, { 0, 0, 0}}, // ( 15, 64) + { 0, { 0, 0, 0}}, // ( 16, 64) + { 0, { 0, 0, 0}}, // ( 17, 64) + { 0, { 0, 0, 0}}, // ( 18, 64) + { 0, { 0, 0, 0}}, // ( 19, 64) + { 0, { 0, 0, 0}}, // ( 20, 64) + { 0, { 0, 0, 0}}, // ( 21, 64) + { 0, { 0, 0, 0}}, // ( 22, 64) + { 0, { 0, 0, 0}}, // ( 23, 64) + { 0, { 0, 0, 0}}, // ( 24, 64) + { 0, { 0, 0, 0}}, // ( 25, 64) + { 0, { 0, 0, 0}}, // ( 26, 64) + { 0, { 0, 0, 0}}, // ( 27, 64) + { 0, { 0, 0, 0}}, // ( 28, 64) + { 0, { 0, 0, 0}}, // ( 29, 64) + { 0, { 0, 0, 0}}, // ( 30, 64) + { 0, { 0, 0, 0}}, // ( 31, 64) + { 0, { 0, 0, 0}}, // ( 32, 64) + { 0, { 0, 0, 0}}, // ( 33, 64) + { 0, { 0, 0, 0}}, // ( 34, 64) + { 0, { 0, 0, 0}}, // ( 35, 64) + { 0, { 0, 0, 0}}, // ( 36, 64) + { 0, { 0, 0, 0}}, // ( 37, 64) + { 0, { 0, 0, 0}}, // ( 38, 64) + { 0, { 0, 0, 0}}, // ( 39, 64) + { 0, { 0, 0, 0}}, // ( 40, 64) + { 0, { 0, 0, 0}}, // ( 41, 64) + { 0, { 0, 0, 0}}, // ( 42, 64) + { 0, { 0, 0, 0}}, // ( 43, 64) + { 0, { 0, 0, 0}}, // ( 44, 64) + { 0, { 0, 0, 0}}, // ( 45, 64) + { 0, { 0, 0, 0}}, // ( 46, 64) + { 0, { 0, 0, 0}}, // ( 47, 64) + { 0, { 0, 0, 0}}, // ( 48, 64) + { 0, { 0, 0, 0}}, // ( 49, 64) + { 0, { 0, 0, 0}}, // ( 50, 64) + { 0, { 0, 0, 0}}, // ( 51, 64) + { 0, { 0, 0, 0}}, // ( 52, 64) + { 0, { 0, 0, 0}}, // ( 53, 64) + { 0, { 0, 0, 0}}, // ( 54, 64) + { 0, { 0, 0, 0}}, // ( 55, 64) + { 0, { 0, 0, 0}}, // ( 56, 64) + { 0, { 0, 0, 0}}, // ( 57, 64) + { 0, { 0, 0, 0}}, // ( 58, 64) + { 0, { 0, 0, 0}}, // ( 59, 64) + { 0, { 0, 0, 0}}, // ( 60, 64) + { 0, { 0, 0, 0}}, // ( 61, 64) + { 0, { 0, 0, 0}}, // ( 62, 64) + { 0, { 0, 0, 0}}, // ( 63, 64) + { 0, { 0, 0, 0}}, // ( 64, 64) + { 0, { 0, 0, 0}}, // ( 65, 64) + { 0, { 0, 0, 0}}, // ( 66, 64) + { 0, { 0, 0, 0}}, // ( 67, 64) + { 0, { 0, 0, 0}}, // ( 68, 64) + { 0, { 0, 0, 0}}, // ( 69, 64) + { 0, { 0, 0, 0}}, // ( 70, 64) + { 0, { 0, 0, 0}}, // ( 71, 64) + { 0, { 0, 0, 0}}, // ( 72, 64) + { 0, { 0, 0, 0}}, // ( 73, 64) + { 0, { 0, 0, 0}}, // ( 74, 64) + { 0, { 0, 0, 0}}, // ( 75, 64) + { 0, { 0, 0, 0}}, // ( 76, 64) + { 0, { 0, 0, 0}}, // ( 77, 64) + { 0, { 0, 0, 0}}, // ( 78, 64) + { 0, { 0, 0, 0}}, // ( 79, 64) + { 0, { 0, 0, 0}}, // ( 80, 64) + { 0, { 0, 0, 0}}, // ( 81, 64) + { 0, { 0, 0, 0}}, // ( 82, 64) + { 0, { 0, 0, 0}}, // ( 83, 64) + { 0, { 0, 0, 0}}, // ( 84, 64) + { 0, { 0, 0, 0}}, // ( 85, 64) + { 0, { 0, 0, 0}}, // ( 86, 64) + { 0, { 0, 0, 0}}, // ( 87, 64) + { 0, { 0, 0, 0}}, // ( 88, 64) + { 0, { 0, 0, 0}}, // ( 89, 64) + { 0, { 0, 0, 0}}, // ( 90, 64) + { 0, { 0, 0, 0}}, // ( 91, 64) + { 0, { 0, 0, 0}}, // ( 92, 64) + { 0, { 0, 0, 0}}, // ( 93, 64) + { 0, { 0, 0, 0}}, // ( 94, 64) + { 0, { 0, 0, 0}}, // ( 95, 64) + { 0, { 0, 0, 0}}, // ( 96, 64) + { 0, { 0, 0, 0}}, // ( 97, 64) + { 0, { 0, 0, 0}}, // ( 98, 64) + { 0, { 0, 0, 0}}, // ( 99, 64) + { 0, { 0, 0, 0}}, // (100, 64) + { 0, { 0, 0, 0}}, // (101, 64) + { 0, { 0, 0, 0}}, // (102, 64) + { 0, { 0, 0, 0}}, // (103, 64) + { 0, { 0, 0, 0}}, // (104, 64) + { 0, { 0, 0, 0}}, // (105, 64) + { 0, { 0, 0, 0}}, // (106, 64) + { 0, { 0, 0, 0}}, // (107, 64) + { 0, { 0, 0, 0}}, // (108, 64) + { 0, { 0, 0, 0}}, // (109, 64) + { 0, { 0, 0, 0}}, // (110, 64) + { 0, { 0, 0, 0}}, // (111, 64) + { 0, { 0, 0, 0}}, // (112, 64) + { 0, { 0, 0, 0}}, // (113, 64) + { 0, { 0, 0, 0}}, // (114, 64) + { 0, { 0, 0, 0}}, // (115, 64) + { 0, { 0, 0, 0}}, // (116, 64) + { 0, { 0, 0, 0}}, // (117, 64) + { 0, { 0, 0, 0}}, // (118, 64) + { 0, { 0, 0, 0}}, // (119, 64) + { 0, { 0, 0, 0}}, // (120, 64) + { 0, { 0, 0, 0}}, // (121, 64) + { 0, { 0, 0, 0}}, // (122, 64) + { 0, { 0, 0, 0}}, // (123, 64) + { 0, { 0, 0, 0}}, // (124, 64) + { 0, { 0, 0, 0}}, // (125, 64) + { 0, { 0, 0, 0}}, // (126, 64) + { 0, { 0, 0, 0}}, // (127, 64) + { 0, { 0, 0, 0}}, // (128, 64) + { 0, { 0, 0, 0}}, // (129, 64) + { 0, { 0, 0, 0}}, // (130, 64) + { 0, { 0, 0, 0}}, // (131, 64) + { 0, { 0, 0, 0}}, // (132, 64) + { 0, { 0, 0, 0}}, // (133, 64) + { 0, { 0, 0, 0}}, // (134, 64) + { 0, { 0, 0, 0}}, // (135, 64) + { 0, { 0, 0, 0}}, // (136, 64) + { 0, { 0, 0, 0}}, // (137, 64) + { 0, { 0, 0, 0}}, // (138, 64) + { 0, { 0, 0, 0}}, // (139, 64) + { 0, { 0, 0, 0}}, // (140, 64) + { 0, { 0, 0, 0}}, // (141, 64) + { 0, { 0, 0, 0}}, // (142, 64) + { 0, { 0, 0, 0}}, // (143, 64) + { 0, { 0, 0, 0}}, // (144, 64) + { 0, { 0, 0, 0}}, // (145, 64) + { 0, { 0, 0, 0}}, // (146, 64) + { 0, { 0, 0, 0}}, // (147, 64) + { 0, { 0, 0, 0}}, // (148, 64) + { 0, { 0, 0, 0}}, // (149, 64) + { 0, { 0, 0, 0}}, // (150, 64) + { 0, { 0, 0, 0}}, // (151, 64) + { 0, { 0, 0, 0}}, // (152, 64) + { 0, { 0, 0, 0}}, // (153, 64) + { 0, { 0, 0, 0}}, // (154, 64) + { 0, { 0, 0, 0}}, // (155, 64) + { 0, { 0, 0, 0}}, // (156, 64) + { 0, { 0, 0, 0}}, // (157, 64) + { 0, { 0, 0, 0}}, // (158, 64) + { 0, { 0, 0, 0}}, // (159, 64) + { 0, { 0, 0, 0}}, // (160, 64) + { 0, { 0, 0, 0}}, // (161, 64) + { 0, { 0, 0, 0}}, // (162, 64) + { 0, { 0, 0, 0}}, // (163, 64) + { 0, { 0, 0, 0}}, // (164, 64) + { 0, { 0, 0, 0}}, // (165, 64) + { 0, { 0, 0, 0}}, // (166, 64) + { 0, { 0, 0, 0}}, // (167, 64) + { 0, { 0, 0, 0}}, // (168, 64) + { 0, { 0, 0, 0}}, // (169, 64) + { 0, { 0, 0, 0}}, // (170, 64) + { 0, { 0, 0, 0}}, // (171, 64) + { 0, { 0, 0, 0}}, // (172, 64) + { 0, { 0, 0, 0}}, // (173, 64) + { 98, { 0, 0, 0}}, // (174, 64) + {128, { 0, 0, 0}}, // (175, 64) + {128, { 0, 0, 0}}, // (176, 64) + {128, { 0, 0, 0}}, // (177, 64) + {128, { 0, 0, 0}}, // (178, 64) + {128, { 0, 0, 0}}, // (179, 64) + {128, { 0, 0, 0}}, // ( 0, 65) + {128, { 0, 0, 0}}, // ( 1, 65) + {128, { 0, 0, 0}}, // ( 2, 65) + {128, { 0, 0, 0}}, // ( 3, 65) + {128, { 0, 0, 0}}, // ( 4, 65) + { 62, { 0, 0, 0}}, // ( 5, 65) + { 0, { 0, 0, 0}}, // ( 6, 65) + { 0, { 0, 0, 0}}, // ( 7, 65) + { 0, { 0, 0, 0}}, // ( 8, 65) + { 0, { 0, 0, 0}}, // ( 9, 65) + { 0, { 0, 0, 0}}, // ( 10, 65) + { 0, { 0, 0, 0}}, // ( 11, 65) + { 0, { 0, 0, 0}}, // ( 12, 65) + { 0, { 0, 0, 0}}, // ( 13, 65) + { 0, { 0, 0, 0}}, // ( 14, 65) + { 0, { 0, 0, 0}}, // ( 15, 65) + { 0, { 0, 0, 0}}, // ( 16, 65) + { 0, { 0, 0, 0}}, // ( 17, 65) + { 0, { 0, 0, 0}}, // ( 18, 65) + { 0, { 0, 0, 0}}, // ( 19, 65) + { 0, { 0, 0, 0}}, // ( 20, 65) + { 0, { 0, 0, 0}}, // ( 21, 65) + { 0, { 0, 0, 0}}, // ( 22, 65) + { 0, { 0, 0, 0}}, // ( 23, 65) + { 0, { 0, 0, 0}}, // ( 24, 65) + { 0, { 0, 0, 0}}, // ( 25, 65) + { 0, { 0, 0, 0}}, // ( 26, 65) + { 0, { 0, 0, 0}}, // ( 27, 65) + { 0, { 0, 0, 0}}, // ( 28, 65) + { 0, { 0, 0, 0}}, // ( 29, 65) + { 0, { 0, 0, 0}}, // ( 30, 65) + { 0, { 0, 0, 0}}, // ( 31, 65) + { 0, { 0, 0, 0}}, // ( 32, 65) + { 0, { 0, 0, 0}}, // ( 33, 65) + { 0, { 0, 0, 0}}, // ( 34, 65) + { 0, { 0, 0, 0}}, // ( 35, 65) + { 0, { 0, 0, 0}}, // ( 36, 65) + { 0, { 0, 0, 0}}, // ( 37, 65) + { 0, { 0, 0, 0}}, // ( 38, 65) + { 0, { 0, 0, 0}}, // ( 39, 65) + { 0, { 0, 0, 0}}, // ( 40, 65) + { 0, { 0, 0, 0}}, // ( 41, 65) + { 0, { 0, 0, 0}}, // ( 42, 65) + { 0, { 0, 0, 0}}, // ( 43, 65) + { 0, { 0, 0, 0}}, // ( 44, 65) + { 0, { 0, 0, 0}}, // ( 45, 65) + { 0, { 0, 0, 0}}, // ( 46, 65) + { 0, { 0, 0, 0}}, // ( 47, 65) + { 0, { 0, 0, 0}}, // ( 48, 65) + { 0, { 0, 0, 0}}, // ( 49, 65) + { 0, { 0, 0, 0}}, // ( 50, 65) + { 0, { 0, 0, 0}}, // ( 51, 65) + { 0, { 0, 0, 0}}, // ( 52, 65) + { 0, { 0, 0, 0}}, // ( 53, 65) + { 0, { 0, 0, 0}}, // ( 54, 65) + { 0, { 0, 0, 0}}, // ( 55, 65) + { 0, { 0, 0, 0}}, // ( 56, 65) + { 0, { 0, 0, 0}}, // ( 57, 65) + { 0, { 0, 0, 0}}, // ( 58, 65) + { 0, { 0, 0, 0}}, // ( 59, 65) + { 0, { 0, 0, 0}}, // ( 60, 65) + { 0, { 0, 0, 0}}, // ( 61, 65) + { 0, { 0, 0, 0}}, // ( 62, 65) + { 0, { 0, 0, 0}}, // ( 63, 65) + { 0, { 0, 0, 0}}, // ( 64, 65) + { 0, { 0, 0, 0}}, // ( 65, 65) + { 0, { 0, 0, 0}}, // ( 66, 65) + { 0, { 0, 0, 0}}, // ( 67, 65) + { 0, { 0, 0, 0}}, // ( 68, 65) + { 0, { 0, 0, 0}}, // ( 69, 65) + { 0, { 0, 0, 0}}, // ( 70, 65) + { 0, { 0, 0, 0}}, // ( 71, 65) + { 0, { 0, 0, 0}}, // ( 72, 65) + { 0, { 0, 0, 0}}, // ( 73, 65) + { 0, { 0, 0, 0}}, // ( 74, 65) + { 0, { 0, 0, 0}}, // ( 75, 65) + { 0, { 0, 0, 0}}, // ( 76, 65) + { 0, { 0, 0, 0}}, // ( 77, 65) + { 0, { 0, 0, 0}}, // ( 78, 65) + { 0, { 0, 0, 0}}, // ( 79, 65) + { 0, { 0, 0, 0}}, // ( 80, 65) + { 0, { 0, 0, 0}}, // ( 81, 65) + { 0, { 0, 0, 0}}, // ( 82, 65) + { 0, { 0, 0, 0}}, // ( 83, 65) + { 0, { 0, 0, 0}}, // ( 84, 65) + { 0, { 0, 0, 0}}, // ( 85, 65) + { 0, { 0, 0, 0}}, // ( 86, 65) + { 0, { 0, 0, 0}}, // ( 87, 65) + { 0, { 0, 0, 0}}, // ( 88, 65) + { 0, { 0, 0, 0}}, // ( 89, 65) + { 0, { 0, 0, 0}}, // ( 90, 65) + { 0, { 0, 0, 0}}, // ( 91, 65) + { 0, { 0, 0, 0}}, // ( 92, 65) + { 0, { 0, 0, 0}}, // ( 93, 65) + { 0, { 0, 0, 0}}, // ( 94, 65) + { 0, { 0, 0, 0}}, // ( 95, 65) + { 0, { 0, 0, 0}}, // ( 96, 65) + { 0, { 0, 0, 0}}, // ( 97, 65) + { 0, { 0, 0, 0}}, // ( 98, 65) + { 0, { 0, 0, 0}}, // ( 99, 65) + { 0, { 0, 0, 0}}, // (100, 65) + { 0, { 0, 0, 0}}, // (101, 65) + { 0, { 0, 0, 0}}, // (102, 65) + { 0, { 0, 0, 0}}, // (103, 65) + { 0, { 0, 0, 0}}, // (104, 65) + { 0, { 0, 0, 0}}, // (105, 65) + { 0, { 0, 0, 0}}, // (106, 65) + { 0, { 0, 0, 0}}, // (107, 65) + { 0, { 0, 0, 0}}, // (108, 65) + { 0, { 0, 0, 0}}, // (109, 65) + { 0, { 0, 0, 0}}, // (110, 65) + { 0, { 0, 0, 0}}, // (111, 65) + { 0, { 0, 0, 0}}, // (112, 65) + { 0, { 0, 0, 0}}, // (113, 65) + { 0, { 0, 0, 0}}, // (114, 65) + { 0, { 0, 0, 0}}, // (115, 65) + { 0, { 0, 0, 0}}, // (116, 65) + { 0, { 0, 0, 0}}, // (117, 65) + { 0, { 0, 0, 0}}, // (118, 65) + { 0, { 0, 0, 0}}, // (119, 65) + { 0, { 0, 0, 0}}, // (120, 65) + { 0, { 0, 0, 0}}, // (121, 65) + { 0, { 0, 0, 0}}, // (122, 65) + { 0, { 0, 0, 0}}, // (123, 65) + { 0, { 0, 0, 0}}, // (124, 65) + { 0, { 0, 0, 0}}, // (125, 65) + { 0, { 0, 0, 0}}, // (126, 65) + { 0, { 0, 0, 0}}, // (127, 65) + { 0, { 0, 0, 0}}, // (128, 65) + { 0, { 0, 0, 0}}, // (129, 65) + { 0, { 0, 0, 0}}, // (130, 65) + { 0, { 0, 0, 0}}, // (131, 65) + { 0, { 0, 0, 0}}, // (132, 65) + { 0, { 0, 0, 0}}, // (133, 65) + { 0, { 0, 0, 0}}, // (134, 65) + { 0, { 0, 0, 0}}, // (135, 65) + { 0, { 0, 0, 0}}, // (136, 65) + { 0, { 0, 0, 0}}, // (137, 65) + { 0, { 0, 0, 0}}, // (138, 65) + { 0, { 0, 0, 0}}, // (139, 65) + { 0, { 0, 0, 0}}, // (140, 65) + { 0, { 0, 0, 0}}, // (141, 65) + { 0, { 0, 0, 0}}, // (142, 65) + { 0, { 0, 0, 0}}, // (143, 65) + { 0, { 0, 0, 0}}, // (144, 65) + { 0, { 0, 0, 0}}, // (145, 65) + { 0, { 0, 0, 0}}, // (146, 65) + { 0, { 0, 0, 0}}, // (147, 65) + { 0, { 0, 0, 0}}, // (148, 65) + { 0, { 0, 0, 0}}, // (149, 65) + { 0, { 0, 0, 0}}, // (150, 65) + { 0, { 0, 0, 0}}, // (151, 65) + { 0, { 0, 0, 0}}, // (152, 65) + { 0, { 0, 0, 0}}, // (153, 65) + { 0, { 0, 0, 0}}, // (154, 65) + { 0, { 0, 0, 0}}, // (155, 65) + { 0, { 0, 0, 0}}, // (156, 65) + { 0, { 0, 0, 0}}, // (157, 65) + { 0, { 0, 0, 0}}, // (158, 65) + { 0, { 0, 0, 0}}, // (159, 65) + { 0, { 0, 0, 0}}, // (160, 65) + { 0, { 0, 0, 0}}, // (161, 65) + { 0, { 0, 0, 0}}, // (162, 65) + { 0, { 0, 0, 0}}, // (163, 65) + { 0, { 0, 0, 0}}, // (164, 65) + { 0, { 0, 0, 0}}, // (165, 65) + { 0, { 0, 0, 0}}, // (166, 65) + { 0, { 0, 0, 0}}, // (167, 65) + { 0, { 0, 0, 0}}, // (168, 65) + { 0, { 0, 0, 0}}, // (169, 65) + { 0, { 0, 0, 0}}, // (170, 65) + { 0, { 0, 0, 0}}, // (171, 65) + { 0, { 0, 0, 0}}, // (172, 65) + { 0, { 0, 0, 0}}, // (173, 65) + { 58, { 0, 0, 0}}, // (174, 65) + {128, { 0, 0, 0}}, // (175, 65) + {128, { 0, 0, 0}}, // (176, 65) + {128, { 0, 0, 0}}, // (177, 65) + {128, { 0, 0, 0}}, // (178, 65) + {128, { 0, 0, 0}}, // (179, 65) + {128, { 0, 0, 0}}, // ( 0, 66) + {128, { 0, 0, 0}}, // ( 1, 66) + {128, { 0, 0, 0}}, // ( 2, 66) + {128, { 0, 0, 0}}, // ( 3, 66) + {128, { 0, 0, 0}}, // ( 4, 66) + { 25, { 0, 0, 0}}, // ( 5, 66) + { 0, { 0, 0, 0}}, // ( 6, 66) + { 0, { 0, 0, 0}}, // ( 7, 66) + { 0, { 0, 0, 0}}, // ( 8, 66) + { 0, { 0, 0, 0}}, // ( 9, 66) + { 0, { 0, 0, 0}}, // ( 10, 66) + { 0, { 0, 0, 0}}, // ( 11, 66) + { 0, { 0, 0, 0}}, // ( 12, 66) + { 0, { 0, 0, 0}}, // ( 13, 66) + { 0, { 0, 0, 0}}, // ( 14, 66) + { 0, { 0, 0, 0}}, // ( 15, 66) + { 0, { 0, 0, 0}}, // ( 16, 66) + { 0, { 0, 0, 0}}, // ( 17, 66) + { 0, { 0, 0, 0}}, // ( 18, 66) + { 0, { 0, 0, 0}}, // ( 19, 66) + { 0, { 0, 0, 0}}, // ( 20, 66) + { 0, { 0, 0, 0}}, // ( 21, 66) + { 0, { 0, 0, 0}}, // ( 22, 66) + { 0, { 0, 0, 0}}, // ( 23, 66) + { 0, { 0, 0, 0}}, // ( 24, 66) + { 0, { 0, 0, 0}}, // ( 25, 66) + { 0, { 0, 0, 0}}, // ( 26, 66) + { 0, { 0, 0, 0}}, // ( 27, 66) + { 0, { 0, 0, 0}}, // ( 28, 66) + { 0, { 0, 0, 0}}, // ( 29, 66) + { 0, { 0, 0, 0}}, // ( 30, 66) + { 0, { 0, 0, 0}}, // ( 31, 66) + { 0, { 0, 0, 0}}, // ( 32, 66) + { 0, { 0, 0, 0}}, // ( 33, 66) + { 0, { 0, 0, 0}}, // ( 34, 66) + { 0, { 0, 0, 0}}, // ( 35, 66) + { 0, { 0, 0, 0}}, // ( 36, 66) + { 0, { 0, 0, 0}}, // ( 37, 66) + { 0, { 0, 0, 0}}, // ( 38, 66) + { 0, { 0, 0, 0}}, // ( 39, 66) + { 0, { 0, 0, 0}}, // ( 40, 66) + { 0, { 0, 0, 0}}, // ( 41, 66) + { 0, { 0, 0, 0}}, // ( 42, 66) + { 0, { 0, 0, 0}}, // ( 43, 66) + { 0, { 0, 0, 0}}, // ( 44, 66) + { 0, { 0, 0, 0}}, // ( 45, 66) + { 0, { 0, 0, 0}}, // ( 46, 66) + { 0, { 0, 0, 0}}, // ( 47, 66) + { 0, { 0, 0, 0}}, // ( 48, 66) + { 0, { 0, 0, 0}}, // ( 49, 66) + { 0, { 0, 0, 0}}, // ( 50, 66) + { 0, { 0, 0, 0}}, // ( 51, 66) + { 0, { 0, 0, 0}}, // ( 52, 66) + { 0, { 0, 0, 0}}, // ( 53, 66) + { 0, { 0, 0, 0}}, // ( 54, 66) + { 0, { 0, 0, 0}}, // ( 55, 66) + { 0, { 0, 0, 0}}, // ( 56, 66) + { 0, { 0, 0, 0}}, // ( 57, 66) + { 0, { 0, 0, 0}}, // ( 58, 66) + { 0, { 0, 0, 0}}, // ( 59, 66) + { 0, { 0, 0, 0}}, // ( 60, 66) + { 0, { 0, 0, 0}}, // ( 61, 66) + { 0, { 0, 0, 0}}, // ( 62, 66) + { 0, { 0, 0, 0}}, // ( 63, 66) + { 0, { 0, 0, 0}}, // ( 64, 66) + { 0, { 0, 0, 0}}, // ( 65, 66) + { 0, { 0, 0, 0}}, // ( 66, 66) + { 0, { 0, 0, 0}}, // ( 67, 66) + { 0, { 0, 0, 0}}, // ( 68, 66) + { 0, { 0, 0, 0}}, // ( 69, 66) + { 0, { 0, 0, 0}}, // ( 70, 66) + { 0, { 0, 0, 0}}, // ( 71, 66) + { 0, { 0, 0, 0}}, // ( 72, 66) + { 0, { 0, 0, 0}}, // ( 73, 66) + { 0, { 0, 0, 0}}, // ( 74, 66) + { 0, { 0, 0, 0}}, // ( 75, 66) + { 0, { 0, 0, 0}}, // ( 76, 66) + { 0, { 0, 0, 0}}, // ( 77, 66) + { 0, { 0, 0, 0}}, // ( 78, 66) + { 0, { 0, 0, 0}}, // ( 79, 66) + { 0, { 0, 0, 0}}, // ( 80, 66) + { 0, { 0, 0, 0}}, // ( 81, 66) + { 0, { 0, 0, 0}}, // ( 82, 66) + { 0, { 0, 0, 0}}, // ( 83, 66) + { 0, { 0, 0, 0}}, // ( 84, 66) + { 0, { 0, 0, 0}}, // ( 85, 66) + { 0, { 0, 0, 0}}, // ( 86, 66) + { 0, { 0, 0, 0}}, // ( 87, 66) + { 0, { 0, 0, 0}}, // ( 88, 66) + { 0, { 0, 0, 0}}, // ( 89, 66) + { 0, { 0, 0, 0}}, // ( 90, 66) + { 0, { 0, 0, 0}}, // ( 91, 66) + { 0, { 0, 0, 0}}, // ( 92, 66) + { 0, { 0, 0, 0}}, // ( 93, 66) + { 0, { 0, 0, 0}}, // ( 94, 66) + { 0, { 0, 0, 0}}, // ( 95, 66) + { 0, { 0, 0, 0}}, // ( 96, 66) + { 0, { 0, 0, 0}}, // ( 97, 66) + { 0, { 0, 0, 0}}, // ( 98, 66) + { 0, { 0, 0, 0}}, // ( 99, 66) + { 0, { 0, 0, 0}}, // (100, 66) + { 0, { 0, 0, 0}}, // (101, 66) + { 0, { 0, 0, 0}}, // (102, 66) + { 0, { 0, 0, 0}}, // (103, 66) + { 0, { 0, 0, 0}}, // (104, 66) + { 0, { 0, 0, 0}}, // (105, 66) + { 0, { 0, 0, 0}}, // (106, 66) + { 0, { 0, 0, 0}}, // (107, 66) + { 0, { 0, 0, 0}}, // (108, 66) + { 0, { 0, 0, 0}}, // (109, 66) + { 0, { 0, 0, 0}}, // (110, 66) + { 0, { 0, 0, 0}}, // (111, 66) + { 0, { 0, 0, 0}}, // (112, 66) + { 0, { 0, 0, 0}}, // (113, 66) + { 0, { 0, 0, 0}}, // (114, 66) + { 0, { 0, 0, 0}}, // (115, 66) + { 0, { 0, 0, 0}}, // (116, 66) + { 0, { 0, 0, 0}}, // (117, 66) + { 0, { 0, 0, 0}}, // (118, 66) + { 0, { 0, 0, 0}}, // (119, 66) + { 0, { 0, 0, 0}}, // (120, 66) + { 0, { 0, 0, 0}}, // (121, 66) + { 0, { 0, 0, 0}}, // (122, 66) + { 0, { 0, 0, 0}}, // (123, 66) + { 0, { 0, 0, 0}}, // (124, 66) + { 0, { 0, 0, 0}}, // (125, 66) + { 0, { 0, 0, 0}}, // (126, 66) + { 0, { 0, 0, 0}}, // (127, 66) + { 0, { 0, 0, 0}}, // (128, 66) + { 0, { 0, 0, 0}}, // (129, 66) + { 0, { 0, 0, 0}}, // (130, 66) + { 0, { 0, 0, 0}}, // (131, 66) + { 0, { 0, 0, 0}}, // (132, 66) + { 0, { 0, 0, 0}}, // (133, 66) + { 0, { 0, 0, 0}}, // (134, 66) + { 0, { 0, 0, 0}}, // (135, 66) + { 0, { 0, 0, 0}}, // (136, 66) + { 0, { 0, 0, 0}}, // (137, 66) + { 0, { 0, 0, 0}}, // (138, 66) + { 0, { 0, 0, 0}}, // (139, 66) + { 0, { 0, 0, 0}}, // (140, 66) + { 0, { 0, 0, 0}}, // (141, 66) + { 0, { 0, 0, 0}}, // (142, 66) + { 0, { 0, 0, 0}}, // (143, 66) + { 0, { 0, 0, 0}}, // (144, 66) + { 0, { 0, 0, 0}}, // (145, 66) + { 0, { 0, 0, 0}}, // (146, 66) + { 0, { 0, 0, 0}}, // (147, 66) + { 0, { 0, 0, 0}}, // (148, 66) + { 0, { 0, 0, 0}}, // (149, 66) + { 0, { 0, 0, 0}}, // (150, 66) + { 0, { 0, 0, 0}}, // (151, 66) + { 0, { 0, 0, 0}}, // (152, 66) + { 0, { 0, 0, 0}}, // (153, 66) + { 0, { 0, 0, 0}}, // (154, 66) + { 0, { 0, 0, 0}}, // (155, 66) + { 0, { 0, 0, 0}}, // (156, 66) + { 0, { 0, 0, 0}}, // (157, 66) + { 0, { 0, 0, 0}}, // (158, 66) + { 0, { 0, 0, 0}}, // (159, 66) + { 0, { 0, 0, 0}}, // (160, 66) + { 0, { 0, 0, 0}}, // (161, 66) + { 0, { 0, 0, 0}}, // (162, 66) + { 0, { 0, 0, 0}}, // (163, 66) + { 0, { 0, 0, 0}}, // (164, 66) + { 0, { 0, 0, 0}}, // (165, 66) + { 0, { 0, 0, 0}}, // (166, 66) + { 0, { 0, 0, 0}}, // (167, 66) + { 0, { 0, 0, 0}}, // (168, 66) + { 0, { 0, 0, 0}}, // (169, 66) + { 0, { 0, 0, 0}}, // (170, 66) + { 0, { 0, 0, 0}}, // (171, 66) + { 0, { 0, 0, 0}}, // (172, 66) + { 0, { 0, 0, 0}}, // (173, 66) + { 23, { 0, 0, 0}}, // (174, 66) + {128, { 0, 0, 0}}, // (175, 66) + {128, { 0, 0, 0}}, // (176, 66) + {128, { 0, 0, 0}}, // (177, 66) + {128, { 0, 0, 0}}, // (178, 66) + {128, { 0, 0, 0}}, // (179, 66) + {128, { 0, 0, 0}}, // ( 0, 67) + {128, { 0, 0, 0}}, // ( 1, 67) + {128, { 0, 0, 0}}, // ( 2, 67) + {128, { 0, 0, 0}}, // ( 3, 67) + {117, { 0, 0, 0}}, // ( 4, 67) + { 1, { 0, 0, 0}}, // ( 5, 67) + { 0, { 0, 0, 0}}, // ( 6, 67) + { 0, { 0, 0, 0}}, // ( 7, 67) + { 0, { 0, 0, 0}}, // ( 8, 67) + { 0, { 0, 0, 0}}, // ( 9, 67) + { 0, { 0, 0, 0}}, // ( 10, 67) + { 0, { 0, 0, 0}}, // ( 11, 67) + { 0, { 0, 0, 0}}, // ( 12, 67) + { 0, { 0, 0, 0}}, // ( 13, 67) + { 0, { 0, 0, 0}}, // ( 14, 67) + { 0, { 0, 0, 0}}, // ( 15, 67) + { 0, { 0, 0, 0}}, // ( 16, 67) + { 0, { 0, 0, 0}}, // ( 17, 67) + { 0, { 0, 0, 0}}, // ( 18, 67) + { 0, { 0, 0, 0}}, // ( 19, 67) + { 0, { 0, 0, 0}}, // ( 20, 67) + { 0, { 0, 0, 0}}, // ( 21, 67) + { 0, { 0, 0, 0}}, // ( 22, 67) + { 0, { 0, 0, 0}}, // ( 23, 67) + { 0, { 0, 0, 0}}, // ( 24, 67) + { 0, { 0, 0, 0}}, // ( 25, 67) + { 0, { 0, 0, 0}}, // ( 26, 67) + { 0, { 0, 0, 0}}, // ( 27, 67) + { 0, { 0, 0, 0}}, // ( 28, 67) + { 0, { 0, 0, 0}}, // ( 29, 67) + { 0, { 0, 0, 0}}, // ( 30, 67) + { 0, { 0, 0, 0}}, // ( 31, 67) + { 0, { 0, 0, 0}}, // ( 32, 67) + { 0, { 0, 0, 0}}, // ( 33, 67) + { 0, { 0, 0, 0}}, // ( 34, 67) + { 0, { 0, 0, 0}}, // ( 35, 67) + { 0, { 0, 0, 0}}, // ( 36, 67) + { 0, { 0, 0, 0}}, // ( 37, 67) + { 0, { 0, 0, 0}}, // ( 38, 67) + { 0, { 0, 0, 0}}, // ( 39, 67) + { 0, { 0, 0, 0}}, // ( 40, 67) + { 0, { 0, 0, 0}}, // ( 41, 67) + { 0, { 0, 0, 0}}, // ( 42, 67) + { 0, { 0, 0, 0}}, // ( 43, 67) + { 0, { 0, 0, 0}}, // ( 44, 67) + { 0, { 0, 0, 0}}, // ( 45, 67) + { 0, { 0, 0, 0}}, // ( 46, 67) + { 0, { 0, 0, 0}}, // ( 47, 67) + { 0, { 0, 0, 0}}, // ( 48, 67) + { 0, { 0, 0, 0}}, // ( 49, 67) + { 0, { 0, 0, 0}}, // ( 50, 67) + { 0, { 0, 0, 0}}, // ( 51, 67) + { 0, { 0, 0, 0}}, // ( 52, 67) + { 0, { 0, 0, 0}}, // ( 53, 67) + { 0, { 0, 0, 0}}, // ( 54, 67) + { 0, { 0, 0, 0}}, // ( 55, 67) + { 0, { 0, 0, 0}}, // ( 56, 67) + { 0, { 0, 0, 0}}, // ( 57, 67) + { 0, { 0, 0, 0}}, // ( 58, 67) + { 0, { 0, 0, 0}}, // ( 59, 67) + { 0, { 0, 0, 0}}, // ( 60, 67) + { 0, { 0, 0, 0}}, // ( 61, 67) + { 0, { 0, 0, 0}}, // ( 62, 67) + { 0, { 0, 0, 0}}, // ( 63, 67) + { 0, { 0, 0, 0}}, // ( 64, 67) + { 0, { 0, 0, 0}}, // ( 65, 67) + { 0, { 0, 0, 0}}, // ( 66, 67) + { 0, { 0, 0, 0}}, // ( 67, 67) + { 0, { 0, 0, 0}}, // ( 68, 67) + { 0, { 0, 0, 0}}, // ( 69, 67) + { 0, { 0, 0, 0}}, // ( 70, 67) + { 0, { 0, 0, 0}}, // ( 71, 67) + { 0, { 0, 0, 0}}, // ( 72, 67) + { 0, { 0, 0, 0}}, // ( 73, 67) + { 0, { 0, 0, 0}}, // ( 74, 67) + { 0, { 0, 0, 0}}, // ( 75, 67) + { 0, { 0, 0, 0}}, // ( 76, 67) + { 0, { 0, 0, 0}}, // ( 77, 67) + { 0, { 0, 0, 0}}, // ( 78, 67) + { 0, { 0, 0, 0}}, // ( 79, 67) + { 0, { 0, 0, 0}}, // ( 80, 67) + { 0, { 0, 0, 0}}, // ( 81, 67) + { 0, { 0, 0, 0}}, // ( 82, 67) + { 0, { 0, 0, 0}}, // ( 83, 67) + { 0, { 0, 0, 0}}, // ( 84, 67) + { 0, { 0, 0, 0}}, // ( 85, 67) + { 0, { 0, 0, 0}}, // ( 86, 67) + { 0, { 0, 0, 0}}, // ( 87, 67) + { 0, { 0, 0, 0}}, // ( 88, 67) + { 0, { 0, 0, 0}}, // ( 89, 67) + { 0, { 0, 0, 0}}, // ( 90, 67) + { 0, { 0, 0, 0}}, // ( 91, 67) + { 0, { 0, 0, 0}}, // ( 92, 67) + { 0, { 0, 0, 0}}, // ( 93, 67) + { 0, { 0, 0, 0}}, // ( 94, 67) + { 0, { 0, 0, 0}}, // ( 95, 67) + { 0, { 0, 0, 0}}, // ( 96, 67) + { 0, { 0, 0, 0}}, // ( 97, 67) + { 0, { 0, 0, 0}}, // ( 98, 67) + { 0, { 0, 0, 0}}, // ( 99, 67) + { 0, { 0, 0, 0}}, // (100, 67) + { 0, { 0, 0, 0}}, // (101, 67) + { 0, { 0, 0, 0}}, // (102, 67) + { 0, { 0, 0, 0}}, // (103, 67) + { 0, { 0, 0, 0}}, // (104, 67) + { 0, { 0, 0, 0}}, // (105, 67) + { 0, { 0, 0, 0}}, // (106, 67) + { 0, { 0, 0, 0}}, // (107, 67) + { 0, { 0, 0, 0}}, // (108, 67) + { 0, { 0, 0, 0}}, // (109, 67) + { 0, { 0, 0, 0}}, // (110, 67) + { 0, { 0, 0, 0}}, // (111, 67) + { 0, { 0, 0, 0}}, // (112, 67) + { 0, { 0, 0, 0}}, // (113, 67) + { 0, { 0, 0, 0}}, // (114, 67) + { 0, { 0, 0, 0}}, // (115, 67) + { 0, { 0, 0, 0}}, // (116, 67) + { 0, { 0, 0, 0}}, // (117, 67) + { 0, { 0, 0, 0}}, // (118, 67) + { 0, { 0, 0, 0}}, // (119, 67) + { 0, { 0, 0, 0}}, // (120, 67) + { 0, { 0, 0, 0}}, // (121, 67) + { 0, { 0, 0, 0}}, // (122, 67) + { 0, { 0, 0, 0}}, // (123, 67) + { 0, { 0, 0, 0}}, // (124, 67) + { 0, { 0, 0, 0}}, // (125, 67) + { 0, { 0, 0, 0}}, // (126, 67) + { 0, { 0, 0, 0}}, // (127, 67) + { 0, { 0, 0, 0}}, // (128, 67) + { 0, { 0, 0, 0}}, // (129, 67) + { 0, { 0, 0, 0}}, // (130, 67) + { 0, { 0, 0, 0}}, // (131, 67) + { 0, { 0, 0, 0}}, // (132, 67) + { 0, { 0, 0, 0}}, // (133, 67) + { 0, { 0, 0, 0}}, // (134, 67) + { 0, { 0, 0, 0}}, // (135, 67) + { 0, { 0, 0, 0}}, // (136, 67) + { 0, { 0, 0, 0}}, // (137, 67) + { 0, { 0, 0, 0}}, // (138, 67) + { 0, { 0, 0, 0}}, // (139, 67) + { 0, { 0, 0, 0}}, // (140, 67) + { 0, { 0, 0, 0}}, // (141, 67) + { 0, { 0, 0, 0}}, // (142, 67) + { 0, { 0, 0, 0}}, // (143, 67) + { 0, { 0, 0, 0}}, // (144, 67) + { 0, { 0, 0, 0}}, // (145, 67) + { 0, { 0, 0, 0}}, // (146, 67) + { 0, { 0, 0, 0}}, // (147, 67) + { 0, { 0, 0, 0}}, // (148, 67) + { 0, { 0, 0, 0}}, // (149, 67) + { 0, { 0, 0, 0}}, // (150, 67) + { 0, { 0, 0, 0}}, // (151, 67) + { 0, { 0, 0, 0}}, // (152, 67) + { 0, { 0, 0, 0}}, // (153, 67) + { 0, { 0, 0, 0}}, // (154, 67) + { 0, { 0, 0, 0}}, // (155, 67) + { 0, { 0, 0, 0}}, // (156, 67) + { 0, { 0, 0, 0}}, // (157, 67) + { 0, { 0, 0, 0}}, // (158, 67) + { 0, { 0, 0, 0}}, // (159, 67) + { 0, { 0, 0, 0}}, // (160, 67) + { 0, { 0, 0, 0}}, // (161, 67) + { 0, { 0, 0, 0}}, // (162, 67) + { 0, { 0, 0, 0}}, // (163, 67) + { 0, { 0, 0, 0}}, // (164, 67) + { 0, { 0, 0, 0}}, // (165, 67) + { 0, { 0, 0, 0}}, // (166, 67) + { 0, { 0, 0, 0}}, // (167, 67) + { 0, { 0, 0, 0}}, // (168, 67) + { 0, { 0, 0, 0}}, // (169, 67) + { 0, { 0, 0, 0}}, // (170, 67) + { 0, { 0, 0, 0}}, // (171, 67) + { 0, { 0, 0, 0}}, // (172, 67) + { 0, { 0, 0, 0}}, // (173, 67) + { 1, { 0, 0, 0}}, // (174, 67) + {115, { 0, 0, 0}}, // (175, 67) + {128, { 0, 0, 0}}, // (176, 67) + {128, { 0, 0, 0}}, // (177, 67) + {128, { 0, 0, 0}}, // (178, 67) + {128, { 0, 0, 0}}, // (179, 67) + {128, { 0, 0, 0}}, // ( 0, 68) + {128, { 0, 0, 0}}, // ( 1, 68) + {128, { 0, 0, 0}}, // ( 2, 68) + {128, { 0, 0, 0}}, // ( 3, 68) + { 84, { 0, 0, 0}}, // ( 4, 68) + { 0, { 0, 0, 0}}, // ( 5, 68) + { 0, { 0, 0, 0}}, // ( 6, 68) + { 0, { 0, 0, 0}}, // ( 7, 68) + { 0, { 0, 0, 0}}, // ( 8, 68) + { 0, { 0, 0, 0}}, // ( 9, 68) + { 0, { 0, 0, 0}}, // ( 10, 68) + { 0, { 0, 0, 0}}, // ( 11, 68) + { 0, { 0, 0, 0}}, // ( 12, 68) + { 0, { 0, 0, 0}}, // ( 13, 68) + { 0, { 0, 0, 0}}, // ( 14, 68) + { 0, { 0, 0, 0}}, // ( 15, 68) + { 0, { 0, 0, 0}}, // ( 16, 68) + { 0, { 0, 0, 0}}, // ( 17, 68) + { 0, { 0, 0, 0}}, // ( 18, 68) + { 0, { 0, 0, 0}}, // ( 19, 68) + { 0, { 0, 0, 0}}, // ( 20, 68) + { 0, { 0, 0, 0}}, // ( 21, 68) + { 0, { 0, 0, 0}}, // ( 22, 68) + { 0, { 0, 0, 0}}, // ( 23, 68) + { 0, { 0, 0, 0}}, // ( 24, 68) + { 0, { 0, 0, 0}}, // ( 25, 68) + { 0, { 0, 0, 0}}, // ( 26, 68) + { 0, { 0, 0, 0}}, // ( 27, 68) + { 0, { 0, 0, 0}}, // ( 28, 68) + { 0, { 0, 0, 0}}, // ( 29, 68) + { 0, { 0, 0, 0}}, // ( 30, 68) + { 0, { 0, 0, 0}}, // ( 31, 68) + { 0, { 0, 0, 0}}, // ( 32, 68) + { 0, { 0, 0, 0}}, // ( 33, 68) + { 0, { 0, 0, 0}}, // ( 34, 68) + { 0, { 0, 0, 0}}, // ( 35, 68) + { 0, { 0, 0, 0}}, // ( 36, 68) + { 0, { 0, 0, 0}}, // ( 37, 68) + { 0, { 0, 0, 0}}, // ( 38, 68) + { 0, { 0, 0, 0}}, // ( 39, 68) + { 0, { 0, 0, 0}}, // ( 40, 68) + { 0, { 0, 0, 0}}, // ( 41, 68) + { 0, { 0, 0, 0}}, // ( 42, 68) + { 0, { 0, 0, 0}}, // ( 43, 68) + { 0, { 0, 0, 0}}, // ( 44, 68) + { 0, { 0, 0, 0}}, // ( 45, 68) + { 0, { 0, 0, 0}}, // ( 46, 68) + { 0, { 0, 0, 0}}, // ( 47, 68) + { 0, { 0, 0, 0}}, // ( 48, 68) + { 0, { 0, 0, 0}}, // ( 49, 68) + { 0, { 0, 0, 0}}, // ( 50, 68) + { 0, { 0, 0, 0}}, // ( 51, 68) + { 0, { 0, 0, 0}}, // ( 52, 68) + { 0, { 0, 0, 0}}, // ( 53, 68) + { 0, { 0, 0, 0}}, // ( 54, 68) + { 0, { 0, 0, 0}}, // ( 55, 68) + { 0, { 0, 0, 0}}, // ( 56, 68) + { 0, { 0, 0, 0}}, // ( 57, 68) + { 0, { 0, 0, 0}}, // ( 58, 68) + { 0, { 0, 0, 0}}, // ( 59, 68) + { 0, { 0, 0, 0}}, // ( 60, 68) + { 0, { 0, 0, 0}}, // ( 61, 68) + { 0, { 0, 0, 0}}, // ( 62, 68) + { 0, { 0, 0, 0}}, // ( 63, 68) + { 0, { 0, 0, 0}}, // ( 64, 68) + { 0, { 0, 0, 0}}, // ( 65, 68) + { 0, { 0, 0, 0}}, // ( 66, 68) + { 0, { 0, 0, 0}}, // ( 67, 68) + { 0, { 0, 0, 0}}, // ( 68, 68) + { 0, { 0, 0, 0}}, // ( 69, 68) + { 0, { 0, 0, 0}}, // ( 70, 68) + { 0, { 0, 0, 0}}, // ( 71, 68) + { 0, { 0, 0, 0}}, // ( 72, 68) + { 0, { 0, 0, 0}}, // ( 73, 68) + { 0, { 0, 0, 0}}, // ( 74, 68) + { 0, { 0, 0, 0}}, // ( 75, 68) + { 0, { 0, 0, 0}}, // ( 76, 68) + { 0, { 0, 0, 0}}, // ( 77, 68) + { 0, { 0, 0, 0}}, // ( 78, 68) + { 0, { 0, 0, 0}}, // ( 79, 68) + { 0, { 0, 0, 0}}, // ( 80, 68) + { 0, { 0, 0, 0}}, // ( 81, 68) + { 0, { 0, 0, 0}}, // ( 82, 68) + { 0, { 0, 0, 0}}, // ( 83, 68) + { 0, { 0, 0, 0}}, // ( 84, 68) + { 0, { 0, 0, 0}}, // ( 85, 68) + { 0, { 0, 0, 0}}, // ( 86, 68) + { 0, { 0, 0, 0}}, // ( 87, 68) + { 0, { 0, 0, 0}}, // ( 88, 68) + { 0, { 0, 0, 0}}, // ( 89, 68) + { 0, { 0, 0, 0}}, // ( 90, 68) + { 0, { 0, 0, 0}}, // ( 91, 68) + { 0, { 0, 0, 0}}, // ( 92, 68) + { 0, { 0, 0, 0}}, // ( 93, 68) + { 0, { 0, 0, 0}}, // ( 94, 68) + { 0, { 0, 0, 0}}, // ( 95, 68) + { 0, { 0, 0, 0}}, // ( 96, 68) + { 0, { 0, 0, 0}}, // ( 97, 68) + { 0, { 0, 0, 0}}, // ( 98, 68) + { 0, { 0, 0, 0}}, // ( 99, 68) + { 0, { 0, 0, 0}}, // (100, 68) + { 0, { 0, 0, 0}}, // (101, 68) + { 0, { 0, 0, 0}}, // (102, 68) + { 0, { 0, 0, 0}}, // (103, 68) + { 0, { 0, 0, 0}}, // (104, 68) + { 0, { 0, 0, 0}}, // (105, 68) + { 0, { 0, 0, 0}}, // (106, 68) + { 0, { 0, 0, 0}}, // (107, 68) + { 0, { 0, 0, 0}}, // (108, 68) + { 0, { 0, 0, 0}}, // (109, 68) + { 0, { 0, 0, 0}}, // (110, 68) + { 0, { 0, 0, 0}}, // (111, 68) + { 0, { 0, 0, 0}}, // (112, 68) + { 0, { 0, 0, 0}}, // (113, 68) + { 0, { 0, 0, 0}}, // (114, 68) + { 0, { 0, 0, 0}}, // (115, 68) + { 0, { 0, 0, 0}}, // (116, 68) + { 0, { 0, 0, 0}}, // (117, 68) + { 0, { 0, 0, 0}}, // (118, 68) + { 0, { 0, 0, 0}}, // (119, 68) + { 0, { 0, 0, 0}}, // (120, 68) + { 0, { 0, 0, 0}}, // (121, 68) + { 0, { 0, 0, 0}}, // (122, 68) + { 0, { 0, 0, 0}}, // (123, 68) + { 0, { 0, 0, 0}}, // (124, 68) + { 0, { 0, 0, 0}}, // (125, 68) + { 0, { 0, 0, 0}}, // (126, 68) + { 0, { 0, 0, 0}}, // (127, 68) + { 0, { 0, 0, 0}}, // (128, 68) + { 0, { 0, 0, 0}}, // (129, 68) + { 0, { 0, 0, 0}}, // (130, 68) + { 0, { 0, 0, 0}}, // (131, 68) + { 0, { 0, 0, 0}}, // (132, 68) + { 0, { 0, 0, 0}}, // (133, 68) + { 0, { 0, 0, 0}}, // (134, 68) + { 0, { 0, 0, 0}}, // (135, 68) + { 0, { 0, 0, 0}}, // (136, 68) + { 0, { 0, 0, 0}}, // (137, 68) + { 0, { 0, 0, 0}}, // (138, 68) + { 0, { 0, 0, 0}}, // (139, 68) + { 0, { 0, 0, 0}}, // (140, 68) + { 0, { 0, 0, 0}}, // (141, 68) + { 0, { 0, 0, 0}}, // (142, 68) + { 0, { 0, 0, 0}}, // (143, 68) + { 0, { 0, 0, 0}}, // (144, 68) + { 0, { 0, 0, 0}}, // (145, 68) + { 0, { 0, 0, 0}}, // (146, 68) + { 0, { 0, 0, 0}}, // (147, 68) + { 0, { 0, 0, 0}}, // (148, 68) + { 0, { 0, 0, 0}}, // (149, 68) + { 0, { 0, 0, 0}}, // (150, 68) + { 0, { 0, 0, 0}}, // (151, 68) + { 0, { 0, 0, 0}}, // (152, 68) + { 0, { 0, 0, 0}}, // (153, 68) + { 0, { 0, 0, 0}}, // (154, 68) + { 0, { 0, 0, 0}}, // (155, 68) + { 0, { 0, 0, 0}}, // (156, 68) + { 0, { 0, 0, 0}}, // (157, 68) + { 0, { 0, 0, 0}}, // (158, 68) + { 0, { 0, 0, 0}}, // (159, 68) + { 0, { 0, 0, 0}}, // (160, 68) + { 0, { 0, 0, 0}}, // (161, 68) + { 0, { 0, 0, 0}}, // (162, 68) + { 0, { 0, 0, 0}}, // (163, 68) + { 0, { 0, 0, 0}}, // (164, 68) + { 0, { 0, 0, 0}}, // (165, 68) + { 0, { 0, 0, 0}}, // (166, 68) + { 0, { 0, 0, 0}}, // (167, 68) + { 0, { 0, 0, 0}}, // (168, 68) + { 0, { 0, 0, 0}}, // (169, 68) + { 0, { 0, 0, 0}}, // (170, 68) + { 0, { 0, 0, 0}}, // (171, 68) + { 0, { 0, 0, 0}}, // (172, 68) + { 0, { 0, 0, 0}}, // (173, 68) + { 0, { 0, 0, 0}}, // (174, 68) + { 83, { 0, 0, 0}}, // (175, 68) + {128, { 0, 0, 0}}, // (176, 68) + {128, { 0, 0, 0}}, // (177, 68) + {128, { 0, 0, 0}}, // (178, 68) + {128, { 0, 0, 0}}, // (179, 68) + {128, { 0, 0, 0}}, // ( 0, 69) + {128, { 0, 0, 0}}, // ( 1, 69) + {128, { 0, 0, 0}}, // ( 2, 69) + {128, { 0, 0, 0}}, // ( 3, 69) + { 52, { 0, 0, 0}}, // ( 4, 69) + { 0, { 0, 0, 0}}, // ( 5, 69) + { 0, { 0, 0, 0}}, // ( 6, 69) + { 0, { 0, 0, 0}}, // ( 7, 69) + { 0, { 0, 0, 0}}, // ( 8, 69) + { 0, { 0, 0, 0}}, // ( 9, 69) + { 0, { 0, 0, 0}}, // ( 10, 69) + { 0, { 0, 0, 0}}, // ( 11, 69) + { 0, { 0, 0, 0}}, // ( 12, 69) + { 0, { 0, 0, 0}}, // ( 13, 69) + { 0, { 0, 0, 0}}, // ( 14, 69) + { 0, { 0, 0, 0}}, // ( 15, 69) + { 0, { 0, 0, 0}}, // ( 16, 69) + { 0, { 0, 0, 0}}, // ( 17, 69) + { 0, { 0, 0, 0}}, // ( 18, 69) + { 0, { 0, 0, 0}}, // ( 19, 69) + { 0, { 0, 0, 0}}, // ( 20, 69) + { 0, { 0, 0, 0}}, // ( 21, 69) + { 0, { 0, 0, 0}}, // ( 22, 69) + { 0, { 0, 0, 0}}, // ( 23, 69) + { 0, { 0, 0, 0}}, // ( 24, 69) + { 0, { 0, 0, 0}}, // ( 25, 69) + { 0, { 0, 0, 0}}, // ( 26, 69) + { 0, { 0, 0, 0}}, // ( 27, 69) + { 0, { 0, 0, 0}}, // ( 28, 69) + { 0, { 0, 0, 0}}, // ( 29, 69) + { 0, { 0, 0, 0}}, // ( 30, 69) + { 0, { 0, 0, 0}}, // ( 31, 69) + { 0, { 0, 0, 0}}, // ( 32, 69) + { 0, { 0, 0, 0}}, // ( 33, 69) + { 0, { 0, 0, 0}}, // ( 34, 69) + { 0, { 0, 0, 0}}, // ( 35, 69) + { 0, { 0, 0, 0}}, // ( 36, 69) + { 0, { 0, 0, 0}}, // ( 37, 69) + { 0, { 0, 0, 0}}, // ( 38, 69) + { 0, { 0, 0, 0}}, // ( 39, 69) + { 0, { 0, 0, 0}}, // ( 40, 69) + { 0, { 0, 0, 0}}, // ( 41, 69) + { 0, { 0, 0, 0}}, // ( 42, 69) + { 0, { 0, 0, 0}}, // ( 43, 69) + { 0, { 0, 0, 0}}, // ( 44, 69) + { 0, { 0, 0, 0}}, // ( 45, 69) + { 0, { 0, 0, 0}}, // ( 46, 69) + { 0, { 0, 0, 0}}, // ( 47, 69) + { 0, { 0, 0, 0}}, // ( 48, 69) + { 0, { 0, 0, 0}}, // ( 49, 69) + { 0, { 0, 0, 0}}, // ( 50, 69) + { 0, { 0, 0, 0}}, // ( 51, 69) + { 0, { 0, 0, 0}}, // ( 52, 69) + { 0, { 0, 0, 0}}, // ( 53, 69) + { 0, { 0, 0, 0}}, // ( 54, 69) + { 0, { 0, 0, 0}}, // ( 55, 69) + { 0, { 0, 0, 0}}, // ( 56, 69) + { 0, { 0, 0, 0}}, // ( 57, 69) + { 0, { 0, 0, 0}}, // ( 58, 69) + { 0, { 0, 0, 0}}, // ( 59, 69) + { 0, { 0, 0, 0}}, // ( 60, 69) + { 0, { 0, 0, 0}}, // ( 61, 69) + { 0, { 0, 0, 0}}, // ( 62, 69) + { 0, { 0, 0, 0}}, // ( 63, 69) + { 0, { 0, 0, 0}}, // ( 64, 69) + { 0, { 0, 0, 0}}, // ( 65, 69) + { 0, { 0, 0, 0}}, // ( 66, 69) + { 0, { 0, 0, 0}}, // ( 67, 69) + { 0, { 0, 0, 0}}, // ( 68, 69) + { 0, { 0, 0, 0}}, // ( 69, 69) + { 0, { 0, 0, 0}}, // ( 70, 69) + { 0, { 0, 0, 0}}, // ( 71, 69) + { 0, { 0, 0, 0}}, // ( 72, 69) + { 0, { 0, 0, 0}}, // ( 73, 69) + { 0, { 0, 0, 0}}, // ( 74, 69) + { 0, { 0, 0, 0}}, // ( 75, 69) + { 0, { 0, 0, 0}}, // ( 76, 69) + { 0, { 0, 0, 0}}, // ( 77, 69) + { 0, { 0, 0, 0}}, // ( 78, 69) + { 0, { 0, 0, 0}}, // ( 79, 69) + { 0, { 0, 0, 0}}, // ( 80, 69) + { 0, { 0, 0, 0}}, // ( 81, 69) + { 0, { 0, 0, 0}}, // ( 82, 69) + { 0, { 0, 0, 0}}, // ( 83, 69) + { 0, { 0, 0, 0}}, // ( 84, 69) + { 0, { 0, 0, 0}}, // ( 85, 69) + { 0, { 0, 0, 0}}, // ( 86, 69) + { 0, { 0, 0, 0}}, // ( 87, 69) + { 0, { 0, 0, 0}}, // ( 88, 69) + { 0, { 0, 0, 0}}, // ( 89, 69) + { 0, { 0, 0, 0}}, // ( 90, 69) + { 0, { 0, 0, 0}}, // ( 91, 69) + { 0, { 0, 0, 0}}, // ( 92, 69) + { 0, { 0, 0, 0}}, // ( 93, 69) + { 0, { 0, 0, 0}}, // ( 94, 69) + { 0, { 0, 0, 0}}, // ( 95, 69) + { 0, { 0, 0, 0}}, // ( 96, 69) + { 0, { 0, 0, 0}}, // ( 97, 69) + { 0, { 0, 0, 0}}, // ( 98, 69) + { 0, { 0, 0, 0}}, // ( 99, 69) + { 0, { 0, 0, 0}}, // (100, 69) + { 0, { 0, 0, 0}}, // (101, 69) + { 0, { 0, 0, 0}}, // (102, 69) + { 0, { 0, 0, 0}}, // (103, 69) + { 0, { 0, 0, 0}}, // (104, 69) + { 0, { 0, 0, 0}}, // (105, 69) + { 0, { 0, 0, 0}}, // (106, 69) + { 0, { 0, 0, 0}}, // (107, 69) + { 0, { 0, 0, 0}}, // (108, 69) + { 0, { 0, 0, 0}}, // (109, 69) + { 0, { 0, 0, 0}}, // (110, 69) + { 0, { 0, 0, 0}}, // (111, 69) + { 0, { 0, 0, 0}}, // (112, 69) + { 0, { 0, 0, 0}}, // (113, 69) + { 0, { 0, 0, 0}}, // (114, 69) + { 0, { 0, 0, 0}}, // (115, 69) + { 0, { 0, 0, 0}}, // (116, 69) + { 0, { 0, 0, 0}}, // (117, 69) + { 0, { 0, 0, 0}}, // (118, 69) + { 0, { 0, 0, 0}}, // (119, 69) + { 0, { 0, 0, 0}}, // (120, 69) + { 0, { 0, 0, 0}}, // (121, 69) + { 0, { 0, 0, 0}}, // (122, 69) + { 0, { 0, 0, 0}}, // (123, 69) + { 0, { 0, 0, 0}}, // (124, 69) + { 0, { 0, 0, 0}}, // (125, 69) + { 0, { 0, 0, 0}}, // (126, 69) + { 0, { 0, 0, 0}}, // (127, 69) + { 0, { 0, 0, 0}}, // (128, 69) + { 0, { 0, 0, 0}}, // (129, 69) + { 0, { 0, 0, 0}}, // (130, 69) + { 0, { 0, 0, 0}}, // (131, 69) + { 0, { 0, 0, 0}}, // (132, 69) + { 0, { 0, 0, 0}}, // (133, 69) + { 0, { 0, 0, 0}}, // (134, 69) + { 0, { 0, 0, 0}}, // (135, 69) + { 0, { 0, 0, 0}}, // (136, 69) + { 0, { 0, 0, 0}}, // (137, 69) + { 0, { 0, 0, 0}}, // (138, 69) + { 0, { 0, 0, 0}}, // (139, 69) + { 0, { 0, 0, 0}}, // (140, 69) + { 0, { 0, 0, 0}}, // (141, 69) + { 0, { 0, 0, 0}}, // (142, 69) + { 0, { 0, 0, 0}}, // (143, 69) + { 0, { 0, 0, 0}}, // (144, 69) + { 0, { 0, 0, 0}}, // (145, 69) + { 0, { 0, 0, 0}}, // (146, 69) + { 0, { 0, 0, 0}}, // (147, 69) + { 0, { 0, 0, 0}}, // (148, 69) + { 0, { 0, 0, 0}}, // (149, 69) + { 0, { 0, 0, 0}}, // (150, 69) + { 0, { 0, 0, 0}}, // (151, 69) + { 0, { 0, 0, 0}}, // (152, 69) + { 0, { 0, 0, 0}}, // (153, 69) + { 0, { 0, 0, 0}}, // (154, 69) + { 0, { 0, 0, 0}}, // (155, 69) + { 0, { 0, 0, 0}}, // (156, 69) + { 0, { 0, 0, 0}}, // (157, 69) + { 0, { 0, 0, 0}}, // (158, 69) + { 0, { 0, 0, 0}}, // (159, 69) + { 0, { 0, 0, 0}}, // (160, 69) + { 0, { 0, 0, 0}}, // (161, 69) + { 0, { 0, 0, 0}}, // (162, 69) + { 0, { 0, 0, 0}}, // (163, 69) + { 0, { 0, 0, 0}}, // (164, 69) + { 0, { 0, 0, 0}}, // (165, 69) + { 0, { 0, 0, 0}}, // (166, 69) + { 0, { 0, 0, 0}}, // (167, 69) + { 0, { 0, 0, 0}}, // (168, 69) + { 0, { 0, 0, 0}}, // (169, 69) + { 0, { 0, 0, 0}}, // (170, 69) + { 0, { 0, 0, 0}}, // (171, 69) + { 0, { 0, 0, 0}}, // (172, 69) + { 0, { 0, 0, 0}}, // (173, 69) + { 0, { 0, 0, 0}}, // (174, 69) + { 52, { 0, 0, 0}}, // (175, 69) + {128, { 0, 0, 0}}, // (176, 69) + {128, { 0, 0, 0}}, // (177, 69) + {128, { 0, 0, 0}}, // (178, 69) + {128, { 0, 0, 0}}, // (179, 69) + {128, { 0, 0, 0}}, // ( 0, 70) + {128, { 0, 0, 0}}, // ( 1, 70) + {128, { 0, 0, 0}}, // ( 2, 70) + {128, { 0, 0, 0}}, // ( 3, 70) + { 22, { 0, 0, 0}}, // ( 4, 70) + { 0, { 0, 0, 0}}, // ( 5, 70) + { 0, { 0, 0, 0}}, // ( 6, 70) + { 0, { 0, 0, 0}}, // ( 7, 70) + { 0, { 0, 0, 0}}, // ( 8, 70) + { 0, { 0, 0, 0}}, // ( 9, 70) + { 0, { 0, 0, 0}}, // ( 10, 70) + { 0, { 0, 0, 0}}, // ( 11, 70) + { 0, { 0, 0, 0}}, // ( 12, 70) + { 0, { 0, 0, 0}}, // ( 13, 70) + { 0, { 0, 0, 0}}, // ( 14, 70) + { 0, { 0, 0, 0}}, // ( 15, 70) + { 0, { 0, 0, 0}}, // ( 16, 70) + { 0, { 0, 0, 0}}, // ( 17, 70) + { 0, { 0, 0, 0}}, // ( 18, 70) + { 0, { 0, 0, 0}}, // ( 19, 70) + { 0, { 0, 0, 0}}, // ( 20, 70) + { 0, { 0, 0, 0}}, // ( 21, 70) + { 0, { 0, 0, 0}}, // ( 22, 70) + { 0, { 0, 0, 0}}, // ( 23, 70) + { 0, { 0, 0, 0}}, // ( 24, 70) + { 0, { 0, 0, 0}}, // ( 25, 70) + { 0, { 0, 0, 0}}, // ( 26, 70) + { 0, { 0, 0, 0}}, // ( 27, 70) + { 0, { 0, 0, 0}}, // ( 28, 70) + { 0, { 0, 0, 0}}, // ( 29, 70) + { 0, { 0, 0, 0}}, // ( 30, 70) + { 0, { 0, 0, 0}}, // ( 31, 70) + { 0, { 0, 0, 0}}, // ( 32, 70) + { 0, { 0, 0, 0}}, // ( 33, 70) + { 0, { 0, 0, 0}}, // ( 34, 70) + { 0, { 0, 0, 0}}, // ( 35, 70) + { 0, { 0, 0, 0}}, // ( 36, 70) + { 0, { 0, 0, 0}}, // ( 37, 70) + { 0, { 0, 0, 0}}, // ( 38, 70) + { 0, { 0, 0, 0}}, // ( 39, 70) + { 0, { 0, 0, 0}}, // ( 40, 70) + { 0, { 0, 0, 0}}, // ( 41, 70) + { 0, { 0, 0, 0}}, // ( 42, 70) + { 0, { 0, 0, 0}}, // ( 43, 70) + { 0, { 0, 0, 0}}, // ( 44, 70) + { 0, { 0, 0, 0}}, // ( 45, 70) + { 0, { 0, 0, 0}}, // ( 46, 70) + { 0, { 0, 0, 0}}, // ( 47, 70) + { 0, { 0, 0, 0}}, // ( 48, 70) + { 0, { 0, 0, 0}}, // ( 49, 70) + { 0, { 0, 0, 0}}, // ( 50, 70) + { 0, { 0, 0, 0}}, // ( 51, 70) + { 0, { 0, 0, 0}}, // ( 52, 70) + { 0, { 0, 0, 0}}, // ( 53, 70) + { 0, { 0, 0, 0}}, // ( 54, 70) + { 0, { 0, 0, 0}}, // ( 55, 70) + { 0, { 0, 0, 0}}, // ( 56, 70) + { 0, { 0, 0, 0}}, // ( 57, 70) + { 0, { 0, 0, 0}}, // ( 58, 70) + { 0, { 0, 0, 0}}, // ( 59, 70) + { 0, { 0, 0, 0}}, // ( 60, 70) + { 0, { 0, 0, 0}}, // ( 61, 70) + { 0, { 0, 0, 0}}, // ( 62, 70) + { 0, { 0, 0, 0}}, // ( 63, 70) + { 0, { 0, 0, 0}}, // ( 64, 70) + { 0, { 0, 0, 0}}, // ( 65, 70) + { 0, { 0, 0, 0}}, // ( 66, 70) + { 0, { 0, 0, 0}}, // ( 67, 70) + { 0, { 0, 0, 0}}, // ( 68, 70) + { 0, { 0, 0, 0}}, // ( 69, 70) + { 0, { 0, 0, 0}}, // ( 70, 70) + { 0, { 0, 0, 0}}, // ( 71, 70) + { 0, { 0, 0, 0}}, // ( 72, 70) + { 0, { 0, 0, 0}}, // ( 73, 70) + { 0, { 0, 0, 0}}, // ( 74, 70) + { 0, { 0, 0, 0}}, // ( 75, 70) + { 0, { 0, 0, 0}}, // ( 76, 70) + { 0, { 0, 0, 0}}, // ( 77, 70) + { 0, { 0, 0, 0}}, // ( 78, 70) + { 0, { 0, 0, 0}}, // ( 79, 70) + { 0, { 0, 0, 0}}, // ( 80, 70) + { 0, { 0, 0, 0}}, // ( 81, 70) + { 0, { 0, 0, 0}}, // ( 82, 70) + { 0, { 0, 0, 0}}, // ( 83, 70) + { 0, { 0, 0, 0}}, // ( 84, 70) + { 0, { 0, 0, 0}}, // ( 85, 70) + { 0, { 0, 0, 0}}, // ( 86, 70) + { 0, { 0, 0, 0}}, // ( 87, 70) + { 0, { 0, 0, 0}}, // ( 88, 70) + { 0, { 0, 0, 0}}, // ( 89, 70) + { 0, { 0, 0, 0}}, // ( 90, 70) + { 0, { 0, 0, 0}}, // ( 91, 70) + { 0, { 0, 0, 0}}, // ( 92, 70) + { 0, { 0, 0, 0}}, // ( 93, 70) + { 0, { 0, 0, 0}}, // ( 94, 70) + { 0, { 0, 0, 0}}, // ( 95, 70) + { 0, { 0, 0, 0}}, // ( 96, 70) + { 0, { 0, 0, 0}}, // ( 97, 70) + { 0, { 0, 0, 0}}, // ( 98, 70) + { 0, { 0, 0, 0}}, // ( 99, 70) + { 0, { 0, 0, 0}}, // (100, 70) + { 0, { 0, 0, 0}}, // (101, 70) + { 0, { 0, 0, 0}}, // (102, 70) + { 0, { 0, 0, 0}}, // (103, 70) + { 0, { 0, 0, 0}}, // (104, 70) + { 0, { 0, 0, 0}}, // (105, 70) + { 0, { 0, 0, 0}}, // (106, 70) + { 0, { 0, 0, 0}}, // (107, 70) + { 0, { 0, 0, 0}}, // (108, 70) + { 0, { 0, 0, 0}}, // (109, 70) + { 0, { 0, 0, 0}}, // (110, 70) + { 0, { 0, 0, 0}}, // (111, 70) + { 0, { 0, 0, 0}}, // (112, 70) + { 0, { 0, 0, 0}}, // (113, 70) + { 0, { 0, 0, 0}}, // (114, 70) + { 0, { 0, 0, 0}}, // (115, 70) + { 0, { 0, 0, 0}}, // (116, 70) + { 0, { 0, 0, 0}}, // (117, 70) + { 0, { 0, 0, 0}}, // (118, 70) + { 0, { 0, 0, 0}}, // (119, 70) + { 0, { 0, 0, 0}}, // (120, 70) + { 0, { 0, 0, 0}}, // (121, 70) + { 0, { 0, 0, 0}}, // (122, 70) + { 0, { 0, 0, 0}}, // (123, 70) + { 0, { 0, 0, 0}}, // (124, 70) + { 0, { 0, 0, 0}}, // (125, 70) + { 0, { 0, 0, 0}}, // (126, 70) + { 0, { 0, 0, 0}}, // (127, 70) + { 0, { 0, 0, 0}}, // (128, 70) + { 0, { 0, 0, 0}}, // (129, 70) + { 0, { 0, 0, 0}}, // (130, 70) + { 0, { 0, 0, 0}}, // (131, 70) + { 0, { 0, 0, 0}}, // (132, 70) + { 0, { 0, 0, 0}}, // (133, 70) + { 0, { 0, 0, 0}}, // (134, 70) + { 0, { 0, 0, 0}}, // (135, 70) + { 0, { 0, 0, 0}}, // (136, 70) + { 0, { 0, 0, 0}}, // (137, 70) + { 0, { 0, 0, 0}}, // (138, 70) + { 0, { 0, 0, 0}}, // (139, 70) + { 0, { 0, 0, 0}}, // (140, 70) + { 0, { 0, 0, 0}}, // (141, 70) + { 0, { 0, 0, 0}}, // (142, 70) + { 0, { 0, 0, 0}}, // (143, 70) + { 0, { 0, 0, 0}}, // (144, 70) + { 0, { 0, 0, 0}}, // (145, 70) + { 0, { 0, 0, 0}}, // (146, 70) + { 0, { 0, 0, 0}}, // (147, 70) + { 0, { 0, 0, 0}}, // (148, 70) + { 0, { 0, 0, 0}}, // (149, 70) + { 0, { 0, 0, 0}}, // (150, 70) + { 0, { 0, 0, 0}}, // (151, 70) + { 0, { 0, 0, 0}}, // (152, 70) + { 0, { 0, 0, 0}}, // (153, 70) + { 0, { 0, 0, 0}}, // (154, 70) + { 0, { 0, 0, 0}}, // (155, 70) + { 0, { 0, 0, 0}}, // (156, 70) + { 0, { 0, 0, 0}}, // (157, 70) + { 0, { 0, 0, 0}}, // (158, 70) + { 0, { 0, 0, 0}}, // (159, 70) + { 0, { 0, 0, 0}}, // (160, 70) + { 0, { 0, 0, 0}}, // (161, 70) + { 0, { 0, 0, 0}}, // (162, 70) + { 0, { 0, 0, 0}}, // (163, 70) + { 0, { 0, 0, 0}}, // (164, 70) + { 0, { 0, 0, 0}}, // (165, 70) + { 0, { 0, 0, 0}}, // (166, 70) + { 0, { 0, 0, 0}}, // (167, 70) + { 0, { 0, 0, 0}}, // (168, 70) + { 0, { 0, 0, 0}}, // (169, 70) + { 0, { 0, 0, 0}}, // (170, 70) + { 0, { 0, 0, 0}}, // (171, 70) + { 0, { 0, 0, 0}}, // (172, 70) + { 0, { 0, 0, 0}}, // (173, 70) + { 0, { 0, 0, 0}}, // (174, 70) + { 22, { 0, 0, 0}}, // (175, 70) + {128, { 0, 0, 0}}, // (176, 70) + {128, { 0, 0, 0}}, // (177, 70) + {128, { 0, 0, 0}}, // (178, 70) + {128, { 0, 0, 0}}, // (179, 70) + {128, { 0, 0, 0}}, // ( 0, 71) + {128, { 0, 0, 0}}, // ( 1, 71) + {128, { 0, 0, 0}}, // ( 2, 71) + {120, { 0, 0, 0}}, // ( 3, 71) + { 1, { 0, 0, 0}}, // ( 4, 71) + { 0, { 0, 0, 0}}, // ( 5, 71) + { 0, { 0, 0, 0}}, // ( 6, 71) + { 0, { 0, 0, 0}}, // ( 7, 71) + { 0, { 0, 0, 0}}, // ( 8, 71) + { 0, { 0, 0, 0}}, // ( 9, 71) + { 0, { 0, 0, 0}}, // ( 10, 71) + { 0, { 0, 0, 0}}, // ( 11, 71) + { 0, { 0, 0, 0}}, // ( 12, 71) + { 0, { 0, 0, 0}}, // ( 13, 71) + { 0, { 0, 0, 0}}, // ( 14, 71) + { 0, { 0, 0, 0}}, // ( 15, 71) + { 0, { 0, 0, 0}}, // ( 16, 71) + { 0, { 0, 0, 0}}, // ( 17, 71) + { 0, { 0, 0, 0}}, // ( 18, 71) + { 0, { 0, 0, 0}}, // ( 19, 71) + { 0, { 0, 0, 0}}, // ( 20, 71) + { 0, { 0, 0, 0}}, // ( 21, 71) + { 0, { 0, 0, 0}}, // ( 22, 71) + { 0, { 0, 0, 0}}, // ( 23, 71) + { 0, { 0, 0, 0}}, // ( 24, 71) + { 0, { 0, 0, 0}}, // ( 25, 71) + { 0, { 0, 0, 0}}, // ( 26, 71) + { 0, { 0, 0, 0}}, // ( 27, 71) + { 0, { 0, 0, 0}}, // ( 28, 71) + { 0, { 0, 0, 0}}, // ( 29, 71) + { 0, { 0, 0, 0}}, // ( 30, 71) + { 0, { 0, 0, 0}}, // ( 31, 71) + { 0, { 0, 0, 0}}, // ( 32, 71) + { 0, { 0, 0, 0}}, // ( 33, 71) + { 0, { 0, 0, 0}}, // ( 34, 71) + { 0, { 0, 0, 0}}, // ( 35, 71) + { 0, { 0, 0, 0}}, // ( 36, 71) + { 0, { 0, 0, 0}}, // ( 37, 71) + { 0, { 0, 0, 0}}, // ( 38, 71) + { 0, { 0, 0, 0}}, // ( 39, 71) + { 0, { 0, 0, 0}}, // ( 40, 71) + { 0, { 0, 0, 0}}, // ( 41, 71) + { 0, { 0, 0, 0}}, // ( 42, 71) + { 0, { 0, 0, 0}}, // ( 43, 71) + { 0, { 0, 0, 0}}, // ( 44, 71) + { 0, { 0, 0, 0}}, // ( 45, 71) + { 0, { 0, 0, 0}}, // ( 46, 71) + { 0, { 0, 0, 0}}, // ( 47, 71) + { 0, { 0, 0, 0}}, // ( 48, 71) + { 0, { 0, 0, 0}}, // ( 49, 71) + { 0, { 0, 0, 0}}, // ( 50, 71) + { 0, { 0, 0, 0}}, // ( 51, 71) + { 0, { 0, 0, 0}}, // ( 52, 71) + { 0, { 0, 0, 0}}, // ( 53, 71) + { 0, { 0, 0, 0}}, // ( 54, 71) + { 0, { 0, 0, 0}}, // ( 55, 71) + { 0, { 0, 0, 0}}, // ( 56, 71) + { 0, { 0, 0, 0}}, // ( 57, 71) + { 0, { 0, 0, 0}}, // ( 58, 71) + { 0, { 0, 0, 0}}, // ( 59, 71) + { 0, { 0, 0, 0}}, // ( 60, 71) + { 0, { 0, 0, 0}}, // ( 61, 71) + { 0, { 0, 0, 0}}, // ( 62, 71) + { 0, { 0, 0, 0}}, // ( 63, 71) + { 0, { 0, 0, 0}}, // ( 64, 71) + { 0, { 0, 0, 0}}, // ( 65, 71) + { 0, { 0, 0, 0}}, // ( 66, 71) + { 0, { 0, 0, 0}}, // ( 67, 71) + { 0, { 0, 0, 0}}, // ( 68, 71) + { 0, { 0, 0, 0}}, // ( 69, 71) + { 0, { 0, 0, 0}}, // ( 70, 71) + { 0, { 0, 0, 0}}, // ( 71, 71) + { 0, { 0, 0, 0}}, // ( 72, 71) + { 0, { 0, 0, 0}}, // ( 73, 71) + { 0, { 0, 0, 0}}, // ( 74, 71) + { 0, { 0, 0, 0}}, // ( 75, 71) + { 0, { 0, 0, 0}}, // ( 76, 71) + { 0, { 0, 0, 0}}, // ( 77, 71) + { 0, { 0, 0, 0}}, // ( 78, 71) + { 0, { 0, 0, 0}}, // ( 79, 71) + { 0, { 0, 0, 0}}, // ( 80, 71) + { 0, { 0, 0, 0}}, // ( 81, 71) + { 0, { 0, 0, 0}}, // ( 82, 71) + { 0, { 0, 0, 0}}, // ( 83, 71) + { 0, { 0, 0, 0}}, // ( 84, 71) + { 0, { 0, 0, 0}}, // ( 85, 71) + { 0, { 0, 0, 0}}, // ( 86, 71) + { 0, { 0, 0, 0}}, // ( 87, 71) + { 0, { 0, 0, 0}}, // ( 88, 71) + { 0, { 0, 0, 0}}, // ( 89, 71) + { 0, { 0, 0, 0}}, // ( 90, 71) + { 0, { 0, 0, 0}}, // ( 91, 71) + { 0, { 0, 0, 0}}, // ( 92, 71) + { 0, { 0, 0, 0}}, // ( 93, 71) + { 0, { 0, 0, 0}}, // ( 94, 71) + { 0, { 0, 0, 0}}, // ( 95, 71) + { 0, { 0, 0, 0}}, // ( 96, 71) + { 0, { 0, 0, 0}}, // ( 97, 71) + { 0, { 0, 0, 0}}, // ( 98, 71) + { 0, { 0, 0, 0}}, // ( 99, 71) + { 0, { 0, 0, 0}}, // (100, 71) + { 0, { 0, 0, 0}}, // (101, 71) + { 0, { 0, 0, 0}}, // (102, 71) + { 0, { 0, 0, 0}}, // (103, 71) + { 0, { 0, 0, 0}}, // (104, 71) + { 0, { 0, 0, 0}}, // (105, 71) + { 0, { 0, 0, 0}}, // (106, 71) + { 0, { 0, 0, 0}}, // (107, 71) + { 0, { 0, 0, 0}}, // (108, 71) + { 0, { 0, 0, 0}}, // (109, 71) + { 0, { 0, 0, 0}}, // (110, 71) + { 0, { 0, 0, 0}}, // (111, 71) + { 0, { 0, 0, 0}}, // (112, 71) + { 0, { 0, 0, 0}}, // (113, 71) + { 0, { 0, 0, 0}}, // (114, 71) + { 0, { 0, 0, 0}}, // (115, 71) + { 0, { 0, 0, 0}}, // (116, 71) + { 0, { 0, 0, 0}}, // (117, 71) + { 0, { 0, 0, 0}}, // (118, 71) + { 0, { 0, 0, 0}}, // (119, 71) + { 0, { 0, 0, 0}}, // (120, 71) + { 0, { 0, 0, 0}}, // (121, 71) + { 0, { 0, 0, 0}}, // (122, 71) + { 0, { 0, 0, 0}}, // (123, 71) + { 0, { 0, 0, 0}}, // (124, 71) + { 0, { 0, 0, 0}}, // (125, 71) + { 0, { 0, 0, 0}}, // (126, 71) + { 0, { 0, 0, 0}}, // (127, 71) + { 0, { 0, 0, 0}}, // (128, 71) + { 0, { 0, 0, 0}}, // (129, 71) + { 0, { 0, 0, 0}}, // (130, 71) + { 0, { 0, 0, 0}}, // (131, 71) + { 0, { 0, 0, 0}}, // (132, 71) + { 0, { 0, 0, 0}}, // (133, 71) + { 0, { 0, 0, 0}}, // (134, 71) + { 0, { 0, 0, 0}}, // (135, 71) + { 0, { 0, 0, 0}}, // (136, 71) + { 0, { 0, 0, 0}}, // (137, 71) + { 0, { 0, 0, 0}}, // (138, 71) + { 0, { 0, 0, 0}}, // (139, 71) + { 0, { 0, 0, 0}}, // (140, 71) + { 0, { 0, 0, 0}}, // (141, 71) + { 0, { 0, 0, 0}}, // (142, 71) + { 0, { 0, 0, 0}}, // (143, 71) + { 0, { 0, 0, 0}}, // (144, 71) + { 0, { 0, 0, 0}}, // (145, 71) + { 0, { 0, 0, 0}}, // (146, 71) + { 0, { 0, 0, 0}}, // (147, 71) + { 0, { 0, 0, 0}}, // (148, 71) + { 0, { 0, 0, 0}}, // (149, 71) + { 0, { 0, 0, 0}}, // (150, 71) + { 0, { 0, 0, 0}}, // (151, 71) + { 0, { 0, 0, 0}}, // (152, 71) + { 0, { 0, 0, 0}}, // (153, 71) + { 0, { 0, 0, 0}}, // (154, 71) + { 0, { 0, 0, 0}}, // (155, 71) + { 0, { 0, 0, 0}}, // (156, 71) + { 0, { 0, 0, 0}}, // (157, 71) + { 0, { 0, 0, 0}}, // (158, 71) + { 0, { 0, 0, 0}}, // (159, 71) + { 0, { 0, 0, 0}}, // (160, 71) + { 0, { 0, 0, 0}}, // (161, 71) + { 0, { 0, 0, 0}}, // (162, 71) + { 0, { 0, 0, 0}}, // (163, 71) + { 0, { 0, 0, 0}}, // (164, 71) + { 0, { 0, 0, 0}}, // (165, 71) + { 0, { 0, 0, 0}}, // (166, 71) + { 0, { 0, 0, 0}}, // (167, 71) + { 0, { 0, 0, 0}}, // (168, 71) + { 0, { 0, 0, 0}}, // (169, 71) + { 0, { 0, 0, 0}}, // (170, 71) + { 0, { 0, 0, 0}}, // (171, 71) + { 0, { 0, 0, 0}}, // (172, 71) + { 0, { 0, 0, 0}}, // (173, 71) + { 0, { 0, 0, 0}}, // (174, 71) + { 1, { 0, 0, 0}}, // (175, 71) + {120, { 0, 0, 0}}, // (176, 71) + {128, { 0, 0, 0}}, // (177, 71) + {128, { 0, 0, 0}}, // (178, 71) + {128, { 0, 0, 0}}, // (179, 71) + {128, { 0, 0, 0}}, // ( 0, 72) + {128, { 0, 0, 0}}, // ( 1, 72) + {128, { 0, 0, 0}}, // ( 2, 72) + { 95, { 0, 0, 0}}, // ( 3, 72) + { 0, { 0, 0, 0}}, // ( 4, 72) + { 0, { 0, 0, 0}}, // ( 5, 72) + { 0, { 0, 0, 0}}, // ( 6, 72) + { 0, { 0, 0, 0}}, // ( 7, 72) + { 0, { 0, 0, 0}}, // ( 8, 72) + { 0, { 0, 0, 0}}, // ( 9, 72) + { 0, { 0, 0, 0}}, // ( 10, 72) + { 0, { 0, 0, 0}}, // ( 11, 72) + { 0, { 0, 0, 0}}, // ( 12, 72) + { 0, { 0, 0, 0}}, // ( 13, 72) + { 0, { 0, 0, 0}}, // ( 14, 72) + { 0, { 0, 0, 0}}, // ( 15, 72) + { 0, { 0, 0, 0}}, // ( 16, 72) + { 0, { 0, 0, 0}}, // ( 17, 72) + { 0, { 0, 0, 0}}, // ( 18, 72) + { 0, { 0, 0, 0}}, // ( 19, 72) + { 0, { 0, 0, 0}}, // ( 20, 72) + { 0, { 0, 0, 0}}, // ( 21, 72) + { 0, { 0, 0, 0}}, // ( 22, 72) + { 0, { 0, 0, 0}}, // ( 23, 72) + { 0, { 0, 0, 0}}, // ( 24, 72) + { 0, { 0, 0, 0}}, // ( 25, 72) + { 0, { 0, 0, 0}}, // ( 26, 72) + { 0, { 0, 0, 0}}, // ( 27, 72) + { 0, { 0, 0, 0}}, // ( 28, 72) + { 0, { 0, 0, 0}}, // ( 29, 72) + { 0, { 0, 0, 0}}, // ( 30, 72) + { 0, { 0, 0, 0}}, // ( 31, 72) + { 0, { 0, 0, 0}}, // ( 32, 72) + { 0, { 0, 0, 0}}, // ( 33, 72) + { 0, { 0, 0, 0}}, // ( 34, 72) + { 0, { 0, 0, 0}}, // ( 35, 72) + { 0, { 0, 0, 0}}, // ( 36, 72) + { 0, { 0, 0, 0}}, // ( 37, 72) + { 0, { 0, 0, 0}}, // ( 38, 72) + { 0, { 0, 0, 0}}, // ( 39, 72) + { 0, { 0, 0, 0}}, // ( 40, 72) + { 0, { 0, 0, 0}}, // ( 41, 72) + { 0, { 0, 0, 0}}, // ( 42, 72) + { 0, { 0, 0, 0}}, // ( 43, 72) + { 0, { 0, 0, 0}}, // ( 44, 72) + { 0, { 0, 0, 0}}, // ( 45, 72) + { 0, { 0, 0, 0}}, // ( 46, 72) + { 0, { 0, 0, 0}}, // ( 47, 72) + { 0, { 0, 0, 0}}, // ( 48, 72) + { 0, { 0, 0, 0}}, // ( 49, 72) + { 0, { 0, 0, 0}}, // ( 50, 72) + { 0, { 0, 0, 0}}, // ( 51, 72) + { 0, { 0, 0, 0}}, // ( 52, 72) + { 0, { 0, 0, 0}}, // ( 53, 72) + { 0, { 0, 0, 0}}, // ( 54, 72) + { 0, { 0, 0, 0}}, // ( 55, 72) + { 0, { 0, 0, 0}}, // ( 56, 72) + { 0, { 0, 0, 0}}, // ( 57, 72) + { 0, { 0, 0, 0}}, // ( 58, 72) + { 0, { 0, 0, 0}}, // ( 59, 72) + { 0, { 0, 0, 0}}, // ( 60, 72) + { 0, { 0, 0, 0}}, // ( 61, 72) + { 0, { 0, 0, 0}}, // ( 62, 72) + { 0, { 0, 0, 0}}, // ( 63, 72) + { 0, { 0, 0, 0}}, // ( 64, 72) + { 0, { 0, 0, 0}}, // ( 65, 72) + { 0, { 0, 0, 0}}, // ( 66, 72) + { 0, { 0, 0, 0}}, // ( 67, 72) + { 0, { 0, 0, 0}}, // ( 68, 72) + { 0, { 0, 0, 0}}, // ( 69, 72) + { 0, { 0, 0, 0}}, // ( 70, 72) + { 0, { 0, 0, 0}}, // ( 71, 72) + { 0, { 0, 0, 0}}, // ( 72, 72) + { 0, { 0, 0, 0}}, // ( 73, 72) + { 0, { 0, 0, 0}}, // ( 74, 72) + { 0, { 0, 0, 0}}, // ( 75, 72) + { 0, { 0, 0, 0}}, // ( 76, 72) + { 0, { 0, 0, 0}}, // ( 77, 72) + { 0, { 0, 0, 0}}, // ( 78, 72) + { 0, { 0, 0, 0}}, // ( 79, 72) + { 0, { 0, 0, 0}}, // ( 80, 72) + { 0, { 0, 0, 0}}, // ( 81, 72) + { 0, { 0, 0, 0}}, // ( 82, 72) + { 0, { 0, 0, 0}}, // ( 83, 72) + { 0, { 0, 0, 0}}, // ( 84, 72) + { 0, { 0, 0, 0}}, // ( 85, 72) + { 0, { 0, 0, 0}}, // ( 86, 72) + { 0, { 0, 0, 0}}, // ( 87, 72) + { 0, { 0, 0, 0}}, // ( 88, 72) + { 0, { 0, 0, 0}}, // ( 89, 72) + { 0, { 0, 0, 0}}, // ( 90, 72) + { 0, { 0, 0, 0}}, // ( 91, 72) + { 0, { 0, 0, 0}}, // ( 92, 72) + { 0, { 0, 0, 0}}, // ( 93, 72) + { 0, { 0, 0, 0}}, // ( 94, 72) + { 0, { 0, 0, 0}}, // ( 95, 72) + { 0, { 0, 0, 0}}, // ( 96, 72) + { 0, { 0, 0, 0}}, // ( 97, 72) + { 0, { 0, 0, 0}}, // ( 98, 72) + { 0, { 0, 0, 0}}, // ( 99, 72) + { 0, { 0, 0, 0}}, // (100, 72) + { 0, { 0, 0, 0}}, // (101, 72) + { 0, { 0, 0, 0}}, // (102, 72) + { 0, { 0, 0, 0}}, // (103, 72) + { 0, { 0, 0, 0}}, // (104, 72) + { 0, { 0, 0, 0}}, // (105, 72) + { 0, { 0, 0, 0}}, // (106, 72) + { 0, { 0, 0, 0}}, // (107, 72) + { 0, { 0, 0, 0}}, // (108, 72) + { 0, { 0, 0, 0}}, // (109, 72) + { 0, { 0, 0, 0}}, // (110, 72) + { 0, { 0, 0, 0}}, // (111, 72) + { 0, { 0, 0, 0}}, // (112, 72) + { 0, { 0, 0, 0}}, // (113, 72) + { 0, { 0, 0, 0}}, // (114, 72) + { 0, { 0, 0, 0}}, // (115, 72) + { 0, { 0, 0, 0}}, // (116, 72) + { 0, { 0, 0, 0}}, // (117, 72) + { 0, { 0, 0, 0}}, // (118, 72) + { 0, { 0, 0, 0}}, // (119, 72) + { 0, { 0, 0, 0}}, // (120, 72) + { 0, { 0, 0, 0}}, // (121, 72) + { 0, { 0, 0, 0}}, // (122, 72) + { 0, { 0, 0, 0}}, // (123, 72) + { 0, { 0, 0, 0}}, // (124, 72) + { 0, { 0, 0, 0}}, // (125, 72) + { 0, { 0, 0, 0}}, // (126, 72) + { 0, { 0, 0, 0}}, // (127, 72) + { 0, { 0, 0, 0}}, // (128, 72) + { 0, { 0, 0, 0}}, // (129, 72) + { 0, { 0, 0, 0}}, // (130, 72) + { 0, { 0, 0, 0}}, // (131, 72) + { 0, { 0, 0, 0}}, // (132, 72) + { 0, { 0, 0, 0}}, // (133, 72) + { 0, { 0, 0, 0}}, // (134, 72) + { 0, { 0, 0, 0}}, // (135, 72) + { 0, { 0, 0, 0}}, // (136, 72) + { 0, { 0, 0, 0}}, // (137, 72) + { 0, { 0, 0, 0}}, // (138, 72) + { 0, { 0, 0, 0}}, // (139, 72) + { 0, { 0, 0, 0}}, // (140, 72) + { 0, { 0, 0, 0}}, // (141, 72) + { 0, { 0, 0, 0}}, // (142, 72) + { 0, { 0, 0, 0}}, // (143, 72) + { 0, { 0, 0, 0}}, // (144, 72) + { 0, { 0, 0, 0}}, // (145, 72) + { 0, { 0, 0, 0}}, // (146, 72) + { 0, { 0, 0, 0}}, // (147, 72) + { 0, { 0, 0, 0}}, // (148, 72) + { 0, { 0, 0, 0}}, // (149, 72) + { 0, { 0, 0, 0}}, // (150, 72) + { 0, { 0, 0, 0}}, // (151, 72) + { 0, { 0, 0, 0}}, // (152, 72) + { 0, { 0, 0, 0}}, // (153, 72) + { 0, { 0, 0, 0}}, // (154, 72) + { 0, { 0, 0, 0}}, // (155, 72) + { 0, { 0, 0, 0}}, // (156, 72) + { 0, { 0, 0, 0}}, // (157, 72) + { 0, { 0, 0, 0}}, // (158, 72) + { 0, { 0, 0, 0}}, // (159, 72) + { 0, { 0, 0, 0}}, // (160, 72) + { 0, { 0, 0, 0}}, // (161, 72) + { 0, { 0, 0, 0}}, // (162, 72) + { 0, { 0, 0, 0}}, // (163, 72) + { 0, { 0, 0, 0}}, // (164, 72) + { 0, { 0, 0, 0}}, // (165, 72) + { 0, { 0, 0, 0}}, // (166, 72) + { 0, { 0, 0, 0}}, // (167, 72) + { 0, { 0, 0, 0}}, // (168, 72) + { 0, { 0, 0, 0}}, // (169, 72) + { 0, { 0, 0, 0}}, // (170, 72) + { 0, { 0, 0, 0}}, // (171, 72) + { 0, { 0, 0, 0}}, // (172, 72) + { 0, { 0, 0, 0}}, // (173, 72) + { 0, { 0, 0, 0}}, // (174, 72) + { 0, { 0, 0, 0}}, // (175, 72) + { 95, { 0, 0, 0}}, // (176, 72) + {128, { 0, 0, 0}}, // (177, 72) + {128, { 0, 0, 0}}, // (178, 72) + {128, { 0, 0, 0}}, // (179, 72) + {128, { 0, 0, 0}}, // ( 0, 73) + {128, { 0, 0, 0}}, // ( 1, 73) + {128, { 0, 0, 0}}, // ( 2, 73) + { 72, { 0, 0, 0}}, // ( 3, 73) + { 0, { 0, 0, 0}}, // ( 4, 73) + { 0, { 0, 0, 0}}, // ( 5, 73) + { 0, { 0, 0, 0}}, // ( 6, 73) + { 0, { 0, 0, 0}}, // ( 7, 73) + { 0, { 0, 0, 0}}, // ( 8, 73) + { 0, { 0, 0, 0}}, // ( 9, 73) + { 0, { 0, 0, 0}}, // ( 10, 73) + { 0, { 0, 0, 0}}, // ( 11, 73) + { 0, { 0, 0, 0}}, // ( 12, 73) + { 0, { 0, 0, 0}}, // ( 13, 73) + { 0, { 0, 0, 0}}, // ( 14, 73) + { 0, { 0, 0, 0}}, // ( 15, 73) + { 0, { 0, 0, 0}}, // ( 16, 73) + { 0, { 0, 0, 0}}, // ( 17, 73) + { 0, { 0, 0, 0}}, // ( 18, 73) + { 0, { 0, 0, 0}}, // ( 19, 73) + { 0, { 0, 0, 0}}, // ( 20, 73) + { 0, { 0, 0, 0}}, // ( 21, 73) + { 0, { 0, 0, 0}}, // ( 22, 73) + { 0, { 0, 0, 0}}, // ( 23, 73) + { 0, { 0, 0, 0}}, // ( 24, 73) + { 0, { 0, 0, 0}}, // ( 25, 73) + { 0, { 0, 0, 0}}, // ( 26, 73) + { 0, { 0, 0, 0}}, // ( 27, 73) + { 0, { 0, 0, 0}}, // ( 28, 73) + { 0, { 0, 0, 0}}, // ( 29, 73) + { 0, { 0, 0, 0}}, // ( 30, 73) + { 0, { 0, 0, 0}}, // ( 31, 73) + { 0, { 0, 0, 0}}, // ( 32, 73) + { 0, { 0, 0, 0}}, // ( 33, 73) + { 0, { 0, 0, 0}}, // ( 34, 73) + { 0, { 0, 0, 0}}, // ( 35, 73) + { 0, { 0, 0, 0}}, // ( 36, 73) + { 0, { 0, 0, 0}}, // ( 37, 73) + { 0, { 0, 0, 0}}, // ( 38, 73) + { 0, { 0, 0, 0}}, // ( 39, 73) + { 0, { 0, 0, 0}}, // ( 40, 73) + { 0, { 0, 0, 0}}, // ( 41, 73) + { 0, { 0, 0, 0}}, // ( 42, 73) + { 0, { 0, 0, 0}}, // ( 43, 73) + { 0, { 0, 0, 0}}, // ( 44, 73) + { 0, { 0, 0, 0}}, // ( 45, 73) + { 0, { 0, 0, 0}}, // ( 46, 73) + { 0, { 0, 0, 0}}, // ( 47, 73) + { 0, { 0, 0, 0}}, // ( 48, 73) + { 0, { 0, 0, 0}}, // ( 49, 73) + { 0, { 0, 0, 0}}, // ( 50, 73) + { 0, { 0, 0, 0}}, // ( 51, 73) + { 0, { 0, 0, 0}}, // ( 52, 73) + { 0, { 0, 0, 0}}, // ( 53, 73) + { 0, { 0, 0, 0}}, // ( 54, 73) + { 0, { 0, 0, 0}}, // ( 55, 73) + { 0, { 0, 0, 0}}, // ( 56, 73) + { 0, { 0, 0, 0}}, // ( 57, 73) + { 0, { 0, 0, 0}}, // ( 58, 73) + { 0, { 0, 0, 0}}, // ( 59, 73) + { 0, { 0, 0, 0}}, // ( 60, 73) + { 0, { 0, 0, 0}}, // ( 61, 73) + { 0, { 0, 0, 0}}, // ( 62, 73) + { 0, { 0, 0, 0}}, // ( 63, 73) + { 0, { 0, 0, 0}}, // ( 64, 73) + { 0, { 0, 0, 0}}, // ( 65, 73) + { 0, { 0, 0, 0}}, // ( 66, 73) + { 0, { 0, 0, 0}}, // ( 67, 73) + { 0, { 0, 0, 0}}, // ( 68, 73) + { 0, { 0, 0, 0}}, // ( 69, 73) + { 0, { 0, 0, 0}}, // ( 70, 73) + { 0, { 0, 0, 0}}, // ( 71, 73) + { 0, { 0, 0, 0}}, // ( 72, 73) + { 0, { 0, 0, 0}}, // ( 73, 73) + { 0, { 0, 0, 0}}, // ( 74, 73) + { 0, { 0, 0, 0}}, // ( 75, 73) + { 0, { 0, 0, 0}}, // ( 76, 73) + { 0, { 0, 0, 0}}, // ( 77, 73) + { 0, { 0, 0, 0}}, // ( 78, 73) + { 0, { 0, 0, 0}}, // ( 79, 73) + { 0, { 0, 0, 0}}, // ( 80, 73) + { 0, { 0, 0, 0}}, // ( 81, 73) + { 0, { 0, 0, 0}}, // ( 82, 73) + { 0, { 0, 0, 0}}, // ( 83, 73) + { 0, { 0, 0, 0}}, // ( 84, 73) + { 0, { 0, 0, 0}}, // ( 85, 73) + { 0, { 0, 0, 0}}, // ( 86, 73) + { 0, { 0, 0, 0}}, // ( 87, 73) + { 0, { 0, 0, 0}}, // ( 88, 73) + { 0, { 0, 0, 0}}, // ( 89, 73) + { 0, { 0, 0, 0}}, // ( 90, 73) + { 0, { 0, 0, 0}}, // ( 91, 73) + { 0, { 0, 0, 0}}, // ( 92, 73) + { 0, { 0, 0, 0}}, // ( 93, 73) + { 0, { 0, 0, 0}}, // ( 94, 73) + { 0, { 0, 0, 0}}, // ( 95, 73) + { 0, { 0, 0, 0}}, // ( 96, 73) + { 0, { 0, 0, 0}}, // ( 97, 73) + { 0, { 0, 0, 0}}, // ( 98, 73) + { 0, { 0, 0, 0}}, // ( 99, 73) + { 0, { 0, 0, 0}}, // (100, 73) + { 0, { 0, 0, 0}}, // (101, 73) + { 0, { 0, 0, 0}}, // (102, 73) + { 0, { 0, 0, 0}}, // (103, 73) + { 0, { 0, 0, 0}}, // (104, 73) + { 0, { 0, 0, 0}}, // (105, 73) + { 0, { 0, 0, 0}}, // (106, 73) + { 0, { 0, 0, 0}}, // (107, 73) + { 0, { 0, 0, 0}}, // (108, 73) + { 0, { 0, 0, 0}}, // (109, 73) + { 0, { 0, 0, 0}}, // (110, 73) + { 0, { 0, 0, 0}}, // (111, 73) + { 0, { 0, 0, 0}}, // (112, 73) + { 0, { 0, 0, 0}}, // (113, 73) + { 0, { 0, 0, 0}}, // (114, 73) + { 0, { 0, 0, 0}}, // (115, 73) + { 0, { 0, 0, 0}}, // (116, 73) + { 0, { 0, 0, 0}}, // (117, 73) + { 0, { 0, 0, 0}}, // (118, 73) + { 0, { 0, 0, 0}}, // (119, 73) + { 0, { 0, 0, 0}}, // (120, 73) + { 0, { 0, 0, 0}}, // (121, 73) + { 0, { 0, 0, 0}}, // (122, 73) + { 0, { 0, 0, 0}}, // (123, 73) + { 0, { 0, 0, 0}}, // (124, 73) + { 0, { 0, 0, 0}}, // (125, 73) + { 0, { 0, 0, 0}}, // (126, 73) + { 0, { 0, 0, 0}}, // (127, 73) + { 0, { 0, 0, 0}}, // (128, 73) + { 0, { 0, 0, 0}}, // (129, 73) + { 0, { 0, 0, 0}}, // (130, 73) + { 0, { 0, 0, 0}}, // (131, 73) + { 0, { 0, 0, 0}}, // (132, 73) + { 0, { 0, 0, 0}}, // (133, 73) + { 0, { 0, 0, 0}}, // (134, 73) + { 0, { 0, 0, 0}}, // (135, 73) + { 0, { 0, 0, 0}}, // (136, 73) + { 0, { 0, 0, 0}}, // (137, 73) + { 0, { 0, 0, 0}}, // (138, 73) + { 0, { 0, 0, 0}}, // (139, 73) + { 0, { 0, 0, 0}}, // (140, 73) + { 0, { 0, 0, 0}}, // (141, 73) + { 0, { 0, 0, 0}}, // (142, 73) + { 0, { 0, 0, 0}}, // (143, 73) + { 0, { 0, 0, 0}}, // (144, 73) + { 0, { 0, 0, 0}}, // (145, 73) + { 0, { 0, 0, 0}}, // (146, 73) + { 0, { 0, 0, 0}}, // (147, 73) + { 0, { 0, 0, 0}}, // (148, 73) + { 0, { 0, 0, 0}}, // (149, 73) + { 0, { 0, 0, 0}}, // (150, 73) + { 0, { 0, 0, 0}}, // (151, 73) + { 0, { 0, 0, 0}}, // (152, 73) + { 0, { 0, 0, 0}}, // (153, 73) + { 0, { 0, 0, 0}}, // (154, 73) + { 0, { 0, 0, 0}}, // (155, 73) + { 0, { 0, 0, 0}}, // (156, 73) + { 0, { 0, 0, 0}}, // (157, 73) + { 0, { 0, 0, 0}}, // (158, 73) + { 0, { 0, 0, 0}}, // (159, 73) + { 0, { 0, 0, 0}}, // (160, 73) + { 0, { 0, 0, 0}}, // (161, 73) + { 0, { 0, 0, 0}}, // (162, 73) + { 0, { 0, 0, 0}}, // (163, 73) + { 0, { 0, 0, 0}}, // (164, 73) + { 0, { 0, 0, 0}}, // (165, 73) + { 0, { 0, 0, 0}}, // (166, 73) + { 0, { 0, 0, 0}}, // (167, 73) + { 0, { 0, 0, 0}}, // (168, 73) + { 0, { 0, 0, 0}}, // (169, 73) + { 0, { 0, 0, 0}}, // (170, 73) + { 0, { 0, 0, 0}}, // (171, 73) + { 0, { 0, 0, 0}}, // (172, 73) + { 0, { 0, 0, 0}}, // (173, 73) + { 0, { 0, 0, 0}}, // (174, 73) + { 0, { 0, 0, 0}}, // (175, 73) + { 70, { 0, 0, 0}}, // (176, 73) + {128, { 0, 0, 0}}, // (177, 73) + {128, { 0, 0, 0}}, // (178, 73) + {128, { 0, 0, 0}}, // (179, 73) + {128, { 0, 0, 0}}, // ( 0, 74) + {128, { 0, 0, 0}}, // ( 1, 74) + {128, { 0, 0, 0}}, // ( 2, 74) + { 50, { 0, 0, 0}}, // ( 3, 74) + { 0, { 0, 0, 0}}, // ( 4, 74) + { 0, { 0, 0, 0}}, // ( 5, 74) + { 0, { 0, 0, 0}}, // ( 6, 74) + { 0, { 0, 0, 0}}, // ( 7, 74) + { 0, { 0, 0, 0}}, // ( 8, 74) + { 0, { 0, 0, 0}}, // ( 9, 74) + { 0, { 0, 0, 0}}, // ( 10, 74) + { 0, { 0, 0, 0}}, // ( 11, 74) + { 0, { 0, 0, 0}}, // ( 12, 74) + { 0, { 0, 0, 0}}, // ( 13, 74) + { 0, { 0, 0, 0}}, // ( 14, 74) + { 0, { 0, 0, 0}}, // ( 15, 74) + { 0, { 0, 0, 0}}, // ( 16, 74) + { 0, { 0, 0, 0}}, // ( 17, 74) + { 0, { 0, 0, 0}}, // ( 18, 74) + { 0, { 0, 0, 0}}, // ( 19, 74) + { 0, { 0, 0, 0}}, // ( 20, 74) + { 0, { 0, 0, 0}}, // ( 21, 74) + { 0, { 0, 0, 0}}, // ( 22, 74) + { 0, { 0, 0, 0}}, // ( 23, 74) + { 0, { 0, 0, 0}}, // ( 24, 74) + { 0, { 0, 0, 0}}, // ( 25, 74) + { 0, { 0, 0, 0}}, // ( 26, 74) + { 0, { 0, 0, 0}}, // ( 27, 74) + { 0, { 0, 0, 0}}, // ( 28, 74) + { 0, { 0, 0, 0}}, // ( 29, 74) + { 0, { 0, 0, 0}}, // ( 30, 74) + { 0, { 0, 0, 0}}, // ( 31, 74) + { 0, { 0, 0, 0}}, // ( 32, 74) + { 0, { 0, 0, 0}}, // ( 33, 74) + { 0, { 0, 0, 0}}, // ( 34, 74) + { 0, { 0, 0, 0}}, // ( 35, 74) + { 0, { 0, 0, 0}}, // ( 36, 74) + { 0, { 0, 0, 0}}, // ( 37, 74) + { 0, { 0, 0, 0}}, // ( 38, 74) + { 0, { 0, 0, 0}}, // ( 39, 74) + { 0, { 0, 0, 0}}, // ( 40, 74) + { 0, { 0, 0, 0}}, // ( 41, 74) + { 0, { 0, 0, 0}}, // ( 42, 74) + { 0, { 0, 0, 0}}, // ( 43, 74) + { 0, { 0, 0, 0}}, // ( 44, 74) + { 0, { 0, 0, 0}}, // ( 45, 74) + { 0, { 0, 0, 0}}, // ( 46, 74) + { 0, { 0, 0, 0}}, // ( 47, 74) + { 0, { 0, 0, 0}}, // ( 48, 74) + { 0, { 0, 0, 0}}, // ( 49, 74) + { 0, { 0, 0, 0}}, // ( 50, 74) + { 0, { 0, 0, 0}}, // ( 51, 74) + { 0, { 0, 0, 0}}, // ( 52, 74) + { 0, { 0, 0, 0}}, // ( 53, 74) + { 0, { 0, 0, 0}}, // ( 54, 74) + { 0, { 0, 0, 0}}, // ( 55, 74) + { 0, { 0, 0, 0}}, // ( 56, 74) + { 0, { 0, 0, 0}}, // ( 57, 74) + { 0, { 0, 0, 0}}, // ( 58, 74) + { 0, { 0, 0, 0}}, // ( 59, 74) + { 0, { 0, 0, 0}}, // ( 60, 74) + { 0, { 0, 0, 0}}, // ( 61, 74) + { 0, { 0, 0, 0}}, // ( 62, 74) + { 0, { 0, 0, 0}}, // ( 63, 74) + { 0, { 0, 0, 0}}, // ( 64, 74) + { 0, { 0, 0, 0}}, // ( 65, 74) + { 0, { 0, 0, 0}}, // ( 66, 74) + { 0, { 0, 0, 0}}, // ( 67, 74) + { 0, { 0, 0, 0}}, // ( 68, 74) + { 0, { 0, 0, 0}}, // ( 69, 74) + { 0, { 0, 0, 0}}, // ( 70, 74) + { 0, { 0, 0, 0}}, // ( 71, 74) + { 0, { 0, 0, 0}}, // ( 72, 74) + { 0, { 0, 0, 0}}, // ( 73, 74) + { 0, { 0, 0, 0}}, // ( 74, 74) + { 0, { 0, 0, 0}}, // ( 75, 74) + { 0, { 0, 0, 0}}, // ( 76, 74) + { 0, { 0, 0, 0}}, // ( 77, 74) + { 0, { 0, 0, 0}}, // ( 78, 74) + { 0, { 0, 0, 0}}, // ( 79, 74) + { 0, { 0, 0, 0}}, // ( 80, 74) + { 0, { 0, 0, 0}}, // ( 81, 74) + { 0, { 0, 0, 0}}, // ( 82, 74) + { 0, { 0, 0, 0}}, // ( 83, 74) + { 0, { 0, 0, 0}}, // ( 84, 74) + { 0, { 0, 0, 0}}, // ( 85, 74) + { 0, { 0, 0, 0}}, // ( 86, 74) + { 0, { 0, 0, 0}}, // ( 87, 74) + { 0, { 0, 0, 0}}, // ( 88, 74) + { 0, { 0, 0, 0}}, // ( 89, 74) + { 0, { 0, 0, 0}}, // ( 90, 74) + { 0, { 0, 0, 0}}, // ( 91, 74) + { 0, { 0, 0, 0}}, // ( 92, 74) + { 0, { 0, 0, 0}}, // ( 93, 74) + { 0, { 0, 0, 0}}, // ( 94, 74) + { 0, { 0, 0, 0}}, // ( 95, 74) + { 0, { 0, 0, 0}}, // ( 96, 74) + { 0, { 0, 0, 0}}, // ( 97, 74) + { 0, { 0, 0, 0}}, // ( 98, 74) + { 0, { 0, 0, 0}}, // ( 99, 74) + { 0, { 0, 0, 0}}, // (100, 74) + { 0, { 0, 0, 0}}, // (101, 74) + { 0, { 0, 0, 0}}, // (102, 74) + { 0, { 0, 0, 0}}, // (103, 74) + { 0, { 0, 0, 0}}, // (104, 74) + { 0, { 0, 0, 0}}, // (105, 74) + { 0, { 0, 0, 0}}, // (106, 74) + { 0, { 0, 0, 0}}, // (107, 74) + { 0, { 0, 0, 0}}, // (108, 74) + { 0, { 0, 0, 0}}, // (109, 74) + { 0, { 0, 0, 0}}, // (110, 74) + { 0, { 0, 0, 0}}, // (111, 74) + { 0, { 0, 0, 0}}, // (112, 74) + { 0, { 0, 0, 0}}, // (113, 74) + { 0, { 0, 0, 0}}, // (114, 74) + { 0, { 0, 0, 0}}, // (115, 74) + { 0, { 0, 0, 0}}, // (116, 74) + { 0, { 0, 0, 0}}, // (117, 74) + { 0, { 0, 0, 0}}, // (118, 74) + { 0, { 0, 0, 0}}, // (119, 74) + { 0, { 0, 0, 0}}, // (120, 74) + { 0, { 0, 0, 0}}, // (121, 74) + { 0, { 0, 0, 0}}, // (122, 74) + { 0, { 0, 0, 0}}, // (123, 74) + { 0, { 0, 0, 0}}, // (124, 74) + { 0, { 0, 0, 0}}, // (125, 74) + { 0, { 0, 0, 0}}, // (126, 74) + { 0, { 0, 0, 0}}, // (127, 74) + { 0, { 0, 0, 0}}, // (128, 74) + { 0, { 0, 0, 0}}, // (129, 74) + { 0, { 0, 0, 0}}, // (130, 74) + { 0, { 0, 0, 0}}, // (131, 74) + { 0, { 0, 0, 0}}, // (132, 74) + { 0, { 0, 0, 0}}, // (133, 74) + { 0, { 0, 0, 0}}, // (134, 74) + { 0, { 0, 0, 0}}, // (135, 74) + { 0, { 0, 0, 0}}, // (136, 74) + { 0, { 0, 0, 0}}, // (137, 74) + { 0, { 0, 0, 0}}, // (138, 74) + { 0, { 0, 0, 0}}, // (139, 74) + { 0, { 0, 0, 0}}, // (140, 74) + { 0, { 0, 0, 0}}, // (141, 74) + { 0, { 0, 0, 0}}, // (142, 74) + { 0, { 0, 0, 0}}, // (143, 74) + { 0, { 0, 0, 0}}, // (144, 74) + { 0, { 0, 0, 0}}, // (145, 74) + { 0, { 0, 0, 0}}, // (146, 74) + { 0, { 0, 0, 0}}, // (147, 74) + { 0, { 0, 0, 0}}, // (148, 74) + { 0, { 0, 0, 0}}, // (149, 74) + { 0, { 0, 0, 0}}, // (150, 74) + { 0, { 0, 0, 0}}, // (151, 74) + { 0, { 0, 0, 0}}, // (152, 74) + { 0, { 0, 0, 0}}, // (153, 74) + { 0, { 0, 0, 0}}, // (154, 74) + { 0, { 0, 0, 0}}, // (155, 74) + { 0, { 0, 0, 0}}, // (156, 74) + { 0, { 0, 0, 0}}, // (157, 74) + { 0, { 0, 0, 0}}, // (158, 74) + { 0, { 0, 0, 0}}, // (159, 74) + { 0, { 0, 0, 0}}, // (160, 74) + { 0, { 0, 0, 0}}, // (161, 74) + { 0, { 0, 0, 0}}, // (162, 74) + { 0, { 0, 0, 0}}, // (163, 74) + { 0, { 0, 0, 0}}, // (164, 74) + { 0, { 0, 0, 0}}, // (165, 74) + { 0, { 0, 0, 0}}, // (166, 74) + { 0, { 0, 0, 0}}, // (167, 74) + { 0, { 0, 0, 0}}, // (168, 74) + { 0, { 0, 0, 0}}, // (169, 74) + { 0, { 0, 0, 0}}, // (170, 74) + { 0, { 0, 0, 0}}, // (171, 74) + { 0, { 0, 0, 0}}, // (172, 74) + { 0, { 0, 0, 0}}, // (173, 74) + { 0, { 0, 0, 0}}, // (174, 74) + { 0, { 0, 0, 0}}, // (175, 74) + { 47, { 0, 0, 0}}, // (176, 74) + {128, { 0, 0, 0}}, // (177, 74) + {128, { 0, 0, 0}}, // (178, 74) + {128, { 0, 0, 0}}, // (179, 74) + {128, { 0, 0, 0}}, // ( 0, 75) + {128, { 0, 0, 0}}, // ( 1, 75) + {128, { 0, 0, 0}}, // ( 2, 75) + { 27, { 0, 0, 0}}, // ( 3, 75) + { 0, { 0, 0, 0}}, // ( 4, 75) + { 0, { 0, 0, 0}}, // ( 5, 75) + { 0, { 0, 0, 0}}, // ( 6, 75) + { 0, { 0, 0, 0}}, // ( 7, 75) + { 0, { 0, 0, 0}}, // ( 8, 75) + { 0, { 0, 0, 0}}, // ( 9, 75) + { 0, { 0, 0, 0}}, // ( 10, 75) + { 0, { 0, 0, 0}}, // ( 11, 75) + { 0, { 0, 0, 0}}, // ( 12, 75) + { 0, { 0, 0, 0}}, // ( 13, 75) + { 0, { 0, 0, 0}}, // ( 14, 75) + { 0, { 0, 0, 0}}, // ( 15, 75) + { 0, { 0, 0, 0}}, // ( 16, 75) + { 0, { 0, 0, 0}}, // ( 17, 75) + { 0, { 0, 0, 0}}, // ( 18, 75) + { 0, { 0, 0, 0}}, // ( 19, 75) + { 0, { 0, 0, 0}}, // ( 20, 75) + { 0, { 0, 0, 0}}, // ( 21, 75) + { 0, { 0, 0, 0}}, // ( 22, 75) + { 0, { 0, 0, 0}}, // ( 23, 75) + { 0, { 0, 0, 0}}, // ( 24, 75) + { 0, { 0, 0, 0}}, // ( 25, 75) + { 0, { 0, 0, 0}}, // ( 26, 75) + { 0, { 0, 0, 0}}, // ( 27, 75) + { 0, { 0, 0, 0}}, // ( 28, 75) + { 0, { 0, 0, 0}}, // ( 29, 75) + { 0, { 0, 0, 0}}, // ( 30, 75) + { 0, { 0, 0, 0}}, // ( 31, 75) + { 0, { 0, 0, 0}}, // ( 32, 75) + { 0, { 0, 0, 0}}, // ( 33, 75) + { 0, { 0, 0, 0}}, // ( 34, 75) + { 0, { 0, 0, 0}}, // ( 35, 75) + { 0, { 0, 0, 0}}, // ( 36, 75) + { 0, { 0, 0, 0}}, // ( 37, 75) + { 0, { 0, 0, 0}}, // ( 38, 75) + { 0, { 0, 0, 0}}, // ( 39, 75) + { 0, { 0, 0, 0}}, // ( 40, 75) + { 0, { 0, 0, 0}}, // ( 41, 75) + { 0, { 0, 0, 0}}, // ( 42, 75) + { 0, { 0, 0, 0}}, // ( 43, 75) + { 0, { 0, 0, 0}}, // ( 44, 75) + { 0, { 0, 0, 0}}, // ( 45, 75) + { 0, { 0, 0, 0}}, // ( 46, 75) + { 0, { 0, 0, 0}}, // ( 47, 75) + { 0, { 0, 0, 0}}, // ( 48, 75) + { 0, { 0, 0, 0}}, // ( 49, 75) + { 0, { 0, 0, 0}}, // ( 50, 75) + { 0, { 0, 0, 0}}, // ( 51, 75) + { 0, { 0, 0, 0}}, // ( 52, 75) + { 0, { 0, 0, 0}}, // ( 53, 75) + { 0, { 0, 0, 0}}, // ( 54, 75) + { 0, { 0, 0, 0}}, // ( 55, 75) + { 0, { 0, 0, 0}}, // ( 56, 75) + { 0, { 0, 0, 0}}, // ( 57, 75) + { 0, { 0, 0, 0}}, // ( 58, 75) + { 0, { 0, 0, 0}}, // ( 59, 75) + { 0, { 0, 0, 0}}, // ( 60, 75) + { 0, { 0, 0, 0}}, // ( 61, 75) + { 0, { 0, 0, 0}}, // ( 62, 75) + { 0, { 0, 0, 0}}, // ( 63, 75) + { 0, { 0, 0, 0}}, // ( 64, 75) + { 0, { 0, 0, 0}}, // ( 65, 75) + { 0, { 0, 0, 0}}, // ( 66, 75) + { 0, { 0, 0, 0}}, // ( 67, 75) + { 0, { 0, 0, 0}}, // ( 68, 75) + { 0, { 0, 0, 0}}, // ( 69, 75) + { 0, { 0, 0, 0}}, // ( 70, 75) + { 0, { 0, 0, 0}}, // ( 71, 75) + { 0, { 0, 0, 0}}, // ( 72, 75) + { 0, { 0, 0, 0}}, // ( 73, 75) + { 0, { 0, 0, 0}}, // ( 74, 75) + { 0, { 0, 0, 0}}, // ( 75, 75) + { 0, { 0, 0, 0}}, // ( 76, 75) + { 0, { 0, 0, 0}}, // ( 77, 75) + { 0, { 0, 0, 0}}, // ( 78, 75) + { 0, { 0, 0, 0}}, // ( 79, 75) + { 0, { 0, 0, 0}}, // ( 80, 75) + { 0, { 0, 0, 0}}, // ( 81, 75) + { 0, { 0, 0, 0}}, // ( 82, 75) + { 0, { 0, 0, 0}}, // ( 83, 75) + { 0, { 0, 0, 0}}, // ( 84, 75) + { 0, { 0, 0, 0}}, // ( 85, 75) + { 0, { 0, 0, 0}}, // ( 86, 75) + { 0, { 0, 0, 0}}, // ( 87, 75) + { 0, { 0, 0, 0}}, // ( 88, 75) + { 0, { 0, 0, 0}}, // ( 89, 75) + { 0, { 0, 0, 0}}, // ( 90, 75) + { 0, { 0, 0, 0}}, // ( 91, 75) + { 0, { 0, 0, 0}}, // ( 92, 75) + { 0, { 0, 0, 0}}, // ( 93, 75) + { 0, { 0, 0, 0}}, // ( 94, 75) + { 0, { 0, 0, 0}}, // ( 95, 75) + { 0, { 0, 0, 0}}, // ( 96, 75) + { 0, { 0, 0, 0}}, // ( 97, 75) + { 0, { 0, 0, 0}}, // ( 98, 75) + { 0, { 0, 0, 0}}, // ( 99, 75) + { 0, { 0, 0, 0}}, // (100, 75) + { 0, { 0, 0, 0}}, // (101, 75) + { 0, { 0, 0, 0}}, // (102, 75) + { 0, { 0, 0, 0}}, // (103, 75) + { 0, { 0, 0, 0}}, // (104, 75) + { 0, { 0, 0, 0}}, // (105, 75) + { 0, { 0, 0, 0}}, // (106, 75) + { 0, { 0, 0, 0}}, // (107, 75) + { 0, { 0, 0, 0}}, // (108, 75) + { 0, { 0, 0, 0}}, // (109, 75) + { 0, { 0, 0, 0}}, // (110, 75) + { 0, { 0, 0, 0}}, // (111, 75) + { 0, { 0, 0, 0}}, // (112, 75) + { 0, { 0, 0, 0}}, // (113, 75) + { 0, { 0, 0, 0}}, // (114, 75) + { 0, { 0, 0, 0}}, // (115, 75) + { 0, { 0, 0, 0}}, // (116, 75) + { 0, { 0, 0, 0}}, // (117, 75) + { 0, { 0, 0, 0}}, // (118, 75) + { 0, { 0, 0, 0}}, // (119, 75) + { 0, { 0, 0, 0}}, // (120, 75) + { 0, { 0, 0, 0}}, // (121, 75) + { 0, { 0, 0, 0}}, // (122, 75) + { 0, { 0, 0, 0}}, // (123, 75) + { 0, { 0, 0, 0}}, // (124, 75) + { 0, { 0, 0, 0}}, // (125, 75) + { 0, { 0, 0, 0}}, // (126, 75) + { 0, { 0, 0, 0}}, // (127, 75) + { 0, { 0, 0, 0}}, // (128, 75) + { 0, { 0, 0, 0}}, // (129, 75) + { 0, { 0, 0, 0}}, // (130, 75) + { 0, { 0, 0, 0}}, // (131, 75) + { 0, { 0, 0, 0}}, // (132, 75) + { 0, { 0, 0, 0}}, // (133, 75) + { 0, { 0, 0, 0}}, // (134, 75) + { 0, { 0, 0, 0}}, // (135, 75) + { 0, { 0, 0, 0}}, // (136, 75) + { 0, { 0, 0, 0}}, // (137, 75) + { 0, { 0, 0, 0}}, // (138, 75) + { 0, { 0, 0, 0}}, // (139, 75) + { 0, { 0, 0, 0}}, // (140, 75) + { 0, { 0, 0, 0}}, // (141, 75) + { 0, { 0, 0, 0}}, // (142, 75) + { 0, { 0, 0, 0}}, // (143, 75) + { 0, { 0, 0, 0}}, // (144, 75) + { 0, { 0, 0, 0}}, // (145, 75) + { 0, { 0, 0, 0}}, // (146, 75) + { 0, { 0, 0, 0}}, // (147, 75) + { 0, { 0, 0, 0}}, // (148, 75) + { 0, { 0, 0, 0}}, // (149, 75) + { 0, { 0, 0, 0}}, // (150, 75) + { 0, { 0, 0, 0}}, // (151, 75) + { 0, { 0, 0, 0}}, // (152, 75) + { 0, { 0, 0, 0}}, // (153, 75) + { 0, { 0, 0, 0}}, // (154, 75) + { 0, { 0, 0, 0}}, // (155, 75) + { 0, { 0, 0, 0}}, // (156, 75) + { 0, { 0, 0, 0}}, // (157, 75) + { 0, { 0, 0, 0}}, // (158, 75) + { 0, { 0, 0, 0}}, // (159, 75) + { 0, { 0, 0, 0}}, // (160, 75) + { 0, { 0, 0, 0}}, // (161, 75) + { 0, { 0, 0, 0}}, // (162, 75) + { 0, { 0, 0, 0}}, // (163, 75) + { 0, { 0, 0, 0}}, // (164, 75) + { 0, { 0, 0, 0}}, // (165, 75) + { 0, { 0, 0, 0}}, // (166, 75) + { 0, { 0, 0, 0}}, // (167, 75) + { 0, { 0, 0, 0}}, // (168, 75) + { 0, { 0, 0, 0}}, // (169, 75) + { 0, { 0, 0, 0}}, // (170, 75) + { 0, { 0, 0, 0}}, // (171, 75) + { 0, { 0, 0, 0}}, // (172, 75) + { 0, { 0, 0, 0}}, // (173, 75) + { 0, { 0, 0, 0}}, // (174, 75) + { 0, { 0, 0, 0}}, // (175, 75) + { 25, { 0, 0, 0}}, // (176, 75) + {128, { 0, 0, 0}}, // (177, 75) + {128, { 0, 0, 0}}, // (178, 75) + {128, { 0, 0, 0}}, // (179, 75) + {128, { 0, 0, 0}}, // ( 0, 76) + {128, { 0, 0, 0}}, // ( 1, 76) + {127, { 0, 0, 0}}, // ( 2, 76) + { 6, { 0, 0, 0}}, // ( 3, 76) + { 0, { 0, 0, 0}}, // ( 4, 76) + { 0, { 0, 0, 0}}, // ( 5, 76) + { 0, { 0, 0, 0}}, // ( 6, 76) + { 0, { 0, 0, 0}}, // ( 7, 76) + { 0, { 0, 0, 0}}, // ( 8, 76) + { 0, { 0, 0, 0}}, // ( 9, 76) + { 0, { 0, 0, 0}}, // ( 10, 76) + { 0, { 0, 0, 0}}, // ( 11, 76) + { 0, { 0, 0, 0}}, // ( 12, 76) + { 0, { 0, 0, 0}}, // ( 13, 76) + { 0, { 0, 0, 0}}, // ( 14, 76) + { 0, { 0, 0, 0}}, // ( 15, 76) + { 0, { 0, 0, 0}}, // ( 16, 76) + { 0, { 0, 0, 0}}, // ( 17, 76) + { 0, { 0, 0, 0}}, // ( 18, 76) + { 0, { 0, 0, 0}}, // ( 19, 76) + { 0, { 0, 0, 0}}, // ( 20, 76) + { 0, { 0, 0, 0}}, // ( 21, 76) + { 0, { 0, 0, 0}}, // ( 22, 76) + { 0, { 0, 0, 0}}, // ( 23, 76) + { 0, { 0, 0, 0}}, // ( 24, 76) + { 0, { 0, 0, 0}}, // ( 25, 76) + { 0, { 0, 0, 0}}, // ( 26, 76) + { 0, { 0, 0, 0}}, // ( 27, 76) + { 0, { 0, 0, 0}}, // ( 28, 76) + { 0, { 0, 0, 0}}, // ( 29, 76) + { 0, { 0, 0, 0}}, // ( 30, 76) + { 0, { 0, 0, 0}}, // ( 31, 76) + { 0, { 0, 0, 0}}, // ( 32, 76) + { 0, { 0, 0, 0}}, // ( 33, 76) + { 0, { 0, 0, 0}}, // ( 34, 76) + { 0, { 0, 0, 0}}, // ( 35, 76) + { 0, { 0, 0, 0}}, // ( 36, 76) + { 0, { 0, 0, 0}}, // ( 37, 76) + { 0, { 0, 0, 0}}, // ( 38, 76) + { 0, { 0, 0, 0}}, // ( 39, 76) + { 0, { 0, 0, 0}}, // ( 40, 76) + { 0, { 0, 0, 0}}, // ( 41, 76) + { 0, { 0, 0, 0}}, // ( 42, 76) + { 0, { 0, 0, 0}}, // ( 43, 76) + { 0, { 0, 0, 0}}, // ( 44, 76) + { 0, { 0, 0, 0}}, // ( 45, 76) + { 0, { 0, 0, 0}}, // ( 46, 76) + { 0, { 0, 0, 0}}, // ( 47, 76) + { 0, { 0, 0, 0}}, // ( 48, 76) + { 0, { 0, 0, 0}}, // ( 49, 76) + { 0, { 0, 0, 0}}, // ( 50, 76) + { 0, { 0, 0, 0}}, // ( 51, 76) + { 0, { 0, 0, 0}}, // ( 52, 76) + { 0, { 0, 0, 0}}, // ( 53, 76) + { 0, { 0, 0, 0}}, // ( 54, 76) + { 0, { 0, 0, 0}}, // ( 55, 76) + { 0, { 0, 0, 0}}, // ( 56, 76) + { 0, { 0, 0, 0}}, // ( 57, 76) + { 0, { 0, 0, 0}}, // ( 58, 76) + { 0, { 0, 0, 0}}, // ( 59, 76) + { 0, { 0, 0, 0}}, // ( 60, 76) + { 0, { 0, 0, 0}}, // ( 61, 76) + { 0, { 0, 0, 0}}, // ( 62, 76) + { 0, { 0, 0, 0}}, // ( 63, 76) + { 0, { 0, 0, 0}}, // ( 64, 76) + { 0, { 0, 0, 0}}, // ( 65, 76) + { 0, { 0, 0, 0}}, // ( 66, 76) + { 0, { 0, 0, 0}}, // ( 67, 76) + { 0, { 0, 0, 0}}, // ( 68, 76) + { 0, { 0, 0, 0}}, // ( 69, 76) + { 0, { 0, 0, 0}}, // ( 70, 76) + { 0, { 0, 0, 0}}, // ( 71, 76) + { 0, { 0, 0, 0}}, // ( 72, 76) + { 0, { 0, 0, 0}}, // ( 73, 76) + { 0, { 0, 0, 0}}, // ( 74, 76) + { 0, { 0, 0, 0}}, // ( 75, 76) + { 0, { 0, 0, 0}}, // ( 76, 76) + { 0, { 0, 0, 0}}, // ( 77, 76) + { 0, { 0, 0, 0}}, // ( 78, 76) + { 0, { 0, 0, 0}}, // ( 79, 76) + { 0, { 0, 0, 0}}, // ( 80, 76) + { 0, { 0, 0, 0}}, // ( 81, 76) + { 0, { 0, 0, 0}}, // ( 82, 76) + { 0, { 0, 0, 0}}, // ( 83, 76) + { 0, { 0, 0, 0}}, // ( 84, 76) + { 0, { 0, 0, 0}}, // ( 85, 76) + { 0, { 0, 0, 0}}, // ( 86, 76) + { 0, { 0, 0, 0}}, // ( 87, 76) + { 0, { 0, 0, 0}}, // ( 88, 76) + { 0, { 0, 0, 0}}, // ( 89, 76) + { 0, { 0, 0, 0}}, // ( 90, 76) + { 0, { 0, 0, 0}}, // ( 91, 76) + { 0, { 0, 0, 0}}, // ( 92, 76) + { 0, { 0, 0, 0}}, // ( 93, 76) + { 0, { 0, 0, 0}}, // ( 94, 76) + { 0, { 0, 0, 0}}, // ( 95, 76) + { 0, { 0, 0, 0}}, // ( 96, 76) + { 0, { 0, 0, 0}}, // ( 97, 76) + { 0, { 0, 0, 0}}, // ( 98, 76) + { 0, { 0, 0, 0}}, // ( 99, 76) + { 0, { 0, 0, 0}}, // (100, 76) + { 0, { 0, 0, 0}}, // (101, 76) + { 0, { 0, 0, 0}}, // (102, 76) + { 0, { 0, 0, 0}}, // (103, 76) + { 0, { 0, 0, 0}}, // (104, 76) + { 0, { 0, 0, 0}}, // (105, 76) + { 0, { 0, 0, 0}}, // (106, 76) + { 0, { 0, 0, 0}}, // (107, 76) + { 0, { 0, 0, 0}}, // (108, 76) + { 0, { 0, 0, 0}}, // (109, 76) + { 0, { 0, 0, 0}}, // (110, 76) + { 0, { 0, 0, 0}}, // (111, 76) + { 0, { 0, 0, 0}}, // (112, 76) + { 0, { 0, 0, 0}}, // (113, 76) + { 0, { 0, 0, 0}}, // (114, 76) + { 0, { 0, 0, 0}}, // (115, 76) + { 0, { 0, 0, 0}}, // (116, 76) + { 0, { 0, 0, 0}}, // (117, 76) + { 0, { 0, 0, 0}}, // (118, 76) + { 0, { 0, 0, 0}}, // (119, 76) + { 0, { 0, 0, 0}}, // (120, 76) + { 0, { 0, 0, 0}}, // (121, 76) + { 0, { 0, 0, 0}}, // (122, 76) + { 0, { 0, 0, 0}}, // (123, 76) + { 0, { 0, 0, 0}}, // (124, 76) + { 0, { 0, 0, 0}}, // (125, 76) + { 0, { 0, 0, 0}}, // (126, 76) + { 0, { 0, 0, 0}}, // (127, 76) + { 0, { 0, 0, 0}}, // (128, 76) + { 0, { 0, 0, 0}}, // (129, 76) + { 0, { 0, 0, 0}}, // (130, 76) + { 0, { 0, 0, 0}}, // (131, 76) + { 0, { 0, 0, 0}}, // (132, 76) + { 0, { 0, 0, 0}}, // (133, 76) + { 0, { 0, 0, 0}}, // (134, 76) + { 0, { 0, 0, 0}}, // (135, 76) + { 0, { 0, 0, 0}}, // (136, 76) + { 0, { 0, 0, 0}}, // (137, 76) + { 0, { 0, 0, 0}}, // (138, 76) + { 0, { 0, 0, 0}}, // (139, 76) + { 0, { 0, 0, 0}}, // (140, 76) + { 0, { 0, 0, 0}}, // (141, 76) + { 0, { 0, 0, 0}}, // (142, 76) + { 0, { 0, 0, 0}}, // (143, 76) + { 0, { 0, 0, 0}}, // (144, 76) + { 0, { 0, 0, 0}}, // (145, 76) + { 0, { 0, 0, 0}}, // (146, 76) + { 0, { 0, 0, 0}}, // (147, 76) + { 0, { 0, 0, 0}}, // (148, 76) + { 0, { 0, 0, 0}}, // (149, 76) + { 0, { 0, 0, 0}}, // (150, 76) + { 0, { 0, 0, 0}}, // (151, 76) + { 0, { 0, 0, 0}}, // (152, 76) + { 0, { 0, 0, 0}}, // (153, 76) + { 0, { 0, 0, 0}}, // (154, 76) + { 0, { 0, 0, 0}}, // (155, 76) + { 0, { 0, 0, 0}}, // (156, 76) + { 0, { 0, 0, 0}}, // (157, 76) + { 0, { 0, 0, 0}}, // (158, 76) + { 0, { 0, 0, 0}}, // (159, 76) + { 0, { 0, 0, 0}}, // (160, 76) + { 0, { 0, 0, 0}}, // (161, 76) + { 0, { 0, 0, 0}}, // (162, 76) + { 0, { 0, 0, 0}}, // (163, 76) + { 0, { 0, 0, 0}}, // (164, 76) + { 0, { 0, 0, 0}}, // (165, 76) + { 0, { 0, 0, 0}}, // (166, 76) + { 0, { 0, 0, 0}}, // (167, 76) + { 0, { 0, 0, 0}}, // (168, 76) + { 0, { 0, 0, 0}}, // (169, 76) + { 0, { 0, 0, 0}}, // (170, 76) + { 0, { 0, 0, 0}}, // (171, 76) + { 0, { 0, 0, 0}}, // (172, 76) + { 0, { 0, 0, 0}}, // (173, 76) + { 0, { 0, 0, 0}}, // (174, 76) + { 0, { 0, 0, 0}}, // (175, 76) + { 5, { 0, 0, 0}}, // (176, 76) + {127, { 0, 0, 0}}, // (177, 76) + {128, { 0, 0, 0}}, // (178, 76) + {128, { 0, 0, 0}}, // (179, 76) + {128, { 0, 0, 0}}, // ( 0, 77) + {128, { 0, 0, 0}}, // ( 1, 77) + {115, { 0, 0, 0}}, // ( 2, 77) + { 0, { 0, 0, 0}}, // ( 3, 77) + { 0, { 0, 0, 0}}, // ( 4, 77) + { 0, { 0, 0, 0}}, // ( 5, 77) + { 0, { 0, 0, 0}}, // ( 6, 77) + { 0, { 0, 0, 0}}, // ( 7, 77) + { 0, { 0, 0, 0}}, // ( 8, 77) + { 0, { 0, 0, 0}}, // ( 9, 77) + { 0, { 0, 0, 0}}, // ( 10, 77) + { 0, { 0, 0, 0}}, // ( 11, 77) + { 0, { 0, 0, 0}}, // ( 12, 77) + { 0, { 0, 0, 0}}, // ( 13, 77) + { 0, { 0, 0, 0}}, // ( 14, 77) + { 0, { 0, 0, 0}}, // ( 15, 77) + { 0, { 0, 0, 0}}, // ( 16, 77) + { 0, { 0, 0, 0}}, // ( 17, 77) + { 0, { 0, 0, 0}}, // ( 18, 77) + { 0, { 0, 0, 0}}, // ( 19, 77) + { 0, { 0, 0, 0}}, // ( 20, 77) + { 0, { 0, 0, 0}}, // ( 21, 77) + { 0, { 0, 0, 0}}, // ( 22, 77) + { 0, { 0, 0, 0}}, // ( 23, 77) + { 0, { 0, 0, 0}}, // ( 24, 77) + { 0, { 0, 0, 0}}, // ( 25, 77) + { 0, { 0, 0, 0}}, // ( 26, 77) + { 0, { 0, 0, 0}}, // ( 27, 77) + { 0, { 0, 0, 0}}, // ( 28, 77) + { 0, { 0, 0, 0}}, // ( 29, 77) + { 0, { 0, 0, 0}}, // ( 30, 77) + { 0, { 0, 0, 0}}, // ( 31, 77) + { 0, { 0, 0, 0}}, // ( 32, 77) + { 0, { 0, 0, 0}}, // ( 33, 77) + { 0, { 0, 0, 0}}, // ( 34, 77) + { 0, { 0, 0, 0}}, // ( 35, 77) + { 0, { 0, 0, 0}}, // ( 36, 77) + { 0, { 0, 0, 0}}, // ( 37, 77) + { 0, { 0, 0, 0}}, // ( 38, 77) + { 0, { 0, 0, 0}}, // ( 39, 77) + { 0, { 0, 0, 0}}, // ( 40, 77) + { 0, { 0, 0, 0}}, // ( 41, 77) + { 0, { 0, 0, 0}}, // ( 42, 77) + { 0, { 0, 0, 0}}, // ( 43, 77) + { 0, { 0, 0, 0}}, // ( 44, 77) + { 0, { 0, 0, 0}}, // ( 45, 77) + { 0, { 0, 0, 0}}, // ( 46, 77) + { 0, { 0, 0, 0}}, // ( 47, 77) + { 0, { 0, 0, 0}}, // ( 48, 77) + { 0, { 0, 0, 0}}, // ( 49, 77) + { 0, { 0, 0, 0}}, // ( 50, 77) + { 0, { 0, 0, 0}}, // ( 51, 77) + { 0, { 0, 0, 0}}, // ( 52, 77) + { 0, { 0, 0, 0}}, // ( 53, 77) + { 0, { 0, 0, 0}}, // ( 54, 77) + { 0, { 0, 0, 0}}, // ( 55, 77) + { 0, { 0, 0, 0}}, // ( 56, 77) + { 0, { 0, 0, 0}}, // ( 57, 77) + { 0, { 0, 0, 0}}, // ( 58, 77) + { 0, { 0, 0, 0}}, // ( 59, 77) + { 0, { 0, 0, 0}}, // ( 60, 77) + { 0, { 0, 0, 0}}, // ( 61, 77) + { 0, { 0, 0, 0}}, // ( 62, 77) + { 0, { 0, 0, 0}}, // ( 63, 77) + { 0, { 0, 0, 0}}, // ( 64, 77) + { 0, { 0, 0, 0}}, // ( 65, 77) + { 0, { 0, 0, 0}}, // ( 66, 77) + { 0, { 0, 0, 0}}, // ( 67, 77) + { 0, { 0, 0, 0}}, // ( 68, 77) + { 0, { 0, 0, 0}}, // ( 69, 77) + { 0, { 0, 0, 0}}, // ( 70, 77) + { 0, { 0, 0, 0}}, // ( 71, 77) + { 0, { 0, 0, 0}}, // ( 72, 77) + { 0, { 0, 0, 0}}, // ( 73, 77) + { 0, { 0, 0, 0}}, // ( 74, 77) + { 0, { 0, 0, 0}}, // ( 75, 77) + { 0, { 0, 0, 0}}, // ( 76, 77) + { 0, { 0, 0, 0}}, // ( 77, 77) + { 0, { 0, 0, 0}}, // ( 78, 77) + { 0, { 0, 0, 0}}, // ( 79, 77) + { 0, { 0, 0, 0}}, // ( 80, 77) + { 0, { 0, 0, 0}}, // ( 81, 77) + { 0, { 0, 0, 0}}, // ( 82, 77) + { 0, { 0, 0, 0}}, // ( 83, 77) + { 0, { 0, 0, 0}}, // ( 84, 77) + { 0, { 0, 0, 0}}, // ( 85, 77) + { 0, { 0, 0, 0}}, // ( 86, 77) + { 0, { 0, 0, 0}}, // ( 87, 77) + { 0, { 0, 0, 0}}, // ( 88, 77) + { 0, { 0, 0, 0}}, // ( 89, 77) + { 0, { 0, 0, 0}}, // ( 90, 77) + { 0, { 0, 0, 0}}, // ( 91, 77) + { 0, { 0, 0, 0}}, // ( 92, 77) + { 0, { 0, 0, 0}}, // ( 93, 77) + { 0, { 0, 0, 0}}, // ( 94, 77) + { 0, { 0, 0, 0}}, // ( 95, 77) + { 0, { 0, 0, 0}}, // ( 96, 77) + { 0, { 0, 0, 0}}, // ( 97, 77) + { 0, { 0, 0, 0}}, // ( 98, 77) + { 0, { 0, 0, 0}}, // ( 99, 77) + { 0, { 0, 0, 0}}, // (100, 77) + { 0, { 0, 0, 0}}, // (101, 77) + { 0, { 0, 0, 0}}, // (102, 77) + { 0, { 0, 0, 0}}, // (103, 77) + { 0, { 0, 0, 0}}, // (104, 77) + { 0, { 0, 0, 0}}, // (105, 77) + { 0, { 0, 0, 0}}, // (106, 77) + { 0, { 0, 0, 0}}, // (107, 77) + { 0, { 0, 0, 0}}, // (108, 77) + { 0, { 0, 0, 0}}, // (109, 77) + { 0, { 0, 0, 0}}, // (110, 77) + { 0, { 0, 0, 0}}, // (111, 77) + { 0, { 0, 0, 0}}, // (112, 77) + { 0, { 0, 0, 0}}, // (113, 77) + { 0, { 0, 0, 0}}, // (114, 77) + { 0, { 0, 0, 0}}, // (115, 77) + { 0, { 0, 0, 0}}, // (116, 77) + { 0, { 0, 0, 0}}, // (117, 77) + { 0, { 0, 0, 0}}, // (118, 77) + { 0, { 0, 0, 0}}, // (119, 77) + { 0, { 0, 0, 0}}, // (120, 77) + { 0, { 0, 0, 0}}, // (121, 77) + { 0, { 0, 0, 0}}, // (122, 77) + { 0, { 0, 0, 0}}, // (123, 77) + { 0, { 0, 0, 0}}, // (124, 77) + { 0, { 0, 0, 0}}, // (125, 77) + { 0, { 0, 0, 0}}, // (126, 77) + { 0, { 0, 0, 0}}, // (127, 77) + { 0, { 0, 0, 0}}, // (128, 77) + { 0, { 0, 0, 0}}, // (129, 77) + { 0, { 0, 0, 0}}, // (130, 77) + { 0, { 0, 0, 0}}, // (131, 77) + { 0, { 0, 0, 0}}, // (132, 77) + { 0, { 0, 0, 0}}, // (133, 77) + { 0, { 0, 0, 0}}, // (134, 77) + { 0, { 0, 0, 0}}, // (135, 77) + { 0, { 0, 0, 0}}, // (136, 77) + { 0, { 0, 0, 0}}, // (137, 77) + { 0, { 0, 0, 0}}, // (138, 77) + { 0, { 0, 0, 0}}, // (139, 77) + { 0, { 0, 0, 0}}, // (140, 77) + { 0, { 0, 0, 0}}, // (141, 77) + { 0, { 0, 0, 0}}, // (142, 77) + { 0, { 0, 0, 0}}, // (143, 77) + { 0, { 0, 0, 0}}, // (144, 77) + { 0, { 0, 0, 0}}, // (145, 77) + { 0, { 0, 0, 0}}, // (146, 77) + { 0, { 0, 0, 0}}, // (147, 77) + { 0, { 0, 0, 0}}, // (148, 77) + { 0, { 0, 0, 0}}, // (149, 77) + { 0, { 0, 0, 0}}, // (150, 77) + { 0, { 0, 0, 0}}, // (151, 77) + { 0, { 0, 0, 0}}, // (152, 77) + { 0, { 0, 0, 0}}, // (153, 77) + { 0, { 0, 0, 0}}, // (154, 77) + { 0, { 0, 0, 0}}, // (155, 77) + { 0, { 0, 0, 0}}, // (156, 77) + { 0, { 0, 0, 0}}, // (157, 77) + { 0, { 0, 0, 0}}, // (158, 77) + { 0, { 0, 0, 0}}, // (159, 77) + { 0, { 0, 0, 0}}, // (160, 77) + { 0, { 0, 0, 0}}, // (161, 77) + { 0, { 0, 0, 0}}, // (162, 77) + { 0, { 0, 0, 0}}, // (163, 77) + { 0, { 0, 0, 0}}, // (164, 77) + { 0, { 0, 0, 0}}, // (165, 77) + { 0, { 0, 0, 0}}, // (166, 77) + { 0, { 0, 0, 0}}, // (167, 77) + { 0, { 0, 0, 0}}, // (168, 77) + { 0, { 0, 0, 0}}, // (169, 77) + { 0, { 0, 0, 0}}, // (170, 77) + { 0, { 0, 0, 0}}, // (171, 77) + { 0, { 0, 0, 0}}, // (172, 77) + { 0, { 0, 0, 0}}, // (173, 77) + { 0, { 0, 0, 0}}, // (174, 77) + { 0, { 0, 0, 0}}, // (175, 77) + { 0, { 0, 0, 0}}, // (176, 77) + {115, { 0, 0, 0}}, // (177, 77) + {128, { 0, 0, 0}}, // (178, 77) + {128, { 0, 0, 0}}, // (179, 77) + {128, { 0, 0, 0}}, // ( 0, 78) + {128, { 0, 0, 0}}, // ( 1, 78) + { 99, { 0, 0, 0}}, // ( 2, 78) + { 0, { 0, 0, 0}}, // ( 3, 78) + { 0, { 0, 0, 0}}, // ( 4, 78) + { 0, { 0, 0, 0}}, // ( 5, 78) + { 0, { 0, 0, 0}}, // ( 6, 78) + { 0, { 0, 0, 0}}, // ( 7, 78) + { 0, { 0, 0, 0}}, // ( 8, 78) + { 0, { 0, 0, 0}}, // ( 9, 78) + { 0, { 0, 0, 0}}, // ( 10, 78) + { 0, { 0, 0, 0}}, // ( 11, 78) + { 0, { 0, 0, 0}}, // ( 12, 78) + { 0, { 0, 0, 0}}, // ( 13, 78) + { 0, { 0, 0, 0}}, // ( 14, 78) + { 0, { 0, 0, 0}}, // ( 15, 78) + { 0, { 0, 0, 0}}, // ( 16, 78) + { 0, { 0, 0, 0}}, // ( 17, 78) + { 0, { 0, 0, 0}}, // ( 18, 78) + { 0, { 0, 0, 0}}, // ( 19, 78) + { 0, { 0, 0, 0}}, // ( 20, 78) + { 0, { 0, 0, 0}}, // ( 21, 78) + { 0, { 0, 0, 0}}, // ( 22, 78) + { 0, { 0, 0, 0}}, // ( 23, 78) + { 0, { 0, 0, 0}}, // ( 24, 78) + { 0, { 0, 0, 0}}, // ( 25, 78) + { 0, { 0, 0, 0}}, // ( 26, 78) + { 0, { 0, 0, 0}}, // ( 27, 78) + { 0, { 0, 0, 0}}, // ( 28, 78) + { 0, { 0, 0, 0}}, // ( 29, 78) + { 0, { 0, 0, 0}}, // ( 30, 78) + { 0, { 0, 0, 0}}, // ( 31, 78) + { 0, { 0, 0, 0}}, // ( 32, 78) + { 0, { 0, 0, 0}}, // ( 33, 78) + { 0, { 0, 0, 0}}, // ( 34, 78) + { 0, { 0, 0, 0}}, // ( 35, 78) + { 0, { 0, 0, 0}}, // ( 36, 78) + { 0, { 0, 0, 0}}, // ( 37, 78) + { 0, { 0, 0, 0}}, // ( 38, 78) + { 0, { 0, 0, 0}}, // ( 39, 78) + { 0, { 0, 0, 0}}, // ( 40, 78) + { 0, { 0, 0, 0}}, // ( 41, 78) + { 0, { 0, 0, 0}}, // ( 42, 78) + { 0, { 0, 0, 0}}, // ( 43, 78) + { 0, { 0, 0, 0}}, // ( 44, 78) + { 0, { 0, 0, 0}}, // ( 45, 78) + { 0, { 0, 0, 0}}, // ( 46, 78) + { 0, { 0, 0, 0}}, // ( 47, 78) + { 0, { 0, 0, 0}}, // ( 48, 78) + { 0, { 0, 0, 0}}, // ( 49, 78) + { 0, { 0, 0, 0}}, // ( 50, 78) + { 0, { 0, 0, 0}}, // ( 51, 78) + { 0, { 0, 0, 0}}, // ( 52, 78) + { 0, { 0, 0, 0}}, // ( 53, 78) + { 0, { 0, 0, 0}}, // ( 54, 78) + { 0, { 0, 0, 0}}, // ( 55, 78) + { 0, { 0, 0, 0}}, // ( 56, 78) + { 0, { 0, 0, 0}}, // ( 57, 78) + { 0, { 0, 0, 0}}, // ( 58, 78) + { 0, { 0, 0, 0}}, // ( 59, 78) + { 0, { 0, 0, 0}}, // ( 60, 78) + { 0, { 0, 0, 0}}, // ( 61, 78) + { 0, { 0, 0, 0}}, // ( 62, 78) + { 0, { 0, 0, 0}}, // ( 63, 78) + { 0, { 0, 0, 0}}, // ( 64, 78) + { 0, { 0, 0, 0}}, // ( 65, 78) + { 0, { 0, 0, 0}}, // ( 66, 78) + { 0, { 0, 0, 0}}, // ( 67, 78) + { 0, { 0, 0, 0}}, // ( 68, 78) + { 0, { 0, 0, 0}}, // ( 69, 78) + { 0, { 0, 0, 0}}, // ( 70, 78) + { 0, { 0, 0, 0}}, // ( 71, 78) + { 0, { 0, 0, 0}}, // ( 72, 78) + { 0, { 0, 0, 0}}, // ( 73, 78) + { 0, { 0, 0, 0}}, // ( 74, 78) + { 0, { 0, 0, 0}}, // ( 75, 78) + { 0, { 0, 0, 0}}, // ( 76, 78) + { 0, { 0, 0, 0}}, // ( 77, 78) + { 0, { 0, 0, 0}}, // ( 78, 78) + { 0, { 0, 0, 0}}, // ( 79, 78) + { 0, { 0, 0, 0}}, // ( 80, 78) + { 0, { 0, 0, 0}}, // ( 81, 78) + { 0, { 0, 0, 0}}, // ( 82, 78) + { 0, { 0, 0, 0}}, // ( 83, 78) + { 0, { 0, 0, 0}}, // ( 84, 78) + { 0, { 0, 0, 0}}, // ( 85, 78) + { 0, { 0, 0, 0}}, // ( 86, 78) + { 0, { 0, 0, 0}}, // ( 87, 78) + { 0, { 0, 0, 0}}, // ( 88, 78) + { 0, { 0, 0, 0}}, // ( 89, 78) + { 0, { 0, 0, 0}}, // ( 90, 78) + { 0, { 0, 0, 0}}, // ( 91, 78) + { 0, { 0, 0, 0}}, // ( 92, 78) + { 0, { 0, 0, 0}}, // ( 93, 78) + { 0, { 0, 0, 0}}, // ( 94, 78) + { 0, { 0, 0, 0}}, // ( 95, 78) + { 0, { 0, 0, 0}}, // ( 96, 78) + { 0, { 0, 0, 0}}, // ( 97, 78) + { 0, { 0, 0, 0}}, // ( 98, 78) + { 0, { 0, 0, 0}}, // ( 99, 78) + { 0, { 0, 0, 0}}, // (100, 78) + { 0, { 0, 0, 0}}, // (101, 78) + { 0, { 0, 0, 0}}, // (102, 78) + { 0, { 0, 0, 0}}, // (103, 78) + { 0, { 0, 0, 0}}, // (104, 78) + { 0, { 0, 0, 0}}, // (105, 78) + { 0, { 0, 0, 0}}, // (106, 78) + { 0, { 0, 0, 0}}, // (107, 78) + { 0, { 0, 0, 0}}, // (108, 78) + { 0, { 0, 0, 0}}, // (109, 78) + { 0, { 0, 0, 0}}, // (110, 78) + { 0, { 0, 0, 0}}, // (111, 78) + { 0, { 0, 0, 0}}, // (112, 78) + { 0, { 0, 0, 0}}, // (113, 78) + { 0, { 0, 0, 0}}, // (114, 78) + { 0, { 0, 0, 0}}, // (115, 78) + { 0, { 0, 0, 0}}, // (116, 78) + { 0, { 0, 0, 0}}, // (117, 78) + { 0, { 0, 0, 0}}, // (118, 78) + { 0, { 0, 0, 0}}, // (119, 78) + { 0, { 0, 0, 0}}, // (120, 78) + { 0, { 0, 0, 0}}, // (121, 78) + { 0, { 0, 0, 0}}, // (122, 78) + { 0, { 0, 0, 0}}, // (123, 78) + { 0, { 0, 0, 0}}, // (124, 78) + { 0, { 0, 0, 0}}, // (125, 78) + { 0, { 0, 0, 0}}, // (126, 78) + { 0, { 0, 0, 0}}, // (127, 78) + { 0, { 0, 0, 0}}, // (128, 78) + { 0, { 0, 0, 0}}, // (129, 78) + { 0, { 0, 0, 0}}, // (130, 78) + { 0, { 0, 0, 0}}, // (131, 78) + { 0, { 0, 0, 0}}, // (132, 78) + { 0, { 0, 0, 0}}, // (133, 78) + { 0, { 0, 0, 0}}, // (134, 78) + { 0, { 0, 0, 0}}, // (135, 78) + { 0, { 0, 0, 0}}, // (136, 78) + { 0, { 0, 0, 0}}, // (137, 78) + { 0, { 0, 0, 0}}, // (138, 78) + { 0, { 0, 0, 0}}, // (139, 78) + { 0, { 0, 0, 0}}, // (140, 78) + { 0, { 0, 0, 0}}, // (141, 78) + { 0, { 0, 0, 0}}, // (142, 78) + { 0, { 0, 0, 0}}, // (143, 78) + { 0, { 0, 0, 0}}, // (144, 78) + { 0, { 0, 0, 0}}, // (145, 78) + { 0, { 0, 0, 0}}, // (146, 78) + { 0, { 0, 0, 0}}, // (147, 78) + { 0, { 0, 0, 0}}, // (148, 78) + { 0, { 0, 0, 0}}, // (149, 78) + { 0, { 0, 0, 0}}, // (150, 78) + { 0, { 0, 0, 0}}, // (151, 78) + { 0, { 0, 0, 0}}, // (152, 78) + { 0, { 0, 0, 0}}, // (153, 78) + { 0, { 0, 0, 0}}, // (154, 78) + { 0, { 0, 0, 0}}, // (155, 78) + { 0, { 0, 0, 0}}, // (156, 78) + { 0, { 0, 0, 0}}, // (157, 78) + { 0, { 0, 0, 0}}, // (158, 78) + { 0, { 0, 0, 0}}, // (159, 78) + { 0, { 0, 0, 0}}, // (160, 78) + { 0, { 0, 0, 0}}, // (161, 78) + { 0, { 0, 0, 0}}, // (162, 78) + { 0, { 0, 0, 0}}, // (163, 78) + { 0, { 0, 0, 0}}, // (164, 78) + { 0, { 0, 0, 0}}, // (165, 78) + { 0, { 0, 0, 0}}, // (166, 78) + { 0, { 0, 0, 0}}, // (167, 78) + { 0, { 0, 0, 0}}, // (168, 78) + { 0, { 0, 0, 0}}, // (169, 78) + { 0, { 0, 0, 0}}, // (170, 78) + { 0, { 0, 0, 0}}, // (171, 78) + { 0, { 0, 0, 0}}, // (172, 78) + { 0, { 0, 0, 0}}, // (173, 78) + { 0, { 0, 0, 0}}, // (174, 78) + { 0, { 0, 0, 0}}, // (175, 78) + { 0, { 0, 0, 0}}, // (176, 78) + { 99, { 0, 0, 0}}, // (177, 78) + {128, { 0, 0, 0}}, // (178, 78) + {128, { 0, 0, 0}}, // (179, 78) + {128, { 0, 0, 0}}, // ( 0, 79) + {128, { 0, 0, 0}}, // ( 1, 79) + { 83, { 0, 0, 0}}, // ( 2, 79) + { 0, { 0, 0, 0}}, // ( 3, 79) + { 0, { 0, 0, 0}}, // ( 4, 79) + { 0, { 0, 0, 0}}, // ( 5, 79) + { 0, { 0, 0, 0}}, // ( 6, 79) + { 0, { 0, 0, 0}}, // ( 7, 79) + { 0, { 0, 0, 0}}, // ( 8, 79) + { 0, { 0, 0, 0}}, // ( 9, 79) + { 0, { 0, 0, 0}}, // ( 10, 79) + { 0, { 0, 0, 0}}, // ( 11, 79) + { 0, { 0, 0, 0}}, // ( 12, 79) + { 0, { 0, 0, 0}}, // ( 13, 79) + { 0, { 0, 0, 0}}, // ( 14, 79) + { 0, { 0, 0, 0}}, // ( 15, 79) + { 0, { 0, 0, 0}}, // ( 16, 79) + { 0, { 0, 0, 0}}, // ( 17, 79) + { 0, { 0, 0, 0}}, // ( 18, 79) + { 0, { 0, 0, 0}}, // ( 19, 79) + { 0, { 0, 0, 0}}, // ( 20, 79) + { 0, { 0, 0, 0}}, // ( 21, 79) + { 0, { 0, 0, 0}}, // ( 22, 79) + { 0, { 0, 0, 0}}, // ( 23, 79) + { 0, { 0, 0, 0}}, // ( 24, 79) + { 0, { 0, 0, 0}}, // ( 25, 79) + { 0, { 0, 0, 0}}, // ( 26, 79) + { 0, { 0, 0, 0}}, // ( 27, 79) + { 0, { 0, 0, 0}}, // ( 28, 79) + { 0, { 0, 0, 0}}, // ( 29, 79) + { 0, { 0, 0, 0}}, // ( 30, 79) + { 0, { 0, 0, 0}}, // ( 31, 79) + { 0, { 0, 0, 0}}, // ( 32, 79) + { 0, { 0, 0, 0}}, // ( 33, 79) + { 0, { 0, 0, 0}}, // ( 34, 79) + { 0, { 0, 0, 0}}, // ( 35, 79) + { 0, { 0, 0, 0}}, // ( 36, 79) + { 0, { 0, 0, 0}}, // ( 37, 79) + { 0, { 0, 0, 0}}, // ( 38, 79) + { 0, { 0, 0, 0}}, // ( 39, 79) + { 0, { 0, 0, 0}}, // ( 40, 79) + { 0, { 0, 0, 0}}, // ( 41, 79) + { 0, { 0, 0, 0}}, // ( 42, 79) + { 0, { 0, 0, 0}}, // ( 43, 79) + { 0, { 0, 0, 0}}, // ( 44, 79) + { 0, { 0, 0, 0}}, // ( 45, 79) + { 0, { 0, 0, 0}}, // ( 46, 79) + { 0, { 0, 0, 0}}, // ( 47, 79) + { 0, { 0, 0, 0}}, // ( 48, 79) + { 0, { 0, 0, 0}}, // ( 49, 79) + { 0, { 0, 0, 0}}, // ( 50, 79) + { 0, { 0, 0, 0}}, // ( 51, 79) + { 0, { 0, 0, 0}}, // ( 52, 79) + { 0, { 0, 0, 0}}, // ( 53, 79) + { 0, { 0, 0, 0}}, // ( 54, 79) + { 0, { 0, 0, 0}}, // ( 55, 79) + { 0, { 0, 0, 0}}, // ( 56, 79) + { 0, { 0, 0, 0}}, // ( 57, 79) + { 0, { 0, 0, 0}}, // ( 58, 79) + { 0, { 0, 0, 0}}, // ( 59, 79) + { 0, { 0, 0, 0}}, // ( 60, 79) + { 0, { 0, 0, 0}}, // ( 61, 79) + { 0, { 0, 0, 0}}, // ( 62, 79) + { 0, { 0, 0, 0}}, // ( 63, 79) + { 0, { 0, 0, 0}}, // ( 64, 79) + { 0, { 0, 0, 0}}, // ( 65, 79) + { 0, { 0, 0, 0}}, // ( 66, 79) + { 0, { 0, 0, 0}}, // ( 67, 79) + { 0, { 0, 0, 0}}, // ( 68, 79) + { 0, { 0, 0, 0}}, // ( 69, 79) + { 0, { 0, 0, 0}}, // ( 70, 79) + { 0, { 0, 0, 0}}, // ( 71, 79) + { 0, { 0, 0, 0}}, // ( 72, 79) + { 0, { 0, 0, 0}}, // ( 73, 79) + { 0, { 0, 0, 0}}, // ( 74, 79) + { 0, { 0, 0, 0}}, // ( 75, 79) + { 0, { 0, 0, 0}}, // ( 76, 79) + { 0, { 0, 0, 0}}, // ( 77, 79) + { 0, { 0, 0, 0}}, // ( 78, 79) + { 0, { 0, 0, 0}}, // ( 79, 79) + { 0, { 0, 0, 0}}, // ( 80, 79) + { 0, { 0, 0, 0}}, // ( 81, 79) + { 0, { 0, 0, 0}}, // ( 82, 79) + { 0, { 0, 0, 0}}, // ( 83, 79) + { 0, { 0, 0, 0}}, // ( 84, 79) + { 0, { 0, 0, 0}}, // ( 85, 79) + { 0, { 0, 0, 0}}, // ( 86, 79) + { 0, { 0, 0, 0}}, // ( 87, 79) + { 0, { 0, 0, 0}}, // ( 88, 79) + { 0, { 0, 0, 0}}, // ( 89, 79) + { 0, { 0, 0, 0}}, // ( 90, 79) + { 0, { 0, 0, 0}}, // ( 91, 79) + { 0, { 0, 0, 0}}, // ( 92, 79) + { 0, { 0, 0, 0}}, // ( 93, 79) + { 0, { 0, 0, 0}}, // ( 94, 79) + { 0, { 0, 0, 0}}, // ( 95, 79) + { 0, { 0, 0, 0}}, // ( 96, 79) + { 0, { 0, 0, 0}}, // ( 97, 79) + { 0, { 0, 0, 0}}, // ( 98, 79) + { 0, { 0, 0, 0}}, // ( 99, 79) + { 0, { 0, 0, 0}}, // (100, 79) + { 0, { 0, 0, 0}}, // (101, 79) + { 0, { 0, 0, 0}}, // (102, 79) + { 0, { 0, 0, 0}}, // (103, 79) + { 0, { 0, 0, 0}}, // (104, 79) + { 0, { 0, 0, 0}}, // (105, 79) + { 0, { 0, 0, 0}}, // (106, 79) + { 0, { 0, 0, 0}}, // (107, 79) + { 0, { 0, 0, 0}}, // (108, 79) + { 0, { 0, 0, 0}}, // (109, 79) + { 0, { 0, 0, 0}}, // (110, 79) + { 0, { 0, 0, 0}}, // (111, 79) + { 0, { 0, 0, 0}}, // (112, 79) + { 0, { 0, 0, 0}}, // (113, 79) + { 0, { 0, 0, 0}}, // (114, 79) + { 0, { 0, 0, 0}}, // (115, 79) + { 0, { 0, 0, 0}}, // (116, 79) + { 0, { 0, 0, 0}}, // (117, 79) + { 0, { 0, 0, 0}}, // (118, 79) + { 0, { 0, 0, 0}}, // (119, 79) + { 0, { 0, 0, 0}}, // (120, 79) + { 0, { 0, 0, 0}}, // (121, 79) + { 0, { 0, 0, 0}}, // (122, 79) + { 0, { 0, 0, 0}}, // (123, 79) + { 0, { 0, 0, 0}}, // (124, 79) + { 0, { 0, 0, 0}}, // (125, 79) + { 0, { 0, 0, 0}}, // (126, 79) + { 0, { 0, 0, 0}}, // (127, 79) + { 0, { 0, 0, 0}}, // (128, 79) + { 0, { 0, 0, 0}}, // (129, 79) + { 0, { 0, 0, 0}}, // (130, 79) + { 0, { 0, 0, 0}}, // (131, 79) + { 0, { 0, 0, 0}}, // (132, 79) + { 0, { 0, 0, 0}}, // (133, 79) + { 0, { 0, 0, 0}}, // (134, 79) + { 0, { 0, 0, 0}}, // (135, 79) + { 0, { 0, 0, 0}}, // (136, 79) + { 0, { 0, 0, 0}}, // (137, 79) + { 0, { 0, 0, 0}}, // (138, 79) + { 0, { 0, 0, 0}}, // (139, 79) + { 0, { 0, 0, 0}}, // (140, 79) + { 0, { 0, 0, 0}}, // (141, 79) + { 0, { 0, 0, 0}}, // (142, 79) + { 0, { 0, 0, 0}}, // (143, 79) + { 0, { 0, 0, 0}}, // (144, 79) + { 0, { 0, 0, 0}}, // (145, 79) + { 0, { 0, 0, 0}}, // (146, 79) + { 0, { 0, 0, 0}}, // (147, 79) + { 0, { 0, 0, 0}}, // (148, 79) + { 0, { 0, 0, 0}}, // (149, 79) + { 0, { 0, 0, 0}}, // (150, 79) + { 0, { 0, 0, 0}}, // (151, 79) + { 0, { 0, 0, 0}}, // (152, 79) + { 0, { 0, 0, 0}}, // (153, 79) + { 0, { 0, 0, 0}}, // (154, 79) + { 0, { 0, 0, 0}}, // (155, 79) + { 0, { 0, 0, 0}}, // (156, 79) + { 0, { 0, 0, 0}}, // (157, 79) + { 0, { 0, 0, 0}}, // (158, 79) + { 0, { 0, 0, 0}}, // (159, 79) + { 0, { 0, 0, 0}}, // (160, 79) + { 0, { 0, 0, 0}}, // (161, 79) + { 0, { 0, 0, 0}}, // (162, 79) + { 0, { 0, 0, 0}}, // (163, 79) + { 0, { 0, 0, 0}}, // (164, 79) + { 0, { 0, 0, 0}}, // (165, 79) + { 0, { 0, 0, 0}}, // (166, 79) + { 0, { 0, 0, 0}}, // (167, 79) + { 0, { 0, 0, 0}}, // (168, 79) + { 0, { 0, 0, 0}}, // (169, 79) + { 0, { 0, 0, 0}}, // (170, 79) + { 0, { 0, 0, 0}}, // (171, 79) + { 0, { 0, 0, 0}}, // (172, 79) + { 0, { 0, 0, 0}}, // (173, 79) + { 0, { 0, 0, 0}}, // (174, 79) + { 0, { 0, 0, 0}}, // (175, 79) + { 0, { 0, 0, 0}}, // (176, 79) + { 83, { 0, 0, 0}}, // (177, 79) + {128, { 0, 0, 0}}, // (178, 79) + {128, { 0, 0, 0}}, // (179, 79) + {128, { 0, 0, 0}}, // ( 0, 80) + {128, { 0, 0, 0}}, // ( 1, 80) + { 66, { 0, 0, 0}}, // ( 2, 80) + { 0, { 0, 0, 0}}, // ( 3, 80) + { 0, { 0, 0, 0}}, // ( 4, 80) + { 0, { 0, 0, 0}}, // ( 5, 80) + { 0, { 0, 0, 0}}, // ( 6, 80) + { 0, { 0, 0, 0}}, // ( 7, 80) + { 0, { 0, 0, 0}}, // ( 8, 80) + { 0, { 0, 0, 0}}, // ( 9, 80) + { 0, { 0, 0, 0}}, // ( 10, 80) + { 0, { 0, 0, 0}}, // ( 11, 80) + { 0, { 0, 0, 0}}, // ( 12, 80) + { 0, { 0, 0, 0}}, // ( 13, 80) + { 0, { 0, 0, 0}}, // ( 14, 80) + { 0, { 0, 0, 0}}, // ( 15, 80) + { 0, { 0, 0, 0}}, // ( 16, 80) + { 0, { 0, 0, 0}}, // ( 17, 80) + { 0, { 0, 0, 0}}, // ( 18, 80) + { 0, { 0, 0, 0}}, // ( 19, 80) + { 0, { 0, 0, 0}}, // ( 20, 80) + { 0, { 0, 0, 0}}, // ( 21, 80) + { 0, { 0, 0, 0}}, // ( 22, 80) + { 0, { 0, 0, 0}}, // ( 23, 80) + { 0, { 0, 0, 0}}, // ( 24, 80) + { 0, { 0, 0, 0}}, // ( 25, 80) + { 0, { 0, 0, 0}}, // ( 26, 80) + { 0, { 0, 0, 0}}, // ( 27, 80) + { 0, { 0, 0, 0}}, // ( 28, 80) + { 0, { 0, 0, 0}}, // ( 29, 80) + { 0, { 0, 0, 0}}, // ( 30, 80) + { 0, { 0, 0, 0}}, // ( 31, 80) + { 0, { 0, 0, 0}}, // ( 32, 80) + { 0, { 0, 0, 0}}, // ( 33, 80) + { 0, { 0, 0, 0}}, // ( 34, 80) + { 0, { 0, 0, 0}}, // ( 35, 80) + { 0, { 0, 0, 0}}, // ( 36, 80) + { 0, { 0, 0, 0}}, // ( 37, 80) + { 0, { 0, 0, 0}}, // ( 38, 80) + { 0, { 0, 0, 0}}, // ( 39, 80) + { 0, { 0, 0, 0}}, // ( 40, 80) + { 0, { 0, 0, 0}}, // ( 41, 80) + { 0, { 0, 0, 0}}, // ( 42, 80) + { 0, { 0, 0, 0}}, // ( 43, 80) + { 0, { 0, 0, 0}}, // ( 44, 80) + { 0, { 0, 0, 0}}, // ( 45, 80) + { 0, { 0, 0, 0}}, // ( 46, 80) + { 0, { 0, 0, 0}}, // ( 47, 80) + { 0, { 0, 0, 0}}, // ( 48, 80) + { 0, { 0, 0, 0}}, // ( 49, 80) + { 0, { 0, 0, 0}}, // ( 50, 80) + { 0, { 0, 0, 0}}, // ( 51, 80) + { 0, { 0, 0, 0}}, // ( 52, 80) + { 0, { 0, 0, 0}}, // ( 53, 80) + { 0, { 0, 0, 0}}, // ( 54, 80) + { 0, { 0, 0, 0}}, // ( 55, 80) + { 0, { 0, 0, 0}}, // ( 56, 80) + { 0, { 0, 0, 0}}, // ( 57, 80) + { 0, { 0, 0, 0}}, // ( 58, 80) + { 0, { 0, 0, 0}}, // ( 59, 80) + { 0, { 0, 0, 0}}, // ( 60, 80) + { 0, { 0, 0, 0}}, // ( 61, 80) + { 0, { 0, 0, 0}}, // ( 62, 80) + { 0, { 0, 0, 0}}, // ( 63, 80) + { 0, { 0, 0, 0}}, // ( 64, 80) + { 0, { 0, 0, 0}}, // ( 65, 80) + { 0, { 0, 0, 0}}, // ( 66, 80) + { 0, { 0, 0, 0}}, // ( 67, 80) + { 0, { 0, 0, 0}}, // ( 68, 80) + { 0, { 0, 0, 0}}, // ( 69, 80) + { 0, { 0, 0, 0}}, // ( 70, 80) + { 0, { 0, 0, 0}}, // ( 71, 80) + { 0, { 0, 0, 0}}, // ( 72, 80) + { 0, { 0, 0, 0}}, // ( 73, 80) + { 0, { 0, 0, 0}}, // ( 74, 80) + { 0, { 0, 0, 0}}, // ( 75, 80) + { 0, { 0, 0, 0}}, // ( 76, 80) + { 0, { 0, 0, 0}}, // ( 77, 80) + { 0, { 0, 0, 0}}, // ( 78, 80) + { 0, { 0, 0, 0}}, // ( 79, 80) + { 0, { 0, 0, 0}}, // ( 80, 80) + { 0, { 0, 0, 0}}, // ( 81, 80) + { 0, { 0, 0, 0}}, // ( 82, 80) + { 0, { 0, 0, 0}}, // ( 83, 80) + { 0, { 0, 0, 0}}, // ( 84, 80) + { 0, { 0, 0, 0}}, // ( 85, 80) + { 0, { 0, 0, 0}}, // ( 86, 80) + { 0, { 0, 0, 0}}, // ( 87, 80) + { 0, { 0, 0, 0}}, // ( 88, 80) + { 0, { 0, 0, 0}}, // ( 89, 80) + { 0, { 0, 0, 0}}, // ( 90, 80) + { 0, { 0, 0, 0}}, // ( 91, 80) + { 0, { 0, 0, 0}}, // ( 92, 80) + { 0, { 0, 0, 0}}, // ( 93, 80) + { 0, { 0, 0, 0}}, // ( 94, 80) + { 0, { 0, 0, 0}}, // ( 95, 80) + { 0, { 0, 0, 0}}, // ( 96, 80) + { 0, { 0, 0, 0}}, // ( 97, 80) + { 0, { 0, 0, 0}}, // ( 98, 80) + { 0, { 0, 0, 0}}, // ( 99, 80) + { 0, { 0, 0, 0}}, // (100, 80) + { 0, { 0, 0, 0}}, // (101, 80) + { 0, { 0, 0, 0}}, // (102, 80) + { 0, { 0, 0, 0}}, // (103, 80) + { 0, { 0, 0, 0}}, // (104, 80) + { 0, { 0, 0, 0}}, // (105, 80) + { 0, { 0, 0, 0}}, // (106, 80) + { 0, { 0, 0, 0}}, // (107, 80) + { 0, { 0, 0, 0}}, // (108, 80) + { 0, { 0, 0, 0}}, // (109, 80) + { 0, { 0, 0, 0}}, // (110, 80) + { 0, { 0, 0, 0}}, // (111, 80) + { 0, { 0, 0, 0}}, // (112, 80) + { 0, { 0, 0, 0}}, // (113, 80) + { 0, { 0, 0, 0}}, // (114, 80) + { 0, { 0, 0, 0}}, // (115, 80) + { 0, { 0, 0, 0}}, // (116, 80) + { 0, { 0, 0, 0}}, // (117, 80) + { 0, { 0, 0, 0}}, // (118, 80) + { 0, { 0, 0, 0}}, // (119, 80) + { 0, { 0, 0, 0}}, // (120, 80) + { 0, { 0, 0, 0}}, // (121, 80) + { 0, { 0, 0, 0}}, // (122, 80) + { 0, { 0, 0, 0}}, // (123, 80) + { 0, { 0, 0, 0}}, // (124, 80) + { 0, { 0, 0, 0}}, // (125, 80) + { 0, { 0, 0, 0}}, // (126, 80) + { 0, { 0, 0, 0}}, // (127, 80) + { 0, { 0, 0, 0}}, // (128, 80) + { 0, { 0, 0, 0}}, // (129, 80) + { 0, { 0, 0, 0}}, // (130, 80) + { 0, { 0, 0, 0}}, // (131, 80) + { 0, { 0, 0, 0}}, // (132, 80) + { 0, { 0, 0, 0}}, // (133, 80) + { 0, { 0, 0, 0}}, // (134, 80) + { 0, { 0, 0, 0}}, // (135, 80) + { 0, { 0, 0, 0}}, // (136, 80) + { 0, { 0, 0, 0}}, // (137, 80) + { 0, { 0, 0, 0}}, // (138, 80) + { 0, { 0, 0, 0}}, // (139, 80) + { 0, { 0, 0, 0}}, // (140, 80) + { 0, { 0, 0, 0}}, // (141, 80) + { 0, { 0, 0, 0}}, // (142, 80) + { 0, { 0, 0, 0}}, // (143, 80) + { 0, { 0, 0, 0}}, // (144, 80) + { 0, { 0, 0, 0}}, // (145, 80) + { 0, { 0, 0, 0}}, // (146, 80) + { 0, { 0, 0, 0}}, // (147, 80) + { 0, { 0, 0, 0}}, // (148, 80) + { 0, { 0, 0, 0}}, // (149, 80) + { 0, { 0, 0, 0}}, // (150, 80) + { 0, { 0, 0, 0}}, // (151, 80) + { 0, { 0, 0, 0}}, // (152, 80) + { 0, { 0, 0, 0}}, // (153, 80) + { 0, { 0, 0, 0}}, // (154, 80) + { 0, { 0, 0, 0}}, // (155, 80) + { 0, { 0, 0, 0}}, // (156, 80) + { 0, { 0, 0, 0}}, // (157, 80) + { 0, { 0, 0, 0}}, // (158, 80) + { 0, { 0, 0, 0}}, // (159, 80) + { 0, { 0, 0, 0}}, // (160, 80) + { 0, { 0, 0, 0}}, // (161, 80) + { 0, { 0, 0, 0}}, // (162, 80) + { 0, { 0, 0, 0}}, // (163, 80) + { 0, { 0, 0, 0}}, // (164, 80) + { 0, { 0, 0, 0}}, // (165, 80) + { 0, { 0, 0, 0}}, // (166, 80) + { 0, { 0, 0, 0}}, // (167, 80) + { 0, { 0, 0, 0}}, // (168, 80) + { 0, { 0, 0, 0}}, // (169, 80) + { 0, { 0, 0, 0}}, // (170, 80) + { 0, { 0, 0, 0}}, // (171, 80) + { 0, { 0, 0, 0}}, // (172, 80) + { 0, { 0, 0, 0}}, // (173, 80) + { 0, { 0, 0, 0}}, // (174, 80) + { 0, { 0, 0, 0}}, // (175, 80) + { 0, { 0, 0, 0}}, // (176, 80) + { 67, { 0, 0, 0}}, // (177, 80) + {128, { 0, 0, 0}}, // (178, 80) + {128, { 0, 0, 0}}, // (179, 80) + {128, { 0, 0, 0}}, // ( 0, 81) + {128, { 0, 0, 0}}, // ( 1, 81) + { 54, { 0, 0, 0}}, // ( 2, 81) + { 0, { 0, 0, 0}}, // ( 3, 81) + { 0, { 0, 0, 0}}, // ( 4, 81) + { 0, { 0, 0, 0}}, // ( 5, 81) + { 0, { 0, 0, 0}}, // ( 6, 81) + { 0, { 0, 0, 0}}, // ( 7, 81) + { 0, { 0, 0, 0}}, // ( 8, 81) + { 0, { 0, 0, 0}}, // ( 9, 81) + { 0, { 0, 0, 0}}, // ( 10, 81) + { 0, { 0, 0, 0}}, // ( 11, 81) + { 0, { 0, 0, 0}}, // ( 12, 81) + { 0, { 0, 0, 0}}, // ( 13, 81) + { 0, { 0, 0, 0}}, // ( 14, 81) + { 0, { 0, 0, 0}}, // ( 15, 81) + { 0, { 0, 0, 0}}, // ( 16, 81) + { 0, { 0, 0, 0}}, // ( 17, 81) + { 0, { 0, 0, 0}}, // ( 18, 81) + { 0, { 0, 0, 0}}, // ( 19, 81) + { 0, { 0, 0, 0}}, // ( 20, 81) + { 0, { 0, 0, 0}}, // ( 21, 81) + { 0, { 0, 0, 0}}, // ( 22, 81) + { 0, { 0, 0, 0}}, // ( 23, 81) + { 0, { 0, 0, 0}}, // ( 24, 81) + { 0, { 0, 0, 0}}, // ( 25, 81) + { 0, { 0, 0, 0}}, // ( 26, 81) + { 0, { 0, 0, 0}}, // ( 27, 81) + { 0, { 0, 0, 0}}, // ( 28, 81) + { 0, { 0, 0, 0}}, // ( 29, 81) + { 0, { 0, 0, 0}}, // ( 30, 81) + { 0, { 0, 0, 0}}, // ( 31, 81) + { 0, { 0, 0, 0}}, // ( 32, 81) + { 0, { 0, 0, 0}}, // ( 33, 81) + { 0, { 0, 0, 0}}, // ( 34, 81) + { 0, { 0, 0, 0}}, // ( 35, 81) + { 0, { 0, 0, 0}}, // ( 36, 81) + { 0, { 0, 0, 0}}, // ( 37, 81) + { 0, { 0, 0, 0}}, // ( 38, 81) + { 0, { 0, 0, 0}}, // ( 39, 81) + { 0, { 0, 0, 0}}, // ( 40, 81) + { 0, { 0, 0, 0}}, // ( 41, 81) + { 0, { 0, 0, 0}}, // ( 42, 81) + { 0, { 0, 0, 0}}, // ( 43, 81) + { 0, { 0, 0, 0}}, // ( 44, 81) + { 0, { 0, 0, 0}}, // ( 45, 81) + { 0, { 0, 0, 0}}, // ( 46, 81) + { 0, { 0, 0, 0}}, // ( 47, 81) + { 0, { 0, 0, 0}}, // ( 48, 81) + { 0, { 0, 0, 0}}, // ( 49, 81) + { 0, { 0, 0, 0}}, // ( 50, 81) + { 0, { 0, 0, 0}}, // ( 51, 81) + { 0, { 0, 0, 0}}, // ( 52, 81) + { 0, { 0, 0, 0}}, // ( 53, 81) + { 0, { 0, 0, 0}}, // ( 54, 81) + { 0, { 0, 0, 0}}, // ( 55, 81) + { 0, { 0, 0, 0}}, // ( 56, 81) + { 0, { 0, 0, 0}}, // ( 57, 81) + { 0, { 0, 0, 0}}, // ( 58, 81) + { 0, { 0, 0, 0}}, // ( 59, 81) + { 0, { 0, 0, 0}}, // ( 60, 81) + { 0, { 0, 0, 0}}, // ( 61, 81) + { 0, { 0, 0, 0}}, // ( 62, 81) + { 0, { 0, 0, 0}}, // ( 63, 81) + { 0, { 0, 0, 0}}, // ( 64, 81) + { 0, { 0, 0, 0}}, // ( 65, 81) + { 0, { 0, 0, 0}}, // ( 66, 81) + { 0, { 0, 0, 0}}, // ( 67, 81) + { 0, { 0, 0, 0}}, // ( 68, 81) + { 0, { 0, 0, 0}}, // ( 69, 81) + { 0, { 0, 0, 0}}, // ( 70, 81) + { 0, { 0, 0, 0}}, // ( 71, 81) + { 0, { 0, 0, 0}}, // ( 72, 81) + { 0, { 0, 0, 0}}, // ( 73, 81) + { 0, { 0, 0, 0}}, // ( 74, 81) + { 0, { 0, 0, 0}}, // ( 75, 81) + { 0, { 0, 0, 0}}, // ( 76, 81) + { 0, { 0, 0, 0}}, // ( 77, 81) + { 0, { 0, 0, 0}}, // ( 78, 81) + { 0, { 0, 0, 0}}, // ( 79, 81) + { 0, { 0, 0, 0}}, // ( 80, 81) + { 0, { 0, 0, 0}}, // ( 81, 81) + { 0, { 0, 0, 0}}, // ( 82, 81) + { 0, { 0, 0, 0}}, // ( 83, 81) + { 0, { 0, 0, 0}}, // ( 84, 81) + { 0, { 0, 0, 0}}, // ( 85, 81) + { 0, { 0, 0, 0}}, // ( 86, 81) + { 0, { 0, 0, 0}}, // ( 87, 81) + { 0, { 0, 0, 0}}, // ( 88, 81) + { 0, { 0, 0, 0}}, // ( 89, 81) + { 0, { 0, 0, 0}}, // ( 90, 81) + { 0, { 0, 0, 0}}, // ( 91, 81) + { 0, { 0, 0, 0}}, // ( 92, 81) + { 0, { 0, 0, 0}}, // ( 93, 81) + { 0, { 0, 0, 0}}, // ( 94, 81) + { 0, { 0, 0, 0}}, // ( 95, 81) + { 0, { 0, 0, 0}}, // ( 96, 81) + { 0, { 0, 0, 0}}, // ( 97, 81) + { 0, { 0, 0, 0}}, // ( 98, 81) + { 0, { 0, 0, 0}}, // ( 99, 81) + { 0, { 0, 0, 0}}, // (100, 81) + { 0, { 0, 0, 0}}, // (101, 81) + { 0, { 0, 0, 0}}, // (102, 81) + { 0, { 0, 0, 0}}, // (103, 81) + { 0, { 0, 0, 0}}, // (104, 81) + { 0, { 0, 0, 0}}, // (105, 81) + { 0, { 0, 0, 0}}, // (106, 81) + { 0, { 0, 0, 0}}, // (107, 81) + { 0, { 0, 0, 0}}, // (108, 81) + { 0, { 0, 0, 0}}, // (109, 81) + { 0, { 0, 0, 0}}, // (110, 81) + { 0, { 0, 0, 0}}, // (111, 81) + { 0, { 0, 0, 0}}, // (112, 81) + { 0, { 0, 0, 0}}, // (113, 81) + { 0, { 0, 0, 0}}, // (114, 81) + { 0, { 0, 0, 0}}, // (115, 81) + { 0, { 0, 0, 0}}, // (116, 81) + { 0, { 0, 0, 0}}, // (117, 81) + { 0, { 0, 0, 0}}, // (118, 81) + { 0, { 0, 0, 0}}, // (119, 81) + { 0, { 0, 0, 0}}, // (120, 81) + { 0, { 0, 0, 0}}, // (121, 81) + { 0, { 0, 0, 0}}, // (122, 81) + { 0, { 0, 0, 0}}, // (123, 81) + { 0, { 0, 0, 0}}, // (124, 81) + { 0, { 0, 0, 0}}, // (125, 81) + { 0, { 0, 0, 0}}, // (126, 81) + { 0, { 0, 0, 0}}, // (127, 81) + { 0, { 0, 0, 0}}, // (128, 81) + { 0, { 0, 0, 0}}, // (129, 81) + { 0, { 0, 0, 0}}, // (130, 81) + { 0, { 0, 0, 0}}, // (131, 81) + { 0, { 0, 0, 0}}, // (132, 81) + { 0, { 0, 0, 0}}, // (133, 81) + { 0, { 0, 0, 0}}, // (134, 81) + { 0, { 0, 0, 0}}, // (135, 81) + { 0, { 0, 0, 0}}, // (136, 81) + { 0, { 0, 0, 0}}, // (137, 81) + { 0, { 0, 0, 0}}, // (138, 81) + { 0, { 0, 0, 0}}, // (139, 81) + { 0, { 0, 0, 0}}, // (140, 81) + { 0, { 0, 0, 0}}, // (141, 81) + { 0, { 0, 0, 0}}, // (142, 81) + { 0, { 0, 0, 0}}, // (143, 81) + { 0, { 0, 0, 0}}, // (144, 81) + { 0, { 0, 0, 0}}, // (145, 81) + { 0, { 0, 0, 0}}, // (146, 81) + { 0, { 0, 0, 0}}, // (147, 81) + { 0, { 0, 0, 0}}, // (148, 81) + { 0, { 0, 0, 0}}, // (149, 81) + { 0, { 0, 0, 0}}, // (150, 81) + { 0, { 0, 0, 0}}, // (151, 81) + { 0, { 0, 0, 0}}, // (152, 81) + { 0, { 0, 0, 0}}, // (153, 81) + { 0, { 0, 0, 0}}, // (154, 81) + { 0, { 0, 0, 0}}, // (155, 81) + { 0, { 0, 0, 0}}, // (156, 81) + { 0, { 0, 0, 0}}, // (157, 81) + { 0, { 0, 0, 0}}, // (158, 81) + { 0, { 0, 0, 0}}, // (159, 81) + { 0, { 0, 0, 0}}, // (160, 81) + { 0, { 0, 0, 0}}, // (161, 81) + { 0, { 0, 0, 0}}, // (162, 81) + { 0, { 0, 0, 0}}, // (163, 81) + { 0, { 0, 0, 0}}, // (164, 81) + { 0, { 0, 0, 0}}, // (165, 81) + { 0, { 0, 0, 0}}, // (166, 81) + { 0, { 0, 0, 0}}, // (167, 81) + { 0, { 0, 0, 0}}, // (168, 81) + { 0, { 0, 0, 0}}, // (169, 81) + { 0, { 0, 0, 0}}, // (170, 81) + { 0, { 0, 0, 0}}, // (171, 81) + { 0, { 0, 0, 0}}, // (172, 81) + { 0, { 0, 0, 0}}, // (173, 81) + { 0, { 0, 0, 0}}, // (174, 81) + { 0, { 0, 0, 0}}, // (175, 81) + { 0, { 0, 0, 0}}, // (176, 81) + { 54, { 0, 0, 0}}, // (177, 81) + {128, { 0, 0, 0}}, // (178, 81) + {128, { 0, 0, 0}}, // (179, 81) + {128, { 0, 0, 0}}, // ( 0, 82) + {128, { 0, 0, 0}}, // ( 1, 82) + { 43, { 0, 0, 0}}, // ( 2, 82) + { 0, { 0, 0, 0}}, // ( 3, 82) + { 0, { 0, 0, 0}}, // ( 4, 82) + { 0, { 0, 0, 0}}, // ( 5, 82) + { 0, { 0, 0, 0}}, // ( 6, 82) + { 0, { 0, 0, 0}}, // ( 7, 82) + { 0, { 0, 0, 0}}, // ( 8, 82) + { 0, { 0, 0, 0}}, // ( 9, 82) + { 0, { 0, 0, 0}}, // ( 10, 82) + { 0, { 0, 0, 0}}, // ( 11, 82) + { 0, { 0, 0, 0}}, // ( 12, 82) + { 0, { 0, 0, 0}}, // ( 13, 82) + { 0, { 0, 0, 0}}, // ( 14, 82) + { 0, { 0, 0, 0}}, // ( 15, 82) + { 0, { 0, 0, 0}}, // ( 16, 82) + { 0, { 0, 0, 0}}, // ( 17, 82) + { 0, { 0, 0, 0}}, // ( 18, 82) + { 0, { 0, 0, 0}}, // ( 19, 82) + { 0, { 0, 0, 0}}, // ( 20, 82) + { 0, { 0, 0, 0}}, // ( 21, 82) + { 0, { 0, 0, 0}}, // ( 22, 82) + { 0, { 0, 0, 0}}, // ( 23, 82) + { 0, { 0, 0, 0}}, // ( 24, 82) + { 0, { 0, 0, 0}}, // ( 25, 82) + { 0, { 0, 0, 0}}, // ( 26, 82) + { 0, { 0, 0, 0}}, // ( 27, 82) + { 0, { 0, 0, 0}}, // ( 28, 82) + { 0, { 0, 0, 0}}, // ( 29, 82) + { 0, { 0, 0, 0}}, // ( 30, 82) + { 0, { 0, 0, 0}}, // ( 31, 82) + { 0, { 0, 0, 0}}, // ( 32, 82) + { 0, { 0, 0, 0}}, // ( 33, 82) + { 0, { 0, 0, 0}}, // ( 34, 82) + { 0, { 0, 0, 0}}, // ( 35, 82) + { 0, { 0, 0, 0}}, // ( 36, 82) + { 0, { 0, 0, 0}}, // ( 37, 82) + { 0, { 0, 0, 0}}, // ( 38, 82) + { 0, { 0, 0, 0}}, // ( 39, 82) + { 0, { 0, 0, 0}}, // ( 40, 82) + { 0, { 0, 0, 0}}, // ( 41, 82) + { 0, { 0, 0, 0}}, // ( 42, 82) + { 0, { 0, 0, 0}}, // ( 43, 82) + { 0, { 0, 0, 0}}, // ( 44, 82) + { 0, { 0, 0, 0}}, // ( 45, 82) + { 0, { 0, 0, 0}}, // ( 46, 82) + { 0, { 0, 0, 0}}, // ( 47, 82) + { 0, { 0, 0, 0}}, // ( 48, 82) + { 0, { 0, 0, 0}}, // ( 49, 82) + { 0, { 0, 0, 0}}, // ( 50, 82) + { 0, { 0, 0, 0}}, // ( 51, 82) + { 0, { 0, 0, 0}}, // ( 52, 82) + { 0, { 0, 0, 0}}, // ( 53, 82) + { 0, { 0, 0, 0}}, // ( 54, 82) + { 0, { 0, 0, 0}}, // ( 55, 82) + { 0, { 0, 0, 0}}, // ( 56, 82) + { 0, { 0, 0, 0}}, // ( 57, 82) + { 0, { 0, 0, 0}}, // ( 58, 82) + { 0, { 0, 0, 0}}, // ( 59, 82) + { 0, { 0, 0, 0}}, // ( 60, 82) + { 0, { 0, 0, 0}}, // ( 61, 82) + { 0, { 0, 0, 0}}, // ( 62, 82) + { 0, { 0, 0, 0}}, // ( 63, 82) + { 0, { 0, 0, 0}}, // ( 64, 82) + { 0, { 0, 0, 0}}, // ( 65, 82) + { 0, { 0, 0, 0}}, // ( 66, 82) + { 0, { 0, 0, 0}}, // ( 67, 82) + { 0, { 0, 0, 0}}, // ( 68, 82) + { 0, { 0, 0, 0}}, // ( 69, 82) + { 0, { 0, 0, 0}}, // ( 70, 82) + { 0, { 0, 0, 0}}, // ( 71, 82) + { 0, { 0, 0, 0}}, // ( 72, 82) + { 0, { 0, 0, 0}}, // ( 73, 82) + { 0, { 0, 0, 0}}, // ( 74, 82) + { 0, { 0, 0, 0}}, // ( 75, 82) + { 0, { 0, 0, 0}}, // ( 76, 82) + { 0, { 0, 0, 0}}, // ( 77, 82) + { 0, { 0, 0, 0}}, // ( 78, 82) + { 0, { 0, 0, 0}}, // ( 79, 82) + { 0, { 0, 0, 0}}, // ( 80, 82) + { 0, { 0, 0, 0}}, // ( 81, 82) + { 0, { 0, 0, 0}}, // ( 82, 82) + { 0, { 0, 0, 0}}, // ( 83, 82) + { 0, { 0, 0, 0}}, // ( 84, 82) + { 0, { 0, 0, 0}}, // ( 85, 82) + { 0, { 0, 0, 0}}, // ( 86, 82) + { 0, { 0, 0, 0}}, // ( 87, 82) + { 0, { 0, 0, 0}}, // ( 88, 82) + { 0, { 0, 0, 0}}, // ( 89, 82) + { 0, { 0, 0, 0}}, // ( 90, 82) + { 0, { 0, 0, 0}}, // ( 91, 82) + { 0, { 0, 0, 0}}, // ( 92, 82) + { 0, { 0, 0, 0}}, // ( 93, 82) + { 0, { 0, 0, 0}}, // ( 94, 82) + { 0, { 0, 0, 0}}, // ( 95, 82) + { 0, { 0, 0, 0}}, // ( 96, 82) + { 0, { 0, 0, 0}}, // ( 97, 82) + { 0, { 0, 0, 0}}, // ( 98, 82) + { 0, { 0, 0, 0}}, // ( 99, 82) + { 0, { 0, 0, 0}}, // (100, 82) + { 0, { 0, 0, 0}}, // (101, 82) + { 0, { 0, 0, 0}}, // (102, 82) + { 0, { 0, 0, 0}}, // (103, 82) + { 0, { 0, 0, 0}}, // (104, 82) + { 0, { 0, 0, 0}}, // (105, 82) + { 0, { 0, 0, 0}}, // (106, 82) + { 0, { 0, 0, 0}}, // (107, 82) + { 0, { 0, 0, 0}}, // (108, 82) + { 0, { 0, 0, 0}}, // (109, 82) + { 0, { 0, 0, 0}}, // (110, 82) + { 0, { 0, 0, 0}}, // (111, 82) + { 0, { 0, 0, 0}}, // (112, 82) + { 0, { 0, 0, 0}}, // (113, 82) + { 0, { 0, 0, 0}}, // (114, 82) + { 0, { 0, 0, 0}}, // (115, 82) + { 0, { 0, 0, 0}}, // (116, 82) + { 0, { 0, 0, 0}}, // (117, 82) + { 0, { 0, 0, 0}}, // (118, 82) + { 0, { 0, 0, 0}}, // (119, 82) + { 0, { 0, 0, 0}}, // (120, 82) + { 0, { 0, 0, 0}}, // (121, 82) + { 0, { 0, 0, 0}}, // (122, 82) + { 0, { 0, 0, 0}}, // (123, 82) + { 0, { 0, 0, 0}}, // (124, 82) + { 0, { 0, 0, 0}}, // (125, 82) + { 0, { 0, 0, 0}}, // (126, 82) + { 0, { 0, 0, 0}}, // (127, 82) + { 0, { 0, 0, 0}}, // (128, 82) + { 0, { 0, 0, 0}}, // (129, 82) + { 0, { 0, 0, 0}}, // (130, 82) + { 0, { 0, 0, 0}}, // (131, 82) + { 0, { 0, 0, 0}}, // (132, 82) + { 0, { 0, 0, 0}}, // (133, 82) + { 0, { 0, 0, 0}}, // (134, 82) + { 0, { 0, 0, 0}}, // (135, 82) + { 0, { 0, 0, 0}}, // (136, 82) + { 0, { 0, 0, 0}}, // (137, 82) + { 0, { 0, 0, 0}}, // (138, 82) + { 0, { 0, 0, 0}}, // (139, 82) + { 0, { 0, 0, 0}}, // (140, 82) + { 0, { 0, 0, 0}}, // (141, 82) + { 0, { 0, 0, 0}}, // (142, 82) + { 0, { 0, 0, 0}}, // (143, 82) + { 0, { 0, 0, 0}}, // (144, 82) + { 0, { 0, 0, 0}}, // (145, 82) + { 0, { 0, 0, 0}}, // (146, 82) + { 0, { 0, 0, 0}}, // (147, 82) + { 0, { 0, 0, 0}}, // (148, 82) + { 0, { 0, 0, 0}}, // (149, 82) + { 0, { 0, 0, 0}}, // (150, 82) + { 0, { 0, 0, 0}}, // (151, 82) + { 0, { 0, 0, 0}}, // (152, 82) + { 0, { 0, 0, 0}}, // (153, 82) + { 0, { 0, 0, 0}}, // (154, 82) + { 0, { 0, 0, 0}}, // (155, 82) + { 0, { 0, 0, 0}}, // (156, 82) + { 0, { 0, 0, 0}}, // (157, 82) + { 0, { 0, 0, 0}}, // (158, 82) + { 0, { 0, 0, 0}}, // (159, 82) + { 0, { 0, 0, 0}}, // (160, 82) + { 0, { 0, 0, 0}}, // (161, 82) + { 0, { 0, 0, 0}}, // (162, 82) + { 0, { 0, 0, 0}}, // (163, 82) + { 0, { 0, 0, 0}}, // (164, 82) + { 0, { 0, 0, 0}}, // (165, 82) + { 0, { 0, 0, 0}}, // (166, 82) + { 0, { 0, 0, 0}}, // (167, 82) + { 0, { 0, 0, 0}}, // (168, 82) + { 0, { 0, 0, 0}}, // (169, 82) + { 0, { 0, 0, 0}}, // (170, 82) + { 0, { 0, 0, 0}}, // (171, 82) + { 0, { 0, 0, 0}}, // (172, 82) + { 0, { 0, 0, 0}}, // (173, 82) + { 0, { 0, 0, 0}}, // (174, 82) + { 0, { 0, 0, 0}}, // (175, 82) + { 0, { 0, 0, 0}}, // (176, 82) + { 43, { 0, 0, 0}}, // (177, 82) + {128, { 0, 0, 0}}, // (178, 82) + {128, { 0, 0, 0}}, // (179, 82) + {128, { 0, 0, 0}}, // ( 0, 83) + {128, { 0, 0, 0}}, // ( 1, 83) + { 34, { 0, 0, 0}}, // ( 2, 83) + { 0, { 0, 0, 0}}, // ( 3, 83) + { 0, { 0, 0, 0}}, // ( 4, 83) + { 0, { 0, 0, 0}}, // ( 5, 83) + { 0, { 0, 0, 0}}, // ( 6, 83) + { 0, { 0, 0, 0}}, // ( 7, 83) + { 0, { 0, 0, 0}}, // ( 8, 83) + { 0, { 0, 0, 0}}, // ( 9, 83) + { 0, { 0, 0, 0}}, // ( 10, 83) + { 0, { 0, 0, 0}}, // ( 11, 83) + { 0, { 0, 0, 0}}, // ( 12, 83) + { 0, { 0, 0, 0}}, // ( 13, 83) + { 0, { 0, 0, 0}}, // ( 14, 83) + { 0, { 0, 0, 0}}, // ( 15, 83) + { 0, { 0, 0, 0}}, // ( 16, 83) + { 0, { 0, 0, 0}}, // ( 17, 83) + { 0, { 0, 0, 0}}, // ( 18, 83) + { 0, { 0, 0, 0}}, // ( 19, 83) + { 0, { 0, 0, 0}}, // ( 20, 83) + { 0, { 0, 0, 0}}, // ( 21, 83) + { 0, { 0, 0, 0}}, // ( 22, 83) + { 0, { 0, 0, 0}}, // ( 23, 83) + { 0, { 0, 0, 0}}, // ( 24, 83) + { 0, { 0, 0, 0}}, // ( 25, 83) + { 0, { 0, 0, 0}}, // ( 26, 83) + { 0, { 0, 0, 0}}, // ( 27, 83) + { 0, { 0, 0, 0}}, // ( 28, 83) + { 0, { 0, 0, 0}}, // ( 29, 83) + { 0, { 0, 0, 0}}, // ( 30, 83) + { 0, { 0, 0, 0}}, // ( 31, 83) + { 0, { 0, 0, 0}}, // ( 32, 83) + { 0, { 0, 0, 0}}, // ( 33, 83) + { 0, { 0, 0, 0}}, // ( 34, 83) + { 0, { 0, 0, 0}}, // ( 35, 83) + { 0, { 0, 0, 0}}, // ( 36, 83) + { 0, { 0, 0, 0}}, // ( 37, 83) + { 0, { 0, 0, 0}}, // ( 38, 83) + { 0, { 0, 0, 0}}, // ( 39, 83) + { 0, { 0, 0, 0}}, // ( 40, 83) + { 0, { 0, 0, 0}}, // ( 41, 83) + { 0, { 0, 0, 0}}, // ( 42, 83) + { 0, { 0, 0, 0}}, // ( 43, 83) + { 0, { 0, 0, 0}}, // ( 44, 83) + { 0, { 0, 0, 0}}, // ( 45, 83) + { 0, { 0, 0, 0}}, // ( 46, 83) + { 0, { 0, 0, 0}}, // ( 47, 83) + { 0, { 0, 0, 0}}, // ( 48, 83) + { 0, { 0, 0, 0}}, // ( 49, 83) + { 0, { 0, 0, 0}}, // ( 50, 83) + { 0, { 0, 0, 0}}, // ( 51, 83) + { 0, { 0, 0, 0}}, // ( 52, 83) + { 0, { 0, 0, 0}}, // ( 53, 83) + { 0, { 0, 0, 0}}, // ( 54, 83) + { 0, { 0, 0, 0}}, // ( 55, 83) + { 0, { 0, 0, 0}}, // ( 56, 83) + { 0, { 0, 0, 0}}, // ( 57, 83) + { 0, { 0, 0, 0}}, // ( 58, 83) + { 0, { 0, 0, 0}}, // ( 59, 83) + { 0, { 0, 0, 0}}, // ( 60, 83) + { 0, { 0, 0, 0}}, // ( 61, 83) + { 0, { 0, 0, 0}}, // ( 62, 83) + { 0, { 0, 0, 0}}, // ( 63, 83) + { 0, { 0, 0, 0}}, // ( 64, 83) + { 0, { 0, 0, 0}}, // ( 65, 83) + { 0, { 0, 0, 0}}, // ( 66, 83) + { 0, { 0, 0, 0}}, // ( 67, 83) + { 0, { 0, 0, 0}}, // ( 68, 83) + { 0, { 0, 0, 0}}, // ( 69, 83) + { 0, { 0, 0, 0}}, // ( 70, 83) + { 0, { 0, 0, 0}}, // ( 71, 83) + { 0, { 0, 0, 0}}, // ( 72, 83) + { 0, { 0, 0, 0}}, // ( 73, 83) + { 0, { 0, 0, 0}}, // ( 74, 83) + { 0, { 0, 0, 0}}, // ( 75, 83) + { 0, { 0, 0, 0}}, // ( 76, 83) + { 0, { 0, 0, 0}}, // ( 77, 83) + { 0, { 0, 0, 0}}, // ( 78, 83) + { 0, { 0, 0, 0}}, // ( 79, 83) + { 0, { 0, 0, 0}}, // ( 80, 83) + { 0, { 0, 0, 0}}, // ( 81, 83) + { 0, { 0, 0, 0}}, // ( 82, 83) + { 0, { 0, 0, 0}}, // ( 83, 83) + { 0, { 0, 0, 0}}, // ( 84, 83) + { 0, { 0, 0, 0}}, // ( 85, 83) + { 0, { 0, 0, 0}}, // ( 86, 83) + { 0, { 0, 0, 0}}, // ( 87, 83) + { 0, { 0, 0, 0}}, // ( 88, 83) + { 0, { 0, 0, 0}}, // ( 89, 83) + { 0, { 0, 0, 0}}, // ( 90, 83) + { 0, { 0, 0, 0}}, // ( 91, 83) + { 0, { 0, 0, 0}}, // ( 92, 83) + { 0, { 0, 0, 0}}, // ( 93, 83) + { 0, { 0, 0, 0}}, // ( 94, 83) + { 0, { 0, 0, 0}}, // ( 95, 83) + { 0, { 0, 0, 0}}, // ( 96, 83) + { 0, { 0, 0, 0}}, // ( 97, 83) + { 0, { 0, 0, 0}}, // ( 98, 83) + { 0, { 0, 0, 0}}, // ( 99, 83) + { 0, { 0, 0, 0}}, // (100, 83) + { 0, { 0, 0, 0}}, // (101, 83) + { 0, { 0, 0, 0}}, // (102, 83) + { 0, { 0, 0, 0}}, // (103, 83) + { 0, { 0, 0, 0}}, // (104, 83) + { 0, { 0, 0, 0}}, // (105, 83) + { 0, { 0, 0, 0}}, // (106, 83) + { 0, { 0, 0, 0}}, // (107, 83) + { 0, { 0, 0, 0}}, // (108, 83) + { 0, { 0, 0, 0}}, // (109, 83) + { 0, { 0, 0, 0}}, // (110, 83) + { 0, { 0, 0, 0}}, // (111, 83) + { 0, { 0, 0, 0}}, // (112, 83) + { 0, { 0, 0, 0}}, // (113, 83) + { 0, { 0, 0, 0}}, // (114, 83) + { 0, { 0, 0, 0}}, // (115, 83) + { 0, { 0, 0, 0}}, // (116, 83) + { 0, { 0, 0, 0}}, // (117, 83) + { 0, { 0, 0, 0}}, // (118, 83) + { 0, { 0, 0, 0}}, // (119, 83) + { 0, { 0, 0, 0}}, // (120, 83) + { 0, { 0, 0, 0}}, // (121, 83) + { 0, { 0, 0, 0}}, // (122, 83) + { 0, { 0, 0, 0}}, // (123, 83) + { 0, { 0, 0, 0}}, // (124, 83) + { 0, { 0, 0, 0}}, // (125, 83) + { 0, { 0, 0, 0}}, // (126, 83) + { 0, { 0, 0, 0}}, // (127, 83) + { 0, { 0, 0, 0}}, // (128, 83) + { 0, { 0, 0, 0}}, // (129, 83) + { 0, { 0, 0, 0}}, // (130, 83) + { 0, { 0, 0, 0}}, // (131, 83) + { 0, { 0, 0, 0}}, // (132, 83) + { 0, { 0, 0, 0}}, // (133, 83) + { 0, { 0, 0, 0}}, // (134, 83) + { 0, { 0, 0, 0}}, // (135, 83) + { 0, { 0, 0, 0}}, // (136, 83) + { 0, { 0, 0, 0}}, // (137, 83) + { 0, { 0, 0, 0}}, // (138, 83) + { 0, { 0, 0, 0}}, // (139, 83) + { 0, { 0, 0, 0}}, // (140, 83) + { 0, { 0, 0, 0}}, // (141, 83) + { 0, { 0, 0, 0}}, // (142, 83) + { 0, { 0, 0, 0}}, // (143, 83) + { 0, { 0, 0, 0}}, // (144, 83) + { 0, { 0, 0, 0}}, // (145, 83) + { 0, { 0, 0, 0}}, // (146, 83) + { 0, { 0, 0, 0}}, // (147, 83) + { 0, { 0, 0, 0}}, // (148, 83) + { 0, { 0, 0, 0}}, // (149, 83) + { 0, { 0, 0, 0}}, // (150, 83) + { 0, { 0, 0, 0}}, // (151, 83) + { 0, { 0, 0, 0}}, // (152, 83) + { 0, { 0, 0, 0}}, // (153, 83) + { 0, { 0, 0, 0}}, // (154, 83) + { 0, { 0, 0, 0}}, // (155, 83) + { 0, { 0, 0, 0}}, // (156, 83) + { 0, { 0, 0, 0}}, // (157, 83) + { 0, { 0, 0, 0}}, // (158, 83) + { 0, { 0, 0, 0}}, // (159, 83) + { 0, { 0, 0, 0}}, // (160, 83) + { 0, { 0, 0, 0}}, // (161, 83) + { 0, { 0, 0, 0}}, // (162, 83) + { 0, { 0, 0, 0}}, // (163, 83) + { 0, { 0, 0, 0}}, // (164, 83) + { 0, { 0, 0, 0}}, // (165, 83) + { 0, { 0, 0, 0}}, // (166, 83) + { 0, { 0, 0, 0}}, // (167, 83) + { 0, { 0, 0, 0}}, // (168, 83) + { 0, { 0, 0, 0}}, // (169, 83) + { 0, { 0, 0, 0}}, // (170, 83) + { 0, { 0, 0, 0}}, // (171, 83) + { 0, { 0, 0, 0}}, // (172, 83) + { 0, { 0, 0, 0}}, // (173, 83) + { 0, { 0, 0, 0}}, // (174, 83) + { 0, { 0, 0, 0}}, // (175, 83) + { 0, { 0, 0, 0}}, // (176, 83) + { 34, { 0, 0, 0}}, // (177, 83) + {128, { 0, 0, 0}}, // (178, 83) + {128, { 0, 0, 0}}, // (179, 83) + {128, { 0, 0, 0}}, // ( 0, 84) + {128, { 0, 0, 0}}, // ( 1, 84) + { 25, { 0, 0, 0}}, // ( 2, 84) + { 0, { 0, 0, 0}}, // ( 3, 84) + { 0, { 0, 0, 0}}, // ( 4, 84) + { 0, { 0, 0, 0}}, // ( 5, 84) + { 0, { 0, 0, 0}}, // ( 6, 84) + { 0, { 0, 0, 0}}, // ( 7, 84) + { 0, { 0, 0, 0}}, // ( 8, 84) + { 0, { 0, 0, 0}}, // ( 9, 84) + { 0, { 0, 0, 0}}, // ( 10, 84) + { 0, { 0, 0, 0}}, // ( 11, 84) + { 0, { 0, 0, 0}}, // ( 12, 84) + { 0, { 0, 0, 0}}, // ( 13, 84) + { 0, { 0, 0, 0}}, // ( 14, 84) + { 0, { 0, 0, 0}}, // ( 15, 84) + { 0, { 0, 0, 0}}, // ( 16, 84) + { 0, { 0, 0, 0}}, // ( 17, 84) + { 0, { 0, 0, 0}}, // ( 18, 84) + { 0, { 0, 0, 0}}, // ( 19, 84) + { 0, { 0, 0, 0}}, // ( 20, 84) + { 0, { 0, 0, 0}}, // ( 21, 84) + { 0, { 0, 0, 0}}, // ( 22, 84) + { 0, { 0, 0, 0}}, // ( 23, 84) + { 0, { 0, 0, 0}}, // ( 24, 84) + { 0, { 0, 0, 0}}, // ( 25, 84) + { 0, { 0, 0, 0}}, // ( 26, 84) + { 0, { 0, 0, 0}}, // ( 27, 84) + { 0, { 0, 0, 0}}, // ( 28, 84) + { 0, { 0, 0, 0}}, // ( 29, 84) + { 0, { 0, 0, 0}}, // ( 30, 84) + { 0, { 0, 0, 0}}, // ( 31, 84) + { 0, { 0, 0, 0}}, // ( 32, 84) + { 0, { 0, 0, 0}}, // ( 33, 84) + { 0, { 0, 0, 0}}, // ( 34, 84) + { 0, { 0, 0, 0}}, // ( 35, 84) + { 0, { 0, 0, 0}}, // ( 36, 84) + { 0, { 0, 0, 0}}, // ( 37, 84) + { 0, { 0, 0, 0}}, // ( 38, 84) + { 0, { 0, 0, 0}}, // ( 39, 84) + { 0, { 0, 0, 0}}, // ( 40, 84) + { 0, { 0, 0, 0}}, // ( 41, 84) + { 0, { 0, 0, 0}}, // ( 42, 84) + { 0, { 0, 0, 0}}, // ( 43, 84) + { 0, { 0, 0, 0}}, // ( 44, 84) + { 0, { 0, 0, 0}}, // ( 45, 84) + { 0, { 0, 0, 0}}, // ( 46, 84) + { 0, { 0, 0, 0}}, // ( 47, 84) + { 0, { 0, 0, 0}}, // ( 48, 84) + { 0, { 0, 0, 0}}, // ( 49, 84) + { 0, { 0, 0, 0}}, // ( 50, 84) + { 0, { 0, 0, 0}}, // ( 51, 84) + { 0, { 0, 0, 0}}, // ( 52, 84) + { 0, { 0, 0, 0}}, // ( 53, 84) + { 0, { 0, 0, 0}}, // ( 54, 84) + { 0, { 0, 0, 0}}, // ( 55, 84) + { 0, { 0, 0, 0}}, // ( 56, 84) + { 0, { 0, 0, 0}}, // ( 57, 84) + { 0, { 0, 0, 0}}, // ( 58, 84) + { 0, { 0, 0, 0}}, // ( 59, 84) + { 0, { 0, 0, 0}}, // ( 60, 84) + { 0, { 0, 0, 0}}, // ( 61, 84) + { 0, { 0, 0, 0}}, // ( 62, 84) + { 0, { 0, 0, 0}}, // ( 63, 84) + { 0, { 0, 0, 0}}, // ( 64, 84) + { 0, { 0, 0, 0}}, // ( 65, 84) + { 0, { 0, 0, 0}}, // ( 66, 84) + { 0, { 0, 0, 0}}, // ( 67, 84) + { 0, { 0, 0, 0}}, // ( 68, 84) + { 0, { 0, 0, 0}}, // ( 69, 84) + { 0, { 0, 0, 0}}, // ( 70, 84) + { 0, { 0, 0, 0}}, // ( 71, 84) + { 0, { 0, 0, 0}}, // ( 72, 84) + { 0, { 0, 0, 0}}, // ( 73, 84) + { 0, { 0, 0, 0}}, // ( 74, 84) + { 0, { 0, 0, 0}}, // ( 75, 84) + { 0, { 0, 0, 0}}, // ( 76, 84) + { 0, { 0, 0, 0}}, // ( 77, 84) + { 0, { 0, 0, 0}}, // ( 78, 84) + { 0, { 0, 0, 0}}, // ( 79, 84) + { 0, { 0, 0, 0}}, // ( 80, 84) + { 0, { 0, 0, 0}}, // ( 81, 84) + { 0, { 0, 0, 0}}, // ( 82, 84) + { 0, { 0, 0, 0}}, // ( 83, 84) + { 0, { 0, 0, 0}}, // ( 84, 84) + { 0, { 0, 0, 0}}, // ( 85, 84) + { 0, { 0, 0, 0}}, // ( 86, 84) + { 0, { 0, 0, 0}}, // ( 87, 84) + { 0, { 0, 0, 0}}, // ( 88, 84) + { 0, { 0, 0, 0}}, // ( 89, 84) + { 0, { 0, 0, 0}}, // ( 90, 84) + { 0, { 0, 0, 0}}, // ( 91, 84) + { 0, { 0, 0, 0}}, // ( 92, 84) + { 0, { 0, 0, 0}}, // ( 93, 84) + { 0, { 0, 0, 0}}, // ( 94, 84) + { 0, { 0, 0, 0}}, // ( 95, 84) + { 0, { 0, 0, 0}}, // ( 96, 84) + { 0, { 0, 0, 0}}, // ( 97, 84) + { 0, { 0, 0, 0}}, // ( 98, 84) + { 0, { 0, 0, 0}}, // ( 99, 84) + { 0, { 0, 0, 0}}, // (100, 84) + { 0, { 0, 0, 0}}, // (101, 84) + { 0, { 0, 0, 0}}, // (102, 84) + { 0, { 0, 0, 0}}, // (103, 84) + { 0, { 0, 0, 0}}, // (104, 84) + { 0, { 0, 0, 0}}, // (105, 84) + { 0, { 0, 0, 0}}, // (106, 84) + { 0, { 0, 0, 0}}, // (107, 84) + { 0, { 0, 0, 0}}, // (108, 84) + { 0, { 0, 0, 0}}, // (109, 84) + { 0, { 0, 0, 0}}, // (110, 84) + { 0, { 0, 0, 0}}, // (111, 84) + { 0, { 0, 0, 0}}, // (112, 84) + { 0, { 0, 0, 0}}, // (113, 84) + { 0, { 0, 0, 0}}, // (114, 84) + { 0, { 0, 0, 0}}, // (115, 84) + { 0, { 0, 0, 0}}, // (116, 84) + { 0, { 0, 0, 0}}, // (117, 84) + { 0, { 0, 0, 0}}, // (118, 84) + { 0, { 0, 0, 0}}, // (119, 84) + { 0, { 0, 0, 0}}, // (120, 84) + { 0, { 0, 0, 0}}, // (121, 84) + { 0, { 0, 0, 0}}, // (122, 84) + { 0, { 0, 0, 0}}, // (123, 84) + { 0, { 0, 0, 0}}, // (124, 84) + { 0, { 0, 0, 0}}, // (125, 84) + { 0, { 0, 0, 0}}, // (126, 84) + { 0, { 0, 0, 0}}, // (127, 84) + { 0, { 0, 0, 0}}, // (128, 84) + { 0, { 0, 0, 0}}, // (129, 84) + { 0, { 0, 0, 0}}, // (130, 84) + { 0, { 0, 0, 0}}, // (131, 84) + { 0, { 0, 0, 0}}, // (132, 84) + { 0, { 0, 0, 0}}, // (133, 84) + { 0, { 0, 0, 0}}, // (134, 84) + { 0, { 0, 0, 0}}, // (135, 84) + { 0, { 0, 0, 0}}, // (136, 84) + { 0, { 0, 0, 0}}, // (137, 84) + { 0, { 0, 0, 0}}, // (138, 84) + { 0, { 0, 0, 0}}, // (139, 84) + { 0, { 0, 0, 0}}, // (140, 84) + { 0, { 0, 0, 0}}, // (141, 84) + { 0, { 0, 0, 0}}, // (142, 84) + { 0, { 0, 0, 0}}, // (143, 84) + { 0, { 0, 0, 0}}, // (144, 84) + { 0, { 0, 0, 0}}, // (145, 84) + { 0, { 0, 0, 0}}, // (146, 84) + { 0, { 0, 0, 0}}, // (147, 84) + { 0, { 0, 0, 0}}, // (148, 84) + { 0, { 0, 0, 0}}, // (149, 84) + { 0, { 0, 0, 0}}, // (150, 84) + { 0, { 0, 0, 0}}, // (151, 84) + { 0, { 0, 0, 0}}, // (152, 84) + { 0, { 0, 0, 0}}, // (153, 84) + { 0, { 0, 0, 0}}, // (154, 84) + { 0, { 0, 0, 0}}, // (155, 84) + { 0, { 0, 0, 0}}, // (156, 84) + { 0, { 0, 0, 0}}, // (157, 84) + { 0, { 0, 0, 0}}, // (158, 84) + { 0, { 0, 0, 0}}, // (159, 84) + { 0, { 0, 0, 0}}, // (160, 84) + { 0, { 0, 0, 0}}, // (161, 84) + { 0, { 0, 0, 0}}, // (162, 84) + { 0, { 0, 0, 0}}, // (163, 84) + { 0, { 0, 0, 0}}, // (164, 84) + { 0, { 0, 0, 0}}, // (165, 84) + { 0, { 0, 0, 0}}, // (166, 84) + { 0, { 0, 0, 0}}, // (167, 84) + { 0, { 0, 0, 0}}, // (168, 84) + { 0, { 0, 0, 0}}, // (169, 84) + { 0, { 0, 0, 0}}, // (170, 84) + { 0, { 0, 0, 0}}, // (171, 84) + { 0, { 0, 0, 0}}, // (172, 84) + { 0, { 0, 0, 0}}, // (173, 84) + { 0, { 0, 0, 0}}, // (174, 84) + { 0, { 0, 0, 0}}, // (175, 84) + { 0, { 0, 0, 0}}, // (176, 84) + { 25, { 0, 0, 0}}, // (177, 84) + {128, { 0, 0, 0}}, // (178, 84) + {128, { 0, 0, 0}}, // (179, 84) + {128, { 0, 0, 0}}, // ( 0, 85) + {128, { 0, 0, 0}}, // ( 1, 85) + { 16, { 0, 0, 0}}, // ( 2, 85) + { 0, { 0, 0, 0}}, // ( 3, 85) + { 0, { 0, 0, 0}}, // ( 4, 85) + { 0, { 0, 0, 0}}, // ( 5, 85) + { 0, { 0, 0, 0}}, // ( 6, 85) + { 0, { 0, 0, 0}}, // ( 7, 85) + { 0, { 0, 0, 0}}, // ( 8, 85) + { 0, { 0, 0, 0}}, // ( 9, 85) + { 0, { 0, 0, 0}}, // ( 10, 85) + { 0, { 0, 0, 0}}, // ( 11, 85) + { 0, { 0, 0, 0}}, // ( 12, 85) + { 0, { 0, 0, 0}}, // ( 13, 85) + { 0, { 0, 0, 0}}, // ( 14, 85) + { 0, { 0, 0, 0}}, // ( 15, 85) + { 0, { 0, 0, 0}}, // ( 16, 85) + { 0, { 0, 0, 0}}, // ( 17, 85) + { 0, { 0, 0, 0}}, // ( 18, 85) + { 0, { 0, 0, 0}}, // ( 19, 85) + { 0, { 0, 0, 0}}, // ( 20, 85) + { 0, { 0, 0, 0}}, // ( 21, 85) + { 0, { 0, 0, 0}}, // ( 22, 85) + { 0, { 0, 0, 0}}, // ( 23, 85) + { 0, { 0, 0, 0}}, // ( 24, 85) + { 0, { 0, 0, 0}}, // ( 25, 85) + { 0, { 0, 0, 0}}, // ( 26, 85) + { 0, { 0, 0, 0}}, // ( 27, 85) + { 0, { 0, 0, 0}}, // ( 28, 85) + { 0, { 0, 0, 0}}, // ( 29, 85) + { 0, { 0, 0, 0}}, // ( 30, 85) + { 0, { 0, 0, 0}}, // ( 31, 85) + { 0, { 0, 0, 0}}, // ( 32, 85) + { 0, { 0, 0, 0}}, // ( 33, 85) + { 0, { 0, 0, 0}}, // ( 34, 85) + { 0, { 0, 0, 0}}, // ( 35, 85) + { 0, { 0, 0, 0}}, // ( 36, 85) + { 0, { 0, 0, 0}}, // ( 37, 85) + { 0, { 0, 0, 0}}, // ( 38, 85) + { 0, { 0, 0, 0}}, // ( 39, 85) + { 0, { 0, 0, 0}}, // ( 40, 85) + { 0, { 0, 0, 0}}, // ( 41, 85) + { 0, { 0, 0, 0}}, // ( 42, 85) + { 0, { 0, 0, 0}}, // ( 43, 85) + { 0, { 0, 0, 0}}, // ( 44, 85) + { 0, { 0, 0, 0}}, // ( 45, 85) + { 0, { 0, 0, 0}}, // ( 46, 85) + { 0, { 0, 0, 0}}, // ( 47, 85) + { 0, { 0, 0, 0}}, // ( 48, 85) + { 0, { 0, 0, 0}}, // ( 49, 85) + { 0, { 0, 0, 0}}, // ( 50, 85) + { 0, { 0, 0, 0}}, // ( 51, 85) + { 0, { 0, 0, 0}}, // ( 52, 85) + { 0, { 0, 0, 0}}, // ( 53, 85) + { 0, { 0, 0, 0}}, // ( 54, 85) + { 0, { 0, 0, 0}}, // ( 55, 85) + { 0, { 0, 0, 0}}, // ( 56, 85) + { 0, { 0, 0, 0}}, // ( 57, 85) + { 0, { 0, 0, 0}}, // ( 58, 85) + { 0, { 0, 0, 0}}, // ( 59, 85) + { 0, { 0, 0, 0}}, // ( 60, 85) + { 0, { 0, 0, 0}}, // ( 61, 85) + { 0, { 0, 0, 0}}, // ( 62, 85) + { 0, { 0, 0, 0}}, // ( 63, 85) + { 0, { 0, 0, 0}}, // ( 64, 85) + { 0, { 0, 0, 0}}, // ( 65, 85) + { 0, { 0, 0, 0}}, // ( 66, 85) + { 0, { 0, 0, 0}}, // ( 67, 85) + { 0, { 0, 0, 0}}, // ( 68, 85) + { 0, { 0, 0, 0}}, // ( 69, 85) + { 0, { 0, 0, 0}}, // ( 70, 85) + { 0, { 0, 0, 0}}, // ( 71, 85) + { 0, { 0, 0, 0}}, // ( 72, 85) + { 0, { 0, 0, 0}}, // ( 73, 85) + { 0, { 0, 0, 0}}, // ( 74, 85) + { 0, { 0, 0, 0}}, // ( 75, 85) + { 0, { 0, 0, 0}}, // ( 76, 85) + { 0, { 0, 0, 0}}, // ( 77, 85) + { 0, { 0, 0, 0}}, // ( 78, 85) + { 0, { 0, 0, 0}}, // ( 79, 85) + { 0, { 0, 0, 0}}, // ( 80, 85) + { 0, { 0, 0, 0}}, // ( 81, 85) + { 0, { 0, 0, 0}}, // ( 82, 85) + { 0, { 0, 0, 0}}, // ( 83, 85) + { 0, { 0, 0, 0}}, // ( 84, 85) + { 0, { 0, 0, 0}}, // ( 85, 85) + { 0, { 0, 0, 0}}, // ( 86, 85) + { 0, { 0, 0, 0}}, // ( 87, 85) + { 0, { 0, 0, 0}}, // ( 88, 85) + { 0, { 0, 0, 0}}, // ( 89, 85) + { 0, { 0, 0, 0}}, // ( 90, 85) + { 0, { 0, 0, 0}}, // ( 91, 85) + { 0, { 0, 0, 0}}, // ( 92, 85) + { 0, { 0, 0, 0}}, // ( 93, 85) + { 0, { 0, 0, 0}}, // ( 94, 85) + { 0, { 0, 0, 0}}, // ( 95, 85) + { 0, { 0, 0, 0}}, // ( 96, 85) + { 0, { 0, 0, 0}}, // ( 97, 85) + { 0, { 0, 0, 0}}, // ( 98, 85) + { 0, { 0, 0, 0}}, // ( 99, 85) + { 0, { 0, 0, 0}}, // (100, 85) + { 0, { 0, 0, 0}}, // (101, 85) + { 0, { 0, 0, 0}}, // (102, 85) + { 0, { 0, 0, 0}}, // (103, 85) + { 0, { 0, 0, 0}}, // (104, 85) + { 0, { 0, 0, 0}}, // (105, 85) + { 0, { 0, 0, 0}}, // (106, 85) + { 0, { 0, 0, 0}}, // (107, 85) + { 0, { 0, 0, 0}}, // (108, 85) + { 0, { 0, 0, 0}}, // (109, 85) + { 0, { 0, 0, 0}}, // (110, 85) + { 0, { 0, 0, 0}}, // (111, 85) + { 0, { 0, 0, 0}}, // (112, 85) + { 0, { 0, 0, 0}}, // (113, 85) + { 0, { 0, 0, 0}}, // (114, 85) + { 0, { 0, 0, 0}}, // (115, 85) + { 0, { 0, 0, 0}}, // (116, 85) + { 0, { 0, 0, 0}}, // (117, 85) + { 0, { 0, 0, 0}}, // (118, 85) + { 0, { 0, 0, 0}}, // (119, 85) + { 0, { 0, 0, 0}}, // (120, 85) + { 0, { 0, 0, 0}}, // (121, 85) + { 0, { 0, 0, 0}}, // (122, 85) + { 0, { 0, 0, 0}}, // (123, 85) + { 0, { 0, 0, 0}}, // (124, 85) + { 0, { 0, 0, 0}}, // (125, 85) + { 0, { 0, 0, 0}}, // (126, 85) + { 0, { 0, 0, 0}}, // (127, 85) + { 0, { 0, 0, 0}}, // (128, 85) + { 0, { 0, 0, 0}}, // (129, 85) + { 0, { 0, 0, 0}}, // (130, 85) + { 0, { 0, 0, 0}}, // (131, 85) + { 0, { 0, 0, 0}}, // (132, 85) + { 0, { 0, 0, 0}}, // (133, 85) + { 0, { 0, 0, 0}}, // (134, 85) + { 0, { 0, 0, 0}}, // (135, 85) + { 0, { 0, 0, 0}}, // (136, 85) + { 0, { 0, 0, 0}}, // (137, 85) + { 0, { 0, 0, 0}}, // (138, 85) + { 0, { 0, 0, 0}}, // (139, 85) + { 0, { 0, 0, 0}}, // (140, 85) + { 0, { 0, 0, 0}}, // (141, 85) + { 0, { 0, 0, 0}}, // (142, 85) + { 0, { 0, 0, 0}}, // (143, 85) + { 0, { 0, 0, 0}}, // (144, 85) + { 0, { 0, 0, 0}}, // (145, 85) + { 0, { 0, 0, 0}}, // (146, 85) + { 0, { 0, 0, 0}}, // (147, 85) + { 0, { 0, 0, 0}}, // (148, 85) + { 0, { 0, 0, 0}}, // (149, 85) + { 0, { 0, 0, 0}}, // (150, 85) + { 0, { 0, 0, 0}}, // (151, 85) + { 0, { 0, 0, 0}}, // (152, 85) + { 0, { 0, 0, 0}}, // (153, 85) + { 0, { 0, 0, 0}}, // (154, 85) + { 0, { 0, 0, 0}}, // (155, 85) + { 0, { 0, 0, 0}}, // (156, 85) + { 0, { 0, 0, 0}}, // (157, 85) + { 0, { 0, 0, 0}}, // (158, 85) + { 0, { 0, 0, 0}}, // (159, 85) + { 0, { 0, 0, 0}}, // (160, 85) + { 0, { 0, 0, 0}}, // (161, 85) + { 0, { 0, 0, 0}}, // (162, 85) + { 0, { 0, 0, 0}}, // (163, 85) + { 0, { 0, 0, 0}}, // (164, 85) + { 0, { 0, 0, 0}}, // (165, 85) + { 0, { 0, 0, 0}}, // (166, 85) + { 0, { 0, 0, 0}}, // (167, 85) + { 0, { 0, 0, 0}}, // (168, 85) + { 0, { 0, 0, 0}}, // (169, 85) + { 0, { 0, 0, 0}}, // (170, 85) + { 0, { 0, 0, 0}}, // (171, 85) + { 0, { 0, 0, 0}}, // (172, 85) + { 0, { 0, 0, 0}}, // (173, 85) + { 0, { 0, 0, 0}}, // (174, 85) + { 0, { 0, 0, 0}}, // (175, 85) + { 0, { 0, 0, 0}}, // (176, 85) + { 15, { 0, 0, 0}}, // (177, 85) + {128, { 0, 0, 0}}, // (178, 85) + {128, { 0, 0, 0}}, // (179, 85) + {128, { 0, 0, 0}}, // ( 0, 86) + {128, { 0, 0, 0}}, // ( 1, 86) + { 12, { 0, 0, 0}}, // ( 2, 86) + { 0, { 0, 0, 0}}, // ( 3, 86) + { 0, { 0, 0, 0}}, // ( 4, 86) + { 0, { 0, 0, 0}}, // ( 5, 86) + { 0, { 0, 0, 0}}, // ( 6, 86) + { 0, { 0, 0, 0}}, // ( 7, 86) + { 0, { 0, 0, 0}}, // ( 8, 86) + { 0, { 0, 0, 0}}, // ( 9, 86) + { 0, { 0, 0, 0}}, // ( 10, 86) + { 0, { 0, 0, 0}}, // ( 11, 86) + { 0, { 0, 0, 0}}, // ( 12, 86) + { 0, { 0, 0, 0}}, // ( 13, 86) + { 0, { 0, 0, 0}}, // ( 14, 86) + { 0, { 0, 0, 0}}, // ( 15, 86) + { 0, { 0, 0, 0}}, // ( 16, 86) + { 0, { 0, 0, 0}}, // ( 17, 86) + { 0, { 0, 0, 0}}, // ( 18, 86) + { 0, { 0, 0, 0}}, // ( 19, 86) + { 0, { 0, 0, 0}}, // ( 20, 86) + { 0, { 0, 0, 0}}, // ( 21, 86) + { 0, { 0, 0, 0}}, // ( 22, 86) + { 0, { 0, 0, 0}}, // ( 23, 86) + { 0, { 0, 0, 0}}, // ( 24, 86) + { 0, { 0, 0, 0}}, // ( 25, 86) + { 0, { 0, 0, 0}}, // ( 26, 86) + { 0, { 0, 0, 0}}, // ( 27, 86) + { 0, { 0, 0, 0}}, // ( 28, 86) + { 0, { 0, 0, 0}}, // ( 29, 86) + { 0, { 0, 0, 0}}, // ( 30, 86) + { 0, { 0, 0, 0}}, // ( 31, 86) + { 0, { 0, 0, 0}}, // ( 32, 86) + { 0, { 0, 0, 0}}, // ( 33, 86) + { 0, { 0, 0, 0}}, // ( 34, 86) + { 0, { 0, 0, 0}}, // ( 35, 86) + { 0, { 0, 0, 0}}, // ( 36, 86) + { 0, { 0, 0, 0}}, // ( 37, 86) + { 0, { 0, 0, 0}}, // ( 38, 86) + { 0, { 0, 0, 0}}, // ( 39, 86) + { 0, { 0, 0, 0}}, // ( 40, 86) + { 0, { 0, 0, 0}}, // ( 41, 86) + { 0, { 0, 0, 0}}, // ( 42, 86) + { 0, { 0, 0, 0}}, // ( 43, 86) + { 0, { 0, 0, 0}}, // ( 44, 86) + { 0, { 0, 0, 0}}, // ( 45, 86) + { 0, { 0, 0, 0}}, // ( 46, 86) + { 0, { 0, 0, 0}}, // ( 47, 86) + { 0, { 0, 0, 0}}, // ( 48, 86) + { 0, { 0, 0, 0}}, // ( 49, 86) + { 0, { 0, 0, 0}}, // ( 50, 86) + { 0, { 0, 0, 0}}, // ( 51, 86) + { 0, { 0, 0, 0}}, // ( 52, 86) + { 0, { 0, 0, 0}}, // ( 53, 86) + { 0, { 0, 0, 0}}, // ( 54, 86) + { 0, { 0, 0, 0}}, // ( 55, 86) + { 0, { 0, 0, 0}}, // ( 56, 86) + { 0, { 0, 0, 0}}, // ( 57, 86) + { 0, { 0, 0, 0}}, // ( 58, 86) + { 0, { 0, 0, 0}}, // ( 59, 86) + { 0, { 0, 0, 0}}, // ( 60, 86) + { 0, { 0, 0, 0}}, // ( 61, 86) + { 0, { 0, 0, 0}}, // ( 62, 86) + { 0, { 0, 0, 0}}, // ( 63, 86) + { 0, { 0, 0, 0}}, // ( 64, 86) + { 0, { 0, 0, 0}}, // ( 65, 86) + { 0, { 0, 0, 0}}, // ( 66, 86) + { 0, { 0, 0, 0}}, // ( 67, 86) + { 0, { 0, 0, 0}}, // ( 68, 86) + { 0, { 0, 0, 0}}, // ( 69, 86) + { 0, { 0, 0, 0}}, // ( 70, 86) + { 0, { 0, 0, 0}}, // ( 71, 86) + { 0, { 0, 0, 0}}, // ( 72, 86) + { 0, { 0, 0, 0}}, // ( 73, 86) + { 0, { 0, 0, 0}}, // ( 74, 86) + { 0, { 0, 0, 0}}, // ( 75, 86) + { 0, { 0, 0, 0}}, // ( 76, 86) + { 0, { 0, 0, 0}}, // ( 77, 86) + { 0, { 0, 0, 0}}, // ( 78, 86) + { 0, { 0, 0, 0}}, // ( 79, 86) + { 0, { 0, 0, 0}}, // ( 80, 86) + { 0, { 0, 0, 0}}, // ( 81, 86) + { 0, { 0, 0, 0}}, // ( 82, 86) + { 0, { 0, 0, 0}}, // ( 83, 86) + { 0, { 0, 0, 0}}, // ( 84, 86) + { 0, { 0, 0, 0}}, // ( 85, 86) + { 0, { 0, 0, 0}}, // ( 86, 86) + { 0, { 0, 0, 0}}, // ( 87, 86) + { 0, { 0, 0, 0}}, // ( 88, 86) + { 0, { 0, 0, 0}}, // ( 89, 86) + { 0, { 0, 0, 0}}, // ( 90, 86) + { 0, { 0, 0, 0}}, // ( 91, 86) + { 0, { 0, 0, 0}}, // ( 92, 86) + { 0, { 0, 0, 0}}, // ( 93, 86) + { 0, { 0, 0, 0}}, // ( 94, 86) + { 0, { 0, 0, 0}}, // ( 95, 86) + { 0, { 0, 0, 0}}, // ( 96, 86) + { 0, { 0, 0, 0}}, // ( 97, 86) + { 0, { 0, 0, 0}}, // ( 98, 86) + { 0, { 0, 0, 0}}, // ( 99, 86) + { 0, { 0, 0, 0}}, // (100, 86) + { 0, { 0, 0, 0}}, // (101, 86) + { 0, { 0, 0, 0}}, // (102, 86) + { 0, { 0, 0, 0}}, // (103, 86) + { 0, { 0, 0, 0}}, // (104, 86) + { 0, { 0, 0, 0}}, // (105, 86) + { 0, { 0, 0, 0}}, // (106, 86) + { 0, { 0, 0, 0}}, // (107, 86) + { 0, { 0, 0, 0}}, // (108, 86) + { 0, { 0, 0, 0}}, // (109, 86) + { 0, { 0, 0, 0}}, // (110, 86) + { 0, { 0, 0, 0}}, // (111, 86) + { 0, { 0, 0, 0}}, // (112, 86) + { 0, { 0, 0, 0}}, // (113, 86) + { 0, { 0, 0, 0}}, // (114, 86) + { 0, { 0, 0, 0}}, // (115, 86) + { 0, { 0, 0, 0}}, // (116, 86) + { 0, { 0, 0, 0}}, // (117, 86) + { 0, { 0, 0, 0}}, // (118, 86) + { 0, { 0, 0, 0}}, // (119, 86) + { 0, { 0, 0, 0}}, // (120, 86) + { 0, { 0, 0, 0}}, // (121, 86) + { 0, { 0, 0, 0}}, // (122, 86) + { 0, { 0, 0, 0}}, // (123, 86) + { 0, { 0, 0, 0}}, // (124, 86) + { 0, { 0, 0, 0}}, // (125, 86) + { 0, { 0, 0, 0}}, // (126, 86) + { 0, { 0, 0, 0}}, // (127, 86) + { 0, { 0, 0, 0}}, // (128, 86) + { 0, { 0, 0, 0}}, // (129, 86) + { 0, { 0, 0, 0}}, // (130, 86) + { 0, { 0, 0, 0}}, // (131, 86) + { 0, { 0, 0, 0}}, // (132, 86) + { 0, { 0, 0, 0}}, // (133, 86) + { 0, { 0, 0, 0}}, // (134, 86) + { 0, { 0, 0, 0}}, // (135, 86) + { 0, { 0, 0, 0}}, // (136, 86) + { 0, { 0, 0, 0}}, // (137, 86) + { 0, { 0, 0, 0}}, // (138, 86) + { 0, { 0, 0, 0}}, // (139, 86) + { 0, { 0, 0, 0}}, // (140, 86) + { 0, { 0, 0, 0}}, // (141, 86) + { 0, { 0, 0, 0}}, // (142, 86) + { 0, { 0, 0, 0}}, // (143, 86) + { 0, { 0, 0, 0}}, // (144, 86) + { 0, { 0, 0, 0}}, // (145, 86) + { 0, { 0, 0, 0}}, // (146, 86) + { 0, { 0, 0, 0}}, // (147, 86) + { 0, { 0, 0, 0}}, // (148, 86) + { 0, { 0, 0, 0}}, // (149, 86) + { 0, { 0, 0, 0}}, // (150, 86) + { 0, { 0, 0, 0}}, // (151, 86) + { 0, { 0, 0, 0}}, // (152, 86) + { 0, { 0, 0, 0}}, // (153, 86) + { 0, { 0, 0, 0}}, // (154, 86) + { 0, { 0, 0, 0}}, // (155, 86) + { 0, { 0, 0, 0}}, // (156, 86) + { 0, { 0, 0, 0}}, // (157, 86) + { 0, { 0, 0, 0}}, // (158, 86) + { 0, { 0, 0, 0}}, // (159, 86) + { 0, { 0, 0, 0}}, // (160, 86) + { 0, { 0, 0, 0}}, // (161, 86) + { 0, { 0, 0, 0}}, // (162, 86) + { 0, { 0, 0, 0}}, // (163, 86) + { 0, { 0, 0, 0}}, // (164, 86) + { 0, { 0, 0, 0}}, // (165, 86) + { 0, { 0, 0, 0}}, // (166, 86) + { 0, { 0, 0, 0}}, // (167, 86) + { 0, { 0, 0, 0}}, // (168, 86) + { 0, { 0, 0, 0}}, // (169, 86) + { 0, { 0, 0, 0}}, // (170, 86) + { 0, { 0, 0, 0}}, // (171, 86) + { 0, { 0, 0, 0}}, // (172, 86) + { 0, { 0, 0, 0}}, // (173, 86) + { 0, { 0, 0, 0}}, // (174, 86) + { 0, { 0, 0, 0}}, // (175, 86) + { 0, { 0, 0, 0}}, // (176, 86) + { 11, { 0, 0, 0}}, // (177, 86) + {128, { 0, 0, 0}}, // (178, 86) + {128, { 0, 0, 0}}, // (179, 86) + {128, { 0, 0, 0}}, // ( 0, 87) + {128, { 0, 0, 0}}, // ( 1, 87) + { 8, { 0, 0, 0}}, // ( 2, 87) + { 0, { 0, 0, 0}}, // ( 3, 87) + { 0, { 0, 0, 0}}, // ( 4, 87) + { 0, { 0, 0, 0}}, // ( 5, 87) + { 0, { 0, 0, 0}}, // ( 6, 87) + { 0, { 0, 0, 0}}, // ( 7, 87) + { 0, { 0, 0, 0}}, // ( 8, 87) + { 0, { 0, 0, 0}}, // ( 9, 87) + { 0, { 0, 0, 0}}, // ( 10, 87) + { 0, { 0, 0, 0}}, // ( 11, 87) + { 0, { 0, 0, 0}}, // ( 12, 87) + { 0, { 0, 0, 0}}, // ( 13, 87) + { 0, { 0, 0, 0}}, // ( 14, 87) + { 0, { 0, 0, 0}}, // ( 15, 87) + { 0, { 0, 0, 0}}, // ( 16, 87) + { 0, { 0, 0, 0}}, // ( 17, 87) + { 0, { 0, 0, 0}}, // ( 18, 87) + { 0, { 0, 0, 0}}, // ( 19, 87) + { 0, { 0, 0, 0}}, // ( 20, 87) + { 0, { 0, 0, 0}}, // ( 21, 87) + { 0, { 0, 0, 0}}, // ( 22, 87) + { 0, { 0, 0, 0}}, // ( 23, 87) + { 0, { 0, 0, 0}}, // ( 24, 87) + { 0, { 0, 0, 0}}, // ( 25, 87) + { 0, { 0, 0, 0}}, // ( 26, 87) + { 0, { 0, 0, 0}}, // ( 27, 87) + { 0, { 0, 0, 0}}, // ( 28, 87) + { 0, { 0, 0, 0}}, // ( 29, 87) + { 0, { 0, 0, 0}}, // ( 30, 87) + { 0, { 0, 0, 0}}, // ( 31, 87) + { 0, { 0, 0, 0}}, // ( 32, 87) + { 0, { 0, 0, 0}}, // ( 33, 87) + { 0, { 0, 0, 0}}, // ( 34, 87) + { 0, { 0, 0, 0}}, // ( 35, 87) + { 0, { 0, 0, 0}}, // ( 36, 87) + { 0, { 0, 0, 0}}, // ( 37, 87) + { 0, { 0, 0, 0}}, // ( 38, 87) + { 0, { 0, 0, 0}}, // ( 39, 87) + { 0, { 0, 0, 0}}, // ( 40, 87) + { 0, { 0, 0, 0}}, // ( 41, 87) + { 0, { 0, 0, 0}}, // ( 42, 87) + { 0, { 0, 0, 0}}, // ( 43, 87) + { 0, { 0, 0, 0}}, // ( 44, 87) + { 0, { 0, 0, 0}}, // ( 45, 87) + { 0, { 0, 0, 0}}, // ( 46, 87) + { 0, { 0, 0, 0}}, // ( 47, 87) + { 0, { 0, 0, 0}}, // ( 48, 87) + { 0, { 0, 0, 0}}, // ( 49, 87) + { 0, { 0, 0, 0}}, // ( 50, 87) + { 0, { 0, 0, 0}}, // ( 51, 87) + { 0, { 0, 0, 0}}, // ( 52, 87) + { 0, { 0, 0, 0}}, // ( 53, 87) + { 0, { 0, 0, 0}}, // ( 54, 87) + { 0, { 0, 0, 0}}, // ( 55, 87) + { 0, { 0, 0, 0}}, // ( 56, 87) + { 0, { 0, 0, 0}}, // ( 57, 87) + { 0, { 0, 0, 0}}, // ( 58, 87) + { 0, { 0, 0, 0}}, // ( 59, 87) + { 0, { 0, 0, 0}}, // ( 60, 87) + { 0, { 0, 0, 0}}, // ( 61, 87) + { 0, { 0, 0, 0}}, // ( 62, 87) + { 0, { 0, 0, 0}}, // ( 63, 87) + { 0, { 0, 0, 0}}, // ( 64, 87) + { 0, { 0, 0, 0}}, // ( 65, 87) + { 0, { 0, 0, 0}}, // ( 66, 87) + { 0, { 0, 0, 0}}, // ( 67, 87) + { 0, { 0, 0, 0}}, // ( 68, 87) + { 0, { 0, 0, 0}}, // ( 69, 87) + { 0, { 0, 0, 0}}, // ( 70, 87) + { 0, { 0, 0, 0}}, // ( 71, 87) + { 0, { 0, 0, 0}}, // ( 72, 87) + { 0, { 0, 0, 0}}, // ( 73, 87) + { 0, { 0, 0, 0}}, // ( 74, 87) + { 0, { 0, 0, 0}}, // ( 75, 87) + { 0, { 0, 0, 0}}, // ( 76, 87) + { 0, { 0, 0, 0}}, // ( 77, 87) + { 0, { 0, 0, 0}}, // ( 78, 87) + { 0, { 0, 0, 0}}, // ( 79, 87) + { 0, { 0, 0, 0}}, // ( 80, 87) + { 0, { 0, 0, 0}}, // ( 81, 87) + { 0, { 0, 0, 0}}, // ( 82, 87) + { 0, { 0, 0, 0}}, // ( 83, 87) + { 0, { 0, 0, 0}}, // ( 84, 87) + { 0, { 0, 0, 0}}, // ( 85, 87) + { 0, { 0, 0, 0}}, // ( 86, 87) + { 0, { 0, 0, 0}}, // ( 87, 87) + { 0, { 0, 0, 0}}, // ( 88, 87) + { 0, { 0, 0, 0}}, // ( 89, 87) + { 0, { 0, 0, 0}}, // ( 90, 87) + { 0, { 0, 0, 0}}, // ( 91, 87) + { 0, { 0, 0, 0}}, // ( 92, 87) + { 0, { 0, 0, 0}}, // ( 93, 87) + { 0, { 0, 0, 0}}, // ( 94, 87) + { 0, { 0, 0, 0}}, // ( 95, 87) + { 0, { 0, 0, 0}}, // ( 96, 87) + { 0, { 0, 0, 0}}, // ( 97, 87) + { 0, { 0, 0, 0}}, // ( 98, 87) + { 0, { 0, 0, 0}}, // ( 99, 87) + { 0, { 0, 0, 0}}, // (100, 87) + { 0, { 0, 0, 0}}, // (101, 87) + { 0, { 0, 0, 0}}, // (102, 87) + { 0, { 0, 0, 0}}, // (103, 87) + { 0, { 0, 0, 0}}, // (104, 87) + { 0, { 0, 0, 0}}, // (105, 87) + { 0, { 0, 0, 0}}, // (106, 87) + { 0, { 0, 0, 0}}, // (107, 87) + { 0, { 0, 0, 0}}, // (108, 87) + { 0, { 0, 0, 0}}, // (109, 87) + { 0, { 0, 0, 0}}, // (110, 87) + { 0, { 0, 0, 0}}, // (111, 87) + { 0, { 0, 0, 0}}, // (112, 87) + { 0, { 0, 0, 0}}, // (113, 87) + { 0, { 0, 0, 0}}, // (114, 87) + { 0, { 0, 0, 0}}, // (115, 87) + { 0, { 0, 0, 0}}, // (116, 87) + { 0, { 0, 0, 0}}, // (117, 87) + { 0, { 0, 0, 0}}, // (118, 87) + { 0, { 0, 0, 0}}, // (119, 87) + { 0, { 0, 0, 0}}, // (120, 87) + { 0, { 0, 0, 0}}, // (121, 87) + { 0, { 0, 0, 0}}, // (122, 87) + { 0, { 0, 0, 0}}, // (123, 87) + { 0, { 0, 0, 0}}, // (124, 87) + { 0, { 0, 0, 0}}, // (125, 87) + { 0, { 0, 0, 0}}, // (126, 87) + { 0, { 0, 0, 0}}, // (127, 87) + { 0, { 0, 0, 0}}, // (128, 87) + { 0, { 0, 0, 0}}, // (129, 87) + { 0, { 0, 0, 0}}, // (130, 87) + { 0, { 0, 0, 0}}, // (131, 87) + { 0, { 0, 0, 0}}, // (132, 87) + { 0, { 0, 0, 0}}, // (133, 87) + { 0, { 0, 0, 0}}, // (134, 87) + { 0, { 0, 0, 0}}, // (135, 87) + { 0, { 0, 0, 0}}, // (136, 87) + { 0, { 0, 0, 0}}, // (137, 87) + { 0, { 0, 0, 0}}, // (138, 87) + { 0, { 0, 0, 0}}, // (139, 87) + { 0, { 0, 0, 0}}, // (140, 87) + { 0, { 0, 0, 0}}, // (141, 87) + { 0, { 0, 0, 0}}, // (142, 87) + { 0, { 0, 0, 0}}, // (143, 87) + { 0, { 0, 0, 0}}, // (144, 87) + { 0, { 0, 0, 0}}, // (145, 87) + { 0, { 0, 0, 0}}, // (146, 87) + { 0, { 0, 0, 0}}, // (147, 87) + { 0, { 0, 0, 0}}, // (148, 87) + { 0, { 0, 0, 0}}, // (149, 87) + { 0, { 0, 0, 0}}, // (150, 87) + { 0, { 0, 0, 0}}, // (151, 87) + { 0, { 0, 0, 0}}, // (152, 87) + { 0, { 0, 0, 0}}, // (153, 87) + { 0, { 0, 0, 0}}, // (154, 87) + { 0, { 0, 0, 0}}, // (155, 87) + { 0, { 0, 0, 0}}, // (156, 87) + { 0, { 0, 0, 0}}, // (157, 87) + { 0, { 0, 0, 0}}, // (158, 87) + { 0, { 0, 0, 0}}, // (159, 87) + { 0, { 0, 0, 0}}, // (160, 87) + { 0, { 0, 0, 0}}, // (161, 87) + { 0, { 0, 0, 0}}, // (162, 87) + { 0, { 0, 0, 0}}, // (163, 87) + { 0, { 0, 0, 0}}, // (164, 87) + { 0, { 0, 0, 0}}, // (165, 87) + { 0, { 0, 0, 0}}, // (166, 87) + { 0, { 0, 0, 0}}, // (167, 87) + { 0, { 0, 0, 0}}, // (168, 87) + { 0, { 0, 0, 0}}, // (169, 87) + { 0, { 0, 0, 0}}, // (170, 87) + { 0, { 0, 0, 0}}, // (171, 87) + { 0, { 0, 0, 0}}, // (172, 87) + { 0, { 0, 0, 0}}, // (173, 87) + { 0, { 0, 0, 0}}, // (174, 87) + { 0, { 0, 0, 0}}, // (175, 87) + { 0, { 0, 0, 0}}, // (176, 87) + { 8, { 0, 0, 0}}, // (177, 87) + {128, { 0, 0, 0}}, // (178, 87) + {128, { 0, 0, 0}}, // (179, 87) + {128, { 0, 0, 0}}, // ( 0, 88) + {128, { 0, 0, 0}}, // ( 1, 88) + { 7, { 0, 0, 0}}, // ( 2, 88) + { 0, { 0, 0, 0}}, // ( 3, 88) + { 0, { 0, 0, 0}}, // ( 4, 88) + { 0, { 0, 0, 0}}, // ( 5, 88) + { 0, { 0, 0, 0}}, // ( 6, 88) + { 0, { 0, 0, 0}}, // ( 7, 88) + { 0, { 0, 0, 0}}, // ( 8, 88) + { 0, { 0, 0, 0}}, // ( 9, 88) + { 0, { 0, 0, 0}}, // ( 10, 88) + { 0, { 0, 0, 0}}, // ( 11, 88) + { 0, { 0, 0, 0}}, // ( 12, 88) + { 0, { 0, 0, 0}}, // ( 13, 88) + { 0, { 0, 0, 0}}, // ( 14, 88) + { 0, { 0, 0, 0}}, // ( 15, 88) + { 0, { 0, 0, 0}}, // ( 16, 88) + { 0, { 0, 0, 0}}, // ( 17, 88) + { 0, { 0, 0, 0}}, // ( 18, 88) + { 0, { 0, 0, 0}}, // ( 19, 88) + { 0, { 0, 0, 0}}, // ( 20, 88) + { 0, { 0, 0, 0}}, // ( 21, 88) + { 0, { 0, 0, 0}}, // ( 22, 88) + { 0, { 0, 0, 0}}, // ( 23, 88) + { 0, { 0, 0, 0}}, // ( 24, 88) + { 0, { 0, 0, 0}}, // ( 25, 88) + { 0, { 0, 0, 0}}, // ( 26, 88) + { 0, { 0, 0, 0}}, // ( 27, 88) + { 0, { 0, 0, 0}}, // ( 28, 88) + { 0, { 0, 0, 0}}, // ( 29, 88) + { 0, { 0, 0, 0}}, // ( 30, 88) + { 0, { 0, 0, 0}}, // ( 31, 88) + { 0, { 0, 0, 0}}, // ( 32, 88) + { 0, { 0, 0, 0}}, // ( 33, 88) + { 0, { 0, 0, 0}}, // ( 34, 88) + { 0, { 0, 0, 0}}, // ( 35, 88) + { 0, { 0, 0, 0}}, // ( 36, 88) + { 0, { 0, 0, 0}}, // ( 37, 88) + { 0, { 0, 0, 0}}, // ( 38, 88) + { 0, { 0, 0, 0}}, // ( 39, 88) + { 0, { 0, 0, 0}}, // ( 40, 88) + { 0, { 0, 0, 0}}, // ( 41, 88) + { 0, { 0, 0, 0}}, // ( 42, 88) + { 0, { 0, 0, 0}}, // ( 43, 88) + { 0, { 0, 0, 0}}, // ( 44, 88) + { 0, { 0, 0, 0}}, // ( 45, 88) + { 0, { 0, 0, 0}}, // ( 46, 88) + { 0, { 0, 0, 0}}, // ( 47, 88) + { 0, { 0, 0, 0}}, // ( 48, 88) + { 0, { 0, 0, 0}}, // ( 49, 88) + { 0, { 0, 0, 0}}, // ( 50, 88) + { 0, { 0, 0, 0}}, // ( 51, 88) + { 0, { 0, 0, 0}}, // ( 52, 88) + { 0, { 0, 0, 0}}, // ( 53, 88) + { 0, { 0, 0, 0}}, // ( 54, 88) + { 0, { 0, 0, 0}}, // ( 55, 88) + { 0, { 0, 0, 0}}, // ( 56, 88) + { 0, { 0, 0, 0}}, // ( 57, 88) + { 0, { 0, 0, 0}}, // ( 58, 88) + { 0, { 0, 0, 0}}, // ( 59, 88) + { 0, { 0, 0, 0}}, // ( 60, 88) + { 0, { 0, 0, 0}}, // ( 61, 88) + { 0, { 0, 0, 0}}, // ( 62, 88) + { 0, { 0, 0, 0}}, // ( 63, 88) + { 0, { 0, 0, 0}}, // ( 64, 88) + { 0, { 0, 0, 0}}, // ( 65, 88) + { 0, { 0, 0, 0}}, // ( 66, 88) + { 0, { 0, 0, 0}}, // ( 67, 88) + { 0, { 0, 0, 0}}, // ( 68, 88) + { 0, { 0, 0, 0}}, // ( 69, 88) + { 0, { 0, 0, 0}}, // ( 70, 88) + { 0, { 0, 0, 0}}, // ( 71, 88) + { 0, { 0, 0, 0}}, // ( 72, 88) + { 0, { 0, 0, 0}}, // ( 73, 88) + { 0, { 0, 0, 0}}, // ( 74, 88) + { 0, { 0, 0, 0}}, // ( 75, 88) + { 0, { 0, 0, 0}}, // ( 76, 88) + { 0, { 0, 0, 0}}, // ( 77, 88) + { 0, { 0, 0, 0}}, // ( 78, 88) + { 0, { 0, 0, 0}}, // ( 79, 88) + { 0, { 0, 0, 0}}, // ( 80, 88) + { 0, { 0, 0, 0}}, // ( 81, 88) + { 0, { 0, 0, 0}}, // ( 82, 88) + { 0, { 0, 0, 0}}, // ( 83, 88) + { 0, { 0, 0, 0}}, // ( 84, 88) + { 0, { 0, 0, 0}}, // ( 85, 88) + { 0, { 0, 0, 0}}, // ( 86, 88) + { 0, { 0, 0, 0}}, // ( 87, 88) + { 0, { 0, 0, 0}}, // ( 88, 88) + { 0, { 0, 0, 0}}, // ( 89, 88) + { 0, { 0, 0, 0}}, // ( 90, 88) + { 0, { 0, 0, 0}}, // ( 91, 88) + { 0, { 0, 0, 0}}, // ( 92, 88) + { 0, { 0, 0, 0}}, // ( 93, 88) + { 0, { 0, 0, 0}}, // ( 94, 88) + { 0, { 0, 0, 0}}, // ( 95, 88) + { 0, { 0, 0, 0}}, // ( 96, 88) + { 0, { 0, 0, 0}}, // ( 97, 88) + { 0, { 0, 0, 0}}, // ( 98, 88) + { 0, { 0, 0, 0}}, // ( 99, 88) + { 0, { 0, 0, 0}}, // (100, 88) + { 0, { 0, 0, 0}}, // (101, 88) + { 0, { 0, 0, 0}}, // (102, 88) + { 0, { 0, 0, 0}}, // (103, 88) + { 0, { 0, 0, 0}}, // (104, 88) + { 0, { 0, 0, 0}}, // (105, 88) + { 0, { 0, 0, 0}}, // (106, 88) + { 0, { 0, 0, 0}}, // (107, 88) + { 0, { 0, 0, 0}}, // (108, 88) + { 0, { 0, 0, 0}}, // (109, 88) + { 0, { 0, 0, 0}}, // (110, 88) + { 0, { 0, 0, 0}}, // (111, 88) + { 0, { 0, 0, 0}}, // (112, 88) + { 0, { 0, 0, 0}}, // (113, 88) + { 0, { 0, 0, 0}}, // (114, 88) + { 0, { 0, 0, 0}}, // (115, 88) + { 0, { 0, 0, 0}}, // (116, 88) + { 0, { 0, 0, 0}}, // (117, 88) + { 0, { 0, 0, 0}}, // (118, 88) + { 0, { 0, 0, 0}}, // (119, 88) + { 0, { 0, 0, 0}}, // (120, 88) + { 0, { 0, 0, 0}}, // (121, 88) + { 0, { 0, 0, 0}}, // (122, 88) + { 0, { 0, 0, 0}}, // (123, 88) + { 0, { 0, 0, 0}}, // (124, 88) + { 0, { 0, 0, 0}}, // (125, 88) + { 0, { 0, 0, 0}}, // (126, 88) + { 0, { 0, 0, 0}}, // (127, 88) + { 0, { 0, 0, 0}}, // (128, 88) + { 0, { 0, 0, 0}}, // (129, 88) + { 0, { 0, 0, 0}}, // (130, 88) + { 0, { 0, 0, 0}}, // (131, 88) + { 0, { 0, 0, 0}}, // (132, 88) + { 0, { 0, 0, 0}}, // (133, 88) + { 0, { 0, 0, 0}}, // (134, 88) + { 0, { 0, 0, 0}}, // (135, 88) + { 0, { 0, 0, 0}}, // (136, 88) + { 0, { 0, 0, 0}}, // (137, 88) + { 0, { 0, 0, 0}}, // (138, 88) + { 0, { 0, 0, 0}}, // (139, 88) + { 0, { 0, 0, 0}}, // (140, 88) + { 0, { 0, 0, 0}}, // (141, 88) + { 0, { 0, 0, 0}}, // (142, 88) + { 0, { 0, 0, 0}}, // (143, 88) + { 0, { 0, 0, 0}}, // (144, 88) + { 0, { 0, 0, 0}}, // (145, 88) + { 0, { 0, 0, 0}}, // (146, 88) + { 0, { 0, 0, 0}}, // (147, 88) + { 0, { 0, 0, 0}}, // (148, 88) + { 0, { 0, 0, 0}}, // (149, 88) + { 0, { 0, 0, 0}}, // (150, 88) + { 0, { 0, 0, 0}}, // (151, 88) + { 0, { 0, 0, 0}}, // (152, 88) + { 0, { 0, 0, 0}}, // (153, 88) + { 0, { 0, 0, 0}}, // (154, 88) + { 0, { 0, 0, 0}}, // (155, 88) + { 0, { 0, 0, 0}}, // (156, 88) + { 0, { 0, 0, 0}}, // (157, 88) + { 0, { 0, 0, 0}}, // (158, 88) + { 0, { 0, 0, 0}}, // (159, 88) + { 0, { 0, 0, 0}}, // (160, 88) + { 0, { 0, 0, 0}}, // (161, 88) + { 0, { 0, 0, 0}}, // (162, 88) + { 0, { 0, 0, 0}}, // (163, 88) + { 0, { 0, 0, 0}}, // (164, 88) + { 0, { 0, 0, 0}}, // (165, 88) + { 0, { 0, 0, 0}}, // (166, 88) + { 0, { 0, 0, 0}}, // (167, 88) + { 0, { 0, 0, 0}}, // (168, 88) + { 0, { 0, 0, 0}}, // (169, 88) + { 0, { 0, 0, 0}}, // (170, 88) + { 0, { 0, 0, 0}}, // (171, 88) + { 0, { 0, 0, 0}}, // (172, 88) + { 0, { 0, 0, 0}}, // (173, 88) + { 0, { 0, 0, 0}}, // (174, 88) + { 0, { 0, 0, 0}}, // (175, 88) + { 0, { 0, 0, 0}}, // (176, 88) + { 6, { 0, 0, 0}}, // (177, 88) + {128, { 0, 0, 0}}, // (178, 88) + {128, { 0, 0, 0}}, // (179, 88) + {128, { 0, 0, 0}}, // ( 0, 89) + {128, { 0, 0, 0}}, // ( 1, 89) + { 0, { 0, 0, 0}}, // ( 2, 89) + { 0, { 0, 0, 0}}, // ( 3, 89) + { 0, { 0, 0, 0}}, // ( 4, 89) + { 0, { 0, 0, 0}}, // ( 5, 89) + { 0, { 0, 0, 0}}, // ( 6, 89) + { 0, { 0, 0, 0}}, // ( 7, 89) + { 0, { 0, 0, 0}}, // ( 8, 89) + { 0, { 0, 0, 0}}, // ( 9, 89) + { 0, { 0, 0, 0}}, // ( 10, 89) + { 0, { 0, 0, 0}}, // ( 11, 89) + { 0, { 0, 0, 0}}, // ( 12, 89) + { 0, { 0, 0, 0}}, // ( 13, 89) + { 0, { 0, 0, 0}}, // ( 14, 89) + { 0, { 0, 0, 0}}, // ( 15, 89) + { 0, { 0, 0, 0}}, // ( 16, 89) + { 0, { 0, 0, 0}}, // ( 17, 89) + { 0, { 0, 0, 0}}, // ( 18, 89) + { 0, { 0, 0, 0}}, // ( 19, 89) + { 0, { 0, 0, 0}}, // ( 20, 89) + { 0, { 0, 0, 0}}, // ( 21, 89) + { 0, { 0, 0, 0}}, // ( 22, 89) + { 0, { 0, 0, 0}}, // ( 23, 89) + { 0, { 0, 0, 0}}, // ( 24, 89) + { 0, { 0, 0, 0}}, // ( 25, 89) + { 0, { 0, 0, 0}}, // ( 26, 89) + { 0, { 0, 0, 0}}, // ( 27, 89) + { 0, { 0, 0, 0}}, // ( 28, 89) + { 0, { 0, 0, 0}}, // ( 29, 89) + { 0, { 0, 0, 0}}, // ( 30, 89) + { 0, { 0, 0, 0}}, // ( 31, 89) + { 0, { 0, 0, 0}}, // ( 32, 89) + { 0, { 0, 0, 0}}, // ( 33, 89) + { 0, { 0, 0, 0}}, // ( 34, 89) + { 0, { 0, 0, 0}}, // ( 35, 89) + { 0, { 0, 0, 0}}, // ( 36, 89) + { 0, { 0, 0, 0}}, // ( 37, 89) + { 0, { 0, 0, 0}}, // ( 38, 89) + { 0, { 0, 0, 0}}, // ( 39, 89) + { 0, { 0, 0, 0}}, // ( 40, 89) + { 0, { 0, 0, 0}}, // ( 41, 89) + { 0, { 0, 0, 0}}, // ( 42, 89) + { 0, { 0, 0, 0}}, // ( 43, 89) + { 0, { 0, 0, 0}}, // ( 44, 89) + { 0, { 0, 0, 0}}, // ( 45, 89) + { 0, { 0, 0, 0}}, // ( 46, 89) + { 0, { 0, 0, 0}}, // ( 47, 89) + { 0, { 0, 0, 0}}, // ( 48, 89) + { 0, { 0, 0, 0}}, // ( 49, 89) + { 0, { 0, 0, 0}}, // ( 50, 89) + { 0, { 0, 0, 0}}, // ( 51, 89) + { 0, { 0, 0, 0}}, // ( 52, 89) + { 0, { 0, 0, 0}}, // ( 53, 89) + { 0, { 0, 0, 0}}, // ( 54, 89) + { 0, { 0, 0, 0}}, // ( 55, 89) + { 0, { 0, 0, 0}}, // ( 56, 89) + { 0, { 0, 0, 0}}, // ( 57, 89) + { 0, { 0, 0, 0}}, // ( 58, 89) + { 0, { 0, 0, 0}}, // ( 59, 89) + { 0, { 0, 0, 0}}, // ( 60, 89) + { 0, { 0, 0, 0}}, // ( 61, 89) + { 0, { 0, 0, 0}}, // ( 62, 89) + { 0, { 0, 0, 0}}, // ( 63, 89) + { 0, { 0, 0, 0}}, // ( 64, 89) + { 0, { 0, 0, 0}}, // ( 65, 89) + { 0, { 0, 0, 0}}, // ( 66, 89) + { 0, { 0, 0, 0}}, // ( 67, 89) + { 0, { 0, 0, 0}}, // ( 68, 89) + { 0, { 0, 0, 0}}, // ( 69, 89) + { 0, { 0, 0, 0}}, // ( 70, 89) + { 0, { 0, 0, 0}}, // ( 71, 89) + { 0, { 0, 0, 0}}, // ( 72, 89) + { 0, { 0, 0, 0}}, // ( 73, 89) + { 0, { 0, 0, 0}}, // ( 74, 89) + { 0, { 0, 0, 0}}, // ( 75, 89) + { 0, { 0, 0, 0}}, // ( 76, 89) + { 0, { 0, 0, 0}}, // ( 77, 89) + { 0, { 0, 0, 0}}, // ( 78, 89) + { 0, { 0, 0, 0}}, // ( 79, 89) + { 0, { 0, 0, 0}}, // ( 80, 89) + { 0, { 0, 0, 0}}, // ( 81, 89) + { 0, { 0, 0, 0}}, // ( 82, 89) + { 0, { 0, 0, 0}}, // ( 83, 89) + { 0, { 0, 0, 0}}, // ( 84, 89) + { 0, { 0, 0, 0}}, // ( 85, 89) + { 0, { 0, 0, 0}}, // ( 86, 89) + { 0, { 0, 0, 0}}, // ( 87, 89) + { 0, { 0, 0, 0}}, // ( 88, 89) + { 0, { 0, 0, 0}}, // ( 89, 89) + { 0, { 0, 0, 0}}, // ( 90, 89) + { 0, { 0, 0, 0}}, // ( 91, 89) + { 0, { 0, 0, 0}}, // ( 92, 89) + { 0, { 0, 0, 0}}, // ( 93, 89) + { 0, { 0, 0, 0}}, // ( 94, 89) + { 0, { 0, 0, 0}}, // ( 95, 89) + { 0, { 0, 0, 0}}, // ( 96, 89) + { 0, { 0, 0, 0}}, // ( 97, 89) + { 0, { 0, 0, 0}}, // ( 98, 89) + { 0, { 0, 0, 0}}, // ( 99, 89) + { 0, { 0, 0, 0}}, // (100, 89) + { 0, { 0, 0, 0}}, // (101, 89) + { 0, { 0, 0, 0}}, // (102, 89) + { 0, { 0, 0, 0}}, // (103, 89) + { 0, { 0, 0, 0}}, // (104, 89) + { 0, { 0, 0, 0}}, // (105, 89) + { 0, { 0, 0, 0}}, // (106, 89) + { 0, { 0, 0, 0}}, // (107, 89) + { 0, { 0, 0, 0}}, // (108, 89) + { 0, { 0, 0, 0}}, // (109, 89) + { 0, { 0, 0, 0}}, // (110, 89) + { 0, { 0, 0, 0}}, // (111, 89) + { 0, { 0, 0, 0}}, // (112, 89) + { 0, { 0, 0, 0}}, // (113, 89) + { 0, { 0, 0, 0}}, // (114, 89) + { 0, { 0, 0, 0}}, // (115, 89) + { 0, { 0, 0, 0}}, // (116, 89) + { 0, { 0, 0, 0}}, // (117, 89) + { 0, { 0, 0, 0}}, // (118, 89) + { 0, { 0, 0, 0}}, // (119, 89) + { 0, { 0, 0, 0}}, // (120, 89) + { 0, { 0, 0, 0}}, // (121, 89) + { 0, { 0, 0, 0}}, // (122, 89) + { 0, { 0, 0, 0}}, // (123, 89) + { 0, { 0, 0, 0}}, // (124, 89) + { 0, { 0, 0, 0}}, // (125, 89) + { 0, { 0, 0, 0}}, // (126, 89) + { 0, { 0, 0, 0}}, // (127, 89) + { 0, { 0, 0, 0}}, // (128, 89) + { 0, { 0, 0, 0}}, // (129, 89) + { 0, { 0, 0, 0}}, // (130, 89) + { 0, { 0, 0, 0}}, // (131, 89) + { 0, { 0, 0, 0}}, // (132, 89) + { 0, { 0, 0, 0}}, // (133, 89) + { 0, { 0, 0, 0}}, // (134, 89) + { 0, { 0, 0, 0}}, // (135, 89) + { 0, { 0, 0, 0}}, // (136, 89) + { 0, { 0, 0, 0}}, // (137, 89) + { 0, { 0, 0, 0}}, // (138, 89) + { 0, { 0, 0, 0}}, // (139, 89) + { 0, { 0, 0, 0}}, // (140, 89) + { 0, { 0, 0, 0}}, // (141, 89) + { 0, { 0, 0, 0}}, // (142, 89) + { 0, { 0, 0, 0}}, // (143, 89) + { 0, { 0, 0, 0}}, // (144, 89) + { 0, { 0, 0, 0}}, // (145, 89) + { 0, { 0, 0, 0}}, // (146, 89) + { 0, { 0, 0, 0}}, // (147, 89) + { 0, { 0, 0, 0}}, // (148, 89) + { 0, { 0, 0, 0}}, // (149, 89) + { 0, { 0, 0, 0}}, // (150, 89) + { 0, { 0, 0, 0}}, // (151, 89) + { 0, { 0, 0, 0}}, // (152, 89) + { 0, { 0, 0, 0}}, // (153, 89) + { 0, { 0, 0, 0}}, // (154, 89) + { 0, { 0, 0, 0}}, // (155, 89) + { 0, { 0, 0, 0}}, // (156, 89) + { 0, { 0, 0, 0}}, // (157, 89) + { 0, { 0, 0, 0}}, // (158, 89) + { 0, { 0, 0, 0}}, // (159, 89) + { 0, { 0, 0, 0}}, // (160, 89) + { 0, { 0, 0, 0}}, // (161, 89) + { 0, { 0, 0, 0}}, // (162, 89) + { 0, { 0, 0, 0}}, // (163, 89) + { 0, { 0, 0, 0}}, // (164, 89) + { 0, { 0, 0, 0}}, // (165, 89) + { 0, { 0, 0, 0}}, // (166, 89) + { 0, { 0, 0, 0}}, // (167, 89) + { 0, { 0, 0, 0}}, // (168, 89) + { 0, { 0, 0, 0}}, // (169, 89) + { 0, { 0, 0, 0}}, // (170, 89) + { 0, { 0, 0, 0}}, // (171, 89) + { 0, { 0, 0, 0}}, // (172, 89) + { 0, { 0, 0, 0}}, // (173, 89) + { 0, { 0, 0, 0}}, // (174, 89) + { 0, { 0, 0, 0}}, // (175, 89) + { 0, { 0, 0, 0}}, // (176, 89) + { 0, { 0, 0, 0}}, // (177, 89) + {128, { 0, 0, 0}}, // (178, 89) + {128, { 0, 0, 0}}, // (179, 89) + {128, { 0, 0, 0}}, // ( 0, 90) + {128, { 0, 0, 0}}, // ( 1, 90) + { 0, { 0, 0, 0}}, // ( 2, 90) + { 0, { 0, 0, 0}}, // ( 3, 90) + { 0, { 0, 0, 0}}, // ( 4, 90) + { 0, { 0, 0, 0}}, // ( 5, 90) + { 0, { 0, 0, 0}}, // ( 6, 90) + { 0, { 0, 0, 0}}, // ( 7, 90) + { 0, { 0, 0, 0}}, // ( 8, 90) + { 0, { 0, 0, 0}}, // ( 9, 90) + { 0, { 0, 0, 0}}, // ( 10, 90) + { 0, { 0, 0, 0}}, // ( 11, 90) + { 0, { 0, 0, 0}}, // ( 12, 90) + { 0, { 0, 0, 0}}, // ( 13, 90) + { 0, { 0, 0, 0}}, // ( 14, 90) + { 0, { 0, 0, 0}}, // ( 15, 90) + { 0, { 0, 0, 0}}, // ( 16, 90) + { 0, { 0, 0, 0}}, // ( 17, 90) + { 0, { 0, 0, 0}}, // ( 18, 90) + { 0, { 0, 0, 0}}, // ( 19, 90) + { 0, { 0, 0, 0}}, // ( 20, 90) + { 0, { 0, 0, 0}}, // ( 21, 90) + { 0, { 0, 0, 0}}, // ( 22, 90) + { 0, { 0, 0, 0}}, // ( 23, 90) + { 0, { 0, 0, 0}}, // ( 24, 90) + { 0, { 0, 0, 0}}, // ( 25, 90) + { 0, { 0, 0, 0}}, // ( 26, 90) + { 0, { 0, 0, 0}}, // ( 27, 90) + { 0, { 0, 0, 0}}, // ( 28, 90) + { 0, { 0, 0, 0}}, // ( 29, 90) + { 0, { 0, 0, 0}}, // ( 30, 90) + { 0, { 0, 0, 0}}, // ( 31, 90) + { 0, { 0, 0, 0}}, // ( 32, 90) + { 0, { 0, 0, 0}}, // ( 33, 90) + { 0, { 0, 0, 0}}, // ( 34, 90) + { 0, { 0, 0, 0}}, // ( 35, 90) + { 0, { 0, 0, 0}}, // ( 36, 90) + { 0, { 0, 0, 0}}, // ( 37, 90) + { 0, { 0, 0, 0}}, // ( 38, 90) + { 0, { 0, 0, 0}}, // ( 39, 90) + { 0, { 0, 0, 0}}, // ( 40, 90) + { 0, { 0, 0, 0}}, // ( 41, 90) + { 0, { 0, 0, 0}}, // ( 42, 90) + { 0, { 0, 0, 0}}, // ( 43, 90) + { 0, { 0, 0, 0}}, // ( 44, 90) + { 0, { 0, 0, 0}}, // ( 45, 90) + { 0, { 0, 0, 0}}, // ( 46, 90) + { 0, { 0, 0, 0}}, // ( 47, 90) + { 0, { 0, 0, 0}}, // ( 48, 90) + { 0, { 0, 0, 0}}, // ( 49, 90) + { 0, { 0, 0, 0}}, // ( 50, 90) + { 0, { 0, 0, 0}}, // ( 51, 90) + { 0, { 0, 0, 0}}, // ( 52, 90) + { 0, { 0, 0, 0}}, // ( 53, 90) + { 0, { 0, 0, 0}}, // ( 54, 90) + { 0, { 0, 0, 0}}, // ( 55, 90) + { 0, { 0, 0, 0}}, // ( 56, 90) + { 0, { 0, 0, 0}}, // ( 57, 90) + { 0, { 0, 0, 0}}, // ( 58, 90) + { 0, { 0, 0, 0}}, // ( 59, 90) + { 0, { 0, 0, 0}}, // ( 60, 90) + { 0, { 0, 0, 0}}, // ( 61, 90) + { 0, { 0, 0, 0}}, // ( 62, 90) + { 0, { 0, 0, 0}}, // ( 63, 90) + { 0, { 0, 0, 0}}, // ( 64, 90) + { 0, { 0, 0, 0}}, // ( 65, 90) + { 0, { 0, 0, 0}}, // ( 66, 90) + { 0, { 0, 0, 0}}, // ( 67, 90) + { 0, { 0, 0, 0}}, // ( 68, 90) + { 0, { 0, 0, 0}}, // ( 69, 90) + { 0, { 0, 0, 0}}, // ( 70, 90) + { 0, { 0, 0, 0}}, // ( 71, 90) + { 0, { 0, 0, 0}}, // ( 72, 90) + { 0, { 0, 0, 0}}, // ( 73, 90) + { 0, { 0, 0, 0}}, // ( 74, 90) + { 0, { 0, 0, 0}}, // ( 75, 90) + { 0, { 0, 0, 0}}, // ( 76, 90) + { 0, { 0, 0, 0}}, // ( 77, 90) + { 0, { 0, 0, 0}}, // ( 78, 90) + { 0, { 0, 0, 0}}, // ( 79, 90) + { 0, { 0, 0, 0}}, // ( 80, 90) + { 0, { 0, 0, 0}}, // ( 81, 90) + { 0, { 0, 0, 0}}, // ( 82, 90) + { 0, { 0, 0, 0}}, // ( 83, 90) + { 0, { 0, 0, 0}}, // ( 84, 90) + { 0, { 0, 0, 0}}, // ( 85, 90) + { 0, { 0, 0, 0}}, // ( 86, 90) + { 0, { 0, 0, 0}}, // ( 87, 90) + { 0, { 0, 0, 0}}, // ( 88, 90) + { 0, { 0, 0, 0}}, // ( 89, 90) + { 0, { 0, 0, 0}}, // ( 90, 90) + { 0, { 0, 0, 0}}, // ( 91, 90) + { 0, { 0, 0, 0}}, // ( 92, 90) + { 0, { 0, 0, 0}}, // ( 93, 90) + { 0, { 0, 0, 0}}, // ( 94, 90) + { 0, { 0, 0, 0}}, // ( 95, 90) + { 0, { 0, 0, 0}}, // ( 96, 90) + { 0, { 0, 0, 0}}, // ( 97, 90) + { 0, { 0, 0, 0}}, // ( 98, 90) + { 0, { 0, 0, 0}}, // ( 99, 90) + { 0, { 0, 0, 0}}, // (100, 90) + { 0, { 0, 0, 0}}, // (101, 90) + { 0, { 0, 0, 0}}, // (102, 90) + { 0, { 0, 0, 0}}, // (103, 90) + { 0, { 0, 0, 0}}, // (104, 90) + { 0, { 0, 0, 0}}, // (105, 90) + { 0, { 0, 0, 0}}, // (106, 90) + { 0, { 0, 0, 0}}, // (107, 90) + { 0, { 0, 0, 0}}, // (108, 90) + { 0, { 0, 0, 0}}, // (109, 90) + { 0, { 0, 0, 0}}, // (110, 90) + { 0, { 0, 0, 0}}, // (111, 90) + { 0, { 0, 0, 0}}, // (112, 90) + { 0, { 0, 0, 0}}, // (113, 90) + { 0, { 0, 0, 0}}, // (114, 90) + { 0, { 0, 0, 0}}, // (115, 90) + { 0, { 0, 0, 0}}, // (116, 90) + { 0, { 0, 0, 0}}, // (117, 90) + { 0, { 0, 0, 0}}, // (118, 90) + { 0, { 0, 0, 0}}, // (119, 90) + { 0, { 0, 0, 0}}, // (120, 90) + { 0, { 0, 0, 0}}, // (121, 90) + { 0, { 0, 0, 0}}, // (122, 90) + { 0, { 0, 0, 0}}, // (123, 90) + { 0, { 0, 0, 0}}, // (124, 90) + { 0, { 0, 0, 0}}, // (125, 90) + { 0, { 0, 0, 0}}, // (126, 90) + { 0, { 0, 0, 0}}, // (127, 90) + { 0, { 0, 0, 0}}, // (128, 90) + { 0, { 0, 0, 0}}, // (129, 90) + { 0, { 0, 0, 0}}, // (130, 90) + { 0, { 0, 0, 0}}, // (131, 90) + { 0, { 0, 0, 0}}, // (132, 90) + { 0, { 0, 0, 0}}, // (133, 90) + { 0, { 0, 0, 0}}, // (134, 90) + { 0, { 0, 0, 0}}, // (135, 90) + { 0, { 0, 0, 0}}, // (136, 90) + { 0, { 0, 0, 0}}, // (137, 90) + { 0, { 0, 0, 0}}, // (138, 90) + { 0, { 0, 0, 0}}, // (139, 90) + { 0, { 0, 0, 0}}, // (140, 90) + { 0, { 0, 0, 0}}, // (141, 90) + { 0, { 0, 0, 0}}, // (142, 90) + { 0, { 0, 0, 0}}, // (143, 90) + { 0, { 0, 0, 0}}, // (144, 90) + { 0, { 0, 0, 0}}, // (145, 90) + { 0, { 0, 0, 0}}, // (146, 90) + { 0, { 0, 0, 0}}, // (147, 90) + { 0, { 0, 0, 0}}, // (148, 90) + { 0, { 0, 0, 0}}, // (149, 90) + { 0, { 0, 0, 0}}, // (150, 90) + { 0, { 0, 0, 0}}, // (151, 90) + { 0, { 0, 0, 0}}, // (152, 90) + { 0, { 0, 0, 0}}, // (153, 90) + { 0, { 0, 0, 0}}, // (154, 90) + { 0, { 0, 0, 0}}, // (155, 90) + { 0, { 0, 0, 0}}, // (156, 90) + { 0, { 0, 0, 0}}, // (157, 90) + { 0, { 0, 0, 0}}, // (158, 90) + { 0, { 0, 0, 0}}, // (159, 90) + { 0, { 0, 0, 0}}, // (160, 90) + { 0, { 0, 0, 0}}, // (161, 90) + { 0, { 0, 0, 0}}, // (162, 90) + { 0, { 0, 0, 0}}, // (163, 90) + { 0, { 0, 0, 0}}, // (164, 90) + { 0, { 0, 0, 0}}, // (165, 90) + { 0, { 0, 0, 0}}, // (166, 90) + { 0, { 0, 0, 0}}, // (167, 90) + { 0, { 0, 0, 0}}, // (168, 90) + { 0, { 0, 0, 0}}, // (169, 90) + { 0, { 0, 0, 0}}, // (170, 90) + { 0, { 0, 0, 0}}, // (171, 90) + { 0, { 0, 0, 0}}, // (172, 90) + { 0, { 0, 0, 0}}, // (173, 90) + { 0, { 0, 0, 0}}, // (174, 90) + { 0, { 0, 0, 0}}, // (175, 90) + { 0, { 0, 0, 0}}, // (176, 90) + { 0, { 0, 0, 0}}, // (177, 90) + {128, { 0, 0, 0}}, // (178, 90) + {128, { 0, 0, 0}}, // (179, 90) + {128, { 0, 0, 0}}, // ( 0, 91) + {128, { 0, 0, 0}}, // ( 1, 91) + { 7, { 0, 0, 0}}, // ( 2, 91) + { 0, { 0, 0, 0}}, // ( 3, 91) + { 0, { 0, 0, 0}}, // ( 4, 91) + { 0, { 0, 0, 0}}, // ( 5, 91) + { 0, { 0, 0, 0}}, // ( 6, 91) + { 0, { 0, 0, 0}}, // ( 7, 91) + { 0, { 0, 0, 0}}, // ( 8, 91) + { 0, { 0, 0, 0}}, // ( 9, 91) + { 0, { 0, 0, 0}}, // ( 10, 91) + { 0, { 0, 0, 0}}, // ( 11, 91) + { 0, { 0, 0, 0}}, // ( 12, 91) + { 0, { 0, 0, 0}}, // ( 13, 91) + { 0, { 0, 0, 0}}, // ( 14, 91) + { 0, { 0, 0, 0}}, // ( 15, 91) + { 0, { 0, 0, 0}}, // ( 16, 91) + { 0, { 0, 0, 0}}, // ( 17, 91) + { 0, { 0, 0, 0}}, // ( 18, 91) + { 0, { 0, 0, 0}}, // ( 19, 91) + { 0, { 0, 0, 0}}, // ( 20, 91) + { 0, { 0, 0, 0}}, // ( 21, 91) + { 0, { 0, 0, 0}}, // ( 22, 91) + { 0, { 0, 0, 0}}, // ( 23, 91) + { 0, { 0, 0, 0}}, // ( 24, 91) + { 0, { 0, 0, 0}}, // ( 25, 91) + { 0, { 0, 0, 0}}, // ( 26, 91) + { 0, { 0, 0, 0}}, // ( 27, 91) + { 0, { 0, 0, 0}}, // ( 28, 91) + { 0, { 0, 0, 0}}, // ( 29, 91) + { 0, { 0, 0, 0}}, // ( 30, 91) + { 0, { 0, 0, 0}}, // ( 31, 91) + { 0, { 0, 0, 0}}, // ( 32, 91) + { 0, { 0, 0, 0}}, // ( 33, 91) + { 0, { 0, 0, 0}}, // ( 34, 91) + { 0, { 0, 0, 0}}, // ( 35, 91) + { 0, { 0, 0, 0}}, // ( 36, 91) + { 0, { 0, 0, 0}}, // ( 37, 91) + { 0, { 0, 0, 0}}, // ( 38, 91) + { 0, { 0, 0, 0}}, // ( 39, 91) + { 0, { 0, 0, 0}}, // ( 40, 91) + { 0, { 0, 0, 0}}, // ( 41, 91) + { 0, { 0, 0, 0}}, // ( 42, 91) + { 0, { 0, 0, 0}}, // ( 43, 91) + { 0, { 0, 0, 0}}, // ( 44, 91) + { 0, { 0, 0, 0}}, // ( 45, 91) + { 0, { 0, 0, 0}}, // ( 46, 91) + { 0, { 0, 0, 0}}, // ( 47, 91) + { 0, { 0, 0, 0}}, // ( 48, 91) + { 0, { 0, 0, 0}}, // ( 49, 91) + { 0, { 0, 0, 0}}, // ( 50, 91) + { 0, { 0, 0, 0}}, // ( 51, 91) + { 0, { 0, 0, 0}}, // ( 52, 91) + { 0, { 0, 0, 0}}, // ( 53, 91) + { 0, { 0, 0, 0}}, // ( 54, 91) + { 0, { 0, 0, 0}}, // ( 55, 91) + { 0, { 0, 0, 0}}, // ( 56, 91) + { 0, { 0, 0, 0}}, // ( 57, 91) + { 0, { 0, 0, 0}}, // ( 58, 91) + { 0, { 0, 0, 0}}, // ( 59, 91) + { 0, { 0, 0, 0}}, // ( 60, 91) + { 0, { 0, 0, 0}}, // ( 61, 91) + { 0, { 0, 0, 0}}, // ( 62, 91) + { 0, { 0, 0, 0}}, // ( 63, 91) + { 0, { 0, 0, 0}}, // ( 64, 91) + { 0, { 0, 0, 0}}, // ( 65, 91) + { 0, { 0, 0, 0}}, // ( 66, 91) + { 0, { 0, 0, 0}}, // ( 67, 91) + { 0, { 0, 0, 0}}, // ( 68, 91) + { 0, { 0, 0, 0}}, // ( 69, 91) + { 0, { 0, 0, 0}}, // ( 70, 91) + { 0, { 0, 0, 0}}, // ( 71, 91) + { 0, { 0, 0, 0}}, // ( 72, 91) + { 0, { 0, 0, 0}}, // ( 73, 91) + { 0, { 0, 0, 0}}, // ( 74, 91) + { 0, { 0, 0, 0}}, // ( 75, 91) + { 0, { 0, 0, 0}}, // ( 76, 91) + { 0, { 0, 0, 0}}, // ( 77, 91) + { 0, { 0, 0, 0}}, // ( 78, 91) + { 0, { 0, 0, 0}}, // ( 79, 91) + { 0, { 0, 0, 0}}, // ( 80, 91) + { 0, { 0, 0, 0}}, // ( 81, 91) + { 0, { 0, 0, 0}}, // ( 82, 91) + { 0, { 0, 0, 0}}, // ( 83, 91) + { 0, { 0, 0, 0}}, // ( 84, 91) + { 0, { 0, 0, 0}}, // ( 85, 91) + { 0, { 0, 0, 0}}, // ( 86, 91) + { 0, { 0, 0, 0}}, // ( 87, 91) + { 0, { 0, 0, 0}}, // ( 88, 91) + { 0, { 0, 0, 0}}, // ( 89, 91) + { 0, { 0, 0, 0}}, // ( 90, 91) + { 0, { 0, 0, 0}}, // ( 91, 91) + { 0, { 0, 0, 0}}, // ( 92, 91) + { 0, { 0, 0, 0}}, // ( 93, 91) + { 0, { 0, 0, 0}}, // ( 94, 91) + { 0, { 0, 0, 0}}, // ( 95, 91) + { 0, { 0, 0, 0}}, // ( 96, 91) + { 0, { 0, 0, 0}}, // ( 97, 91) + { 0, { 0, 0, 0}}, // ( 98, 91) + { 0, { 0, 0, 0}}, // ( 99, 91) + { 0, { 0, 0, 0}}, // (100, 91) + { 0, { 0, 0, 0}}, // (101, 91) + { 0, { 0, 0, 0}}, // (102, 91) + { 0, { 0, 0, 0}}, // (103, 91) + { 0, { 0, 0, 0}}, // (104, 91) + { 0, { 0, 0, 0}}, // (105, 91) + { 0, { 0, 0, 0}}, // (106, 91) + { 0, { 0, 0, 0}}, // (107, 91) + { 0, { 0, 0, 0}}, // (108, 91) + { 0, { 0, 0, 0}}, // (109, 91) + { 0, { 0, 0, 0}}, // (110, 91) + { 0, { 0, 0, 0}}, // (111, 91) + { 0, { 0, 0, 0}}, // (112, 91) + { 0, { 0, 0, 0}}, // (113, 91) + { 0, { 0, 0, 0}}, // (114, 91) + { 0, { 0, 0, 0}}, // (115, 91) + { 0, { 0, 0, 0}}, // (116, 91) + { 0, { 0, 0, 0}}, // (117, 91) + { 0, { 0, 0, 0}}, // (118, 91) + { 0, { 0, 0, 0}}, // (119, 91) + { 0, { 0, 0, 0}}, // (120, 91) + { 0, { 0, 0, 0}}, // (121, 91) + { 0, { 0, 0, 0}}, // (122, 91) + { 0, { 0, 0, 0}}, // (123, 91) + { 0, { 0, 0, 0}}, // (124, 91) + { 0, { 0, 0, 0}}, // (125, 91) + { 0, { 0, 0, 0}}, // (126, 91) + { 0, { 0, 0, 0}}, // (127, 91) + { 0, { 0, 0, 0}}, // (128, 91) + { 0, { 0, 0, 0}}, // (129, 91) + { 0, { 0, 0, 0}}, // (130, 91) + { 0, { 0, 0, 0}}, // (131, 91) + { 0, { 0, 0, 0}}, // (132, 91) + { 0, { 0, 0, 0}}, // (133, 91) + { 0, { 0, 0, 0}}, // (134, 91) + { 0, { 0, 0, 0}}, // (135, 91) + { 0, { 0, 0, 0}}, // (136, 91) + { 0, { 0, 0, 0}}, // (137, 91) + { 0, { 0, 0, 0}}, // (138, 91) + { 0, { 0, 0, 0}}, // (139, 91) + { 0, { 0, 0, 0}}, // (140, 91) + { 0, { 0, 0, 0}}, // (141, 91) + { 0, { 0, 0, 0}}, // (142, 91) + { 0, { 0, 0, 0}}, // (143, 91) + { 0, { 0, 0, 0}}, // (144, 91) + { 0, { 0, 0, 0}}, // (145, 91) + { 0, { 0, 0, 0}}, // (146, 91) + { 0, { 0, 0, 0}}, // (147, 91) + { 0, { 0, 0, 0}}, // (148, 91) + { 0, { 0, 0, 0}}, // (149, 91) + { 0, { 0, 0, 0}}, // (150, 91) + { 0, { 0, 0, 0}}, // (151, 91) + { 0, { 0, 0, 0}}, // (152, 91) + { 0, { 0, 0, 0}}, // (153, 91) + { 0, { 0, 0, 0}}, // (154, 91) + { 0, { 0, 0, 0}}, // (155, 91) + { 0, { 0, 0, 0}}, // (156, 91) + { 0, { 0, 0, 0}}, // (157, 91) + { 0, { 0, 0, 0}}, // (158, 91) + { 0, { 0, 0, 0}}, // (159, 91) + { 0, { 0, 0, 0}}, // (160, 91) + { 0, { 0, 0, 0}}, // (161, 91) + { 0, { 0, 0, 0}}, // (162, 91) + { 0, { 0, 0, 0}}, // (163, 91) + { 0, { 0, 0, 0}}, // (164, 91) + { 0, { 0, 0, 0}}, // (165, 91) + { 0, { 0, 0, 0}}, // (166, 91) + { 0, { 0, 0, 0}}, // (167, 91) + { 0, { 0, 0, 0}}, // (168, 91) + { 0, { 0, 0, 0}}, // (169, 91) + { 0, { 0, 0, 0}}, // (170, 91) + { 0, { 0, 0, 0}}, // (171, 91) + { 0, { 0, 0, 0}}, // (172, 91) + { 0, { 0, 0, 0}}, // (173, 91) + { 0, { 0, 0, 0}}, // (174, 91) + { 0, { 0, 0, 0}}, // (175, 91) + { 0, { 0, 0, 0}}, // (176, 91) + { 6, { 0, 0, 0}}, // (177, 91) + {128, { 0, 0, 0}}, // (178, 91) + {128, { 0, 0, 0}}, // (179, 91) + {128, { 0, 0, 0}}, // ( 0, 92) + {128, { 0, 0, 0}}, // ( 1, 92) + { 8, { 0, 0, 0}}, // ( 2, 92) + { 0, { 0, 0, 0}}, // ( 3, 92) + { 0, { 0, 0, 0}}, // ( 4, 92) + { 0, { 0, 0, 0}}, // ( 5, 92) + { 0, { 0, 0, 0}}, // ( 6, 92) + { 0, { 0, 0, 0}}, // ( 7, 92) + { 0, { 0, 0, 0}}, // ( 8, 92) + { 0, { 0, 0, 0}}, // ( 9, 92) + { 0, { 0, 0, 0}}, // ( 10, 92) + { 0, { 0, 0, 0}}, // ( 11, 92) + { 0, { 0, 0, 0}}, // ( 12, 92) + { 0, { 0, 0, 0}}, // ( 13, 92) + { 0, { 0, 0, 0}}, // ( 14, 92) + { 0, { 0, 0, 0}}, // ( 15, 92) + { 0, { 0, 0, 0}}, // ( 16, 92) + { 0, { 0, 0, 0}}, // ( 17, 92) + { 0, { 0, 0, 0}}, // ( 18, 92) + { 0, { 0, 0, 0}}, // ( 19, 92) + { 0, { 0, 0, 0}}, // ( 20, 92) + { 0, { 0, 0, 0}}, // ( 21, 92) + { 0, { 0, 0, 0}}, // ( 22, 92) + { 0, { 0, 0, 0}}, // ( 23, 92) + { 0, { 0, 0, 0}}, // ( 24, 92) + { 0, { 0, 0, 0}}, // ( 25, 92) + { 0, { 0, 0, 0}}, // ( 26, 92) + { 0, { 0, 0, 0}}, // ( 27, 92) + { 0, { 0, 0, 0}}, // ( 28, 92) + { 0, { 0, 0, 0}}, // ( 29, 92) + { 0, { 0, 0, 0}}, // ( 30, 92) + { 0, { 0, 0, 0}}, // ( 31, 92) + { 0, { 0, 0, 0}}, // ( 32, 92) + { 0, { 0, 0, 0}}, // ( 33, 92) + { 0, { 0, 0, 0}}, // ( 34, 92) + { 0, { 0, 0, 0}}, // ( 35, 92) + { 0, { 0, 0, 0}}, // ( 36, 92) + { 0, { 0, 0, 0}}, // ( 37, 92) + { 0, { 0, 0, 0}}, // ( 38, 92) + { 0, { 0, 0, 0}}, // ( 39, 92) + { 0, { 0, 0, 0}}, // ( 40, 92) + { 0, { 0, 0, 0}}, // ( 41, 92) + { 0, { 0, 0, 0}}, // ( 42, 92) + { 0, { 0, 0, 0}}, // ( 43, 92) + { 0, { 0, 0, 0}}, // ( 44, 92) + { 0, { 0, 0, 0}}, // ( 45, 92) + { 0, { 0, 0, 0}}, // ( 46, 92) + { 0, { 0, 0, 0}}, // ( 47, 92) + { 0, { 0, 0, 0}}, // ( 48, 92) + { 0, { 0, 0, 0}}, // ( 49, 92) + { 0, { 0, 0, 0}}, // ( 50, 92) + { 0, { 0, 0, 0}}, // ( 51, 92) + { 0, { 0, 0, 0}}, // ( 52, 92) + { 0, { 0, 0, 0}}, // ( 53, 92) + { 0, { 0, 0, 0}}, // ( 54, 92) + { 0, { 0, 0, 0}}, // ( 55, 92) + { 0, { 0, 0, 0}}, // ( 56, 92) + { 0, { 0, 0, 0}}, // ( 57, 92) + { 0, { 0, 0, 0}}, // ( 58, 92) + { 0, { 0, 0, 0}}, // ( 59, 92) + { 0, { 0, 0, 0}}, // ( 60, 92) + { 0, { 0, 0, 0}}, // ( 61, 92) + { 0, { 0, 0, 0}}, // ( 62, 92) + { 0, { 0, 0, 0}}, // ( 63, 92) + { 0, { 0, 0, 0}}, // ( 64, 92) + { 0, { 0, 0, 0}}, // ( 65, 92) + { 0, { 0, 0, 0}}, // ( 66, 92) + { 0, { 0, 0, 0}}, // ( 67, 92) + { 0, { 0, 0, 0}}, // ( 68, 92) + { 0, { 0, 0, 0}}, // ( 69, 92) + { 0, { 0, 0, 0}}, // ( 70, 92) + { 0, { 0, 0, 0}}, // ( 71, 92) + { 0, { 0, 0, 0}}, // ( 72, 92) + { 0, { 0, 0, 0}}, // ( 73, 92) + { 0, { 0, 0, 0}}, // ( 74, 92) + { 0, { 0, 0, 0}}, // ( 75, 92) + { 0, { 0, 0, 0}}, // ( 76, 92) + { 0, { 0, 0, 0}}, // ( 77, 92) + { 0, { 0, 0, 0}}, // ( 78, 92) + { 0, { 0, 0, 0}}, // ( 79, 92) + { 0, { 0, 0, 0}}, // ( 80, 92) + { 0, { 0, 0, 0}}, // ( 81, 92) + { 0, { 0, 0, 0}}, // ( 82, 92) + { 0, { 0, 0, 0}}, // ( 83, 92) + { 0, { 0, 0, 0}}, // ( 84, 92) + { 0, { 0, 0, 0}}, // ( 85, 92) + { 0, { 0, 0, 0}}, // ( 86, 92) + { 0, { 0, 0, 0}}, // ( 87, 92) + { 0, { 0, 0, 0}}, // ( 88, 92) + { 0, { 0, 0, 0}}, // ( 89, 92) + { 0, { 0, 0, 0}}, // ( 90, 92) + { 0, { 0, 0, 0}}, // ( 91, 92) + { 0, { 0, 0, 0}}, // ( 92, 92) + { 0, { 0, 0, 0}}, // ( 93, 92) + { 0, { 0, 0, 0}}, // ( 94, 92) + { 0, { 0, 0, 0}}, // ( 95, 92) + { 0, { 0, 0, 0}}, // ( 96, 92) + { 0, { 0, 0, 0}}, // ( 97, 92) + { 0, { 0, 0, 0}}, // ( 98, 92) + { 0, { 0, 0, 0}}, // ( 99, 92) + { 0, { 0, 0, 0}}, // (100, 92) + { 0, { 0, 0, 0}}, // (101, 92) + { 0, { 0, 0, 0}}, // (102, 92) + { 0, { 0, 0, 0}}, // (103, 92) + { 0, { 0, 0, 0}}, // (104, 92) + { 0, { 0, 0, 0}}, // (105, 92) + { 0, { 0, 0, 0}}, // (106, 92) + { 0, { 0, 0, 0}}, // (107, 92) + { 0, { 0, 0, 0}}, // (108, 92) + { 0, { 0, 0, 0}}, // (109, 92) + { 0, { 0, 0, 0}}, // (110, 92) + { 0, { 0, 0, 0}}, // (111, 92) + { 0, { 0, 0, 0}}, // (112, 92) + { 0, { 0, 0, 0}}, // (113, 92) + { 0, { 0, 0, 0}}, // (114, 92) + { 0, { 0, 0, 0}}, // (115, 92) + { 0, { 0, 0, 0}}, // (116, 92) + { 0, { 0, 0, 0}}, // (117, 92) + { 0, { 0, 0, 0}}, // (118, 92) + { 0, { 0, 0, 0}}, // (119, 92) + { 0, { 0, 0, 0}}, // (120, 92) + { 0, { 0, 0, 0}}, // (121, 92) + { 0, { 0, 0, 0}}, // (122, 92) + { 0, { 0, 0, 0}}, // (123, 92) + { 0, { 0, 0, 0}}, // (124, 92) + { 0, { 0, 0, 0}}, // (125, 92) + { 0, { 0, 0, 0}}, // (126, 92) + { 0, { 0, 0, 0}}, // (127, 92) + { 0, { 0, 0, 0}}, // (128, 92) + { 0, { 0, 0, 0}}, // (129, 92) + { 0, { 0, 0, 0}}, // (130, 92) + { 0, { 0, 0, 0}}, // (131, 92) + { 0, { 0, 0, 0}}, // (132, 92) + { 0, { 0, 0, 0}}, // (133, 92) + { 0, { 0, 0, 0}}, // (134, 92) + { 0, { 0, 0, 0}}, // (135, 92) + { 0, { 0, 0, 0}}, // (136, 92) + { 0, { 0, 0, 0}}, // (137, 92) + { 0, { 0, 0, 0}}, // (138, 92) + { 0, { 0, 0, 0}}, // (139, 92) + { 0, { 0, 0, 0}}, // (140, 92) + { 0, { 0, 0, 0}}, // (141, 92) + { 0, { 0, 0, 0}}, // (142, 92) + { 0, { 0, 0, 0}}, // (143, 92) + { 0, { 0, 0, 0}}, // (144, 92) + { 0, { 0, 0, 0}}, // (145, 92) + { 0, { 0, 0, 0}}, // (146, 92) + { 0, { 0, 0, 0}}, // (147, 92) + { 0, { 0, 0, 0}}, // (148, 92) + { 0, { 0, 0, 0}}, // (149, 92) + { 0, { 0, 0, 0}}, // (150, 92) + { 0, { 0, 0, 0}}, // (151, 92) + { 0, { 0, 0, 0}}, // (152, 92) + { 0, { 0, 0, 0}}, // (153, 92) + { 0, { 0, 0, 0}}, // (154, 92) + { 0, { 0, 0, 0}}, // (155, 92) + { 0, { 0, 0, 0}}, // (156, 92) + { 0, { 0, 0, 0}}, // (157, 92) + { 0, { 0, 0, 0}}, // (158, 92) + { 0, { 0, 0, 0}}, // (159, 92) + { 0, { 0, 0, 0}}, // (160, 92) + { 0, { 0, 0, 0}}, // (161, 92) + { 0, { 0, 0, 0}}, // (162, 92) + { 0, { 0, 0, 0}}, // (163, 92) + { 0, { 0, 0, 0}}, // (164, 92) + { 0, { 0, 0, 0}}, // (165, 92) + { 0, { 0, 0, 0}}, // (166, 92) + { 0, { 0, 0, 0}}, // (167, 92) + { 0, { 0, 0, 0}}, // (168, 92) + { 0, { 0, 0, 0}}, // (169, 92) + { 0, { 0, 0, 0}}, // (170, 92) + { 0, { 0, 0, 0}}, // (171, 92) + { 0, { 0, 0, 0}}, // (172, 92) + { 0, { 0, 0, 0}}, // (173, 92) + { 0, { 0, 0, 0}}, // (174, 92) + { 0, { 0, 0, 0}}, // (175, 92) + { 0, { 0, 0, 0}}, // (176, 92) + { 8, { 0, 0, 0}}, // (177, 92) + {128, { 0, 0, 0}}, // (178, 92) + {128, { 0, 0, 0}}, // (179, 92) + {128, { 0, 0, 0}}, // ( 0, 93) + {128, { 0, 0, 0}}, // ( 1, 93) + { 12, { 0, 0, 0}}, // ( 2, 93) + { 0, { 0, 0, 0}}, // ( 3, 93) + { 0, { 0, 0, 0}}, // ( 4, 93) + { 0, { 0, 0, 0}}, // ( 5, 93) + { 0, { 0, 0, 0}}, // ( 6, 93) + { 0, { 0, 0, 0}}, // ( 7, 93) + { 0, { 0, 0, 0}}, // ( 8, 93) + { 0, { 0, 0, 0}}, // ( 9, 93) + { 0, { 0, 0, 0}}, // ( 10, 93) + { 0, { 0, 0, 0}}, // ( 11, 93) + { 0, { 0, 0, 0}}, // ( 12, 93) + { 0, { 0, 0, 0}}, // ( 13, 93) + { 0, { 0, 0, 0}}, // ( 14, 93) + { 0, { 0, 0, 0}}, // ( 15, 93) + { 0, { 0, 0, 0}}, // ( 16, 93) + { 0, { 0, 0, 0}}, // ( 17, 93) + { 0, { 0, 0, 0}}, // ( 18, 93) + { 0, { 0, 0, 0}}, // ( 19, 93) + { 0, { 0, 0, 0}}, // ( 20, 93) + { 0, { 0, 0, 0}}, // ( 21, 93) + { 0, { 0, 0, 0}}, // ( 22, 93) + { 0, { 0, 0, 0}}, // ( 23, 93) + { 0, { 0, 0, 0}}, // ( 24, 93) + { 0, { 0, 0, 0}}, // ( 25, 93) + { 0, { 0, 0, 0}}, // ( 26, 93) + { 0, { 0, 0, 0}}, // ( 27, 93) + { 0, { 0, 0, 0}}, // ( 28, 93) + { 0, { 0, 0, 0}}, // ( 29, 93) + { 0, { 0, 0, 0}}, // ( 30, 93) + { 0, { 0, 0, 0}}, // ( 31, 93) + { 0, { 0, 0, 0}}, // ( 32, 93) + { 0, { 0, 0, 0}}, // ( 33, 93) + { 0, { 0, 0, 0}}, // ( 34, 93) + { 0, { 0, 0, 0}}, // ( 35, 93) + { 0, { 0, 0, 0}}, // ( 36, 93) + { 0, { 0, 0, 0}}, // ( 37, 93) + { 0, { 0, 0, 0}}, // ( 38, 93) + { 0, { 0, 0, 0}}, // ( 39, 93) + { 0, { 0, 0, 0}}, // ( 40, 93) + { 0, { 0, 0, 0}}, // ( 41, 93) + { 0, { 0, 0, 0}}, // ( 42, 93) + { 0, { 0, 0, 0}}, // ( 43, 93) + { 0, { 0, 0, 0}}, // ( 44, 93) + { 0, { 0, 0, 0}}, // ( 45, 93) + { 0, { 0, 0, 0}}, // ( 46, 93) + { 0, { 0, 0, 0}}, // ( 47, 93) + { 0, { 0, 0, 0}}, // ( 48, 93) + { 0, { 0, 0, 0}}, // ( 49, 93) + { 0, { 0, 0, 0}}, // ( 50, 93) + { 0, { 0, 0, 0}}, // ( 51, 93) + { 0, { 0, 0, 0}}, // ( 52, 93) + { 0, { 0, 0, 0}}, // ( 53, 93) + { 0, { 0, 0, 0}}, // ( 54, 93) + { 0, { 0, 0, 0}}, // ( 55, 93) + { 0, { 0, 0, 0}}, // ( 56, 93) + { 0, { 0, 0, 0}}, // ( 57, 93) + { 0, { 0, 0, 0}}, // ( 58, 93) + { 0, { 0, 0, 0}}, // ( 59, 93) + { 0, { 0, 0, 0}}, // ( 60, 93) + { 0, { 0, 0, 0}}, // ( 61, 93) + { 0, { 0, 0, 0}}, // ( 62, 93) + { 0, { 0, 0, 0}}, // ( 63, 93) + { 0, { 0, 0, 0}}, // ( 64, 93) + { 0, { 0, 0, 0}}, // ( 65, 93) + { 0, { 0, 0, 0}}, // ( 66, 93) + { 0, { 0, 0, 0}}, // ( 67, 93) + { 0, { 0, 0, 0}}, // ( 68, 93) + { 0, { 0, 0, 0}}, // ( 69, 93) + { 0, { 0, 0, 0}}, // ( 70, 93) + { 0, { 0, 0, 0}}, // ( 71, 93) + { 0, { 0, 0, 0}}, // ( 72, 93) + { 0, { 0, 0, 0}}, // ( 73, 93) + { 0, { 0, 0, 0}}, // ( 74, 93) + { 0, { 0, 0, 0}}, // ( 75, 93) + { 0, { 0, 0, 0}}, // ( 76, 93) + { 0, { 0, 0, 0}}, // ( 77, 93) + { 0, { 0, 0, 0}}, // ( 78, 93) + { 0, { 0, 0, 0}}, // ( 79, 93) + { 0, { 0, 0, 0}}, // ( 80, 93) + { 0, { 0, 0, 0}}, // ( 81, 93) + { 0, { 0, 0, 0}}, // ( 82, 93) + { 0, { 0, 0, 0}}, // ( 83, 93) + { 0, { 0, 0, 0}}, // ( 84, 93) + { 0, { 0, 0, 0}}, // ( 85, 93) + { 0, { 0, 0, 0}}, // ( 86, 93) + { 0, { 0, 0, 0}}, // ( 87, 93) + { 0, { 0, 0, 0}}, // ( 88, 93) + { 0, { 0, 0, 0}}, // ( 89, 93) + { 0, { 0, 0, 0}}, // ( 90, 93) + { 0, { 0, 0, 0}}, // ( 91, 93) + { 0, { 0, 0, 0}}, // ( 92, 93) + { 0, { 0, 0, 0}}, // ( 93, 93) + { 0, { 0, 0, 0}}, // ( 94, 93) + { 0, { 0, 0, 0}}, // ( 95, 93) + { 0, { 0, 0, 0}}, // ( 96, 93) + { 0, { 0, 0, 0}}, // ( 97, 93) + { 0, { 0, 0, 0}}, // ( 98, 93) + { 0, { 0, 0, 0}}, // ( 99, 93) + { 0, { 0, 0, 0}}, // (100, 93) + { 0, { 0, 0, 0}}, // (101, 93) + { 0, { 0, 0, 0}}, // (102, 93) + { 0, { 0, 0, 0}}, // (103, 93) + { 0, { 0, 0, 0}}, // (104, 93) + { 0, { 0, 0, 0}}, // (105, 93) + { 0, { 0, 0, 0}}, // (106, 93) + { 0, { 0, 0, 0}}, // (107, 93) + { 0, { 0, 0, 0}}, // (108, 93) + { 0, { 0, 0, 0}}, // (109, 93) + { 0, { 0, 0, 0}}, // (110, 93) + { 0, { 0, 0, 0}}, // (111, 93) + { 0, { 0, 0, 0}}, // (112, 93) + { 0, { 0, 0, 0}}, // (113, 93) + { 0, { 0, 0, 0}}, // (114, 93) + { 0, { 0, 0, 0}}, // (115, 93) + { 0, { 0, 0, 0}}, // (116, 93) + { 0, { 0, 0, 0}}, // (117, 93) + { 0, { 0, 0, 0}}, // (118, 93) + { 0, { 0, 0, 0}}, // (119, 93) + { 0, { 0, 0, 0}}, // (120, 93) + { 0, { 0, 0, 0}}, // (121, 93) + { 0, { 0, 0, 0}}, // (122, 93) + { 0, { 0, 0, 0}}, // (123, 93) + { 0, { 0, 0, 0}}, // (124, 93) + { 0, { 0, 0, 0}}, // (125, 93) + { 0, { 0, 0, 0}}, // (126, 93) + { 0, { 0, 0, 0}}, // (127, 93) + { 0, { 0, 0, 0}}, // (128, 93) + { 0, { 0, 0, 0}}, // (129, 93) + { 0, { 0, 0, 0}}, // (130, 93) + { 0, { 0, 0, 0}}, // (131, 93) + { 0, { 0, 0, 0}}, // (132, 93) + { 0, { 0, 0, 0}}, // (133, 93) + { 0, { 0, 0, 0}}, // (134, 93) + { 0, { 0, 0, 0}}, // (135, 93) + { 0, { 0, 0, 0}}, // (136, 93) + { 0, { 0, 0, 0}}, // (137, 93) + { 0, { 0, 0, 0}}, // (138, 93) + { 0, { 0, 0, 0}}, // (139, 93) + { 0, { 0, 0, 0}}, // (140, 93) + { 0, { 0, 0, 0}}, // (141, 93) + { 0, { 0, 0, 0}}, // (142, 93) + { 0, { 0, 0, 0}}, // (143, 93) + { 0, { 0, 0, 0}}, // (144, 93) + { 0, { 0, 0, 0}}, // (145, 93) + { 0, { 0, 0, 0}}, // (146, 93) + { 0, { 0, 0, 0}}, // (147, 93) + { 0, { 0, 0, 0}}, // (148, 93) + { 0, { 0, 0, 0}}, // (149, 93) + { 0, { 0, 0, 0}}, // (150, 93) + { 0, { 0, 0, 0}}, // (151, 93) + { 0, { 0, 0, 0}}, // (152, 93) + { 0, { 0, 0, 0}}, // (153, 93) + { 0, { 0, 0, 0}}, // (154, 93) + { 0, { 0, 0, 0}}, // (155, 93) + { 0, { 0, 0, 0}}, // (156, 93) + { 0, { 0, 0, 0}}, // (157, 93) + { 0, { 0, 0, 0}}, // (158, 93) + { 0, { 0, 0, 0}}, // (159, 93) + { 0, { 0, 0, 0}}, // (160, 93) + { 0, { 0, 0, 0}}, // (161, 93) + { 0, { 0, 0, 0}}, // (162, 93) + { 0, { 0, 0, 0}}, // (163, 93) + { 0, { 0, 0, 0}}, // (164, 93) + { 0, { 0, 0, 0}}, // (165, 93) + { 0, { 0, 0, 0}}, // (166, 93) + { 0, { 0, 0, 0}}, // (167, 93) + { 0, { 0, 0, 0}}, // (168, 93) + { 0, { 0, 0, 0}}, // (169, 93) + { 0, { 0, 0, 0}}, // (170, 93) + { 0, { 0, 0, 0}}, // (171, 93) + { 0, { 0, 0, 0}}, // (172, 93) + { 0, { 0, 0, 0}}, // (173, 93) + { 0, { 0, 0, 0}}, // (174, 93) + { 0, { 0, 0, 0}}, // (175, 93) + { 0, { 0, 0, 0}}, // (176, 93) + { 11, { 0, 0, 0}}, // (177, 93) + {128, { 0, 0, 0}}, // (178, 93) + {128, { 0, 0, 0}}, // (179, 93) + {128, { 0, 0, 0}}, // ( 0, 94) + {128, { 0, 0, 0}}, // ( 1, 94) + { 16, { 0, 0, 0}}, // ( 2, 94) + { 0, { 0, 0, 0}}, // ( 3, 94) + { 0, { 0, 0, 0}}, // ( 4, 94) + { 0, { 0, 0, 0}}, // ( 5, 94) + { 0, { 0, 0, 0}}, // ( 6, 94) + { 0, { 0, 0, 0}}, // ( 7, 94) + { 0, { 0, 0, 0}}, // ( 8, 94) + { 0, { 0, 0, 0}}, // ( 9, 94) + { 0, { 0, 0, 0}}, // ( 10, 94) + { 0, { 0, 0, 0}}, // ( 11, 94) + { 0, { 0, 0, 0}}, // ( 12, 94) + { 0, { 0, 0, 0}}, // ( 13, 94) + { 0, { 0, 0, 0}}, // ( 14, 94) + { 0, { 0, 0, 0}}, // ( 15, 94) + { 0, { 0, 0, 0}}, // ( 16, 94) + { 0, { 0, 0, 0}}, // ( 17, 94) + { 0, { 0, 0, 0}}, // ( 18, 94) + { 0, { 0, 0, 0}}, // ( 19, 94) + { 0, { 0, 0, 0}}, // ( 20, 94) + { 0, { 0, 0, 0}}, // ( 21, 94) + { 0, { 0, 0, 0}}, // ( 22, 94) + { 0, { 0, 0, 0}}, // ( 23, 94) + { 0, { 0, 0, 0}}, // ( 24, 94) + { 0, { 0, 0, 0}}, // ( 25, 94) + { 0, { 0, 0, 0}}, // ( 26, 94) + { 0, { 0, 0, 0}}, // ( 27, 94) + { 0, { 0, 0, 0}}, // ( 28, 94) + { 0, { 0, 0, 0}}, // ( 29, 94) + { 0, { 0, 0, 0}}, // ( 30, 94) + { 0, { 0, 0, 0}}, // ( 31, 94) + { 0, { 0, 0, 0}}, // ( 32, 94) + { 0, { 0, 0, 0}}, // ( 33, 94) + { 0, { 0, 0, 0}}, // ( 34, 94) + { 0, { 0, 0, 0}}, // ( 35, 94) + { 0, { 0, 0, 0}}, // ( 36, 94) + { 0, { 0, 0, 0}}, // ( 37, 94) + { 0, { 0, 0, 0}}, // ( 38, 94) + { 0, { 0, 0, 0}}, // ( 39, 94) + { 0, { 0, 0, 0}}, // ( 40, 94) + { 0, { 0, 0, 0}}, // ( 41, 94) + { 0, { 0, 0, 0}}, // ( 42, 94) + { 0, { 0, 0, 0}}, // ( 43, 94) + { 0, { 0, 0, 0}}, // ( 44, 94) + { 0, { 0, 0, 0}}, // ( 45, 94) + { 0, { 0, 0, 0}}, // ( 46, 94) + { 0, { 0, 0, 0}}, // ( 47, 94) + { 0, { 0, 0, 0}}, // ( 48, 94) + { 0, { 0, 0, 0}}, // ( 49, 94) + { 0, { 0, 0, 0}}, // ( 50, 94) + { 0, { 0, 0, 0}}, // ( 51, 94) + { 0, { 0, 0, 0}}, // ( 52, 94) + { 0, { 0, 0, 0}}, // ( 53, 94) + { 0, { 0, 0, 0}}, // ( 54, 94) + { 0, { 0, 0, 0}}, // ( 55, 94) + { 0, { 0, 0, 0}}, // ( 56, 94) + { 0, { 0, 0, 0}}, // ( 57, 94) + { 0, { 0, 0, 0}}, // ( 58, 94) + { 0, { 0, 0, 0}}, // ( 59, 94) + { 0, { 0, 0, 0}}, // ( 60, 94) + { 0, { 0, 0, 0}}, // ( 61, 94) + { 0, { 0, 0, 0}}, // ( 62, 94) + { 0, { 0, 0, 0}}, // ( 63, 94) + { 0, { 0, 0, 0}}, // ( 64, 94) + { 0, { 0, 0, 0}}, // ( 65, 94) + { 0, { 0, 0, 0}}, // ( 66, 94) + { 0, { 0, 0, 0}}, // ( 67, 94) + { 0, { 0, 0, 0}}, // ( 68, 94) + { 0, { 0, 0, 0}}, // ( 69, 94) + { 0, { 0, 0, 0}}, // ( 70, 94) + { 0, { 0, 0, 0}}, // ( 71, 94) + { 0, { 0, 0, 0}}, // ( 72, 94) + { 0, { 0, 0, 0}}, // ( 73, 94) + { 0, { 0, 0, 0}}, // ( 74, 94) + { 0, { 0, 0, 0}}, // ( 75, 94) + { 0, { 0, 0, 0}}, // ( 76, 94) + { 0, { 0, 0, 0}}, // ( 77, 94) + { 0, { 0, 0, 0}}, // ( 78, 94) + { 0, { 0, 0, 0}}, // ( 79, 94) + { 0, { 0, 0, 0}}, // ( 80, 94) + { 0, { 0, 0, 0}}, // ( 81, 94) + { 0, { 0, 0, 0}}, // ( 82, 94) + { 0, { 0, 0, 0}}, // ( 83, 94) + { 0, { 0, 0, 0}}, // ( 84, 94) + { 0, { 0, 0, 0}}, // ( 85, 94) + { 0, { 0, 0, 0}}, // ( 86, 94) + { 0, { 0, 0, 0}}, // ( 87, 94) + { 0, { 0, 0, 0}}, // ( 88, 94) + { 0, { 0, 0, 0}}, // ( 89, 94) + { 0, { 0, 0, 0}}, // ( 90, 94) + { 0, { 0, 0, 0}}, // ( 91, 94) + { 0, { 0, 0, 0}}, // ( 92, 94) + { 0, { 0, 0, 0}}, // ( 93, 94) + { 0, { 0, 0, 0}}, // ( 94, 94) + { 0, { 0, 0, 0}}, // ( 95, 94) + { 0, { 0, 0, 0}}, // ( 96, 94) + { 0, { 0, 0, 0}}, // ( 97, 94) + { 0, { 0, 0, 0}}, // ( 98, 94) + { 0, { 0, 0, 0}}, // ( 99, 94) + { 0, { 0, 0, 0}}, // (100, 94) + { 0, { 0, 0, 0}}, // (101, 94) + { 0, { 0, 0, 0}}, // (102, 94) + { 0, { 0, 0, 0}}, // (103, 94) + { 0, { 0, 0, 0}}, // (104, 94) + { 0, { 0, 0, 0}}, // (105, 94) + { 0, { 0, 0, 0}}, // (106, 94) + { 0, { 0, 0, 0}}, // (107, 94) + { 0, { 0, 0, 0}}, // (108, 94) + { 0, { 0, 0, 0}}, // (109, 94) + { 0, { 0, 0, 0}}, // (110, 94) + { 0, { 0, 0, 0}}, // (111, 94) + { 0, { 0, 0, 0}}, // (112, 94) + { 0, { 0, 0, 0}}, // (113, 94) + { 0, { 0, 0, 0}}, // (114, 94) + { 0, { 0, 0, 0}}, // (115, 94) + { 0, { 0, 0, 0}}, // (116, 94) + { 0, { 0, 0, 0}}, // (117, 94) + { 0, { 0, 0, 0}}, // (118, 94) + { 0, { 0, 0, 0}}, // (119, 94) + { 0, { 0, 0, 0}}, // (120, 94) + { 0, { 0, 0, 0}}, // (121, 94) + { 0, { 0, 0, 0}}, // (122, 94) + { 0, { 0, 0, 0}}, // (123, 94) + { 0, { 0, 0, 0}}, // (124, 94) + { 0, { 0, 0, 0}}, // (125, 94) + { 0, { 0, 0, 0}}, // (126, 94) + { 0, { 0, 0, 0}}, // (127, 94) + { 0, { 0, 0, 0}}, // (128, 94) + { 0, { 0, 0, 0}}, // (129, 94) + { 0, { 0, 0, 0}}, // (130, 94) + { 0, { 0, 0, 0}}, // (131, 94) + { 0, { 0, 0, 0}}, // (132, 94) + { 0, { 0, 0, 0}}, // (133, 94) + { 0, { 0, 0, 0}}, // (134, 94) + { 0, { 0, 0, 0}}, // (135, 94) + { 0, { 0, 0, 0}}, // (136, 94) + { 0, { 0, 0, 0}}, // (137, 94) + { 0, { 0, 0, 0}}, // (138, 94) + { 0, { 0, 0, 0}}, // (139, 94) + { 0, { 0, 0, 0}}, // (140, 94) + { 0, { 0, 0, 0}}, // (141, 94) + { 0, { 0, 0, 0}}, // (142, 94) + { 0, { 0, 0, 0}}, // (143, 94) + { 0, { 0, 0, 0}}, // (144, 94) + { 0, { 0, 0, 0}}, // (145, 94) + { 0, { 0, 0, 0}}, // (146, 94) + { 0, { 0, 0, 0}}, // (147, 94) + { 0, { 0, 0, 0}}, // (148, 94) + { 0, { 0, 0, 0}}, // (149, 94) + { 0, { 0, 0, 0}}, // (150, 94) + { 0, { 0, 0, 0}}, // (151, 94) + { 0, { 0, 0, 0}}, // (152, 94) + { 0, { 0, 0, 0}}, // (153, 94) + { 0, { 0, 0, 0}}, // (154, 94) + { 0, { 0, 0, 0}}, // (155, 94) + { 0, { 0, 0, 0}}, // (156, 94) + { 0, { 0, 0, 0}}, // (157, 94) + { 0, { 0, 0, 0}}, // (158, 94) + { 0, { 0, 0, 0}}, // (159, 94) + { 0, { 0, 0, 0}}, // (160, 94) + { 0, { 0, 0, 0}}, // (161, 94) + { 0, { 0, 0, 0}}, // (162, 94) + { 0, { 0, 0, 0}}, // (163, 94) + { 0, { 0, 0, 0}}, // (164, 94) + { 0, { 0, 0, 0}}, // (165, 94) + { 0, { 0, 0, 0}}, // (166, 94) + { 0, { 0, 0, 0}}, // (167, 94) + { 0, { 0, 0, 0}}, // (168, 94) + { 0, { 0, 0, 0}}, // (169, 94) + { 0, { 0, 0, 0}}, // (170, 94) + { 0, { 0, 0, 0}}, // (171, 94) + { 0, { 0, 0, 0}}, // (172, 94) + { 0, { 0, 0, 0}}, // (173, 94) + { 0, { 0, 0, 0}}, // (174, 94) + { 0, { 0, 0, 0}}, // (175, 94) + { 0, { 0, 0, 0}}, // (176, 94) + { 15, { 0, 0, 0}}, // (177, 94) + {128, { 0, 0, 0}}, // (178, 94) + {128, { 0, 0, 0}}, // (179, 94) + {128, { 0, 0, 0}}, // ( 0, 95) + {128, { 0, 0, 0}}, // ( 1, 95) + { 25, { 0, 0, 0}}, // ( 2, 95) + { 0, { 0, 0, 0}}, // ( 3, 95) + { 0, { 0, 0, 0}}, // ( 4, 95) + { 0, { 0, 0, 0}}, // ( 5, 95) + { 0, { 0, 0, 0}}, // ( 6, 95) + { 0, { 0, 0, 0}}, // ( 7, 95) + { 0, { 0, 0, 0}}, // ( 8, 95) + { 0, { 0, 0, 0}}, // ( 9, 95) + { 0, { 0, 0, 0}}, // ( 10, 95) + { 0, { 0, 0, 0}}, // ( 11, 95) + { 0, { 0, 0, 0}}, // ( 12, 95) + { 0, { 0, 0, 0}}, // ( 13, 95) + { 0, { 0, 0, 0}}, // ( 14, 95) + { 0, { 0, 0, 0}}, // ( 15, 95) + { 0, { 0, 0, 0}}, // ( 16, 95) + { 0, { 0, 0, 0}}, // ( 17, 95) + { 0, { 0, 0, 0}}, // ( 18, 95) + { 0, { 0, 0, 0}}, // ( 19, 95) + { 0, { 0, 0, 0}}, // ( 20, 95) + { 0, { 0, 0, 0}}, // ( 21, 95) + { 0, { 0, 0, 0}}, // ( 22, 95) + { 0, { 0, 0, 0}}, // ( 23, 95) + { 0, { 0, 0, 0}}, // ( 24, 95) + { 0, { 0, 0, 0}}, // ( 25, 95) + { 0, { 0, 0, 0}}, // ( 26, 95) + { 0, { 0, 0, 0}}, // ( 27, 95) + { 0, { 0, 0, 0}}, // ( 28, 95) + { 0, { 0, 0, 0}}, // ( 29, 95) + { 0, { 0, 0, 0}}, // ( 30, 95) + { 0, { 0, 0, 0}}, // ( 31, 95) + { 0, { 0, 0, 0}}, // ( 32, 95) + { 0, { 0, 0, 0}}, // ( 33, 95) + { 0, { 0, 0, 0}}, // ( 34, 95) + { 0, { 0, 0, 0}}, // ( 35, 95) + { 0, { 0, 0, 0}}, // ( 36, 95) + { 0, { 0, 0, 0}}, // ( 37, 95) + { 0, { 0, 0, 0}}, // ( 38, 95) + { 0, { 0, 0, 0}}, // ( 39, 95) + { 0, { 0, 0, 0}}, // ( 40, 95) + { 0, { 0, 0, 0}}, // ( 41, 95) + { 0, { 0, 0, 0}}, // ( 42, 95) + { 0, { 0, 0, 0}}, // ( 43, 95) + { 0, { 0, 0, 0}}, // ( 44, 95) + { 0, { 0, 0, 0}}, // ( 45, 95) + { 0, { 0, 0, 0}}, // ( 46, 95) + { 0, { 0, 0, 0}}, // ( 47, 95) + { 0, { 0, 0, 0}}, // ( 48, 95) + { 0, { 0, 0, 0}}, // ( 49, 95) + { 0, { 0, 0, 0}}, // ( 50, 95) + { 0, { 0, 0, 0}}, // ( 51, 95) + { 0, { 0, 0, 0}}, // ( 52, 95) + { 0, { 0, 0, 0}}, // ( 53, 95) + { 0, { 0, 0, 0}}, // ( 54, 95) + { 0, { 0, 0, 0}}, // ( 55, 95) + { 0, { 0, 0, 0}}, // ( 56, 95) + { 0, { 0, 0, 0}}, // ( 57, 95) + { 0, { 0, 0, 0}}, // ( 58, 95) + { 0, { 0, 0, 0}}, // ( 59, 95) + { 0, { 0, 0, 0}}, // ( 60, 95) + { 0, { 0, 0, 0}}, // ( 61, 95) + { 0, { 0, 0, 0}}, // ( 62, 95) + { 0, { 0, 0, 0}}, // ( 63, 95) + { 0, { 0, 0, 0}}, // ( 64, 95) + { 0, { 0, 0, 0}}, // ( 65, 95) + { 0, { 0, 0, 0}}, // ( 66, 95) + { 0, { 0, 0, 0}}, // ( 67, 95) + { 0, { 0, 0, 0}}, // ( 68, 95) + { 0, { 0, 0, 0}}, // ( 69, 95) + { 0, { 0, 0, 0}}, // ( 70, 95) + { 0, { 0, 0, 0}}, // ( 71, 95) + { 0, { 0, 0, 0}}, // ( 72, 95) + { 0, { 0, 0, 0}}, // ( 73, 95) + { 0, { 0, 0, 0}}, // ( 74, 95) + { 0, { 0, 0, 0}}, // ( 75, 95) + { 0, { 0, 0, 0}}, // ( 76, 95) + { 0, { 0, 0, 0}}, // ( 77, 95) + { 0, { 0, 0, 0}}, // ( 78, 95) + { 0, { 0, 0, 0}}, // ( 79, 95) + { 0, { 0, 0, 0}}, // ( 80, 95) + { 0, { 0, 0, 0}}, // ( 81, 95) + { 0, { 0, 0, 0}}, // ( 82, 95) + { 0, { 0, 0, 0}}, // ( 83, 95) + { 0, { 0, 0, 0}}, // ( 84, 95) + { 0, { 0, 0, 0}}, // ( 85, 95) + { 0, { 0, 0, 0}}, // ( 86, 95) + { 0, { 0, 0, 0}}, // ( 87, 95) + { 0, { 0, 0, 0}}, // ( 88, 95) + { 0, { 0, 0, 0}}, // ( 89, 95) + { 0, { 0, 0, 0}}, // ( 90, 95) + { 0, { 0, 0, 0}}, // ( 91, 95) + { 0, { 0, 0, 0}}, // ( 92, 95) + { 0, { 0, 0, 0}}, // ( 93, 95) + { 0, { 0, 0, 0}}, // ( 94, 95) + { 0, { 0, 0, 0}}, // ( 95, 95) + { 0, { 0, 0, 0}}, // ( 96, 95) + { 0, { 0, 0, 0}}, // ( 97, 95) + { 0, { 0, 0, 0}}, // ( 98, 95) + { 0, { 0, 0, 0}}, // ( 99, 95) + { 0, { 0, 0, 0}}, // (100, 95) + { 0, { 0, 0, 0}}, // (101, 95) + { 0, { 0, 0, 0}}, // (102, 95) + { 0, { 0, 0, 0}}, // (103, 95) + { 0, { 0, 0, 0}}, // (104, 95) + { 0, { 0, 0, 0}}, // (105, 95) + { 0, { 0, 0, 0}}, // (106, 95) + { 0, { 0, 0, 0}}, // (107, 95) + { 0, { 0, 0, 0}}, // (108, 95) + { 0, { 0, 0, 0}}, // (109, 95) + { 0, { 0, 0, 0}}, // (110, 95) + { 0, { 0, 0, 0}}, // (111, 95) + { 0, { 0, 0, 0}}, // (112, 95) + { 0, { 0, 0, 0}}, // (113, 95) + { 0, { 0, 0, 0}}, // (114, 95) + { 0, { 0, 0, 0}}, // (115, 95) + { 0, { 0, 0, 0}}, // (116, 95) + { 0, { 0, 0, 0}}, // (117, 95) + { 0, { 0, 0, 0}}, // (118, 95) + { 0, { 0, 0, 0}}, // (119, 95) + { 0, { 0, 0, 0}}, // (120, 95) + { 0, { 0, 0, 0}}, // (121, 95) + { 0, { 0, 0, 0}}, // (122, 95) + { 0, { 0, 0, 0}}, // (123, 95) + { 0, { 0, 0, 0}}, // (124, 95) + { 0, { 0, 0, 0}}, // (125, 95) + { 0, { 0, 0, 0}}, // (126, 95) + { 0, { 0, 0, 0}}, // (127, 95) + { 0, { 0, 0, 0}}, // (128, 95) + { 0, { 0, 0, 0}}, // (129, 95) + { 0, { 0, 0, 0}}, // (130, 95) + { 0, { 0, 0, 0}}, // (131, 95) + { 0, { 0, 0, 0}}, // (132, 95) + { 0, { 0, 0, 0}}, // (133, 95) + { 0, { 0, 0, 0}}, // (134, 95) + { 0, { 0, 0, 0}}, // (135, 95) + { 0, { 0, 0, 0}}, // (136, 95) + { 0, { 0, 0, 0}}, // (137, 95) + { 0, { 0, 0, 0}}, // (138, 95) + { 0, { 0, 0, 0}}, // (139, 95) + { 0, { 0, 0, 0}}, // (140, 95) + { 0, { 0, 0, 0}}, // (141, 95) + { 0, { 0, 0, 0}}, // (142, 95) + { 0, { 0, 0, 0}}, // (143, 95) + { 0, { 0, 0, 0}}, // (144, 95) + { 0, { 0, 0, 0}}, // (145, 95) + { 0, { 0, 0, 0}}, // (146, 95) + { 0, { 0, 0, 0}}, // (147, 95) + { 0, { 0, 0, 0}}, // (148, 95) + { 0, { 0, 0, 0}}, // (149, 95) + { 0, { 0, 0, 0}}, // (150, 95) + { 0, { 0, 0, 0}}, // (151, 95) + { 0, { 0, 0, 0}}, // (152, 95) + { 0, { 0, 0, 0}}, // (153, 95) + { 0, { 0, 0, 0}}, // (154, 95) + { 0, { 0, 0, 0}}, // (155, 95) + { 0, { 0, 0, 0}}, // (156, 95) + { 0, { 0, 0, 0}}, // (157, 95) + { 0, { 0, 0, 0}}, // (158, 95) + { 0, { 0, 0, 0}}, // (159, 95) + { 0, { 0, 0, 0}}, // (160, 95) + { 0, { 0, 0, 0}}, // (161, 95) + { 0, { 0, 0, 0}}, // (162, 95) + { 0, { 0, 0, 0}}, // (163, 95) + { 0, { 0, 0, 0}}, // (164, 95) + { 0, { 0, 0, 0}}, // (165, 95) + { 0, { 0, 0, 0}}, // (166, 95) + { 0, { 0, 0, 0}}, // (167, 95) + { 0, { 0, 0, 0}}, // (168, 95) + { 0, { 0, 0, 0}}, // (169, 95) + { 0, { 0, 0, 0}}, // (170, 95) + { 0, { 0, 0, 0}}, // (171, 95) + { 0, { 0, 0, 0}}, // (172, 95) + { 0, { 0, 0, 0}}, // (173, 95) + { 0, { 0, 0, 0}}, // (174, 95) + { 0, { 0, 0, 0}}, // (175, 95) + { 0, { 0, 0, 0}}, // (176, 95) + { 25, { 0, 0, 0}}, // (177, 95) + {128, { 0, 0, 0}}, // (178, 95) + {128, { 0, 0, 0}}, // (179, 95) + {128, { 0, 0, 0}}, // ( 0, 96) + {128, { 0, 0, 0}}, // ( 1, 96) + { 34, { 0, 0, 0}}, // ( 2, 96) + { 0, { 0, 0, 0}}, // ( 3, 96) + { 0, { 0, 0, 0}}, // ( 4, 96) + { 0, { 0, 0, 0}}, // ( 5, 96) + { 0, { 0, 0, 0}}, // ( 6, 96) + { 0, { 0, 0, 0}}, // ( 7, 96) + { 0, { 0, 0, 0}}, // ( 8, 96) + { 0, { 0, 0, 0}}, // ( 9, 96) + { 0, { 0, 0, 0}}, // ( 10, 96) + { 0, { 0, 0, 0}}, // ( 11, 96) + { 0, { 0, 0, 0}}, // ( 12, 96) + { 0, { 0, 0, 0}}, // ( 13, 96) + { 0, { 0, 0, 0}}, // ( 14, 96) + { 0, { 0, 0, 0}}, // ( 15, 96) + { 0, { 0, 0, 0}}, // ( 16, 96) + { 0, { 0, 0, 0}}, // ( 17, 96) + { 0, { 0, 0, 0}}, // ( 18, 96) + { 0, { 0, 0, 0}}, // ( 19, 96) + { 0, { 0, 0, 0}}, // ( 20, 96) + { 0, { 0, 0, 0}}, // ( 21, 96) + { 0, { 0, 0, 0}}, // ( 22, 96) + { 0, { 0, 0, 0}}, // ( 23, 96) + { 0, { 0, 0, 0}}, // ( 24, 96) + { 0, { 0, 0, 0}}, // ( 25, 96) + { 0, { 0, 0, 0}}, // ( 26, 96) + { 0, { 0, 0, 0}}, // ( 27, 96) + { 0, { 0, 0, 0}}, // ( 28, 96) + { 0, { 0, 0, 0}}, // ( 29, 96) + { 0, { 0, 0, 0}}, // ( 30, 96) + { 0, { 0, 0, 0}}, // ( 31, 96) + { 0, { 0, 0, 0}}, // ( 32, 96) + { 0, { 0, 0, 0}}, // ( 33, 96) + { 0, { 0, 0, 0}}, // ( 34, 96) + { 0, { 0, 0, 0}}, // ( 35, 96) + { 0, { 0, 0, 0}}, // ( 36, 96) + { 0, { 0, 0, 0}}, // ( 37, 96) + { 0, { 0, 0, 0}}, // ( 38, 96) + { 0, { 0, 0, 0}}, // ( 39, 96) + { 0, { 0, 0, 0}}, // ( 40, 96) + { 0, { 0, 0, 0}}, // ( 41, 96) + { 0, { 0, 0, 0}}, // ( 42, 96) + { 0, { 0, 0, 0}}, // ( 43, 96) + { 0, { 0, 0, 0}}, // ( 44, 96) + { 0, { 0, 0, 0}}, // ( 45, 96) + { 0, { 0, 0, 0}}, // ( 46, 96) + { 0, { 0, 0, 0}}, // ( 47, 96) + { 0, { 0, 0, 0}}, // ( 48, 96) + { 0, { 0, 0, 0}}, // ( 49, 96) + { 0, { 0, 0, 0}}, // ( 50, 96) + { 0, { 0, 0, 0}}, // ( 51, 96) + { 0, { 0, 0, 0}}, // ( 52, 96) + { 0, { 0, 0, 0}}, // ( 53, 96) + { 0, { 0, 0, 0}}, // ( 54, 96) + { 0, { 0, 0, 0}}, // ( 55, 96) + { 0, { 0, 0, 0}}, // ( 56, 96) + { 0, { 0, 0, 0}}, // ( 57, 96) + { 0, { 0, 0, 0}}, // ( 58, 96) + { 0, { 0, 0, 0}}, // ( 59, 96) + { 0, { 0, 0, 0}}, // ( 60, 96) + { 0, { 0, 0, 0}}, // ( 61, 96) + { 0, { 0, 0, 0}}, // ( 62, 96) + { 0, { 0, 0, 0}}, // ( 63, 96) + { 0, { 0, 0, 0}}, // ( 64, 96) + { 0, { 0, 0, 0}}, // ( 65, 96) + { 0, { 0, 0, 0}}, // ( 66, 96) + { 0, { 0, 0, 0}}, // ( 67, 96) + { 0, { 0, 0, 0}}, // ( 68, 96) + { 0, { 0, 0, 0}}, // ( 69, 96) + { 0, { 0, 0, 0}}, // ( 70, 96) + { 0, { 0, 0, 0}}, // ( 71, 96) + { 0, { 0, 0, 0}}, // ( 72, 96) + { 0, { 0, 0, 0}}, // ( 73, 96) + { 0, { 0, 0, 0}}, // ( 74, 96) + { 0, { 0, 0, 0}}, // ( 75, 96) + { 0, { 0, 0, 0}}, // ( 76, 96) + { 0, { 0, 0, 0}}, // ( 77, 96) + { 0, { 0, 0, 0}}, // ( 78, 96) + { 0, { 0, 0, 0}}, // ( 79, 96) + { 0, { 0, 0, 0}}, // ( 80, 96) + { 0, { 0, 0, 0}}, // ( 81, 96) + { 0, { 0, 0, 0}}, // ( 82, 96) + { 0, { 0, 0, 0}}, // ( 83, 96) + { 0, { 0, 0, 0}}, // ( 84, 96) + { 0, { 0, 0, 0}}, // ( 85, 96) + { 0, { 0, 0, 0}}, // ( 86, 96) + { 0, { 0, 0, 0}}, // ( 87, 96) + { 0, { 0, 0, 0}}, // ( 88, 96) + { 0, { 0, 0, 0}}, // ( 89, 96) + { 0, { 0, 0, 0}}, // ( 90, 96) + { 0, { 0, 0, 0}}, // ( 91, 96) + { 0, { 0, 0, 0}}, // ( 92, 96) + { 0, { 0, 0, 0}}, // ( 93, 96) + { 0, { 0, 0, 0}}, // ( 94, 96) + { 0, { 0, 0, 0}}, // ( 95, 96) + { 0, { 0, 0, 0}}, // ( 96, 96) + { 0, { 0, 0, 0}}, // ( 97, 96) + { 0, { 0, 0, 0}}, // ( 98, 96) + { 0, { 0, 0, 0}}, // ( 99, 96) + { 0, { 0, 0, 0}}, // (100, 96) + { 0, { 0, 0, 0}}, // (101, 96) + { 0, { 0, 0, 0}}, // (102, 96) + { 0, { 0, 0, 0}}, // (103, 96) + { 0, { 0, 0, 0}}, // (104, 96) + { 0, { 0, 0, 0}}, // (105, 96) + { 0, { 0, 0, 0}}, // (106, 96) + { 0, { 0, 0, 0}}, // (107, 96) + { 0, { 0, 0, 0}}, // (108, 96) + { 0, { 0, 0, 0}}, // (109, 96) + { 0, { 0, 0, 0}}, // (110, 96) + { 0, { 0, 0, 0}}, // (111, 96) + { 0, { 0, 0, 0}}, // (112, 96) + { 0, { 0, 0, 0}}, // (113, 96) + { 0, { 0, 0, 0}}, // (114, 96) + { 0, { 0, 0, 0}}, // (115, 96) + { 0, { 0, 0, 0}}, // (116, 96) + { 0, { 0, 0, 0}}, // (117, 96) + { 0, { 0, 0, 0}}, // (118, 96) + { 0, { 0, 0, 0}}, // (119, 96) + { 0, { 0, 0, 0}}, // (120, 96) + { 0, { 0, 0, 0}}, // (121, 96) + { 0, { 0, 0, 0}}, // (122, 96) + { 0, { 0, 0, 0}}, // (123, 96) + { 0, { 0, 0, 0}}, // (124, 96) + { 0, { 0, 0, 0}}, // (125, 96) + { 0, { 0, 0, 0}}, // (126, 96) + { 0, { 0, 0, 0}}, // (127, 96) + { 0, { 0, 0, 0}}, // (128, 96) + { 0, { 0, 0, 0}}, // (129, 96) + { 0, { 0, 0, 0}}, // (130, 96) + { 0, { 0, 0, 0}}, // (131, 96) + { 0, { 0, 0, 0}}, // (132, 96) + { 0, { 0, 0, 0}}, // (133, 96) + { 0, { 0, 0, 0}}, // (134, 96) + { 0, { 0, 0, 0}}, // (135, 96) + { 0, { 0, 0, 0}}, // (136, 96) + { 0, { 0, 0, 0}}, // (137, 96) + { 0, { 0, 0, 0}}, // (138, 96) + { 0, { 0, 0, 0}}, // (139, 96) + { 0, { 0, 0, 0}}, // (140, 96) + { 0, { 0, 0, 0}}, // (141, 96) + { 0, { 0, 0, 0}}, // (142, 96) + { 0, { 0, 0, 0}}, // (143, 96) + { 0, { 0, 0, 0}}, // (144, 96) + { 0, { 0, 0, 0}}, // (145, 96) + { 0, { 0, 0, 0}}, // (146, 96) + { 0, { 0, 0, 0}}, // (147, 96) + { 0, { 0, 0, 0}}, // (148, 96) + { 0, { 0, 0, 0}}, // (149, 96) + { 0, { 0, 0, 0}}, // (150, 96) + { 0, { 0, 0, 0}}, // (151, 96) + { 0, { 0, 0, 0}}, // (152, 96) + { 0, { 0, 0, 0}}, // (153, 96) + { 0, { 0, 0, 0}}, // (154, 96) + { 0, { 0, 0, 0}}, // (155, 96) + { 0, { 0, 0, 0}}, // (156, 96) + { 0, { 0, 0, 0}}, // (157, 96) + { 0, { 0, 0, 0}}, // (158, 96) + { 0, { 0, 0, 0}}, // (159, 96) + { 0, { 0, 0, 0}}, // (160, 96) + { 0, { 0, 0, 0}}, // (161, 96) + { 0, { 0, 0, 0}}, // (162, 96) + { 0, { 0, 0, 0}}, // (163, 96) + { 0, { 0, 0, 0}}, // (164, 96) + { 0, { 0, 0, 0}}, // (165, 96) + { 0, { 0, 0, 0}}, // (166, 96) + { 0, { 0, 0, 0}}, // (167, 96) + { 0, { 0, 0, 0}}, // (168, 96) + { 0, { 0, 0, 0}}, // (169, 96) + { 0, { 0, 0, 0}}, // (170, 96) + { 0, { 0, 0, 0}}, // (171, 96) + { 0, { 0, 0, 0}}, // (172, 96) + { 0, { 0, 0, 0}}, // (173, 96) + { 0, { 0, 0, 0}}, // (174, 96) + { 0, { 0, 0, 0}}, // (175, 96) + { 0, { 0, 0, 0}}, // (176, 96) + { 34, { 0, 0, 0}}, // (177, 96) + {128, { 0, 0, 0}}, // (178, 96) + {128, { 0, 0, 0}}, // (179, 96) + {128, { 0, 0, 0}}, // ( 0, 97) + {128, { 0, 0, 0}}, // ( 1, 97) + { 43, { 0, 0, 0}}, // ( 2, 97) + { 0, { 0, 0, 0}}, // ( 3, 97) + { 0, { 0, 0, 0}}, // ( 4, 97) + { 0, { 0, 0, 0}}, // ( 5, 97) + { 0, { 0, 0, 0}}, // ( 6, 97) + { 0, { 0, 0, 0}}, // ( 7, 97) + { 0, { 0, 0, 0}}, // ( 8, 97) + { 0, { 0, 0, 0}}, // ( 9, 97) + { 0, { 0, 0, 0}}, // ( 10, 97) + { 0, { 0, 0, 0}}, // ( 11, 97) + { 0, { 0, 0, 0}}, // ( 12, 97) + { 0, { 0, 0, 0}}, // ( 13, 97) + { 0, { 0, 0, 0}}, // ( 14, 97) + { 0, { 0, 0, 0}}, // ( 15, 97) + { 0, { 0, 0, 0}}, // ( 16, 97) + { 0, { 0, 0, 0}}, // ( 17, 97) + { 0, { 0, 0, 0}}, // ( 18, 97) + { 0, { 0, 0, 0}}, // ( 19, 97) + { 0, { 0, 0, 0}}, // ( 20, 97) + { 0, { 0, 0, 0}}, // ( 21, 97) + { 0, { 0, 0, 0}}, // ( 22, 97) + { 0, { 0, 0, 0}}, // ( 23, 97) + { 0, { 0, 0, 0}}, // ( 24, 97) + { 0, { 0, 0, 0}}, // ( 25, 97) + { 0, { 0, 0, 0}}, // ( 26, 97) + { 0, { 0, 0, 0}}, // ( 27, 97) + { 0, { 0, 0, 0}}, // ( 28, 97) + { 0, { 0, 0, 0}}, // ( 29, 97) + { 0, { 0, 0, 0}}, // ( 30, 97) + { 0, { 0, 0, 0}}, // ( 31, 97) + { 0, { 0, 0, 0}}, // ( 32, 97) + { 0, { 0, 0, 0}}, // ( 33, 97) + { 0, { 0, 0, 0}}, // ( 34, 97) + { 0, { 0, 0, 0}}, // ( 35, 97) + { 0, { 0, 0, 0}}, // ( 36, 97) + { 0, { 0, 0, 0}}, // ( 37, 97) + { 0, { 0, 0, 0}}, // ( 38, 97) + { 0, { 0, 0, 0}}, // ( 39, 97) + { 0, { 0, 0, 0}}, // ( 40, 97) + { 0, { 0, 0, 0}}, // ( 41, 97) + { 0, { 0, 0, 0}}, // ( 42, 97) + { 0, { 0, 0, 0}}, // ( 43, 97) + { 0, { 0, 0, 0}}, // ( 44, 97) + { 0, { 0, 0, 0}}, // ( 45, 97) + { 0, { 0, 0, 0}}, // ( 46, 97) + { 0, { 0, 0, 0}}, // ( 47, 97) + { 0, { 0, 0, 0}}, // ( 48, 97) + { 0, { 0, 0, 0}}, // ( 49, 97) + { 0, { 0, 0, 0}}, // ( 50, 97) + { 0, { 0, 0, 0}}, // ( 51, 97) + { 0, { 0, 0, 0}}, // ( 52, 97) + { 0, { 0, 0, 0}}, // ( 53, 97) + { 0, { 0, 0, 0}}, // ( 54, 97) + { 0, { 0, 0, 0}}, // ( 55, 97) + { 0, { 0, 0, 0}}, // ( 56, 97) + { 0, { 0, 0, 0}}, // ( 57, 97) + { 0, { 0, 0, 0}}, // ( 58, 97) + { 0, { 0, 0, 0}}, // ( 59, 97) + { 0, { 0, 0, 0}}, // ( 60, 97) + { 0, { 0, 0, 0}}, // ( 61, 97) + { 0, { 0, 0, 0}}, // ( 62, 97) + { 0, { 0, 0, 0}}, // ( 63, 97) + { 0, { 0, 0, 0}}, // ( 64, 97) + { 0, { 0, 0, 0}}, // ( 65, 97) + { 0, { 0, 0, 0}}, // ( 66, 97) + { 0, { 0, 0, 0}}, // ( 67, 97) + { 0, { 0, 0, 0}}, // ( 68, 97) + { 0, { 0, 0, 0}}, // ( 69, 97) + { 0, { 0, 0, 0}}, // ( 70, 97) + { 0, { 0, 0, 0}}, // ( 71, 97) + { 0, { 0, 0, 0}}, // ( 72, 97) + { 0, { 0, 0, 0}}, // ( 73, 97) + { 0, { 0, 0, 0}}, // ( 74, 97) + { 0, { 0, 0, 0}}, // ( 75, 97) + { 0, { 0, 0, 0}}, // ( 76, 97) + { 0, { 0, 0, 0}}, // ( 77, 97) + { 0, { 0, 0, 0}}, // ( 78, 97) + { 0, { 0, 0, 0}}, // ( 79, 97) + { 0, { 0, 0, 0}}, // ( 80, 97) + { 0, { 0, 0, 0}}, // ( 81, 97) + { 0, { 0, 0, 0}}, // ( 82, 97) + { 0, { 0, 0, 0}}, // ( 83, 97) + { 0, { 0, 0, 0}}, // ( 84, 97) + { 0, { 0, 0, 0}}, // ( 85, 97) + { 0, { 0, 0, 0}}, // ( 86, 97) + { 0, { 0, 0, 0}}, // ( 87, 97) + { 0, { 0, 0, 0}}, // ( 88, 97) + { 0, { 0, 0, 0}}, // ( 89, 97) + { 0, { 0, 0, 0}}, // ( 90, 97) + { 0, { 0, 0, 0}}, // ( 91, 97) + { 0, { 0, 0, 0}}, // ( 92, 97) + { 0, { 0, 0, 0}}, // ( 93, 97) + { 0, { 0, 0, 0}}, // ( 94, 97) + { 0, { 0, 0, 0}}, // ( 95, 97) + { 0, { 0, 0, 0}}, // ( 96, 97) + { 0, { 0, 0, 0}}, // ( 97, 97) + { 0, { 0, 0, 0}}, // ( 98, 97) + { 0, { 0, 0, 0}}, // ( 99, 97) + { 0, { 0, 0, 0}}, // (100, 97) + { 0, { 0, 0, 0}}, // (101, 97) + { 0, { 0, 0, 0}}, // (102, 97) + { 0, { 0, 0, 0}}, // (103, 97) + { 0, { 0, 0, 0}}, // (104, 97) + { 0, { 0, 0, 0}}, // (105, 97) + { 0, { 0, 0, 0}}, // (106, 97) + { 0, { 0, 0, 0}}, // (107, 97) + { 0, { 0, 0, 0}}, // (108, 97) + { 0, { 0, 0, 0}}, // (109, 97) + { 0, { 0, 0, 0}}, // (110, 97) + { 0, { 0, 0, 0}}, // (111, 97) + { 0, { 0, 0, 0}}, // (112, 97) + { 0, { 0, 0, 0}}, // (113, 97) + { 0, { 0, 0, 0}}, // (114, 97) + { 0, { 0, 0, 0}}, // (115, 97) + { 0, { 0, 0, 0}}, // (116, 97) + { 0, { 0, 0, 0}}, // (117, 97) + { 0, { 0, 0, 0}}, // (118, 97) + { 0, { 0, 0, 0}}, // (119, 97) + { 0, { 0, 0, 0}}, // (120, 97) + { 0, { 0, 0, 0}}, // (121, 97) + { 0, { 0, 0, 0}}, // (122, 97) + { 0, { 0, 0, 0}}, // (123, 97) + { 0, { 0, 0, 0}}, // (124, 97) + { 0, { 0, 0, 0}}, // (125, 97) + { 0, { 0, 0, 0}}, // (126, 97) + { 0, { 0, 0, 0}}, // (127, 97) + { 0, { 0, 0, 0}}, // (128, 97) + { 0, { 0, 0, 0}}, // (129, 97) + { 0, { 0, 0, 0}}, // (130, 97) + { 0, { 0, 0, 0}}, // (131, 97) + { 0, { 0, 0, 0}}, // (132, 97) + { 0, { 0, 0, 0}}, // (133, 97) + { 0, { 0, 0, 0}}, // (134, 97) + { 0, { 0, 0, 0}}, // (135, 97) + { 0, { 0, 0, 0}}, // (136, 97) + { 0, { 0, 0, 0}}, // (137, 97) + { 0, { 0, 0, 0}}, // (138, 97) + { 0, { 0, 0, 0}}, // (139, 97) + { 0, { 0, 0, 0}}, // (140, 97) + { 0, { 0, 0, 0}}, // (141, 97) + { 0, { 0, 0, 0}}, // (142, 97) + { 0, { 0, 0, 0}}, // (143, 97) + { 0, { 0, 0, 0}}, // (144, 97) + { 0, { 0, 0, 0}}, // (145, 97) + { 0, { 0, 0, 0}}, // (146, 97) + { 0, { 0, 0, 0}}, // (147, 97) + { 0, { 0, 0, 0}}, // (148, 97) + { 0, { 0, 0, 0}}, // (149, 97) + { 0, { 0, 0, 0}}, // (150, 97) + { 0, { 0, 0, 0}}, // (151, 97) + { 0, { 0, 0, 0}}, // (152, 97) + { 0, { 0, 0, 0}}, // (153, 97) + { 0, { 0, 0, 0}}, // (154, 97) + { 0, { 0, 0, 0}}, // (155, 97) + { 0, { 0, 0, 0}}, // (156, 97) + { 0, { 0, 0, 0}}, // (157, 97) + { 0, { 0, 0, 0}}, // (158, 97) + { 0, { 0, 0, 0}}, // (159, 97) + { 0, { 0, 0, 0}}, // (160, 97) + { 0, { 0, 0, 0}}, // (161, 97) + { 0, { 0, 0, 0}}, // (162, 97) + { 0, { 0, 0, 0}}, // (163, 97) + { 0, { 0, 0, 0}}, // (164, 97) + { 0, { 0, 0, 0}}, // (165, 97) + { 0, { 0, 0, 0}}, // (166, 97) + { 0, { 0, 0, 0}}, // (167, 97) + { 0, { 0, 0, 0}}, // (168, 97) + { 0, { 0, 0, 0}}, // (169, 97) + { 0, { 0, 0, 0}}, // (170, 97) + { 0, { 0, 0, 0}}, // (171, 97) + { 0, { 0, 0, 0}}, // (172, 97) + { 0, { 0, 0, 0}}, // (173, 97) + { 0, { 0, 0, 0}}, // (174, 97) + { 0, { 0, 0, 0}}, // (175, 97) + { 0, { 0, 0, 0}}, // (176, 97) + { 43, { 0, 0, 0}}, // (177, 97) + {128, { 0, 0, 0}}, // (178, 97) + {128, { 0, 0, 0}}, // (179, 97) + {128, { 0, 0, 0}}, // ( 0, 98) + {128, { 0, 0, 0}}, // ( 1, 98) + { 54, { 0, 0, 0}}, // ( 2, 98) + { 0, { 0, 0, 0}}, // ( 3, 98) + { 0, { 0, 0, 0}}, // ( 4, 98) + { 0, { 0, 0, 0}}, // ( 5, 98) + { 0, { 0, 0, 0}}, // ( 6, 98) + { 0, { 0, 0, 0}}, // ( 7, 98) + { 0, { 0, 0, 0}}, // ( 8, 98) + { 0, { 0, 0, 0}}, // ( 9, 98) + { 0, { 0, 0, 0}}, // ( 10, 98) + { 0, { 0, 0, 0}}, // ( 11, 98) + { 0, { 0, 0, 0}}, // ( 12, 98) + { 0, { 0, 0, 0}}, // ( 13, 98) + { 0, { 0, 0, 0}}, // ( 14, 98) + { 0, { 0, 0, 0}}, // ( 15, 98) + { 0, { 0, 0, 0}}, // ( 16, 98) + { 0, { 0, 0, 0}}, // ( 17, 98) + { 0, { 0, 0, 0}}, // ( 18, 98) + { 0, { 0, 0, 0}}, // ( 19, 98) + { 0, { 0, 0, 0}}, // ( 20, 98) + { 0, { 0, 0, 0}}, // ( 21, 98) + { 0, { 0, 0, 0}}, // ( 22, 98) + { 0, { 0, 0, 0}}, // ( 23, 98) + { 0, { 0, 0, 0}}, // ( 24, 98) + { 0, { 0, 0, 0}}, // ( 25, 98) + { 0, { 0, 0, 0}}, // ( 26, 98) + { 0, { 0, 0, 0}}, // ( 27, 98) + { 0, { 0, 0, 0}}, // ( 28, 98) + { 0, { 0, 0, 0}}, // ( 29, 98) + { 0, { 0, 0, 0}}, // ( 30, 98) + { 0, { 0, 0, 0}}, // ( 31, 98) + { 0, { 0, 0, 0}}, // ( 32, 98) + { 0, { 0, 0, 0}}, // ( 33, 98) + { 0, { 0, 0, 0}}, // ( 34, 98) + { 0, { 0, 0, 0}}, // ( 35, 98) + { 0, { 0, 0, 0}}, // ( 36, 98) + { 0, { 0, 0, 0}}, // ( 37, 98) + { 0, { 0, 0, 0}}, // ( 38, 98) + { 0, { 0, 0, 0}}, // ( 39, 98) + { 0, { 0, 0, 0}}, // ( 40, 98) + { 0, { 0, 0, 0}}, // ( 41, 98) + { 0, { 0, 0, 0}}, // ( 42, 98) + { 0, { 0, 0, 0}}, // ( 43, 98) + { 0, { 0, 0, 0}}, // ( 44, 98) + { 0, { 0, 0, 0}}, // ( 45, 98) + { 0, { 0, 0, 0}}, // ( 46, 98) + { 0, { 0, 0, 0}}, // ( 47, 98) + { 0, { 0, 0, 0}}, // ( 48, 98) + { 0, { 0, 0, 0}}, // ( 49, 98) + { 0, { 0, 0, 0}}, // ( 50, 98) + { 0, { 0, 0, 0}}, // ( 51, 98) + { 0, { 0, 0, 0}}, // ( 52, 98) + { 0, { 0, 0, 0}}, // ( 53, 98) + { 0, { 0, 0, 0}}, // ( 54, 98) + { 0, { 0, 0, 0}}, // ( 55, 98) + { 0, { 0, 0, 0}}, // ( 56, 98) + { 0, { 0, 0, 0}}, // ( 57, 98) + { 0, { 0, 0, 0}}, // ( 58, 98) + { 0, { 0, 0, 0}}, // ( 59, 98) + { 0, { 0, 0, 0}}, // ( 60, 98) + { 0, { 0, 0, 0}}, // ( 61, 98) + { 0, { 0, 0, 0}}, // ( 62, 98) + { 0, { 0, 0, 0}}, // ( 63, 98) + { 0, { 0, 0, 0}}, // ( 64, 98) + { 0, { 0, 0, 0}}, // ( 65, 98) + { 0, { 0, 0, 0}}, // ( 66, 98) + { 0, { 0, 0, 0}}, // ( 67, 98) + { 0, { 0, 0, 0}}, // ( 68, 98) + { 0, { 0, 0, 0}}, // ( 69, 98) + { 0, { 0, 0, 0}}, // ( 70, 98) + { 0, { 0, 0, 0}}, // ( 71, 98) + { 0, { 0, 0, 0}}, // ( 72, 98) + { 0, { 0, 0, 0}}, // ( 73, 98) + { 0, { 0, 0, 0}}, // ( 74, 98) + { 0, { 0, 0, 0}}, // ( 75, 98) + { 0, { 0, 0, 0}}, // ( 76, 98) + { 0, { 0, 0, 0}}, // ( 77, 98) + { 0, { 0, 0, 0}}, // ( 78, 98) + { 0, { 0, 0, 0}}, // ( 79, 98) + { 0, { 0, 0, 0}}, // ( 80, 98) + { 0, { 0, 0, 0}}, // ( 81, 98) + { 0, { 0, 0, 0}}, // ( 82, 98) + { 0, { 0, 0, 0}}, // ( 83, 98) + { 0, { 0, 0, 0}}, // ( 84, 98) + { 0, { 0, 0, 0}}, // ( 85, 98) + { 0, { 0, 0, 0}}, // ( 86, 98) + { 0, { 0, 0, 0}}, // ( 87, 98) + { 0, { 0, 0, 0}}, // ( 88, 98) + { 0, { 0, 0, 0}}, // ( 89, 98) + { 0, { 0, 0, 0}}, // ( 90, 98) + { 0, { 0, 0, 0}}, // ( 91, 98) + { 0, { 0, 0, 0}}, // ( 92, 98) + { 0, { 0, 0, 0}}, // ( 93, 98) + { 0, { 0, 0, 0}}, // ( 94, 98) + { 0, { 0, 0, 0}}, // ( 95, 98) + { 0, { 0, 0, 0}}, // ( 96, 98) + { 0, { 0, 0, 0}}, // ( 97, 98) + { 0, { 0, 0, 0}}, // ( 98, 98) + { 0, { 0, 0, 0}}, // ( 99, 98) + { 0, { 0, 0, 0}}, // (100, 98) + { 0, { 0, 0, 0}}, // (101, 98) + { 0, { 0, 0, 0}}, // (102, 98) + { 0, { 0, 0, 0}}, // (103, 98) + { 0, { 0, 0, 0}}, // (104, 98) + { 0, { 0, 0, 0}}, // (105, 98) + { 0, { 0, 0, 0}}, // (106, 98) + { 0, { 0, 0, 0}}, // (107, 98) + { 0, { 0, 0, 0}}, // (108, 98) + { 0, { 0, 0, 0}}, // (109, 98) + { 0, { 0, 0, 0}}, // (110, 98) + { 0, { 0, 0, 0}}, // (111, 98) + { 0, { 0, 0, 0}}, // (112, 98) + { 0, { 0, 0, 0}}, // (113, 98) + { 0, { 0, 0, 0}}, // (114, 98) + { 0, { 0, 0, 0}}, // (115, 98) + { 0, { 0, 0, 0}}, // (116, 98) + { 0, { 0, 0, 0}}, // (117, 98) + { 0, { 0, 0, 0}}, // (118, 98) + { 0, { 0, 0, 0}}, // (119, 98) + { 0, { 0, 0, 0}}, // (120, 98) + { 0, { 0, 0, 0}}, // (121, 98) + { 0, { 0, 0, 0}}, // (122, 98) + { 0, { 0, 0, 0}}, // (123, 98) + { 0, { 0, 0, 0}}, // (124, 98) + { 0, { 0, 0, 0}}, // (125, 98) + { 0, { 0, 0, 0}}, // (126, 98) + { 0, { 0, 0, 0}}, // (127, 98) + { 0, { 0, 0, 0}}, // (128, 98) + { 0, { 0, 0, 0}}, // (129, 98) + { 0, { 0, 0, 0}}, // (130, 98) + { 0, { 0, 0, 0}}, // (131, 98) + { 0, { 0, 0, 0}}, // (132, 98) + { 0, { 0, 0, 0}}, // (133, 98) + { 0, { 0, 0, 0}}, // (134, 98) + { 0, { 0, 0, 0}}, // (135, 98) + { 0, { 0, 0, 0}}, // (136, 98) + { 0, { 0, 0, 0}}, // (137, 98) + { 0, { 0, 0, 0}}, // (138, 98) + { 0, { 0, 0, 0}}, // (139, 98) + { 0, { 0, 0, 0}}, // (140, 98) + { 0, { 0, 0, 0}}, // (141, 98) + { 0, { 0, 0, 0}}, // (142, 98) + { 0, { 0, 0, 0}}, // (143, 98) + { 0, { 0, 0, 0}}, // (144, 98) + { 0, { 0, 0, 0}}, // (145, 98) + { 0, { 0, 0, 0}}, // (146, 98) + { 0, { 0, 0, 0}}, // (147, 98) + { 0, { 0, 0, 0}}, // (148, 98) + { 0, { 0, 0, 0}}, // (149, 98) + { 0, { 0, 0, 0}}, // (150, 98) + { 0, { 0, 0, 0}}, // (151, 98) + { 0, { 0, 0, 0}}, // (152, 98) + { 0, { 0, 0, 0}}, // (153, 98) + { 0, { 0, 0, 0}}, // (154, 98) + { 0, { 0, 0, 0}}, // (155, 98) + { 0, { 0, 0, 0}}, // (156, 98) + { 0, { 0, 0, 0}}, // (157, 98) + { 0, { 0, 0, 0}}, // (158, 98) + { 0, { 0, 0, 0}}, // (159, 98) + { 0, { 0, 0, 0}}, // (160, 98) + { 0, { 0, 0, 0}}, // (161, 98) + { 0, { 0, 0, 0}}, // (162, 98) + { 0, { 0, 0, 0}}, // (163, 98) + { 0, { 0, 0, 0}}, // (164, 98) + { 0, { 0, 0, 0}}, // (165, 98) + { 0, { 0, 0, 0}}, // (166, 98) + { 0, { 0, 0, 0}}, // (167, 98) + { 0, { 0, 0, 0}}, // (168, 98) + { 0, { 0, 0, 0}}, // (169, 98) + { 0, { 0, 0, 0}}, // (170, 98) + { 0, { 0, 0, 0}}, // (171, 98) + { 0, { 0, 0, 0}}, // (172, 98) + { 0, { 0, 0, 0}}, // (173, 98) + { 0, { 0, 0, 0}}, // (174, 98) + { 0, { 0, 0, 0}}, // (175, 98) + { 0, { 0, 0, 0}}, // (176, 98) + { 54, { 0, 0, 0}}, // (177, 98) + {128, { 0, 0, 0}}, // (178, 98) + {128, { 0, 0, 0}}, // (179, 98) + {128, { 0, 0, 0}}, // ( 0, 99) + {128, { 0, 0, 0}}, // ( 1, 99) + { 66, { 0, 0, 0}}, // ( 2, 99) + { 0, { 0, 0, 0}}, // ( 3, 99) + { 0, { 0, 0, 0}}, // ( 4, 99) + { 0, { 0, 0, 0}}, // ( 5, 99) + { 0, { 0, 0, 0}}, // ( 6, 99) + { 0, { 0, 0, 0}}, // ( 7, 99) + { 0, { 0, 0, 0}}, // ( 8, 99) + { 0, { 0, 0, 0}}, // ( 9, 99) + { 0, { 0, 0, 0}}, // ( 10, 99) + { 0, { 0, 0, 0}}, // ( 11, 99) + { 0, { 0, 0, 0}}, // ( 12, 99) + { 0, { 0, 0, 0}}, // ( 13, 99) + { 0, { 0, 0, 0}}, // ( 14, 99) + { 0, { 0, 0, 0}}, // ( 15, 99) + { 0, { 0, 0, 0}}, // ( 16, 99) + { 0, { 0, 0, 0}}, // ( 17, 99) + { 0, { 0, 0, 0}}, // ( 18, 99) + { 0, { 0, 0, 0}}, // ( 19, 99) + { 0, { 0, 0, 0}}, // ( 20, 99) + { 0, { 0, 0, 0}}, // ( 21, 99) + { 0, { 0, 0, 0}}, // ( 22, 99) + { 0, { 0, 0, 0}}, // ( 23, 99) + { 0, { 0, 0, 0}}, // ( 24, 99) + { 0, { 0, 0, 0}}, // ( 25, 99) + { 0, { 0, 0, 0}}, // ( 26, 99) + { 0, { 0, 0, 0}}, // ( 27, 99) + { 0, { 0, 0, 0}}, // ( 28, 99) + { 0, { 0, 0, 0}}, // ( 29, 99) + { 0, { 0, 0, 0}}, // ( 30, 99) + { 0, { 0, 0, 0}}, // ( 31, 99) + { 0, { 0, 0, 0}}, // ( 32, 99) + { 0, { 0, 0, 0}}, // ( 33, 99) + { 0, { 0, 0, 0}}, // ( 34, 99) + { 0, { 0, 0, 0}}, // ( 35, 99) + { 0, { 0, 0, 0}}, // ( 36, 99) + { 0, { 0, 0, 0}}, // ( 37, 99) + { 0, { 0, 0, 0}}, // ( 38, 99) + { 0, { 0, 0, 0}}, // ( 39, 99) + { 0, { 0, 0, 0}}, // ( 40, 99) + { 0, { 0, 0, 0}}, // ( 41, 99) + { 0, { 0, 0, 0}}, // ( 42, 99) + { 0, { 0, 0, 0}}, // ( 43, 99) + { 0, { 0, 0, 0}}, // ( 44, 99) + { 0, { 0, 0, 0}}, // ( 45, 99) + { 0, { 0, 0, 0}}, // ( 46, 99) + { 0, { 0, 0, 0}}, // ( 47, 99) + { 0, { 0, 0, 0}}, // ( 48, 99) + { 0, { 0, 0, 0}}, // ( 49, 99) + { 0, { 0, 0, 0}}, // ( 50, 99) + { 0, { 0, 0, 0}}, // ( 51, 99) + { 0, { 0, 0, 0}}, // ( 52, 99) + { 0, { 0, 0, 0}}, // ( 53, 99) + { 0, { 0, 0, 0}}, // ( 54, 99) + { 0, { 0, 0, 0}}, // ( 55, 99) + { 0, { 0, 0, 0}}, // ( 56, 99) + { 0, { 0, 0, 0}}, // ( 57, 99) + { 0, { 0, 0, 0}}, // ( 58, 99) + { 0, { 0, 0, 0}}, // ( 59, 99) + { 0, { 0, 0, 0}}, // ( 60, 99) + { 0, { 0, 0, 0}}, // ( 61, 99) + { 0, { 0, 0, 0}}, // ( 62, 99) + { 0, { 0, 0, 0}}, // ( 63, 99) + { 0, { 0, 0, 0}}, // ( 64, 99) + { 0, { 0, 0, 0}}, // ( 65, 99) + { 0, { 0, 0, 0}}, // ( 66, 99) + { 0, { 0, 0, 0}}, // ( 67, 99) + { 0, { 0, 0, 0}}, // ( 68, 99) + { 0, { 0, 0, 0}}, // ( 69, 99) + { 0, { 0, 0, 0}}, // ( 70, 99) + { 0, { 0, 0, 0}}, // ( 71, 99) + { 0, { 0, 0, 0}}, // ( 72, 99) + { 0, { 0, 0, 0}}, // ( 73, 99) + { 0, { 0, 0, 0}}, // ( 74, 99) + { 0, { 0, 0, 0}}, // ( 75, 99) + { 0, { 0, 0, 0}}, // ( 76, 99) + { 0, { 0, 0, 0}}, // ( 77, 99) + { 0, { 0, 0, 0}}, // ( 78, 99) + { 0, { 0, 0, 0}}, // ( 79, 99) + { 0, { 0, 0, 0}}, // ( 80, 99) + { 0, { 0, 0, 0}}, // ( 81, 99) + { 0, { 0, 0, 0}}, // ( 82, 99) + { 0, { 0, 0, 0}}, // ( 83, 99) + { 0, { 0, 0, 0}}, // ( 84, 99) + { 0, { 0, 0, 0}}, // ( 85, 99) + { 0, { 0, 0, 0}}, // ( 86, 99) + { 0, { 0, 0, 0}}, // ( 87, 99) + { 0, { 0, 0, 0}}, // ( 88, 99) + { 0, { 0, 0, 0}}, // ( 89, 99) + { 0, { 0, 0, 0}}, // ( 90, 99) + { 0, { 0, 0, 0}}, // ( 91, 99) + { 0, { 0, 0, 0}}, // ( 92, 99) + { 0, { 0, 0, 0}}, // ( 93, 99) + { 0, { 0, 0, 0}}, // ( 94, 99) + { 0, { 0, 0, 0}}, // ( 95, 99) + { 0, { 0, 0, 0}}, // ( 96, 99) + { 0, { 0, 0, 0}}, // ( 97, 99) + { 0, { 0, 0, 0}}, // ( 98, 99) + { 0, { 0, 0, 0}}, // ( 99, 99) + { 0, { 0, 0, 0}}, // (100, 99) + { 0, { 0, 0, 0}}, // (101, 99) + { 0, { 0, 0, 0}}, // (102, 99) + { 0, { 0, 0, 0}}, // (103, 99) + { 0, { 0, 0, 0}}, // (104, 99) + { 0, { 0, 0, 0}}, // (105, 99) + { 0, { 0, 0, 0}}, // (106, 99) + { 0, { 0, 0, 0}}, // (107, 99) + { 0, { 0, 0, 0}}, // (108, 99) + { 0, { 0, 0, 0}}, // (109, 99) + { 0, { 0, 0, 0}}, // (110, 99) + { 0, { 0, 0, 0}}, // (111, 99) + { 0, { 0, 0, 0}}, // (112, 99) + { 0, { 0, 0, 0}}, // (113, 99) + { 0, { 0, 0, 0}}, // (114, 99) + { 0, { 0, 0, 0}}, // (115, 99) + { 0, { 0, 0, 0}}, // (116, 99) + { 0, { 0, 0, 0}}, // (117, 99) + { 0, { 0, 0, 0}}, // (118, 99) + { 0, { 0, 0, 0}}, // (119, 99) + { 0, { 0, 0, 0}}, // (120, 99) + { 0, { 0, 0, 0}}, // (121, 99) + { 0, { 0, 0, 0}}, // (122, 99) + { 0, { 0, 0, 0}}, // (123, 99) + { 0, { 0, 0, 0}}, // (124, 99) + { 0, { 0, 0, 0}}, // (125, 99) + { 0, { 0, 0, 0}}, // (126, 99) + { 0, { 0, 0, 0}}, // (127, 99) + { 0, { 0, 0, 0}}, // (128, 99) + { 0, { 0, 0, 0}}, // (129, 99) + { 0, { 0, 0, 0}}, // (130, 99) + { 0, { 0, 0, 0}}, // (131, 99) + { 0, { 0, 0, 0}}, // (132, 99) + { 0, { 0, 0, 0}}, // (133, 99) + { 0, { 0, 0, 0}}, // (134, 99) + { 0, { 0, 0, 0}}, // (135, 99) + { 0, { 0, 0, 0}}, // (136, 99) + { 0, { 0, 0, 0}}, // (137, 99) + { 0, { 0, 0, 0}}, // (138, 99) + { 0, { 0, 0, 0}}, // (139, 99) + { 0, { 0, 0, 0}}, // (140, 99) + { 0, { 0, 0, 0}}, // (141, 99) + { 0, { 0, 0, 0}}, // (142, 99) + { 0, { 0, 0, 0}}, // (143, 99) + { 0, { 0, 0, 0}}, // (144, 99) + { 0, { 0, 0, 0}}, // (145, 99) + { 0, { 0, 0, 0}}, // (146, 99) + { 0, { 0, 0, 0}}, // (147, 99) + { 0, { 0, 0, 0}}, // (148, 99) + { 0, { 0, 0, 0}}, // (149, 99) + { 0, { 0, 0, 0}}, // (150, 99) + { 0, { 0, 0, 0}}, // (151, 99) + { 0, { 0, 0, 0}}, // (152, 99) + { 0, { 0, 0, 0}}, // (153, 99) + { 0, { 0, 0, 0}}, // (154, 99) + { 0, { 0, 0, 0}}, // (155, 99) + { 0, { 0, 0, 0}}, // (156, 99) + { 0, { 0, 0, 0}}, // (157, 99) + { 0, { 0, 0, 0}}, // (158, 99) + { 0, { 0, 0, 0}}, // (159, 99) + { 0, { 0, 0, 0}}, // (160, 99) + { 0, { 0, 0, 0}}, // (161, 99) + { 0, { 0, 0, 0}}, // (162, 99) + { 0, { 0, 0, 0}}, // (163, 99) + { 0, { 0, 0, 0}}, // (164, 99) + { 0, { 0, 0, 0}}, // (165, 99) + { 0, { 0, 0, 0}}, // (166, 99) + { 0, { 0, 0, 0}}, // (167, 99) + { 0, { 0, 0, 0}}, // (168, 99) + { 0, { 0, 0, 0}}, // (169, 99) + { 0, { 0, 0, 0}}, // (170, 99) + { 0, { 0, 0, 0}}, // (171, 99) + { 0, { 0, 0, 0}}, // (172, 99) + { 0, { 0, 0, 0}}, // (173, 99) + { 0, { 0, 0, 0}}, // (174, 99) + { 0, { 0, 0, 0}}, // (175, 99) + { 0, { 0, 0, 0}}, // (176, 99) + { 67, { 0, 0, 0}}, // (177, 99) + {128, { 0, 0, 0}}, // (178, 99) + {128, { 0, 0, 0}}, // (179, 99) + {128, { 0, 0, 0}}, // ( 0, 100) + {128, { 0, 0, 0}}, // ( 1, 100) + { 83, { 0, 0, 0}}, // ( 2, 100) + { 0, { 0, 0, 0}}, // ( 3, 100) + { 0, { 0, 0, 0}}, // ( 4, 100) + { 0, { 0, 0, 0}}, // ( 5, 100) + { 0, { 0, 0, 0}}, // ( 6, 100) + { 0, { 0, 0, 0}}, // ( 7, 100) + { 0, { 0, 0, 0}}, // ( 8, 100) + { 0, { 0, 0, 0}}, // ( 9, 100) + { 0, { 0, 0, 0}}, // ( 10, 100) + { 0, { 0, 0, 0}}, // ( 11, 100) + { 0, { 0, 0, 0}}, // ( 12, 100) + { 0, { 0, 0, 0}}, // ( 13, 100) + { 0, { 0, 0, 0}}, // ( 14, 100) + { 0, { 0, 0, 0}}, // ( 15, 100) + { 0, { 0, 0, 0}}, // ( 16, 100) + { 0, { 0, 0, 0}}, // ( 17, 100) + { 0, { 0, 0, 0}}, // ( 18, 100) + { 0, { 0, 0, 0}}, // ( 19, 100) + { 0, { 0, 0, 0}}, // ( 20, 100) + { 0, { 0, 0, 0}}, // ( 21, 100) + { 0, { 0, 0, 0}}, // ( 22, 100) + { 0, { 0, 0, 0}}, // ( 23, 100) + { 0, { 0, 0, 0}}, // ( 24, 100) + { 0, { 0, 0, 0}}, // ( 25, 100) + { 0, { 0, 0, 0}}, // ( 26, 100) + { 0, { 0, 0, 0}}, // ( 27, 100) + { 0, { 0, 0, 0}}, // ( 28, 100) + { 0, { 0, 0, 0}}, // ( 29, 100) + { 0, { 0, 0, 0}}, // ( 30, 100) + { 0, { 0, 0, 0}}, // ( 31, 100) + { 0, { 0, 0, 0}}, // ( 32, 100) + { 0, { 0, 0, 0}}, // ( 33, 100) + { 0, { 0, 0, 0}}, // ( 34, 100) + { 0, { 0, 0, 0}}, // ( 35, 100) + { 0, { 0, 0, 0}}, // ( 36, 100) + { 0, { 0, 0, 0}}, // ( 37, 100) + { 0, { 0, 0, 0}}, // ( 38, 100) + { 0, { 0, 0, 0}}, // ( 39, 100) + { 0, { 0, 0, 0}}, // ( 40, 100) + { 0, { 0, 0, 0}}, // ( 41, 100) + { 0, { 0, 0, 0}}, // ( 42, 100) + { 0, { 0, 0, 0}}, // ( 43, 100) + { 0, { 0, 0, 0}}, // ( 44, 100) + { 0, { 0, 0, 0}}, // ( 45, 100) + { 0, { 0, 0, 0}}, // ( 46, 100) + { 0, { 0, 0, 0}}, // ( 47, 100) + { 0, { 0, 0, 0}}, // ( 48, 100) + { 0, { 0, 0, 0}}, // ( 49, 100) + { 0, { 0, 0, 0}}, // ( 50, 100) + { 0, { 0, 0, 0}}, // ( 51, 100) + { 0, { 0, 0, 0}}, // ( 52, 100) + { 0, { 0, 0, 0}}, // ( 53, 100) + { 0, { 0, 0, 0}}, // ( 54, 100) + { 0, { 0, 0, 0}}, // ( 55, 100) + { 0, { 0, 0, 0}}, // ( 56, 100) + { 0, { 0, 0, 0}}, // ( 57, 100) + { 0, { 0, 0, 0}}, // ( 58, 100) + { 0, { 0, 0, 0}}, // ( 59, 100) + { 0, { 0, 0, 0}}, // ( 60, 100) + { 0, { 0, 0, 0}}, // ( 61, 100) + { 0, { 0, 0, 0}}, // ( 62, 100) + { 0, { 0, 0, 0}}, // ( 63, 100) + { 0, { 0, 0, 0}}, // ( 64, 100) + { 0, { 0, 0, 0}}, // ( 65, 100) + { 0, { 0, 0, 0}}, // ( 66, 100) + { 0, { 0, 0, 0}}, // ( 67, 100) + { 0, { 0, 0, 0}}, // ( 68, 100) + { 0, { 0, 0, 0}}, // ( 69, 100) + { 0, { 0, 0, 0}}, // ( 70, 100) + { 0, { 0, 0, 0}}, // ( 71, 100) + { 0, { 0, 0, 0}}, // ( 72, 100) + { 0, { 0, 0, 0}}, // ( 73, 100) + { 0, { 0, 0, 0}}, // ( 74, 100) + { 0, { 0, 0, 0}}, // ( 75, 100) + { 0, { 0, 0, 0}}, // ( 76, 100) + { 0, { 0, 0, 0}}, // ( 77, 100) + { 0, { 0, 0, 0}}, // ( 78, 100) + { 0, { 0, 0, 0}}, // ( 79, 100) + { 0, { 0, 0, 0}}, // ( 80, 100) + { 0, { 0, 0, 0}}, // ( 81, 100) + { 0, { 0, 0, 0}}, // ( 82, 100) + { 0, { 0, 0, 0}}, // ( 83, 100) + { 0, { 0, 0, 0}}, // ( 84, 100) + { 0, { 0, 0, 0}}, // ( 85, 100) + { 0, { 0, 0, 0}}, // ( 86, 100) + { 0, { 0, 0, 0}}, // ( 87, 100) + { 0, { 0, 0, 0}}, // ( 88, 100) + { 0, { 0, 0, 0}}, // ( 89, 100) + { 0, { 0, 0, 0}}, // ( 90, 100) + { 0, { 0, 0, 0}}, // ( 91, 100) + { 0, { 0, 0, 0}}, // ( 92, 100) + { 0, { 0, 0, 0}}, // ( 93, 100) + { 0, { 0, 0, 0}}, // ( 94, 100) + { 0, { 0, 0, 0}}, // ( 95, 100) + { 0, { 0, 0, 0}}, // ( 96, 100) + { 0, { 0, 0, 0}}, // ( 97, 100) + { 0, { 0, 0, 0}}, // ( 98, 100) + { 0, { 0, 0, 0}}, // ( 99, 100) + { 0, { 0, 0, 0}}, // (100, 100) + { 0, { 0, 0, 0}}, // (101, 100) + { 0, { 0, 0, 0}}, // (102, 100) + { 0, { 0, 0, 0}}, // (103, 100) + { 0, { 0, 0, 0}}, // (104, 100) + { 0, { 0, 0, 0}}, // (105, 100) + { 0, { 0, 0, 0}}, // (106, 100) + { 0, { 0, 0, 0}}, // (107, 100) + { 0, { 0, 0, 0}}, // (108, 100) + { 0, { 0, 0, 0}}, // (109, 100) + { 0, { 0, 0, 0}}, // (110, 100) + { 0, { 0, 0, 0}}, // (111, 100) + { 0, { 0, 0, 0}}, // (112, 100) + { 0, { 0, 0, 0}}, // (113, 100) + { 0, { 0, 0, 0}}, // (114, 100) + { 0, { 0, 0, 0}}, // (115, 100) + { 0, { 0, 0, 0}}, // (116, 100) + { 0, { 0, 0, 0}}, // (117, 100) + { 0, { 0, 0, 0}}, // (118, 100) + { 0, { 0, 0, 0}}, // (119, 100) + { 0, { 0, 0, 0}}, // (120, 100) + { 0, { 0, 0, 0}}, // (121, 100) + { 0, { 0, 0, 0}}, // (122, 100) + { 0, { 0, 0, 0}}, // (123, 100) + { 0, { 0, 0, 0}}, // (124, 100) + { 0, { 0, 0, 0}}, // (125, 100) + { 0, { 0, 0, 0}}, // (126, 100) + { 0, { 0, 0, 0}}, // (127, 100) + { 0, { 0, 0, 0}}, // (128, 100) + { 0, { 0, 0, 0}}, // (129, 100) + { 0, { 0, 0, 0}}, // (130, 100) + { 0, { 0, 0, 0}}, // (131, 100) + { 0, { 0, 0, 0}}, // (132, 100) + { 0, { 0, 0, 0}}, // (133, 100) + { 0, { 0, 0, 0}}, // (134, 100) + { 0, { 0, 0, 0}}, // (135, 100) + { 0, { 0, 0, 0}}, // (136, 100) + { 0, { 0, 0, 0}}, // (137, 100) + { 0, { 0, 0, 0}}, // (138, 100) + { 0, { 0, 0, 0}}, // (139, 100) + { 0, { 0, 0, 0}}, // (140, 100) + { 0, { 0, 0, 0}}, // (141, 100) + { 0, { 0, 0, 0}}, // (142, 100) + { 0, { 0, 0, 0}}, // (143, 100) + { 0, { 0, 0, 0}}, // (144, 100) + { 0, { 0, 0, 0}}, // (145, 100) + { 0, { 0, 0, 0}}, // (146, 100) + { 0, { 0, 0, 0}}, // (147, 100) + { 0, { 0, 0, 0}}, // (148, 100) + { 0, { 0, 0, 0}}, // (149, 100) + { 0, { 0, 0, 0}}, // (150, 100) + { 0, { 0, 0, 0}}, // (151, 100) + { 0, { 0, 0, 0}}, // (152, 100) + { 0, { 0, 0, 0}}, // (153, 100) + { 0, { 0, 0, 0}}, // (154, 100) + { 0, { 0, 0, 0}}, // (155, 100) + { 0, { 0, 0, 0}}, // (156, 100) + { 0, { 0, 0, 0}}, // (157, 100) + { 0, { 0, 0, 0}}, // (158, 100) + { 0, { 0, 0, 0}}, // (159, 100) + { 0, { 0, 0, 0}}, // (160, 100) + { 0, { 0, 0, 0}}, // (161, 100) + { 0, { 0, 0, 0}}, // (162, 100) + { 0, { 0, 0, 0}}, // (163, 100) + { 0, { 0, 0, 0}}, // (164, 100) + { 0, { 0, 0, 0}}, // (165, 100) + { 0, { 0, 0, 0}}, // (166, 100) + { 0, { 0, 0, 0}}, // (167, 100) + { 0, { 0, 0, 0}}, // (168, 100) + { 0, { 0, 0, 0}}, // (169, 100) + { 0, { 0, 0, 0}}, // (170, 100) + { 0, { 0, 0, 0}}, // (171, 100) + { 0, { 0, 0, 0}}, // (172, 100) + { 0, { 0, 0, 0}}, // (173, 100) + { 0, { 0, 0, 0}}, // (174, 100) + { 0, { 0, 0, 0}}, // (175, 100) + { 0, { 0, 0, 0}}, // (176, 100) + { 83, { 0, 0, 0}}, // (177, 100) + {128, { 0, 0, 0}}, // (178, 100) + {128, { 0, 0, 0}}, // (179, 100) + {128, { 0, 0, 0}}, // ( 0, 101) + {128, { 0, 0, 0}}, // ( 1, 101) + { 99, { 0, 0, 0}}, // ( 2, 101) + { 0, { 0, 0, 0}}, // ( 3, 101) + { 0, { 0, 0, 0}}, // ( 4, 101) + { 0, { 0, 0, 0}}, // ( 5, 101) + { 0, { 0, 0, 0}}, // ( 6, 101) + { 0, { 0, 0, 0}}, // ( 7, 101) + { 0, { 0, 0, 0}}, // ( 8, 101) + { 0, { 0, 0, 0}}, // ( 9, 101) + { 0, { 0, 0, 0}}, // ( 10, 101) + { 0, { 0, 0, 0}}, // ( 11, 101) + { 0, { 0, 0, 0}}, // ( 12, 101) + { 0, { 0, 0, 0}}, // ( 13, 101) + { 0, { 0, 0, 0}}, // ( 14, 101) + { 0, { 0, 0, 0}}, // ( 15, 101) + { 0, { 0, 0, 0}}, // ( 16, 101) + { 0, { 0, 0, 0}}, // ( 17, 101) + { 0, { 0, 0, 0}}, // ( 18, 101) + { 0, { 0, 0, 0}}, // ( 19, 101) + { 0, { 0, 0, 0}}, // ( 20, 101) + { 0, { 0, 0, 0}}, // ( 21, 101) + { 0, { 0, 0, 0}}, // ( 22, 101) + { 0, { 0, 0, 0}}, // ( 23, 101) + { 0, { 0, 0, 0}}, // ( 24, 101) + { 0, { 0, 0, 0}}, // ( 25, 101) + { 0, { 0, 0, 0}}, // ( 26, 101) + { 0, { 0, 0, 0}}, // ( 27, 101) + { 0, { 0, 0, 0}}, // ( 28, 101) + { 0, { 0, 0, 0}}, // ( 29, 101) + { 0, { 0, 0, 0}}, // ( 30, 101) + { 0, { 0, 0, 0}}, // ( 31, 101) + { 0, { 0, 0, 0}}, // ( 32, 101) + { 0, { 0, 0, 0}}, // ( 33, 101) + { 0, { 0, 0, 0}}, // ( 34, 101) + { 0, { 0, 0, 0}}, // ( 35, 101) + { 0, { 0, 0, 0}}, // ( 36, 101) + { 0, { 0, 0, 0}}, // ( 37, 101) + { 0, { 0, 0, 0}}, // ( 38, 101) + { 0, { 0, 0, 0}}, // ( 39, 101) + { 0, { 0, 0, 0}}, // ( 40, 101) + { 0, { 0, 0, 0}}, // ( 41, 101) + { 0, { 0, 0, 0}}, // ( 42, 101) + { 0, { 0, 0, 0}}, // ( 43, 101) + { 0, { 0, 0, 0}}, // ( 44, 101) + { 0, { 0, 0, 0}}, // ( 45, 101) + { 0, { 0, 0, 0}}, // ( 46, 101) + { 0, { 0, 0, 0}}, // ( 47, 101) + { 0, { 0, 0, 0}}, // ( 48, 101) + { 0, { 0, 0, 0}}, // ( 49, 101) + { 0, { 0, 0, 0}}, // ( 50, 101) + { 0, { 0, 0, 0}}, // ( 51, 101) + { 0, { 0, 0, 0}}, // ( 52, 101) + { 0, { 0, 0, 0}}, // ( 53, 101) + { 0, { 0, 0, 0}}, // ( 54, 101) + { 0, { 0, 0, 0}}, // ( 55, 101) + { 0, { 0, 0, 0}}, // ( 56, 101) + { 0, { 0, 0, 0}}, // ( 57, 101) + { 0, { 0, 0, 0}}, // ( 58, 101) + { 0, { 0, 0, 0}}, // ( 59, 101) + { 0, { 0, 0, 0}}, // ( 60, 101) + { 0, { 0, 0, 0}}, // ( 61, 101) + { 0, { 0, 0, 0}}, // ( 62, 101) + { 0, { 0, 0, 0}}, // ( 63, 101) + { 0, { 0, 0, 0}}, // ( 64, 101) + { 0, { 0, 0, 0}}, // ( 65, 101) + { 0, { 0, 0, 0}}, // ( 66, 101) + { 0, { 0, 0, 0}}, // ( 67, 101) + { 0, { 0, 0, 0}}, // ( 68, 101) + { 0, { 0, 0, 0}}, // ( 69, 101) + { 0, { 0, 0, 0}}, // ( 70, 101) + { 0, { 0, 0, 0}}, // ( 71, 101) + { 0, { 0, 0, 0}}, // ( 72, 101) + { 0, { 0, 0, 0}}, // ( 73, 101) + { 0, { 0, 0, 0}}, // ( 74, 101) + { 0, { 0, 0, 0}}, // ( 75, 101) + { 0, { 0, 0, 0}}, // ( 76, 101) + { 0, { 0, 0, 0}}, // ( 77, 101) + { 0, { 0, 0, 0}}, // ( 78, 101) + { 0, { 0, 0, 0}}, // ( 79, 101) + { 0, { 0, 0, 0}}, // ( 80, 101) + { 0, { 0, 0, 0}}, // ( 81, 101) + { 0, { 0, 0, 0}}, // ( 82, 101) + { 0, { 0, 0, 0}}, // ( 83, 101) + { 0, { 0, 0, 0}}, // ( 84, 101) + { 0, { 0, 0, 0}}, // ( 85, 101) + { 0, { 0, 0, 0}}, // ( 86, 101) + { 0, { 0, 0, 0}}, // ( 87, 101) + { 0, { 0, 0, 0}}, // ( 88, 101) + { 0, { 0, 0, 0}}, // ( 89, 101) + { 0, { 0, 0, 0}}, // ( 90, 101) + { 0, { 0, 0, 0}}, // ( 91, 101) + { 0, { 0, 0, 0}}, // ( 92, 101) + { 0, { 0, 0, 0}}, // ( 93, 101) + { 0, { 0, 0, 0}}, // ( 94, 101) + { 0, { 0, 0, 0}}, // ( 95, 101) + { 0, { 0, 0, 0}}, // ( 96, 101) + { 0, { 0, 0, 0}}, // ( 97, 101) + { 0, { 0, 0, 0}}, // ( 98, 101) + { 0, { 0, 0, 0}}, // ( 99, 101) + { 0, { 0, 0, 0}}, // (100, 101) + { 0, { 0, 0, 0}}, // (101, 101) + { 0, { 0, 0, 0}}, // (102, 101) + { 0, { 0, 0, 0}}, // (103, 101) + { 0, { 0, 0, 0}}, // (104, 101) + { 0, { 0, 0, 0}}, // (105, 101) + { 0, { 0, 0, 0}}, // (106, 101) + { 0, { 0, 0, 0}}, // (107, 101) + { 0, { 0, 0, 0}}, // (108, 101) + { 0, { 0, 0, 0}}, // (109, 101) + { 0, { 0, 0, 0}}, // (110, 101) + { 0, { 0, 0, 0}}, // (111, 101) + { 0, { 0, 0, 0}}, // (112, 101) + { 0, { 0, 0, 0}}, // (113, 101) + { 0, { 0, 0, 0}}, // (114, 101) + { 0, { 0, 0, 0}}, // (115, 101) + { 0, { 0, 0, 0}}, // (116, 101) + { 0, { 0, 0, 0}}, // (117, 101) + { 0, { 0, 0, 0}}, // (118, 101) + { 0, { 0, 0, 0}}, // (119, 101) + { 0, { 0, 0, 0}}, // (120, 101) + { 0, { 0, 0, 0}}, // (121, 101) + { 0, { 0, 0, 0}}, // (122, 101) + { 0, { 0, 0, 0}}, // (123, 101) + { 0, { 0, 0, 0}}, // (124, 101) + { 0, { 0, 0, 0}}, // (125, 101) + { 0, { 0, 0, 0}}, // (126, 101) + { 0, { 0, 0, 0}}, // (127, 101) + { 0, { 0, 0, 0}}, // (128, 101) + { 0, { 0, 0, 0}}, // (129, 101) + { 0, { 0, 0, 0}}, // (130, 101) + { 0, { 0, 0, 0}}, // (131, 101) + { 0, { 0, 0, 0}}, // (132, 101) + { 0, { 0, 0, 0}}, // (133, 101) + { 0, { 0, 0, 0}}, // (134, 101) + { 0, { 0, 0, 0}}, // (135, 101) + { 0, { 0, 0, 0}}, // (136, 101) + { 0, { 0, 0, 0}}, // (137, 101) + { 0, { 0, 0, 0}}, // (138, 101) + { 0, { 0, 0, 0}}, // (139, 101) + { 0, { 0, 0, 0}}, // (140, 101) + { 0, { 0, 0, 0}}, // (141, 101) + { 0, { 0, 0, 0}}, // (142, 101) + { 0, { 0, 0, 0}}, // (143, 101) + { 0, { 0, 0, 0}}, // (144, 101) + { 0, { 0, 0, 0}}, // (145, 101) + { 0, { 0, 0, 0}}, // (146, 101) + { 0, { 0, 0, 0}}, // (147, 101) + { 0, { 0, 0, 0}}, // (148, 101) + { 0, { 0, 0, 0}}, // (149, 101) + { 0, { 0, 0, 0}}, // (150, 101) + { 0, { 0, 0, 0}}, // (151, 101) + { 0, { 0, 0, 0}}, // (152, 101) + { 0, { 0, 0, 0}}, // (153, 101) + { 0, { 0, 0, 0}}, // (154, 101) + { 0, { 0, 0, 0}}, // (155, 101) + { 0, { 0, 0, 0}}, // (156, 101) + { 0, { 0, 0, 0}}, // (157, 101) + { 0, { 0, 0, 0}}, // (158, 101) + { 0, { 0, 0, 0}}, // (159, 101) + { 0, { 0, 0, 0}}, // (160, 101) + { 0, { 0, 0, 0}}, // (161, 101) + { 0, { 0, 0, 0}}, // (162, 101) + { 0, { 0, 0, 0}}, // (163, 101) + { 0, { 0, 0, 0}}, // (164, 101) + { 0, { 0, 0, 0}}, // (165, 101) + { 0, { 0, 0, 0}}, // (166, 101) + { 0, { 0, 0, 0}}, // (167, 101) + { 0, { 0, 0, 0}}, // (168, 101) + { 0, { 0, 0, 0}}, // (169, 101) + { 0, { 0, 0, 0}}, // (170, 101) + { 0, { 0, 0, 0}}, // (171, 101) + { 0, { 0, 0, 0}}, // (172, 101) + { 0, { 0, 0, 0}}, // (173, 101) + { 0, { 0, 0, 0}}, // (174, 101) + { 0, { 0, 0, 0}}, // (175, 101) + { 0, { 0, 0, 0}}, // (176, 101) + { 99, { 0, 0, 0}}, // (177, 101) + {128, { 0, 0, 0}}, // (178, 101) + {128, { 0, 0, 0}}, // (179, 101) + {128, { 0, 0, 0}}, // ( 0, 102) + {128, { 0, 0, 0}}, // ( 1, 102) + {115, { 0, 0, 0}}, // ( 2, 102) + { 0, { 0, 0, 0}}, // ( 3, 102) + { 0, { 0, 0, 0}}, // ( 4, 102) + { 0, { 0, 0, 0}}, // ( 5, 102) + { 0, { 0, 0, 0}}, // ( 6, 102) + { 0, { 0, 0, 0}}, // ( 7, 102) + { 0, { 0, 0, 0}}, // ( 8, 102) + { 0, { 0, 0, 0}}, // ( 9, 102) + { 0, { 0, 0, 0}}, // ( 10, 102) + { 0, { 0, 0, 0}}, // ( 11, 102) + { 0, { 0, 0, 0}}, // ( 12, 102) + { 0, { 0, 0, 0}}, // ( 13, 102) + { 0, { 0, 0, 0}}, // ( 14, 102) + { 0, { 0, 0, 0}}, // ( 15, 102) + { 0, { 0, 0, 0}}, // ( 16, 102) + { 0, { 0, 0, 0}}, // ( 17, 102) + { 0, { 0, 0, 0}}, // ( 18, 102) + { 0, { 0, 0, 0}}, // ( 19, 102) + { 0, { 0, 0, 0}}, // ( 20, 102) + { 0, { 0, 0, 0}}, // ( 21, 102) + { 0, { 0, 0, 0}}, // ( 22, 102) + { 0, { 0, 0, 0}}, // ( 23, 102) + { 0, { 0, 0, 0}}, // ( 24, 102) + { 0, { 0, 0, 0}}, // ( 25, 102) + { 0, { 0, 0, 0}}, // ( 26, 102) + { 0, { 0, 0, 0}}, // ( 27, 102) + { 0, { 0, 0, 0}}, // ( 28, 102) + { 0, { 0, 0, 0}}, // ( 29, 102) + { 0, { 0, 0, 0}}, // ( 30, 102) + { 0, { 0, 0, 0}}, // ( 31, 102) + { 0, { 0, 0, 0}}, // ( 32, 102) + { 0, { 0, 0, 0}}, // ( 33, 102) + { 0, { 0, 0, 0}}, // ( 34, 102) + { 0, { 0, 0, 0}}, // ( 35, 102) + { 0, { 0, 0, 0}}, // ( 36, 102) + { 0, { 0, 0, 0}}, // ( 37, 102) + { 0, { 0, 0, 0}}, // ( 38, 102) + { 0, { 0, 0, 0}}, // ( 39, 102) + { 0, { 0, 0, 0}}, // ( 40, 102) + { 0, { 0, 0, 0}}, // ( 41, 102) + { 0, { 0, 0, 0}}, // ( 42, 102) + { 0, { 0, 0, 0}}, // ( 43, 102) + { 0, { 0, 0, 0}}, // ( 44, 102) + { 0, { 0, 0, 0}}, // ( 45, 102) + { 0, { 0, 0, 0}}, // ( 46, 102) + { 0, { 0, 0, 0}}, // ( 47, 102) + { 0, { 0, 0, 0}}, // ( 48, 102) + { 0, { 0, 0, 0}}, // ( 49, 102) + { 0, { 0, 0, 0}}, // ( 50, 102) + { 0, { 0, 0, 0}}, // ( 51, 102) + { 0, { 0, 0, 0}}, // ( 52, 102) + { 0, { 0, 0, 0}}, // ( 53, 102) + { 0, { 0, 0, 0}}, // ( 54, 102) + { 0, { 0, 0, 0}}, // ( 55, 102) + { 0, { 0, 0, 0}}, // ( 56, 102) + { 0, { 0, 0, 0}}, // ( 57, 102) + { 0, { 0, 0, 0}}, // ( 58, 102) + { 0, { 0, 0, 0}}, // ( 59, 102) + { 0, { 0, 0, 0}}, // ( 60, 102) + { 0, { 0, 0, 0}}, // ( 61, 102) + { 0, { 0, 0, 0}}, // ( 62, 102) + { 0, { 0, 0, 0}}, // ( 63, 102) + { 0, { 0, 0, 0}}, // ( 64, 102) + { 0, { 0, 0, 0}}, // ( 65, 102) + { 0, { 0, 0, 0}}, // ( 66, 102) + { 0, { 0, 0, 0}}, // ( 67, 102) + { 0, { 0, 0, 0}}, // ( 68, 102) + { 0, { 0, 0, 0}}, // ( 69, 102) + { 0, { 0, 0, 0}}, // ( 70, 102) + { 0, { 0, 0, 0}}, // ( 71, 102) + { 0, { 0, 0, 0}}, // ( 72, 102) + { 0, { 0, 0, 0}}, // ( 73, 102) + { 0, { 0, 0, 0}}, // ( 74, 102) + { 0, { 0, 0, 0}}, // ( 75, 102) + { 0, { 0, 0, 0}}, // ( 76, 102) + { 0, { 0, 0, 0}}, // ( 77, 102) + { 0, { 0, 0, 0}}, // ( 78, 102) + { 0, { 0, 0, 0}}, // ( 79, 102) + { 0, { 0, 0, 0}}, // ( 80, 102) + { 0, { 0, 0, 0}}, // ( 81, 102) + { 0, { 0, 0, 0}}, // ( 82, 102) + { 0, { 0, 0, 0}}, // ( 83, 102) + { 0, { 0, 0, 0}}, // ( 84, 102) + { 0, { 0, 0, 0}}, // ( 85, 102) + { 0, { 0, 0, 0}}, // ( 86, 102) + { 0, { 0, 0, 0}}, // ( 87, 102) + { 0, { 0, 0, 0}}, // ( 88, 102) + { 0, { 0, 0, 0}}, // ( 89, 102) + { 0, { 0, 0, 0}}, // ( 90, 102) + { 0, { 0, 0, 0}}, // ( 91, 102) + { 0, { 0, 0, 0}}, // ( 92, 102) + { 0, { 0, 0, 0}}, // ( 93, 102) + { 0, { 0, 0, 0}}, // ( 94, 102) + { 0, { 0, 0, 0}}, // ( 95, 102) + { 0, { 0, 0, 0}}, // ( 96, 102) + { 0, { 0, 0, 0}}, // ( 97, 102) + { 0, { 0, 0, 0}}, // ( 98, 102) + { 0, { 0, 0, 0}}, // ( 99, 102) + { 0, { 0, 0, 0}}, // (100, 102) + { 0, { 0, 0, 0}}, // (101, 102) + { 0, { 0, 0, 0}}, // (102, 102) + { 0, { 0, 0, 0}}, // (103, 102) + { 0, { 0, 0, 0}}, // (104, 102) + { 0, { 0, 0, 0}}, // (105, 102) + { 0, { 0, 0, 0}}, // (106, 102) + { 0, { 0, 0, 0}}, // (107, 102) + { 0, { 0, 0, 0}}, // (108, 102) + { 0, { 0, 0, 0}}, // (109, 102) + { 0, { 0, 0, 0}}, // (110, 102) + { 0, { 0, 0, 0}}, // (111, 102) + { 0, { 0, 0, 0}}, // (112, 102) + { 0, { 0, 0, 0}}, // (113, 102) + { 0, { 0, 0, 0}}, // (114, 102) + { 0, { 0, 0, 0}}, // (115, 102) + { 0, { 0, 0, 0}}, // (116, 102) + { 0, { 0, 0, 0}}, // (117, 102) + { 0, { 0, 0, 0}}, // (118, 102) + { 0, { 0, 0, 0}}, // (119, 102) + { 0, { 0, 0, 0}}, // (120, 102) + { 0, { 0, 0, 0}}, // (121, 102) + { 0, { 0, 0, 0}}, // (122, 102) + { 0, { 0, 0, 0}}, // (123, 102) + { 0, { 0, 0, 0}}, // (124, 102) + { 0, { 0, 0, 0}}, // (125, 102) + { 0, { 0, 0, 0}}, // (126, 102) + { 0, { 0, 0, 0}}, // (127, 102) + { 0, { 0, 0, 0}}, // (128, 102) + { 0, { 0, 0, 0}}, // (129, 102) + { 0, { 0, 0, 0}}, // (130, 102) + { 0, { 0, 0, 0}}, // (131, 102) + { 0, { 0, 0, 0}}, // (132, 102) + { 0, { 0, 0, 0}}, // (133, 102) + { 0, { 0, 0, 0}}, // (134, 102) + { 0, { 0, 0, 0}}, // (135, 102) + { 0, { 0, 0, 0}}, // (136, 102) + { 0, { 0, 0, 0}}, // (137, 102) + { 0, { 0, 0, 0}}, // (138, 102) + { 0, { 0, 0, 0}}, // (139, 102) + { 0, { 0, 0, 0}}, // (140, 102) + { 0, { 0, 0, 0}}, // (141, 102) + { 0, { 0, 0, 0}}, // (142, 102) + { 0, { 0, 0, 0}}, // (143, 102) + { 0, { 0, 0, 0}}, // (144, 102) + { 0, { 0, 0, 0}}, // (145, 102) + { 0, { 0, 0, 0}}, // (146, 102) + { 0, { 0, 0, 0}}, // (147, 102) + { 0, { 0, 0, 0}}, // (148, 102) + { 0, { 0, 0, 0}}, // (149, 102) + { 0, { 0, 0, 0}}, // (150, 102) + { 0, { 0, 0, 0}}, // (151, 102) + { 0, { 0, 0, 0}}, // (152, 102) + { 0, { 0, 0, 0}}, // (153, 102) + { 0, { 0, 0, 0}}, // (154, 102) + { 0, { 0, 0, 0}}, // (155, 102) + { 0, { 0, 0, 0}}, // (156, 102) + { 0, { 0, 0, 0}}, // (157, 102) + { 0, { 0, 0, 0}}, // (158, 102) + { 0, { 0, 0, 0}}, // (159, 102) + { 0, { 0, 0, 0}}, // (160, 102) + { 0, { 0, 0, 0}}, // (161, 102) + { 0, { 0, 0, 0}}, // (162, 102) + { 0, { 0, 0, 0}}, // (163, 102) + { 0, { 0, 0, 0}}, // (164, 102) + { 0, { 0, 0, 0}}, // (165, 102) + { 0, { 0, 0, 0}}, // (166, 102) + { 0, { 0, 0, 0}}, // (167, 102) + { 0, { 0, 0, 0}}, // (168, 102) + { 0, { 0, 0, 0}}, // (169, 102) + { 0, { 0, 0, 0}}, // (170, 102) + { 0, { 0, 0, 0}}, // (171, 102) + { 0, { 0, 0, 0}}, // (172, 102) + { 0, { 0, 0, 0}}, // (173, 102) + { 0, { 0, 0, 0}}, // (174, 102) + { 0, { 0, 0, 0}}, // (175, 102) + { 0, { 0, 0, 0}}, // (176, 102) + {115, { 0, 0, 0}}, // (177, 102) + {128, { 0, 0, 0}}, // (178, 102) + {128, { 0, 0, 0}}, // (179, 102) + {128, { 0, 0, 0}}, // ( 0, 103) + {128, { 0, 0, 0}}, // ( 1, 103) + {127, { 0, 0, 0}}, // ( 2, 103) + { 6, { 0, 0, 0}}, // ( 3, 103) + { 0, { 0, 0, 0}}, // ( 4, 103) + { 0, { 0, 0, 0}}, // ( 5, 103) + { 0, { 0, 0, 0}}, // ( 6, 103) + { 0, { 0, 0, 0}}, // ( 7, 103) + { 0, { 0, 0, 0}}, // ( 8, 103) + { 0, { 0, 0, 0}}, // ( 9, 103) + { 0, { 0, 0, 0}}, // ( 10, 103) + { 0, { 0, 0, 0}}, // ( 11, 103) + { 0, { 0, 0, 0}}, // ( 12, 103) + { 0, { 0, 0, 0}}, // ( 13, 103) + { 0, { 0, 0, 0}}, // ( 14, 103) + { 0, { 0, 0, 0}}, // ( 15, 103) + { 0, { 0, 0, 0}}, // ( 16, 103) + { 0, { 0, 0, 0}}, // ( 17, 103) + { 0, { 0, 0, 0}}, // ( 18, 103) + { 0, { 0, 0, 0}}, // ( 19, 103) + { 0, { 0, 0, 0}}, // ( 20, 103) + { 0, { 0, 0, 0}}, // ( 21, 103) + { 0, { 0, 0, 0}}, // ( 22, 103) + { 0, { 0, 0, 0}}, // ( 23, 103) + { 0, { 0, 0, 0}}, // ( 24, 103) + { 0, { 0, 0, 0}}, // ( 25, 103) + { 0, { 0, 0, 0}}, // ( 26, 103) + { 0, { 0, 0, 0}}, // ( 27, 103) + { 0, { 0, 0, 0}}, // ( 28, 103) + { 0, { 0, 0, 0}}, // ( 29, 103) + { 0, { 0, 0, 0}}, // ( 30, 103) + { 0, { 0, 0, 0}}, // ( 31, 103) + { 0, { 0, 0, 0}}, // ( 32, 103) + { 0, { 0, 0, 0}}, // ( 33, 103) + { 0, { 0, 0, 0}}, // ( 34, 103) + { 0, { 0, 0, 0}}, // ( 35, 103) + { 0, { 0, 0, 0}}, // ( 36, 103) + { 0, { 0, 0, 0}}, // ( 37, 103) + { 0, { 0, 0, 0}}, // ( 38, 103) + { 0, { 0, 0, 0}}, // ( 39, 103) + { 0, { 0, 0, 0}}, // ( 40, 103) + { 0, { 0, 0, 0}}, // ( 41, 103) + { 0, { 0, 0, 0}}, // ( 42, 103) + { 0, { 0, 0, 0}}, // ( 43, 103) + { 0, { 0, 0, 0}}, // ( 44, 103) + { 0, { 0, 0, 0}}, // ( 45, 103) + { 0, { 0, 0, 0}}, // ( 46, 103) + { 0, { 0, 0, 0}}, // ( 47, 103) + { 0, { 0, 0, 0}}, // ( 48, 103) + { 0, { 0, 0, 0}}, // ( 49, 103) + { 0, { 0, 0, 0}}, // ( 50, 103) + { 0, { 0, 0, 0}}, // ( 51, 103) + { 0, { 0, 0, 0}}, // ( 52, 103) + { 0, { 0, 0, 0}}, // ( 53, 103) + { 0, { 0, 0, 0}}, // ( 54, 103) + { 0, { 0, 0, 0}}, // ( 55, 103) + { 0, { 0, 0, 0}}, // ( 56, 103) + { 0, { 0, 0, 0}}, // ( 57, 103) + { 0, { 0, 0, 0}}, // ( 58, 103) + { 0, { 0, 0, 0}}, // ( 59, 103) + { 0, { 0, 0, 0}}, // ( 60, 103) + { 0, { 0, 0, 0}}, // ( 61, 103) + { 0, { 0, 0, 0}}, // ( 62, 103) + { 0, { 0, 0, 0}}, // ( 63, 103) + { 0, { 0, 0, 0}}, // ( 64, 103) + { 0, { 0, 0, 0}}, // ( 65, 103) + { 0, { 0, 0, 0}}, // ( 66, 103) + { 0, { 0, 0, 0}}, // ( 67, 103) + { 0, { 0, 0, 0}}, // ( 68, 103) + { 0, { 0, 0, 0}}, // ( 69, 103) + { 0, { 0, 0, 0}}, // ( 70, 103) + { 0, { 0, 0, 0}}, // ( 71, 103) + { 0, { 0, 0, 0}}, // ( 72, 103) + { 0, { 0, 0, 0}}, // ( 73, 103) + { 0, { 0, 0, 0}}, // ( 74, 103) + { 0, { 0, 0, 0}}, // ( 75, 103) + { 0, { 0, 0, 0}}, // ( 76, 103) + { 0, { 0, 0, 0}}, // ( 77, 103) + { 0, { 0, 0, 0}}, // ( 78, 103) + { 0, { 0, 0, 0}}, // ( 79, 103) + { 0, { 0, 0, 0}}, // ( 80, 103) + { 0, { 0, 0, 0}}, // ( 81, 103) + { 0, { 0, 0, 0}}, // ( 82, 103) + { 0, { 0, 0, 0}}, // ( 83, 103) + { 0, { 0, 0, 0}}, // ( 84, 103) + { 0, { 0, 0, 0}}, // ( 85, 103) + { 0, { 0, 0, 0}}, // ( 86, 103) + { 0, { 0, 0, 0}}, // ( 87, 103) + { 0, { 0, 0, 0}}, // ( 88, 103) + { 0, { 0, 0, 0}}, // ( 89, 103) + { 0, { 0, 0, 0}}, // ( 90, 103) + { 0, { 0, 0, 0}}, // ( 91, 103) + { 0, { 0, 0, 0}}, // ( 92, 103) + { 0, { 0, 0, 0}}, // ( 93, 103) + { 0, { 0, 0, 0}}, // ( 94, 103) + { 0, { 0, 0, 0}}, // ( 95, 103) + { 0, { 0, 0, 0}}, // ( 96, 103) + { 0, { 0, 0, 0}}, // ( 97, 103) + { 0, { 0, 0, 0}}, // ( 98, 103) + { 0, { 0, 0, 0}}, // ( 99, 103) + { 0, { 0, 0, 0}}, // (100, 103) + { 0, { 0, 0, 0}}, // (101, 103) + { 0, { 0, 0, 0}}, // (102, 103) + { 0, { 0, 0, 0}}, // (103, 103) + { 0, { 0, 0, 0}}, // (104, 103) + { 0, { 0, 0, 0}}, // (105, 103) + { 0, { 0, 0, 0}}, // (106, 103) + { 0, { 0, 0, 0}}, // (107, 103) + { 0, { 0, 0, 0}}, // (108, 103) + { 0, { 0, 0, 0}}, // (109, 103) + { 0, { 0, 0, 0}}, // (110, 103) + { 0, { 0, 0, 0}}, // (111, 103) + { 0, { 0, 0, 0}}, // (112, 103) + { 0, { 0, 0, 0}}, // (113, 103) + { 0, { 0, 0, 0}}, // (114, 103) + { 0, { 0, 0, 0}}, // (115, 103) + { 0, { 0, 0, 0}}, // (116, 103) + { 0, { 0, 0, 0}}, // (117, 103) + { 0, { 0, 0, 0}}, // (118, 103) + { 0, { 0, 0, 0}}, // (119, 103) + { 0, { 0, 0, 0}}, // (120, 103) + { 0, { 0, 0, 0}}, // (121, 103) + { 0, { 0, 0, 0}}, // (122, 103) + { 0, { 0, 0, 0}}, // (123, 103) + { 0, { 0, 0, 0}}, // (124, 103) + { 0, { 0, 0, 0}}, // (125, 103) + { 0, { 0, 0, 0}}, // (126, 103) + { 0, { 0, 0, 0}}, // (127, 103) + { 0, { 0, 0, 0}}, // (128, 103) + { 0, { 0, 0, 0}}, // (129, 103) + { 0, { 0, 0, 0}}, // (130, 103) + { 0, { 0, 0, 0}}, // (131, 103) + { 0, { 0, 0, 0}}, // (132, 103) + { 0, { 0, 0, 0}}, // (133, 103) + { 0, { 0, 0, 0}}, // (134, 103) + { 0, { 0, 0, 0}}, // (135, 103) + { 0, { 0, 0, 0}}, // (136, 103) + { 0, { 0, 0, 0}}, // (137, 103) + { 0, { 0, 0, 0}}, // (138, 103) + { 0, { 0, 0, 0}}, // (139, 103) + { 0, { 0, 0, 0}}, // (140, 103) + { 0, { 0, 0, 0}}, // (141, 103) + { 0, { 0, 0, 0}}, // (142, 103) + { 0, { 0, 0, 0}}, // (143, 103) + { 0, { 0, 0, 0}}, // (144, 103) + { 0, { 0, 0, 0}}, // (145, 103) + { 0, { 0, 0, 0}}, // (146, 103) + { 0, { 0, 0, 0}}, // (147, 103) + { 0, { 0, 0, 0}}, // (148, 103) + { 0, { 0, 0, 0}}, // (149, 103) + { 0, { 0, 0, 0}}, // (150, 103) + { 0, { 0, 0, 0}}, // (151, 103) + { 0, { 0, 0, 0}}, // (152, 103) + { 0, { 0, 0, 0}}, // (153, 103) + { 0, { 0, 0, 0}}, // (154, 103) + { 0, { 0, 0, 0}}, // (155, 103) + { 0, { 0, 0, 0}}, // (156, 103) + { 0, { 0, 0, 0}}, // (157, 103) + { 0, { 0, 0, 0}}, // (158, 103) + { 0, { 0, 0, 0}}, // (159, 103) + { 0, { 0, 0, 0}}, // (160, 103) + { 0, { 0, 0, 0}}, // (161, 103) + { 0, { 0, 0, 0}}, // (162, 103) + { 0, { 0, 0, 0}}, // (163, 103) + { 0, { 0, 0, 0}}, // (164, 103) + { 0, { 0, 0, 0}}, // (165, 103) + { 0, { 0, 0, 0}}, // (166, 103) + { 0, { 0, 0, 0}}, // (167, 103) + { 0, { 0, 0, 0}}, // (168, 103) + { 0, { 0, 0, 0}}, // (169, 103) + { 0, { 0, 0, 0}}, // (170, 103) + { 0, { 0, 0, 0}}, // (171, 103) + { 0, { 0, 0, 0}}, // (172, 103) + { 0, { 0, 0, 0}}, // (173, 103) + { 0, { 0, 0, 0}}, // (174, 103) + { 0, { 0, 0, 0}}, // (175, 103) + { 5, { 0, 0, 0}}, // (176, 103) + {127, { 0, 0, 0}}, // (177, 103) + {128, { 0, 0, 0}}, // (178, 103) + {128, { 0, 0, 0}}, // (179, 103) + {128, { 0, 0, 0}}, // ( 0, 104) + {128, { 0, 0, 0}}, // ( 1, 104) + {128, { 0, 0, 0}}, // ( 2, 104) + { 27, { 0, 0, 0}}, // ( 3, 104) + { 0, { 0, 0, 0}}, // ( 4, 104) + { 0, { 0, 0, 0}}, // ( 5, 104) + { 0, { 0, 0, 0}}, // ( 6, 104) + { 0, { 0, 0, 0}}, // ( 7, 104) + { 0, { 0, 0, 0}}, // ( 8, 104) + { 0, { 0, 0, 0}}, // ( 9, 104) + { 0, { 0, 0, 0}}, // ( 10, 104) + { 0, { 0, 0, 0}}, // ( 11, 104) + { 0, { 0, 0, 0}}, // ( 12, 104) + { 0, { 0, 0, 0}}, // ( 13, 104) + { 0, { 0, 0, 0}}, // ( 14, 104) + { 0, { 0, 0, 0}}, // ( 15, 104) + { 0, { 0, 0, 0}}, // ( 16, 104) + { 0, { 0, 0, 0}}, // ( 17, 104) + { 0, { 0, 0, 0}}, // ( 18, 104) + { 0, { 0, 0, 0}}, // ( 19, 104) + { 0, { 0, 0, 0}}, // ( 20, 104) + { 0, { 0, 0, 0}}, // ( 21, 104) + { 0, { 0, 0, 0}}, // ( 22, 104) + { 0, { 0, 0, 0}}, // ( 23, 104) + { 0, { 0, 0, 0}}, // ( 24, 104) + { 0, { 0, 0, 0}}, // ( 25, 104) + { 0, { 0, 0, 0}}, // ( 26, 104) + { 0, { 0, 0, 0}}, // ( 27, 104) + { 0, { 0, 0, 0}}, // ( 28, 104) + { 0, { 0, 0, 0}}, // ( 29, 104) + { 0, { 0, 0, 0}}, // ( 30, 104) + { 0, { 0, 0, 0}}, // ( 31, 104) + { 0, { 0, 0, 0}}, // ( 32, 104) + { 0, { 0, 0, 0}}, // ( 33, 104) + { 0, { 0, 0, 0}}, // ( 34, 104) + { 0, { 0, 0, 0}}, // ( 35, 104) + { 0, { 0, 0, 0}}, // ( 36, 104) + { 0, { 0, 0, 0}}, // ( 37, 104) + { 0, { 0, 0, 0}}, // ( 38, 104) + { 0, { 0, 0, 0}}, // ( 39, 104) + { 0, { 0, 0, 0}}, // ( 40, 104) + { 0, { 0, 0, 0}}, // ( 41, 104) + { 0, { 0, 0, 0}}, // ( 42, 104) + { 0, { 0, 0, 0}}, // ( 43, 104) + { 0, { 0, 0, 0}}, // ( 44, 104) + { 0, { 0, 0, 0}}, // ( 45, 104) + { 0, { 0, 0, 0}}, // ( 46, 104) + { 0, { 0, 0, 0}}, // ( 47, 104) + { 0, { 0, 0, 0}}, // ( 48, 104) + { 0, { 0, 0, 0}}, // ( 49, 104) + { 0, { 0, 0, 0}}, // ( 50, 104) + { 0, { 0, 0, 0}}, // ( 51, 104) + { 0, { 0, 0, 0}}, // ( 52, 104) + { 0, { 0, 0, 0}}, // ( 53, 104) + { 0, { 0, 0, 0}}, // ( 54, 104) + { 0, { 0, 0, 0}}, // ( 55, 104) + { 0, { 0, 0, 0}}, // ( 56, 104) + { 0, { 0, 0, 0}}, // ( 57, 104) + { 0, { 0, 0, 0}}, // ( 58, 104) + { 0, { 0, 0, 0}}, // ( 59, 104) + { 0, { 0, 0, 0}}, // ( 60, 104) + { 0, { 0, 0, 0}}, // ( 61, 104) + { 0, { 0, 0, 0}}, // ( 62, 104) + { 0, { 0, 0, 0}}, // ( 63, 104) + { 0, { 0, 0, 0}}, // ( 64, 104) + { 0, { 0, 0, 0}}, // ( 65, 104) + { 0, { 0, 0, 0}}, // ( 66, 104) + { 0, { 0, 0, 0}}, // ( 67, 104) + { 0, { 0, 0, 0}}, // ( 68, 104) + { 0, { 0, 0, 0}}, // ( 69, 104) + { 0, { 0, 0, 0}}, // ( 70, 104) + { 0, { 0, 0, 0}}, // ( 71, 104) + { 0, { 0, 0, 0}}, // ( 72, 104) + { 0, { 0, 0, 0}}, // ( 73, 104) + { 0, { 0, 0, 0}}, // ( 74, 104) + { 0, { 0, 0, 0}}, // ( 75, 104) + { 0, { 0, 0, 0}}, // ( 76, 104) + { 0, { 0, 0, 0}}, // ( 77, 104) + { 0, { 0, 0, 0}}, // ( 78, 104) + { 0, { 0, 0, 0}}, // ( 79, 104) + { 0, { 0, 0, 0}}, // ( 80, 104) + { 0, { 0, 0, 0}}, // ( 81, 104) + { 0, { 0, 0, 0}}, // ( 82, 104) + { 0, { 0, 0, 0}}, // ( 83, 104) + { 0, { 0, 0, 0}}, // ( 84, 104) + { 0, { 0, 0, 0}}, // ( 85, 104) + { 0, { 0, 0, 0}}, // ( 86, 104) + { 0, { 0, 0, 0}}, // ( 87, 104) + { 0, { 0, 0, 0}}, // ( 88, 104) + { 0, { 0, 0, 0}}, // ( 89, 104) + { 0, { 0, 0, 0}}, // ( 90, 104) + { 0, { 0, 0, 0}}, // ( 91, 104) + { 0, { 0, 0, 0}}, // ( 92, 104) + { 0, { 0, 0, 0}}, // ( 93, 104) + { 0, { 0, 0, 0}}, // ( 94, 104) + { 0, { 0, 0, 0}}, // ( 95, 104) + { 0, { 0, 0, 0}}, // ( 96, 104) + { 0, { 0, 0, 0}}, // ( 97, 104) + { 0, { 0, 0, 0}}, // ( 98, 104) + { 0, { 0, 0, 0}}, // ( 99, 104) + { 0, { 0, 0, 0}}, // (100, 104) + { 0, { 0, 0, 0}}, // (101, 104) + { 0, { 0, 0, 0}}, // (102, 104) + { 0, { 0, 0, 0}}, // (103, 104) + { 0, { 0, 0, 0}}, // (104, 104) + { 0, { 0, 0, 0}}, // (105, 104) + { 0, { 0, 0, 0}}, // (106, 104) + { 0, { 0, 0, 0}}, // (107, 104) + { 0, { 0, 0, 0}}, // (108, 104) + { 0, { 0, 0, 0}}, // (109, 104) + { 0, { 0, 0, 0}}, // (110, 104) + { 0, { 0, 0, 0}}, // (111, 104) + { 0, { 0, 0, 0}}, // (112, 104) + { 0, { 0, 0, 0}}, // (113, 104) + { 0, { 0, 0, 0}}, // (114, 104) + { 0, { 0, 0, 0}}, // (115, 104) + { 0, { 0, 0, 0}}, // (116, 104) + { 0, { 0, 0, 0}}, // (117, 104) + { 0, { 0, 0, 0}}, // (118, 104) + { 0, { 0, 0, 0}}, // (119, 104) + { 0, { 0, 0, 0}}, // (120, 104) + { 0, { 0, 0, 0}}, // (121, 104) + { 0, { 0, 0, 0}}, // (122, 104) + { 0, { 0, 0, 0}}, // (123, 104) + { 0, { 0, 0, 0}}, // (124, 104) + { 0, { 0, 0, 0}}, // (125, 104) + { 0, { 0, 0, 0}}, // (126, 104) + { 0, { 0, 0, 0}}, // (127, 104) + { 0, { 0, 0, 0}}, // (128, 104) + { 0, { 0, 0, 0}}, // (129, 104) + { 0, { 0, 0, 0}}, // (130, 104) + { 0, { 0, 0, 0}}, // (131, 104) + { 0, { 0, 0, 0}}, // (132, 104) + { 0, { 0, 0, 0}}, // (133, 104) + { 0, { 0, 0, 0}}, // (134, 104) + { 0, { 0, 0, 0}}, // (135, 104) + { 0, { 0, 0, 0}}, // (136, 104) + { 0, { 0, 0, 0}}, // (137, 104) + { 0, { 0, 0, 0}}, // (138, 104) + { 0, { 0, 0, 0}}, // (139, 104) + { 0, { 0, 0, 0}}, // (140, 104) + { 0, { 0, 0, 0}}, // (141, 104) + { 0, { 0, 0, 0}}, // (142, 104) + { 0, { 0, 0, 0}}, // (143, 104) + { 0, { 0, 0, 0}}, // (144, 104) + { 0, { 0, 0, 0}}, // (145, 104) + { 0, { 0, 0, 0}}, // (146, 104) + { 0, { 0, 0, 0}}, // (147, 104) + { 0, { 0, 0, 0}}, // (148, 104) + { 0, { 0, 0, 0}}, // (149, 104) + { 0, { 0, 0, 0}}, // (150, 104) + { 0, { 0, 0, 0}}, // (151, 104) + { 0, { 0, 0, 0}}, // (152, 104) + { 0, { 0, 0, 0}}, // (153, 104) + { 0, { 0, 0, 0}}, // (154, 104) + { 0, { 0, 0, 0}}, // (155, 104) + { 0, { 0, 0, 0}}, // (156, 104) + { 0, { 0, 0, 0}}, // (157, 104) + { 0, { 0, 0, 0}}, // (158, 104) + { 0, { 0, 0, 0}}, // (159, 104) + { 0, { 0, 0, 0}}, // (160, 104) + { 0, { 0, 0, 0}}, // (161, 104) + { 0, { 0, 0, 0}}, // (162, 104) + { 0, { 0, 0, 0}}, // (163, 104) + { 0, { 0, 0, 0}}, // (164, 104) + { 0, { 0, 0, 0}}, // (165, 104) + { 0, { 0, 0, 0}}, // (166, 104) + { 0, { 0, 0, 0}}, // (167, 104) + { 0, { 0, 0, 0}}, // (168, 104) + { 0, { 0, 0, 0}}, // (169, 104) + { 0, { 0, 0, 0}}, // (170, 104) + { 0, { 0, 0, 0}}, // (171, 104) + { 0, { 0, 0, 0}}, // (172, 104) + { 0, { 0, 0, 0}}, // (173, 104) + { 0, { 0, 0, 0}}, // (174, 104) + { 0, { 0, 0, 0}}, // (175, 104) + { 25, { 0, 0, 0}}, // (176, 104) + {128, { 0, 0, 0}}, // (177, 104) + {128, { 0, 0, 0}}, // (178, 104) + {128, { 0, 0, 0}}, // (179, 104) + {128, { 0, 0, 0}}, // ( 0, 105) + {128, { 0, 0, 0}}, // ( 1, 105) + {128, { 0, 0, 0}}, // ( 2, 105) + { 50, { 0, 0, 0}}, // ( 3, 105) + { 0, { 0, 0, 0}}, // ( 4, 105) + { 0, { 0, 0, 0}}, // ( 5, 105) + { 0, { 0, 0, 0}}, // ( 6, 105) + { 0, { 0, 0, 0}}, // ( 7, 105) + { 0, { 0, 0, 0}}, // ( 8, 105) + { 0, { 0, 0, 0}}, // ( 9, 105) + { 0, { 0, 0, 0}}, // ( 10, 105) + { 0, { 0, 0, 0}}, // ( 11, 105) + { 0, { 0, 0, 0}}, // ( 12, 105) + { 0, { 0, 0, 0}}, // ( 13, 105) + { 0, { 0, 0, 0}}, // ( 14, 105) + { 0, { 0, 0, 0}}, // ( 15, 105) + { 0, { 0, 0, 0}}, // ( 16, 105) + { 0, { 0, 0, 0}}, // ( 17, 105) + { 0, { 0, 0, 0}}, // ( 18, 105) + { 0, { 0, 0, 0}}, // ( 19, 105) + { 0, { 0, 0, 0}}, // ( 20, 105) + { 0, { 0, 0, 0}}, // ( 21, 105) + { 0, { 0, 0, 0}}, // ( 22, 105) + { 0, { 0, 0, 0}}, // ( 23, 105) + { 0, { 0, 0, 0}}, // ( 24, 105) + { 0, { 0, 0, 0}}, // ( 25, 105) + { 0, { 0, 0, 0}}, // ( 26, 105) + { 0, { 0, 0, 0}}, // ( 27, 105) + { 0, { 0, 0, 0}}, // ( 28, 105) + { 0, { 0, 0, 0}}, // ( 29, 105) + { 0, { 0, 0, 0}}, // ( 30, 105) + { 0, { 0, 0, 0}}, // ( 31, 105) + { 0, { 0, 0, 0}}, // ( 32, 105) + { 0, { 0, 0, 0}}, // ( 33, 105) + { 0, { 0, 0, 0}}, // ( 34, 105) + { 0, { 0, 0, 0}}, // ( 35, 105) + { 0, { 0, 0, 0}}, // ( 36, 105) + { 0, { 0, 0, 0}}, // ( 37, 105) + { 0, { 0, 0, 0}}, // ( 38, 105) + { 0, { 0, 0, 0}}, // ( 39, 105) + { 0, { 0, 0, 0}}, // ( 40, 105) + { 0, { 0, 0, 0}}, // ( 41, 105) + { 0, { 0, 0, 0}}, // ( 42, 105) + { 0, { 0, 0, 0}}, // ( 43, 105) + { 0, { 0, 0, 0}}, // ( 44, 105) + { 0, { 0, 0, 0}}, // ( 45, 105) + { 0, { 0, 0, 0}}, // ( 46, 105) + { 0, { 0, 0, 0}}, // ( 47, 105) + { 0, { 0, 0, 0}}, // ( 48, 105) + { 0, { 0, 0, 0}}, // ( 49, 105) + { 0, { 0, 0, 0}}, // ( 50, 105) + { 0, { 0, 0, 0}}, // ( 51, 105) + { 0, { 0, 0, 0}}, // ( 52, 105) + { 0, { 0, 0, 0}}, // ( 53, 105) + { 0, { 0, 0, 0}}, // ( 54, 105) + { 0, { 0, 0, 0}}, // ( 55, 105) + { 0, { 0, 0, 0}}, // ( 56, 105) + { 0, { 0, 0, 0}}, // ( 57, 105) + { 0, { 0, 0, 0}}, // ( 58, 105) + { 0, { 0, 0, 0}}, // ( 59, 105) + { 0, { 0, 0, 0}}, // ( 60, 105) + { 0, { 0, 0, 0}}, // ( 61, 105) + { 0, { 0, 0, 0}}, // ( 62, 105) + { 0, { 0, 0, 0}}, // ( 63, 105) + { 0, { 0, 0, 0}}, // ( 64, 105) + { 0, { 0, 0, 0}}, // ( 65, 105) + { 0, { 0, 0, 0}}, // ( 66, 105) + { 0, { 0, 0, 0}}, // ( 67, 105) + { 0, { 0, 0, 0}}, // ( 68, 105) + { 0, { 0, 0, 0}}, // ( 69, 105) + { 0, { 0, 0, 0}}, // ( 70, 105) + { 0, { 0, 0, 0}}, // ( 71, 105) + { 0, { 0, 0, 0}}, // ( 72, 105) + { 0, { 0, 0, 0}}, // ( 73, 105) + { 0, { 0, 0, 0}}, // ( 74, 105) + { 0, { 0, 0, 0}}, // ( 75, 105) + { 0, { 0, 0, 0}}, // ( 76, 105) + { 0, { 0, 0, 0}}, // ( 77, 105) + { 0, { 0, 0, 0}}, // ( 78, 105) + { 0, { 0, 0, 0}}, // ( 79, 105) + { 0, { 0, 0, 0}}, // ( 80, 105) + { 0, { 0, 0, 0}}, // ( 81, 105) + { 0, { 0, 0, 0}}, // ( 82, 105) + { 0, { 0, 0, 0}}, // ( 83, 105) + { 0, { 0, 0, 0}}, // ( 84, 105) + { 0, { 0, 0, 0}}, // ( 85, 105) + { 0, { 0, 0, 0}}, // ( 86, 105) + { 0, { 0, 0, 0}}, // ( 87, 105) + { 0, { 0, 0, 0}}, // ( 88, 105) + { 0, { 0, 0, 0}}, // ( 89, 105) + { 0, { 0, 0, 0}}, // ( 90, 105) + { 0, { 0, 0, 0}}, // ( 91, 105) + { 0, { 0, 0, 0}}, // ( 92, 105) + { 0, { 0, 0, 0}}, // ( 93, 105) + { 0, { 0, 0, 0}}, // ( 94, 105) + { 0, { 0, 0, 0}}, // ( 95, 105) + { 0, { 0, 0, 0}}, // ( 96, 105) + { 0, { 0, 0, 0}}, // ( 97, 105) + { 0, { 0, 0, 0}}, // ( 98, 105) + { 0, { 0, 0, 0}}, // ( 99, 105) + { 0, { 0, 0, 0}}, // (100, 105) + { 0, { 0, 0, 0}}, // (101, 105) + { 0, { 0, 0, 0}}, // (102, 105) + { 0, { 0, 0, 0}}, // (103, 105) + { 0, { 0, 0, 0}}, // (104, 105) + { 0, { 0, 0, 0}}, // (105, 105) + { 0, { 0, 0, 0}}, // (106, 105) + { 0, { 0, 0, 0}}, // (107, 105) + { 0, { 0, 0, 0}}, // (108, 105) + { 0, { 0, 0, 0}}, // (109, 105) + { 0, { 0, 0, 0}}, // (110, 105) + { 0, { 0, 0, 0}}, // (111, 105) + { 0, { 0, 0, 0}}, // (112, 105) + { 0, { 0, 0, 0}}, // (113, 105) + { 0, { 0, 0, 0}}, // (114, 105) + { 0, { 0, 0, 0}}, // (115, 105) + { 0, { 0, 0, 0}}, // (116, 105) + { 0, { 0, 0, 0}}, // (117, 105) + { 0, { 0, 0, 0}}, // (118, 105) + { 0, { 0, 0, 0}}, // (119, 105) + { 0, { 0, 0, 0}}, // (120, 105) + { 0, { 0, 0, 0}}, // (121, 105) + { 0, { 0, 0, 0}}, // (122, 105) + { 0, { 0, 0, 0}}, // (123, 105) + { 0, { 0, 0, 0}}, // (124, 105) + { 0, { 0, 0, 0}}, // (125, 105) + { 0, { 0, 0, 0}}, // (126, 105) + { 0, { 0, 0, 0}}, // (127, 105) + { 0, { 0, 0, 0}}, // (128, 105) + { 0, { 0, 0, 0}}, // (129, 105) + { 0, { 0, 0, 0}}, // (130, 105) + { 0, { 0, 0, 0}}, // (131, 105) + { 0, { 0, 0, 0}}, // (132, 105) + { 0, { 0, 0, 0}}, // (133, 105) + { 0, { 0, 0, 0}}, // (134, 105) + { 0, { 0, 0, 0}}, // (135, 105) + { 0, { 0, 0, 0}}, // (136, 105) + { 0, { 0, 0, 0}}, // (137, 105) + { 0, { 0, 0, 0}}, // (138, 105) + { 0, { 0, 0, 0}}, // (139, 105) + { 0, { 0, 0, 0}}, // (140, 105) + { 0, { 0, 0, 0}}, // (141, 105) + { 0, { 0, 0, 0}}, // (142, 105) + { 0, { 0, 0, 0}}, // (143, 105) + { 0, { 0, 0, 0}}, // (144, 105) + { 0, { 0, 0, 0}}, // (145, 105) + { 0, { 0, 0, 0}}, // (146, 105) + { 0, { 0, 0, 0}}, // (147, 105) + { 0, { 0, 0, 0}}, // (148, 105) + { 0, { 0, 0, 0}}, // (149, 105) + { 0, { 0, 0, 0}}, // (150, 105) + { 0, { 0, 0, 0}}, // (151, 105) + { 0, { 0, 0, 0}}, // (152, 105) + { 0, { 0, 0, 0}}, // (153, 105) + { 0, { 0, 0, 0}}, // (154, 105) + { 0, { 0, 0, 0}}, // (155, 105) + { 0, { 0, 0, 0}}, // (156, 105) + { 0, { 0, 0, 0}}, // (157, 105) + { 0, { 0, 0, 0}}, // (158, 105) + { 0, { 0, 0, 0}}, // (159, 105) + { 0, { 0, 0, 0}}, // (160, 105) + { 0, { 0, 0, 0}}, // (161, 105) + { 0, { 0, 0, 0}}, // (162, 105) + { 0, { 0, 0, 0}}, // (163, 105) + { 0, { 0, 0, 0}}, // (164, 105) + { 0, { 0, 0, 0}}, // (165, 105) + { 0, { 0, 0, 0}}, // (166, 105) + { 0, { 0, 0, 0}}, // (167, 105) + { 0, { 0, 0, 0}}, // (168, 105) + { 0, { 0, 0, 0}}, // (169, 105) + { 0, { 0, 0, 0}}, // (170, 105) + { 0, { 0, 0, 0}}, // (171, 105) + { 0, { 0, 0, 0}}, // (172, 105) + { 0, { 0, 0, 0}}, // (173, 105) + { 0, { 0, 0, 0}}, // (174, 105) + { 0, { 0, 0, 0}}, // (175, 105) + { 47, { 0, 0, 0}}, // (176, 105) + {128, { 0, 0, 0}}, // (177, 105) + {128, { 0, 0, 0}}, // (178, 105) + {128, { 0, 0, 0}}, // (179, 105) + {128, { 0, 0, 0}}, // ( 0, 106) + {128, { 0, 0, 0}}, // ( 1, 106) + {128, { 0, 0, 0}}, // ( 2, 106) + { 72, { 0, 0, 0}}, // ( 3, 106) + { 0, { 0, 0, 0}}, // ( 4, 106) + { 0, { 0, 0, 0}}, // ( 5, 106) + { 0, { 0, 0, 0}}, // ( 6, 106) + { 0, { 0, 0, 0}}, // ( 7, 106) + { 0, { 0, 0, 0}}, // ( 8, 106) + { 0, { 0, 0, 0}}, // ( 9, 106) + { 0, { 0, 0, 0}}, // ( 10, 106) + { 0, { 0, 0, 0}}, // ( 11, 106) + { 0, { 0, 0, 0}}, // ( 12, 106) + { 0, { 0, 0, 0}}, // ( 13, 106) + { 0, { 0, 0, 0}}, // ( 14, 106) + { 0, { 0, 0, 0}}, // ( 15, 106) + { 0, { 0, 0, 0}}, // ( 16, 106) + { 0, { 0, 0, 0}}, // ( 17, 106) + { 0, { 0, 0, 0}}, // ( 18, 106) + { 0, { 0, 0, 0}}, // ( 19, 106) + { 0, { 0, 0, 0}}, // ( 20, 106) + { 0, { 0, 0, 0}}, // ( 21, 106) + { 0, { 0, 0, 0}}, // ( 22, 106) + { 0, { 0, 0, 0}}, // ( 23, 106) + { 0, { 0, 0, 0}}, // ( 24, 106) + { 0, { 0, 0, 0}}, // ( 25, 106) + { 0, { 0, 0, 0}}, // ( 26, 106) + { 0, { 0, 0, 0}}, // ( 27, 106) + { 0, { 0, 0, 0}}, // ( 28, 106) + { 0, { 0, 0, 0}}, // ( 29, 106) + { 0, { 0, 0, 0}}, // ( 30, 106) + { 0, { 0, 0, 0}}, // ( 31, 106) + { 0, { 0, 0, 0}}, // ( 32, 106) + { 0, { 0, 0, 0}}, // ( 33, 106) + { 0, { 0, 0, 0}}, // ( 34, 106) + { 0, { 0, 0, 0}}, // ( 35, 106) + { 0, { 0, 0, 0}}, // ( 36, 106) + { 0, { 0, 0, 0}}, // ( 37, 106) + { 0, { 0, 0, 0}}, // ( 38, 106) + { 0, { 0, 0, 0}}, // ( 39, 106) + { 0, { 0, 0, 0}}, // ( 40, 106) + { 0, { 0, 0, 0}}, // ( 41, 106) + { 0, { 0, 0, 0}}, // ( 42, 106) + { 0, { 0, 0, 0}}, // ( 43, 106) + { 0, { 0, 0, 0}}, // ( 44, 106) + { 0, { 0, 0, 0}}, // ( 45, 106) + { 0, { 0, 0, 0}}, // ( 46, 106) + { 0, { 0, 0, 0}}, // ( 47, 106) + { 0, { 0, 0, 0}}, // ( 48, 106) + { 0, { 0, 0, 0}}, // ( 49, 106) + { 0, { 0, 0, 0}}, // ( 50, 106) + { 0, { 0, 0, 0}}, // ( 51, 106) + { 0, { 0, 0, 0}}, // ( 52, 106) + { 0, { 0, 0, 0}}, // ( 53, 106) + { 0, { 0, 0, 0}}, // ( 54, 106) + { 0, { 0, 0, 0}}, // ( 55, 106) + { 0, { 0, 0, 0}}, // ( 56, 106) + { 0, { 0, 0, 0}}, // ( 57, 106) + { 0, { 0, 0, 0}}, // ( 58, 106) + { 0, { 0, 0, 0}}, // ( 59, 106) + { 0, { 0, 0, 0}}, // ( 60, 106) + { 0, { 0, 0, 0}}, // ( 61, 106) + { 0, { 0, 0, 0}}, // ( 62, 106) + { 0, { 0, 0, 0}}, // ( 63, 106) + { 0, { 0, 0, 0}}, // ( 64, 106) + { 0, { 0, 0, 0}}, // ( 65, 106) + { 0, { 0, 0, 0}}, // ( 66, 106) + { 0, { 0, 0, 0}}, // ( 67, 106) + { 0, { 0, 0, 0}}, // ( 68, 106) + { 0, { 0, 0, 0}}, // ( 69, 106) + { 0, { 0, 0, 0}}, // ( 70, 106) + { 0, { 0, 0, 0}}, // ( 71, 106) + { 0, { 0, 0, 0}}, // ( 72, 106) + { 0, { 0, 0, 0}}, // ( 73, 106) + { 0, { 0, 0, 0}}, // ( 74, 106) + { 0, { 0, 0, 0}}, // ( 75, 106) + { 0, { 0, 0, 0}}, // ( 76, 106) + { 0, { 0, 0, 0}}, // ( 77, 106) + { 0, { 0, 0, 0}}, // ( 78, 106) + { 0, { 0, 0, 0}}, // ( 79, 106) + { 0, { 0, 0, 0}}, // ( 80, 106) + { 0, { 0, 0, 0}}, // ( 81, 106) + { 0, { 0, 0, 0}}, // ( 82, 106) + { 0, { 0, 0, 0}}, // ( 83, 106) + { 0, { 0, 0, 0}}, // ( 84, 106) + { 0, { 0, 0, 0}}, // ( 85, 106) + { 0, { 0, 0, 0}}, // ( 86, 106) + { 0, { 0, 0, 0}}, // ( 87, 106) + { 0, { 0, 0, 0}}, // ( 88, 106) + { 0, { 0, 0, 0}}, // ( 89, 106) + { 0, { 0, 0, 0}}, // ( 90, 106) + { 0, { 0, 0, 0}}, // ( 91, 106) + { 0, { 0, 0, 0}}, // ( 92, 106) + { 0, { 0, 0, 0}}, // ( 93, 106) + { 0, { 0, 0, 0}}, // ( 94, 106) + { 0, { 0, 0, 0}}, // ( 95, 106) + { 0, { 0, 0, 0}}, // ( 96, 106) + { 0, { 0, 0, 0}}, // ( 97, 106) + { 0, { 0, 0, 0}}, // ( 98, 106) + { 0, { 0, 0, 0}}, // ( 99, 106) + { 0, { 0, 0, 0}}, // (100, 106) + { 0, { 0, 0, 0}}, // (101, 106) + { 0, { 0, 0, 0}}, // (102, 106) + { 0, { 0, 0, 0}}, // (103, 106) + { 0, { 0, 0, 0}}, // (104, 106) + { 0, { 0, 0, 0}}, // (105, 106) + { 0, { 0, 0, 0}}, // (106, 106) + { 0, { 0, 0, 0}}, // (107, 106) + { 0, { 0, 0, 0}}, // (108, 106) + { 0, { 0, 0, 0}}, // (109, 106) + { 0, { 0, 0, 0}}, // (110, 106) + { 0, { 0, 0, 0}}, // (111, 106) + { 0, { 0, 0, 0}}, // (112, 106) + { 0, { 0, 0, 0}}, // (113, 106) + { 0, { 0, 0, 0}}, // (114, 106) + { 0, { 0, 0, 0}}, // (115, 106) + { 0, { 0, 0, 0}}, // (116, 106) + { 0, { 0, 0, 0}}, // (117, 106) + { 0, { 0, 0, 0}}, // (118, 106) + { 0, { 0, 0, 0}}, // (119, 106) + { 0, { 0, 0, 0}}, // (120, 106) + { 0, { 0, 0, 0}}, // (121, 106) + { 0, { 0, 0, 0}}, // (122, 106) + { 0, { 0, 0, 0}}, // (123, 106) + { 0, { 0, 0, 0}}, // (124, 106) + { 0, { 0, 0, 0}}, // (125, 106) + { 0, { 0, 0, 0}}, // (126, 106) + { 0, { 0, 0, 0}}, // (127, 106) + { 0, { 0, 0, 0}}, // (128, 106) + { 0, { 0, 0, 0}}, // (129, 106) + { 0, { 0, 0, 0}}, // (130, 106) + { 0, { 0, 0, 0}}, // (131, 106) + { 0, { 0, 0, 0}}, // (132, 106) + { 0, { 0, 0, 0}}, // (133, 106) + { 0, { 0, 0, 0}}, // (134, 106) + { 0, { 0, 0, 0}}, // (135, 106) + { 0, { 0, 0, 0}}, // (136, 106) + { 0, { 0, 0, 0}}, // (137, 106) + { 0, { 0, 0, 0}}, // (138, 106) + { 0, { 0, 0, 0}}, // (139, 106) + { 0, { 0, 0, 0}}, // (140, 106) + { 0, { 0, 0, 0}}, // (141, 106) + { 0, { 0, 0, 0}}, // (142, 106) + { 0, { 0, 0, 0}}, // (143, 106) + { 0, { 0, 0, 0}}, // (144, 106) + { 0, { 0, 0, 0}}, // (145, 106) + { 0, { 0, 0, 0}}, // (146, 106) + { 0, { 0, 0, 0}}, // (147, 106) + { 0, { 0, 0, 0}}, // (148, 106) + { 0, { 0, 0, 0}}, // (149, 106) + { 0, { 0, 0, 0}}, // (150, 106) + { 0, { 0, 0, 0}}, // (151, 106) + { 0, { 0, 0, 0}}, // (152, 106) + { 0, { 0, 0, 0}}, // (153, 106) + { 0, { 0, 0, 0}}, // (154, 106) + { 0, { 0, 0, 0}}, // (155, 106) + { 0, { 0, 0, 0}}, // (156, 106) + { 0, { 0, 0, 0}}, // (157, 106) + { 0, { 0, 0, 0}}, // (158, 106) + { 0, { 0, 0, 0}}, // (159, 106) + { 0, { 0, 0, 0}}, // (160, 106) + { 0, { 0, 0, 0}}, // (161, 106) + { 0, { 0, 0, 0}}, // (162, 106) + { 0, { 0, 0, 0}}, // (163, 106) + { 0, { 0, 0, 0}}, // (164, 106) + { 0, { 0, 0, 0}}, // (165, 106) + { 0, { 0, 0, 0}}, // (166, 106) + { 0, { 0, 0, 0}}, // (167, 106) + { 0, { 0, 0, 0}}, // (168, 106) + { 0, { 0, 0, 0}}, // (169, 106) + { 0, { 0, 0, 0}}, // (170, 106) + { 0, { 0, 0, 0}}, // (171, 106) + { 0, { 0, 0, 0}}, // (172, 106) + { 0, { 0, 0, 0}}, // (173, 106) + { 0, { 0, 0, 0}}, // (174, 106) + { 0, { 0, 0, 0}}, // (175, 106) + { 70, { 0, 0, 0}}, // (176, 106) + {128, { 0, 0, 0}}, // (177, 106) + {128, { 0, 0, 0}}, // (178, 106) + {128, { 0, 0, 0}}, // (179, 106) + {128, { 0, 0, 0}}, // ( 0, 107) + {128, { 0, 0, 0}}, // ( 1, 107) + {128, { 0, 0, 0}}, // ( 2, 107) + { 95, { 0, 0, 0}}, // ( 3, 107) + { 0, { 0, 0, 0}}, // ( 4, 107) + { 0, { 0, 0, 0}}, // ( 5, 107) + { 0, { 0, 0, 0}}, // ( 6, 107) + { 0, { 0, 0, 0}}, // ( 7, 107) + { 0, { 0, 0, 0}}, // ( 8, 107) + { 0, { 0, 0, 0}}, // ( 9, 107) + { 0, { 0, 0, 0}}, // ( 10, 107) + { 0, { 0, 0, 0}}, // ( 11, 107) + { 0, { 0, 0, 0}}, // ( 12, 107) + { 0, { 0, 0, 0}}, // ( 13, 107) + { 0, { 0, 0, 0}}, // ( 14, 107) + { 0, { 0, 0, 0}}, // ( 15, 107) + { 0, { 0, 0, 0}}, // ( 16, 107) + { 0, { 0, 0, 0}}, // ( 17, 107) + { 0, { 0, 0, 0}}, // ( 18, 107) + { 0, { 0, 0, 0}}, // ( 19, 107) + { 0, { 0, 0, 0}}, // ( 20, 107) + { 0, { 0, 0, 0}}, // ( 21, 107) + { 0, { 0, 0, 0}}, // ( 22, 107) + { 0, { 0, 0, 0}}, // ( 23, 107) + { 0, { 0, 0, 0}}, // ( 24, 107) + { 0, { 0, 0, 0}}, // ( 25, 107) + { 0, { 0, 0, 0}}, // ( 26, 107) + { 0, { 0, 0, 0}}, // ( 27, 107) + { 0, { 0, 0, 0}}, // ( 28, 107) + { 0, { 0, 0, 0}}, // ( 29, 107) + { 0, { 0, 0, 0}}, // ( 30, 107) + { 0, { 0, 0, 0}}, // ( 31, 107) + { 0, { 0, 0, 0}}, // ( 32, 107) + { 0, { 0, 0, 0}}, // ( 33, 107) + { 0, { 0, 0, 0}}, // ( 34, 107) + { 0, { 0, 0, 0}}, // ( 35, 107) + { 0, { 0, 0, 0}}, // ( 36, 107) + { 0, { 0, 0, 0}}, // ( 37, 107) + { 0, { 0, 0, 0}}, // ( 38, 107) + { 0, { 0, 0, 0}}, // ( 39, 107) + { 0, { 0, 0, 0}}, // ( 40, 107) + { 0, { 0, 0, 0}}, // ( 41, 107) + { 0, { 0, 0, 0}}, // ( 42, 107) + { 0, { 0, 0, 0}}, // ( 43, 107) + { 0, { 0, 0, 0}}, // ( 44, 107) + { 0, { 0, 0, 0}}, // ( 45, 107) + { 0, { 0, 0, 0}}, // ( 46, 107) + { 0, { 0, 0, 0}}, // ( 47, 107) + { 0, { 0, 0, 0}}, // ( 48, 107) + { 0, { 0, 0, 0}}, // ( 49, 107) + { 0, { 0, 0, 0}}, // ( 50, 107) + { 0, { 0, 0, 0}}, // ( 51, 107) + { 0, { 0, 0, 0}}, // ( 52, 107) + { 0, { 0, 0, 0}}, // ( 53, 107) + { 0, { 0, 0, 0}}, // ( 54, 107) + { 0, { 0, 0, 0}}, // ( 55, 107) + { 0, { 0, 0, 0}}, // ( 56, 107) + { 0, { 0, 0, 0}}, // ( 57, 107) + { 0, { 0, 0, 0}}, // ( 58, 107) + { 0, { 0, 0, 0}}, // ( 59, 107) + { 0, { 0, 0, 0}}, // ( 60, 107) + { 0, { 0, 0, 0}}, // ( 61, 107) + { 0, { 0, 0, 0}}, // ( 62, 107) + { 0, { 0, 0, 0}}, // ( 63, 107) + { 0, { 0, 0, 0}}, // ( 64, 107) + { 0, { 0, 0, 0}}, // ( 65, 107) + { 0, { 0, 0, 0}}, // ( 66, 107) + { 0, { 0, 0, 0}}, // ( 67, 107) + { 0, { 0, 0, 0}}, // ( 68, 107) + { 0, { 0, 0, 0}}, // ( 69, 107) + { 0, { 0, 0, 0}}, // ( 70, 107) + { 0, { 0, 0, 0}}, // ( 71, 107) + { 0, { 0, 0, 0}}, // ( 72, 107) + { 0, { 0, 0, 0}}, // ( 73, 107) + { 0, { 0, 0, 0}}, // ( 74, 107) + { 0, { 0, 0, 0}}, // ( 75, 107) + { 0, { 0, 0, 0}}, // ( 76, 107) + { 0, { 0, 0, 0}}, // ( 77, 107) + { 0, { 0, 0, 0}}, // ( 78, 107) + { 0, { 0, 0, 0}}, // ( 79, 107) + { 0, { 0, 0, 0}}, // ( 80, 107) + { 0, { 0, 0, 0}}, // ( 81, 107) + { 0, { 0, 0, 0}}, // ( 82, 107) + { 0, { 0, 0, 0}}, // ( 83, 107) + { 0, { 0, 0, 0}}, // ( 84, 107) + { 0, { 0, 0, 0}}, // ( 85, 107) + { 0, { 0, 0, 0}}, // ( 86, 107) + { 0, { 0, 0, 0}}, // ( 87, 107) + { 0, { 0, 0, 0}}, // ( 88, 107) + { 0, { 0, 0, 0}}, // ( 89, 107) + { 0, { 0, 0, 0}}, // ( 90, 107) + { 0, { 0, 0, 0}}, // ( 91, 107) + { 0, { 0, 0, 0}}, // ( 92, 107) + { 0, { 0, 0, 0}}, // ( 93, 107) + { 0, { 0, 0, 0}}, // ( 94, 107) + { 0, { 0, 0, 0}}, // ( 95, 107) + { 0, { 0, 0, 0}}, // ( 96, 107) + { 0, { 0, 0, 0}}, // ( 97, 107) + { 0, { 0, 0, 0}}, // ( 98, 107) + { 0, { 0, 0, 0}}, // ( 99, 107) + { 0, { 0, 0, 0}}, // (100, 107) + { 0, { 0, 0, 0}}, // (101, 107) + { 0, { 0, 0, 0}}, // (102, 107) + { 0, { 0, 0, 0}}, // (103, 107) + { 0, { 0, 0, 0}}, // (104, 107) + { 0, { 0, 0, 0}}, // (105, 107) + { 0, { 0, 0, 0}}, // (106, 107) + { 0, { 0, 0, 0}}, // (107, 107) + { 0, { 0, 0, 0}}, // (108, 107) + { 0, { 0, 0, 0}}, // (109, 107) + { 0, { 0, 0, 0}}, // (110, 107) + { 0, { 0, 0, 0}}, // (111, 107) + { 0, { 0, 0, 0}}, // (112, 107) + { 0, { 0, 0, 0}}, // (113, 107) + { 0, { 0, 0, 0}}, // (114, 107) + { 0, { 0, 0, 0}}, // (115, 107) + { 0, { 0, 0, 0}}, // (116, 107) + { 0, { 0, 0, 0}}, // (117, 107) + { 0, { 0, 0, 0}}, // (118, 107) + { 0, { 0, 0, 0}}, // (119, 107) + { 0, { 0, 0, 0}}, // (120, 107) + { 0, { 0, 0, 0}}, // (121, 107) + { 0, { 0, 0, 0}}, // (122, 107) + { 0, { 0, 0, 0}}, // (123, 107) + { 0, { 0, 0, 0}}, // (124, 107) + { 0, { 0, 0, 0}}, // (125, 107) + { 0, { 0, 0, 0}}, // (126, 107) + { 0, { 0, 0, 0}}, // (127, 107) + { 0, { 0, 0, 0}}, // (128, 107) + { 0, { 0, 0, 0}}, // (129, 107) + { 0, { 0, 0, 0}}, // (130, 107) + { 0, { 0, 0, 0}}, // (131, 107) + { 0, { 0, 0, 0}}, // (132, 107) + { 0, { 0, 0, 0}}, // (133, 107) + { 0, { 0, 0, 0}}, // (134, 107) + { 0, { 0, 0, 0}}, // (135, 107) + { 0, { 0, 0, 0}}, // (136, 107) + { 0, { 0, 0, 0}}, // (137, 107) + { 0, { 0, 0, 0}}, // (138, 107) + { 0, { 0, 0, 0}}, // (139, 107) + { 0, { 0, 0, 0}}, // (140, 107) + { 0, { 0, 0, 0}}, // (141, 107) + { 0, { 0, 0, 0}}, // (142, 107) + { 0, { 0, 0, 0}}, // (143, 107) + { 0, { 0, 0, 0}}, // (144, 107) + { 0, { 0, 0, 0}}, // (145, 107) + { 0, { 0, 0, 0}}, // (146, 107) + { 0, { 0, 0, 0}}, // (147, 107) + { 0, { 0, 0, 0}}, // (148, 107) + { 0, { 0, 0, 0}}, // (149, 107) + { 0, { 0, 0, 0}}, // (150, 107) + { 0, { 0, 0, 0}}, // (151, 107) + { 0, { 0, 0, 0}}, // (152, 107) + { 0, { 0, 0, 0}}, // (153, 107) + { 0, { 0, 0, 0}}, // (154, 107) + { 0, { 0, 0, 0}}, // (155, 107) + { 0, { 0, 0, 0}}, // (156, 107) + { 0, { 0, 0, 0}}, // (157, 107) + { 0, { 0, 0, 0}}, // (158, 107) + { 0, { 0, 0, 0}}, // (159, 107) + { 0, { 0, 0, 0}}, // (160, 107) + { 0, { 0, 0, 0}}, // (161, 107) + { 0, { 0, 0, 0}}, // (162, 107) + { 0, { 0, 0, 0}}, // (163, 107) + { 0, { 0, 0, 0}}, // (164, 107) + { 0, { 0, 0, 0}}, // (165, 107) + { 0, { 0, 0, 0}}, // (166, 107) + { 0, { 0, 0, 0}}, // (167, 107) + { 0, { 0, 0, 0}}, // (168, 107) + { 0, { 0, 0, 0}}, // (169, 107) + { 0, { 0, 0, 0}}, // (170, 107) + { 0, { 0, 0, 0}}, // (171, 107) + { 0, { 0, 0, 0}}, // (172, 107) + { 0, { 0, 0, 0}}, // (173, 107) + { 0, { 0, 0, 0}}, // (174, 107) + { 0, { 0, 0, 0}}, // (175, 107) + { 95, { 0, 0, 0}}, // (176, 107) + {128, { 0, 0, 0}}, // (177, 107) + {128, { 0, 0, 0}}, // (178, 107) + {128, { 0, 0, 0}}, // (179, 107) + {128, { 0, 0, 0}}, // ( 0, 108) + {128, { 0, 0, 0}}, // ( 1, 108) + {128, { 0, 0, 0}}, // ( 2, 108) + {120, { 0, 0, 0}}, // ( 3, 108) + { 1, { 0, 0, 0}}, // ( 4, 108) + { 0, { 0, 0, 0}}, // ( 5, 108) + { 0, { 0, 0, 0}}, // ( 6, 108) + { 0, { 0, 0, 0}}, // ( 7, 108) + { 0, { 0, 0, 0}}, // ( 8, 108) + { 0, { 0, 0, 0}}, // ( 9, 108) + { 0, { 0, 0, 0}}, // ( 10, 108) + { 0, { 0, 0, 0}}, // ( 11, 108) + { 0, { 0, 0, 0}}, // ( 12, 108) + { 0, { 0, 0, 0}}, // ( 13, 108) + { 0, { 0, 0, 0}}, // ( 14, 108) + { 0, { 0, 0, 0}}, // ( 15, 108) + { 0, { 0, 0, 0}}, // ( 16, 108) + { 0, { 0, 0, 0}}, // ( 17, 108) + { 0, { 0, 0, 0}}, // ( 18, 108) + { 0, { 0, 0, 0}}, // ( 19, 108) + { 0, { 0, 0, 0}}, // ( 20, 108) + { 0, { 0, 0, 0}}, // ( 21, 108) + { 0, { 0, 0, 0}}, // ( 22, 108) + { 0, { 0, 0, 0}}, // ( 23, 108) + { 0, { 0, 0, 0}}, // ( 24, 108) + { 0, { 0, 0, 0}}, // ( 25, 108) + { 0, { 0, 0, 0}}, // ( 26, 108) + { 0, { 0, 0, 0}}, // ( 27, 108) + { 0, { 0, 0, 0}}, // ( 28, 108) + { 0, { 0, 0, 0}}, // ( 29, 108) + { 0, { 0, 0, 0}}, // ( 30, 108) + { 0, { 0, 0, 0}}, // ( 31, 108) + { 0, { 0, 0, 0}}, // ( 32, 108) + { 0, { 0, 0, 0}}, // ( 33, 108) + { 0, { 0, 0, 0}}, // ( 34, 108) + { 0, { 0, 0, 0}}, // ( 35, 108) + { 0, { 0, 0, 0}}, // ( 36, 108) + { 0, { 0, 0, 0}}, // ( 37, 108) + { 0, { 0, 0, 0}}, // ( 38, 108) + { 0, { 0, 0, 0}}, // ( 39, 108) + { 0, { 0, 0, 0}}, // ( 40, 108) + { 0, { 0, 0, 0}}, // ( 41, 108) + { 0, { 0, 0, 0}}, // ( 42, 108) + { 0, { 0, 0, 0}}, // ( 43, 108) + { 0, { 0, 0, 0}}, // ( 44, 108) + { 0, { 0, 0, 0}}, // ( 45, 108) + { 0, { 0, 0, 0}}, // ( 46, 108) + { 0, { 0, 0, 0}}, // ( 47, 108) + { 0, { 0, 0, 0}}, // ( 48, 108) + { 0, { 0, 0, 0}}, // ( 49, 108) + { 0, { 0, 0, 0}}, // ( 50, 108) + { 0, { 0, 0, 0}}, // ( 51, 108) + { 0, { 0, 0, 0}}, // ( 52, 108) + { 0, { 0, 0, 0}}, // ( 53, 108) + { 0, { 0, 0, 0}}, // ( 54, 108) + { 0, { 0, 0, 0}}, // ( 55, 108) + { 0, { 0, 0, 0}}, // ( 56, 108) + { 0, { 0, 0, 0}}, // ( 57, 108) + { 0, { 0, 0, 0}}, // ( 58, 108) + { 0, { 0, 0, 0}}, // ( 59, 108) + { 0, { 0, 0, 0}}, // ( 60, 108) + { 0, { 0, 0, 0}}, // ( 61, 108) + { 0, { 0, 0, 0}}, // ( 62, 108) + { 0, { 0, 0, 0}}, // ( 63, 108) + { 0, { 0, 0, 0}}, // ( 64, 108) + { 0, { 0, 0, 0}}, // ( 65, 108) + { 0, { 0, 0, 0}}, // ( 66, 108) + { 0, { 0, 0, 0}}, // ( 67, 108) + { 0, { 0, 0, 0}}, // ( 68, 108) + { 0, { 0, 0, 0}}, // ( 69, 108) + { 0, { 0, 0, 0}}, // ( 70, 108) + { 0, { 0, 0, 0}}, // ( 71, 108) + { 0, { 0, 0, 0}}, // ( 72, 108) + { 0, { 0, 0, 0}}, // ( 73, 108) + { 0, { 0, 0, 0}}, // ( 74, 108) + { 0, { 0, 0, 0}}, // ( 75, 108) + { 0, { 0, 0, 0}}, // ( 76, 108) + { 0, { 0, 0, 0}}, // ( 77, 108) + { 0, { 0, 0, 0}}, // ( 78, 108) + { 0, { 0, 0, 0}}, // ( 79, 108) + { 0, { 0, 0, 0}}, // ( 80, 108) + { 0, { 0, 0, 0}}, // ( 81, 108) + { 0, { 0, 0, 0}}, // ( 82, 108) + { 0, { 0, 0, 0}}, // ( 83, 108) + { 0, { 0, 0, 0}}, // ( 84, 108) + { 0, { 0, 0, 0}}, // ( 85, 108) + { 0, { 0, 0, 0}}, // ( 86, 108) + { 0, { 0, 0, 0}}, // ( 87, 108) + { 0, { 0, 0, 0}}, // ( 88, 108) + { 0, { 0, 0, 0}}, // ( 89, 108) + { 0, { 0, 0, 0}}, // ( 90, 108) + { 0, { 0, 0, 0}}, // ( 91, 108) + { 0, { 0, 0, 0}}, // ( 92, 108) + { 0, { 0, 0, 0}}, // ( 93, 108) + { 0, { 0, 0, 0}}, // ( 94, 108) + { 0, { 0, 0, 0}}, // ( 95, 108) + { 0, { 0, 0, 0}}, // ( 96, 108) + { 0, { 0, 0, 0}}, // ( 97, 108) + { 0, { 0, 0, 0}}, // ( 98, 108) + { 0, { 0, 0, 0}}, // ( 99, 108) + { 0, { 0, 0, 0}}, // (100, 108) + { 0, { 0, 0, 0}}, // (101, 108) + { 0, { 0, 0, 0}}, // (102, 108) + { 0, { 0, 0, 0}}, // (103, 108) + { 0, { 0, 0, 0}}, // (104, 108) + { 0, { 0, 0, 0}}, // (105, 108) + { 0, { 0, 0, 0}}, // (106, 108) + { 0, { 0, 0, 0}}, // (107, 108) + { 0, { 0, 0, 0}}, // (108, 108) + { 0, { 0, 0, 0}}, // (109, 108) + { 0, { 0, 0, 0}}, // (110, 108) + { 0, { 0, 0, 0}}, // (111, 108) + { 0, { 0, 0, 0}}, // (112, 108) + { 0, { 0, 0, 0}}, // (113, 108) + { 0, { 0, 0, 0}}, // (114, 108) + { 0, { 0, 0, 0}}, // (115, 108) + { 0, { 0, 0, 0}}, // (116, 108) + { 0, { 0, 0, 0}}, // (117, 108) + { 0, { 0, 0, 0}}, // (118, 108) + { 0, { 0, 0, 0}}, // (119, 108) + { 0, { 0, 0, 0}}, // (120, 108) + { 0, { 0, 0, 0}}, // (121, 108) + { 0, { 0, 0, 0}}, // (122, 108) + { 0, { 0, 0, 0}}, // (123, 108) + { 0, { 0, 0, 0}}, // (124, 108) + { 0, { 0, 0, 0}}, // (125, 108) + { 0, { 0, 0, 0}}, // (126, 108) + { 0, { 0, 0, 0}}, // (127, 108) + { 0, { 0, 0, 0}}, // (128, 108) + { 0, { 0, 0, 0}}, // (129, 108) + { 0, { 0, 0, 0}}, // (130, 108) + { 0, { 0, 0, 0}}, // (131, 108) + { 0, { 0, 0, 0}}, // (132, 108) + { 0, { 0, 0, 0}}, // (133, 108) + { 0, { 0, 0, 0}}, // (134, 108) + { 0, { 0, 0, 0}}, // (135, 108) + { 0, { 0, 0, 0}}, // (136, 108) + { 0, { 0, 0, 0}}, // (137, 108) + { 0, { 0, 0, 0}}, // (138, 108) + { 0, { 0, 0, 0}}, // (139, 108) + { 0, { 0, 0, 0}}, // (140, 108) + { 0, { 0, 0, 0}}, // (141, 108) + { 0, { 0, 0, 0}}, // (142, 108) + { 0, { 0, 0, 0}}, // (143, 108) + { 0, { 0, 0, 0}}, // (144, 108) + { 0, { 0, 0, 0}}, // (145, 108) + { 0, { 0, 0, 0}}, // (146, 108) + { 0, { 0, 0, 0}}, // (147, 108) + { 0, { 0, 0, 0}}, // (148, 108) + { 0, { 0, 0, 0}}, // (149, 108) + { 0, { 0, 0, 0}}, // (150, 108) + { 0, { 0, 0, 0}}, // (151, 108) + { 0, { 0, 0, 0}}, // (152, 108) + { 0, { 0, 0, 0}}, // (153, 108) + { 0, { 0, 0, 0}}, // (154, 108) + { 0, { 0, 0, 0}}, // (155, 108) + { 0, { 0, 0, 0}}, // (156, 108) + { 0, { 0, 0, 0}}, // (157, 108) + { 0, { 0, 0, 0}}, // (158, 108) + { 0, { 0, 0, 0}}, // (159, 108) + { 0, { 0, 0, 0}}, // (160, 108) + { 0, { 0, 0, 0}}, // (161, 108) + { 0, { 0, 0, 0}}, // (162, 108) + { 0, { 0, 0, 0}}, // (163, 108) + { 0, { 0, 0, 0}}, // (164, 108) + { 0, { 0, 0, 0}}, // (165, 108) + { 0, { 0, 0, 0}}, // (166, 108) + { 0, { 0, 0, 0}}, // (167, 108) + { 0, { 0, 0, 0}}, // (168, 108) + { 0, { 0, 0, 0}}, // (169, 108) + { 0, { 0, 0, 0}}, // (170, 108) + { 0, { 0, 0, 0}}, // (171, 108) + { 0, { 0, 0, 0}}, // (172, 108) + { 0, { 0, 0, 0}}, // (173, 108) + { 0, { 0, 0, 0}}, // (174, 108) + { 1, { 0, 0, 0}}, // (175, 108) + {120, { 0, 0, 0}}, // (176, 108) + {128, { 0, 0, 0}}, // (177, 108) + {128, { 0, 0, 0}}, // (178, 108) + {128, { 0, 0, 0}}, // (179, 108) + {128, { 0, 0, 0}}, // ( 0, 109) + {128, { 0, 0, 0}}, // ( 1, 109) + {128, { 0, 0, 0}}, // ( 2, 109) + {128, { 0, 0, 0}}, // ( 3, 109) + { 22, { 0, 0, 0}}, // ( 4, 109) + { 0, { 0, 0, 0}}, // ( 5, 109) + { 0, { 0, 0, 0}}, // ( 6, 109) + { 0, { 0, 0, 0}}, // ( 7, 109) + { 0, { 0, 0, 0}}, // ( 8, 109) + { 0, { 0, 0, 0}}, // ( 9, 109) + { 0, { 0, 0, 0}}, // ( 10, 109) + { 0, { 0, 0, 0}}, // ( 11, 109) + { 0, { 0, 0, 0}}, // ( 12, 109) + { 0, { 0, 0, 0}}, // ( 13, 109) + { 0, { 0, 0, 0}}, // ( 14, 109) + { 0, { 0, 0, 0}}, // ( 15, 109) + { 0, { 0, 0, 0}}, // ( 16, 109) + { 0, { 0, 0, 0}}, // ( 17, 109) + { 0, { 0, 0, 0}}, // ( 18, 109) + { 0, { 0, 0, 0}}, // ( 19, 109) + { 0, { 0, 0, 0}}, // ( 20, 109) + { 0, { 0, 0, 0}}, // ( 21, 109) + { 0, { 0, 0, 0}}, // ( 22, 109) + { 0, { 0, 0, 0}}, // ( 23, 109) + { 0, { 0, 0, 0}}, // ( 24, 109) + { 0, { 0, 0, 0}}, // ( 25, 109) + { 0, { 0, 0, 0}}, // ( 26, 109) + { 0, { 0, 0, 0}}, // ( 27, 109) + { 0, { 0, 0, 0}}, // ( 28, 109) + { 0, { 0, 0, 0}}, // ( 29, 109) + { 0, { 0, 0, 0}}, // ( 30, 109) + { 0, { 0, 0, 0}}, // ( 31, 109) + { 0, { 0, 0, 0}}, // ( 32, 109) + { 0, { 0, 0, 0}}, // ( 33, 109) + { 0, { 0, 0, 0}}, // ( 34, 109) + { 0, { 0, 0, 0}}, // ( 35, 109) + { 0, { 0, 0, 0}}, // ( 36, 109) + { 0, { 0, 0, 0}}, // ( 37, 109) + { 0, { 0, 0, 0}}, // ( 38, 109) + { 0, { 0, 0, 0}}, // ( 39, 109) + { 0, { 0, 0, 0}}, // ( 40, 109) + { 0, { 0, 0, 0}}, // ( 41, 109) + { 0, { 0, 0, 0}}, // ( 42, 109) + { 0, { 0, 0, 0}}, // ( 43, 109) + { 0, { 0, 0, 0}}, // ( 44, 109) + { 0, { 0, 0, 0}}, // ( 45, 109) + { 0, { 0, 0, 0}}, // ( 46, 109) + { 0, { 0, 0, 0}}, // ( 47, 109) + { 0, { 0, 0, 0}}, // ( 48, 109) + { 0, { 0, 0, 0}}, // ( 49, 109) + { 0, { 0, 0, 0}}, // ( 50, 109) + { 0, { 0, 0, 0}}, // ( 51, 109) + { 0, { 0, 0, 0}}, // ( 52, 109) + { 0, { 0, 0, 0}}, // ( 53, 109) + { 0, { 0, 0, 0}}, // ( 54, 109) + { 0, { 0, 0, 0}}, // ( 55, 109) + { 0, { 0, 0, 0}}, // ( 56, 109) + { 0, { 0, 0, 0}}, // ( 57, 109) + { 0, { 0, 0, 0}}, // ( 58, 109) + { 0, { 0, 0, 0}}, // ( 59, 109) + { 0, { 0, 0, 0}}, // ( 60, 109) + { 0, { 0, 0, 0}}, // ( 61, 109) + { 0, { 0, 0, 0}}, // ( 62, 109) + { 0, { 0, 0, 0}}, // ( 63, 109) + { 0, { 0, 0, 0}}, // ( 64, 109) + { 0, { 0, 0, 0}}, // ( 65, 109) + { 0, { 0, 0, 0}}, // ( 66, 109) + { 0, { 0, 0, 0}}, // ( 67, 109) + { 0, { 0, 0, 0}}, // ( 68, 109) + { 0, { 0, 0, 0}}, // ( 69, 109) + { 0, { 0, 0, 0}}, // ( 70, 109) + { 0, { 0, 0, 0}}, // ( 71, 109) + { 0, { 0, 0, 0}}, // ( 72, 109) + { 0, { 0, 0, 0}}, // ( 73, 109) + { 0, { 0, 0, 0}}, // ( 74, 109) + { 0, { 0, 0, 0}}, // ( 75, 109) + { 0, { 0, 0, 0}}, // ( 76, 109) + { 0, { 0, 0, 0}}, // ( 77, 109) + { 0, { 0, 0, 0}}, // ( 78, 109) + { 0, { 0, 0, 0}}, // ( 79, 109) + { 0, { 0, 0, 0}}, // ( 80, 109) + { 0, { 0, 0, 0}}, // ( 81, 109) + { 0, { 0, 0, 0}}, // ( 82, 109) + { 0, { 0, 0, 0}}, // ( 83, 109) + { 0, { 0, 0, 0}}, // ( 84, 109) + { 0, { 0, 0, 0}}, // ( 85, 109) + { 0, { 0, 0, 0}}, // ( 86, 109) + { 0, { 0, 0, 0}}, // ( 87, 109) + { 0, { 0, 0, 0}}, // ( 88, 109) + { 0, { 0, 0, 0}}, // ( 89, 109) + { 0, { 0, 0, 0}}, // ( 90, 109) + { 0, { 0, 0, 0}}, // ( 91, 109) + { 0, { 0, 0, 0}}, // ( 92, 109) + { 0, { 0, 0, 0}}, // ( 93, 109) + { 0, { 0, 0, 0}}, // ( 94, 109) + { 0, { 0, 0, 0}}, // ( 95, 109) + { 0, { 0, 0, 0}}, // ( 96, 109) + { 0, { 0, 0, 0}}, // ( 97, 109) + { 0, { 0, 0, 0}}, // ( 98, 109) + { 0, { 0, 0, 0}}, // ( 99, 109) + { 0, { 0, 0, 0}}, // (100, 109) + { 0, { 0, 0, 0}}, // (101, 109) + { 0, { 0, 0, 0}}, // (102, 109) + { 0, { 0, 0, 0}}, // (103, 109) + { 0, { 0, 0, 0}}, // (104, 109) + { 0, { 0, 0, 0}}, // (105, 109) + { 0, { 0, 0, 0}}, // (106, 109) + { 0, { 0, 0, 0}}, // (107, 109) + { 0, { 0, 0, 0}}, // (108, 109) + { 0, { 0, 0, 0}}, // (109, 109) + { 0, { 0, 0, 0}}, // (110, 109) + { 0, { 0, 0, 0}}, // (111, 109) + { 0, { 0, 0, 0}}, // (112, 109) + { 0, { 0, 0, 0}}, // (113, 109) + { 0, { 0, 0, 0}}, // (114, 109) + { 0, { 0, 0, 0}}, // (115, 109) + { 0, { 0, 0, 0}}, // (116, 109) + { 0, { 0, 0, 0}}, // (117, 109) + { 0, { 0, 0, 0}}, // (118, 109) + { 0, { 0, 0, 0}}, // (119, 109) + { 0, { 0, 0, 0}}, // (120, 109) + { 0, { 0, 0, 0}}, // (121, 109) + { 0, { 0, 0, 0}}, // (122, 109) + { 0, { 0, 0, 0}}, // (123, 109) + { 0, { 0, 0, 0}}, // (124, 109) + { 0, { 0, 0, 0}}, // (125, 109) + { 0, { 0, 0, 0}}, // (126, 109) + { 0, { 0, 0, 0}}, // (127, 109) + { 0, { 0, 0, 0}}, // (128, 109) + { 0, { 0, 0, 0}}, // (129, 109) + { 0, { 0, 0, 0}}, // (130, 109) + { 0, { 0, 0, 0}}, // (131, 109) + { 0, { 0, 0, 0}}, // (132, 109) + { 0, { 0, 0, 0}}, // (133, 109) + { 0, { 0, 0, 0}}, // (134, 109) + { 0, { 0, 0, 0}}, // (135, 109) + { 0, { 0, 0, 0}}, // (136, 109) + { 0, { 0, 0, 0}}, // (137, 109) + { 0, { 0, 0, 0}}, // (138, 109) + { 0, { 0, 0, 0}}, // (139, 109) + { 0, { 0, 0, 0}}, // (140, 109) + { 0, { 0, 0, 0}}, // (141, 109) + { 0, { 0, 0, 0}}, // (142, 109) + { 0, { 0, 0, 0}}, // (143, 109) + { 0, { 0, 0, 0}}, // (144, 109) + { 0, { 0, 0, 0}}, // (145, 109) + { 0, { 0, 0, 0}}, // (146, 109) + { 0, { 0, 0, 0}}, // (147, 109) + { 0, { 0, 0, 0}}, // (148, 109) + { 0, { 0, 0, 0}}, // (149, 109) + { 0, { 0, 0, 0}}, // (150, 109) + { 0, { 0, 0, 0}}, // (151, 109) + { 0, { 0, 0, 0}}, // (152, 109) + { 0, { 0, 0, 0}}, // (153, 109) + { 0, { 0, 0, 0}}, // (154, 109) + { 0, { 0, 0, 0}}, // (155, 109) + { 0, { 0, 0, 0}}, // (156, 109) + { 0, { 0, 0, 0}}, // (157, 109) + { 0, { 0, 0, 0}}, // (158, 109) + { 0, { 0, 0, 0}}, // (159, 109) + { 0, { 0, 0, 0}}, // (160, 109) + { 0, { 0, 0, 0}}, // (161, 109) + { 0, { 0, 0, 0}}, // (162, 109) + { 0, { 0, 0, 0}}, // (163, 109) + { 0, { 0, 0, 0}}, // (164, 109) + { 0, { 0, 0, 0}}, // (165, 109) + { 0, { 0, 0, 0}}, // (166, 109) + { 0, { 0, 0, 0}}, // (167, 109) + { 0, { 0, 0, 0}}, // (168, 109) + { 0, { 0, 0, 0}}, // (169, 109) + { 0, { 0, 0, 0}}, // (170, 109) + { 0, { 0, 0, 0}}, // (171, 109) + { 0, { 0, 0, 0}}, // (172, 109) + { 0, { 0, 0, 0}}, // (173, 109) + { 0, { 0, 0, 0}}, // (174, 109) + { 22, { 0, 0, 0}}, // (175, 109) + {128, { 0, 0, 0}}, // (176, 109) + {128, { 0, 0, 0}}, // (177, 109) + {128, { 0, 0, 0}}, // (178, 109) + {128, { 0, 0, 0}}, // (179, 109) + {128, { 0, 0, 0}}, // ( 0, 110) + {128, { 0, 0, 0}}, // ( 1, 110) + {128, { 0, 0, 0}}, // ( 2, 110) + {128, { 0, 0, 0}}, // ( 3, 110) + { 52, { 0, 0, 0}}, // ( 4, 110) + { 0, { 0, 0, 0}}, // ( 5, 110) + { 0, { 0, 0, 0}}, // ( 6, 110) + { 0, { 0, 0, 0}}, // ( 7, 110) + { 0, { 0, 0, 0}}, // ( 8, 110) + { 0, { 0, 0, 0}}, // ( 9, 110) + { 0, { 0, 0, 0}}, // ( 10, 110) + { 0, { 0, 0, 0}}, // ( 11, 110) + { 0, { 0, 0, 0}}, // ( 12, 110) + { 0, { 0, 0, 0}}, // ( 13, 110) + { 0, { 0, 0, 0}}, // ( 14, 110) + { 0, { 0, 0, 0}}, // ( 15, 110) + { 0, { 0, 0, 0}}, // ( 16, 110) + { 0, { 0, 0, 0}}, // ( 17, 110) + { 0, { 0, 0, 0}}, // ( 18, 110) + { 0, { 0, 0, 0}}, // ( 19, 110) + { 0, { 0, 0, 0}}, // ( 20, 110) + { 0, { 0, 0, 0}}, // ( 21, 110) + { 0, { 0, 0, 0}}, // ( 22, 110) + { 0, { 0, 0, 0}}, // ( 23, 110) + { 0, { 0, 0, 0}}, // ( 24, 110) + { 0, { 0, 0, 0}}, // ( 25, 110) + { 0, { 0, 0, 0}}, // ( 26, 110) + { 0, { 0, 0, 0}}, // ( 27, 110) + { 0, { 0, 0, 0}}, // ( 28, 110) + { 0, { 0, 0, 0}}, // ( 29, 110) + { 0, { 0, 0, 0}}, // ( 30, 110) + { 0, { 0, 0, 0}}, // ( 31, 110) + { 0, { 0, 0, 0}}, // ( 32, 110) + { 0, { 0, 0, 0}}, // ( 33, 110) + { 0, { 0, 0, 0}}, // ( 34, 110) + { 0, { 0, 0, 0}}, // ( 35, 110) + { 0, { 0, 0, 0}}, // ( 36, 110) + { 0, { 0, 0, 0}}, // ( 37, 110) + { 0, { 0, 0, 0}}, // ( 38, 110) + { 0, { 0, 0, 0}}, // ( 39, 110) + { 0, { 0, 0, 0}}, // ( 40, 110) + { 0, { 0, 0, 0}}, // ( 41, 110) + { 0, { 0, 0, 0}}, // ( 42, 110) + { 0, { 0, 0, 0}}, // ( 43, 110) + { 0, { 0, 0, 0}}, // ( 44, 110) + { 0, { 0, 0, 0}}, // ( 45, 110) + { 0, { 0, 0, 0}}, // ( 46, 110) + { 0, { 0, 0, 0}}, // ( 47, 110) + { 0, { 0, 0, 0}}, // ( 48, 110) + { 0, { 0, 0, 0}}, // ( 49, 110) + { 0, { 0, 0, 0}}, // ( 50, 110) + { 0, { 0, 0, 0}}, // ( 51, 110) + { 0, { 0, 0, 0}}, // ( 52, 110) + { 0, { 0, 0, 0}}, // ( 53, 110) + { 0, { 0, 0, 0}}, // ( 54, 110) + { 0, { 0, 0, 0}}, // ( 55, 110) + { 0, { 0, 0, 0}}, // ( 56, 110) + { 0, { 0, 0, 0}}, // ( 57, 110) + { 0, { 0, 0, 0}}, // ( 58, 110) + { 0, { 0, 0, 0}}, // ( 59, 110) + { 0, { 0, 0, 0}}, // ( 60, 110) + { 0, { 0, 0, 0}}, // ( 61, 110) + { 0, { 0, 0, 0}}, // ( 62, 110) + { 0, { 0, 0, 0}}, // ( 63, 110) + { 0, { 0, 0, 0}}, // ( 64, 110) + { 0, { 0, 0, 0}}, // ( 65, 110) + { 0, { 0, 0, 0}}, // ( 66, 110) + { 0, { 0, 0, 0}}, // ( 67, 110) + { 0, { 0, 0, 0}}, // ( 68, 110) + { 0, { 0, 0, 0}}, // ( 69, 110) + { 0, { 0, 0, 0}}, // ( 70, 110) + { 0, { 0, 0, 0}}, // ( 71, 110) + { 0, { 0, 0, 0}}, // ( 72, 110) + { 0, { 0, 0, 0}}, // ( 73, 110) + { 0, { 0, 0, 0}}, // ( 74, 110) + { 0, { 0, 0, 0}}, // ( 75, 110) + { 0, { 0, 0, 0}}, // ( 76, 110) + { 0, { 0, 0, 0}}, // ( 77, 110) + { 0, { 0, 0, 0}}, // ( 78, 110) + { 0, { 0, 0, 0}}, // ( 79, 110) + { 0, { 0, 0, 0}}, // ( 80, 110) + { 0, { 0, 0, 0}}, // ( 81, 110) + { 0, { 0, 0, 0}}, // ( 82, 110) + { 0, { 0, 0, 0}}, // ( 83, 110) + { 0, { 0, 0, 0}}, // ( 84, 110) + { 0, { 0, 0, 0}}, // ( 85, 110) + { 0, { 0, 0, 0}}, // ( 86, 110) + { 0, { 0, 0, 0}}, // ( 87, 110) + { 0, { 0, 0, 0}}, // ( 88, 110) + { 0, { 0, 0, 0}}, // ( 89, 110) + { 0, { 0, 0, 0}}, // ( 90, 110) + { 0, { 0, 0, 0}}, // ( 91, 110) + { 0, { 0, 0, 0}}, // ( 92, 110) + { 0, { 0, 0, 0}}, // ( 93, 110) + { 0, { 0, 0, 0}}, // ( 94, 110) + { 0, { 0, 0, 0}}, // ( 95, 110) + { 0, { 0, 0, 0}}, // ( 96, 110) + { 0, { 0, 0, 0}}, // ( 97, 110) + { 0, { 0, 0, 0}}, // ( 98, 110) + { 0, { 0, 0, 0}}, // ( 99, 110) + { 0, { 0, 0, 0}}, // (100, 110) + { 0, { 0, 0, 0}}, // (101, 110) + { 0, { 0, 0, 0}}, // (102, 110) + { 0, { 0, 0, 0}}, // (103, 110) + { 0, { 0, 0, 0}}, // (104, 110) + { 0, { 0, 0, 0}}, // (105, 110) + { 0, { 0, 0, 0}}, // (106, 110) + { 0, { 0, 0, 0}}, // (107, 110) + { 0, { 0, 0, 0}}, // (108, 110) + { 0, { 0, 0, 0}}, // (109, 110) + { 0, { 0, 0, 0}}, // (110, 110) + { 0, { 0, 0, 0}}, // (111, 110) + { 0, { 0, 0, 0}}, // (112, 110) + { 0, { 0, 0, 0}}, // (113, 110) + { 0, { 0, 0, 0}}, // (114, 110) + { 0, { 0, 0, 0}}, // (115, 110) + { 0, { 0, 0, 0}}, // (116, 110) + { 0, { 0, 0, 0}}, // (117, 110) + { 0, { 0, 0, 0}}, // (118, 110) + { 0, { 0, 0, 0}}, // (119, 110) + { 0, { 0, 0, 0}}, // (120, 110) + { 0, { 0, 0, 0}}, // (121, 110) + { 0, { 0, 0, 0}}, // (122, 110) + { 0, { 0, 0, 0}}, // (123, 110) + { 0, { 0, 0, 0}}, // (124, 110) + { 0, { 0, 0, 0}}, // (125, 110) + { 0, { 0, 0, 0}}, // (126, 110) + { 0, { 0, 0, 0}}, // (127, 110) + { 0, { 0, 0, 0}}, // (128, 110) + { 0, { 0, 0, 0}}, // (129, 110) + { 0, { 0, 0, 0}}, // (130, 110) + { 0, { 0, 0, 0}}, // (131, 110) + { 0, { 0, 0, 0}}, // (132, 110) + { 0, { 0, 0, 0}}, // (133, 110) + { 0, { 0, 0, 0}}, // (134, 110) + { 0, { 0, 0, 0}}, // (135, 110) + { 0, { 0, 0, 0}}, // (136, 110) + { 0, { 0, 0, 0}}, // (137, 110) + { 0, { 0, 0, 0}}, // (138, 110) + { 0, { 0, 0, 0}}, // (139, 110) + { 0, { 0, 0, 0}}, // (140, 110) + { 0, { 0, 0, 0}}, // (141, 110) + { 0, { 0, 0, 0}}, // (142, 110) + { 0, { 0, 0, 0}}, // (143, 110) + { 0, { 0, 0, 0}}, // (144, 110) + { 0, { 0, 0, 0}}, // (145, 110) + { 0, { 0, 0, 0}}, // (146, 110) + { 0, { 0, 0, 0}}, // (147, 110) + { 0, { 0, 0, 0}}, // (148, 110) + { 0, { 0, 0, 0}}, // (149, 110) + { 0, { 0, 0, 0}}, // (150, 110) + { 0, { 0, 0, 0}}, // (151, 110) + { 0, { 0, 0, 0}}, // (152, 110) + { 0, { 0, 0, 0}}, // (153, 110) + { 0, { 0, 0, 0}}, // (154, 110) + { 0, { 0, 0, 0}}, // (155, 110) + { 0, { 0, 0, 0}}, // (156, 110) + { 0, { 0, 0, 0}}, // (157, 110) + { 0, { 0, 0, 0}}, // (158, 110) + { 0, { 0, 0, 0}}, // (159, 110) + { 0, { 0, 0, 0}}, // (160, 110) + { 0, { 0, 0, 0}}, // (161, 110) + { 0, { 0, 0, 0}}, // (162, 110) + { 0, { 0, 0, 0}}, // (163, 110) + { 0, { 0, 0, 0}}, // (164, 110) + { 0, { 0, 0, 0}}, // (165, 110) + { 0, { 0, 0, 0}}, // (166, 110) + { 0, { 0, 0, 0}}, // (167, 110) + { 0, { 0, 0, 0}}, // (168, 110) + { 0, { 0, 0, 0}}, // (169, 110) + { 0, { 0, 0, 0}}, // (170, 110) + { 0, { 0, 0, 0}}, // (171, 110) + { 0, { 0, 0, 0}}, // (172, 110) + { 0, { 0, 0, 0}}, // (173, 110) + { 0, { 0, 0, 0}}, // (174, 110) + { 52, { 0, 0, 0}}, // (175, 110) + {128, { 0, 0, 0}}, // (176, 110) + {128, { 0, 0, 0}}, // (177, 110) + {128, { 0, 0, 0}}, // (178, 110) + {128, { 0, 0, 0}}, // (179, 110) + {128, { 0, 0, 0}}, // ( 0, 111) + {128, { 0, 0, 0}}, // ( 1, 111) + {128, { 0, 0, 0}}, // ( 2, 111) + {128, { 0, 0, 0}}, // ( 3, 111) + { 83, { 0, 0, 0}}, // ( 4, 111) + { 0, { 0, 0, 0}}, // ( 5, 111) + { 0, { 0, 0, 0}}, // ( 6, 111) + { 0, { 0, 0, 0}}, // ( 7, 111) + { 0, { 0, 0, 0}}, // ( 8, 111) + { 0, { 0, 0, 0}}, // ( 9, 111) + { 0, { 0, 0, 0}}, // ( 10, 111) + { 0, { 0, 0, 0}}, // ( 11, 111) + { 0, { 0, 0, 0}}, // ( 12, 111) + { 0, { 0, 0, 0}}, // ( 13, 111) + { 0, { 0, 0, 0}}, // ( 14, 111) + { 0, { 0, 0, 0}}, // ( 15, 111) + { 0, { 0, 0, 0}}, // ( 16, 111) + { 0, { 0, 0, 0}}, // ( 17, 111) + { 0, { 0, 0, 0}}, // ( 18, 111) + { 0, { 0, 0, 0}}, // ( 19, 111) + { 0, { 0, 0, 0}}, // ( 20, 111) + { 0, { 0, 0, 0}}, // ( 21, 111) + { 0, { 0, 0, 0}}, // ( 22, 111) + { 0, { 0, 0, 0}}, // ( 23, 111) + { 0, { 0, 0, 0}}, // ( 24, 111) + { 0, { 0, 0, 0}}, // ( 25, 111) + { 0, { 0, 0, 0}}, // ( 26, 111) + { 0, { 0, 0, 0}}, // ( 27, 111) + { 0, { 0, 0, 0}}, // ( 28, 111) + { 0, { 0, 0, 0}}, // ( 29, 111) + { 0, { 0, 0, 0}}, // ( 30, 111) + { 0, { 0, 0, 0}}, // ( 31, 111) + { 0, { 0, 0, 0}}, // ( 32, 111) + { 0, { 0, 0, 0}}, // ( 33, 111) + { 0, { 0, 0, 0}}, // ( 34, 111) + { 0, { 0, 0, 0}}, // ( 35, 111) + { 0, { 0, 0, 0}}, // ( 36, 111) + { 0, { 0, 0, 0}}, // ( 37, 111) + { 0, { 0, 0, 0}}, // ( 38, 111) + { 0, { 0, 0, 0}}, // ( 39, 111) + { 0, { 0, 0, 0}}, // ( 40, 111) + { 0, { 0, 0, 0}}, // ( 41, 111) + { 0, { 0, 0, 0}}, // ( 42, 111) + { 0, { 0, 0, 0}}, // ( 43, 111) + { 0, { 0, 0, 0}}, // ( 44, 111) + { 0, { 0, 0, 0}}, // ( 45, 111) + { 0, { 0, 0, 0}}, // ( 46, 111) + { 0, { 0, 0, 0}}, // ( 47, 111) + { 0, { 0, 0, 0}}, // ( 48, 111) + { 0, { 0, 0, 0}}, // ( 49, 111) + { 0, { 0, 0, 0}}, // ( 50, 111) + { 0, { 0, 0, 0}}, // ( 51, 111) + { 0, { 0, 0, 0}}, // ( 52, 111) + { 0, { 0, 0, 0}}, // ( 53, 111) + { 0, { 0, 0, 0}}, // ( 54, 111) + { 0, { 0, 0, 0}}, // ( 55, 111) + { 0, { 0, 0, 0}}, // ( 56, 111) + { 0, { 0, 0, 0}}, // ( 57, 111) + { 0, { 0, 0, 0}}, // ( 58, 111) + { 0, { 0, 0, 0}}, // ( 59, 111) + { 0, { 0, 0, 0}}, // ( 60, 111) + { 0, { 0, 0, 0}}, // ( 61, 111) + { 0, { 0, 0, 0}}, // ( 62, 111) + { 0, { 0, 0, 0}}, // ( 63, 111) + { 0, { 0, 0, 0}}, // ( 64, 111) + { 0, { 0, 0, 0}}, // ( 65, 111) + { 0, { 0, 0, 0}}, // ( 66, 111) + { 0, { 0, 0, 0}}, // ( 67, 111) + { 0, { 0, 0, 0}}, // ( 68, 111) + { 0, { 0, 0, 0}}, // ( 69, 111) + { 0, { 0, 0, 0}}, // ( 70, 111) + { 0, { 0, 0, 0}}, // ( 71, 111) + { 0, { 0, 0, 0}}, // ( 72, 111) + { 0, { 0, 0, 0}}, // ( 73, 111) + { 0, { 0, 0, 0}}, // ( 74, 111) + { 0, { 0, 0, 0}}, // ( 75, 111) + { 0, { 0, 0, 0}}, // ( 76, 111) + { 0, { 0, 0, 0}}, // ( 77, 111) + { 0, { 0, 0, 0}}, // ( 78, 111) + { 0, { 0, 0, 0}}, // ( 79, 111) + { 0, { 0, 0, 0}}, // ( 80, 111) + { 0, { 0, 0, 0}}, // ( 81, 111) + { 0, { 0, 0, 0}}, // ( 82, 111) + { 0, { 0, 0, 0}}, // ( 83, 111) + { 0, { 0, 0, 0}}, // ( 84, 111) + { 0, { 0, 0, 0}}, // ( 85, 111) + { 0, { 0, 0, 0}}, // ( 86, 111) + { 0, { 0, 0, 0}}, // ( 87, 111) + { 0, { 0, 0, 0}}, // ( 88, 111) + { 0, { 0, 0, 0}}, // ( 89, 111) + { 0, { 0, 0, 0}}, // ( 90, 111) + { 0, { 0, 0, 0}}, // ( 91, 111) + { 0, { 0, 0, 0}}, // ( 92, 111) + { 0, { 0, 0, 0}}, // ( 93, 111) + { 0, { 0, 0, 0}}, // ( 94, 111) + { 0, { 0, 0, 0}}, // ( 95, 111) + { 0, { 0, 0, 0}}, // ( 96, 111) + { 0, { 0, 0, 0}}, // ( 97, 111) + { 0, { 0, 0, 0}}, // ( 98, 111) + { 0, { 0, 0, 0}}, // ( 99, 111) + { 0, { 0, 0, 0}}, // (100, 111) + { 0, { 0, 0, 0}}, // (101, 111) + { 0, { 0, 0, 0}}, // (102, 111) + { 0, { 0, 0, 0}}, // (103, 111) + { 0, { 0, 0, 0}}, // (104, 111) + { 0, { 0, 0, 0}}, // (105, 111) + { 0, { 0, 0, 0}}, // (106, 111) + { 0, { 0, 0, 0}}, // (107, 111) + { 0, { 0, 0, 0}}, // (108, 111) + { 0, { 0, 0, 0}}, // (109, 111) + { 0, { 0, 0, 0}}, // (110, 111) + { 0, { 0, 0, 0}}, // (111, 111) + { 0, { 0, 0, 0}}, // (112, 111) + { 0, { 0, 0, 0}}, // (113, 111) + { 0, { 0, 0, 0}}, // (114, 111) + { 0, { 0, 0, 0}}, // (115, 111) + { 0, { 0, 0, 0}}, // (116, 111) + { 0, { 0, 0, 0}}, // (117, 111) + { 0, { 0, 0, 0}}, // (118, 111) + { 0, { 0, 0, 0}}, // (119, 111) + { 0, { 0, 0, 0}}, // (120, 111) + { 0, { 0, 0, 0}}, // (121, 111) + { 0, { 0, 0, 0}}, // (122, 111) + { 0, { 0, 0, 0}}, // (123, 111) + { 0, { 0, 0, 0}}, // (124, 111) + { 0, { 0, 0, 0}}, // (125, 111) + { 0, { 0, 0, 0}}, // (126, 111) + { 0, { 0, 0, 0}}, // (127, 111) + { 0, { 0, 0, 0}}, // (128, 111) + { 0, { 0, 0, 0}}, // (129, 111) + { 0, { 0, 0, 0}}, // (130, 111) + { 0, { 0, 0, 0}}, // (131, 111) + { 0, { 0, 0, 0}}, // (132, 111) + { 0, { 0, 0, 0}}, // (133, 111) + { 0, { 0, 0, 0}}, // (134, 111) + { 0, { 0, 0, 0}}, // (135, 111) + { 0, { 0, 0, 0}}, // (136, 111) + { 0, { 0, 0, 0}}, // (137, 111) + { 0, { 0, 0, 0}}, // (138, 111) + { 0, { 0, 0, 0}}, // (139, 111) + { 0, { 0, 0, 0}}, // (140, 111) + { 0, { 0, 0, 0}}, // (141, 111) + { 0, { 0, 0, 0}}, // (142, 111) + { 0, { 0, 0, 0}}, // (143, 111) + { 0, { 0, 0, 0}}, // (144, 111) + { 0, { 0, 0, 0}}, // (145, 111) + { 0, { 0, 0, 0}}, // (146, 111) + { 0, { 0, 0, 0}}, // (147, 111) + { 0, { 0, 0, 0}}, // (148, 111) + { 0, { 0, 0, 0}}, // (149, 111) + { 0, { 0, 0, 0}}, // (150, 111) + { 0, { 0, 0, 0}}, // (151, 111) + { 0, { 0, 0, 0}}, // (152, 111) + { 0, { 0, 0, 0}}, // (153, 111) + { 0, { 0, 0, 0}}, // (154, 111) + { 0, { 0, 0, 0}}, // (155, 111) + { 0, { 0, 0, 0}}, // (156, 111) + { 0, { 0, 0, 0}}, // (157, 111) + { 0, { 0, 0, 0}}, // (158, 111) + { 0, { 0, 0, 0}}, // (159, 111) + { 0, { 0, 0, 0}}, // (160, 111) + { 0, { 0, 0, 0}}, // (161, 111) + { 0, { 0, 0, 0}}, // (162, 111) + { 0, { 0, 0, 0}}, // (163, 111) + { 0, { 0, 0, 0}}, // (164, 111) + { 0, { 0, 0, 0}}, // (165, 111) + { 0, { 0, 0, 0}}, // (166, 111) + { 0, { 0, 0, 0}}, // (167, 111) + { 0, { 0, 0, 0}}, // (168, 111) + { 0, { 0, 0, 0}}, // (169, 111) + { 0, { 0, 0, 0}}, // (170, 111) + { 0, { 0, 0, 0}}, // (171, 111) + { 0, { 0, 0, 0}}, // (172, 111) + { 0, { 0, 0, 0}}, // (173, 111) + { 0, { 0, 0, 0}}, // (174, 111) + { 83, { 0, 0, 0}}, // (175, 111) + {128, { 0, 0, 0}}, // (176, 111) + {128, { 0, 0, 0}}, // (177, 111) + {128, { 0, 0, 0}}, // (178, 111) + {128, { 0, 0, 0}}, // (179, 111) + {128, { 0, 0, 0}}, // ( 0, 112) + {128, { 0, 0, 0}}, // ( 1, 112) + {128, { 0, 0, 0}}, // ( 2, 112) + {128, { 0, 0, 0}}, // ( 3, 112) + {117, { 0, 0, 0}}, // ( 4, 112) + { 1, { 0, 0, 0}}, // ( 5, 112) + { 0, { 0, 0, 0}}, // ( 6, 112) + { 0, { 0, 0, 0}}, // ( 7, 112) + { 0, { 0, 0, 0}}, // ( 8, 112) + { 0, { 0, 0, 0}}, // ( 9, 112) + { 0, { 0, 0, 0}}, // ( 10, 112) + { 0, { 0, 0, 0}}, // ( 11, 112) + { 0, { 0, 0, 0}}, // ( 12, 112) + { 0, { 0, 0, 0}}, // ( 13, 112) + { 0, { 0, 0, 0}}, // ( 14, 112) + { 0, { 0, 0, 0}}, // ( 15, 112) + { 0, { 0, 0, 0}}, // ( 16, 112) + { 0, { 0, 0, 0}}, // ( 17, 112) + { 0, { 0, 0, 0}}, // ( 18, 112) + { 0, { 0, 0, 0}}, // ( 19, 112) + { 0, { 0, 0, 0}}, // ( 20, 112) + { 0, { 0, 0, 0}}, // ( 21, 112) + { 0, { 0, 0, 0}}, // ( 22, 112) + { 0, { 0, 0, 0}}, // ( 23, 112) + { 0, { 0, 0, 0}}, // ( 24, 112) + { 0, { 0, 0, 0}}, // ( 25, 112) + { 0, { 0, 0, 0}}, // ( 26, 112) + { 0, { 0, 0, 0}}, // ( 27, 112) + { 0, { 0, 0, 0}}, // ( 28, 112) + { 0, { 0, 0, 0}}, // ( 29, 112) + { 0, { 0, 0, 0}}, // ( 30, 112) + { 0, { 0, 0, 0}}, // ( 31, 112) + { 0, { 0, 0, 0}}, // ( 32, 112) + { 0, { 0, 0, 0}}, // ( 33, 112) + { 0, { 0, 0, 0}}, // ( 34, 112) + { 0, { 0, 0, 0}}, // ( 35, 112) + { 0, { 0, 0, 0}}, // ( 36, 112) + { 0, { 0, 0, 0}}, // ( 37, 112) + { 0, { 0, 0, 0}}, // ( 38, 112) + { 0, { 0, 0, 0}}, // ( 39, 112) + { 0, { 0, 0, 0}}, // ( 40, 112) + { 0, { 0, 0, 0}}, // ( 41, 112) + { 0, { 0, 0, 0}}, // ( 42, 112) + { 0, { 0, 0, 0}}, // ( 43, 112) + { 0, { 0, 0, 0}}, // ( 44, 112) + { 0, { 0, 0, 0}}, // ( 45, 112) + { 0, { 0, 0, 0}}, // ( 46, 112) + { 0, { 0, 0, 0}}, // ( 47, 112) + { 0, { 0, 0, 0}}, // ( 48, 112) + { 0, { 0, 0, 0}}, // ( 49, 112) + { 0, { 0, 0, 0}}, // ( 50, 112) + { 0, { 0, 0, 0}}, // ( 51, 112) + { 0, { 0, 0, 0}}, // ( 52, 112) + { 0, { 0, 0, 0}}, // ( 53, 112) + { 0, { 0, 0, 0}}, // ( 54, 112) + { 0, { 0, 0, 0}}, // ( 55, 112) + { 0, { 0, 0, 0}}, // ( 56, 112) + { 0, { 0, 0, 0}}, // ( 57, 112) + { 0, { 0, 0, 0}}, // ( 58, 112) + { 0, { 0, 0, 0}}, // ( 59, 112) + { 0, { 0, 0, 0}}, // ( 60, 112) + { 0, { 0, 0, 0}}, // ( 61, 112) + { 0, { 0, 0, 0}}, // ( 62, 112) + { 0, { 0, 0, 0}}, // ( 63, 112) + { 0, { 0, 0, 0}}, // ( 64, 112) + { 0, { 0, 0, 0}}, // ( 65, 112) + { 0, { 0, 0, 0}}, // ( 66, 112) + { 0, { 0, 0, 0}}, // ( 67, 112) + { 0, { 0, 0, 0}}, // ( 68, 112) + { 0, { 0, 0, 0}}, // ( 69, 112) + { 0, { 0, 0, 0}}, // ( 70, 112) + { 0, { 0, 0, 0}}, // ( 71, 112) + { 0, { 0, 0, 0}}, // ( 72, 112) + { 0, { 0, 0, 0}}, // ( 73, 112) + { 0, { 0, 0, 0}}, // ( 74, 112) + { 0, { 0, 0, 0}}, // ( 75, 112) + { 0, { 0, 0, 0}}, // ( 76, 112) + { 0, { 0, 0, 0}}, // ( 77, 112) + { 0, { 0, 0, 0}}, // ( 78, 112) + { 0, { 0, 0, 0}}, // ( 79, 112) + { 0, { 0, 0, 0}}, // ( 80, 112) + { 0, { 0, 0, 0}}, // ( 81, 112) + { 0, { 0, 0, 0}}, // ( 82, 112) + { 0, { 0, 0, 0}}, // ( 83, 112) + { 0, { 0, 0, 0}}, // ( 84, 112) + { 0, { 0, 0, 0}}, // ( 85, 112) + { 0, { 0, 0, 0}}, // ( 86, 112) + { 0, { 0, 0, 0}}, // ( 87, 112) + { 0, { 0, 0, 0}}, // ( 88, 112) + { 0, { 0, 0, 0}}, // ( 89, 112) + { 0, { 0, 0, 0}}, // ( 90, 112) + { 0, { 0, 0, 0}}, // ( 91, 112) + { 0, { 0, 0, 0}}, // ( 92, 112) + { 0, { 0, 0, 0}}, // ( 93, 112) + { 0, { 0, 0, 0}}, // ( 94, 112) + { 0, { 0, 0, 0}}, // ( 95, 112) + { 0, { 0, 0, 0}}, // ( 96, 112) + { 0, { 0, 0, 0}}, // ( 97, 112) + { 0, { 0, 0, 0}}, // ( 98, 112) + { 0, { 0, 0, 0}}, // ( 99, 112) + { 0, { 0, 0, 0}}, // (100, 112) + { 0, { 0, 0, 0}}, // (101, 112) + { 0, { 0, 0, 0}}, // (102, 112) + { 0, { 0, 0, 0}}, // (103, 112) + { 0, { 0, 0, 0}}, // (104, 112) + { 0, { 0, 0, 0}}, // (105, 112) + { 0, { 0, 0, 0}}, // (106, 112) + { 0, { 0, 0, 0}}, // (107, 112) + { 0, { 0, 0, 0}}, // (108, 112) + { 0, { 0, 0, 0}}, // (109, 112) + { 0, { 0, 0, 0}}, // (110, 112) + { 0, { 0, 0, 0}}, // (111, 112) + { 0, { 0, 0, 0}}, // (112, 112) + { 0, { 0, 0, 0}}, // (113, 112) + { 0, { 0, 0, 0}}, // (114, 112) + { 0, { 0, 0, 0}}, // (115, 112) + { 0, { 0, 0, 0}}, // (116, 112) + { 0, { 0, 0, 0}}, // (117, 112) + { 0, { 0, 0, 0}}, // (118, 112) + { 0, { 0, 0, 0}}, // (119, 112) + { 0, { 0, 0, 0}}, // (120, 112) + { 0, { 0, 0, 0}}, // (121, 112) + { 0, { 0, 0, 0}}, // (122, 112) + { 0, { 0, 0, 0}}, // (123, 112) + { 0, { 0, 0, 0}}, // (124, 112) + { 0, { 0, 0, 0}}, // (125, 112) + { 0, { 0, 0, 0}}, // (126, 112) + { 0, { 0, 0, 0}}, // (127, 112) + { 0, { 0, 0, 0}}, // (128, 112) + { 0, { 0, 0, 0}}, // (129, 112) + { 0, { 0, 0, 0}}, // (130, 112) + { 0, { 0, 0, 0}}, // (131, 112) + { 0, { 0, 0, 0}}, // (132, 112) + { 0, { 0, 0, 0}}, // (133, 112) + { 0, { 0, 0, 0}}, // (134, 112) + { 0, { 0, 0, 0}}, // (135, 112) + { 0, { 0, 0, 0}}, // (136, 112) + { 0, { 0, 0, 0}}, // (137, 112) + { 0, { 0, 0, 0}}, // (138, 112) + { 0, { 0, 0, 0}}, // (139, 112) + { 0, { 0, 0, 0}}, // (140, 112) + { 0, { 0, 0, 0}}, // (141, 112) + { 0, { 0, 0, 0}}, // (142, 112) + { 0, { 0, 0, 0}}, // (143, 112) + { 0, { 0, 0, 0}}, // (144, 112) + { 0, { 0, 0, 0}}, // (145, 112) + { 0, { 0, 0, 0}}, // (146, 112) + { 0, { 0, 0, 0}}, // (147, 112) + { 0, { 0, 0, 0}}, // (148, 112) + { 0, { 0, 0, 0}}, // (149, 112) + { 0, { 0, 0, 0}}, // (150, 112) + { 0, { 0, 0, 0}}, // (151, 112) + { 0, { 0, 0, 0}}, // (152, 112) + { 0, { 0, 0, 0}}, // (153, 112) + { 0, { 0, 0, 0}}, // (154, 112) + { 0, { 0, 0, 0}}, // (155, 112) + { 0, { 0, 0, 0}}, // (156, 112) + { 0, { 0, 0, 0}}, // (157, 112) + { 0, { 0, 0, 0}}, // (158, 112) + { 0, { 0, 0, 0}}, // (159, 112) + { 0, { 0, 0, 0}}, // (160, 112) + { 0, { 0, 0, 0}}, // (161, 112) + { 0, { 0, 0, 0}}, // (162, 112) + { 0, { 0, 0, 0}}, // (163, 112) + { 0, { 0, 0, 0}}, // (164, 112) + { 0, { 0, 0, 0}}, // (165, 112) + { 0, { 0, 0, 0}}, // (166, 112) + { 0, { 0, 0, 0}}, // (167, 112) + { 0, { 0, 0, 0}}, // (168, 112) + { 0, { 0, 0, 0}}, // (169, 112) + { 0, { 0, 0, 0}}, // (170, 112) + { 0, { 0, 0, 0}}, // (171, 112) + { 0, { 0, 0, 0}}, // (172, 112) + { 0, { 0, 0, 0}}, // (173, 112) + { 1, { 0, 0, 0}}, // (174, 112) + {115, { 0, 0, 0}}, // (175, 112) + {128, { 0, 0, 0}}, // (176, 112) + {128, { 0, 0, 0}}, // (177, 112) + {128, { 0, 0, 0}}, // (178, 112) + {128, { 0, 0, 0}}, // (179, 112) + {128, { 0, 0, 0}}, // ( 0, 113) + {128, { 0, 0, 0}}, // ( 1, 113) + {128, { 0, 0, 0}}, // ( 2, 113) + {128, { 0, 0, 0}}, // ( 3, 113) + {128, { 0, 0, 0}}, // ( 4, 113) + { 25, { 0, 0, 0}}, // ( 5, 113) + { 0, { 0, 0, 0}}, // ( 6, 113) + { 0, { 0, 0, 0}}, // ( 7, 113) + { 0, { 0, 0, 0}}, // ( 8, 113) + { 0, { 0, 0, 0}}, // ( 9, 113) + { 0, { 0, 0, 0}}, // ( 10, 113) + { 0, { 0, 0, 0}}, // ( 11, 113) + { 0, { 0, 0, 0}}, // ( 12, 113) + { 0, { 0, 0, 0}}, // ( 13, 113) + { 0, { 0, 0, 0}}, // ( 14, 113) + { 0, { 0, 0, 0}}, // ( 15, 113) + { 0, { 0, 0, 0}}, // ( 16, 113) + { 0, { 0, 0, 0}}, // ( 17, 113) + { 0, { 0, 0, 0}}, // ( 18, 113) + { 0, { 0, 0, 0}}, // ( 19, 113) + { 0, { 0, 0, 0}}, // ( 20, 113) + { 0, { 0, 0, 0}}, // ( 21, 113) + { 0, { 0, 0, 0}}, // ( 22, 113) + { 0, { 0, 0, 0}}, // ( 23, 113) + { 0, { 0, 0, 0}}, // ( 24, 113) + { 0, { 0, 0, 0}}, // ( 25, 113) + { 0, { 0, 0, 0}}, // ( 26, 113) + { 0, { 0, 0, 0}}, // ( 27, 113) + { 0, { 0, 0, 0}}, // ( 28, 113) + { 0, { 0, 0, 0}}, // ( 29, 113) + { 0, { 0, 0, 0}}, // ( 30, 113) + { 0, { 0, 0, 0}}, // ( 31, 113) + { 0, { 0, 0, 0}}, // ( 32, 113) + { 0, { 0, 0, 0}}, // ( 33, 113) + { 0, { 0, 0, 0}}, // ( 34, 113) + { 0, { 0, 0, 0}}, // ( 35, 113) + { 0, { 0, 0, 0}}, // ( 36, 113) + { 0, { 0, 0, 0}}, // ( 37, 113) + { 0, { 0, 0, 0}}, // ( 38, 113) + { 0, { 0, 0, 0}}, // ( 39, 113) + { 0, { 0, 0, 0}}, // ( 40, 113) + { 0, { 0, 0, 0}}, // ( 41, 113) + { 0, { 0, 0, 0}}, // ( 42, 113) + { 0, { 0, 0, 0}}, // ( 43, 113) + { 0, { 0, 0, 0}}, // ( 44, 113) + { 0, { 0, 0, 0}}, // ( 45, 113) + { 0, { 0, 0, 0}}, // ( 46, 113) + { 0, { 0, 0, 0}}, // ( 47, 113) + { 0, { 0, 0, 0}}, // ( 48, 113) + { 0, { 0, 0, 0}}, // ( 49, 113) + { 0, { 0, 0, 0}}, // ( 50, 113) + { 0, { 0, 0, 0}}, // ( 51, 113) + { 0, { 0, 0, 0}}, // ( 52, 113) + { 0, { 0, 0, 0}}, // ( 53, 113) + { 0, { 0, 0, 0}}, // ( 54, 113) + { 0, { 0, 0, 0}}, // ( 55, 113) + { 0, { 0, 0, 0}}, // ( 56, 113) + { 0, { 0, 0, 0}}, // ( 57, 113) + { 0, { 0, 0, 0}}, // ( 58, 113) + { 0, { 0, 0, 0}}, // ( 59, 113) + { 0, { 0, 0, 0}}, // ( 60, 113) + { 0, { 0, 0, 0}}, // ( 61, 113) + { 0, { 0, 0, 0}}, // ( 62, 113) + { 0, { 0, 0, 0}}, // ( 63, 113) + { 0, { 0, 0, 0}}, // ( 64, 113) + { 0, { 0, 0, 0}}, // ( 65, 113) + { 0, { 0, 0, 0}}, // ( 66, 113) + { 0, { 0, 0, 0}}, // ( 67, 113) + { 0, { 0, 0, 0}}, // ( 68, 113) + { 0, { 0, 0, 0}}, // ( 69, 113) + { 0, { 0, 0, 0}}, // ( 70, 113) + { 0, { 0, 0, 0}}, // ( 71, 113) + { 0, { 0, 0, 0}}, // ( 72, 113) + { 0, { 0, 0, 0}}, // ( 73, 113) + { 0, { 0, 0, 0}}, // ( 74, 113) + { 0, { 0, 0, 0}}, // ( 75, 113) + { 0, { 0, 0, 0}}, // ( 76, 113) + { 0, { 0, 0, 0}}, // ( 77, 113) + { 0, { 0, 0, 0}}, // ( 78, 113) + { 0, { 0, 0, 0}}, // ( 79, 113) + { 0, { 0, 0, 0}}, // ( 80, 113) + { 0, { 0, 0, 0}}, // ( 81, 113) + { 0, { 0, 0, 0}}, // ( 82, 113) + { 0, { 0, 0, 0}}, // ( 83, 113) + { 0, { 0, 0, 0}}, // ( 84, 113) + { 0, { 0, 0, 0}}, // ( 85, 113) + { 0, { 0, 0, 0}}, // ( 86, 113) + { 0, { 0, 0, 0}}, // ( 87, 113) + { 0, { 0, 0, 0}}, // ( 88, 113) + { 0, { 0, 0, 0}}, // ( 89, 113) + { 0, { 0, 0, 0}}, // ( 90, 113) + { 0, { 0, 0, 0}}, // ( 91, 113) + { 0, { 0, 0, 0}}, // ( 92, 113) + { 0, { 0, 0, 0}}, // ( 93, 113) + { 0, { 0, 0, 0}}, // ( 94, 113) + { 0, { 0, 0, 0}}, // ( 95, 113) + { 0, { 0, 0, 0}}, // ( 96, 113) + { 0, { 0, 0, 0}}, // ( 97, 113) + { 0, { 0, 0, 0}}, // ( 98, 113) + { 0, { 0, 0, 0}}, // ( 99, 113) + { 0, { 0, 0, 0}}, // (100, 113) + { 0, { 0, 0, 0}}, // (101, 113) + { 0, { 0, 0, 0}}, // (102, 113) + { 0, { 0, 0, 0}}, // (103, 113) + { 0, { 0, 0, 0}}, // (104, 113) + { 0, { 0, 0, 0}}, // (105, 113) + { 0, { 0, 0, 0}}, // (106, 113) + { 0, { 0, 0, 0}}, // (107, 113) + { 0, { 0, 0, 0}}, // (108, 113) + { 0, { 0, 0, 0}}, // (109, 113) + { 0, { 0, 0, 0}}, // (110, 113) + { 0, { 0, 0, 0}}, // (111, 113) + { 0, { 0, 0, 0}}, // (112, 113) + { 0, { 0, 0, 0}}, // (113, 113) + { 0, { 0, 0, 0}}, // (114, 113) + { 0, { 0, 0, 0}}, // (115, 113) + { 0, { 0, 0, 0}}, // (116, 113) + { 0, { 0, 0, 0}}, // (117, 113) + { 0, { 0, 0, 0}}, // (118, 113) + { 0, { 0, 0, 0}}, // (119, 113) + { 0, { 0, 0, 0}}, // (120, 113) + { 0, { 0, 0, 0}}, // (121, 113) + { 0, { 0, 0, 0}}, // (122, 113) + { 0, { 0, 0, 0}}, // (123, 113) + { 0, { 0, 0, 0}}, // (124, 113) + { 0, { 0, 0, 0}}, // (125, 113) + { 0, { 0, 0, 0}}, // (126, 113) + { 0, { 0, 0, 0}}, // (127, 113) + { 0, { 0, 0, 0}}, // (128, 113) + { 0, { 0, 0, 0}}, // (129, 113) + { 0, { 0, 0, 0}}, // (130, 113) + { 0, { 0, 0, 0}}, // (131, 113) + { 0, { 0, 0, 0}}, // (132, 113) + { 0, { 0, 0, 0}}, // (133, 113) + { 0, { 0, 0, 0}}, // (134, 113) + { 0, { 0, 0, 0}}, // (135, 113) + { 0, { 0, 0, 0}}, // (136, 113) + { 0, { 0, 0, 0}}, // (137, 113) + { 0, { 0, 0, 0}}, // (138, 113) + { 0, { 0, 0, 0}}, // (139, 113) + { 0, { 0, 0, 0}}, // (140, 113) + { 0, { 0, 0, 0}}, // (141, 113) + { 0, { 0, 0, 0}}, // (142, 113) + { 0, { 0, 0, 0}}, // (143, 113) + { 0, { 0, 0, 0}}, // (144, 113) + { 0, { 0, 0, 0}}, // (145, 113) + { 0, { 0, 0, 0}}, // (146, 113) + { 0, { 0, 0, 0}}, // (147, 113) + { 0, { 0, 0, 0}}, // (148, 113) + { 0, { 0, 0, 0}}, // (149, 113) + { 0, { 0, 0, 0}}, // (150, 113) + { 0, { 0, 0, 0}}, // (151, 113) + { 0, { 0, 0, 0}}, // (152, 113) + { 0, { 0, 0, 0}}, // (153, 113) + { 0, { 0, 0, 0}}, // (154, 113) + { 0, { 0, 0, 0}}, // (155, 113) + { 0, { 0, 0, 0}}, // (156, 113) + { 0, { 0, 0, 0}}, // (157, 113) + { 0, { 0, 0, 0}}, // (158, 113) + { 0, { 0, 0, 0}}, // (159, 113) + { 0, { 0, 0, 0}}, // (160, 113) + { 0, { 0, 0, 0}}, // (161, 113) + { 0, { 0, 0, 0}}, // (162, 113) + { 0, { 0, 0, 0}}, // (163, 113) + { 0, { 0, 0, 0}}, // (164, 113) + { 0, { 0, 0, 0}}, // (165, 113) + { 0, { 0, 0, 0}}, // (166, 113) + { 0, { 0, 0, 0}}, // (167, 113) + { 0, { 0, 0, 0}}, // (168, 113) + { 0, { 0, 0, 0}}, // (169, 113) + { 0, { 0, 0, 0}}, // (170, 113) + { 0, { 0, 0, 0}}, // (171, 113) + { 0, { 0, 0, 0}}, // (172, 113) + { 0, { 0, 0, 0}}, // (173, 113) + { 23, { 0, 0, 0}}, // (174, 113) + {128, { 0, 0, 0}}, // (175, 113) + {128, { 0, 0, 0}}, // (176, 113) + {128, { 0, 0, 0}}, // (177, 113) + {128, { 0, 0, 0}}, // (178, 113) + {128, { 0, 0, 0}}, // (179, 113) + {128, { 0, 0, 0}}, // ( 0, 114) + {128, { 0, 0, 0}}, // ( 1, 114) + {128, { 0, 0, 0}}, // ( 2, 114) + {128, { 0, 0, 0}}, // ( 3, 114) + {128, { 0, 0, 0}}, // ( 4, 114) + { 62, { 0, 0, 0}}, // ( 5, 114) + { 0, { 0, 0, 0}}, // ( 6, 114) + { 0, { 0, 0, 0}}, // ( 7, 114) + { 0, { 0, 0, 0}}, // ( 8, 114) + { 0, { 0, 0, 0}}, // ( 9, 114) + { 0, { 0, 0, 0}}, // ( 10, 114) + { 0, { 0, 0, 0}}, // ( 11, 114) + { 0, { 0, 0, 0}}, // ( 12, 114) + { 0, { 0, 0, 0}}, // ( 13, 114) + { 0, { 0, 0, 0}}, // ( 14, 114) + { 0, { 0, 0, 0}}, // ( 15, 114) + { 0, { 0, 0, 0}}, // ( 16, 114) + { 0, { 0, 0, 0}}, // ( 17, 114) + { 0, { 0, 0, 0}}, // ( 18, 114) + { 0, { 0, 0, 0}}, // ( 19, 114) + { 0, { 0, 0, 0}}, // ( 20, 114) + { 0, { 0, 0, 0}}, // ( 21, 114) + { 0, { 0, 0, 0}}, // ( 22, 114) + { 0, { 0, 0, 0}}, // ( 23, 114) + { 0, { 0, 0, 0}}, // ( 24, 114) + { 0, { 0, 0, 0}}, // ( 25, 114) + { 0, { 0, 0, 0}}, // ( 26, 114) + { 0, { 0, 0, 0}}, // ( 27, 114) + { 0, { 0, 0, 0}}, // ( 28, 114) + { 0, { 0, 0, 0}}, // ( 29, 114) + { 0, { 0, 0, 0}}, // ( 30, 114) + { 0, { 0, 0, 0}}, // ( 31, 114) + { 0, { 0, 0, 0}}, // ( 32, 114) + { 0, { 0, 0, 0}}, // ( 33, 114) + { 0, { 0, 0, 0}}, // ( 34, 114) + { 0, { 0, 0, 0}}, // ( 35, 114) + { 0, { 0, 0, 0}}, // ( 36, 114) + { 0, { 0, 0, 0}}, // ( 37, 114) + { 0, { 0, 0, 0}}, // ( 38, 114) + { 0, { 0, 0, 0}}, // ( 39, 114) + { 0, { 0, 0, 0}}, // ( 40, 114) + { 0, { 0, 0, 0}}, // ( 41, 114) + { 0, { 0, 0, 0}}, // ( 42, 114) + { 0, { 0, 0, 0}}, // ( 43, 114) + { 0, { 0, 0, 0}}, // ( 44, 114) + { 0, { 0, 0, 0}}, // ( 45, 114) + { 0, { 0, 0, 0}}, // ( 46, 114) + { 0, { 0, 0, 0}}, // ( 47, 114) + { 0, { 0, 0, 0}}, // ( 48, 114) + { 0, { 0, 0, 0}}, // ( 49, 114) + { 0, { 0, 0, 0}}, // ( 50, 114) + { 0, { 0, 0, 0}}, // ( 51, 114) + { 0, { 0, 0, 0}}, // ( 52, 114) + { 0, { 0, 0, 0}}, // ( 53, 114) + { 0, { 0, 0, 0}}, // ( 54, 114) + { 0, { 0, 0, 0}}, // ( 55, 114) + { 0, { 0, 0, 0}}, // ( 56, 114) + { 0, { 0, 0, 0}}, // ( 57, 114) + { 0, { 0, 0, 0}}, // ( 58, 114) + { 0, { 0, 0, 0}}, // ( 59, 114) + { 0, { 0, 0, 0}}, // ( 60, 114) + { 0, { 0, 0, 0}}, // ( 61, 114) + { 0, { 0, 0, 0}}, // ( 62, 114) + { 0, { 0, 0, 0}}, // ( 63, 114) + { 0, { 0, 0, 0}}, // ( 64, 114) + { 0, { 0, 0, 0}}, // ( 65, 114) + { 0, { 0, 0, 0}}, // ( 66, 114) + { 0, { 0, 0, 0}}, // ( 67, 114) + { 0, { 0, 0, 0}}, // ( 68, 114) + { 0, { 0, 0, 0}}, // ( 69, 114) + { 0, { 0, 0, 0}}, // ( 70, 114) + { 0, { 0, 0, 0}}, // ( 71, 114) + { 0, { 0, 0, 0}}, // ( 72, 114) + { 0, { 0, 0, 0}}, // ( 73, 114) + { 0, { 0, 0, 0}}, // ( 74, 114) + { 0, { 0, 0, 0}}, // ( 75, 114) + { 0, { 0, 0, 0}}, // ( 76, 114) + { 0, { 0, 0, 0}}, // ( 77, 114) + { 0, { 0, 0, 0}}, // ( 78, 114) + { 0, { 0, 0, 0}}, // ( 79, 114) + { 0, { 0, 0, 0}}, // ( 80, 114) + { 0, { 0, 0, 0}}, // ( 81, 114) + { 0, { 0, 0, 0}}, // ( 82, 114) + { 0, { 0, 0, 0}}, // ( 83, 114) + { 0, { 0, 0, 0}}, // ( 84, 114) + { 0, { 0, 0, 0}}, // ( 85, 114) + { 0, { 0, 0, 0}}, // ( 86, 114) + { 0, { 0, 0, 0}}, // ( 87, 114) + { 0, { 0, 0, 0}}, // ( 88, 114) + { 0, { 0, 0, 0}}, // ( 89, 114) + { 0, { 0, 0, 0}}, // ( 90, 114) + { 0, { 0, 0, 0}}, // ( 91, 114) + { 0, { 0, 0, 0}}, // ( 92, 114) + { 0, { 0, 0, 0}}, // ( 93, 114) + { 0, { 0, 0, 0}}, // ( 94, 114) + { 0, { 0, 0, 0}}, // ( 95, 114) + { 0, { 0, 0, 0}}, // ( 96, 114) + { 0, { 0, 0, 0}}, // ( 97, 114) + { 0, { 0, 0, 0}}, // ( 98, 114) + { 0, { 0, 0, 0}}, // ( 99, 114) + { 0, { 0, 0, 0}}, // (100, 114) + { 0, { 0, 0, 0}}, // (101, 114) + { 0, { 0, 0, 0}}, // (102, 114) + { 0, { 0, 0, 0}}, // (103, 114) + { 0, { 0, 0, 0}}, // (104, 114) + { 0, { 0, 0, 0}}, // (105, 114) + { 0, { 0, 0, 0}}, // (106, 114) + { 0, { 0, 0, 0}}, // (107, 114) + { 0, { 0, 0, 0}}, // (108, 114) + { 0, { 0, 0, 0}}, // (109, 114) + { 0, { 0, 0, 0}}, // (110, 114) + { 0, { 0, 0, 0}}, // (111, 114) + { 0, { 0, 0, 0}}, // (112, 114) + { 0, { 0, 0, 0}}, // (113, 114) + { 0, { 0, 0, 0}}, // (114, 114) + { 0, { 0, 0, 0}}, // (115, 114) + { 0, { 0, 0, 0}}, // (116, 114) + { 0, { 0, 0, 0}}, // (117, 114) + { 0, { 0, 0, 0}}, // (118, 114) + { 0, { 0, 0, 0}}, // (119, 114) + { 0, { 0, 0, 0}}, // (120, 114) + { 0, { 0, 0, 0}}, // (121, 114) + { 0, { 0, 0, 0}}, // (122, 114) + { 0, { 0, 0, 0}}, // (123, 114) + { 0, { 0, 0, 0}}, // (124, 114) + { 0, { 0, 0, 0}}, // (125, 114) + { 0, { 0, 0, 0}}, // (126, 114) + { 0, { 0, 0, 0}}, // (127, 114) + { 0, { 0, 0, 0}}, // (128, 114) + { 0, { 0, 0, 0}}, // (129, 114) + { 0, { 0, 0, 0}}, // (130, 114) + { 0, { 0, 0, 0}}, // (131, 114) + { 0, { 0, 0, 0}}, // (132, 114) + { 0, { 0, 0, 0}}, // (133, 114) + { 0, { 0, 0, 0}}, // (134, 114) + { 0, { 0, 0, 0}}, // (135, 114) + { 0, { 0, 0, 0}}, // (136, 114) + { 0, { 0, 0, 0}}, // (137, 114) + { 0, { 0, 0, 0}}, // (138, 114) + { 0, { 0, 0, 0}}, // (139, 114) + { 0, { 0, 0, 0}}, // (140, 114) + { 0, { 0, 0, 0}}, // (141, 114) + { 0, { 0, 0, 0}}, // (142, 114) + { 0, { 0, 0, 0}}, // (143, 114) + { 0, { 0, 0, 0}}, // (144, 114) + { 0, { 0, 0, 0}}, // (145, 114) + { 0, { 0, 0, 0}}, // (146, 114) + { 0, { 0, 0, 0}}, // (147, 114) + { 0, { 0, 0, 0}}, // (148, 114) + { 0, { 0, 0, 0}}, // (149, 114) + { 0, { 0, 0, 0}}, // (150, 114) + { 0, { 0, 0, 0}}, // (151, 114) + { 0, { 0, 0, 0}}, // (152, 114) + { 0, { 0, 0, 0}}, // (153, 114) + { 0, { 0, 0, 0}}, // (154, 114) + { 0, { 0, 0, 0}}, // (155, 114) + { 0, { 0, 0, 0}}, // (156, 114) + { 0, { 0, 0, 0}}, // (157, 114) + { 0, { 0, 0, 0}}, // (158, 114) + { 0, { 0, 0, 0}}, // (159, 114) + { 0, { 0, 0, 0}}, // (160, 114) + { 0, { 0, 0, 0}}, // (161, 114) + { 0, { 0, 0, 0}}, // (162, 114) + { 0, { 0, 0, 0}}, // (163, 114) + { 0, { 0, 0, 0}}, // (164, 114) + { 0, { 0, 0, 0}}, // (165, 114) + { 0, { 0, 0, 0}}, // (166, 114) + { 0, { 0, 0, 0}}, // (167, 114) + { 0, { 0, 0, 0}}, // (168, 114) + { 0, { 0, 0, 0}}, // (169, 114) + { 0, { 0, 0, 0}}, // (170, 114) + { 0, { 0, 0, 0}}, // (171, 114) + { 0, { 0, 0, 0}}, // (172, 114) + { 0, { 0, 0, 0}}, // (173, 114) + { 58, { 0, 0, 0}}, // (174, 114) + {128, { 0, 0, 0}}, // (175, 114) + {128, { 0, 0, 0}}, // (176, 114) + {128, { 0, 0, 0}}, // (177, 114) + {128, { 0, 0, 0}}, // (178, 114) + {128, { 0, 0, 0}}, // (179, 114) + {128, { 0, 0, 0}}, // ( 0, 115) + {128, { 0, 0, 0}}, // ( 1, 115) + {128, { 0, 0, 0}}, // ( 2, 115) + {128, { 0, 0, 0}}, // ( 3, 115) + {128, { 0, 0, 0}}, // ( 4, 115) + { 98, { 0, 0, 0}}, // ( 5, 115) + { 0, { 0, 0, 0}}, // ( 6, 115) + { 0, { 0, 0, 0}}, // ( 7, 115) + { 0, { 0, 0, 0}}, // ( 8, 115) + { 0, { 0, 0, 0}}, // ( 9, 115) + { 0, { 0, 0, 0}}, // ( 10, 115) + { 0, { 0, 0, 0}}, // ( 11, 115) + { 0, { 0, 0, 0}}, // ( 12, 115) + { 0, { 0, 0, 0}}, // ( 13, 115) + { 0, { 0, 0, 0}}, // ( 14, 115) + { 0, { 0, 0, 0}}, // ( 15, 115) + { 0, { 0, 0, 0}}, // ( 16, 115) + { 0, { 0, 0, 0}}, // ( 17, 115) + { 0, { 0, 0, 0}}, // ( 18, 115) + { 0, { 0, 0, 0}}, // ( 19, 115) + { 0, { 0, 0, 0}}, // ( 20, 115) + { 0, { 0, 0, 0}}, // ( 21, 115) + { 0, { 0, 0, 0}}, // ( 22, 115) + { 0, { 0, 0, 0}}, // ( 23, 115) + { 0, { 0, 0, 0}}, // ( 24, 115) + { 0, { 0, 0, 0}}, // ( 25, 115) + { 0, { 0, 0, 0}}, // ( 26, 115) + { 0, { 0, 0, 0}}, // ( 27, 115) + { 0, { 0, 0, 0}}, // ( 28, 115) + { 0, { 0, 0, 0}}, // ( 29, 115) + { 0, { 0, 0, 0}}, // ( 30, 115) + { 0, { 0, 0, 0}}, // ( 31, 115) + { 0, { 0, 0, 0}}, // ( 32, 115) + { 0, { 0, 0, 0}}, // ( 33, 115) + { 0, { 0, 0, 0}}, // ( 34, 115) + { 0, { 0, 0, 0}}, // ( 35, 115) + { 0, { 0, 0, 0}}, // ( 36, 115) + { 0, { 0, 0, 0}}, // ( 37, 115) + { 0, { 0, 0, 0}}, // ( 38, 115) + { 0, { 0, 0, 0}}, // ( 39, 115) + { 0, { 0, 0, 0}}, // ( 40, 115) + { 0, { 0, 0, 0}}, // ( 41, 115) + { 0, { 0, 0, 0}}, // ( 42, 115) + { 0, { 0, 0, 0}}, // ( 43, 115) + { 0, { 0, 0, 0}}, // ( 44, 115) + { 0, { 0, 0, 0}}, // ( 45, 115) + { 0, { 0, 0, 0}}, // ( 46, 115) + { 0, { 0, 0, 0}}, // ( 47, 115) + { 0, { 0, 0, 0}}, // ( 48, 115) + { 0, { 0, 0, 0}}, // ( 49, 115) + { 0, { 0, 0, 0}}, // ( 50, 115) + { 0, { 0, 0, 0}}, // ( 51, 115) + { 0, { 0, 0, 0}}, // ( 52, 115) + { 0, { 0, 0, 0}}, // ( 53, 115) + { 0, { 0, 0, 0}}, // ( 54, 115) + { 0, { 0, 0, 0}}, // ( 55, 115) + { 0, { 0, 0, 0}}, // ( 56, 115) + { 0, { 0, 0, 0}}, // ( 57, 115) + { 0, { 0, 0, 0}}, // ( 58, 115) + { 0, { 0, 0, 0}}, // ( 59, 115) + { 0, { 0, 0, 0}}, // ( 60, 115) + { 0, { 0, 0, 0}}, // ( 61, 115) + { 0, { 0, 0, 0}}, // ( 62, 115) + { 0, { 0, 0, 0}}, // ( 63, 115) + { 0, { 0, 0, 0}}, // ( 64, 115) + { 0, { 0, 0, 0}}, // ( 65, 115) + { 0, { 0, 0, 0}}, // ( 66, 115) + { 0, { 0, 0, 0}}, // ( 67, 115) + { 0, { 0, 0, 0}}, // ( 68, 115) + { 0, { 0, 0, 0}}, // ( 69, 115) + { 0, { 0, 0, 0}}, // ( 70, 115) + { 0, { 0, 0, 0}}, // ( 71, 115) + { 0, { 0, 0, 0}}, // ( 72, 115) + { 0, { 0, 0, 0}}, // ( 73, 115) + { 0, { 0, 0, 0}}, // ( 74, 115) + { 0, { 0, 0, 0}}, // ( 75, 115) + { 0, { 0, 0, 0}}, // ( 76, 115) + { 0, { 0, 0, 0}}, // ( 77, 115) + { 0, { 0, 0, 0}}, // ( 78, 115) + { 0, { 0, 0, 0}}, // ( 79, 115) + { 0, { 0, 0, 0}}, // ( 80, 115) + { 0, { 0, 0, 0}}, // ( 81, 115) + { 0, { 0, 0, 0}}, // ( 82, 115) + { 0, { 0, 0, 0}}, // ( 83, 115) + { 0, { 0, 0, 0}}, // ( 84, 115) + { 0, { 0, 0, 0}}, // ( 85, 115) + { 0, { 0, 0, 0}}, // ( 86, 115) + { 0, { 0, 0, 0}}, // ( 87, 115) + { 0, { 0, 0, 0}}, // ( 88, 115) + { 0, { 0, 0, 0}}, // ( 89, 115) + { 0, { 0, 0, 0}}, // ( 90, 115) + { 0, { 0, 0, 0}}, // ( 91, 115) + { 0, { 0, 0, 0}}, // ( 92, 115) + { 0, { 0, 0, 0}}, // ( 93, 115) + { 0, { 0, 0, 0}}, // ( 94, 115) + { 0, { 0, 0, 0}}, // ( 95, 115) + { 0, { 0, 0, 0}}, // ( 96, 115) + { 0, { 0, 0, 0}}, // ( 97, 115) + { 0, { 0, 0, 0}}, // ( 98, 115) + { 0, { 0, 0, 0}}, // ( 99, 115) + { 0, { 0, 0, 0}}, // (100, 115) + { 0, { 0, 0, 0}}, // (101, 115) + { 0, { 0, 0, 0}}, // (102, 115) + { 0, { 0, 0, 0}}, // (103, 115) + { 0, { 0, 0, 0}}, // (104, 115) + { 0, { 0, 0, 0}}, // (105, 115) + { 0, { 0, 0, 0}}, // (106, 115) + { 0, { 0, 0, 0}}, // (107, 115) + { 0, { 0, 0, 0}}, // (108, 115) + { 0, { 0, 0, 0}}, // (109, 115) + { 0, { 0, 0, 0}}, // (110, 115) + { 0, { 0, 0, 0}}, // (111, 115) + { 0, { 0, 0, 0}}, // (112, 115) + { 0, { 0, 0, 0}}, // (113, 115) + { 0, { 0, 0, 0}}, // (114, 115) + { 0, { 0, 0, 0}}, // (115, 115) + { 0, { 0, 0, 0}}, // (116, 115) + { 0, { 0, 0, 0}}, // (117, 115) + { 0, { 0, 0, 0}}, // (118, 115) + { 0, { 0, 0, 0}}, // (119, 115) + { 0, { 0, 0, 0}}, // (120, 115) + { 0, { 0, 0, 0}}, // (121, 115) + { 0, { 0, 0, 0}}, // (122, 115) + { 0, { 0, 0, 0}}, // (123, 115) + { 0, { 0, 0, 0}}, // (124, 115) + { 0, { 0, 0, 0}}, // (125, 115) + { 0, { 0, 0, 0}}, // (126, 115) + { 0, { 0, 0, 0}}, // (127, 115) + { 0, { 0, 0, 0}}, // (128, 115) + { 0, { 0, 0, 0}}, // (129, 115) + { 0, { 0, 0, 0}}, // (130, 115) + { 0, { 0, 0, 0}}, // (131, 115) + { 0, { 0, 0, 0}}, // (132, 115) + { 0, { 0, 0, 0}}, // (133, 115) + { 0, { 0, 0, 0}}, // (134, 115) + { 0, { 0, 0, 0}}, // (135, 115) + { 0, { 0, 0, 0}}, // (136, 115) + { 0, { 0, 0, 0}}, // (137, 115) + { 0, { 0, 0, 0}}, // (138, 115) + { 0, { 0, 0, 0}}, // (139, 115) + { 0, { 0, 0, 0}}, // (140, 115) + { 0, { 0, 0, 0}}, // (141, 115) + { 0, { 0, 0, 0}}, // (142, 115) + { 0, { 0, 0, 0}}, // (143, 115) + { 0, { 0, 0, 0}}, // (144, 115) + { 0, { 0, 0, 0}}, // (145, 115) + { 0, { 0, 0, 0}}, // (146, 115) + { 0, { 0, 0, 0}}, // (147, 115) + { 0, { 0, 0, 0}}, // (148, 115) + { 0, { 0, 0, 0}}, // (149, 115) + { 0, { 0, 0, 0}}, // (150, 115) + { 0, { 0, 0, 0}}, // (151, 115) + { 0, { 0, 0, 0}}, // (152, 115) + { 0, { 0, 0, 0}}, // (153, 115) + { 0, { 0, 0, 0}}, // (154, 115) + { 0, { 0, 0, 0}}, // (155, 115) + { 0, { 0, 0, 0}}, // (156, 115) + { 0, { 0, 0, 0}}, // (157, 115) + { 0, { 0, 0, 0}}, // (158, 115) + { 0, { 0, 0, 0}}, // (159, 115) + { 0, { 0, 0, 0}}, // (160, 115) + { 0, { 0, 0, 0}}, // (161, 115) + { 0, { 0, 0, 0}}, // (162, 115) + { 0, { 0, 0, 0}}, // (163, 115) + { 0, { 0, 0, 0}}, // (164, 115) + { 0, { 0, 0, 0}}, // (165, 115) + { 0, { 0, 0, 0}}, // (166, 115) + { 0, { 0, 0, 0}}, // (167, 115) + { 0, { 0, 0, 0}}, // (168, 115) + { 0, { 0, 0, 0}}, // (169, 115) + { 0, { 0, 0, 0}}, // (170, 115) + { 0, { 0, 0, 0}}, // (171, 115) + { 0, { 0, 0, 0}}, // (172, 115) + { 0, { 0, 0, 0}}, // (173, 115) + { 97, { 0, 0, 0}}, // (174, 115) + {128, { 0, 0, 0}}, // (175, 115) + {128, { 0, 0, 0}}, // (176, 115) + {128, { 0, 0, 0}}, // (177, 115) + {128, { 0, 0, 0}}, // (178, 115) + {128, { 0, 0, 0}}, // (179, 115) + {128, { 0, 0, 0}}, // ( 0, 116) + {128, { 0, 0, 0}}, // ( 1, 116) + {128, { 0, 0, 0}}, // ( 2, 116) + {128, { 0, 0, 0}}, // ( 3, 116) + {128, { 0, 0, 0}}, // ( 4, 116) + {126, { 0, 0, 0}}, // ( 5, 116) + { 11, { 0, 0, 0}}, // ( 6, 116) + { 0, { 0, 0, 0}}, // ( 7, 116) + { 0, { 0, 0, 0}}, // ( 8, 116) + { 0, { 0, 0, 0}}, // ( 9, 116) + { 0, { 0, 0, 0}}, // ( 10, 116) + { 0, { 0, 0, 0}}, // ( 11, 116) + { 0, { 0, 0, 0}}, // ( 12, 116) + { 0, { 0, 0, 0}}, // ( 13, 116) + { 0, { 0, 0, 0}}, // ( 14, 116) + { 0, { 0, 0, 0}}, // ( 15, 116) + { 0, { 0, 0, 0}}, // ( 16, 116) + { 0, { 0, 0, 0}}, // ( 17, 116) + { 0, { 0, 0, 0}}, // ( 18, 116) + { 0, { 0, 0, 0}}, // ( 19, 116) + { 0, { 0, 0, 0}}, // ( 20, 116) + { 0, { 0, 0, 0}}, // ( 21, 116) + { 0, { 0, 0, 0}}, // ( 22, 116) + { 0, { 0, 0, 0}}, // ( 23, 116) + { 0, { 0, 0, 0}}, // ( 24, 116) + { 0, { 0, 0, 0}}, // ( 25, 116) + { 0, { 0, 0, 0}}, // ( 26, 116) + { 0, { 0, 0, 0}}, // ( 27, 116) + { 0, { 0, 0, 0}}, // ( 28, 116) + { 0, { 0, 0, 0}}, // ( 29, 116) + { 0, { 0, 0, 0}}, // ( 30, 116) + { 0, { 0, 0, 0}}, // ( 31, 116) + { 0, { 0, 0, 0}}, // ( 32, 116) + { 0, { 0, 0, 0}}, // ( 33, 116) + { 0, { 0, 0, 0}}, // ( 34, 116) + { 0, { 0, 0, 0}}, // ( 35, 116) + { 0, { 0, 0, 0}}, // ( 36, 116) + { 0, { 0, 0, 0}}, // ( 37, 116) + { 0, { 0, 0, 0}}, // ( 38, 116) + { 0, { 0, 0, 0}}, // ( 39, 116) + { 0, { 0, 0, 0}}, // ( 40, 116) + { 0, { 0, 0, 0}}, // ( 41, 116) + { 0, { 0, 0, 0}}, // ( 42, 116) + { 0, { 0, 0, 0}}, // ( 43, 116) + { 0, { 0, 0, 0}}, // ( 44, 116) + { 0, { 0, 0, 0}}, // ( 45, 116) + { 0, { 0, 0, 0}}, // ( 46, 116) + { 0, { 0, 0, 0}}, // ( 47, 116) + { 0, { 0, 0, 0}}, // ( 48, 116) + { 0, { 0, 0, 0}}, // ( 49, 116) + { 0, { 0, 0, 0}}, // ( 50, 116) + { 0, { 0, 0, 0}}, // ( 51, 116) + { 0, { 0, 0, 0}}, // ( 52, 116) + { 0, { 0, 0, 0}}, // ( 53, 116) + { 0, { 0, 0, 0}}, // ( 54, 116) + { 0, { 0, 0, 0}}, // ( 55, 116) + { 0, { 0, 0, 0}}, // ( 56, 116) + { 0, { 0, 0, 0}}, // ( 57, 116) + { 0, { 0, 0, 0}}, // ( 58, 116) + { 0, { 0, 0, 0}}, // ( 59, 116) + { 0, { 0, 0, 0}}, // ( 60, 116) + { 0, { 0, 0, 0}}, // ( 61, 116) + { 0, { 0, 0, 0}}, // ( 62, 116) + { 0, { 0, 0, 0}}, // ( 63, 116) + { 0, { 0, 0, 0}}, // ( 64, 116) + { 0, { 0, 0, 0}}, // ( 65, 116) + { 0, { 0, 0, 0}}, // ( 66, 116) + { 0, { 0, 0, 0}}, // ( 67, 116) + { 0, { 0, 0, 0}}, // ( 68, 116) + { 0, { 0, 0, 0}}, // ( 69, 116) + { 0, { 0, 0, 0}}, // ( 70, 116) + { 0, { 0, 0, 0}}, // ( 71, 116) + { 0, { 0, 0, 0}}, // ( 72, 116) + { 0, { 0, 0, 0}}, // ( 73, 116) + { 0, { 0, 0, 0}}, // ( 74, 116) + { 0, { 0, 0, 0}}, // ( 75, 116) + { 0, { 0, 0, 0}}, // ( 76, 116) + { 0, { 0, 0, 0}}, // ( 77, 116) + { 0, { 0, 0, 0}}, // ( 78, 116) + { 0, { 0, 0, 0}}, // ( 79, 116) + { 0, { 0, 0, 0}}, // ( 80, 116) + { 0, { 0, 0, 0}}, // ( 81, 116) + { 0, { 0, 0, 0}}, // ( 82, 116) + { 0, { 0, 0, 0}}, // ( 83, 116) + { 0, { 0, 0, 0}}, // ( 84, 116) + { 0, { 0, 0, 0}}, // ( 85, 116) + { 0, { 0, 0, 0}}, // ( 86, 116) + { 0, { 0, 0, 0}}, // ( 87, 116) + { 0, { 0, 0, 0}}, // ( 88, 116) + { 0, { 0, 0, 0}}, // ( 89, 116) + { 0, { 0, 0, 0}}, // ( 90, 116) + { 0, { 0, 0, 0}}, // ( 91, 116) + { 0, { 0, 0, 0}}, // ( 92, 116) + { 0, { 0, 0, 0}}, // ( 93, 116) + { 0, { 0, 0, 0}}, // ( 94, 116) + { 0, { 0, 0, 0}}, // ( 95, 116) + { 0, { 0, 0, 0}}, // ( 96, 116) + { 0, { 0, 0, 0}}, // ( 97, 116) + { 0, { 0, 0, 0}}, // ( 98, 116) + { 0, { 0, 0, 0}}, // ( 99, 116) + { 0, { 0, 0, 0}}, // (100, 116) + { 0, { 0, 0, 0}}, // (101, 116) + { 0, { 0, 0, 0}}, // (102, 116) + { 0, { 0, 0, 0}}, // (103, 116) + { 0, { 0, 0, 0}}, // (104, 116) + { 0, { 0, 0, 0}}, // (105, 116) + { 0, { 0, 0, 0}}, // (106, 116) + { 0, { 0, 0, 0}}, // (107, 116) + { 0, { 0, 0, 0}}, // (108, 116) + { 0, { 0, 0, 0}}, // (109, 116) + { 0, { 0, 0, 0}}, // (110, 116) + { 0, { 0, 0, 0}}, // (111, 116) + { 0, { 0, 0, 0}}, // (112, 116) + { 0, { 0, 0, 0}}, // (113, 116) + { 0, { 0, 0, 0}}, // (114, 116) + { 0, { 0, 0, 0}}, // (115, 116) + { 0, { 0, 0, 0}}, // (116, 116) + { 0, { 0, 0, 0}}, // (117, 116) + { 0, { 0, 0, 0}}, // (118, 116) + { 0, { 0, 0, 0}}, // (119, 116) + { 0, { 0, 0, 0}}, // (120, 116) + { 0, { 0, 0, 0}}, // (121, 116) + { 0, { 0, 0, 0}}, // (122, 116) + { 0, { 0, 0, 0}}, // (123, 116) + { 0, { 0, 0, 0}}, // (124, 116) + { 0, { 0, 0, 0}}, // (125, 116) + { 0, { 0, 0, 0}}, // (126, 116) + { 0, { 0, 0, 0}}, // (127, 116) + { 0, { 0, 0, 0}}, // (128, 116) + { 0, { 0, 0, 0}}, // (129, 116) + { 0, { 0, 0, 0}}, // (130, 116) + { 0, { 0, 0, 0}}, // (131, 116) + { 0, { 0, 0, 0}}, // (132, 116) + { 0, { 0, 0, 0}}, // (133, 116) + { 0, { 0, 0, 0}}, // (134, 116) + { 0, { 0, 0, 0}}, // (135, 116) + { 0, { 0, 0, 0}}, // (136, 116) + { 0, { 0, 0, 0}}, // (137, 116) + { 0, { 0, 0, 0}}, // (138, 116) + { 0, { 0, 0, 0}}, // (139, 116) + { 0, { 0, 0, 0}}, // (140, 116) + { 0, { 0, 0, 0}}, // (141, 116) + { 0, { 0, 0, 0}}, // (142, 116) + { 0, { 0, 0, 0}}, // (143, 116) + { 0, { 0, 0, 0}}, // (144, 116) + { 0, { 0, 0, 0}}, // (145, 116) + { 0, { 0, 0, 0}}, // (146, 116) + { 0, { 0, 0, 0}}, // (147, 116) + { 0, { 0, 0, 0}}, // (148, 116) + { 0, { 0, 0, 0}}, // (149, 116) + { 0, { 0, 0, 0}}, // (150, 116) + { 0, { 0, 0, 0}}, // (151, 116) + { 0, { 0, 0, 0}}, // (152, 116) + { 0, { 0, 0, 0}}, // (153, 116) + { 0, { 0, 0, 0}}, // (154, 116) + { 0, { 0, 0, 0}}, // (155, 116) + { 0, { 0, 0, 0}}, // (156, 116) + { 0, { 0, 0, 0}}, // (157, 116) + { 0, { 0, 0, 0}}, // (158, 116) + { 0, { 0, 0, 0}}, // (159, 116) + { 0, { 0, 0, 0}}, // (160, 116) + { 0, { 0, 0, 0}}, // (161, 116) + { 0, { 0, 0, 0}}, // (162, 116) + { 0, { 0, 0, 0}}, // (163, 116) + { 0, { 0, 0, 0}}, // (164, 116) + { 0, { 0, 0, 0}}, // (165, 116) + { 0, { 0, 0, 0}}, // (166, 116) + { 0, { 0, 0, 0}}, // (167, 116) + { 0, { 0, 0, 0}}, // (168, 116) + { 0, { 0, 0, 0}}, // (169, 116) + { 0, { 0, 0, 0}}, // (170, 116) + { 0, { 0, 0, 0}}, // (171, 116) + { 0, { 0, 0, 0}}, // (172, 116) + { 10, { 0, 0, 0}}, // (173, 116) + {126, { 0, 0, 0}}, // (174, 116) + {128, { 0, 0, 0}}, // (175, 116) + {128, { 0, 0, 0}}, // (176, 116) + {128, { 0, 0, 0}}, // (177, 116) + {128, { 0, 0, 0}}, // (178, 116) + {128, { 0, 0, 0}}, // (179, 116) + {128, { 0, 0, 0}}, // ( 0, 117) + {128, { 0, 0, 0}}, // ( 1, 117) + {128, { 0, 0, 0}}, // ( 2, 117) + {128, { 0, 0, 0}}, // ( 3, 117) + {128, { 0, 0, 0}}, // ( 4, 117) + {128, { 0, 0, 0}}, // ( 5, 117) + { 52, { 0, 0, 0}}, // ( 6, 117) + { 0, { 0, 0, 0}}, // ( 7, 117) + { 0, { 0, 0, 0}}, // ( 8, 117) + { 0, { 0, 0, 0}}, // ( 9, 117) + { 0, { 0, 0, 0}}, // ( 10, 117) + { 0, { 0, 0, 0}}, // ( 11, 117) + { 0, { 0, 0, 0}}, // ( 12, 117) + { 0, { 0, 0, 0}}, // ( 13, 117) + { 0, { 0, 0, 0}}, // ( 14, 117) + { 0, { 0, 0, 0}}, // ( 15, 117) + { 0, { 0, 0, 0}}, // ( 16, 117) + { 0, { 0, 0, 0}}, // ( 17, 117) + { 0, { 0, 0, 0}}, // ( 18, 117) + { 0, { 0, 0, 0}}, // ( 19, 117) + { 0, { 0, 0, 0}}, // ( 20, 117) + { 0, { 0, 0, 0}}, // ( 21, 117) + { 0, { 0, 0, 0}}, // ( 22, 117) + { 0, { 0, 0, 0}}, // ( 23, 117) + { 0, { 0, 0, 0}}, // ( 24, 117) + { 0, { 0, 0, 0}}, // ( 25, 117) + { 0, { 0, 0, 0}}, // ( 26, 117) + { 0, { 0, 0, 0}}, // ( 27, 117) + { 0, { 0, 0, 0}}, // ( 28, 117) + { 0, { 0, 0, 0}}, // ( 29, 117) + { 0, { 0, 0, 0}}, // ( 30, 117) + { 0, { 0, 0, 0}}, // ( 31, 117) + { 0, { 0, 0, 0}}, // ( 32, 117) + { 0, { 0, 0, 0}}, // ( 33, 117) + { 0, { 0, 0, 0}}, // ( 34, 117) + { 0, { 0, 0, 0}}, // ( 35, 117) + { 0, { 0, 0, 0}}, // ( 36, 117) + { 0, { 0, 0, 0}}, // ( 37, 117) + { 0, { 0, 0, 0}}, // ( 38, 117) + { 0, { 0, 0, 0}}, // ( 39, 117) + { 0, { 0, 0, 0}}, // ( 40, 117) + { 0, { 0, 0, 0}}, // ( 41, 117) + { 0, { 0, 0, 0}}, // ( 42, 117) + { 0, { 0, 0, 0}}, // ( 43, 117) + { 0, { 0, 0, 0}}, // ( 44, 117) + { 0, { 0, 0, 0}}, // ( 45, 117) + { 0, { 0, 0, 0}}, // ( 46, 117) + { 0, { 0, 0, 0}}, // ( 47, 117) + { 0, { 0, 0, 0}}, // ( 48, 117) + { 0, { 0, 0, 0}}, // ( 49, 117) + { 0, { 0, 0, 0}}, // ( 50, 117) + { 0, { 0, 0, 0}}, // ( 51, 117) + { 0, { 0, 0, 0}}, // ( 52, 117) + { 0, { 0, 0, 0}}, // ( 53, 117) + { 0, { 0, 0, 0}}, // ( 54, 117) + { 0, { 0, 0, 0}}, // ( 55, 117) + { 0, { 0, 0, 0}}, // ( 56, 117) + { 0, { 0, 0, 0}}, // ( 57, 117) + { 0, { 0, 0, 0}}, // ( 58, 117) + { 0, { 0, 0, 0}}, // ( 59, 117) + { 0, { 0, 0, 0}}, // ( 60, 117) + { 0, { 0, 0, 0}}, // ( 61, 117) + { 0, { 0, 0, 0}}, // ( 62, 117) + { 0, { 0, 0, 0}}, // ( 63, 117) + { 0, { 0, 0, 0}}, // ( 64, 117) + { 0, { 0, 0, 0}}, // ( 65, 117) + { 0, { 0, 0, 0}}, // ( 66, 117) + { 0, { 0, 0, 0}}, // ( 67, 117) + { 0, { 0, 0, 0}}, // ( 68, 117) + { 0, { 0, 0, 0}}, // ( 69, 117) + { 0, { 0, 0, 0}}, // ( 70, 117) + { 0, { 0, 0, 0}}, // ( 71, 117) + { 0, { 0, 0, 0}}, // ( 72, 117) + { 0, { 0, 0, 0}}, // ( 73, 117) + { 0, { 0, 0, 0}}, // ( 74, 117) + { 0, { 0, 0, 0}}, // ( 75, 117) + { 0, { 0, 0, 0}}, // ( 76, 117) + { 0, { 0, 0, 0}}, // ( 77, 117) + { 0, { 0, 0, 0}}, // ( 78, 117) + { 0, { 0, 0, 0}}, // ( 79, 117) + { 0, { 0, 0, 0}}, // ( 80, 117) + { 0, { 0, 0, 0}}, // ( 81, 117) + { 0, { 0, 0, 0}}, // ( 82, 117) + { 0, { 0, 0, 0}}, // ( 83, 117) + { 0, { 0, 0, 0}}, // ( 84, 117) + { 0, { 0, 0, 0}}, // ( 85, 117) + { 0, { 0, 0, 0}}, // ( 86, 117) + { 0, { 0, 0, 0}}, // ( 87, 117) + { 0, { 0, 0, 0}}, // ( 88, 117) + { 0, { 0, 0, 0}}, // ( 89, 117) + { 0, { 0, 0, 0}}, // ( 90, 117) + { 0, { 0, 0, 0}}, // ( 91, 117) + { 0, { 0, 0, 0}}, // ( 92, 117) + { 0, { 0, 0, 0}}, // ( 93, 117) + { 0, { 0, 0, 0}}, // ( 94, 117) + { 0, { 0, 0, 0}}, // ( 95, 117) + { 0, { 0, 0, 0}}, // ( 96, 117) + { 0, { 0, 0, 0}}, // ( 97, 117) + { 0, { 0, 0, 0}}, // ( 98, 117) + { 0, { 0, 0, 0}}, // ( 99, 117) + { 0, { 0, 0, 0}}, // (100, 117) + { 0, { 0, 0, 0}}, // (101, 117) + { 0, { 0, 0, 0}}, // (102, 117) + { 0, { 0, 0, 0}}, // (103, 117) + { 0, { 0, 0, 0}}, // (104, 117) + { 0, { 0, 0, 0}}, // (105, 117) + { 0, { 0, 0, 0}}, // (106, 117) + { 0, { 0, 0, 0}}, // (107, 117) + { 0, { 0, 0, 0}}, // (108, 117) + { 0, { 0, 0, 0}}, // (109, 117) + { 0, { 0, 0, 0}}, // (110, 117) + { 0, { 0, 0, 0}}, // (111, 117) + { 0, { 0, 0, 0}}, // (112, 117) + { 0, { 0, 0, 0}}, // (113, 117) + { 0, { 0, 0, 0}}, // (114, 117) + { 0, { 0, 0, 0}}, // (115, 117) + { 0, { 0, 0, 0}}, // (116, 117) + { 0, { 0, 0, 0}}, // (117, 117) + { 0, { 0, 0, 0}}, // (118, 117) + { 0, { 0, 0, 0}}, // (119, 117) + { 0, { 0, 0, 0}}, // (120, 117) + { 0, { 0, 0, 0}}, // (121, 117) + { 0, { 0, 0, 0}}, // (122, 117) + { 0, { 0, 0, 0}}, // (123, 117) + { 0, { 0, 0, 0}}, // (124, 117) + { 0, { 0, 0, 0}}, // (125, 117) + { 0, { 0, 0, 0}}, // (126, 117) + { 0, { 0, 0, 0}}, // (127, 117) + { 0, { 0, 0, 0}}, // (128, 117) + { 0, { 0, 0, 0}}, // (129, 117) + { 0, { 0, 0, 0}}, // (130, 117) + { 0, { 0, 0, 0}}, // (131, 117) + { 0, { 0, 0, 0}}, // (132, 117) + { 0, { 0, 0, 0}}, // (133, 117) + { 0, { 0, 0, 0}}, // (134, 117) + { 0, { 0, 0, 0}}, // (135, 117) + { 0, { 0, 0, 0}}, // (136, 117) + { 0, { 0, 0, 0}}, // (137, 117) + { 0, { 0, 0, 0}}, // (138, 117) + { 0, { 0, 0, 0}}, // (139, 117) + { 0, { 0, 0, 0}}, // (140, 117) + { 0, { 0, 0, 0}}, // (141, 117) + { 0, { 0, 0, 0}}, // (142, 117) + { 0, { 0, 0, 0}}, // (143, 117) + { 0, { 0, 0, 0}}, // (144, 117) + { 0, { 0, 0, 0}}, // (145, 117) + { 0, { 0, 0, 0}}, // (146, 117) + { 0, { 0, 0, 0}}, // (147, 117) + { 0, { 0, 0, 0}}, // (148, 117) + { 0, { 0, 0, 0}}, // (149, 117) + { 0, { 0, 0, 0}}, // (150, 117) + { 0, { 0, 0, 0}}, // (151, 117) + { 0, { 0, 0, 0}}, // (152, 117) + { 0, { 0, 0, 0}}, // (153, 117) + { 0, { 0, 0, 0}}, // (154, 117) + { 0, { 0, 0, 0}}, // (155, 117) + { 0, { 0, 0, 0}}, // (156, 117) + { 0, { 0, 0, 0}}, // (157, 117) + { 0, { 0, 0, 0}}, // (158, 117) + { 0, { 0, 0, 0}}, // (159, 117) + { 0, { 0, 0, 0}}, // (160, 117) + { 0, { 0, 0, 0}}, // (161, 117) + { 0, { 0, 0, 0}}, // (162, 117) + { 0, { 0, 0, 0}}, // (163, 117) + { 0, { 0, 0, 0}}, // (164, 117) + { 0, { 0, 0, 0}}, // (165, 117) + { 0, { 0, 0, 0}}, // (166, 117) + { 0, { 0, 0, 0}}, // (167, 117) + { 0, { 0, 0, 0}}, // (168, 117) + { 0, { 0, 0, 0}}, // (169, 117) + { 0, { 0, 0, 0}}, // (170, 117) + { 0, { 0, 0, 0}}, // (171, 117) + { 0, { 0, 0, 0}}, // (172, 117) + { 52, { 0, 0, 0}}, // (173, 117) + {128, { 0, 0, 0}}, // (174, 117) + {128, { 0, 0, 0}}, // (175, 117) + {128, { 0, 0, 0}}, // (176, 117) + {128, { 0, 0, 0}}, // (177, 117) + {128, { 0, 0, 0}}, // (178, 117) + {128, { 0, 0, 0}}, // (179, 117) + {128, { 0, 0, 0}}, // ( 0, 118) + {128, { 0, 0, 0}}, // ( 1, 118) + {128, { 0, 0, 0}}, // ( 2, 118) + {128, { 0, 0, 0}}, // ( 3, 118) + {128, { 0, 0, 0}}, // ( 4, 118) + {128, { 0, 0, 0}}, // ( 5, 118) + { 95, { 0, 0, 0}}, // ( 6, 118) + { 0, { 0, 0, 0}}, // ( 7, 118) + { 0, { 0, 0, 0}}, // ( 8, 118) + { 0, { 0, 0, 0}}, // ( 9, 118) + { 0, { 0, 0, 0}}, // ( 10, 118) + { 0, { 0, 0, 0}}, // ( 11, 118) + { 0, { 0, 0, 0}}, // ( 12, 118) + { 0, { 0, 0, 0}}, // ( 13, 118) + { 0, { 0, 0, 0}}, // ( 14, 118) + { 0, { 0, 0, 0}}, // ( 15, 118) + { 0, { 0, 0, 0}}, // ( 16, 118) + { 0, { 0, 0, 0}}, // ( 17, 118) + { 0, { 0, 0, 0}}, // ( 18, 118) + { 0, { 0, 0, 0}}, // ( 19, 118) + { 0, { 0, 0, 0}}, // ( 20, 118) + { 0, { 0, 0, 0}}, // ( 21, 118) + { 0, { 0, 0, 0}}, // ( 22, 118) + { 0, { 0, 0, 0}}, // ( 23, 118) + { 0, { 0, 0, 0}}, // ( 24, 118) + { 0, { 0, 0, 0}}, // ( 25, 118) + { 0, { 0, 0, 0}}, // ( 26, 118) + { 0, { 0, 0, 0}}, // ( 27, 118) + { 0, { 0, 0, 0}}, // ( 28, 118) + { 0, { 0, 0, 0}}, // ( 29, 118) + { 0, { 0, 0, 0}}, // ( 30, 118) + { 0, { 0, 0, 0}}, // ( 31, 118) + { 0, { 0, 0, 0}}, // ( 32, 118) + { 0, { 0, 0, 0}}, // ( 33, 118) + { 0, { 0, 0, 0}}, // ( 34, 118) + { 0, { 0, 0, 0}}, // ( 35, 118) + { 0, { 0, 0, 0}}, // ( 36, 118) + { 0, { 0, 0, 0}}, // ( 37, 118) + { 0, { 0, 0, 0}}, // ( 38, 118) + { 0, { 0, 0, 0}}, // ( 39, 118) + { 0, { 0, 0, 0}}, // ( 40, 118) + { 0, { 0, 0, 0}}, // ( 41, 118) + { 0, { 0, 0, 0}}, // ( 42, 118) + { 0, { 0, 0, 0}}, // ( 43, 118) + { 0, { 0, 0, 0}}, // ( 44, 118) + { 0, { 0, 0, 0}}, // ( 45, 118) + { 0, { 0, 0, 0}}, // ( 46, 118) + { 0, { 0, 0, 0}}, // ( 47, 118) + { 0, { 0, 0, 0}}, // ( 48, 118) + { 0, { 0, 0, 0}}, // ( 49, 118) + { 0, { 0, 0, 0}}, // ( 50, 118) + { 0, { 0, 0, 0}}, // ( 51, 118) + { 0, { 0, 0, 0}}, // ( 52, 118) + { 0, { 0, 0, 0}}, // ( 53, 118) + { 0, { 0, 0, 0}}, // ( 54, 118) + { 0, { 0, 0, 0}}, // ( 55, 118) + { 0, { 0, 0, 0}}, // ( 56, 118) + { 0, { 0, 0, 0}}, // ( 57, 118) + { 0, { 0, 0, 0}}, // ( 58, 118) + { 0, { 0, 0, 0}}, // ( 59, 118) + { 0, { 0, 0, 0}}, // ( 60, 118) + { 0, { 0, 0, 0}}, // ( 61, 118) + { 0, { 0, 0, 0}}, // ( 62, 118) + { 0, { 0, 0, 0}}, // ( 63, 118) + { 0, { 0, 0, 0}}, // ( 64, 118) + { 0, { 0, 0, 0}}, // ( 65, 118) + { 0, { 0, 0, 0}}, // ( 66, 118) + { 0, { 0, 0, 0}}, // ( 67, 118) + { 0, { 0, 0, 0}}, // ( 68, 118) + { 0, { 0, 0, 0}}, // ( 69, 118) + { 0, { 0, 0, 0}}, // ( 70, 118) + { 0, { 0, 0, 0}}, // ( 71, 118) + { 0, { 0, 0, 0}}, // ( 72, 118) + { 0, { 0, 0, 0}}, // ( 73, 118) + { 0, { 0, 0, 0}}, // ( 74, 118) + { 0, { 0, 0, 0}}, // ( 75, 118) + { 0, { 0, 0, 0}}, // ( 76, 118) + { 0, { 0, 0, 0}}, // ( 77, 118) + { 0, { 0, 0, 0}}, // ( 78, 118) + { 0, { 0, 0, 0}}, // ( 79, 118) + { 0, { 0, 0, 0}}, // ( 80, 118) + { 0, { 0, 0, 0}}, // ( 81, 118) + { 0, { 0, 0, 0}}, // ( 82, 118) + { 0, { 0, 0, 0}}, // ( 83, 118) + { 0, { 0, 0, 0}}, // ( 84, 118) + { 0, { 0, 0, 0}}, // ( 85, 118) + { 0, { 0, 0, 0}}, // ( 86, 118) + { 0, { 0, 0, 0}}, // ( 87, 118) + { 0, { 0, 0, 0}}, // ( 88, 118) + { 0, { 0, 0, 0}}, // ( 89, 118) + { 0, { 0, 0, 0}}, // ( 90, 118) + { 0, { 0, 0, 0}}, // ( 91, 118) + { 0, { 0, 0, 0}}, // ( 92, 118) + { 0, { 0, 0, 0}}, // ( 93, 118) + { 0, { 0, 0, 0}}, // ( 94, 118) + { 0, { 0, 0, 0}}, // ( 95, 118) + { 0, { 0, 0, 0}}, // ( 96, 118) + { 0, { 0, 0, 0}}, // ( 97, 118) + { 0, { 0, 0, 0}}, // ( 98, 118) + { 0, { 0, 0, 0}}, // ( 99, 118) + { 0, { 0, 0, 0}}, // (100, 118) + { 0, { 0, 0, 0}}, // (101, 118) + { 0, { 0, 0, 0}}, // (102, 118) + { 0, { 0, 0, 0}}, // (103, 118) + { 0, { 0, 0, 0}}, // (104, 118) + { 0, { 0, 0, 0}}, // (105, 118) + { 0, { 0, 0, 0}}, // (106, 118) + { 0, { 0, 0, 0}}, // (107, 118) + { 0, { 0, 0, 0}}, // (108, 118) + { 0, { 0, 0, 0}}, // (109, 118) + { 0, { 0, 0, 0}}, // (110, 118) + { 0, { 0, 0, 0}}, // (111, 118) + { 0, { 0, 0, 0}}, // (112, 118) + { 0, { 0, 0, 0}}, // (113, 118) + { 0, { 0, 0, 0}}, // (114, 118) + { 0, { 0, 0, 0}}, // (115, 118) + { 0, { 0, 0, 0}}, // (116, 118) + { 0, { 0, 0, 0}}, // (117, 118) + { 0, { 0, 0, 0}}, // (118, 118) + { 0, { 0, 0, 0}}, // (119, 118) + { 0, { 0, 0, 0}}, // (120, 118) + { 0, { 0, 0, 0}}, // (121, 118) + { 0, { 0, 0, 0}}, // (122, 118) + { 0, { 0, 0, 0}}, // (123, 118) + { 0, { 0, 0, 0}}, // (124, 118) + { 0, { 0, 0, 0}}, // (125, 118) + { 0, { 0, 0, 0}}, // (126, 118) + { 0, { 0, 0, 0}}, // (127, 118) + { 0, { 0, 0, 0}}, // (128, 118) + { 0, { 0, 0, 0}}, // (129, 118) + { 0, { 0, 0, 0}}, // (130, 118) + { 0, { 0, 0, 0}}, // (131, 118) + { 0, { 0, 0, 0}}, // (132, 118) + { 0, { 0, 0, 0}}, // (133, 118) + { 0, { 0, 0, 0}}, // (134, 118) + { 0, { 0, 0, 0}}, // (135, 118) + { 0, { 0, 0, 0}}, // (136, 118) + { 0, { 0, 0, 0}}, // (137, 118) + { 0, { 0, 0, 0}}, // (138, 118) + { 0, { 0, 0, 0}}, // (139, 118) + { 0, { 0, 0, 0}}, // (140, 118) + { 0, { 0, 0, 0}}, // (141, 118) + { 0, { 0, 0, 0}}, // (142, 118) + { 0, { 0, 0, 0}}, // (143, 118) + { 0, { 0, 0, 0}}, // (144, 118) + { 0, { 0, 0, 0}}, // (145, 118) + { 0, { 0, 0, 0}}, // (146, 118) + { 0, { 0, 0, 0}}, // (147, 118) + { 0, { 0, 0, 0}}, // (148, 118) + { 0, { 0, 0, 0}}, // (149, 118) + { 0, { 0, 0, 0}}, // (150, 118) + { 0, { 0, 0, 0}}, // (151, 118) + { 0, { 0, 0, 0}}, // (152, 118) + { 0, { 0, 0, 0}}, // (153, 118) + { 0, { 0, 0, 0}}, // (154, 118) + { 0, { 0, 0, 0}}, // (155, 118) + { 0, { 0, 0, 0}}, // (156, 118) + { 0, { 0, 0, 0}}, // (157, 118) + { 0, { 0, 0, 0}}, // (158, 118) + { 0, { 0, 0, 0}}, // (159, 118) + { 0, { 0, 0, 0}}, // (160, 118) + { 0, { 0, 0, 0}}, // (161, 118) + { 0, { 0, 0, 0}}, // (162, 118) + { 0, { 0, 0, 0}}, // (163, 118) + { 0, { 0, 0, 0}}, // (164, 118) + { 0, { 0, 0, 0}}, // (165, 118) + { 0, { 0, 0, 0}}, // (166, 118) + { 0, { 0, 0, 0}}, // (167, 118) + { 0, { 0, 0, 0}}, // (168, 118) + { 0, { 0, 0, 0}}, // (169, 118) + { 0, { 0, 0, 0}}, // (170, 118) + { 0, { 0, 0, 0}}, // (171, 118) + { 0, { 0, 0, 0}}, // (172, 118) + { 95, { 0, 0, 0}}, // (173, 118) + {128, { 0, 0, 0}}, // (174, 118) + {128, { 0, 0, 0}}, // (175, 118) + {128, { 0, 0, 0}}, // (176, 118) + {128, { 0, 0, 0}}, // (177, 118) + {128, { 0, 0, 0}}, // (178, 118) + {128, { 0, 0, 0}}, // (179, 118) + {128, { 0, 0, 0}}, // ( 0, 119) + {128, { 0, 0, 0}}, // ( 1, 119) + {128, { 0, 0, 0}}, // ( 2, 119) + {128, { 0, 0, 0}}, // ( 3, 119) + {128, { 0, 0, 0}}, // ( 4, 119) + {128, { 0, 0, 0}}, // ( 5, 119) + {126, { 0, 0, 0}}, // ( 6, 119) + { 12, { 0, 0, 0}}, // ( 7, 119) + { 0, { 0, 0, 0}}, // ( 8, 119) + { 0, { 0, 0, 0}}, // ( 9, 119) + { 0, { 0, 0, 0}}, // ( 10, 119) + { 0, { 0, 0, 0}}, // ( 11, 119) + { 0, { 0, 0, 0}}, // ( 12, 119) + { 0, { 0, 0, 0}}, // ( 13, 119) + { 0, { 0, 0, 0}}, // ( 14, 119) + { 0, { 0, 0, 0}}, // ( 15, 119) + { 0, { 0, 0, 0}}, // ( 16, 119) + { 0, { 0, 0, 0}}, // ( 17, 119) + { 0, { 0, 0, 0}}, // ( 18, 119) + { 0, { 0, 0, 0}}, // ( 19, 119) + { 0, { 0, 0, 0}}, // ( 20, 119) + { 0, { 0, 0, 0}}, // ( 21, 119) + { 0, { 0, 0, 0}}, // ( 22, 119) + { 0, { 0, 0, 0}}, // ( 23, 119) + { 0, { 0, 0, 0}}, // ( 24, 119) + { 0, { 0, 0, 0}}, // ( 25, 119) + { 0, { 0, 0, 0}}, // ( 26, 119) + { 0, { 0, 0, 0}}, // ( 27, 119) + { 0, { 0, 0, 0}}, // ( 28, 119) + { 0, { 0, 0, 0}}, // ( 29, 119) + { 0, { 0, 0, 0}}, // ( 30, 119) + { 0, { 0, 0, 0}}, // ( 31, 119) + { 0, { 0, 0, 0}}, // ( 32, 119) + { 0, { 0, 0, 0}}, // ( 33, 119) + { 0, { 0, 0, 0}}, // ( 34, 119) + { 0, { 0, 0, 0}}, // ( 35, 119) + { 0, { 0, 0, 0}}, // ( 36, 119) + { 0, { 0, 0, 0}}, // ( 37, 119) + { 0, { 0, 0, 0}}, // ( 38, 119) + { 0, { 0, 0, 0}}, // ( 39, 119) + { 0, { 0, 0, 0}}, // ( 40, 119) + { 0, { 0, 0, 0}}, // ( 41, 119) + { 0, { 0, 0, 0}}, // ( 42, 119) + { 0, { 0, 0, 0}}, // ( 43, 119) + { 0, { 0, 0, 0}}, // ( 44, 119) + { 0, { 0, 0, 0}}, // ( 45, 119) + { 0, { 0, 0, 0}}, // ( 46, 119) + { 0, { 0, 0, 0}}, // ( 47, 119) + { 0, { 0, 0, 0}}, // ( 48, 119) + { 0, { 0, 0, 0}}, // ( 49, 119) + { 0, { 0, 0, 0}}, // ( 50, 119) + { 0, { 0, 0, 0}}, // ( 51, 119) + { 0, { 0, 0, 0}}, // ( 52, 119) + { 0, { 0, 0, 0}}, // ( 53, 119) + { 0, { 0, 0, 0}}, // ( 54, 119) + { 0, { 0, 0, 0}}, // ( 55, 119) + { 0, { 0, 0, 0}}, // ( 56, 119) + { 0, { 0, 0, 0}}, // ( 57, 119) + { 0, { 0, 0, 0}}, // ( 58, 119) + { 0, { 0, 0, 0}}, // ( 59, 119) + { 0, { 0, 0, 0}}, // ( 60, 119) + { 0, { 0, 0, 0}}, // ( 61, 119) + { 0, { 0, 0, 0}}, // ( 62, 119) + { 0, { 0, 0, 0}}, // ( 63, 119) + { 0, { 0, 0, 0}}, // ( 64, 119) + { 0, { 0, 0, 0}}, // ( 65, 119) + { 0, { 0, 0, 0}}, // ( 66, 119) + { 0, { 0, 0, 0}}, // ( 67, 119) + { 0, { 0, 0, 0}}, // ( 68, 119) + { 0, { 0, 0, 0}}, // ( 69, 119) + { 0, { 0, 0, 0}}, // ( 70, 119) + { 0, { 0, 0, 0}}, // ( 71, 119) + { 0, { 0, 0, 0}}, // ( 72, 119) + { 0, { 0, 0, 0}}, // ( 73, 119) + { 0, { 0, 0, 0}}, // ( 74, 119) + { 0, { 0, 0, 0}}, // ( 75, 119) + { 0, { 0, 0, 0}}, // ( 76, 119) + { 0, { 0, 0, 0}}, // ( 77, 119) + { 0, { 0, 0, 0}}, // ( 78, 119) + { 0, { 0, 0, 0}}, // ( 79, 119) + { 0, { 0, 0, 0}}, // ( 80, 119) + { 0, { 0, 0, 0}}, // ( 81, 119) + { 0, { 0, 0, 0}}, // ( 82, 119) + { 0, { 0, 0, 0}}, // ( 83, 119) + { 0, { 0, 0, 0}}, // ( 84, 119) + { 0, { 0, 0, 0}}, // ( 85, 119) + { 0, { 0, 0, 0}}, // ( 86, 119) + { 0, { 0, 0, 0}}, // ( 87, 119) + { 0, { 0, 0, 0}}, // ( 88, 119) + { 0, { 0, 0, 0}}, // ( 89, 119) + { 0, { 0, 0, 0}}, // ( 90, 119) + { 0, { 0, 0, 0}}, // ( 91, 119) + { 0, { 0, 0, 0}}, // ( 92, 119) + { 0, { 0, 0, 0}}, // ( 93, 119) + { 0, { 0, 0, 0}}, // ( 94, 119) + { 0, { 0, 0, 0}}, // ( 95, 119) + { 0, { 0, 0, 0}}, // ( 96, 119) + { 0, { 0, 0, 0}}, // ( 97, 119) + { 0, { 0, 0, 0}}, // ( 98, 119) + { 0, { 0, 0, 0}}, // ( 99, 119) + { 0, { 0, 0, 0}}, // (100, 119) + { 0, { 0, 0, 0}}, // (101, 119) + { 0, { 0, 0, 0}}, // (102, 119) + { 0, { 0, 0, 0}}, // (103, 119) + { 0, { 0, 0, 0}}, // (104, 119) + { 0, { 0, 0, 0}}, // (105, 119) + { 0, { 0, 0, 0}}, // (106, 119) + { 0, { 0, 0, 0}}, // (107, 119) + { 0, { 0, 0, 0}}, // (108, 119) + { 0, { 0, 0, 0}}, // (109, 119) + { 0, { 0, 0, 0}}, // (110, 119) + { 0, { 0, 0, 0}}, // (111, 119) + { 0, { 0, 0, 0}}, // (112, 119) + { 0, { 0, 0, 0}}, // (113, 119) + { 0, { 0, 0, 0}}, // (114, 119) + { 0, { 0, 0, 0}}, // (115, 119) + { 0, { 0, 0, 0}}, // (116, 119) + { 0, { 0, 0, 0}}, // (117, 119) + { 0, { 0, 0, 0}}, // (118, 119) + { 0, { 0, 0, 0}}, // (119, 119) + { 0, { 0, 0, 0}}, // (120, 119) + { 0, { 0, 0, 0}}, // (121, 119) + { 0, { 0, 0, 0}}, // (122, 119) + { 0, { 0, 0, 0}}, // (123, 119) + { 0, { 0, 0, 0}}, // (124, 119) + { 0, { 0, 0, 0}}, // (125, 119) + { 0, { 0, 0, 0}}, // (126, 119) + { 0, { 0, 0, 0}}, // (127, 119) + { 0, { 0, 0, 0}}, // (128, 119) + { 0, { 0, 0, 0}}, // (129, 119) + { 0, { 0, 0, 0}}, // (130, 119) + { 0, { 0, 0, 0}}, // (131, 119) + { 0, { 0, 0, 0}}, // (132, 119) + { 0, { 0, 0, 0}}, // (133, 119) + { 0, { 0, 0, 0}}, // (134, 119) + { 0, { 0, 0, 0}}, // (135, 119) + { 0, { 0, 0, 0}}, // (136, 119) + { 0, { 0, 0, 0}}, // (137, 119) + { 0, { 0, 0, 0}}, // (138, 119) + { 0, { 0, 0, 0}}, // (139, 119) + { 0, { 0, 0, 0}}, // (140, 119) + { 0, { 0, 0, 0}}, // (141, 119) + { 0, { 0, 0, 0}}, // (142, 119) + { 0, { 0, 0, 0}}, // (143, 119) + { 0, { 0, 0, 0}}, // (144, 119) + { 0, { 0, 0, 0}}, // (145, 119) + { 0, { 0, 0, 0}}, // (146, 119) + { 0, { 0, 0, 0}}, // (147, 119) + { 0, { 0, 0, 0}}, // (148, 119) + { 0, { 0, 0, 0}}, // (149, 119) + { 0, { 0, 0, 0}}, // (150, 119) + { 0, { 0, 0, 0}}, // (151, 119) + { 0, { 0, 0, 0}}, // (152, 119) + { 0, { 0, 0, 0}}, // (153, 119) + { 0, { 0, 0, 0}}, // (154, 119) + { 0, { 0, 0, 0}}, // (155, 119) + { 0, { 0, 0, 0}}, // (156, 119) + { 0, { 0, 0, 0}}, // (157, 119) + { 0, { 0, 0, 0}}, // (158, 119) + { 0, { 0, 0, 0}}, // (159, 119) + { 0, { 0, 0, 0}}, // (160, 119) + { 0, { 0, 0, 0}}, // (161, 119) + { 0, { 0, 0, 0}}, // (162, 119) + { 0, { 0, 0, 0}}, // (163, 119) + { 0, { 0, 0, 0}}, // (164, 119) + { 0, { 0, 0, 0}}, // (165, 119) + { 0, { 0, 0, 0}}, // (166, 119) + { 0, { 0, 0, 0}}, // (167, 119) + { 0, { 0, 0, 0}}, // (168, 119) + { 0, { 0, 0, 0}}, // (169, 119) + { 0, { 0, 0, 0}}, // (170, 119) + { 0, { 0, 0, 0}}, // (171, 119) + { 12, { 0, 0, 0}}, // (172, 119) + {126, { 0, 0, 0}}, // (173, 119) + {128, { 0, 0, 0}}, // (174, 119) + {128, { 0, 0, 0}}, // (175, 119) + {128, { 0, 0, 0}}, // (176, 119) + {128, { 0, 0, 0}}, // (177, 119) + {128, { 0, 0, 0}}, // (178, 119) + {128, { 0, 0, 0}}, // (179, 119) + {128, { 0, 0, 0}}, // ( 0, 120) + {128, { 0, 0, 0}}, // ( 1, 120) + {128, { 0, 0, 0}}, // ( 2, 120) + {128, { 0, 0, 0}}, // ( 3, 120) + {128, { 0, 0, 0}}, // ( 4, 120) + {128, { 0, 0, 0}}, // ( 5, 120) + {128, { 0, 0, 0}}, // ( 6, 120) + { 55, { 0, 0, 0}}, // ( 7, 120) + { 0, { 0, 0, 0}}, // ( 8, 120) + { 0, { 0, 0, 0}}, // ( 9, 120) + { 0, { 0, 0, 0}}, // ( 10, 120) + { 0, { 0, 0, 0}}, // ( 11, 120) + { 0, { 0, 0, 0}}, // ( 12, 120) + { 0, { 0, 0, 0}}, // ( 13, 120) + { 0, { 0, 0, 0}}, // ( 14, 120) + { 0, { 0, 0, 0}}, // ( 15, 120) + { 0, { 0, 0, 0}}, // ( 16, 120) + { 0, { 0, 0, 0}}, // ( 17, 120) + { 0, { 0, 0, 0}}, // ( 18, 120) + { 0, { 0, 0, 0}}, // ( 19, 120) + { 0, { 0, 0, 0}}, // ( 20, 120) + { 0, { 0, 0, 0}}, // ( 21, 120) + { 0, { 0, 0, 0}}, // ( 22, 120) + { 0, { 0, 0, 0}}, // ( 23, 120) + { 0, { 0, 0, 0}}, // ( 24, 120) + { 0, { 0, 0, 0}}, // ( 25, 120) + { 0, { 0, 0, 0}}, // ( 26, 120) + { 0, { 0, 0, 0}}, // ( 27, 120) + { 0, { 0, 0, 0}}, // ( 28, 120) + { 0, { 0, 0, 0}}, // ( 29, 120) + { 0, { 0, 0, 0}}, // ( 30, 120) + { 0, { 0, 0, 0}}, // ( 31, 120) + { 0, { 0, 0, 0}}, // ( 32, 120) + { 0, { 0, 0, 0}}, // ( 33, 120) + { 0, { 0, 0, 0}}, // ( 34, 120) + { 0, { 0, 0, 0}}, // ( 35, 120) + { 0, { 0, 0, 0}}, // ( 36, 120) + { 0, { 0, 0, 0}}, // ( 37, 120) + { 0, { 0, 0, 0}}, // ( 38, 120) + { 0, { 0, 0, 0}}, // ( 39, 120) + { 0, { 0, 0, 0}}, // ( 40, 120) + { 0, { 0, 0, 0}}, // ( 41, 120) + { 0, { 0, 0, 0}}, // ( 42, 120) + { 0, { 0, 0, 0}}, // ( 43, 120) + { 0, { 0, 0, 0}}, // ( 44, 120) + { 0, { 0, 0, 0}}, // ( 45, 120) + { 0, { 0, 0, 0}}, // ( 46, 120) + { 0, { 0, 0, 0}}, // ( 47, 120) + { 0, { 0, 0, 0}}, // ( 48, 120) + { 0, { 0, 0, 0}}, // ( 49, 120) + { 0, { 0, 0, 0}}, // ( 50, 120) + { 0, { 0, 0, 0}}, // ( 51, 120) + { 0, { 0, 0, 0}}, // ( 52, 120) + { 0, { 0, 0, 0}}, // ( 53, 120) + { 0, { 0, 0, 0}}, // ( 54, 120) + { 0, { 0, 0, 0}}, // ( 55, 120) + { 0, { 0, 0, 0}}, // ( 56, 120) + { 0, { 0, 0, 0}}, // ( 57, 120) + { 0, { 0, 0, 0}}, // ( 58, 120) + { 0, { 0, 0, 0}}, // ( 59, 120) + { 0, { 0, 0, 0}}, // ( 60, 120) + { 0, { 0, 0, 0}}, // ( 61, 120) + { 0, { 0, 0, 0}}, // ( 62, 120) + { 0, { 0, 0, 0}}, // ( 63, 120) + { 0, { 0, 0, 0}}, // ( 64, 120) + { 0, { 0, 0, 0}}, // ( 65, 120) + { 0, { 0, 0, 0}}, // ( 66, 120) + { 0, { 0, 0, 0}}, // ( 67, 120) + { 0, { 0, 0, 0}}, // ( 68, 120) + { 0, { 0, 0, 0}}, // ( 69, 120) + { 0, { 0, 0, 0}}, // ( 70, 120) + { 0, { 0, 0, 0}}, // ( 71, 120) + { 0, { 0, 0, 0}}, // ( 72, 120) + { 0, { 0, 0, 0}}, // ( 73, 120) + { 0, { 0, 0, 0}}, // ( 74, 120) + { 0, { 0, 0, 0}}, // ( 75, 120) + { 0, { 0, 0, 0}}, // ( 76, 120) + { 0, { 0, 0, 0}}, // ( 77, 120) + { 0, { 0, 0, 0}}, // ( 78, 120) + { 0, { 0, 0, 0}}, // ( 79, 120) + { 0, { 0, 0, 0}}, // ( 80, 120) + { 0, { 0, 0, 0}}, // ( 81, 120) + { 0, { 0, 0, 0}}, // ( 82, 120) + { 0, { 0, 0, 0}}, // ( 83, 120) + { 0, { 0, 0, 0}}, // ( 84, 120) + { 0, { 0, 0, 0}}, // ( 85, 120) + { 0, { 0, 0, 0}}, // ( 86, 120) + { 0, { 0, 0, 0}}, // ( 87, 120) + { 0, { 0, 0, 0}}, // ( 88, 120) + { 0, { 0, 0, 0}}, // ( 89, 120) + { 0, { 0, 0, 0}}, // ( 90, 120) + { 0, { 0, 0, 0}}, // ( 91, 120) + { 0, { 0, 0, 0}}, // ( 92, 120) + { 0, { 0, 0, 0}}, // ( 93, 120) + { 0, { 0, 0, 0}}, // ( 94, 120) + { 0, { 0, 0, 0}}, // ( 95, 120) + { 0, { 0, 0, 0}}, // ( 96, 120) + { 0, { 0, 0, 0}}, // ( 97, 120) + { 0, { 0, 0, 0}}, // ( 98, 120) + { 0, { 0, 0, 0}}, // ( 99, 120) + { 0, { 0, 0, 0}}, // (100, 120) + { 0, { 0, 0, 0}}, // (101, 120) + { 0, { 0, 0, 0}}, // (102, 120) + { 0, { 0, 0, 0}}, // (103, 120) + { 0, { 0, 0, 0}}, // (104, 120) + { 0, { 0, 0, 0}}, // (105, 120) + { 0, { 0, 0, 0}}, // (106, 120) + { 0, { 0, 0, 0}}, // (107, 120) + { 0, { 0, 0, 0}}, // (108, 120) + { 0, { 0, 0, 0}}, // (109, 120) + { 0, { 0, 0, 0}}, // (110, 120) + { 0, { 0, 0, 0}}, // (111, 120) + { 0, { 0, 0, 0}}, // (112, 120) + { 0, { 0, 0, 0}}, // (113, 120) + { 0, { 0, 0, 0}}, // (114, 120) + { 0, { 0, 0, 0}}, // (115, 120) + { 0, { 0, 0, 0}}, // (116, 120) + { 0, { 0, 0, 0}}, // (117, 120) + { 0, { 0, 0, 0}}, // (118, 120) + { 0, { 0, 0, 0}}, // (119, 120) + { 0, { 0, 0, 0}}, // (120, 120) + { 0, { 0, 0, 0}}, // (121, 120) + { 0, { 0, 0, 0}}, // (122, 120) + { 0, { 0, 0, 0}}, // (123, 120) + { 0, { 0, 0, 0}}, // (124, 120) + { 0, { 0, 0, 0}}, // (125, 120) + { 0, { 0, 0, 0}}, // (126, 120) + { 0, { 0, 0, 0}}, // (127, 120) + { 0, { 0, 0, 0}}, // (128, 120) + { 0, { 0, 0, 0}}, // (129, 120) + { 0, { 0, 0, 0}}, // (130, 120) + { 0, { 0, 0, 0}}, // (131, 120) + { 0, { 0, 0, 0}}, // (132, 120) + { 0, { 0, 0, 0}}, // (133, 120) + { 0, { 0, 0, 0}}, // (134, 120) + { 0, { 0, 0, 0}}, // (135, 120) + { 0, { 0, 0, 0}}, // (136, 120) + { 0, { 0, 0, 0}}, // (137, 120) + { 0, { 0, 0, 0}}, // (138, 120) + { 0, { 0, 0, 0}}, // (139, 120) + { 0, { 0, 0, 0}}, // (140, 120) + { 0, { 0, 0, 0}}, // (141, 120) + { 0, { 0, 0, 0}}, // (142, 120) + { 0, { 0, 0, 0}}, // (143, 120) + { 0, { 0, 0, 0}}, // (144, 120) + { 0, { 0, 0, 0}}, // (145, 120) + { 0, { 0, 0, 0}}, // (146, 120) + { 0, { 0, 0, 0}}, // (147, 120) + { 0, { 0, 0, 0}}, // (148, 120) + { 0, { 0, 0, 0}}, // (149, 120) + { 0, { 0, 0, 0}}, // (150, 120) + { 0, { 0, 0, 0}}, // (151, 120) + { 0, { 0, 0, 0}}, // (152, 120) + { 0, { 0, 0, 0}}, // (153, 120) + { 0, { 0, 0, 0}}, // (154, 120) + { 0, { 0, 0, 0}}, // (155, 120) + { 0, { 0, 0, 0}}, // (156, 120) + { 0, { 0, 0, 0}}, // (157, 120) + { 0, { 0, 0, 0}}, // (158, 120) + { 0, { 0, 0, 0}}, // (159, 120) + { 0, { 0, 0, 0}}, // (160, 120) + { 0, { 0, 0, 0}}, // (161, 120) + { 0, { 0, 0, 0}}, // (162, 120) + { 0, { 0, 0, 0}}, // (163, 120) + { 0, { 0, 0, 0}}, // (164, 120) + { 0, { 0, 0, 0}}, // (165, 120) + { 0, { 0, 0, 0}}, // (166, 120) + { 0, { 0, 0, 0}}, // (167, 120) + { 0, { 0, 0, 0}}, // (168, 120) + { 0, { 0, 0, 0}}, // (169, 120) + { 0, { 0, 0, 0}}, // (170, 120) + { 0, { 0, 0, 0}}, // (171, 120) + { 55, { 0, 0, 0}}, // (172, 120) + {128, { 0, 0, 0}}, // (173, 120) + {128, { 0, 0, 0}}, // (174, 120) + {128, { 0, 0, 0}}, // (175, 120) + {128, { 0, 0, 0}}, // (176, 120) + {128, { 0, 0, 0}}, // (177, 120) + {128, { 0, 0, 0}}, // (178, 120) + {128, { 0, 0, 0}}, // (179, 120) + {128, { 0, 0, 0}}, // ( 0, 121) + {128, { 0, 0, 0}}, // ( 1, 121) + {128, { 0, 0, 0}}, // ( 2, 121) + {128, { 0, 0, 0}}, // ( 3, 121) + {128, { 0, 0, 0}}, // ( 4, 121) + {128, { 0, 0, 0}}, // ( 5, 121) + {128, { 0, 0, 0}}, // ( 6, 121) + {106, { 0, 0, 0}}, // ( 7, 121) + { 0, { 0, 0, 0}}, // ( 8, 121) + { 0, { 0, 0, 0}}, // ( 9, 121) + { 0, { 0, 0, 0}}, // ( 10, 121) + { 0, { 0, 0, 0}}, // ( 11, 121) + { 0, { 0, 0, 0}}, // ( 12, 121) + { 0, { 0, 0, 0}}, // ( 13, 121) + { 0, { 0, 0, 0}}, // ( 14, 121) + { 0, { 0, 0, 0}}, // ( 15, 121) + { 0, { 0, 0, 0}}, // ( 16, 121) + { 0, { 0, 0, 0}}, // ( 17, 121) + { 0, { 0, 0, 0}}, // ( 18, 121) + { 0, { 0, 0, 0}}, // ( 19, 121) + { 0, { 0, 0, 0}}, // ( 20, 121) + { 0, { 0, 0, 0}}, // ( 21, 121) + { 0, { 0, 0, 0}}, // ( 22, 121) + { 0, { 0, 0, 0}}, // ( 23, 121) + { 0, { 0, 0, 0}}, // ( 24, 121) + { 0, { 0, 0, 0}}, // ( 25, 121) + { 0, { 0, 0, 0}}, // ( 26, 121) + { 0, { 0, 0, 0}}, // ( 27, 121) + { 0, { 0, 0, 0}}, // ( 28, 121) + { 0, { 0, 0, 0}}, // ( 29, 121) + { 0, { 0, 0, 0}}, // ( 30, 121) + { 0, { 0, 0, 0}}, // ( 31, 121) + { 0, { 0, 0, 0}}, // ( 32, 121) + { 0, { 0, 0, 0}}, // ( 33, 121) + { 0, { 0, 0, 0}}, // ( 34, 121) + { 0, { 0, 0, 0}}, // ( 35, 121) + { 0, { 0, 0, 0}}, // ( 36, 121) + { 0, { 0, 0, 0}}, // ( 37, 121) + { 0, { 0, 0, 0}}, // ( 38, 121) + { 0, { 0, 0, 0}}, // ( 39, 121) + { 0, { 0, 0, 0}}, // ( 40, 121) + { 0, { 0, 0, 0}}, // ( 41, 121) + { 0, { 0, 0, 0}}, // ( 42, 121) + { 0, { 0, 0, 0}}, // ( 43, 121) + { 0, { 0, 0, 0}}, // ( 44, 121) + { 0, { 0, 0, 0}}, // ( 45, 121) + { 0, { 0, 0, 0}}, // ( 46, 121) + { 0, { 0, 0, 0}}, // ( 47, 121) + { 0, { 0, 0, 0}}, // ( 48, 121) + { 0, { 0, 0, 0}}, // ( 49, 121) + { 0, { 0, 0, 0}}, // ( 50, 121) + { 0, { 0, 0, 0}}, // ( 51, 121) + { 0, { 0, 0, 0}}, // ( 52, 121) + { 0, { 0, 0, 0}}, // ( 53, 121) + { 0, { 0, 0, 0}}, // ( 54, 121) + { 0, { 0, 0, 0}}, // ( 55, 121) + { 0, { 0, 0, 0}}, // ( 56, 121) + { 0, { 0, 0, 0}}, // ( 57, 121) + { 0, { 0, 0, 0}}, // ( 58, 121) + { 0, { 0, 0, 0}}, // ( 59, 121) + { 0, { 0, 0, 0}}, // ( 60, 121) + { 0, { 0, 0, 0}}, // ( 61, 121) + { 0, { 0, 0, 0}}, // ( 62, 121) + { 0, { 0, 0, 0}}, // ( 63, 121) + { 0, { 0, 0, 0}}, // ( 64, 121) + { 0, { 0, 0, 0}}, // ( 65, 121) + { 0, { 0, 0, 0}}, // ( 66, 121) + { 0, { 0, 0, 0}}, // ( 67, 121) + { 0, { 0, 0, 0}}, // ( 68, 121) + { 0, { 0, 0, 0}}, // ( 69, 121) + { 0, { 0, 0, 0}}, // ( 70, 121) + { 0, { 0, 0, 0}}, // ( 71, 121) + { 0, { 0, 0, 0}}, // ( 72, 121) + { 0, { 0, 0, 0}}, // ( 73, 121) + { 0, { 0, 0, 0}}, // ( 74, 121) + { 0, { 0, 0, 0}}, // ( 75, 121) + { 0, { 0, 0, 0}}, // ( 76, 121) + { 0, { 0, 0, 0}}, // ( 77, 121) + { 0, { 0, 0, 0}}, // ( 78, 121) + { 0, { 0, 0, 0}}, // ( 79, 121) + { 0, { 0, 0, 0}}, // ( 80, 121) + { 0, { 0, 0, 0}}, // ( 81, 121) + { 0, { 0, 0, 0}}, // ( 82, 121) + { 0, { 0, 0, 0}}, // ( 83, 121) + { 0, { 0, 0, 0}}, // ( 84, 121) + { 0, { 0, 0, 0}}, // ( 85, 121) + { 0, { 0, 0, 0}}, // ( 86, 121) + { 0, { 0, 0, 0}}, // ( 87, 121) + { 0, { 0, 0, 0}}, // ( 88, 121) + { 0, { 0, 0, 0}}, // ( 89, 121) + { 0, { 0, 0, 0}}, // ( 90, 121) + { 0, { 0, 0, 0}}, // ( 91, 121) + { 0, { 0, 0, 0}}, // ( 92, 121) + { 0, { 0, 0, 0}}, // ( 93, 121) + { 0, { 0, 0, 0}}, // ( 94, 121) + { 0, { 0, 0, 0}}, // ( 95, 121) + { 0, { 0, 0, 0}}, // ( 96, 121) + { 0, { 0, 0, 0}}, // ( 97, 121) + { 0, { 0, 0, 0}}, // ( 98, 121) + { 0, { 0, 0, 0}}, // ( 99, 121) + { 0, { 0, 0, 0}}, // (100, 121) + { 0, { 0, 0, 0}}, // (101, 121) + { 0, { 0, 0, 0}}, // (102, 121) + { 0, { 0, 0, 0}}, // (103, 121) + { 0, { 0, 0, 0}}, // (104, 121) + { 0, { 0, 0, 0}}, // (105, 121) + { 0, { 0, 0, 0}}, // (106, 121) + { 0, { 0, 0, 0}}, // (107, 121) + { 0, { 0, 0, 0}}, // (108, 121) + { 0, { 0, 0, 0}}, // (109, 121) + { 0, { 0, 0, 0}}, // (110, 121) + { 0, { 0, 0, 0}}, // (111, 121) + { 0, { 0, 0, 0}}, // (112, 121) + { 0, { 0, 0, 0}}, // (113, 121) + { 0, { 0, 0, 0}}, // (114, 121) + { 0, { 0, 0, 0}}, // (115, 121) + { 0, { 0, 0, 0}}, // (116, 121) + { 0, { 0, 0, 0}}, // (117, 121) + { 0, { 0, 0, 0}}, // (118, 121) + { 0, { 0, 0, 0}}, // (119, 121) + { 0, { 0, 0, 0}}, // (120, 121) + { 0, { 0, 0, 0}}, // (121, 121) + { 0, { 0, 0, 0}}, // (122, 121) + { 0, { 0, 0, 0}}, // (123, 121) + { 0, { 0, 0, 0}}, // (124, 121) + { 0, { 0, 0, 0}}, // (125, 121) + { 0, { 0, 0, 0}}, // (126, 121) + { 0, { 0, 0, 0}}, // (127, 121) + { 0, { 0, 0, 0}}, // (128, 121) + { 0, { 0, 0, 0}}, // (129, 121) + { 0, { 0, 0, 0}}, // (130, 121) + { 0, { 0, 0, 0}}, // (131, 121) + { 0, { 0, 0, 0}}, // (132, 121) + { 0, { 0, 0, 0}}, // (133, 121) + { 0, { 0, 0, 0}}, // (134, 121) + { 0, { 0, 0, 0}}, // (135, 121) + { 0, { 0, 0, 0}}, // (136, 121) + { 0, { 0, 0, 0}}, // (137, 121) + { 0, { 0, 0, 0}}, // (138, 121) + { 0, { 0, 0, 0}}, // (139, 121) + { 0, { 0, 0, 0}}, // (140, 121) + { 0, { 0, 0, 0}}, // (141, 121) + { 0, { 0, 0, 0}}, // (142, 121) + { 0, { 0, 0, 0}}, // (143, 121) + { 0, { 0, 0, 0}}, // (144, 121) + { 0, { 0, 0, 0}}, // (145, 121) + { 0, { 0, 0, 0}}, // (146, 121) + { 0, { 0, 0, 0}}, // (147, 121) + { 0, { 0, 0, 0}}, // (148, 121) + { 0, { 0, 0, 0}}, // (149, 121) + { 0, { 0, 0, 0}}, // (150, 121) + { 0, { 0, 0, 0}}, // (151, 121) + { 0, { 0, 0, 0}}, // (152, 121) + { 0, { 0, 0, 0}}, // (153, 121) + { 0, { 0, 0, 0}}, // (154, 121) + { 0, { 0, 0, 0}}, // (155, 121) + { 0, { 0, 0, 0}}, // (156, 121) + { 0, { 0, 0, 0}}, // (157, 121) + { 0, { 0, 0, 0}}, // (158, 121) + { 0, { 0, 0, 0}}, // (159, 121) + { 0, { 0, 0, 0}}, // (160, 121) + { 0, { 0, 0, 0}}, // (161, 121) + { 0, { 0, 0, 0}}, // (162, 121) + { 0, { 0, 0, 0}}, // (163, 121) + { 0, { 0, 0, 0}}, // (164, 121) + { 0, { 0, 0, 0}}, // (165, 121) + { 0, { 0, 0, 0}}, // (166, 121) + { 0, { 0, 0, 0}}, // (167, 121) + { 0, { 0, 0, 0}}, // (168, 121) + { 0, { 0, 0, 0}}, // (169, 121) + { 0, { 0, 0, 0}}, // (170, 121) + { 0, { 0, 0, 0}}, // (171, 121) + {105, { 0, 0, 0}}, // (172, 121) + {128, { 0, 0, 0}}, // (173, 121) + {128, { 0, 0, 0}}, // (174, 121) + {128, { 0, 0, 0}}, // (175, 121) + {128, { 0, 0, 0}}, // (176, 121) + {128, { 0, 0, 0}}, // (177, 121) + {128, { 0, 0, 0}}, // (178, 121) + {128, { 0, 0, 0}}, // (179, 121) + {128, { 0, 0, 0}}, // ( 0, 122) + {128, { 0, 0, 0}}, // ( 1, 122) + {128, { 0, 0, 0}}, // ( 2, 122) + {128, { 0, 0, 0}}, // ( 3, 122) + {128, { 0, 0, 0}}, // ( 4, 122) + {128, { 0, 0, 0}}, // ( 5, 122) + {128, { 0, 0, 0}}, // ( 6, 122) + {128, { 0, 0, 0}}, // ( 7, 122) + { 29, { 0, 0, 0}}, // ( 8, 122) + { 0, { 0, 0, 0}}, // ( 9, 122) + { 0, { 0, 0, 0}}, // ( 10, 122) + { 0, { 0, 0, 0}}, // ( 11, 122) + { 0, { 0, 0, 0}}, // ( 12, 122) + { 0, { 0, 0, 0}}, // ( 13, 122) + { 0, { 0, 0, 0}}, // ( 14, 122) + { 0, { 0, 0, 0}}, // ( 15, 122) + { 0, { 0, 0, 0}}, // ( 16, 122) + { 0, { 0, 0, 0}}, // ( 17, 122) + { 0, { 0, 0, 0}}, // ( 18, 122) + { 0, { 0, 0, 0}}, // ( 19, 122) + { 0, { 0, 0, 0}}, // ( 20, 122) + { 0, { 0, 0, 0}}, // ( 21, 122) + { 0, { 0, 0, 0}}, // ( 22, 122) + { 0, { 0, 0, 0}}, // ( 23, 122) + { 0, { 0, 0, 0}}, // ( 24, 122) + { 0, { 0, 0, 0}}, // ( 25, 122) + { 0, { 0, 0, 0}}, // ( 26, 122) + { 0, { 0, 0, 0}}, // ( 27, 122) + { 0, { 0, 0, 0}}, // ( 28, 122) + { 0, { 0, 0, 0}}, // ( 29, 122) + { 0, { 0, 0, 0}}, // ( 30, 122) + { 0, { 0, 0, 0}}, // ( 31, 122) + { 0, { 0, 0, 0}}, // ( 32, 122) + { 0, { 0, 0, 0}}, // ( 33, 122) + { 0, { 0, 0, 0}}, // ( 34, 122) + { 0, { 0, 0, 0}}, // ( 35, 122) + { 0, { 0, 0, 0}}, // ( 36, 122) + { 0, { 0, 0, 0}}, // ( 37, 122) + { 0, { 0, 0, 0}}, // ( 38, 122) + { 0, { 0, 0, 0}}, // ( 39, 122) + { 0, { 0, 0, 0}}, // ( 40, 122) + { 0, { 0, 0, 0}}, // ( 41, 122) + { 0, { 0, 0, 0}}, // ( 42, 122) + { 0, { 0, 0, 0}}, // ( 43, 122) + { 0, { 0, 0, 0}}, // ( 44, 122) + { 0, { 0, 0, 0}}, // ( 45, 122) + { 0, { 0, 0, 0}}, // ( 46, 122) + { 0, { 0, 0, 0}}, // ( 47, 122) + { 0, { 0, 0, 0}}, // ( 48, 122) + { 0, { 0, 0, 0}}, // ( 49, 122) + { 0, { 0, 0, 0}}, // ( 50, 122) + { 0, { 0, 0, 0}}, // ( 51, 122) + { 0, { 0, 0, 0}}, // ( 52, 122) + { 0, { 0, 0, 0}}, // ( 53, 122) + { 0, { 0, 0, 0}}, // ( 54, 122) + { 0, { 0, 0, 0}}, // ( 55, 122) + { 0, { 0, 0, 0}}, // ( 56, 122) + { 0, { 0, 0, 0}}, // ( 57, 122) + { 0, { 0, 0, 0}}, // ( 58, 122) + { 0, { 0, 0, 0}}, // ( 59, 122) + { 0, { 0, 0, 0}}, // ( 60, 122) + { 0, { 0, 0, 0}}, // ( 61, 122) + { 0, { 0, 0, 0}}, // ( 62, 122) + { 0, { 0, 0, 0}}, // ( 63, 122) + { 0, { 0, 0, 0}}, // ( 64, 122) + { 0, { 0, 0, 0}}, // ( 65, 122) + { 0, { 0, 0, 0}}, // ( 66, 122) + { 0, { 0, 0, 0}}, // ( 67, 122) + { 0, { 0, 0, 0}}, // ( 68, 122) + { 0, { 0, 0, 0}}, // ( 69, 122) + { 0, { 0, 0, 0}}, // ( 70, 122) + { 0, { 0, 0, 0}}, // ( 71, 122) + { 0, { 0, 0, 0}}, // ( 72, 122) + { 0, { 0, 0, 0}}, // ( 73, 122) + { 0, { 0, 0, 0}}, // ( 74, 122) + { 0, { 0, 0, 0}}, // ( 75, 122) + { 0, { 0, 0, 0}}, // ( 76, 122) + { 0, { 0, 0, 0}}, // ( 77, 122) + { 0, { 0, 0, 0}}, // ( 78, 122) + { 0, { 0, 0, 0}}, // ( 79, 122) + { 0, { 0, 0, 0}}, // ( 80, 122) + { 0, { 0, 0, 0}}, // ( 81, 122) + { 0, { 0, 0, 0}}, // ( 82, 122) + { 0, { 0, 0, 0}}, // ( 83, 122) + { 0, { 0, 0, 0}}, // ( 84, 122) + { 0, { 0, 0, 0}}, // ( 85, 122) + { 0, { 0, 0, 0}}, // ( 86, 122) + { 0, { 0, 0, 0}}, // ( 87, 122) + { 0, { 0, 0, 0}}, // ( 88, 122) + { 0, { 0, 0, 0}}, // ( 89, 122) + { 0, { 0, 0, 0}}, // ( 90, 122) + { 0, { 0, 0, 0}}, // ( 91, 122) + { 0, { 0, 0, 0}}, // ( 92, 122) + { 0, { 0, 0, 0}}, // ( 93, 122) + { 0, { 0, 0, 0}}, // ( 94, 122) + { 0, { 0, 0, 0}}, // ( 95, 122) + { 0, { 0, 0, 0}}, // ( 96, 122) + { 0, { 0, 0, 0}}, // ( 97, 122) + { 0, { 0, 0, 0}}, // ( 98, 122) + { 0, { 0, 0, 0}}, // ( 99, 122) + { 0, { 0, 0, 0}}, // (100, 122) + { 0, { 0, 0, 0}}, // (101, 122) + { 0, { 0, 0, 0}}, // (102, 122) + { 0, { 0, 0, 0}}, // (103, 122) + { 0, { 0, 0, 0}}, // (104, 122) + { 0, { 0, 0, 0}}, // (105, 122) + { 0, { 0, 0, 0}}, // (106, 122) + { 0, { 0, 0, 0}}, // (107, 122) + { 0, { 0, 0, 0}}, // (108, 122) + { 0, { 0, 0, 0}}, // (109, 122) + { 0, { 0, 0, 0}}, // (110, 122) + { 0, { 0, 0, 0}}, // (111, 122) + { 0, { 0, 0, 0}}, // (112, 122) + { 0, { 0, 0, 0}}, // (113, 122) + { 0, { 0, 0, 0}}, // (114, 122) + { 0, { 0, 0, 0}}, // (115, 122) + { 0, { 0, 0, 0}}, // (116, 122) + { 0, { 0, 0, 0}}, // (117, 122) + { 0, { 0, 0, 0}}, // (118, 122) + { 0, { 0, 0, 0}}, // (119, 122) + { 0, { 0, 0, 0}}, // (120, 122) + { 0, { 0, 0, 0}}, // (121, 122) + { 0, { 0, 0, 0}}, // (122, 122) + { 0, { 0, 0, 0}}, // (123, 122) + { 0, { 0, 0, 0}}, // (124, 122) + { 0, { 0, 0, 0}}, // (125, 122) + { 0, { 0, 0, 0}}, // (126, 122) + { 0, { 0, 0, 0}}, // (127, 122) + { 0, { 0, 0, 0}}, // (128, 122) + { 0, { 0, 0, 0}}, // (129, 122) + { 0, { 0, 0, 0}}, // (130, 122) + { 0, { 0, 0, 0}}, // (131, 122) + { 0, { 0, 0, 0}}, // (132, 122) + { 0, { 0, 0, 0}}, // (133, 122) + { 0, { 0, 0, 0}}, // (134, 122) + { 0, { 0, 0, 0}}, // (135, 122) + { 0, { 0, 0, 0}}, // (136, 122) + { 0, { 0, 0, 0}}, // (137, 122) + { 0, { 0, 0, 0}}, // (138, 122) + { 0, { 0, 0, 0}}, // (139, 122) + { 0, { 0, 0, 0}}, // (140, 122) + { 0, { 0, 0, 0}}, // (141, 122) + { 0, { 0, 0, 0}}, // (142, 122) + { 0, { 0, 0, 0}}, // (143, 122) + { 0, { 0, 0, 0}}, // (144, 122) + { 0, { 0, 0, 0}}, // (145, 122) + { 0, { 0, 0, 0}}, // (146, 122) + { 0, { 0, 0, 0}}, // (147, 122) + { 0, { 0, 0, 0}}, // (148, 122) + { 0, { 0, 0, 0}}, // (149, 122) + { 0, { 0, 0, 0}}, // (150, 122) + { 0, { 0, 0, 0}}, // (151, 122) + { 0, { 0, 0, 0}}, // (152, 122) + { 0, { 0, 0, 0}}, // (153, 122) + { 0, { 0, 0, 0}}, // (154, 122) + { 0, { 0, 0, 0}}, // (155, 122) + { 0, { 0, 0, 0}}, // (156, 122) + { 0, { 0, 0, 0}}, // (157, 122) + { 0, { 0, 0, 0}}, // (158, 122) + { 0, { 0, 0, 0}}, // (159, 122) + { 0, { 0, 0, 0}}, // (160, 122) + { 0, { 0, 0, 0}}, // (161, 122) + { 0, { 0, 0, 0}}, // (162, 122) + { 0, { 0, 0, 0}}, // (163, 122) + { 0, { 0, 0, 0}}, // (164, 122) + { 0, { 0, 0, 0}}, // (165, 122) + { 0, { 0, 0, 0}}, // (166, 122) + { 0, { 0, 0, 0}}, // (167, 122) + { 0, { 0, 0, 0}}, // (168, 122) + { 0, { 0, 0, 0}}, // (169, 122) + { 0, { 0, 0, 0}}, // (170, 122) + { 29, { 0, 0, 0}}, // (171, 122) + {128, { 0, 0, 0}}, // (172, 122) + {128, { 0, 0, 0}}, // (173, 122) + {128, { 0, 0, 0}}, // (174, 122) + {128, { 0, 0, 0}}, // (175, 122) + {128, { 0, 0, 0}}, // (176, 122) + {128, { 0, 0, 0}}, // (177, 122) + {128, { 0, 0, 0}}, // (178, 122) + {128, { 0, 0, 0}}, // (179, 122) + {128, { 0, 0, 0}}, // ( 0, 123) + {128, { 0, 0, 0}}, // ( 1, 123) + {128, { 0, 0, 0}}, // ( 2, 123) + {128, { 0, 0, 0}}, // ( 3, 123) + {128, { 0, 0, 0}}, // ( 4, 123) + {128, { 0, 0, 0}}, // ( 5, 123) + {128, { 0, 0, 0}}, // ( 6, 123) + {128, { 0, 0, 0}}, // ( 7, 123) + { 79, { 0, 0, 0}}, // ( 8, 123) + { 0, { 0, 0, 0}}, // ( 9, 123) + { 0, { 0, 0, 0}}, // ( 10, 123) + { 0, { 0, 0, 0}}, // ( 11, 123) + { 0, { 0, 0, 0}}, // ( 12, 123) + { 0, { 0, 0, 0}}, // ( 13, 123) + { 0, { 0, 0, 0}}, // ( 14, 123) + { 0, { 0, 0, 0}}, // ( 15, 123) + { 0, { 0, 0, 0}}, // ( 16, 123) + { 0, { 0, 0, 0}}, // ( 17, 123) + { 0, { 0, 0, 0}}, // ( 18, 123) + { 0, { 0, 0, 0}}, // ( 19, 123) + { 0, { 0, 0, 0}}, // ( 20, 123) + { 0, { 0, 0, 0}}, // ( 21, 123) + { 0, { 0, 0, 0}}, // ( 22, 123) + { 0, { 0, 0, 0}}, // ( 23, 123) + { 0, { 0, 0, 0}}, // ( 24, 123) + { 0, { 0, 0, 0}}, // ( 25, 123) + { 0, { 0, 0, 0}}, // ( 26, 123) + { 0, { 0, 0, 0}}, // ( 27, 123) + { 0, { 0, 0, 0}}, // ( 28, 123) + { 0, { 0, 0, 0}}, // ( 29, 123) + { 0, { 0, 0, 0}}, // ( 30, 123) + { 0, { 0, 0, 0}}, // ( 31, 123) + { 0, { 0, 0, 0}}, // ( 32, 123) + { 0, { 0, 0, 0}}, // ( 33, 123) + { 0, { 0, 0, 0}}, // ( 34, 123) + { 0, { 0, 0, 0}}, // ( 35, 123) + { 0, { 0, 0, 0}}, // ( 36, 123) + { 0, { 0, 0, 0}}, // ( 37, 123) + { 0, { 0, 0, 0}}, // ( 38, 123) + { 0, { 0, 0, 0}}, // ( 39, 123) + { 0, { 0, 0, 0}}, // ( 40, 123) + { 0, { 0, 0, 0}}, // ( 41, 123) + { 0, { 0, 0, 0}}, // ( 42, 123) + { 0, { 0, 0, 0}}, // ( 43, 123) + { 0, { 0, 0, 0}}, // ( 44, 123) + { 0, { 0, 0, 0}}, // ( 45, 123) + { 0, { 0, 0, 0}}, // ( 46, 123) + { 0, { 0, 0, 0}}, // ( 47, 123) + { 0, { 0, 0, 0}}, // ( 48, 123) + { 0, { 0, 0, 0}}, // ( 49, 123) + { 0, { 0, 0, 0}}, // ( 50, 123) + { 0, { 0, 0, 0}}, // ( 51, 123) + { 0, { 0, 0, 0}}, // ( 52, 123) + { 0, { 0, 0, 0}}, // ( 53, 123) + { 0, { 0, 0, 0}}, // ( 54, 123) + { 0, { 0, 0, 0}}, // ( 55, 123) + { 0, { 0, 0, 0}}, // ( 56, 123) + { 0, { 0, 0, 0}}, // ( 57, 123) + { 0, { 0, 0, 0}}, // ( 58, 123) + { 0, { 0, 0, 0}}, // ( 59, 123) + { 0, { 0, 0, 0}}, // ( 60, 123) + { 0, { 0, 0, 0}}, // ( 61, 123) + { 0, { 0, 0, 0}}, // ( 62, 123) + { 0, { 0, 0, 0}}, // ( 63, 123) + { 0, { 0, 0, 0}}, // ( 64, 123) + { 0, { 0, 0, 0}}, // ( 65, 123) + { 0, { 0, 0, 0}}, // ( 66, 123) + { 0, { 0, 0, 0}}, // ( 67, 123) + { 0, { 0, 0, 0}}, // ( 68, 123) + { 0, { 0, 0, 0}}, // ( 69, 123) + { 0, { 0, 0, 0}}, // ( 70, 123) + { 0, { 0, 0, 0}}, // ( 71, 123) + { 0, { 0, 0, 0}}, // ( 72, 123) + { 0, { 0, 0, 0}}, // ( 73, 123) + { 0, { 0, 0, 0}}, // ( 74, 123) + { 0, { 0, 0, 0}}, // ( 75, 123) + { 0, { 0, 0, 0}}, // ( 76, 123) + { 0, { 0, 0, 0}}, // ( 77, 123) + { 0, { 0, 0, 0}}, // ( 78, 123) + { 0, { 0, 0, 0}}, // ( 79, 123) + { 0, { 0, 0, 0}}, // ( 80, 123) + { 0, { 0, 0, 0}}, // ( 81, 123) + { 0, { 0, 0, 0}}, // ( 82, 123) + { 0, { 0, 0, 0}}, // ( 83, 123) + { 0, { 0, 0, 0}}, // ( 84, 123) + { 0, { 0, 0, 0}}, // ( 85, 123) + { 0, { 0, 0, 0}}, // ( 86, 123) + { 0, { 0, 0, 0}}, // ( 87, 123) + { 0, { 0, 0, 0}}, // ( 88, 123) + { 0, { 0, 0, 0}}, // ( 89, 123) + { 0, { 0, 0, 0}}, // ( 90, 123) + { 0, { 0, 0, 0}}, // ( 91, 123) + { 0, { 0, 0, 0}}, // ( 92, 123) + { 0, { 0, 0, 0}}, // ( 93, 123) + { 0, { 0, 0, 0}}, // ( 94, 123) + { 0, { 0, 0, 0}}, // ( 95, 123) + { 0, { 0, 0, 0}}, // ( 96, 123) + { 0, { 0, 0, 0}}, // ( 97, 123) + { 0, { 0, 0, 0}}, // ( 98, 123) + { 0, { 0, 0, 0}}, // ( 99, 123) + { 0, { 0, 0, 0}}, // (100, 123) + { 0, { 0, 0, 0}}, // (101, 123) + { 0, { 0, 0, 0}}, // (102, 123) + { 0, { 0, 0, 0}}, // (103, 123) + { 0, { 0, 0, 0}}, // (104, 123) + { 0, { 0, 0, 0}}, // (105, 123) + { 0, { 0, 0, 0}}, // (106, 123) + { 0, { 0, 0, 0}}, // (107, 123) + { 0, { 0, 0, 0}}, // (108, 123) + { 0, { 0, 0, 0}}, // (109, 123) + { 0, { 0, 0, 0}}, // (110, 123) + { 0, { 0, 0, 0}}, // (111, 123) + { 0, { 0, 0, 0}}, // (112, 123) + { 0, { 0, 0, 0}}, // (113, 123) + { 0, { 0, 0, 0}}, // (114, 123) + { 0, { 0, 0, 0}}, // (115, 123) + { 0, { 0, 0, 0}}, // (116, 123) + { 0, { 0, 0, 0}}, // (117, 123) + { 0, { 0, 0, 0}}, // (118, 123) + { 0, { 0, 0, 0}}, // (119, 123) + { 0, { 0, 0, 0}}, // (120, 123) + { 0, { 0, 0, 0}}, // (121, 123) + { 0, { 0, 0, 0}}, // (122, 123) + { 0, { 0, 0, 0}}, // (123, 123) + { 0, { 0, 0, 0}}, // (124, 123) + { 0, { 0, 0, 0}}, // (125, 123) + { 0, { 0, 0, 0}}, // (126, 123) + { 0, { 0, 0, 0}}, // (127, 123) + { 0, { 0, 0, 0}}, // (128, 123) + { 0, { 0, 0, 0}}, // (129, 123) + { 0, { 0, 0, 0}}, // (130, 123) + { 0, { 0, 0, 0}}, // (131, 123) + { 0, { 0, 0, 0}}, // (132, 123) + { 0, { 0, 0, 0}}, // (133, 123) + { 0, { 0, 0, 0}}, // (134, 123) + { 0, { 0, 0, 0}}, // (135, 123) + { 0, { 0, 0, 0}}, // (136, 123) + { 0, { 0, 0, 0}}, // (137, 123) + { 0, { 0, 0, 0}}, // (138, 123) + { 0, { 0, 0, 0}}, // (139, 123) + { 0, { 0, 0, 0}}, // (140, 123) + { 0, { 0, 0, 0}}, // (141, 123) + { 0, { 0, 0, 0}}, // (142, 123) + { 0, { 0, 0, 0}}, // (143, 123) + { 0, { 0, 0, 0}}, // (144, 123) + { 0, { 0, 0, 0}}, // (145, 123) + { 0, { 0, 0, 0}}, // (146, 123) + { 0, { 0, 0, 0}}, // (147, 123) + { 0, { 0, 0, 0}}, // (148, 123) + { 0, { 0, 0, 0}}, // (149, 123) + { 0, { 0, 0, 0}}, // (150, 123) + { 0, { 0, 0, 0}}, // (151, 123) + { 0, { 0, 0, 0}}, // (152, 123) + { 0, { 0, 0, 0}}, // (153, 123) + { 0, { 0, 0, 0}}, // (154, 123) + { 0, { 0, 0, 0}}, // (155, 123) + { 0, { 0, 0, 0}}, // (156, 123) + { 0, { 0, 0, 0}}, // (157, 123) + { 0, { 0, 0, 0}}, // (158, 123) + { 0, { 0, 0, 0}}, // (159, 123) + { 0, { 0, 0, 0}}, // (160, 123) + { 0, { 0, 0, 0}}, // (161, 123) + { 0, { 0, 0, 0}}, // (162, 123) + { 0, { 0, 0, 0}}, // (163, 123) + { 0, { 0, 0, 0}}, // (164, 123) + { 0, { 0, 0, 0}}, // (165, 123) + { 0, { 0, 0, 0}}, // (166, 123) + { 0, { 0, 0, 0}}, // (167, 123) + { 0, { 0, 0, 0}}, // (168, 123) + { 0, { 0, 0, 0}}, // (169, 123) + { 0, { 0, 0, 0}}, // (170, 123) + { 79, { 0, 0, 0}}, // (171, 123) + {128, { 0, 0, 0}}, // (172, 123) + {128, { 0, 0, 0}}, // (173, 123) + {128, { 0, 0, 0}}, // (174, 123) + {128, { 0, 0, 0}}, // (175, 123) + {128, { 0, 0, 0}}, // (176, 123) + {128, { 0, 0, 0}}, // (177, 123) + {128, { 0, 0, 0}}, // (178, 123) + {128, { 0, 0, 0}}, // (179, 123) + {128, { 0, 0, 0}}, // ( 0, 124) + {128, { 0, 0, 0}}, // ( 1, 124) + {128, { 0, 0, 0}}, // ( 2, 124) + {128, { 0, 0, 0}}, // ( 3, 124) + {128, { 0, 0, 0}}, // ( 4, 124) + {128, { 0, 0, 0}}, // ( 5, 124) + {128, { 0, 0, 0}}, // ( 6, 124) + {128, { 0, 0, 0}}, // ( 7, 124) + {122, { 0, 0, 0}}, // ( 8, 124) + { 9, { 0, 0, 0}}, // ( 9, 124) + { 0, { 0, 0, 0}}, // ( 10, 124) + { 0, { 0, 0, 0}}, // ( 11, 124) + { 0, { 0, 0, 0}}, // ( 12, 124) + { 0, { 0, 0, 0}}, // ( 13, 124) + { 0, { 0, 0, 0}}, // ( 14, 124) + { 0, { 0, 0, 0}}, // ( 15, 124) + { 0, { 0, 0, 0}}, // ( 16, 124) + { 0, { 0, 0, 0}}, // ( 17, 124) + { 0, { 0, 0, 0}}, // ( 18, 124) + { 0, { 0, 0, 0}}, // ( 19, 124) + { 0, { 0, 0, 0}}, // ( 20, 124) + { 0, { 0, 0, 0}}, // ( 21, 124) + { 0, { 0, 0, 0}}, // ( 22, 124) + { 0, { 0, 0, 0}}, // ( 23, 124) + { 0, { 0, 0, 0}}, // ( 24, 124) + { 0, { 0, 0, 0}}, // ( 25, 124) + { 0, { 0, 0, 0}}, // ( 26, 124) + { 0, { 0, 0, 0}}, // ( 27, 124) + { 0, { 0, 0, 0}}, // ( 28, 124) + { 0, { 0, 0, 0}}, // ( 29, 124) + { 0, { 0, 0, 0}}, // ( 30, 124) + { 0, { 0, 0, 0}}, // ( 31, 124) + { 0, { 0, 0, 0}}, // ( 32, 124) + { 0, { 0, 0, 0}}, // ( 33, 124) + { 0, { 0, 0, 0}}, // ( 34, 124) + { 0, { 0, 0, 0}}, // ( 35, 124) + { 0, { 0, 0, 0}}, // ( 36, 124) + { 0, { 0, 0, 0}}, // ( 37, 124) + { 0, { 0, 0, 0}}, // ( 38, 124) + { 0, { 0, 0, 0}}, // ( 39, 124) + { 0, { 0, 0, 0}}, // ( 40, 124) + { 0, { 0, 0, 0}}, // ( 41, 124) + { 0, { 0, 0, 0}}, // ( 42, 124) + { 0, { 0, 0, 0}}, // ( 43, 124) + { 0, { 0, 0, 0}}, // ( 44, 124) + { 0, { 0, 0, 0}}, // ( 45, 124) + { 0, { 0, 0, 0}}, // ( 46, 124) + { 0, { 0, 0, 0}}, // ( 47, 124) + { 0, { 0, 0, 0}}, // ( 48, 124) + { 0, { 0, 0, 0}}, // ( 49, 124) + { 0, { 0, 0, 0}}, // ( 50, 124) + { 0, { 0, 0, 0}}, // ( 51, 124) + { 0, { 0, 0, 0}}, // ( 52, 124) + { 0, { 0, 0, 0}}, // ( 53, 124) + { 0, { 0, 0, 0}}, // ( 54, 124) + { 0, { 0, 0, 0}}, // ( 55, 124) + { 0, { 0, 0, 0}}, // ( 56, 124) + { 0, { 0, 0, 0}}, // ( 57, 124) + { 0, { 0, 0, 0}}, // ( 58, 124) + { 0, { 0, 0, 0}}, // ( 59, 124) + { 0, { 0, 0, 0}}, // ( 60, 124) + { 0, { 0, 0, 0}}, // ( 61, 124) + { 0, { 0, 0, 0}}, // ( 62, 124) + { 0, { 0, 0, 0}}, // ( 63, 124) + { 0, { 0, 0, 0}}, // ( 64, 124) + { 0, { 0, 0, 0}}, // ( 65, 124) + { 0, { 0, 0, 0}}, // ( 66, 124) + { 0, { 0, 0, 0}}, // ( 67, 124) + { 0, { 0, 0, 0}}, // ( 68, 124) + { 0, { 0, 0, 0}}, // ( 69, 124) + { 0, { 0, 0, 0}}, // ( 70, 124) + { 0, { 0, 0, 0}}, // ( 71, 124) + { 0, { 0, 0, 0}}, // ( 72, 124) + { 0, { 0, 0, 0}}, // ( 73, 124) + { 0, { 0, 0, 0}}, // ( 74, 124) + { 0, { 0, 0, 0}}, // ( 75, 124) + { 0, { 0, 0, 0}}, // ( 76, 124) + { 0, { 0, 0, 0}}, // ( 77, 124) + { 0, { 0, 0, 0}}, // ( 78, 124) + { 0, { 0, 0, 0}}, // ( 79, 124) + { 0, { 0, 0, 0}}, // ( 80, 124) + { 0, { 0, 0, 0}}, // ( 81, 124) + { 0, { 0, 0, 0}}, // ( 82, 124) + { 0, { 0, 0, 0}}, // ( 83, 124) + { 0, { 0, 0, 0}}, // ( 84, 124) + { 0, { 0, 0, 0}}, // ( 85, 124) + { 0, { 0, 0, 0}}, // ( 86, 124) + { 0, { 0, 0, 0}}, // ( 87, 124) + { 0, { 0, 0, 0}}, // ( 88, 124) + { 0, { 0, 0, 0}}, // ( 89, 124) + { 0, { 0, 0, 0}}, // ( 90, 124) + { 0, { 0, 0, 0}}, // ( 91, 124) + { 0, { 0, 0, 0}}, // ( 92, 124) + { 0, { 0, 0, 0}}, // ( 93, 124) + { 0, { 0, 0, 0}}, // ( 94, 124) + { 0, { 0, 0, 0}}, // ( 95, 124) + { 0, { 0, 0, 0}}, // ( 96, 124) + { 0, { 0, 0, 0}}, // ( 97, 124) + { 0, { 0, 0, 0}}, // ( 98, 124) + { 0, { 0, 0, 0}}, // ( 99, 124) + { 0, { 0, 0, 0}}, // (100, 124) + { 0, { 0, 0, 0}}, // (101, 124) + { 0, { 0, 0, 0}}, // (102, 124) + { 0, { 0, 0, 0}}, // (103, 124) + { 0, { 0, 0, 0}}, // (104, 124) + { 0, { 0, 0, 0}}, // (105, 124) + { 0, { 0, 0, 0}}, // (106, 124) + { 0, { 0, 0, 0}}, // (107, 124) + { 0, { 0, 0, 0}}, // (108, 124) + { 0, { 0, 0, 0}}, // (109, 124) + { 0, { 0, 0, 0}}, // (110, 124) + { 0, { 0, 0, 0}}, // (111, 124) + { 0, { 0, 0, 0}}, // (112, 124) + { 0, { 0, 0, 0}}, // (113, 124) + { 0, { 0, 0, 0}}, // (114, 124) + { 0, { 0, 0, 0}}, // (115, 124) + { 0, { 0, 0, 0}}, // (116, 124) + { 0, { 0, 0, 0}}, // (117, 124) + { 0, { 0, 0, 0}}, // (118, 124) + { 0, { 0, 0, 0}}, // (119, 124) + { 0, { 0, 0, 0}}, // (120, 124) + { 0, { 0, 0, 0}}, // (121, 124) + { 0, { 0, 0, 0}}, // (122, 124) + { 0, { 0, 0, 0}}, // (123, 124) + { 0, { 0, 0, 0}}, // (124, 124) + { 0, { 0, 0, 0}}, // (125, 124) + { 0, { 0, 0, 0}}, // (126, 124) + { 0, { 0, 0, 0}}, // (127, 124) + { 0, { 0, 0, 0}}, // (128, 124) + { 0, { 0, 0, 0}}, // (129, 124) + { 0, { 0, 0, 0}}, // (130, 124) + { 0, { 0, 0, 0}}, // (131, 124) + { 0, { 0, 0, 0}}, // (132, 124) + { 0, { 0, 0, 0}}, // (133, 124) + { 0, { 0, 0, 0}}, // (134, 124) + { 0, { 0, 0, 0}}, // (135, 124) + { 0, { 0, 0, 0}}, // (136, 124) + { 0, { 0, 0, 0}}, // (137, 124) + { 0, { 0, 0, 0}}, // (138, 124) + { 0, { 0, 0, 0}}, // (139, 124) + { 0, { 0, 0, 0}}, // (140, 124) + { 0, { 0, 0, 0}}, // (141, 124) + { 0, { 0, 0, 0}}, // (142, 124) + { 0, { 0, 0, 0}}, // (143, 124) + { 0, { 0, 0, 0}}, // (144, 124) + { 0, { 0, 0, 0}}, // (145, 124) + { 0, { 0, 0, 0}}, // (146, 124) + { 0, { 0, 0, 0}}, // (147, 124) + { 0, { 0, 0, 0}}, // (148, 124) + { 0, { 0, 0, 0}}, // (149, 124) + { 0, { 0, 0, 0}}, // (150, 124) + { 0, { 0, 0, 0}}, // (151, 124) + { 0, { 0, 0, 0}}, // (152, 124) + { 0, { 0, 0, 0}}, // (153, 124) + { 0, { 0, 0, 0}}, // (154, 124) + { 0, { 0, 0, 0}}, // (155, 124) + { 0, { 0, 0, 0}}, // (156, 124) + { 0, { 0, 0, 0}}, // (157, 124) + { 0, { 0, 0, 0}}, // (158, 124) + { 0, { 0, 0, 0}}, // (159, 124) + { 0, { 0, 0, 0}}, // (160, 124) + { 0, { 0, 0, 0}}, // (161, 124) + { 0, { 0, 0, 0}}, // (162, 124) + { 0, { 0, 0, 0}}, // (163, 124) + { 0, { 0, 0, 0}}, // (164, 124) + { 0, { 0, 0, 0}}, // (165, 124) + { 0, { 0, 0, 0}}, // (166, 124) + { 0, { 0, 0, 0}}, // (167, 124) + { 0, { 0, 0, 0}}, // (168, 124) + { 0, { 0, 0, 0}}, // (169, 124) + { 8, { 0, 0, 0}}, // (170, 124) + {122, { 0, 0, 0}}, // (171, 124) + {128, { 0, 0, 0}}, // (172, 124) + {128, { 0, 0, 0}}, // (173, 124) + {128, { 0, 0, 0}}, // (174, 124) + {128, { 0, 0, 0}}, // (175, 124) + {128, { 0, 0, 0}}, // (176, 124) + {128, { 0, 0, 0}}, // (177, 124) + {128, { 0, 0, 0}}, // (178, 124) + {128, { 0, 0, 0}}, // (179, 124) + {128, { 0, 0, 0}}, // ( 0, 125) + {128, { 0, 0, 0}}, // ( 1, 125) + {128, { 0, 0, 0}}, // ( 2, 125) + {128, { 0, 0, 0}}, // ( 3, 125) + {128, { 0, 0, 0}}, // ( 4, 125) + {128, { 0, 0, 0}}, // ( 5, 125) + {128, { 0, 0, 0}}, // ( 6, 125) + {128, { 0, 0, 0}}, // ( 7, 125) + {128, { 0, 0, 0}}, // ( 8, 125) + { 62, { 0, 0, 0}}, // ( 9, 125) + { 0, { 0, 0, 0}}, // ( 10, 125) + { 0, { 0, 0, 0}}, // ( 11, 125) + { 0, { 0, 0, 0}}, // ( 12, 125) + { 0, { 0, 0, 0}}, // ( 13, 125) + { 0, { 0, 0, 0}}, // ( 14, 125) + { 0, { 0, 0, 0}}, // ( 15, 125) + { 0, { 0, 0, 0}}, // ( 16, 125) + { 0, { 0, 0, 0}}, // ( 17, 125) + { 0, { 0, 0, 0}}, // ( 18, 125) + { 0, { 0, 0, 0}}, // ( 19, 125) + { 0, { 0, 0, 0}}, // ( 20, 125) + { 0, { 0, 0, 0}}, // ( 21, 125) + { 0, { 0, 0, 0}}, // ( 22, 125) + { 0, { 0, 0, 0}}, // ( 23, 125) + { 0, { 0, 0, 0}}, // ( 24, 125) + { 0, { 0, 0, 0}}, // ( 25, 125) + { 0, { 0, 0, 0}}, // ( 26, 125) + { 0, { 0, 0, 0}}, // ( 27, 125) + { 0, { 0, 0, 0}}, // ( 28, 125) + { 0, { 0, 0, 0}}, // ( 29, 125) + { 0, { 0, 0, 0}}, // ( 30, 125) + { 0, { 0, 0, 0}}, // ( 31, 125) + { 0, { 0, 0, 0}}, // ( 32, 125) + { 0, { 0, 0, 0}}, // ( 33, 125) + { 0, { 0, 0, 0}}, // ( 34, 125) + { 0, { 0, 0, 0}}, // ( 35, 125) + { 0, { 0, 0, 0}}, // ( 36, 125) + { 0, { 0, 0, 0}}, // ( 37, 125) + { 0, { 0, 0, 0}}, // ( 38, 125) + { 0, { 0, 0, 0}}, // ( 39, 125) + { 0, { 0, 0, 0}}, // ( 40, 125) + { 0, { 0, 0, 0}}, // ( 41, 125) + { 0, { 0, 0, 0}}, // ( 42, 125) + { 0, { 0, 0, 0}}, // ( 43, 125) + { 0, { 0, 0, 0}}, // ( 44, 125) + { 0, { 0, 0, 0}}, // ( 45, 125) + { 0, { 0, 0, 0}}, // ( 46, 125) + { 0, { 0, 0, 0}}, // ( 47, 125) + { 0, { 0, 0, 0}}, // ( 48, 125) + { 0, { 0, 0, 0}}, // ( 49, 125) + { 0, { 0, 0, 0}}, // ( 50, 125) + { 0, { 0, 0, 0}}, // ( 51, 125) + { 0, { 0, 0, 0}}, // ( 52, 125) + { 0, { 0, 0, 0}}, // ( 53, 125) + { 0, { 0, 0, 0}}, // ( 54, 125) + { 0, { 0, 0, 0}}, // ( 55, 125) + { 0, { 0, 0, 0}}, // ( 56, 125) + { 0, { 0, 0, 0}}, // ( 57, 125) + { 0, { 0, 0, 0}}, // ( 58, 125) + { 0, { 0, 0, 0}}, // ( 59, 125) + { 0, { 0, 0, 0}}, // ( 60, 125) + { 0, { 0, 0, 0}}, // ( 61, 125) + { 0, { 0, 0, 0}}, // ( 62, 125) + { 0, { 0, 0, 0}}, // ( 63, 125) + { 0, { 0, 0, 0}}, // ( 64, 125) + { 0, { 0, 0, 0}}, // ( 65, 125) + { 0, { 0, 0, 0}}, // ( 66, 125) + { 0, { 0, 0, 0}}, // ( 67, 125) + { 0, { 0, 0, 0}}, // ( 68, 125) + { 0, { 0, 0, 0}}, // ( 69, 125) + { 0, { 0, 0, 0}}, // ( 70, 125) + { 0, { 0, 0, 0}}, // ( 71, 125) + { 0, { 0, 0, 0}}, // ( 72, 125) + { 0, { 0, 0, 0}}, // ( 73, 125) + { 0, { 0, 0, 0}}, // ( 74, 125) + { 0, { 0, 0, 0}}, // ( 75, 125) + { 0, { 0, 0, 0}}, // ( 76, 125) + { 0, { 0, 0, 0}}, // ( 77, 125) + { 0, { 0, 0, 0}}, // ( 78, 125) + { 0, { 0, 0, 0}}, // ( 79, 125) + { 0, { 0, 0, 0}}, // ( 80, 125) + { 0, { 0, 0, 0}}, // ( 81, 125) + { 0, { 0, 0, 0}}, // ( 82, 125) + { 0, { 0, 0, 0}}, // ( 83, 125) + { 0, { 0, 0, 0}}, // ( 84, 125) + { 0, { 0, 0, 0}}, // ( 85, 125) + { 0, { 0, 0, 0}}, // ( 86, 125) + { 0, { 0, 0, 0}}, // ( 87, 125) + { 0, { 0, 0, 0}}, // ( 88, 125) + { 0, { 0, 0, 0}}, // ( 89, 125) + { 0, { 0, 0, 0}}, // ( 90, 125) + { 0, { 0, 0, 0}}, // ( 91, 125) + { 0, { 0, 0, 0}}, // ( 92, 125) + { 0, { 0, 0, 0}}, // ( 93, 125) + { 0, { 0, 0, 0}}, // ( 94, 125) + { 0, { 0, 0, 0}}, // ( 95, 125) + { 0, { 0, 0, 0}}, // ( 96, 125) + { 0, { 0, 0, 0}}, // ( 97, 125) + { 0, { 0, 0, 0}}, // ( 98, 125) + { 0, { 0, 0, 0}}, // ( 99, 125) + { 0, { 0, 0, 0}}, // (100, 125) + { 0, { 0, 0, 0}}, // (101, 125) + { 0, { 0, 0, 0}}, // (102, 125) + { 0, { 0, 0, 0}}, // (103, 125) + { 0, { 0, 0, 0}}, // (104, 125) + { 0, { 0, 0, 0}}, // (105, 125) + { 0, { 0, 0, 0}}, // (106, 125) + { 0, { 0, 0, 0}}, // (107, 125) + { 0, { 0, 0, 0}}, // (108, 125) + { 0, { 0, 0, 0}}, // (109, 125) + { 0, { 0, 0, 0}}, // (110, 125) + { 0, { 0, 0, 0}}, // (111, 125) + { 0, { 0, 0, 0}}, // (112, 125) + { 0, { 0, 0, 0}}, // (113, 125) + { 0, { 0, 0, 0}}, // (114, 125) + { 0, { 0, 0, 0}}, // (115, 125) + { 0, { 0, 0, 0}}, // (116, 125) + { 0, { 0, 0, 0}}, // (117, 125) + { 0, { 0, 0, 0}}, // (118, 125) + { 0, { 0, 0, 0}}, // (119, 125) + { 0, { 0, 0, 0}}, // (120, 125) + { 0, { 0, 0, 0}}, // (121, 125) + { 0, { 0, 0, 0}}, // (122, 125) + { 0, { 0, 0, 0}}, // (123, 125) + { 0, { 0, 0, 0}}, // (124, 125) + { 0, { 0, 0, 0}}, // (125, 125) + { 0, { 0, 0, 0}}, // (126, 125) + { 0, { 0, 0, 0}}, // (127, 125) + { 0, { 0, 0, 0}}, // (128, 125) + { 0, { 0, 0, 0}}, // (129, 125) + { 0, { 0, 0, 0}}, // (130, 125) + { 0, { 0, 0, 0}}, // (131, 125) + { 0, { 0, 0, 0}}, // (132, 125) + { 0, { 0, 0, 0}}, // (133, 125) + { 0, { 0, 0, 0}}, // (134, 125) + { 0, { 0, 0, 0}}, // (135, 125) + { 0, { 0, 0, 0}}, // (136, 125) + { 0, { 0, 0, 0}}, // (137, 125) + { 0, { 0, 0, 0}}, // (138, 125) + { 0, { 0, 0, 0}}, // (139, 125) + { 0, { 0, 0, 0}}, // (140, 125) + { 0, { 0, 0, 0}}, // (141, 125) + { 0, { 0, 0, 0}}, // (142, 125) + { 0, { 0, 0, 0}}, // (143, 125) + { 0, { 0, 0, 0}}, // (144, 125) + { 0, { 0, 0, 0}}, // (145, 125) + { 0, { 0, 0, 0}}, // (146, 125) + { 0, { 0, 0, 0}}, // (147, 125) + { 0, { 0, 0, 0}}, // (148, 125) + { 0, { 0, 0, 0}}, // (149, 125) + { 0, { 0, 0, 0}}, // (150, 125) + { 0, { 0, 0, 0}}, // (151, 125) + { 0, { 0, 0, 0}}, // (152, 125) + { 0, { 0, 0, 0}}, // (153, 125) + { 0, { 0, 0, 0}}, // (154, 125) + { 0, { 0, 0, 0}}, // (155, 125) + { 0, { 0, 0, 0}}, // (156, 125) + { 0, { 0, 0, 0}}, // (157, 125) + { 0, { 0, 0, 0}}, // (158, 125) + { 0, { 0, 0, 0}}, // (159, 125) + { 0, { 0, 0, 0}}, // (160, 125) + { 0, { 0, 0, 0}}, // (161, 125) + { 0, { 0, 0, 0}}, // (162, 125) + { 0, { 0, 0, 0}}, // (163, 125) + { 0, { 0, 0, 0}}, // (164, 125) + { 0, { 0, 0, 0}}, // (165, 125) + { 0, { 0, 0, 0}}, // (166, 125) + { 0, { 0, 0, 0}}, // (167, 125) + { 0, { 0, 0, 0}}, // (168, 125) + { 0, { 0, 0, 0}}, // (169, 125) + { 58, { 0, 0, 0}}, // (170, 125) + {128, { 0, 0, 0}}, // (171, 125) + {128, { 0, 0, 0}}, // (172, 125) + {128, { 0, 0, 0}}, // (173, 125) + {128, { 0, 0, 0}}, // (174, 125) + {128, { 0, 0, 0}}, // (175, 125) + {128, { 0, 0, 0}}, // (176, 125) + {128, { 0, 0, 0}}, // (177, 125) + {128, { 0, 0, 0}}, // (178, 125) + {128, { 0, 0, 0}}, // (179, 125) + {128, { 0, 0, 0}}, // ( 0, 126) + {128, { 0, 0, 0}}, // ( 1, 126) + {128, { 0, 0, 0}}, // ( 2, 126) + {128, { 0, 0, 0}}, // ( 3, 126) + {128, { 0, 0, 0}}, // ( 4, 126) + {128, { 0, 0, 0}}, // ( 5, 126) + {128, { 0, 0, 0}}, // ( 6, 126) + {128, { 0, 0, 0}}, // ( 7, 126) + {128, { 0, 0, 0}}, // ( 8, 126) + {115, { 0, 0, 0}}, // ( 9, 126) + { 3, { 0, 0, 0}}, // ( 10, 126) + { 0, { 0, 0, 0}}, // ( 11, 126) + { 0, { 0, 0, 0}}, // ( 12, 126) + { 0, { 0, 0, 0}}, // ( 13, 126) + { 0, { 0, 0, 0}}, // ( 14, 126) + { 0, { 0, 0, 0}}, // ( 15, 126) + { 0, { 0, 0, 0}}, // ( 16, 126) + { 0, { 0, 0, 0}}, // ( 17, 126) + { 0, { 0, 0, 0}}, // ( 18, 126) + { 0, { 0, 0, 0}}, // ( 19, 126) + { 0, { 0, 0, 0}}, // ( 20, 126) + { 0, { 0, 0, 0}}, // ( 21, 126) + { 0, { 0, 0, 0}}, // ( 22, 126) + { 0, { 0, 0, 0}}, // ( 23, 126) + { 0, { 0, 0, 0}}, // ( 24, 126) + { 0, { 0, 0, 0}}, // ( 25, 126) + { 0, { 0, 0, 0}}, // ( 26, 126) + { 0, { 0, 0, 0}}, // ( 27, 126) + { 0, { 0, 0, 0}}, // ( 28, 126) + { 0, { 0, 0, 0}}, // ( 29, 126) + { 0, { 0, 0, 0}}, // ( 30, 126) + { 0, { 0, 0, 0}}, // ( 31, 126) + { 0, { 0, 0, 0}}, // ( 32, 126) + { 0, { 0, 0, 0}}, // ( 33, 126) + { 0, { 0, 0, 0}}, // ( 34, 126) + { 0, { 0, 0, 0}}, // ( 35, 126) + { 0, { 0, 0, 0}}, // ( 36, 126) + { 0, { 0, 0, 0}}, // ( 37, 126) + { 0, { 0, 0, 0}}, // ( 38, 126) + { 0, { 0, 0, 0}}, // ( 39, 126) + { 0, { 0, 0, 0}}, // ( 40, 126) + { 0, { 0, 0, 0}}, // ( 41, 126) + { 0, { 0, 0, 0}}, // ( 42, 126) + { 0, { 0, 0, 0}}, // ( 43, 126) + { 0, { 0, 0, 0}}, // ( 44, 126) + { 0, { 0, 0, 0}}, // ( 45, 126) + { 0, { 0, 0, 0}}, // ( 46, 126) + { 0, { 0, 0, 0}}, // ( 47, 126) + { 0, { 0, 0, 0}}, // ( 48, 126) + { 0, { 0, 0, 0}}, // ( 49, 126) + { 0, { 0, 0, 0}}, // ( 50, 126) + { 0, { 0, 0, 0}}, // ( 51, 126) + { 0, { 0, 0, 0}}, // ( 52, 126) + { 0, { 0, 0, 0}}, // ( 53, 126) + { 0, { 0, 0, 0}}, // ( 54, 126) + { 0, { 0, 0, 0}}, // ( 55, 126) + { 0, { 0, 0, 0}}, // ( 56, 126) + { 0, { 0, 0, 0}}, // ( 57, 126) + { 0, { 0, 0, 0}}, // ( 58, 126) + { 0, { 0, 0, 0}}, // ( 59, 126) + { 0, { 0, 0, 0}}, // ( 60, 126) + { 0, { 0, 0, 0}}, // ( 61, 126) + { 0, { 0, 0, 0}}, // ( 62, 126) + { 0, { 0, 0, 0}}, // ( 63, 126) + { 0, { 0, 0, 0}}, // ( 64, 126) + { 0, { 0, 0, 0}}, // ( 65, 126) + { 0, { 0, 0, 0}}, // ( 66, 126) + { 0, { 0, 0, 0}}, // ( 67, 126) + { 0, { 0, 0, 0}}, // ( 68, 126) + { 0, { 0, 0, 0}}, // ( 69, 126) + { 0, { 0, 0, 0}}, // ( 70, 126) + { 0, { 0, 0, 0}}, // ( 71, 126) + { 0, { 0, 0, 0}}, // ( 72, 126) + { 0, { 0, 0, 0}}, // ( 73, 126) + { 0, { 0, 0, 0}}, // ( 74, 126) + { 0, { 0, 0, 0}}, // ( 75, 126) + { 0, { 0, 0, 0}}, // ( 76, 126) + { 0, { 0, 0, 0}}, // ( 77, 126) + { 0, { 0, 0, 0}}, // ( 78, 126) + { 0, { 0, 0, 0}}, // ( 79, 126) + { 0, { 0, 0, 0}}, // ( 80, 126) + { 0, { 0, 0, 0}}, // ( 81, 126) + { 0, { 0, 0, 0}}, // ( 82, 126) + { 0, { 0, 0, 0}}, // ( 83, 126) + { 0, { 0, 0, 0}}, // ( 84, 126) + { 0, { 0, 0, 0}}, // ( 85, 126) + { 0, { 0, 0, 0}}, // ( 86, 126) + { 0, { 0, 0, 0}}, // ( 87, 126) + { 0, { 0, 0, 0}}, // ( 88, 126) + { 0, { 0, 0, 0}}, // ( 89, 126) + { 0, { 0, 0, 0}}, // ( 90, 126) + { 0, { 0, 0, 0}}, // ( 91, 126) + { 0, { 0, 0, 0}}, // ( 92, 126) + { 0, { 0, 0, 0}}, // ( 93, 126) + { 0, { 0, 0, 0}}, // ( 94, 126) + { 0, { 0, 0, 0}}, // ( 95, 126) + { 0, { 0, 0, 0}}, // ( 96, 126) + { 0, { 0, 0, 0}}, // ( 97, 126) + { 0, { 0, 0, 0}}, // ( 98, 126) + { 0, { 0, 0, 0}}, // ( 99, 126) + { 0, { 0, 0, 0}}, // (100, 126) + { 0, { 0, 0, 0}}, // (101, 126) + { 0, { 0, 0, 0}}, // (102, 126) + { 0, { 0, 0, 0}}, // (103, 126) + { 0, { 0, 0, 0}}, // (104, 126) + { 0, { 0, 0, 0}}, // (105, 126) + { 0, { 0, 0, 0}}, // (106, 126) + { 0, { 0, 0, 0}}, // (107, 126) + { 0, { 0, 0, 0}}, // (108, 126) + { 0, { 0, 0, 0}}, // (109, 126) + { 0, { 0, 0, 0}}, // (110, 126) + { 0, { 0, 0, 0}}, // (111, 126) + { 0, { 0, 0, 0}}, // (112, 126) + { 0, { 0, 0, 0}}, // (113, 126) + { 0, { 0, 0, 0}}, // (114, 126) + { 0, { 0, 0, 0}}, // (115, 126) + { 0, { 0, 0, 0}}, // (116, 126) + { 0, { 0, 0, 0}}, // (117, 126) + { 0, { 0, 0, 0}}, // (118, 126) + { 0, { 0, 0, 0}}, // (119, 126) + { 0, { 0, 0, 0}}, // (120, 126) + { 0, { 0, 0, 0}}, // (121, 126) + { 0, { 0, 0, 0}}, // (122, 126) + { 0, { 0, 0, 0}}, // (123, 126) + { 0, { 0, 0, 0}}, // (124, 126) + { 0, { 0, 0, 0}}, // (125, 126) + { 0, { 0, 0, 0}}, // (126, 126) + { 0, { 0, 0, 0}}, // (127, 126) + { 0, { 0, 0, 0}}, // (128, 126) + { 0, { 0, 0, 0}}, // (129, 126) + { 0, { 0, 0, 0}}, // (130, 126) + { 0, { 0, 0, 0}}, // (131, 126) + { 0, { 0, 0, 0}}, // (132, 126) + { 0, { 0, 0, 0}}, // (133, 126) + { 0, { 0, 0, 0}}, // (134, 126) + { 0, { 0, 0, 0}}, // (135, 126) + { 0, { 0, 0, 0}}, // (136, 126) + { 0, { 0, 0, 0}}, // (137, 126) + { 0, { 0, 0, 0}}, // (138, 126) + { 0, { 0, 0, 0}}, // (139, 126) + { 0, { 0, 0, 0}}, // (140, 126) + { 0, { 0, 0, 0}}, // (141, 126) + { 0, { 0, 0, 0}}, // (142, 126) + { 0, { 0, 0, 0}}, // (143, 126) + { 0, { 0, 0, 0}}, // (144, 126) + { 0, { 0, 0, 0}}, // (145, 126) + { 0, { 0, 0, 0}}, // (146, 126) + { 0, { 0, 0, 0}}, // (147, 126) + { 0, { 0, 0, 0}}, // (148, 126) + { 0, { 0, 0, 0}}, // (149, 126) + { 0, { 0, 0, 0}}, // (150, 126) + { 0, { 0, 0, 0}}, // (151, 126) + { 0, { 0, 0, 0}}, // (152, 126) + { 0, { 0, 0, 0}}, // (153, 126) + { 0, { 0, 0, 0}}, // (154, 126) + { 0, { 0, 0, 0}}, // (155, 126) + { 0, { 0, 0, 0}}, // (156, 126) + { 0, { 0, 0, 0}}, // (157, 126) + { 0, { 0, 0, 0}}, // (158, 126) + { 0, { 0, 0, 0}}, // (159, 126) + { 0, { 0, 0, 0}}, // (160, 126) + { 0, { 0, 0, 0}}, // (161, 126) + { 0, { 0, 0, 0}}, // (162, 126) + { 0, { 0, 0, 0}}, // (163, 126) + { 0, { 0, 0, 0}}, // (164, 126) + { 0, { 0, 0, 0}}, // (165, 126) + { 0, { 0, 0, 0}}, // (166, 126) + { 0, { 0, 0, 0}}, // (167, 126) + { 0, { 0, 0, 0}}, // (168, 126) + { 3, { 0, 0, 0}}, // (169, 126) + {113, { 0, 0, 0}}, // (170, 126) + {128, { 0, 0, 0}}, // (171, 126) + {128, { 0, 0, 0}}, // (172, 126) + {128, { 0, 0, 0}}, // (173, 126) + {128, { 0, 0, 0}}, // (174, 126) + {128, { 0, 0, 0}}, // (175, 126) + {128, { 0, 0, 0}}, // (176, 126) + {128, { 0, 0, 0}}, // (177, 126) + {128, { 0, 0, 0}}, // (178, 126) + {128, { 0, 0, 0}}, // (179, 126) + {128, { 0, 0, 0}}, // ( 0, 127) + {128, { 0, 0, 0}}, // ( 1, 127) + {128, { 0, 0, 0}}, // ( 2, 127) + {128, { 0, 0, 0}}, // ( 3, 127) + {128, { 0, 0, 0}}, // ( 4, 127) + {128, { 0, 0, 0}}, // ( 5, 127) + {128, { 0, 0, 0}}, // ( 6, 127) + {128, { 0, 0, 0}}, // ( 7, 127) + {128, { 0, 0, 0}}, // ( 8, 127) + {128, { 0, 0, 0}}, // ( 9, 127) + { 49, { 0, 0, 0}}, // ( 10, 127) + { 0, { 0, 0, 0}}, // ( 11, 127) + { 0, { 0, 0, 0}}, // ( 12, 127) + { 0, { 0, 0, 0}}, // ( 13, 127) + { 0, { 0, 0, 0}}, // ( 14, 127) + { 0, { 0, 0, 0}}, // ( 15, 127) + { 0, { 0, 0, 0}}, // ( 16, 127) + { 0, { 0, 0, 0}}, // ( 17, 127) + { 0, { 0, 0, 0}}, // ( 18, 127) + { 0, { 0, 0, 0}}, // ( 19, 127) + { 0, { 0, 0, 0}}, // ( 20, 127) + { 0, { 0, 0, 0}}, // ( 21, 127) + { 0, { 0, 0, 0}}, // ( 22, 127) + { 0, { 0, 0, 0}}, // ( 23, 127) + { 0, { 0, 0, 0}}, // ( 24, 127) + { 0, { 0, 0, 0}}, // ( 25, 127) + { 0, { 0, 0, 0}}, // ( 26, 127) + { 0, { 0, 0, 0}}, // ( 27, 127) + { 0, { 0, 0, 0}}, // ( 28, 127) + { 0, { 0, 0, 0}}, // ( 29, 127) + { 0, { 0, 0, 0}}, // ( 30, 127) + { 0, { 0, 0, 0}}, // ( 31, 127) + { 0, { 0, 0, 0}}, // ( 32, 127) + { 0, { 0, 0, 0}}, // ( 33, 127) + { 0, { 0, 0, 0}}, // ( 34, 127) + { 0, { 0, 0, 0}}, // ( 35, 127) + { 0, { 0, 0, 0}}, // ( 36, 127) + { 0, { 0, 0, 0}}, // ( 37, 127) + { 0, { 0, 0, 0}}, // ( 38, 127) + { 0, { 0, 0, 0}}, // ( 39, 127) + { 0, { 0, 0, 0}}, // ( 40, 127) + { 0, { 0, 0, 0}}, // ( 41, 127) + { 0, { 0, 0, 0}}, // ( 42, 127) + { 0, { 0, 0, 0}}, // ( 43, 127) + { 0, { 0, 0, 0}}, // ( 44, 127) + { 0, { 0, 0, 0}}, // ( 45, 127) + { 0, { 0, 0, 0}}, // ( 46, 127) + { 0, { 0, 0, 0}}, // ( 47, 127) + { 0, { 0, 0, 0}}, // ( 48, 127) + { 0, { 0, 0, 0}}, // ( 49, 127) + { 0, { 0, 0, 0}}, // ( 50, 127) + { 0, { 0, 0, 0}}, // ( 51, 127) + { 0, { 0, 0, 0}}, // ( 52, 127) + { 0, { 0, 0, 0}}, // ( 53, 127) + { 0, { 0, 0, 0}}, // ( 54, 127) + { 0, { 0, 0, 0}}, // ( 55, 127) + { 0, { 0, 0, 0}}, // ( 56, 127) + { 0, { 0, 0, 0}}, // ( 57, 127) + { 0, { 0, 0, 0}}, // ( 58, 127) + { 0, { 0, 0, 0}}, // ( 59, 127) + { 0, { 0, 0, 0}}, // ( 60, 127) + { 0, { 0, 0, 0}}, // ( 61, 127) + { 0, { 0, 0, 0}}, // ( 62, 127) + { 0, { 0, 0, 0}}, // ( 63, 127) + { 0, { 0, 0, 0}}, // ( 64, 127) + { 0, { 0, 0, 0}}, // ( 65, 127) + { 0, { 0, 0, 0}}, // ( 66, 127) + { 0, { 0, 0, 0}}, // ( 67, 127) + { 0, { 0, 0, 0}}, // ( 68, 127) + { 0, { 0, 0, 0}}, // ( 69, 127) + { 0, { 0, 0, 0}}, // ( 70, 127) + { 0, { 0, 0, 0}}, // ( 71, 127) + { 0, { 0, 0, 0}}, // ( 72, 127) + { 0, { 0, 0, 0}}, // ( 73, 127) + { 0, { 0, 0, 0}}, // ( 74, 127) + { 0, { 0, 0, 0}}, // ( 75, 127) + { 0, { 0, 0, 0}}, // ( 76, 127) + { 0, { 0, 0, 0}}, // ( 77, 127) + { 0, { 0, 0, 0}}, // ( 78, 127) + { 0, { 0, 0, 0}}, // ( 79, 127) + { 0, { 0, 0, 0}}, // ( 80, 127) + { 0, { 0, 0, 0}}, // ( 81, 127) + { 0, { 0, 0, 0}}, // ( 82, 127) + { 0, { 0, 0, 0}}, // ( 83, 127) + { 0, { 0, 0, 0}}, // ( 84, 127) + { 0, { 0, 0, 0}}, // ( 85, 127) + { 0, { 0, 0, 0}}, // ( 86, 127) + { 0, { 0, 0, 0}}, // ( 87, 127) + { 0, { 0, 0, 0}}, // ( 88, 127) + { 0, { 0, 0, 0}}, // ( 89, 127) + { 0, { 0, 0, 0}}, // ( 90, 127) + { 0, { 0, 0, 0}}, // ( 91, 127) + { 0, { 0, 0, 0}}, // ( 92, 127) + { 0, { 0, 0, 0}}, // ( 93, 127) + { 0, { 0, 0, 0}}, // ( 94, 127) + { 0, { 0, 0, 0}}, // ( 95, 127) + { 0, { 0, 0, 0}}, // ( 96, 127) + { 0, { 0, 0, 0}}, // ( 97, 127) + { 0, { 0, 0, 0}}, // ( 98, 127) + { 0, { 0, 0, 0}}, // ( 99, 127) + { 0, { 0, 0, 0}}, // (100, 127) + { 0, { 0, 0, 0}}, // (101, 127) + { 0, { 0, 0, 0}}, // (102, 127) + { 0, { 0, 0, 0}}, // (103, 127) + { 0, { 0, 0, 0}}, // (104, 127) + { 0, { 0, 0, 0}}, // (105, 127) + { 0, { 0, 0, 0}}, // (106, 127) + { 0, { 0, 0, 0}}, // (107, 127) + { 0, { 0, 0, 0}}, // (108, 127) + { 0, { 0, 0, 0}}, // (109, 127) + { 0, { 0, 0, 0}}, // (110, 127) + { 0, { 0, 0, 0}}, // (111, 127) + { 0, { 0, 0, 0}}, // (112, 127) + { 0, { 0, 0, 0}}, // (113, 127) + { 0, { 0, 0, 0}}, // (114, 127) + { 0, { 0, 0, 0}}, // (115, 127) + { 0, { 0, 0, 0}}, // (116, 127) + { 0, { 0, 0, 0}}, // (117, 127) + { 0, { 0, 0, 0}}, // (118, 127) + { 0, { 0, 0, 0}}, // (119, 127) + { 0, { 0, 0, 0}}, // (120, 127) + { 0, { 0, 0, 0}}, // (121, 127) + { 0, { 0, 0, 0}}, // (122, 127) + { 0, { 0, 0, 0}}, // (123, 127) + { 0, { 0, 0, 0}}, // (124, 127) + { 0, { 0, 0, 0}}, // (125, 127) + { 0, { 0, 0, 0}}, // (126, 127) + { 0, { 0, 0, 0}}, // (127, 127) + { 0, { 0, 0, 0}}, // (128, 127) + { 0, { 0, 0, 0}}, // (129, 127) + { 0, { 0, 0, 0}}, // (130, 127) + { 0, { 0, 0, 0}}, // (131, 127) + { 0, { 0, 0, 0}}, // (132, 127) + { 0, { 0, 0, 0}}, // (133, 127) + { 0, { 0, 0, 0}}, // (134, 127) + { 0, { 0, 0, 0}}, // (135, 127) + { 0, { 0, 0, 0}}, // (136, 127) + { 0, { 0, 0, 0}}, // (137, 127) + { 0, { 0, 0, 0}}, // (138, 127) + { 0, { 0, 0, 0}}, // (139, 127) + { 0, { 0, 0, 0}}, // (140, 127) + { 0, { 0, 0, 0}}, // (141, 127) + { 0, { 0, 0, 0}}, // (142, 127) + { 0, { 0, 0, 0}}, // (143, 127) + { 0, { 0, 0, 0}}, // (144, 127) + { 0, { 0, 0, 0}}, // (145, 127) + { 0, { 0, 0, 0}}, // (146, 127) + { 0, { 0, 0, 0}}, // (147, 127) + { 0, { 0, 0, 0}}, // (148, 127) + { 0, { 0, 0, 0}}, // (149, 127) + { 0, { 0, 0, 0}}, // (150, 127) + { 0, { 0, 0, 0}}, // (151, 127) + { 0, { 0, 0, 0}}, // (152, 127) + { 0, { 0, 0, 0}}, // (153, 127) + { 0, { 0, 0, 0}}, // (154, 127) + { 0, { 0, 0, 0}}, // (155, 127) + { 0, { 0, 0, 0}}, // (156, 127) + { 0, { 0, 0, 0}}, // (157, 127) + { 0, { 0, 0, 0}}, // (158, 127) + { 0, { 0, 0, 0}}, // (159, 127) + { 0, { 0, 0, 0}}, // (160, 127) + { 0, { 0, 0, 0}}, // (161, 127) + { 0, { 0, 0, 0}}, // (162, 127) + { 0, { 0, 0, 0}}, // (163, 127) + { 0, { 0, 0, 0}}, // (164, 127) + { 0, { 0, 0, 0}}, // (165, 127) + { 0, { 0, 0, 0}}, // (166, 127) + { 0, { 0, 0, 0}}, // (167, 127) + { 0, { 0, 0, 0}}, // (168, 127) + { 47, { 0, 0, 0}}, // (169, 127) + {128, { 0, 0, 0}}, // (170, 127) + {128, { 0, 0, 0}}, // (171, 127) + {128, { 0, 0, 0}}, // (172, 127) + {128, { 0, 0, 0}}, // (173, 127) + {128, { 0, 0, 0}}, // (174, 127) + {128, { 0, 0, 0}}, // (175, 127) + {128, { 0, 0, 0}}, // (176, 127) + {128, { 0, 0, 0}}, // (177, 127) + {128, { 0, 0, 0}}, // (178, 127) + {128, { 0, 0, 0}}, // (179, 127) + {128, { 0, 0, 0}}, // ( 0, 128) + {128, { 0, 0, 0}}, // ( 1, 128) + {128, { 0, 0, 0}}, // ( 2, 128) + {128, { 0, 0, 0}}, // ( 3, 128) + {128, { 0, 0, 0}}, // ( 4, 128) + {128, { 0, 0, 0}}, // ( 5, 128) + {128, { 0, 0, 0}}, // ( 6, 128) + {128, { 0, 0, 0}}, // ( 7, 128) + {128, { 0, 0, 0}}, // ( 8, 128) + {128, { 0, 0, 0}}, // ( 9, 128) + {108, { 0, 0, 0}}, // ( 10, 128) + { 2, { 0, 0, 0}}, // ( 11, 128) + { 0, { 0, 0, 0}}, // ( 12, 128) + { 0, { 0, 0, 0}}, // ( 13, 128) + { 0, { 0, 0, 0}}, // ( 14, 128) + { 0, { 0, 0, 0}}, // ( 15, 128) + { 0, { 0, 0, 0}}, // ( 16, 128) + { 0, { 0, 0, 0}}, // ( 17, 128) + { 0, { 0, 0, 0}}, // ( 18, 128) + { 0, { 0, 0, 0}}, // ( 19, 128) + { 0, { 0, 0, 0}}, // ( 20, 128) + { 0, { 0, 0, 0}}, // ( 21, 128) + { 0, { 0, 0, 0}}, // ( 22, 128) + { 0, { 0, 0, 0}}, // ( 23, 128) + { 0, { 0, 0, 0}}, // ( 24, 128) + { 0, { 0, 0, 0}}, // ( 25, 128) + { 0, { 0, 0, 0}}, // ( 26, 128) + { 0, { 0, 0, 0}}, // ( 27, 128) + { 0, { 0, 0, 0}}, // ( 28, 128) + { 0, { 0, 0, 0}}, // ( 29, 128) + { 0, { 0, 0, 0}}, // ( 30, 128) + { 0, { 0, 0, 0}}, // ( 31, 128) + { 0, { 0, 0, 0}}, // ( 32, 128) + { 0, { 0, 0, 0}}, // ( 33, 128) + { 0, { 0, 0, 0}}, // ( 34, 128) + { 0, { 0, 0, 0}}, // ( 35, 128) + { 0, { 0, 0, 0}}, // ( 36, 128) + { 0, { 0, 0, 0}}, // ( 37, 128) + { 0, { 0, 0, 0}}, // ( 38, 128) + { 0, { 0, 0, 0}}, // ( 39, 128) + { 0, { 0, 0, 0}}, // ( 40, 128) + { 0, { 0, 0, 0}}, // ( 41, 128) + { 0, { 0, 0, 0}}, // ( 42, 128) + { 0, { 0, 0, 0}}, // ( 43, 128) + { 0, { 0, 0, 0}}, // ( 44, 128) + { 0, { 0, 0, 0}}, // ( 45, 128) + { 0, { 0, 0, 0}}, // ( 46, 128) + { 0, { 0, 0, 0}}, // ( 47, 128) + { 0, { 0, 0, 0}}, // ( 48, 128) + { 0, { 0, 0, 0}}, // ( 49, 128) + { 0, { 0, 0, 0}}, // ( 50, 128) + { 0, { 0, 0, 0}}, // ( 51, 128) + { 0, { 0, 0, 0}}, // ( 52, 128) + { 0, { 0, 0, 0}}, // ( 53, 128) + { 0, { 0, 0, 0}}, // ( 54, 128) + { 0, { 0, 0, 0}}, // ( 55, 128) + { 0, { 0, 0, 0}}, // ( 56, 128) + { 0, { 0, 0, 0}}, // ( 57, 128) + { 0, { 0, 0, 0}}, // ( 58, 128) + { 0, { 0, 0, 0}}, // ( 59, 128) + { 0, { 0, 0, 0}}, // ( 60, 128) + { 0, { 0, 0, 0}}, // ( 61, 128) + { 0, { 0, 0, 0}}, // ( 62, 128) + { 0, { 0, 0, 0}}, // ( 63, 128) + { 0, { 0, 0, 0}}, // ( 64, 128) + { 0, { 0, 0, 0}}, // ( 65, 128) + { 0, { 0, 0, 0}}, // ( 66, 128) + { 0, { 0, 0, 0}}, // ( 67, 128) + { 0, { 0, 0, 0}}, // ( 68, 128) + { 0, { 0, 0, 0}}, // ( 69, 128) + { 0, { 0, 0, 0}}, // ( 70, 128) + { 0, { 0, 0, 0}}, // ( 71, 128) + { 0, { 0, 0, 0}}, // ( 72, 128) + { 0, { 0, 0, 0}}, // ( 73, 128) + { 0, { 0, 0, 0}}, // ( 74, 128) + { 0, { 0, 0, 0}}, // ( 75, 128) + { 0, { 0, 0, 0}}, // ( 76, 128) + { 0, { 0, 0, 0}}, // ( 77, 128) + { 0, { 0, 0, 0}}, // ( 78, 128) + { 0, { 0, 0, 0}}, // ( 79, 128) + { 0, { 0, 0, 0}}, // ( 80, 128) + { 0, { 0, 0, 0}}, // ( 81, 128) + { 0, { 0, 0, 0}}, // ( 82, 128) + { 0, { 0, 0, 0}}, // ( 83, 128) + { 0, { 0, 0, 0}}, // ( 84, 128) + { 0, { 0, 0, 0}}, // ( 85, 128) + { 0, { 0, 0, 0}}, // ( 86, 128) + { 0, { 0, 0, 0}}, // ( 87, 128) + { 0, { 0, 0, 0}}, // ( 88, 128) + { 0, { 0, 0, 0}}, // ( 89, 128) + { 0, { 0, 0, 0}}, // ( 90, 128) + { 0, { 0, 0, 0}}, // ( 91, 128) + { 0, { 0, 0, 0}}, // ( 92, 128) + { 0, { 0, 0, 0}}, // ( 93, 128) + { 0, { 0, 0, 0}}, // ( 94, 128) + { 0, { 0, 0, 0}}, // ( 95, 128) + { 0, { 0, 0, 0}}, // ( 96, 128) + { 0, { 0, 0, 0}}, // ( 97, 128) + { 0, { 0, 0, 0}}, // ( 98, 128) + { 0, { 0, 0, 0}}, // ( 99, 128) + { 0, { 0, 0, 0}}, // (100, 128) + { 0, { 0, 0, 0}}, // (101, 128) + { 0, { 0, 0, 0}}, // (102, 128) + { 0, { 0, 0, 0}}, // (103, 128) + { 0, { 0, 0, 0}}, // (104, 128) + { 0, { 0, 0, 0}}, // (105, 128) + { 0, { 0, 0, 0}}, // (106, 128) + { 0, { 0, 0, 0}}, // (107, 128) + { 0, { 0, 0, 0}}, // (108, 128) + { 0, { 0, 0, 0}}, // (109, 128) + { 0, { 0, 0, 0}}, // (110, 128) + { 0, { 0, 0, 0}}, // (111, 128) + { 0, { 0, 0, 0}}, // (112, 128) + { 0, { 0, 0, 0}}, // (113, 128) + { 0, { 0, 0, 0}}, // (114, 128) + { 0, { 0, 0, 0}}, // (115, 128) + { 0, { 0, 0, 0}}, // (116, 128) + { 0, { 0, 0, 0}}, // (117, 128) + { 0, { 0, 0, 0}}, // (118, 128) + { 0, { 0, 0, 0}}, // (119, 128) + { 0, { 0, 0, 0}}, // (120, 128) + { 0, { 0, 0, 0}}, // (121, 128) + { 0, { 0, 0, 0}}, // (122, 128) + { 0, { 0, 0, 0}}, // (123, 128) + { 0, { 0, 0, 0}}, // (124, 128) + { 0, { 0, 0, 0}}, // (125, 128) + { 0, { 0, 0, 0}}, // (126, 128) + { 0, { 0, 0, 0}}, // (127, 128) + { 0, { 0, 0, 0}}, // (128, 128) + { 0, { 0, 0, 0}}, // (129, 128) + { 0, { 0, 0, 0}}, // (130, 128) + { 0, { 0, 0, 0}}, // (131, 128) + { 0, { 0, 0, 0}}, // (132, 128) + { 0, { 0, 0, 0}}, // (133, 128) + { 0, { 0, 0, 0}}, // (134, 128) + { 0, { 0, 0, 0}}, // (135, 128) + { 0, { 0, 0, 0}}, // (136, 128) + { 0, { 0, 0, 0}}, // (137, 128) + { 0, { 0, 0, 0}}, // (138, 128) + { 0, { 0, 0, 0}}, // (139, 128) + { 0, { 0, 0, 0}}, // (140, 128) + { 0, { 0, 0, 0}}, // (141, 128) + { 0, { 0, 0, 0}}, // (142, 128) + { 0, { 0, 0, 0}}, // (143, 128) + { 0, { 0, 0, 0}}, // (144, 128) + { 0, { 0, 0, 0}}, // (145, 128) + { 0, { 0, 0, 0}}, // (146, 128) + { 0, { 0, 0, 0}}, // (147, 128) + { 0, { 0, 0, 0}}, // (148, 128) + { 0, { 0, 0, 0}}, // (149, 128) + { 0, { 0, 0, 0}}, // (150, 128) + { 0, { 0, 0, 0}}, // (151, 128) + { 0, { 0, 0, 0}}, // (152, 128) + { 0, { 0, 0, 0}}, // (153, 128) + { 0, { 0, 0, 0}}, // (154, 128) + { 0, { 0, 0, 0}}, // (155, 128) + { 0, { 0, 0, 0}}, // (156, 128) + { 0, { 0, 0, 0}}, // (157, 128) + { 0, { 0, 0, 0}}, // (158, 128) + { 0, { 0, 0, 0}}, // (159, 128) + { 0, { 0, 0, 0}}, // (160, 128) + { 0, { 0, 0, 0}}, // (161, 128) + { 0, { 0, 0, 0}}, // (162, 128) + { 0, { 0, 0, 0}}, // (163, 128) + { 0, { 0, 0, 0}}, // (164, 128) + { 0, { 0, 0, 0}}, // (165, 128) + { 0, { 0, 0, 0}}, // (166, 128) + { 0, { 0, 0, 0}}, // (167, 128) + { 2, { 0, 0, 0}}, // (168, 128) + {108, { 0, 0, 0}}, // (169, 128) + {128, { 0, 0, 0}}, // (170, 128) + {128, { 0, 0, 0}}, // (171, 128) + {128, { 0, 0, 0}}, // (172, 128) + {128, { 0, 0, 0}}, // (173, 128) + {128, { 0, 0, 0}}, // (174, 128) + {128, { 0, 0, 0}}, // (175, 128) + {128, { 0, 0, 0}}, // (176, 128) + {128, { 0, 0, 0}}, // (177, 128) + {128, { 0, 0, 0}}, // (178, 128) + {128, { 0, 0, 0}}, // (179, 128) + {128, { 0, 0, 0}}, // ( 0, 129) + {128, { 0, 0, 0}}, // ( 1, 129) + {128, { 0, 0, 0}}, // ( 2, 129) + {128, { 0, 0, 0}}, // ( 3, 129) + {128, { 0, 0, 0}}, // ( 4, 129) + {128, { 0, 0, 0}}, // ( 5, 129) + {128, { 0, 0, 0}}, // ( 6, 129) + {128, { 0, 0, 0}}, // ( 7, 129) + {128, { 0, 0, 0}}, // ( 8, 129) + {128, { 0, 0, 0}}, // ( 9, 129) + {128, { 0, 0, 0}}, // ( 10, 129) + { 47, { 0, 0, 0}}, // ( 11, 129) + { 0, { 0, 0, 0}}, // ( 12, 129) + { 0, { 0, 0, 0}}, // ( 13, 129) + { 0, { 0, 0, 0}}, // ( 14, 129) + { 0, { 0, 0, 0}}, // ( 15, 129) + { 0, { 0, 0, 0}}, // ( 16, 129) + { 0, { 0, 0, 0}}, // ( 17, 129) + { 0, { 0, 0, 0}}, // ( 18, 129) + { 0, { 0, 0, 0}}, // ( 19, 129) + { 0, { 0, 0, 0}}, // ( 20, 129) + { 0, { 0, 0, 0}}, // ( 21, 129) + { 0, { 0, 0, 0}}, // ( 22, 129) + { 0, { 0, 0, 0}}, // ( 23, 129) + { 0, { 0, 0, 0}}, // ( 24, 129) + { 0, { 0, 0, 0}}, // ( 25, 129) + { 0, { 0, 0, 0}}, // ( 26, 129) + { 0, { 0, 0, 0}}, // ( 27, 129) + { 0, { 0, 0, 0}}, // ( 28, 129) + { 0, { 0, 0, 0}}, // ( 29, 129) + { 0, { 0, 0, 0}}, // ( 30, 129) + { 0, { 0, 0, 0}}, // ( 31, 129) + { 0, { 0, 0, 0}}, // ( 32, 129) + { 0, { 0, 0, 0}}, // ( 33, 129) + { 0, { 0, 0, 0}}, // ( 34, 129) + { 0, { 0, 0, 0}}, // ( 35, 129) + { 0, { 0, 0, 0}}, // ( 36, 129) + { 0, { 0, 0, 0}}, // ( 37, 129) + { 0, { 0, 0, 0}}, // ( 38, 129) + { 0, { 0, 0, 0}}, // ( 39, 129) + { 0, { 0, 0, 0}}, // ( 40, 129) + { 0, { 0, 0, 0}}, // ( 41, 129) + { 0, { 0, 0, 0}}, // ( 42, 129) + { 0, { 0, 0, 0}}, // ( 43, 129) + { 0, { 0, 0, 0}}, // ( 44, 129) + { 0, { 0, 0, 0}}, // ( 45, 129) + { 0, { 0, 0, 0}}, // ( 46, 129) + { 0, { 0, 0, 0}}, // ( 47, 129) + { 0, { 0, 0, 0}}, // ( 48, 129) + { 0, { 0, 0, 0}}, // ( 49, 129) + { 0, { 0, 0, 0}}, // ( 50, 129) + { 0, { 0, 0, 0}}, // ( 51, 129) + { 0, { 0, 0, 0}}, // ( 52, 129) + { 0, { 0, 0, 0}}, // ( 53, 129) + { 0, { 0, 0, 0}}, // ( 54, 129) + { 0, { 0, 0, 0}}, // ( 55, 129) + { 0, { 0, 0, 0}}, // ( 56, 129) + { 0, { 0, 0, 0}}, // ( 57, 129) + { 0, { 0, 0, 0}}, // ( 58, 129) + { 0, { 0, 0, 0}}, // ( 59, 129) + { 0, { 0, 0, 0}}, // ( 60, 129) + { 0, { 0, 0, 0}}, // ( 61, 129) + { 0, { 0, 0, 0}}, // ( 62, 129) + { 0, { 0, 0, 0}}, // ( 63, 129) + { 0, { 0, 0, 0}}, // ( 64, 129) + { 0, { 0, 0, 0}}, // ( 65, 129) + { 0, { 0, 0, 0}}, // ( 66, 129) + { 0, { 0, 0, 0}}, // ( 67, 129) + { 0, { 0, 0, 0}}, // ( 68, 129) + { 0, { 0, 0, 0}}, // ( 69, 129) + { 0, { 0, 0, 0}}, // ( 70, 129) + { 0, { 0, 0, 0}}, // ( 71, 129) + { 0, { 0, 0, 0}}, // ( 72, 129) + { 0, { 0, 0, 0}}, // ( 73, 129) + { 0, { 0, 0, 0}}, // ( 74, 129) + { 0, { 0, 0, 0}}, // ( 75, 129) + { 0, { 0, 0, 0}}, // ( 76, 129) + { 0, { 0, 0, 0}}, // ( 77, 129) + { 0, { 0, 0, 0}}, // ( 78, 129) + { 0, { 0, 0, 0}}, // ( 79, 129) + { 0, { 0, 0, 0}}, // ( 80, 129) + { 0, { 0, 0, 0}}, // ( 81, 129) + { 0, { 0, 0, 0}}, // ( 82, 129) + { 0, { 0, 0, 0}}, // ( 83, 129) + { 0, { 0, 0, 0}}, // ( 84, 129) + { 0, { 0, 0, 0}}, // ( 85, 129) + { 0, { 0, 0, 0}}, // ( 86, 129) + { 0, { 0, 0, 0}}, // ( 87, 129) + { 0, { 0, 0, 0}}, // ( 88, 129) + { 0, { 0, 0, 0}}, // ( 89, 129) + { 0, { 0, 0, 0}}, // ( 90, 129) + { 0, { 0, 0, 0}}, // ( 91, 129) + { 0, { 0, 0, 0}}, // ( 92, 129) + { 0, { 0, 0, 0}}, // ( 93, 129) + { 0, { 0, 0, 0}}, // ( 94, 129) + { 0, { 0, 0, 0}}, // ( 95, 129) + { 0, { 0, 0, 0}}, // ( 96, 129) + { 0, { 0, 0, 0}}, // ( 97, 129) + { 0, { 0, 0, 0}}, // ( 98, 129) + { 0, { 0, 0, 0}}, // ( 99, 129) + { 0, { 0, 0, 0}}, // (100, 129) + { 0, { 0, 0, 0}}, // (101, 129) + { 0, { 0, 0, 0}}, // (102, 129) + { 0, { 0, 0, 0}}, // (103, 129) + { 0, { 0, 0, 0}}, // (104, 129) + { 0, { 0, 0, 0}}, // (105, 129) + { 0, { 0, 0, 0}}, // (106, 129) + { 0, { 0, 0, 0}}, // (107, 129) + { 0, { 0, 0, 0}}, // (108, 129) + { 0, { 0, 0, 0}}, // (109, 129) + { 0, { 0, 0, 0}}, // (110, 129) + { 0, { 0, 0, 0}}, // (111, 129) + { 0, { 0, 0, 0}}, // (112, 129) + { 0, { 0, 0, 0}}, // (113, 129) + { 0, { 0, 0, 0}}, // (114, 129) + { 0, { 0, 0, 0}}, // (115, 129) + { 0, { 0, 0, 0}}, // (116, 129) + { 0, { 0, 0, 0}}, // (117, 129) + { 0, { 0, 0, 0}}, // (118, 129) + { 0, { 0, 0, 0}}, // (119, 129) + { 0, { 0, 0, 0}}, // (120, 129) + { 0, { 0, 0, 0}}, // (121, 129) + { 0, { 0, 0, 0}}, // (122, 129) + { 0, { 0, 0, 0}}, // (123, 129) + { 0, { 0, 0, 0}}, // (124, 129) + { 0, { 0, 0, 0}}, // (125, 129) + { 0, { 0, 0, 0}}, // (126, 129) + { 0, { 0, 0, 0}}, // (127, 129) + { 0, { 0, 0, 0}}, // (128, 129) + { 0, { 0, 0, 0}}, // (129, 129) + { 0, { 0, 0, 0}}, // (130, 129) + { 0, { 0, 0, 0}}, // (131, 129) + { 0, { 0, 0, 0}}, // (132, 129) + { 0, { 0, 0, 0}}, // (133, 129) + { 0, { 0, 0, 0}}, // (134, 129) + { 0, { 0, 0, 0}}, // (135, 129) + { 0, { 0, 0, 0}}, // (136, 129) + { 0, { 0, 0, 0}}, // (137, 129) + { 0, { 0, 0, 0}}, // (138, 129) + { 0, { 0, 0, 0}}, // (139, 129) + { 0, { 0, 0, 0}}, // (140, 129) + { 0, { 0, 0, 0}}, // (141, 129) + { 0, { 0, 0, 0}}, // (142, 129) + { 0, { 0, 0, 0}}, // (143, 129) + { 0, { 0, 0, 0}}, // (144, 129) + { 0, { 0, 0, 0}}, // (145, 129) + { 0, { 0, 0, 0}}, // (146, 129) + { 0, { 0, 0, 0}}, // (147, 129) + { 0, { 0, 0, 0}}, // (148, 129) + { 0, { 0, 0, 0}}, // (149, 129) + { 0, { 0, 0, 0}}, // (150, 129) + { 0, { 0, 0, 0}}, // (151, 129) + { 0, { 0, 0, 0}}, // (152, 129) + { 0, { 0, 0, 0}}, // (153, 129) + { 0, { 0, 0, 0}}, // (154, 129) + { 0, { 0, 0, 0}}, // (155, 129) + { 0, { 0, 0, 0}}, // (156, 129) + { 0, { 0, 0, 0}}, // (157, 129) + { 0, { 0, 0, 0}}, // (158, 129) + { 0, { 0, 0, 0}}, // (159, 129) + { 0, { 0, 0, 0}}, // (160, 129) + { 0, { 0, 0, 0}}, // (161, 129) + { 0, { 0, 0, 0}}, // (162, 129) + { 0, { 0, 0, 0}}, // (163, 129) + { 0, { 0, 0, 0}}, // (164, 129) + { 0, { 0, 0, 0}}, // (165, 129) + { 0, { 0, 0, 0}}, // (166, 129) + { 0, { 0, 0, 0}}, // (167, 129) + { 47, { 0, 0, 0}}, // (168, 129) + {128, { 0, 0, 0}}, // (169, 129) + {128, { 0, 0, 0}}, // (170, 129) + {128, { 0, 0, 0}}, // (171, 129) + {128, { 0, 0, 0}}, // (172, 129) + {128, { 0, 0, 0}}, // (173, 129) + {128, { 0, 0, 0}}, // (174, 129) + {128, { 0, 0, 0}}, // (175, 129) + {128, { 0, 0, 0}}, // (176, 129) + {128, { 0, 0, 0}}, // (177, 129) + {128, { 0, 0, 0}}, // (178, 129) + {128, { 0, 0, 0}}, // (179, 129) + {128, { 0, 0, 0}}, // ( 0, 130) + {128, { 0, 0, 0}}, // ( 1, 130) + {128, { 0, 0, 0}}, // ( 2, 130) + {128, { 0, 0, 0}}, // ( 3, 130) + {128, { 0, 0, 0}}, // ( 4, 130) + {128, { 0, 0, 0}}, // ( 5, 130) + {128, { 0, 0, 0}}, // ( 6, 130) + {128, { 0, 0, 0}}, // ( 7, 130) + {128, { 0, 0, 0}}, // ( 8, 130) + {128, { 0, 0, 0}}, // ( 9, 130) + {128, { 0, 0, 0}}, // ( 10, 130) + {110, { 0, 0, 0}}, // ( 11, 130) + { 2, { 0, 0, 0}}, // ( 12, 130) + { 0, { 0, 0, 0}}, // ( 13, 130) + { 0, { 0, 0, 0}}, // ( 14, 130) + { 0, { 0, 0, 0}}, // ( 15, 130) + { 0, { 0, 0, 0}}, // ( 16, 130) + { 0, { 0, 0, 0}}, // ( 17, 130) + { 0, { 0, 0, 0}}, // ( 18, 130) + { 0, { 0, 0, 0}}, // ( 19, 130) + { 0, { 0, 0, 0}}, // ( 20, 130) + { 0, { 0, 0, 0}}, // ( 21, 130) + { 0, { 0, 0, 0}}, // ( 22, 130) + { 0, { 0, 0, 0}}, // ( 23, 130) + { 0, { 0, 0, 0}}, // ( 24, 130) + { 0, { 0, 0, 0}}, // ( 25, 130) + { 0, { 0, 0, 0}}, // ( 26, 130) + { 0, { 0, 0, 0}}, // ( 27, 130) + { 0, { 0, 0, 0}}, // ( 28, 130) + { 0, { 0, 0, 0}}, // ( 29, 130) + { 0, { 0, 0, 0}}, // ( 30, 130) + { 0, { 0, 0, 0}}, // ( 31, 130) + { 0, { 0, 0, 0}}, // ( 32, 130) + { 0, { 0, 0, 0}}, // ( 33, 130) + { 0, { 0, 0, 0}}, // ( 34, 130) + { 0, { 0, 0, 0}}, // ( 35, 130) + { 0, { 0, 0, 0}}, // ( 36, 130) + { 0, { 0, 0, 0}}, // ( 37, 130) + { 0, { 0, 0, 0}}, // ( 38, 130) + { 0, { 0, 0, 0}}, // ( 39, 130) + { 0, { 0, 0, 0}}, // ( 40, 130) + { 0, { 0, 0, 0}}, // ( 41, 130) + { 0, { 0, 0, 0}}, // ( 42, 130) + { 0, { 0, 0, 0}}, // ( 43, 130) + { 0, { 0, 0, 0}}, // ( 44, 130) + { 0, { 0, 0, 0}}, // ( 45, 130) + { 0, { 0, 0, 0}}, // ( 46, 130) + { 0, { 0, 0, 0}}, // ( 47, 130) + { 0, { 0, 0, 0}}, // ( 48, 130) + { 0, { 0, 0, 0}}, // ( 49, 130) + { 0, { 0, 0, 0}}, // ( 50, 130) + { 0, { 0, 0, 0}}, // ( 51, 130) + { 0, { 0, 0, 0}}, // ( 52, 130) + { 0, { 0, 0, 0}}, // ( 53, 130) + { 0, { 0, 0, 0}}, // ( 54, 130) + { 0, { 0, 0, 0}}, // ( 55, 130) + { 0, { 0, 0, 0}}, // ( 56, 130) + { 0, { 0, 0, 0}}, // ( 57, 130) + { 0, { 0, 0, 0}}, // ( 58, 130) + { 0, { 0, 0, 0}}, // ( 59, 130) + { 0, { 0, 0, 0}}, // ( 60, 130) + { 0, { 0, 0, 0}}, // ( 61, 130) + { 0, { 0, 0, 0}}, // ( 62, 130) + { 0, { 0, 0, 0}}, // ( 63, 130) + { 0, { 0, 0, 0}}, // ( 64, 130) + { 0, { 0, 0, 0}}, // ( 65, 130) + { 0, { 0, 0, 0}}, // ( 66, 130) + { 0, { 0, 0, 0}}, // ( 67, 130) + { 0, { 0, 0, 0}}, // ( 68, 130) + { 0, { 0, 0, 0}}, // ( 69, 130) + { 0, { 0, 0, 0}}, // ( 70, 130) + { 0, { 0, 0, 0}}, // ( 71, 130) + { 0, { 0, 0, 0}}, // ( 72, 130) + { 0, { 0, 0, 0}}, // ( 73, 130) + { 0, { 0, 0, 0}}, // ( 74, 130) + { 0, { 0, 0, 0}}, // ( 75, 130) + { 0, { 0, 0, 0}}, // ( 76, 130) + { 0, { 0, 0, 0}}, // ( 77, 130) + { 0, { 0, 0, 0}}, // ( 78, 130) + { 0, { 0, 0, 0}}, // ( 79, 130) + { 0, { 0, 0, 0}}, // ( 80, 130) + { 0, { 0, 0, 0}}, // ( 81, 130) + { 0, { 0, 0, 0}}, // ( 82, 130) + { 0, { 0, 0, 0}}, // ( 83, 130) + { 0, { 0, 0, 0}}, // ( 84, 130) + { 0, { 0, 0, 0}}, // ( 85, 130) + { 0, { 0, 0, 0}}, // ( 86, 130) + { 0, { 0, 0, 0}}, // ( 87, 130) + { 0, { 0, 0, 0}}, // ( 88, 130) + { 0, { 0, 0, 0}}, // ( 89, 130) + { 0, { 0, 0, 0}}, // ( 90, 130) + { 0, { 0, 0, 0}}, // ( 91, 130) + { 0, { 0, 0, 0}}, // ( 92, 130) + { 0, { 0, 0, 0}}, // ( 93, 130) + { 0, { 0, 0, 0}}, // ( 94, 130) + { 0, { 0, 0, 0}}, // ( 95, 130) + { 0, { 0, 0, 0}}, // ( 96, 130) + { 0, { 0, 0, 0}}, // ( 97, 130) + { 0, { 0, 0, 0}}, // ( 98, 130) + { 0, { 0, 0, 0}}, // ( 99, 130) + { 0, { 0, 0, 0}}, // (100, 130) + { 0, { 0, 0, 0}}, // (101, 130) + { 0, { 0, 0, 0}}, // (102, 130) + { 0, { 0, 0, 0}}, // (103, 130) + { 0, { 0, 0, 0}}, // (104, 130) + { 0, { 0, 0, 0}}, // (105, 130) + { 0, { 0, 0, 0}}, // (106, 130) + { 0, { 0, 0, 0}}, // (107, 130) + { 0, { 0, 0, 0}}, // (108, 130) + { 0, { 0, 0, 0}}, // (109, 130) + { 0, { 0, 0, 0}}, // (110, 130) + { 0, { 0, 0, 0}}, // (111, 130) + { 0, { 0, 0, 0}}, // (112, 130) + { 0, { 0, 0, 0}}, // (113, 130) + { 0, { 0, 0, 0}}, // (114, 130) + { 0, { 0, 0, 0}}, // (115, 130) + { 0, { 0, 0, 0}}, // (116, 130) + { 0, { 0, 0, 0}}, // (117, 130) + { 0, { 0, 0, 0}}, // (118, 130) + { 0, { 0, 0, 0}}, // (119, 130) + { 0, { 0, 0, 0}}, // (120, 130) + { 0, { 0, 0, 0}}, // (121, 130) + { 0, { 0, 0, 0}}, // (122, 130) + { 0, { 0, 0, 0}}, // (123, 130) + { 0, { 0, 0, 0}}, // (124, 130) + { 0, { 0, 0, 0}}, // (125, 130) + { 0, { 0, 0, 0}}, // (126, 130) + { 0, { 0, 0, 0}}, // (127, 130) + { 0, { 0, 0, 0}}, // (128, 130) + { 0, { 0, 0, 0}}, // (129, 130) + { 0, { 0, 0, 0}}, // (130, 130) + { 0, { 0, 0, 0}}, // (131, 130) + { 0, { 0, 0, 0}}, // (132, 130) + { 0, { 0, 0, 0}}, // (133, 130) + { 0, { 0, 0, 0}}, // (134, 130) + { 0, { 0, 0, 0}}, // (135, 130) + { 0, { 0, 0, 0}}, // (136, 130) + { 0, { 0, 0, 0}}, // (137, 130) + { 0, { 0, 0, 0}}, // (138, 130) + { 0, { 0, 0, 0}}, // (139, 130) + { 0, { 0, 0, 0}}, // (140, 130) + { 0, { 0, 0, 0}}, // (141, 130) + { 0, { 0, 0, 0}}, // (142, 130) + { 0, { 0, 0, 0}}, // (143, 130) + { 0, { 0, 0, 0}}, // (144, 130) + { 0, { 0, 0, 0}}, // (145, 130) + { 0, { 0, 0, 0}}, // (146, 130) + { 0, { 0, 0, 0}}, // (147, 130) + { 0, { 0, 0, 0}}, // (148, 130) + { 0, { 0, 0, 0}}, // (149, 130) + { 0, { 0, 0, 0}}, // (150, 130) + { 0, { 0, 0, 0}}, // (151, 130) + { 0, { 0, 0, 0}}, // (152, 130) + { 0, { 0, 0, 0}}, // (153, 130) + { 0, { 0, 0, 0}}, // (154, 130) + { 0, { 0, 0, 0}}, // (155, 130) + { 0, { 0, 0, 0}}, // (156, 130) + { 0, { 0, 0, 0}}, // (157, 130) + { 0, { 0, 0, 0}}, // (158, 130) + { 0, { 0, 0, 0}}, // (159, 130) + { 0, { 0, 0, 0}}, // (160, 130) + { 0, { 0, 0, 0}}, // (161, 130) + { 0, { 0, 0, 0}}, // (162, 130) + { 0, { 0, 0, 0}}, // (163, 130) + { 0, { 0, 0, 0}}, // (164, 130) + { 0, { 0, 0, 0}}, // (165, 130) + { 0, { 0, 0, 0}}, // (166, 130) + { 2, { 0, 0, 0}}, // (167, 130) + {110, { 0, 0, 0}}, // (168, 130) + {128, { 0, 0, 0}}, // (169, 130) + {128, { 0, 0, 0}}, // (170, 130) + {128, { 0, 0, 0}}, // (171, 130) + {128, { 0, 0, 0}}, // (172, 130) + {128, { 0, 0, 0}}, // (173, 130) + {128, { 0, 0, 0}}, // (174, 130) + {128, { 0, 0, 0}}, // (175, 130) + {128, { 0, 0, 0}}, // (176, 130) + {128, { 0, 0, 0}}, // (177, 130) + {128, { 0, 0, 0}}, // (178, 130) + {128, { 0, 0, 0}}, // (179, 130) + {128, { 0, 0, 0}}, // ( 0, 131) + {128, { 0, 0, 0}}, // ( 1, 131) + {128, { 0, 0, 0}}, // ( 2, 131) + {128, { 0, 0, 0}}, // ( 3, 131) + {128, { 0, 0, 0}}, // ( 4, 131) + {128, { 0, 0, 0}}, // ( 5, 131) + {128, { 0, 0, 0}}, // ( 6, 131) + {128, { 0, 0, 0}}, // ( 7, 131) + {128, { 0, 0, 0}}, // ( 8, 131) + {128, { 0, 0, 0}}, // ( 9, 131) + {128, { 0, 0, 0}}, // ( 10, 131) + {128, { 0, 0, 0}}, // ( 11, 131) + { 51, { 0, 0, 0}}, // ( 12, 131) + { 0, { 0, 0, 0}}, // ( 13, 131) + { 0, { 0, 0, 0}}, // ( 14, 131) + { 0, { 0, 0, 0}}, // ( 15, 131) + { 0, { 0, 0, 0}}, // ( 16, 131) + { 0, { 0, 0, 0}}, // ( 17, 131) + { 0, { 0, 0, 0}}, // ( 18, 131) + { 0, { 0, 0, 0}}, // ( 19, 131) + { 0, { 0, 0, 0}}, // ( 20, 131) + { 0, { 0, 0, 0}}, // ( 21, 131) + { 0, { 0, 0, 0}}, // ( 22, 131) + { 0, { 0, 0, 0}}, // ( 23, 131) + { 0, { 0, 0, 0}}, // ( 24, 131) + { 0, { 0, 0, 0}}, // ( 25, 131) + { 0, { 0, 0, 0}}, // ( 26, 131) + { 0, { 0, 0, 0}}, // ( 27, 131) + { 0, { 0, 0, 0}}, // ( 28, 131) + { 0, { 0, 0, 0}}, // ( 29, 131) + { 0, { 0, 0, 0}}, // ( 30, 131) + { 0, { 0, 0, 0}}, // ( 31, 131) + { 0, { 0, 0, 0}}, // ( 32, 131) + { 0, { 0, 0, 0}}, // ( 33, 131) + { 0, { 0, 0, 0}}, // ( 34, 131) + { 0, { 0, 0, 0}}, // ( 35, 131) + { 0, { 0, 0, 0}}, // ( 36, 131) + { 0, { 0, 0, 0}}, // ( 37, 131) + { 0, { 0, 0, 0}}, // ( 38, 131) + { 0, { 0, 0, 0}}, // ( 39, 131) + { 0, { 0, 0, 0}}, // ( 40, 131) + { 0, { 0, 0, 0}}, // ( 41, 131) + { 0, { 0, 0, 0}}, // ( 42, 131) + { 0, { 0, 0, 0}}, // ( 43, 131) + { 0, { 0, 0, 0}}, // ( 44, 131) + { 0, { 0, 0, 0}}, // ( 45, 131) + { 0, { 0, 0, 0}}, // ( 46, 131) + { 0, { 0, 0, 0}}, // ( 47, 131) + { 0, { 0, 0, 0}}, // ( 48, 131) + { 0, { 0, 0, 0}}, // ( 49, 131) + { 0, { 0, 0, 0}}, // ( 50, 131) + { 0, { 0, 0, 0}}, // ( 51, 131) + { 0, { 0, 0, 0}}, // ( 52, 131) + { 0, { 0, 0, 0}}, // ( 53, 131) + { 0, { 0, 0, 0}}, // ( 54, 131) + { 0, { 0, 0, 0}}, // ( 55, 131) + { 0, { 0, 0, 0}}, // ( 56, 131) + { 0, { 0, 0, 0}}, // ( 57, 131) + { 0, { 0, 0, 0}}, // ( 58, 131) + { 0, { 0, 0, 0}}, // ( 59, 131) + { 0, { 0, 0, 0}}, // ( 60, 131) + { 0, { 0, 0, 0}}, // ( 61, 131) + { 0, { 0, 0, 0}}, // ( 62, 131) + { 0, { 0, 0, 0}}, // ( 63, 131) + { 0, { 0, 0, 0}}, // ( 64, 131) + { 0, { 0, 0, 0}}, // ( 65, 131) + { 0, { 0, 0, 0}}, // ( 66, 131) + { 0, { 0, 0, 0}}, // ( 67, 131) + { 0, { 0, 0, 0}}, // ( 68, 131) + { 0, { 0, 0, 0}}, // ( 69, 131) + { 0, { 0, 0, 0}}, // ( 70, 131) + { 0, { 0, 0, 0}}, // ( 71, 131) + { 0, { 0, 0, 0}}, // ( 72, 131) + { 0, { 0, 0, 0}}, // ( 73, 131) + { 0, { 0, 0, 0}}, // ( 74, 131) + { 0, { 0, 0, 0}}, // ( 75, 131) + { 0, { 0, 0, 0}}, // ( 76, 131) + { 0, { 0, 0, 0}}, // ( 77, 131) + { 0, { 0, 0, 0}}, // ( 78, 131) + { 0, { 0, 0, 0}}, // ( 79, 131) + { 0, { 0, 0, 0}}, // ( 80, 131) + { 0, { 0, 0, 0}}, // ( 81, 131) + { 0, { 0, 0, 0}}, // ( 82, 131) + { 0, { 0, 0, 0}}, // ( 83, 131) + { 0, { 0, 0, 0}}, // ( 84, 131) + { 0, { 0, 0, 0}}, // ( 85, 131) + { 0, { 0, 0, 0}}, // ( 86, 131) + { 0, { 0, 0, 0}}, // ( 87, 131) + { 0, { 0, 0, 0}}, // ( 88, 131) + { 0, { 0, 0, 0}}, // ( 89, 131) + { 0, { 0, 0, 0}}, // ( 90, 131) + { 0, { 0, 0, 0}}, // ( 91, 131) + { 0, { 0, 0, 0}}, // ( 92, 131) + { 0, { 0, 0, 0}}, // ( 93, 131) + { 0, { 0, 0, 0}}, // ( 94, 131) + { 0, { 0, 0, 0}}, // ( 95, 131) + { 0, { 0, 0, 0}}, // ( 96, 131) + { 0, { 0, 0, 0}}, // ( 97, 131) + { 0, { 0, 0, 0}}, // ( 98, 131) + { 0, { 0, 0, 0}}, // ( 99, 131) + { 0, { 0, 0, 0}}, // (100, 131) + { 0, { 0, 0, 0}}, // (101, 131) + { 0, { 0, 0, 0}}, // (102, 131) + { 0, { 0, 0, 0}}, // (103, 131) + { 0, { 0, 0, 0}}, // (104, 131) + { 0, { 0, 0, 0}}, // (105, 131) + { 0, { 0, 0, 0}}, // (106, 131) + { 0, { 0, 0, 0}}, // (107, 131) + { 0, { 0, 0, 0}}, // (108, 131) + { 0, { 0, 0, 0}}, // (109, 131) + { 0, { 0, 0, 0}}, // (110, 131) + { 0, { 0, 0, 0}}, // (111, 131) + { 0, { 0, 0, 0}}, // (112, 131) + { 0, { 0, 0, 0}}, // (113, 131) + { 0, { 0, 0, 0}}, // (114, 131) + { 0, { 0, 0, 0}}, // (115, 131) + { 0, { 0, 0, 0}}, // (116, 131) + { 0, { 0, 0, 0}}, // (117, 131) + { 0, { 0, 0, 0}}, // (118, 131) + { 0, { 0, 0, 0}}, // (119, 131) + { 0, { 0, 0, 0}}, // (120, 131) + { 0, { 0, 0, 0}}, // (121, 131) + { 0, { 0, 0, 0}}, // (122, 131) + { 0, { 0, 0, 0}}, // (123, 131) + { 0, { 0, 0, 0}}, // (124, 131) + { 0, { 0, 0, 0}}, // (125, 131) + { 0, { 0, 0, 0}}, // (126, 131) + { 0, { 0, 0, 0}}, // (127, 131) + { 0, { 0, 0, 0}}, // (128, 131) + { 0, { 0, 0, 0}}, // (129, 131) + { 0, { 0, 0, 0}}, // (130, 131) + { 0, { 0, 0, 0}}, // (131, 131) + { 0, { 0, 0, 0}}, // (132, 131) + { 0, { 0, 0, 0}}, // (133, 131) + { 0, { 0, 0, 0}}, // (134, 131) + { 0, { 0, 0, 0}}, // (135, 131) + { 0, { 0, 0, 0}}, // (136, 131) + { 0, { 0, 0, 0}}, // (137, 131) + { 0, { 0, 0, 0}}, // (138, 131) + { 0, { 0, 0, 0}}, // (139, 131) + { 0, { 0, 0, 0}}, // (140, 131) + { 0, { 0, 0, 0}}, // (141, 131) + { 0, { 0, 0, 0}}, // (142, 131) + { 0, { 0, 0, 0}}, // (143, 131) + { 0, { 0, 0, 0}}, // (144, 131) + { 0, { 0, 0, 0}}, // (145, 131) + { 0, { 0, 0, 0}}, // (146, 131) + { 0, { 0, 0, 0}}, // (147, 131) + { 0, { 0, 0, 0}}, // (148, 131) + { 0, { 0, 0, 0}}, // (149, 131) + { 0, { 0, 0, 0}}, // (150, 131) + { 0, { 0, 0, 0}}, // (151, 131) + { 0, { 0, 0, 0}}, // (152, 131) + { 0, { 0, 0, 0}}, // (153, 131) + { 0, { 0, 0, 0}}, // (154, 131) + { 0, { 0, 0, 0}}, // (155, 131) + { 0, { 0, 0, 0}}, // (156, 131) + { 0, { 0, 0, 0}}, // (157, 131) + { 0, { 0, 0, 0}}, // (158, 131) + { 0, { 0, 0, 0}}, // (159, 131) + { 0, { 0, 0, 0}}, // (160, 131) + { 0, { 0, 0, 0}}, // (161, 131) + { 0, { 0, 0, 0}}, // (162, 131) + { 0, { 0, 0, 0}}, // (163, 131) + { 0, { 0, 0, 0}}, // (164, 131) + { 0, { 0, 0, 0}}, // (165, 131) + { 0, { 0, 0, 0}}, // (166, 131) + { 50, { 0, 0, 0}}, // (167, 131) + {128, { 0, 0, 0}}, // (168, 131) + {128, { 0, 0, 0}}, // (169, 131) + {128, { 0, 0, 0}}, // (170, 131) + {128, { 0, 0, 0}}, // (171, 131) + {128, { 0, 0, 0}}, // (172, 131) + {128, { 0, 0, 0}}, // (173, 131) + {128, { 0, 0, 0}}, // (174, 131) + {128, { 0, 0, 0}}, // (175, 131) + {128, { 0, 0, 0}}, // (176, 131) + {128, { 0, 0, 0}}, // (177, 131) + {128, { 0, 0, 0}}, // (178, 131) + {128, { 0, 0, 0}}, // (179, 131) + {128, { 0, 0, 0}}, // ( 0, 132) + {128, { 0, 0, 0}}, // ( 1, 132) + {128, { 0, 0, 0}}, // ( 2, 132) + {128, { 0, 0, 0}}, // ( 3, 132) + {128, { 0, 0, 0}}, // ( 4, 132) + {128, { 0, 0, 0}}, // ( 5, 132) + {128, { 0, 0, 0}}, // ( 6, 132) + {128, { 0, 0, 0}}, // ( 7, 132) + {128, { 0, 0, 0}}, // ( 8, 132) + {128, { 0, 0, 0}}, // ( 9, 132) + {128, { 0, 0, 0}}, // ( 10, 132) + {128, { 0, 0, 0}}, // ( 11, 132) + {114, { 0, 0, 0}}, // ( 12, 132) + { 6, { 0, 0, 0}}, // ( 13, 132) + { 0, { 0, 0, 0}}, // ( 14, 132) + { 0, { 0, 0, 0}}, // ( 15, 132) + { 0, { 0, 0, 0}}, // ( 16, 132) + { 0, { 0, 0, 0}}, // ( 17, 132) + { 0, { 0, 0, 0}}, // ( 18, 132) + { 0, { 0, 0, 0}}, // ( 19, 132) + { 0, { 0, 0, 0}}, // ( 20, 132) + { 0, { 0, 0, 0}}, // ( 21, 132) + { 0, { 0, 0, 0}}, // ( 22, 132) + { 0, { 0, 0, 0}}, // ( 23, 132) + { 0, { 0, 0, 0}}, // ( 24, 132) + { 0, { 0, 0, 0}}, // ( 25, 132) + { 0, { 0, 0, 0}}, // ( 26, 132) + { 0, { 0, 0, 0}}, // ( 27, 132) + { 0, { 0, 0, 0}}, // ( 28, 132) + { 0, { 0, 0, 0}}, // ( 29, 132) + { 0, { 0, 0, 0}}, // ( 30, 132) + { 0, { 0, 0, 0}}, // ( 31, 132) + { 0, { 0, 0, 0}}, // ( 32, 132) + { 0, { 0, 0, 0}}, // ( 33, 132) + { 0, { 0, 0, 0}}, // ( 34, 132) + { 0, { 0, 0, 0}}, // ( 35, 132) + { 0, { 0, 0, 0}}, // ( 36, 132) + { 0, { 0, 0, 0}}, // ( 37, 132) + { 0, { 0, 0, 0}}, // ( 38, 132) + { 0, { 0, 0, 0}}, // ( 39, 132) + { 0, { 0, 0, 0}}, // ( 40, 132) + { 0, { 0, 0, 0}}, // ( 41, 132) + { 0, { 0, 0, 0}}, // ( 42, 132) + { 0, { 0, 0, 0}}, // ( 43, 132) + { 0, { 0, 0, 0}}, // ( 44, 132) + { 0, { 0, 0, 0}}, // ( 45, 132) + { 0, { 0, 0, 0}}, // ( 46, 132) + { 0, { 0, 0, 0}}, // ( 47, 132) + { 0, { 0, 0, 0}}, // ( 48, 132) + { 0, { 0, 0, 0}}, // ( 49, 132) + { 0, { 0, 0, 0}}, // ( 50, 132) + { 0, { 0, 0, 0}}, // ( 51, 132) + { 0, { 0, 0, 0}}, // ( 52, 132) + { 0, { 0, 0, 0}}, // ( 53, 132) + { 0, { 0, 0, 0}}, // ( 54, 132) + { 0, { 0, 0, 0}}, // ( 55, 132) + { 0, { 0, 0, 0}}, // ( 56, 132) + { 0, { 0, 0, 0}}, // ( 57, 132) + { 0, { 0, 0, 0}}, // ( 58, 132) + { 0, { 0, 0, 0}}, // ( 59, 132) + { 0, { 0, 0, 0}}, // ( 60, 132) + { 0, { 0, 0, 0}}, // ( 61, 132) + { 0, { 0, 0, 0}}, // ( 62, 132) + { 0, { 0, 0, 0}}, // ( 63, 132) + { 0, { 0, 0, 0}}, // ( 64, 132) + { 0, { 0, 0, 0}}, // ( 65, 132) + { 0, { 0, 0, 0}}, // ( 66, 132) + { 0, { 0, 0, 0}}, // ( 67, 132) + { 0, { 0, 0, 0}}, // ( 68, 132) + { 0, { 0, 0, 0}}, // ( 69, 132) + { 0, { 0, 0, 0}}, // ( 70, 132) + { 0, { 0, 0, 0}}, // ( 71, 132) + { 0, { 0, 0, 0}}, // ( 72, 132) + { 0, { 0, 0, 0}}, // ( 73, 132) + { 0, { 0, 0, 0}}, // ( 74, 132) + { 0, { 0, 0, 0}}, // ( 75, 132) + { 0, { 0, 0, 0}}, // ( 76, 132) + { 0, { 0, 0, 0}}, // ( 77, 132) + { 0, { 0, 0, 0}}, // ( 78, 132) + { 0, { 0, 0, 0}}, // ( 79, 132) + { 0, { 0, 0, 0}}, // ( 80, 132) + { 0, { 0, 0, 0}}, // ( 81, 132) + { 0, { 0, 0, 0}}, // ( 82, 132) + { 0, { 0, 0, 0}}, // ( 83, 132) + { 0, { 0, 0, 0}}, // ( 84, 132) + { 0, { 0, 0, 0}}, // ( 85, 132) + { 0, { 0, 0, 0}}, // ( 86, 132) + { 0, { 0, 0, 0}}, // ( 87, 132) + { 0, { 0, 0, 0}}, // ( 88, 132) + { 0, { 0, 0, 0}}, // ( 89, 132) + { 0, { 0, 0, 0}}, // ( 90, 132) + { 0, { 0, 0, 0}}, // ( 91, 132) + { 0, { 0, 0, 0}}, // ( 92, 132) + { 0, { 0, 0, 0}}, // ( 93, 132) + { 0, { 0, 0, 0}}, // ( 94, 132) + { 0, { 0, 0, 0}}, // ( 95, 132) + { 0, { 0, 0, 0}}, // ( 96, 132) + { 0, { 0, 0, 0}}, // ( 97, 132) + { 0, { 0, 0, 0}}, // ( 98, 132) + { 0, { 0, 0, 0}}, // ( 99, 132) + { 0, { 0, 0, 0}}, // (100, 132) + { 0, { 0, 0, 0}}, // (101, 132) + { 0, { 0, 0, 0}}, // (102, 132) + { 0, { 0, 0, 0}}, // (103, 132) + { 0, { 0, 0, 0}}, // (104, 132) + { 0, { 0, 0, 0}}, // (105, 132) + { 0, { 0, 0, 0}}, // (106, 132) + { 0, { 0, 0, 0}}, // (107, 132) + { 0, { 0, 0, 0}}, // (108, 132) + { 0, { 0, 0, 0}}, // (109, 132) + { 0, { 0, 0, 0}}, // (110, 132) + { 0, { 0, 0, 0}}, // (111, 132) + { 0, { 0, 0, 0}}, // (112, 132) + { 0, { 0, 0, 0}}, // (113, 132) + { 0, { 0, 0, 0}}, // (114, 132) + { 0, { 0, 0, 0}}, // (115, 132) + { 0, { 0, 0, 0}}, // (116, 132) + { 0, { 0, 0, 0}}, // (117, 132) + { 0, { 0, 0, 0}}, // (118, 132) + { 0, { 0, 0, 0}}, // (119, 132) + { 0, { 0, 0, 0}}, // (120, 132) + { 0, { 0, 0, 0}}, // (121, 132) + { 0, { 0, 0, 0}}, // (122, 132) + { 0, { 0, 0, 0}}, // (123, 132) + { 0, { 0, 0, 0}}, // (124, 132) + { 0, { 0, 0, 0}}, // (125, 132) + { 0, { 0, 0, 0}}, // (126, 132) + { 0, { 0, 0, 0}}, // (127, 132) + { 0, { 0, 0, 0}}, // (128, 132) + { 0, { 0, 0, 0}}, // (129, 132) + { 0, { 0, 0, 0}}, // (130, 132) + { 0, { 0, 0, 0}}, // (131, 132) + { 0, { 0, 0, 0}}, // (132, 132) + { 0, { 0, 0, 0}}, // (133, 132) + { 0, { 0, 0, 0}}, // (134, 132) + { 0, { 0, 0, 0}}, // (135, 132) + { 0, { 0, 0, 0}}, // (136, 132) + { 0, { 0, 0, 0}}, // (137, 132) + { 0, { 0, 0, 0}}, // (138, 132) + { 0, { 0, 0, 0}}, // (139, 132) + { 0, { 0, 0, 0}}, // (140, 132) + { 0, { 0, 0, 0}}, // (141, 132) + { 0, { 0, 0, 0}}, // (142, 132) + { 0, { 0, 0, 0}}, // (143, 132) + { 0, { 0, 0, 0}}, // (144, 132) + { 0, { 0, 0, 0}}, // (145, 132) + { 0, { 0, 0, 0}}, // (146, 132) + { 0, { 0, 0, 0}}, // (147, 132) + { 0, { 0, 0, 0}}, // (148, 132) + { 0, { 0, 0, 0}}, // (149, 132) + { 0, { 0, 0, 0}}, // (150, 132) + { 0, { 0, 0, 0}}, // (151, 132) + { 0, { 0, 0, 0}}, // (152, 132) + { 0, { 0, 0, 0}}, // (153, 132) + { 0, { 0, 0, 0}}, // (154, 132) + { 0, { 0, 0, 0}}, // (155, 132) + { 0, { 0, 0, 0}}, // (156, 132) + { 0, { 0, 0, 0}}, // (157, 132) + { 0, { 0, 0, 0}}, // (158, 132) + { 0, { 0, 0, 0}}, // (159, 132) + { 0, { 0, 0, 0}}, // (160, 132) + { 0, { 0, 0, 0}}, // (161, 132) + { 0, { 0, 0, 0}}, // (162, 132) + { 0, { 0, 0, 0}}, // (163, 132) + { 0, { 0, 0, 0}}, // (164, 132) + { 0, { 0, 0, 0}}, // (165, 132) + { 6, { 0, 0, 0}}, // (166, 132) + {114, { 0, 0, 0}}, // (167, 132) + {128, { 0, 0, 0}}, // (168, 132) + {128, { 0, 0, 0}}, // (169, 132) + {128, { 0, 0, 0}}, // (170, 132) + {128, { 0, 0, 0}}, // (171, 132) + {128, { 0, 0, 0}}, // (172, 132) + {128, { 0, 0, 0}}, // (173, 132) + {128, { 0, 0, 0}}, // (174, 132) + {128, { 0, 0, 0}}, // (175, 132) + {128, { 0, 0, 0}}, // (176, 132) + {128, { 0, 0, 0}}, // (177, 132) + {128, { 0, 0, 0}}, // (178, 132) + {128, { 0, 0, 0}}, // (179, 132) + {128, { 0, 0, 0}}, // ( 0, 133) + {128, { 0, 0, 0}}, // ( 1, 133) + {128, { 0, 0, 0}}, // ( 2, 133) + {128, { 0, 0, 0}}, // ( 3, 133) + {128, { 0, 0, 0}}, // ( 4, 133) + {128, { 0, 0, 0}}, // ( 5, 133) + {128, { 0, 0, 0}}, // ( 6, 133) + {128, { 0, 0, 0}}, // ( 7, 133) + {128, { 0, 0, 0}}, // ( 8, 133) + {128, { 0, 0, 0}}, // ( 9, 133) + {128, { 0, 0, 0}}, // ( 10, 133) + {128, { 0, 0, 0}}, // ( 11, 133) + {128, { 0, 0, 0}}, // ( 12, 133) + { 65, { 0, 0, 0}}, // ( 13, 133) + { 0, { 0, 0, 0}}, // ( 14, 133) + { 0, { 0, 0, 0}}, // ( 15, 133) + { 0, { 0, 0, 0}}, // ( 16, 133) + { 0, { 0, 0, 0}}, // ( 17, 133) + { 0, { 0, 0, 0}}, // ( 18, 133) + { 0, { 0, 0, 0}}, // ( 19, 133) + { 0, { 0, 0, 0}}, // ( 20, 133) + { 0, { 0, 0, 0}}, // ( 21, 133) + { 0, { 0, 0, 0}}, // ( 22, 133) + { 0, { 0, 0, 0}}, // ( 23, 133) + { 0, { 0, 0, 0}}, // ( 24, 133) + { 0, { 0, 0, 0}}, // ( 25, 133) + { 0, { 0, 0, 0}}, // ( 26, 133) + { 0, { 0, 0, 0}}, // ( 27, 133) + { 0, { 0, 0, 0}}, // ( 28, 133) + { 0, { 0, 0, 0}}, // ( 29, 133) + { 0, { 0, 0, 0}}, // ( 30, 133) + { 0, { 0, 0, 0}}, // ( 31, 133) + { 0, { 0, 0, 0}}, // ( 32, 133) + { 0, { 0, 0, 0}}, // ( 33, 133) + { 0, { 0, 0, 0}}, // ( 34, 133) + { 0, { 0, 0, 0}}, // ( 35, 133) + { 0, { 0, 0, 0}}, // ( 36, 133) + { 0, { 0, 0, 0}}, // ( 37, 133) + { 0, { 0, 0, 0}}, // ( 38, 133) + { 0, { 0, 0, 0}}, // ( 39, 133) + { 0, { 0, 0, 0}}, // ( 40, 133) + { 0, { 0, 0, 0}}, // ( 41, 133) + { 0, { 0, 0, 0}}, // ( 42, 133) + { 0, { 0, 0, 0}}, // ( 43, 133) + { 0, { 0, 0, 0}}, // ( 44, 133) + { 0, { 0, 0, 0}}, // ( 45, 133) + { 0, { 0, 0, 0}}, // ( 46, 133) + { 0, { 0, 0, 0}}, // ( 47, 133) + { 0, { 0, 0, 0}}, // ( 48, 133) + { 0, { 0, 0, 0}}, // ( 49, 133) + { 0, { 0, 0, 0}}, // ( 50, 133) + { 0, { 0, 0, 0}}, // ( 51, 133) + { 0, { 0, 0, 0}}, // ( 52, 133) + { 0, { 0, 0, 0}}, // ( 53, 133) + { 0, { 0, 0, 0}}, // ( 54, 133) + { 0, { 0, 0, 0}}, // ( 55, 133) + { 0, { 0, 0, 0}}, // ( 56, 133) + { 0, { 0, 0, 0}}, // ( 57, 133) + { 0, { 0, 0, 0}}, // ( 58, 133) + { 0, { 0, 0, 0}}, // ( 59, 133) + { 0, { 0, 0, 0}}, // ( 60, 133) + { 0, { 0, 0, 0}}, // ( 61, 133) + { 0, { 0, 0, 0}}, // ( 62, 133) + { 0, { 0, 0, 0}}, // ( 63, 133) + { 0, { 0, 0, 0}}, // ( 64, 133) + { 0, { 0, 0, 0}}, // ( 65, 133) + { 0, { 0, 0, 0}}, // ( 66, 133) + { 0, { 0, 0, 0}}, // ( 67, 133) + { 0, { 0, 0, 0}}, // ( 68, 133) + { 0, { 0, 0, 0}}, // ( 69, 133) + { 0, { 0, 0, 0}}, // ( 70, 133) + { 0, { 0, 0, 0}}, // ( 71, 133) + { 0, { 0, 0, 0}}, // ( 72, 133) + { 0, { 0, 0, 0}}, // ( 73, 133) + { 0, { 0, 0, 0}}, // ( 74, 133) + { 0, { 0, 0, 0}}, // ( 75, 133) + { 0, { 0, 0, 0}}, // ( 76, 133) + { 0, { 0, 0, 0}}, // ( 77, 133) + { 0, { 0, 0, 0}}, // ( 78, 133) + { 0, { 0, 0, 0}}, // ( 79, 133) + { 0, { 0, 0, 0}}, // ( 80, 133) + { 0, { 0, 0, 0}}, // ( 81, 133) + { 0, { 0, 0, 0}}, // ( 82, 133) + { 0, { 0, 0, 0}}, // ( 83, 133) + { 0, { 0, 0, 0}}, // ( 84, 133) + { 0, { 0, 0, 0}}, // ( 85, 133) + { 0, { 0, 0, 0}}, // ( 86, 133) + { 0, { 0, 0, 0}}, // ( 87, 133) + { 0, { 0, 0, 0}}, // ( 88, 133) + { 0, { 0, 0, 0}}, // ( 89, 133) + { 0, { 0, 0, 0}}, // ( 90, 133) + { 0, { 0, 0, 0}}, // ( 91, 133) + { 0, { 0, 0, 0}}, // ( 92, 133) + { 0, { 0, 0, 0}}, // ( 93, 133) + { 0, { 0, 0, 0}}, // ( 94, 133) + { 0, { 0, 0, 0}}, // ( 95, 133) + { 0, { 0, 0, 0}}, // ( 96, 133) + { 0, { 0, 0, 0}}, // ( 97, 133) + { 0, { 0, 0, 0}}, // ( 98, 133) + { 0, { 0, 0, 0}}, // ( 99, 133) + { 0, { 0, 0, 0}}, // (100, 133) + { 0, { 0, 0, 0}}, // (101, 133) + { 0, { 0, 0, 0}}, // (102, 133) + { 0, { 0, 0, 0}}, // (103, 133) + { 0, { 0, 0, 0}}, // (104, 133) + { 0, { 0, 0, 0}}, // (105, 133) + { 0, { 0, 0, 0}}, // (106, 133) + { 0, { 0, 0, 0}}, // (107, 133) + { 0, { 0, 0, 0}}, // (108, 133) + { 0, { 0, 0, 0}}, // (109, 133) + { 0, { 0, 0, 0}}, // (110, 133) + { 0, { 0, 0, 0}}, // (111, 133) + { 0, { 0, 0, 0}}, // (112, 133) + { 0, { 0, 0, 0}}, // (113, 133) + { 0, { 0, 0, 0}}, // (114, 133) + { 0, { 0, 0, 0}}, // (115, 133) + { 0, { 0, 0, 0}}, // (116, 133) + { 0, { 0, 0, 0}}, // (117, 133) + { 0, { 0, 0, 0}}, // (118, 133) + { 0, { 0, 0, 0}}, // (119, 133) + { 0, { 0, 0, 0}}, // (120, 133) + { 0, { 0, 0, 0}}, // (121, 133) + { 0, { 0, 0, 0}}, // (122, 133) + { 0, { 0, 0, 0}}, // (123, 133) + { 0, { 0, 0, 0}}, // (124, 133) + { 0, { 0, 0, 0}}, // (125, 133) + { 0, { 0, 0, 0}}, // (126, 133) + { 0, { 0, 0, 0}}, // (127, 133) + { 0, { 0, 0, 0}}, // (128, 133) + { 0, { 0, 0, 0}}, // (129, 133) + { 0, { 0, 0, 0}}, // (130, 133) + { 0, { 0, 0, 0}}, // (131, 133) + { 0, { 0, 0, 0}}, // (132, 133) + { 0, { 0, 0, 0}}, // (133, 133) + { 0, { 0, 0, 0}}, // (134, 133) + { 0, { 0, 0, 0}}, // (135, 133) + { 0, { 0, 0, 0}}, // (136, 133) + { 0, { 0, 0, 0}}, // (137, 133) + { 0, { 0, 0, 0}}, // (138, 133) + { 0, { 0, 0, 0}}, // (139, 133) + { 0, { 0, 0, 0}}, // (140, 133) + { 0, { 0, 0, 0}}, // (141, 133) + { 0, { 0, 0, 0}}, // (142, 133) + { 0, { 0, 0, 0}}, // (143, 133) + { 0, { 0, 0, 0}}, // (144, 133) + { 0, { 0, 0, 0}}, // (145, 133) + { 0, { 0, 0, 0}}, // (146, 133) + { 0, { 0, 0, 0}}, // (147, 133) + { 0, { 0, 0, 0}}, // (148, 133) + { 0, { 0, 0, 0}}, // (149, 133) + { 0, { 0, 0, 0}}, // (150, 133) + { 0, { 0, 0, 0}}, // (151, 133) + { 0, { 0, 0, 0}}, // (152, 133) + { 0, { 0, 0, 0}}, // (153, 133) + { 0, { 0, 0, 0}}, // (154, 133) + { 0, { 0, 0, 0}}, // (155, 133) + { 0, { 0, 0, 0}}, // (156, 133) + { 0, { 0, 0, 0}}, // (157, 133) + { 0, { 0, 0, 0}}, // (158, 133) + { 0, { 0, 0, 0}}, // (159, 133) + { 0, { 0, 0, 0}}, // (160, 133) + { 0, { 0, 0, 0}}, // (161, 133) + { 0, { 0, 0, 0}}, // (162, 133) + { 0, { 0, 0, 0}}, // (163, 133) + { 0, { 0, 0, 0}}, // (164, 133) + { 0, { 0, 0, 0}}, // (165, 133) + { 65, { 0, 0, 0}}, // (166, 133) + {128, { 0, 0, 0}}, // (167, 133) + {128, { 0, 0, 0}}, // (168, 133) + {128, { 0, 0, 0}}, // (169, 133) + {128, { 0, 0, 0}}, // (170, 133) + {128, { 0, 0, 0}}, // (171, 133) + {128, { 0, 0, 0}}, // (172, 133) + {128, { 0, 0, 0}}, // (173, 133) + {128, { 0, 0, 0}}, // (174, 133) + {128, { 0, 0, 0}}, // (175, 133) + {128, { 0, 0, 0}}, // (176, 133) + {128, { 0, 0, 0}}, // (177, 133) + {128, { 0, 0, 0}}, // (178, 133) + {128, { 0, 0, 0}}, // (179, 133) + {128, { 0, 0, 0}}, // ( 0, 134) + {128, { 0, 0, 0}}, // ( 1, 134) + {128, { 0, 0, 0}}, // ( 2, 134) + {128, { 0, 0, 0}}, // ( 3, 134) + {128, { 0, 0, 0}}, // ( 4, 134) + {128, { 0, 0, 0}}, // ( 5, 134) + {128, { 0, 0, 0}}, // ( 6, 134) + {128, { 0, 0, 0}}, // ( 7, 134) + {128, { 0, 0, 0}}, // ( 8, 134) + {128, { 0, 0, 0}}, // ( 9, 134) + {128, { 0, 0, 0}}, // ( 10, 134) + {128, { 0, 0, 0}}, // ( 11, 134) + {128, { 0, 0, 0}}, // ( 12, 134) + {124, { 0, 0, 0}}, // ( 13, 134) + { 15, { 0, 0, 0}}, // ( 14, 134) + { 0, { 0, 0, 0}}, // ( 15, 134) + { 0, { 0, 0, 0}}, // ( 16, 134) + { 0, { 0, 0, 0}}, // ( 17, 134) + { 0, { 0, 0, 0}}, // ( 18, 134) + { 0, { 0, 0, 0}}, // ( 19, 134) + { 0, { 0, 0, 0}}, // ( 20, 134) + { 0, { 0, 0, 0}}, // ( 21, 134) + { 0, { 0, 0, 0}}, // ( 22, 134) + { 0, { 0, 0, 0}}, // ( 23, 134) + { 0, { 0, 0, 0}}, // ( 24, 134) + { 0, { 0, 0, 0}}, // ( 25, 134) + { 0, { 0, 0, 0}}, // ( 26, 134) + { 0, { 0, 0, 0}}, // ( 27, 134) + { 0, { 0, 0, 0}}, // ( 28, 134) + { 0, { 0, 0, 0}}, // ( 29, 134) + { 0, { 0, 0, 0}}, // ( 30, 134) + { 0, { 0, 0, 0}}, // ( 31, 134) + { 0, { 0, 0, 0}}, // ( 32, 134) + { 0, { 0, 0, 0}}, // ( 33, 134) + { 0, { 0, 0, 0}}, // ( 34, 134) + { 0, { 0, 0, 0}}, // ( 35, 134) + { 0, { 0, 0, 0}}, // ( 36, 134) + { 0, { 0, 0, 0}}, // ( 37, 134) + { 0, { 0, 0, 0}}, // ( 38, 134) + { 0, { 0, 0, 0}}, // ( 39, 134) + { 0, { 0, 0, 0}}, // ( 40, 134) + { 0, { 0, 0, 0}}, // ( 41, 134) + { 0, { 0, 0, 0}}, // ( 42, 134) + { 0, { 0, 0, 0}}, // ( 43, 134) + { 0, { 0, 0, 0}}, // ( 44, 134) + { 0, { 0, 0, 0}}, // ( 45, 134) + { 0, { 0, 0, 0}}, // ( 46, 134) + { 0, { 0, 0, 0}}, // ( 47, 134) + { 0, { 0, 0, 0}}, // ( 48, 134) + { 0, { 0, 0, 0}}, // ( 49, 134) + { 0, { 0, 0, 0}}, // ( 50, 134) + { 0, { 0, 0, 0}}, // ( 51, 134) + { 0, { 0, 0, 0}}, // ( 52, 134) + { 0, { 0, 0, 0}}, // ( 53, 134) + { 0, { 0, 0, 0}}, // ( 54, 134) + { 0, { 0, 0, 0}}, // ( 55, 134) + { 0, { 0, 0, 0}}, // ( 56, 134) + { 0, { 0, 0, 0}}, // ( 57, 134) + { 0, { 0, 0, 0}}, // ( 58, 134) + { 0, { 0, 0, 0}}, // ( 59, 134) + { 0, { 0, 0, 0}}, // ( 60, 134) + { 0, { 0, 0, 0}}, // ( 61, 134) + { 0, { 0, 0, 0}}, // ( 62, 134) + { 0, { 0, 0, 0}}, // ( 63, 134) + { 0, { 0, 0, 0}}, // ( 64, 134) + { 0, { 0, 0, 0}}, // ( 65, 134) + { 0, { 0, 0, 0}}, // ( 66, 134) + { 0, { 0, 0, 0}}, // ( 67, 134) + { 0, { 0, 0, 0}}, // ( 68, 134) + { 0, { 0, 0, 0}}, // ( 69, 134) + { 0, { 0, 0, 0}}, // ( 70, 134) + { 0, { 0, 0, 0}}, // ( 71, 134) + { 0, { 0, 0, 0}}, // ( 72, 134) + { 0, { 0, 0, 0}}, // ( 73, 134) + { 0, { 0, 0, 0}}, // ( 74, 134) + { 0, { 0, 0, 0}}, // ( 75, 134) + { 0, { 0, 0, 0}}, // ( 76, 134) + { 0, { 0, 0, 0}}, // ( 77, 134) + { 0, { 0, 0, 0}}, // ( 78, 134) + { 0, { 0, 0, 0}}, // ( 79, 134) + { 0, { 0, 0, 0}}, // ( 80, 134) + { 0, { 0, 0, 0}}, // ( 81, 134) + { 0, { 0, 0, 0}}, // ( 82, 134) + { 0, { 0, 0, 0}}, // ( 83, 134) + { 0, { 0, 0, 0}}, // ( 84, 134) + { 0, { 0, 0, 0}}, // ( 85, 134) + { 0, { 0, 0, 0}}, // ( 86, 134) + { 0, { 0, 0, 0}}, // ( 87, 134) + { 0, { 0, 0, 0}}, // ( 88, 134) + { 0, { 0, 0, 0}}, // ( 89, 134) + { 0, { 0, 0, 0}}, // ( 90, 134) + { 0, { 0, 0, 0}}, // ( 91, 134) + { 0, { 0, 0, 0}}, // ( 92, 134) + { 0, { 0, 0, 0}}, // ( 93, 134) + { 0, { 0, 0, 0}}, // ( 94, 134) + { 0, { 0, 0, 0}}, // ( 95, 134) + { 0, { 0, 0, 0}}, // ( 96, 134) + { 0, { 0, 0, 0}}, // ( 97, 134) + { 0, { 0, 0, 0}}, // ( 98, 134) + { 0, { 0, 0, 0}}, // ( 99, 134) + { 0, { 0, 0, 0}}, // (100, 134) + { 0, { 0, 0, 0}}, // (101, 134) + { 0, { 0, 0, 0}}, // (102, 134) + { 0, { 0, 0, 0}}, // (103, 134) + { 0, { 0, 0, 0}}, // (104, 134) + { 0, { 0, 0, 0}}, // (105, 134) + { 0, { 0, 0, 0}}, // (106, 134) + { 0, { 0, 0, 0}}, // (107, 134) + { 0, { 0, 0, 0}}, // (108, 134) + { 0, { 0, 0, 0}}, // (109, 134) + { 0, { 0, 0, 0}}, // (110, 134) + { 0, { 0, 0, 0}}, // (111, 134) + { 0, { 0, 0, 0}}, // (112, 134) + { 0, { 0, 0, 0}}, // (113, 134) + { 0, { 0, 0, 0}}, // (114, 134) + { 0, { 0, 0, 0}}, // (115, 134) + { 0, { 0, 0, 0}}, // (116, 134) + { 0, { 0, 0, 0}}, // (117, 134) + { 0, { 0, 0, 0}}, // (118, 134) + { 0, { 0, 0, 0}}, // (119, 134) + { 0, { 0, 0, 0}}, // (120, 134) + { 0, { 0, 0, 0}}, // (121, 134) + { 0, { 0, 0, 0}}, // (122, 134) + { 0, { 0, 0, 0}}, // (123, 134) + { 0, { 0, 0, 0}}, // (124, 134) + { 0, { 0, 0, 0}}, // (125, 134) + { 0, { 0, 0, 0}}, // (126, 134) + { 0, { 0, 0, 0}}, // (127, 134) + { 0, { 0, 0, 0}}, // (128, 134) + { 0, { 0, 0, 0}}, // (129, 134) + { 0, { 0, 0, 0}}, // (130, 134) + { 0, { 0, 0, 0}}, // (131, 134) + { 0, { 0, 0, 0}}, // (132, 134) + { 0, { 0, 0, 0}}, // (133, 134) + { 0, { 0, 0, 0}}, // (134, 134) + { 0, { 0, 0, 0}}, // (135, 134) + { 0, { 0, 0, 0}}, // (136, 134) + { 0, { 0, 0, 0}}, // (137, 134) + { 0, { 0, 0, 0}}, // (138, 134) + { 0, { 0, 0, 0}}, // (139, 134) + { 0, { 0, 0, 0}}, // (140, 134) + { 0, { 0, 0, 0}}, // (141, 134) + { 0, { 0, 0, 0}}, // (142, 134) + { 0, { 0, 0, 0}}, // (143, 134) + { 0, { 0, 0, 0}}, // (144, 134) + { 0, { 0, 0, 0}}, // (145, 134) + { 0, { 0, 0, 0}}, // (146, 134) + { 0, { 0, 0, 0}}, // (147, 134) + { 0, { 0, 0, 0}}, // (148, 134) + { 0, { 0, 0, 0}}, // (149, 134) + { 0, { 0, 0, 0}}, // (150, 134) + { 0, { 0, 0, 0}}, // (151, 134) + { 0, { 0, 0, 0}}, // (152, 134) + { 0, { 0, 0, 0}}, // (153, 134) + { 0, { 0, 0, 0}}, // (154, 134) + { 0, { 0, 0, 0}}, // (155, 134) + { 0, { 0, 0, 0}}, // (156, 134) + { 0, { 0, 0, 0}}, // (157, 134) + { 0, { 0, 0, 0}}, // (158, 134) + { 0, { 0, 0, 0}}, // (159, 134) + { 0, { 0, 0, 0}}, // (160, 134) + { 0, { 0, 0, 0}}, // (161, 134) + { 0, { 0, 0, 0}}, // (162, 134) + { 0, { 0, 0, 0}}, // (163, 134) + { 0, { 0, 0, 0}}, // (164, 134) + { 15, { 0, 0, 0}}, // (165, 134) + {124, { 0, 0, 0}}, // (166, 134) + {128, { 0, 0, 0}}, // (167, 134) + {128, { 0, 0, 0}}, // (168, 134) + {128, { 0, 0, 0}}, // (169, 134) + {128, { 0, 0, 0}}, // (170, 134) + {128, { 0, 0, 0}}, // (171, 134) + {128, { 0, 0, 0}}, // (172, 134) + {128, { 0, 0, 0}}, // (173, 134) + {128, { 0, 0, 0}}, // (174, 134) + {128, { 0, 0, 0}}, // (175, 134) + {128, { 0, 0, 0}}, // (176, 134) + {128, { 0, 0, 0}}, // (177, 134) + {128, { 0, 0, 0}}, // (178, 134) + {128, { 0, 0, 0}}, // (179, 134) + {128, { 0, 0, 0}}, // ( 0, 135) + {128, { 0, 0, 0}}, // ( 1, 135) + {128, { 0, 0, 0}}, // ( 2, 135) + {128, { 0, 0, 0}}, // ( 3, 135) + {128, { 0, 0, 0}}, // ( 4, 135) + {128, { 0, 0, 0}}, // ( 5, 135) + {128, { 0, 0, 0}}, // ( 6, 135) + {128, { 0, 0, 0}}, // ( 7, 135) + {128, { 0, 0, 0}}, // ( 8, 135) + {128, { 0, 0, 0}}, // ( 9, 135) + {128, { 0, 0, 0}}, // ( 10, 135) + {128, { 0, 0, 0}}, // ( 11, 135) + {128, { 0, 0, 0}}, // ( 12, 135) + {128, { 0, 0, 0}}, // ( 13, 135) + { 85, { 0, 0, 0}}, // ( 14, 135) + { 0, { 0, 0, 0}}, // ( 15, 135) + { 0, { 0, 0, 0}}, // ( 16, 135) + { 0, { 0, 0, 0}}, // ( 17, 135) + { 0, { 0, 0, 0}}, // ( 18, 135) + { 0, { 0, 0, 0}}, // ( 19, 135) + { 0, { 0, 0, 0}}, // ( 20, 135) + { 0, { 0, 0, 0}}, // ( 21, 135) + { 0, { 0, 0, 0}}, // ( 22, 135) + { 0, { 0, 0, 0}}, // ( 23, 135) + { 0, { 0, 0, 0}}, // ( 24, 135) + { 0, { 0, 0, 0}}, // ( 25, 135) + { 0, { 0, 0, 0}}, // ( 26, 135) + { 0, { 0, 0, 0}}, // ( 27, 135) + { 0, { 0, 0, 0}}, // ( 28, 135) + { 0, { 0, 0, 0}}, // ( 29, 135) + { 0, { 0, 0, 0}}, // ( 30, 135) + { 0, { 0, 0, 0}}, // ( 31, 135) + { 0, { 0, 0, 0}}, // ( 32, 135) + { 0, { 0, 0, 0}}, // ( 33, 135) + { 0, { 0, 0, 0}}, // ( 34, 135) + { 0, { 0, 0, 0}}, // ( 35, 135) + { 0, { 0, 0, 0}}, // ( 36, 135) + { 0, { 0, 0, 0}}, // ( 37, 135) + { 0, { 0, 0, 0}}, // ( 38, 135) + { 0, { 0, 0, 0}}, // ( 39, 135) + { 0, { 0, 0, 0}}, // ( 40, 135) + { 0, { 0, 0, 0}}, // ( 41, 135) + { 0, { 0, 0, 0}}, // ( 42, 135) + { 0, { 0, 0, 0}}, // ( 43, 135) + { 0, { 0, 0, 0}}, // ( 44, 135) + { 0, { 0, 0, 0}}, // ( 45, 135) + { 0, { 0, 0, 0}}, // ( 46, 135) + { 0, { 0, 0, 0}}, // ( 47, 135) + { 0, { 0, 0, 0}}, // ( 48, 135) + { 0, { 0, 0, 0}}, // ( 49, 135) + { 0, { 0, 0, 0}}, // ( 50, 135) + { 0, { 0, 0, 0}}, // ( 51, 135) + { 0, { 0, 0, 0}}, // ( 52, 135) + { 0, { 0, 0, 0}}, // ( 53, 135) + { 0, { 0, 0, 0}}, // ( 54, 135) + { 0, { 0, 0, 0}}, // ( 55, 135) + { 0, { 0, 0, 0}}, // ( 56, 135) + { 0, { 0, 0, 0}}, // ( 57, 135) + { 0, { 0, 0, 0}}, // ( 58, 135) + { 0, { 0, 0, 0}}, // ( 59, 135) + { 0, { 0, 0, 0}}, // ( 60, 135) + { 0, { 0, 0, 0}}, // ( 61, 135) + { 0, { 0, 0, 0}}, // ( 62, 135) + { 0, { 0, 0, 0}}, // ( 63, 135) + { 0, { 0, 0, 0}}, // ( 64, 135) + { 0, { 0, 0, 0}}, // ( 65, 135) + { 0, { 0, 0, 0}}, // ( 66, 135) + { 0, { 0, 0, 0}}, // ( 67, 135) + { 0, { 0, 0, 0}}, // ( 68, 135) + { 0, { 0, 0, 0}}, // ( 69, 135) + { 0, { 0, 0, 0}}, // ( 70, 135) + { 0, { 0, 0, 0}}, // ( 71, 135) + { 0, { 0, 0, 0}}, // ( 72, 135) + { 0, { 0, 0, 0}}, // ( 73, 135) + { 0, { 0, 0, 0}}, // ( 74, 135) + { 0, { 0, 0, 0}}, // ( 75, 135) + { 0, { 0, 0, 0}}, // ( 76, 135) + { 0, { 0, 0, 0}}, // ( 77, 135) + { 0, { 0, 0, 0}}, // ( 78, 135) + { 0, { 0, 0, 0}}, // ( 79, 135) + { 0, { 0, 0, 0}}, // ( 80, 135) + { 0, { 0, 0, 0}}, // ( 81, 135) + { 0, { 0, 0, 0}}, // ( 82, 135) + { 0, { 0, 0, 0}}, // ( 83, 135) + { 0, { 0, 0, 0}}, // ( 84, 135) + { 0, { 0, 0, 0}}, // ( 85, 135) + { 0, { 0, 0, 0}}, // ( 86, 135) + { 0, { 0, 0, 0}}, // ( 87, 135) + { 0, { 0, 0, 0}}, // ( 88, 135) + { 0, { 0, 0, 0}}, // ( 89, 135) + { 0, { 0, 0, 0}}, // ( 90, 135) + { 0, { 0, 0, 0}}, // ( 91, 135) + { 0, { 0, 0, 0}}, // ( 92, 135) + { 0, { 0, 0, 0}}, // ( 93, 135) + { 0, { 0, 0, 0}}, // ( 94, 135) + { 0, { 0, 0, 0}}, // ( 95, 135) + { 0, { 0, 0, 0}}, // ( 96, 135) + { 0, { 0, 0, 0}}, // ( 97, 135) + { 0, { 0, 0, 0}}, // ( 98, 135) + { 0, { 0, 0, 0}}, // ( 99, 135) + { 0, { 0, 0, 0}}, // (100, 135) + { 0, { 0, 0, 0}}, // (101, 135) + { 0, { 0, 0, 0}}, // (102, 135) + { 0, { 0, 0, 0}}, // (103, 135) + { 0, { 0, 0, 0}}, // (104, 135) + { 0, { 0, 0, 0}}, // (105, 135) + { 0, { 0, 0, 0}}, // (106, 135) + { 0, { 0, 0, 0}}, // (107, 135) + { 0, { 0, 0, 0}}, // (108, 135) + { 0, { 0, 0, 0}}, // (109, 135) + { 0, { 0, 0, 0}}, // (110, 135) + { 0, { 0, 0, 0}}, // (111, 135) + { 0, { 0, 0, 0}}, // (112, 135) + { 0, { 0, 0, 0}}, // (113, 135) + { 0, { 0, 0, 0}}, // (114, 135) + { 0, { 0, 0, 0}}, // (115, 135) + { 0, { 0, 0, 0}}, // (116, 135) + { 0, { 0, 0, 0}}, // (117, 135) + { 0, { 0, 0, 0}}, // (118, 135) + { 0, { 0, 0, 0}}, // (119, 135) + { 0, { 0, 0, 0}}, // (120, 135) + { 0, { 0, 0, 0}}, // (121, 135) + { 0, { 0, 0, 0}}, // (122, 135) + { 0, { 0, 0, 0}}, // (123, 135) + { 0, { 0, 0, 0}}, // (124, 135) + { 0, { 0, 0, 0}}, // (125, 135) + { 0, { 0, 0, 0}}, // (126, 135) + { 0, { 0, 0, 0}}, // (127, 135) + { 0, { 0, 0, 0}}, // (128, 135) + { 0, { 0, 0, 0}}, // (129, 135) + { 0, { 0, 0, 0}}, // (130, 135) + { 0, { 0, 0, 0}}, // (131, 135) + { 0, { 0, 0, 0}}, // (132, 135) + { 0, { 0, 0, 0}}, // (133, 135) + { 0, { 0, 0, 0}}, // (134, 135) + { 0, { 0, 0, 0}}, // (135, 135) + { 0, { 0, 0, 0}}, // (136, 135) + { 0, { 0, 0, 0}}, // (137, 135) + { 0, { 0, 0, 0}}, // (138, 135) + { 0, { 0, 0, 0}}, // (139, 135) + { 0, { 0, 0, 0}}, // (140, 135) + { 0, { 0, 0, 0}}, // (141, 135) + { 0, { 0, 0, 0}}, // (142, 135) + { 0, { 0, 0, 0}}, // (143, 135) + { 0, { 0, 0, 0}}, // (144, 135) + { 0, { 0, 0, 0}}, // (145, 135) + { 0, { 0, 0, 0}}, // (146, 135) + { 0, { 0, 0, 0}}, // (147, 135) + { 0, { 0, 0, 0}}, // (148, 135) + { 0, { 0, 0, 0}}, // (149, 135) + { 0, { 0, 0, 0}}, // (150, 135) + { 0, { 0, 0, 0}}, // (151, 135) + { 0, { 0, 0, 0}}, // (152, 135) + { 0, { 0, 0, 0}}, // (153, 135) + { 0, { 0, 0, 0}}, // (154, 135) + { 0, { 0, 0, 0}}, // (155, 135) + { 0, { 0, 0, 0}}, // (156, 135) + { 0, { 0, 0, 0}}, // (157, 135) + { 0, { 0, 0, 0}}, // (158, 135) + { 0, { 0, 0, 0}}, // (159, 135) + { 0, { 0, 0, 0}}, // (160, 135) + { 0, { 0, 0, 0}}, // (161, 135) + { 0, { 0, 0, 0}}, // (162, 135) + { 0, { 0, 0, 0}}, // (163, 135) + { 0, { 0, 0, 0}}, // (164, 135) + { 85, { 0, 0, 0}}, // (165, 135) + {128, { 0, 0, 0}}, // (166, 135) + {128, { 0, 0, 0}}, // (167, 135) + {128, { 0, 0, 0}}, // (168, 135) + {128, { 0, 0, 0}}, // (169, 135) + {128, { 0, 0, 0}}, // (170, 135) + {128, { 0, 0, 0}}, // (171, 135) + {128, { 0, 0, 0}}, // (172, 135) + {128, { 0, 0, 0}}, // (173, 135) + {128, { 0, 0, 0}}, // (174, 135) + {128, { 0, 0, 0}}, // (175, 135) + {128, { 0, 0, 0}}, // (176, 135) + {128, { 0, 0, 0}}, // (177, 135) + {128, { 0, 0, 0}}, // (178, 135) + {128, { 0, 0, 0}}, // (179, 135) + {128, { 0, 0, 0}}, // ( 0, 136) + {128, { 0, 0, 0}}, // ( 1, 136) + {128, { 0, 0, 0}}, // ( 2, 136) + {128, { 0, 0, 0}}, // ( 3, 136) + {128, { 0, 0, 0}}, // ( 4, 136) + {128, { 0, 0, 0}}, // ( 5, 136) + {128, { 0, 0, 0}}, // ( 6, 136) + {128, { 0, 0, 0}}, // ( 7, 136) + {128, { 0, 0, 0}}, // ( 8, 136) + {128, { 0, 0, 0}}, // ( 9, 136) + {128, { 0, 0, 0}}, // ( 10, 136) + {128, { 0, 0, 0}}, // ( 11, 136) + {128, { 0, 0, 0}}, // ( 12, 136) + {128, { 0, 0, 0}}, // ( 13, 136) + {128, { 0, 0, 0}}, // ( 14, 136) + { 38, { 0, 0, 0}}, // ( 15, 136) + { 0, { 0, 0, 0}}, // ( 16, 136) + { 0, { 0, 0, 0}}, // ( 17, 136) + { 0, { 0, 0, 0}}, // ( 18, 136) + { 0, { 0, 0, 0}}, // ( 19, 136) + { 0, { 0, 0, 0}}, // ( 20, 136) + { 0, { 0, 0, 0}}, // ( 21, 136) + { 0, { 0, 0, 0}}, // ( 22, 136) + { 0, { 0, 0, 0}}, // ( 23, 136) + { 0, { 0, 0, 0}}, // ( 24, 136) + { 0, { 0, 0, 0}}, // ( 25, 136) + { 0, { 0, 0, 0}}, // ( 26, 136) + { 0, { 0, 0, 0}}, // ( 27, 136) + { 0, { 0, 0, 0}}, // ( 28, 136) + { 0, { 0, 0, 0}}, // ( 29, 136) + { 0, { 0, 0, 0}}, // ( 30, 136) + { 0, { 0, 0, 0}}, // ( 31, 136) + { 0, { 0, 0, 0}}, // ( 32, 136) + { 0, { 0, 0, 0}}, // ( 33, 136) + { 0, { 0, 0, 0}}, // ( 34, 136) + { 0, { 0, 0, 0}}, // ( 35, 136) + { 0, { 0, 0, 0}}, // ( 36, 136) + { 0, { 0, 0, 0}}, // ( 37, 136) + { 0, { 0, 0, 0}}, // ( 38, 136) + { 0, { 0, 0, 0}}, // ( 39, 136) + { 0, { 0, 0, 0}}, // ( 40, 136) + { 0, { 0, 0, 0}}, // ( 41, 136) + { 0, { 0, 0, 0}}, // ( 42, 136) + { 0, { 0, 0, 0}}, // ( 43, 136) + { 0, { 0, 0, 0}}, // ( 44, 136) + { 0, { 0, 0, 0}}, // ( 45, 136) + { 0, { 0, 0, 0}}, // ( 46, 136) + { 0, { 0, 0, 0}}, // ( 47, 136) + { 0, { 0, 0, 0}}, // ( 48, 136) + { 0, { 0, 0, 0}}, // ( 49, 136) + { 0, { 0, 0, 0}}, // ( 50, 136) + { 0, { 0, 0, 0}}, // ( 51, 136) + { 0, { 0, 0, 0}}, // ( 52, 136) + { 0, { 0, 0, 0}}, // ( 53, 136) + { 0, { 0, 0, 0}}, // ( 54, 136) + { 0, { 0, 0, 0}}, // ( 55, 136) + { 0, { 0, 0, 0}}, // ( 56, 136) + { 0, { 0, 0, 0}}, // ( 57, 136) + { 0, { 0, 0, 0}}, // ( 58, 136) + { 0, { 0, 0, 0}}, // ( 59, 136) + { 0, { 0, 0, 0}}, // ( 60, 136) + { 0, { 0, 0, 0}}, // ( 61, 136) + { 0, { 0, 0, 0}}, // ( 62, 136) + { 0, { 0, 0, 0}}, // ( 63, 136) + { 0, { 0, 0, 0}}, // ( 64, 136) + { 0, { 0, 0, 0}}, // ( 65, 136) + { 0, { 0, 0, 0}}, // ( 66, 136) + { 0, { 0, 0, 0}}, // ( 67, 136) + { 0, { 0, 0, 0}}, // ( 68, 136) + { 0, { 0, 0, 0}}, // ( 69, 136) + { 0, { 0, 0, 0}}, // ( 70, 136) + { 0, { 0, 0, 0}}, // ( 71, 136) + { 0, { 0, 0, 0}}, // ( 72, 136) + { 0, { 0, 0, 0}}, // ( 73, 136) + { 0, { 0, 0, 0}}, // ( 74, 136) + { 0, { 0, 0, 0}}, // ( 75, 136) + { 0, { 0, 0, 0}}, // ( 76, 136) + { 0, { 0, 0, 0}}, // ( 77, 136) + { 0, { 0, 0, 0}}, // ( 78, 136) + { 0, { 0, 0, 0}}, // ( 79, 136) + { 0, { 0, 0, 0}}, // ( 80, 136) + { 0, { 0, 0, 0}}, // ( 81, 136) + { 0, { 0, 0, 0}}, // ( 82, 136) + { 0, { 0, 0, 0}}, // ( 83, 136) + { 0, { 0, 0, 0}}, // ( 84, 136) + { 0, { 0, 0, 0}}, // ( 85, 136) + { 0, { 0, 0, 0}}, // ( 86, 136) + { 0, { 0, 0, 0}}, // ( 87, 136) + { 0, { 0, 0, 0}}, // ( 88, 136) + { 0, { 0, 0, 0}}, // ( 89, 136) + { 0, { 0, 0, 0}}, // ( 90, 136) + { 0, { 0, 0, 0}}, // ( 91, 136) + { 0, { 0, 0, 0}}, // ( 92, 136) + { 0, { 0, 0, 0}}, // ( 93, 136) + { 0, { 0, 0, 0}}, // ( 94, 136) + { 0, { 0, 0, 0}}, // ( 95, 136) + { 0, { 0, 0, 0}}, // ( 96, 136) + { 0, { 0, 0, 0}}, // ( 97, 136) + { 0, { 0, 0, 0}}, // ( 98, 136) + { 0, { 0, 0, 0}}, // ( 99, 136) + { 0, { 0, 0, 0}}, // (100, 136) + { 0, { 0, 0, 0}}, // (101, 136) + { 0, { 0, 0, 0}}, // (102, 136) + { 0, { 0, 0, 0}}, // (103, 136) + { 0, { 0, 0, 0}}, // (104, 136) + { 0, { 0, 0, 0}}, // (105, 136) + { 0, { 0, 0, 0}}, // (106, 136) + { 0, { 0, 0, 0}}, // (107, 136) + { 0, { 0, 0, 0}}, // (108, 136) + { 0, { 0, 0, 0}}, // (109, 136) + { 0, { 0, 0, 0}}, // (110, 136) + { 0, { 0, 0, 0}}, // (111, 136) + { 0, { 0, 0, 0}}, // (112, 136) + { 0, { 0, 0, 0}}, // (113, 136) + { 0, { 0, 0, 0}}, // (114, 136) + { 0, { 0, 0, 0}}, // (115, 136) + { 0, { 0, 0, 0}}, // (116, 136) + { 0, { 0, 0, 0}}, // (117, 136) + { 0, { 0, 0, 0}}, // (118, 136) + { 0, { 0, 0, 0}}, // (119, 136) + { 0, { 0, 0, 0}}, // (120, 136) + { 0, { 0, 0, 0}}, // (121, 136) + { 0, { 0, 0, 0}}, // (122, 136) + { 0, { 0, 0, 0}}, // (123, 136) + { 0, { 0, 0, 0}}, // (124, 136) + { 0, { 0, 0, 0}}, // (125, 136) + { 0, { 0, 0, 0}}, // (126, 136) + { 0, { 0, 0, 0}}, // (127, 136) + { 0, { 0, 0, 0}}, // (128, 136) + { 0, { 0, 0, 0}}, // (129, 136) + { 0, { 0, 0, 0}}, // (130, 136) + { 0, { 0, 0, 0}}, // (131, 136) + { 0, { 0, 0, 0}}, // (132, 136) + { 0, { 0, 0, 0}}, // (133, 136) + { 0, { 0, 0, 0}}, // (134, 136) + { 0, { 0, 0, 0}}, // (135, 136) + { 0, { 0, 0, 0}}, // (136, 136) + { 0, { 0, 0, 0}}, // (137, 136) + { 0, { 0, 0, 0}}, // (138, 136) + { 0, { 0, 0, 0}}, // (139, 136) + { 0, { 0, 0, 0}}, // (140, 136) + { 0, { 0, 0, 0}}, // (141, 136) + { 0, { 0, 0, 0}}, // (142, 136) + { 0, { 0, 0, 0}}, // (143, 136) + { 0, { 0, 0, 0}}, // (144, 136) + { 0, { 0, 0, 0}}, // (145, 136) + { 0, { 0, 0, 0}}, // (146, 136) + { 0, { 0, 0, 0}}, // (147, 136) + { 0, { 0, 0, 0}}, // (148, 136) + { 0, { 0, 0, 0}}, // (149, 136) + { 0, { 0, 0, 0}}, // (150, 136) + { 0, { 0, 0, 0}}, // (151, 136) + { 0, { 0, 0, 0}}, // (152, 136) + { 0, { 0, 0, 0}}, // (153, 136) + { 0, { 0, 0, 0}}, // (154, 136) + { 0, { 0, 0, 0}}, // (155, 136) + { 0, { 0, 0, 0}}, // (156, 136) + { 0, { 0, 0, 0}}, // (157, 136) + { 0, { 0, 0, 0}}, // (158, 136) + { 0, { 0, 0, 0}}, // (159, 136) + { 0, { 0, 0, 0}}, // (160, 136) + { 0, { 0, 0, 0}}, // (161, 136) + { 0, { 0, 0, 0}}, // (162, 136) + { 0, { 0, 0, 0}}, // (163, 136) + { 38, { 0, 0, 0}}, // (164, 136) + {128, { 0, 0, 0}}, // (165, 136) + {128, { 0, 0, 0}}, // (166, 136) + {128, { 0, 0, 0}}, // (167, 136) + {128, { 0, 0, 0}}, // (168, 136) + {128, { 0, 0, 0}}, // (169, 136) + {128, { 0, 0, 0}}, // (170, 136) + {128, { 0, 0, 0}}, // (171, 136) + {128, { 0, 0, 0}}, // (172, 136) + {128, { 0, 0, 0}}, // (173, 136) + {128, { 0, 0, 0}}, // (174, 136) + {128, { 0, 0, 0}}, // (175, 136) + {128, { 0, 0, 0}}, // (176, 136) + {128, { 0, 0, 0}}, // (177, 136) + {128, { 0, 0, 0}}, // (178, 136) + {128, { 0, 0, 0}}, // (179, 136) + {128, { 0, 0, 0}}, // ( 0, 137) + {128, { 0, 0, 0}}, // ( 1, 137) + {128, { 0, 0, 0}}, // ( 2, 137) + {128, { 0, 0, 0}}, // ( 3, 137) + {128, { 0, 0, 0}}, // ( 4, 137) + {128, { 0, 0, 0}}, // ( 5, 137) + {128, { 0, 0, 0}}, // ( 6, 137) + {128, { 0, 0, 0}}, // ( 7, 137) + {128, { 0, 0, 0}}, // ( 8, 137) + {128, { 0, 0, 0}}, // ( 9, 137) + {128, { 0, 0, 0}}, // ( 10, 137) + {128, { 0, 0, 0}}, // ( 11, 137) + {128, { 0, 0, 0}}, // ( 12, 137) + {128, { 0, 0, 0}}, // ( 13, 137) + {128, { 0, 0, 0}}, // ( 14, 137) + {113, { 0, 0, 0}}, // ( 15, 137) + { 7, { 0, 0, 0}}, // ( 16, 137) + { 0, { 0, 0, 0}}, // ( 17, 137) + { 0, { 0, 0, 0}}, // ( 18, 137) + { 0, { 0, 0, 0}}, // ( 19, 137) + { 0, { 0, 0, 0}}, // ( 20, 137) + { 0, { 0, 0, 0}}, // ( 21, 137) + { 0, { 0, 0, 0}}, // ( 22, 137) + { 0, { 0, 0, 0}}, // ( 23, 137) + { 0, { 0, 0, 0}}, // ( 24, 137) + { 0, { 0, 0, 0}}, // ( 25, 137) + { 0, { 0, 0, 0}}, // ( 26, 137) + { 0, { 0, 0, 0}}, // ( 27, 137) + { 0, { 0, 0, 0}}, // ( 28, 137) + { 0, { 0, 0, 0}}, // ( 29, 137) + { 0, { 0, 0, 0}}, // ( 30, 137) + { 0, { 0, 0, 0}}, // ( 31, 137) + { 0, { 0, 0, 0}}, // ( 32, 137) + { 0, { 0, 0, 0}}, // ( 33, 137) + { 0, { 0, 0, 0}}, // ( 34, 137) + { 0, { 0, 0, 0}}, // ( 35, 137) + { 0, { 0, 0, 0}}, // ( 36, 137) + { 0, { 0, 0, 0}}, // ( 37, 137) + { 0, { 0, 0, 0}}, // ( 38, 137) + { 0, { 0, 0, 0}}, // ( 39, 137) + { 0, { 0, 0, 0}}, // ( 40, 137) + { 0, { 0, 0, 0}}, // ( 41, 137) + { 0, { 0, 0, 0}}, // ( 42, 137) + { 0, { 0, 0, 0}}, // ( 43, 137) + { 0, { 0, 0, 0}}, // ( 44, 137) + { 0, { 0, 0, 0}}, // ( 45, 137) + { 0, { 0, 0, 0}}, // ( 46, 137) + { 0, { 0, 0, 0}}, // ( 47, 137) + { 0, { 0, 0, 0}}, // ( 48, 137) + { 0, { 0, 0, 0}}, // ( 49, 137) + { 0, { 0, 0, 0}}, // ( 50, 137) + { 0, { 0, 0, 0}}, // ( 51, 137) + { 0, { 0, 0, 0}}, // ( 52, 137) + { 0, { 0, 0, 0}}, // ( 53, 137) + { 0, { 0, 0, 0}}, // ( 54, 137) + { 0, { 0, 0, 0}}, // ( 55, 137) + { 0, { 0, 0, 0}}, // ( 56, 137) + { 0, { 0, 0, 0}}, // ( 57, 137) + { 0, { 0, 0, 0}}, // ( 58, 137) + { 0, { 0, 0, 0}}, // ( 59, 137) + { 0, { 0, 0, 0}}, // ( 60, 137) + { 0, { 0, 0, 0}}, // ( 61, 137) + { 0, { 0, 0, 0}}, // ( 62, 137) + { 0, { 0, 0, 0}}, // ( 63, 137) + { 0, { 0, 0, 0}}, // ( 64, 137) + { 0, { 0, 0, 0}}, // ( 65, 137) + { 0, { 0, 0, 0}}, // ( 66, 137) + { 0, { 0, 0, 0}}, // ( 67, 137) + { 0, { 0, 0, 0}}, // ( 68, 137) + { 0, { 0, 0, 0}}, // ( 69, 137) + { 0, { 0, 0, 0}}, // ( 70, 137) + { 0, { 0, 0, 0}}, // ( 71, 137) + { 0, { 0, 0, 0}}, // ( 72, 137) + { 0, { 0, 0, 0}}, // ( 73, 137) + { 0, { 0, 0, 0}}, // ( 74, 137) + { 0, { 0, 0, 0}}, // ( 75, 137) + { 0, { 0, 0, 0}}, // ( 76, 137) + { 0, { 0, 0, 0}}, // ( 77, 137) + { 0, { 0, 0, 0}}, // ( 78, 137) + { 0, { 0, 0, 0}}, // ( 79, 137) + { 0, { 0, 0, 0}}, // ( 80, 137) + { 0, { 0, 0, 0}}, // ( 81, 137) + { 0, { 0, 0, 0}}, // ( 82, 137) + { 0, { 0, 0, 0}}, // ( 83, 137) + { 0, { 0, 0, 0}}, // ( 84, 137) + { 0, { 0, 0, 0}}, // ( 85, 137) + { 0, { 0, 0, 0}}, // ( 86, 137) + { 0, { 0, 0, 0}}, // ( 87, 137) + { 0, { 0, 0, 0}}, // ( 88, 137) + { 0, { 0, 0, 0}}, // ( 89, 137) + { 0, { 0, 0, 0}}, // ( 90, 137) + { 0, { 0, 0, 0}}, // ( 91, 137) + { 0, { 0, 0, 0}}, // ( 92, 137) + { 0, { 0, 0, 0}}, // ( 93, 137) + { 0, { 0, 0, 0}}, // ( 94, 137) + { 0, { 0, 0, 0}}, // ( 95, 137) + { 0, { 0, 0, 0}}, // ( 96, 137) + { 0, { 0, 0, 0}}, // ( 97, 137) + { 0, { 0, 0, 0}}, // ( 98, 137) + { 0, { 0, 0, 0}}, // ( 99, 137) + { 0, { 0, 0, 0}}, // (100, 137) + { 0, { 0, 0, 0}}, // (101, 137) + { 0, { 0, 0, 0}}, // (102, 137) + { 0, { 0, 0, 0}}, // (103, 137) + { 0, { 0, 0, 0}}, // (104, 137) + { 0, { 0, 0, 0}}, // (105, 137) + { 0, { 0, 0, 0}}, // (106, 137) + { 0, { 0, 0, 0}}, // (107, 137) + { 0, { 0, 0, 0}}, // (108, 137) + { 0, { 0, 0, 0}}, // (109, 137) + { 0, { 0, 0, 0}}, // (110, 137) + { 0, { 0, 0, 0}}, // (111, 137) + { 0, { 0, 0, 0}}, // (112, 137) + { 0, { 0, 0, 0}}, // (113, 137) + { 0, { 0, 0, 0}}, // (114, 137) + { 0, { 0, 0, 0}}, // (115, 137) + { 0, { 0, 0, 0}}, // (116, 137) + { 0, { 0, 0, 0}}, // (117, 137) + { 0, { 0, 0, 0}}, // (118, 137) + { 0, { 0, 0, 0}}, // (119, 137) + { 0, { 0, 0, 0}}, // (120, 137) + { 0, { 0, 0, 0}}, // (121, 137) + { 0, { 0, 0, 0}}, // (122, 137) + { 0, { 0, 0, 0}}, // (123, 137) + { 0, { 0, 0, 0}}, // (124, 137) + { 0, { 0, 0, 0}}, // (125, 137) + { 0, { 0, 0, 0}}, // (126, 137) + { 0, { 0, 0, 0}}, // (127, 137) + { 0, { 0, 0, 0}}, // (128, 137) + { 0, { 0, 0, 0}}, // (129, 137) + { 0, { 0, 0, 0}}, // (130, 137) + { 0, { 0, 0, 0}}, // (131, 137) + { 0, { 0, 0, 0}}, // (132, 137) + { 0, { 0, 0, 0}}, // (133, 137) + { 0, { 0, 0, 0}}, // (134, 137) + { 0, { 0, 0, 0}}, // (135, 137) + { 0, { 0, 0, 0}}, // (136, 137) + { 0, { 0, 0, 0}}, // (137, 137) + { 0, { 0, 0, 0}}, // (138, 137) + { 0, { 0, 0, 0}}, // (139, 137) + { 0, { 0, 0, 0}}, // (140, 137) + { 0, { 0, 0, 0}}, // (141, 137) + { 0, { 0, 0, 0}}, // (142, 137) + { 0, { 0, 0, 0}}, // (143, 137) + { 0, { 0, 0, 0}}, // (144, 137) + { 0, { 0, 0, 0}}, // (145, 137) + { 0, { 0, 0, 0}}, // (146, 137) + { 0, { 0, 0, 0}}, // (147, 137) + { 0, { 0, 0, 0}}, // (148, 137) + { 0, { 0, 0, 0}}, // (149, 137) + { 0, { 0, 0, 0}}, // (150, 137) + { 0, { 0, 0, 0}}, // (151, 137) + { 0, { 0, 0, 0}}, // (152, 137) + { 0, { 0, 0, 0}}, // (153, 137) + { 0, { 0, 0, 0}}, // (154, 137) + { 0, { 0, 0, 0}}, // (155, 137) + { 0, { 0, 0, 0}}, // (156, 137) + { 0, { 0, 0, 0}}, // (157, 137) + { 0, { 0, 0, 0}}, // (158, 137) + { 0, { 0, 0, 0}}, // (159, 137) + { 0, { 0, 0, 0}}, // (160, 137) + { 0, { 0, 0, 0}}, // (161, 137) + { 0, { 0, 0, 0}}, // (162, 137) + { 7, { 0, 0, 0}}, // (163, 137) + {113, { 0, 0, 0}}, // (164, 137) + {128, { 0, 0, 0}}, // (165, 137) + {128, { 0, 0, 0}}, // (166, 137) + {128, { 0, 0, 0}}, // (167, 137) + {128, { 0, 0, 0}}, // (168, 137) + {128, { 0, 0, 0}}, // (169, 137) + {128, { 0, 0, 0}}, // (170, 137) + {128, { 0, 0, 0}}, // (171, 137) + {128, { 0, 0, 0}}, // (172, 137) + {128, { 0, 0, 0}}, // (173, 137) + {128, { 0, 0, 0}}, // (174, 137) + {128, { 0, 0, 0}}, // (175, 137) + {128, { 0, 0, 0}}, // (176, 137) + {128, { 0, 0, 0}}, // (177, 137) + {128, { 0, 0, 0}}, // (178, 137) + {128, { 0, 0, 0}}, // (179, 137) + {128, { 0, 0, 0}}, // ( 0, 138) + {128, { 0, 0, 0}}, // ( 1, 138) + {128, { 0, 0, 0}}, // ( 2, 138) + {128, { 0, 0, 0}}, // ( 3, 138) + {128, { 0, 0, 0}}, // ( 4, 138) + {128, { 0, 0, 0}}, // ( 5, 138) + {128, { 0, 0, 0}}, // ( 6, 138) + {128, { 0, 0, 0}}, // ( 7, 138) + {128, { 0, 0, 0}}, // ( 8, 138) + {128, { 0, 0, 0}}, // ( 9, 138) + {128, { 0, 0, 0}}, // ( 10, 138) + {128, { 0, 0, 0}}, // ( 11, 138) + {128, { 0, 0, 0}}, // ( 12, 138) + {128, { 0, 0, 0}}, // ( 13, 138) + {128, { 0, 0, 0}}, // ( 14, 138) + {128, { 0, 0, 0}}, // ( 15, 138) + { 74, { 0, 0, 0}}, // ( 16, 138) + { 0, { 0, 0, 0}}, // ( 17, 138) + { 0, { 0, 0, 0}}, // ( 18, 138) + { 0, { 0, 0, 0}}, // ( 19, 138) + { 0, { 0, 0, 0}}, // ( 20, 138) + { 0, { 0, 0, 0}}, // ( 21, 138) + { 0, { 0, 0, 0}}, // ( 22, 138) + { 0, { 0, 0, 0}}, // ( 23, 138) + { 0, { 0, 0, 0}}, // ( 24, 138) + { 0, { 0, 0, 0}}, // ( 25, 138) + { 0, { 0, 0, 0}}, // ( 26, 138) + { 0, { 0, 0, 0}}, // ( 27, 138) + { 0, { 0, 0, 0}}, // ( 28, 138) + { 0, { 0, 0, 0}}, // ( 29, 138) + { 0, { 0, 0, 0}}, // ( 30, 138) + { 0, { 0, 0, 0}}, // ( 31, 138) + { 0, { 0, 0, 0}}, // ( 32, 138) + { 0, { 0, 0, 0}}, // ( 33, 138) + { 0, { 0, 0, 0}}, // ( 34, 138) + { 0, { 0, 0, 0}}, // ( 35, 138) + { 0, { 0, 0, 0}}, // ( 36, 138) + { 0, { 0, 0, 0}}, // ( 37, 138) + { 0, { 0, 0, 0}}, // ( 38, 138) + { 0, { 0, 0, 0}}, // ( 39, 138) + { 0, { 0, 0, 0}}, // ( 40, 138) + { 0, { 0, 0, 0}}, // ( 41, 138) + { 0, { 0, 0, 0}}, // ( 42, 138) + { 0, { 0, 0, 0}}, // ( 43, 138) + { 0, { 0, 0, 0}}, // ( 44, 138) + { 0, { 0, 0, 0}}, // ( 45, 138) + { 0, { 0, 0, 0}}, // ( 46, 138) + { 0, { 0, 0, 0}}, // ( 47, 138) + { 0, { 0, 0, 0}}, // ( 48, 138) + { 0, { 0, 0, 0}}, // ( 49, 138) + { 0, { 0, 0, 0}}, // ( 50, 138) + { 0, { 0, 0, 0}}, // ( 51, 138) + { 0, { 0, 0, 0}}, // ( 52, 138) + { 0, { 0, 0, 0}}, // ( 53, 138) + { 0, { 0, 0, 0}}, // ( 54, 138) + { 0, { 0, 0, 0}}, // ( 55, 138) + { 0, { 0, 0, 0}}, // ( 56, 138) + { 0, { 0, 0, 0}}, // ( 57, 138) + { 0, { 0, 0, 0}}, // ( 58, 138) + { 0, { 0, 0, 0}}, // ( 59, 138) + { 0, { 0, 0, 0}}, // ( 60, 138) + { 0, { 0, 0, 0}}, // ( 61, 138) + { 0, { 0, 0, 0}}, // ( 62, 138) + { 0, { 0, 0, 0}}, // ( 63, 138) + { 0, { 0, 0, 0}}, // ( 64, 138) + { 0, { 0, 0, 0}}, // ( 65, 138) + { 0, { 0, 0, 0}}, // ( 66, 138) + { 0, { 0, 0, 0}}, // ( 67, 138) + { 0, { 0, 0, 0}}, // ( 68, 138) + { 0, { 0, 0, 0}}, // ( 69, 138) + { 0, { 0, 0, 0}}, // ( 70, 138) + { 0, { 0, 0, 0}}, // ( 71, 138) + { 0, { 0, 0, 0}}, // ( 72, 138) + { 0, { 0, 0, 0}}, // ( 73, 138) + { 0, { 0, 0, 0}}, // ( 74, 138) + { 0, { 0, 0, 0}}, // ( 75, 138) + { 0, { 0, 0, 0}}, // ( 76, 138) + { 0, { 0, 0, 0}}, // ( 77, 138) + { 0, { 0, 0, 0}}, // ( 78, 138) + { 0, { 0, 0, 0}}, // ( 79, 138) + { 0, { 0, 0, 0}}, // ( 80, 138) + { 0, { 0, 0, 0}}, // ( 81, 138) + { 0, { 0, 0, 0}}, // ( 82, 138) + { 0, { 0, 0, 0}}, // ( 83, 138) + { 0, { 0, 0, 0}}, // ( 84, 138) + { 0, { 0, 0, 0}}, // ( 85, 138) + { 0, { 0, 0, 0}}, // ( 86, 138) + { 0, { 0, 0, 0}}, // ( 87, 138) + { 0, { 0, 0, 0}}, // ( 88, 138) + { 0, { 0, 0, 0}}, // ( 89, 138) + { 0, { 0, 0, 0}}, // ( 90, 138) + { 0, { 0, 0, 0}}, // ( 91, 138) + { 0, { 0, 0, 0}}, // ( 92, 138) + { 0, { 0, 0, 0}}, // ( 93, 138) + { 0, { 0, 0, 0}}, // ( 94, 138) + { 0, { 0, 0, 0}}, // ( 95, 138) + { 0, { 0, 0, 0}}, // ( 96, 138) + { 0, { 0, 0, 0}}, // ( 97, 138) + { 0, { 0, 0, 0}}, // ( 98, 138) + { 0, { 0, 0, 0}}, // ( 99, 138) + { 0, { 0, 0, 0}}, // (100, 138) + { 0, { 0, 0, 0}}, // (101, 138) + { 0, { 0, 0, 0}}, // (102, 138) + { 0, { 0, 0, 0}}, // (103, 138) + { 0, { 0, 0, 0}}, // (104, 138) + { 0, { 0, 0, 0}}, // (105, 138) + { 0, { 0, 0, 0}}, // (106, 138) + { 0, { 0, 0, 0}}, // (107, 138) + { 0, { 0, 0, 0}}, // (108, 138) + { 0, { 0, 0, 0}}, // (109, 138) + { 0, { 0, 0, 0}}, // (110, 138) + { 0, { 0, 0, 0}}, // (111, 138) + { 0, { 0, 0, 0}}, // (112, 138) + { 0, { 0, 0, 0}}, // (113, 138) + { 0, { 0, 0, 0}}, // (114, 138) + { 0, { 0, 0, 0}}, // (115, 138) + { 0, { 0, 0, 0}}, // (116, 138) + { 0, { 0, 0, 0}}, // (117, 138) + { 0, { 0, 0, 0}}, // (118, 138) + { 0, { 0, 0, 0}}, // (119, 138) + { 0, { 0, 0, 0}}, // (120, 138) + { 0, { 0, 0, 0}}, // (121, 138) + { 0, { 0, 0, 0}}, // (122, 138) + { 0, { 0, 0, 0}}, // (123, 138) + { 0, { 0, 0, 0}}, // (124, 138) + { 0, { 0, 0, 0}}, // (125, 138) + { 0, { 0, 0, 0}}, // (126, 138) + { 0, { 0, 0, 0}}, // (127, 138) + { 0, { 0, 0, 0}}, // (128, 138) + { 0, { 0, 0, 0}}, // (129, 138) + { 0, { 0, 0, 0}}, // (130, 138) + { 0, { 0, 0, 0}}, // (131, 138) + { 0, { 0, 0, 0}}, // (132, 138) + { 0, { 0, 0, 0}}, // (133, 138) + { 0, { 0, 0, 0}}, // (134, 138) + { 0, { 0, 0, 0}}, // (135, 138) + { 0, { 0, 0, 0}}, // (136, 138) + { 0, { 0, 0, 0}}, // (137, 138) + { 0, { 0, 0, 0}}, // (138, 138) + { 0, { 0, 0, 0}}, // (139, 138) + { 0, { 0, 0, 0}}, // (140, 138) + { 0, { 0, 0, 0}}, // (141, 138) + { 0, { 0, 0, 0}}, // (142, 138) + { 0, { 0, 0, 0}}, // (143, 138) + { 0, { 0, 0, 0}}, // (144, 138) + { 0, { 0, 0, 0}}, // (145, 138) + { 0, { 0, 0, 0}}, // (146, 138) + { 0, { 0, 0, 0}}, // (147, 138) + { 0, { 0, 0, 0}}, // (148, 138) + { 0, { 0, 0, 0}}, // (149, 138) + { 0, { 0, 0, 0}}, // (150, 138) + { 0, { 0, 0, 0}}, // (151, 138) + { 0, { 0, 0, 0}}, // (152, 138) + { 0, { 0, 0, 0}}, // (153, 138) + { 0, { 0, 0, 0}}, // (154, 138) + { 0, { 0, 0, 0}}, // (155, 138) + { 0, { 0, 0, 0}}, // (156, 138) + { 0, { 0, 0, 0}}, // (157, 138) + { 0, { 0, 0, 0}}, // (158, 138) + { 0, { 0, 0, 0}}, // (159, 138) + { 0, { 0, 0, 0}}, // (160, 138) + { 0, { 0, 0, 0}}, // (161, 138) + { 0, { 0, 0, 0}}, // (162, 138) + { 74, { 0, 0, 0}}, // (163, 138) + {128, { 0, 0, 0}}, // (164, 138) + {128, { 0, 0, 0}}, // (165, 138) + {128, { 0, 0, 0}}, // (166, 138) + {128, { 0, 0, 0}}, // (167, 138) + {128, { 0, 0, 0}}, // (168, 138) + {128, { 0, 0, 0}}, // (169, 138) + {128, { 0, 0, 0}}, // (170, 138) + {128, { 0, 0, 0}}, // (171, 138) + {128, { 0, 0, 0}}, // (172, 138) + {128, { 0, 0, 0}}, // (173, 138) + {128, { 0, 0, 0}}, // (174, 138) + {128, { 0, 0, 0}}, // (175, 138) + {128, { 0, 0, 0}}, // (176, 138) + {128, { 0, 0, 0}}, // (177, 138) + {128, { 0, 0, 0}}, // (178, 138) + {128, { 0, 0, 0}}, // (179, 138) + {128, { 0, 0, 0}}, // ( 0, 139) + {128, { 0, 0, 0}}, // ( 1, 139) + {128, { 0, 0, 0}}, // ( 2, 139) + {128, { 0, 0, 0}}, // ( 3, 139) + {128, { 0, 0, 0}}, // ( 4, 139) + {128, { 0, 0, 0}}, // ( 5, 139) + {128, { 0, 0, 0}}, // ( 6, 139) + {128, { 0, 0, 0}}, // ( 7, 139) + {128, { 0, 0, 0}}, // ( 8, 139) + {128, { 0, 0, 0}}, // ( 9, 139) + {128, { 0, 0, 0}}, // ( 10, 139) + {128, { 0, 0, 0}}, // ( 11, 139) + {128, { 0, 0, 0}}, // ( 12, 139) + {128, { 0, 0, 0}}, // ( 13, 139) + {128, { 0, 0, 0}}, // ( 14, 139) + {128, { 0, 0, 0}}, // ( 15, 139) + {127, { 0, 0, 0}}, // ( 16, 139) + { 32, { 0, 0, 0}}, // ( 17, 139) + { 0, { 0, 0, 0}}, // ( 18, 139) + { 0, { 0, 0, 0}}, // ( 19, 139) + { 0, { 0, 0, 0}}, // ( 20, 139) + { 0, { 0, 0, 0}}, // ( 21, 139) + { 0, { 0, 0, 0}}, // ( 22, 139) + { 0, { 0, 0, 0}}, // ( 23, 139) + { 0, { 0, 0, 0}}, // ( 24, 139) + { 0, { 0, 0, 0}}, // ( 25, 139) + { 0, { 0, 0, 0}}, // ( 26, 139) + { 0, { 0, 0, 0}}, // ( 27, 139) + { 0, { 0, 0, 0}}, // ( 28, 139) + { 0, { 0, 0, 0}}, // ( 29, 139) + { 0, { 0, 0, 0}}, // ( 30, 139) + { 0, { 0, 0, 0}}, // ( 31, 139) + { 0, { 0, 0, 0}}, // ( 32, 139) + { 0, { 0, 0, 0}}, // ( 33, 139) + { 0, { 0, 0, 0}}, // ( 34, 139) + { 0, { 0, 0, 0}}, // ( 35, 139) + { 0, { 0, 0, 0}}, // ( 36, 139) + { 0, { 0, 0, 0}}, // ( 37, 139) + { 0, { 0, 0, 0}}, // ( 38, 139) + { 0, { 0, 0, 0}}, // ( 39, 139) + { 0, { 0, 0, 0}}, // ( 40, 139) + { 0, { 0, 0, 0}}, // ( 41, 139) + { 0, { 0, 0, 0}}, // ( 42, 139) + { 0, { 0, 0, 0}}, // ( 43, 139) + { 0, { 0, 0, 0}}, // ( 44, 139) + { 0, { 0, 0, 0}}, // ( 45, 139) + { 0, { 0, 0, 0}}, // ( 46, 139) + { 0, { 0, 0, 0}}, // ( 47, 139) + { 0, { 0, 0, 0}}, // ( 48, 139) + { 0, { 0, 0, 0}}, // ( 49, 139) + { 0, { 0, 0, 0}}, // ( 50, 139) + { 0, { 0, 0, 0}}, // ( 51, 139) + { 0, { 0, 0, 0}}, // ( 52, 139) + { 0, { 0, 0, 0}}, // ( 53, 139) + { 0, { 0, 0, 0}}, // ( 54, 139) + { 0, { 0, 0, 0}}, // ( 55, 139) + { 0, { 0, 0, 0}}, // ( 56, 139) + { 0, { 0, 0, 0}}, // ( 57, 139) + { 0, { 0, 0, 0}}, // ( 58, 139) + { 0, { 0, 0, 0}}, // ( 59, 139) + { 0, { 0, 0, 0}}, // ( 60, 139) + { 0, { 0, 0, 0}}, // ( 61, 139) + { 0, { 0, 0, 0}}, // ( 62, 139) + { 0, { 0, 0, 0}}, // ( 63, 139) + { 0, { 0, 0, 0}}, // ( 64, 139) + { 0, { 0, 0, 0}}, // ( 65, 139) + { 0, { 0, 0, 0}}, // ( 66, 139) + { 0, { 0, 0, 0}}, // ( 67, 139) + { 0, { 0, 0, 0}}, // ( 68, 139) + { 0, { 0, 0, 0}}, // ( 69, 139) + { 0, { 0, 0, 0}}, // ( 70, 139) + { 0, { 0, 0, 0}}, // ( 71, 139) + { 0, { 0, 0, 0}}, // ( 72, 139) + { 0, { 0, 0, 0}}, // ( 73, 139) + { 0, { 0, 0, 0}}, // ( 74, 139) + { 0, { 0, 0, 0}}, // ( 75, 139) + { 0, { 0, 0, 0}}, // ( 76, 139) + { 0, { 0, 0, 0}}, // ( 77, 139) + { 0, { 0, 0, 0}}, // ( 78, 139) + { 0, { 0, 0, 0}}, // ( 79, 139) + { 0, { 0, 0, 0}}, // ( 80, 139) + { 0, { 0, 0, 0}}, // ( 81, 139) + { 0, { 0, 0, 0}}, // ( 82, 139) + { 0, { 0, 0, 0}}, // ( 83, 139) + { 0, { 0, 0, 0}}, // ( 84, 139) + { 0, { 0, 0, 0}}, // ( 85, 139) + { 0, { 0, 0, 0}}, // ( 86, 139) + { 0, { 0, 0, 0}}, // ( 87, 139) + { 0, { 0, 0, 0}}, // ( 88, 139) + { 0, { 0, 0, 0}}, // ( 89, 139) + { 0, { 0, 0, 0}}, // ( 90, 139) + { 0, { 0, 0, 0}}, // ( 91, 139) + { 0, { 0, 0, 0}}, // ( 92, 139) + { 0, { 0, 0, 0}}, // ( 93, 139) + { 0, { 0, 0, 0}}, // ( 94, 139) + { 0, { 0, 0, 0}}, // ( 95, 139) + { 0, { 0, 0, 0}}, // ( 96, 139) + { 0, { 0, 0, 0}}, // ( 97, 139) + { 0, { 0, 0, 0}}, // ( 98, 139) + { 0, { 0, 0, 0}}, // ( 99, 139) + { 0, { 0, 0, 0}}, // (100, 139) + { 0, { 0, 0, 0}}, // (101, 139) + { 0, { 0, 0, 0}}, // (102, 139) + { 0, { 0, 0, 0}}, // (103, 139) + { 0, { 0, 0, 0}}, // (104, 139) + { 0, { 0, 0, 0}}, // (105, 139) + { 0, { 0, 0, 0}}, // (106, 139) + { 0, { 0, 0, 0}}, // (107, 139) + { 0, { 0, 0, 0}}, // (108, 139) + { 0, { 0, 0, 0}}, // (109, 139) + { 0, { 0, 0, 0}}, // (110, 139) + { 0, { 0, 0, 0}}, // (111, 139) + { 0, { 0, 0, 0}}, // (112, 139) + { 0, { 0, 0, 0}}, // (113, 139) + { 0, { 0, 0, 0}}, // (114, 139) + { 0, { 0, 0, 0}}, // (115, 139) + { 0, { 0, 0, 0}}, // (116, 139) + { 0, { 0, 0, 0}}, // (117, 139) + { 0, { 0, 0, 0}}, // (118, 139) + { 0, { 0, 0, 0}}, // (119, 139) + { 0, { 0, 0, 0}}, // (120, 139) + { 0, { 0, 0, 0}}, // (121, 139) + { 0, { 0, 0, 0}}, // (122, 139) + { 0, { 0, 0, 0}}, // (123, 139) + { 0, { 0, 0, 0}}, // (124, 139) + { 0, { 0, 0, 0}}, // (125, 139) + { 0, { 0, 0, 0}}, // (126, 139) + { 0, { 0, 0, 0}}, // (127, 139) + { 0, { 0, 0, 0}}, // (128, 139) + { 0, { 0, 0, 0}}, // (129, 139) + { 0, { 0, 0, 0}}, // (130, 139) + { 0, { 0, 0, 0}}, // (131, 139) + { 0, { 0, 0, 0}}, // (132, 139) + { 0, { 0, 0, 0}}, // (133, 139) + { 0, { 0, 0, 0}}, // (134, 139) + { 0, { 0, 0, 0}}, // (135, 139) + { 0, { 0, 0, 0}}, // (136, 139) + { 0, { 0, 0, 0}}, // (137, 139) + { 0, { 0, 0, 0}}, // (138, 139) + { 0, { 0, 0, 0}}, // (139, 139) + { 0, { 0, 0, 0}}, // (140, 139) + { 0, { 0, 0, 0}}, // (141, 139) + { 0, { 0, 0, 0}}, // (142, 139) + { 0, { 0, 0, 0}}, // (143, 139) + { 0, { 0, 0, 0}}, // (144, 139) + { 0, { 0, 0, 0}}, // (145, 139) + { 0, { 0, 0, 0}}, // (146, 139) + { 0, { 0, 0, 0}}, // (147, 139) + { 0, { 0, 0, 0}}, // (148, 139) + { 0, { 0, 0, 0}}, // (149, 139) + { 0, { 0, 0, 0}}, // (150, 139) + { 0, { 0, 0, 0}}, // (151, 139) + { 0, { 0, 0, 0}}, // (152, 139) + { 0, { 0, 0, 0}}, // (153, 139) + { 0, { 0, 0, 0}}, // (154, 139) + { 0, { 0, 0, 0}}, // (155, 139) + { 0, { 0, 0, 0}}, // (156, 139) + { 0, { 0, 0, 0}}, // (157, 139) + { 0, { 0, 0, 0}}, // (158, 139) + { 0, { 0, 0, 0}}, // (159, 139) + { 0, { 0, 0, 0}}, // (160, 139) + { 0, { 0, 0, 0}}, // (161, 139) + { 32, { 0, 0, 0}}, // (162, 139) + {127, { 0, 0, 0}}, // (163, 139) + {128, { 0, 0, 0}}, // (164, 139) + {128, { 0, 0, 0}}, // (165, 139) + {128, { 0, 0, 0}}, // (166, 139) + {128, { 0, 0, 0}}, // (167, 139) + {128, { 0, 0, 0}}, // (168, 139) + {128, { 0, 0, 0}}, // (169, 139) + {128, { 0, 0, 0}}, // (170, 139) + {128, { 0, 0, 0}}, // (171, 139) + {128, { 0, 0, 0}}, // (172, 139) + {128, { 0, 0, 0}}, // (173, 139) + {128, { 0, 0, 0}}, // (174, 139) + {128, { 0, 0, 0}}, // (175, 139) + {128, { 0, 0, 0}}, // (176, 139) + {128, { 0, 0, 0}}, // (177, 139) + {128, { 0, 0, 0}}, // (178, 139) + {128, { 0, 0, 0}}, // (179, 139) + {128, { 0, 0, 0}}, // ( 0, 140) + {128, { 0, 0, 0}}, // ( 1, 140) + {128, { 0, 0, 0}}, // ( 2, 140) + {128, { 0, 0, 0}}, // ( 3, 140) + {128, { 0, 0, 0}}, // ( 4, 140) + {128, { 0, 0, 0}}, // ( 5, 140) + {128, { 0, 0, 0}}, // ( 6, 140) + {128, { 0, 0, 0}}, // ( 7, 140) + {128, { 0, 0, 0}}, // ( 8, 140) + {128, { 0, 0, 0}}, // ( 9, 140) + {128, { 0, 0, 0}}, // ( 10, 140) + {128, { 0, 0, 0}}, // ( 11, 140) + {128, { 0, 0, 0}}, // ( 12, 140) + {128, { 0, 0, 0}}, // ( 13, 140) + {128, { 0, 0, 0}}, // ( 14, 140) + {128, { 0, 0, 0}}, // ( 15, 140) + {128, { 0, 0, 0}}, // ( 16, 140) + {113, { 0, 0, 0}}, // ( 17, 140) + { 9, { 0, 0, 0}}, // ( 18, 140) + { 0, { 0, 0, 0}}, // ( 19, 140) + { 0, { 0, 0, 0}}, // ( 20, 140) + { 0, { 0, 0, 0}}, // ( 21, 140) + { 0, { 0, 0, 0}}, // ( 22, 140) + { 0, { 0, 0, 0}}, // ( 23, 140) + { 0, { 0, 0, 0}}, // ( 24, 140) + { 0, { 0, 0, 0}}, // ( 25, 140) + { 0, { 0, 0, 0}}, // ( 26, 140) + { 0, { 0, 0, 0}}, // ( 27, 140) + { 0, { 0, 0, 0}}, // ( 28, 140) + { 0, { 0, 0, 0}}, // ( 29, 140) + { 0, { 0, 0, 0}}, // ( 30, 140) + { 0, { 0, 0, 0}}, // ( 31, 140) + { 0, { 0, 0, 0}}, // ( 32, 140) + { 0, { 0, 0, 0}}, // ( 33, 140) + { 0, { 0, 0, 0}}, // ( 34, 140) + { 0, { 0, 0, 0}}, // ( 35, 140) + { 0, { 0, 0, 0}}, // ( 36, 140) + { 0, { 0, 0, 0}}, // ( 37, 140) + { 0, { 0, 0, 0}}, // ( 38, 140) + { 0, { 0, 0, 0}}, // ( 39, 140) + { 0, { 0, 0, 0}}, // ( 40, 140) + { 0, { 0, 0, 0}}, // ( 41, 140) + { 0, { 0, 0, 0}}, // ( 42, 140) + { 0, { 0, 0, 0}}, // ( 43, 140) + { 0, { 0, 0, 0}}, // ( 44, 140) + { 0, { 0, 0, 0}}, // ( 45, 140) + { 0, { 0, 0, 0}}, // ( 46, 140) + { 0, { 0, 0, 0}}, // ( 47, 140) + { 0, { 0, 0, 0}}, // ( 48, 140) + { 0, { 0, 0, 0}}, // ( 49, 140) + { 0, { 0, 0, 0}}, // ( 50, 140) + { 0, { 0, 0, 0}}, // ( 51, 140) + { 0, { 0, 0, 0}}, // ( 52, 140) + { 0, { 0, 0, 0}}, // ( 53, 140) + { 0, { 0, 0, 0}}, // ( 54, 140) + { 0, { 0, 0, 0}}, // ( 55, 140) + { 0, { 0, 0, 0}}, // ( 56, 140) + { 0, { 0, 0, 0}}, // ( 57, 140) + { 0, { 0, 0, 0}}, // ( 58, 140) + { 0, { 0, 0, 0}}, // ( 59, 140) + { 0, { 0, 0, 0}}, // ( 60, 140) + { 0, { 0, 0, 0}}, // ( 61, 140) + { 0, { 0, 0, 0}}, // ( 62, 140) + { 0, { 0, 0, 0}}, // ( 63, 140) + { 0, { 0, 0, 0}}, // ( 64, 140) + { 0, { 0, 0, 0}}, // ( 65, 140) + { 0, { 0, 0, 0}}, // ( 66, 140) + { 0, { 0, 0, 0}}, // ( 67, 140) + { 0, { 0, 0, 0}}, // ( 68, 140) + { 0, { 0, 0, 0}}, // ( 69, 140) + { 0, { 0, 0, 0}}, // ( 70, 140) + { 0, { 0, 0, 0}}, // ( 71, 140) + { 0, { 0, 0, 0}}, // ( 72, 140) + { 0, { 0, 0, 0}}, // ( 73, 140) + { 0, { 0, 0, 0}}, // ( 74, 140) + { 0, { 0, 0, 0}}, // ( 75, 140) + { 0, { 0, 0, 0}}, // ( 76, 140) + { 0, { 0, 0, 0}}, // ( 77, 140) + { 0, { 0, 0, 0}}, // ( 78, 140) + { 0, { 0, 0, 0}}, // ( 79, 140) + { 0, { 0, 0, 0}}, // ( 80, 140) + { 0, { 0, 0, 0}}, // ( 81, 140) + { 0, { 0, 0, 0}}, // ( 82, 140) + { 0, { 0, 0, 0}}, // ( 83, 140) + { 0, { 0, 0, 0}}, // ( 84, 140) + { 0, { 0, 0, 0}}, // ( 85, 140) + { 0, { 0, 0, 0}}, // ( 86, 140) + { 0, { 0, 0, 0}}, // ( 87, 140) + { 0, { 0, 0, 0}}, // ( 88, 140) + { 0, { 0, 0, 0}}, // ( 89, 140) + { 0, { 0, 0, 0}}, // ( 90, 140) + { 0, { 0, 0, 0}}, // ( 91, 140) + { 0, { 0, 0, 0}}, // ( 92, 140) + { 0, { 0, 0, 0}}, // ( 93, 140) + { 0, { 0, 0, 0}}, // ( 94, 140) + { 0, { 0, 0, 0}}, // ( 95, 140) + { 0, { 0, 0, 0}}, // ( 96, 140) + { 0, { 0, 0, 0}}, // ( 97, 140) + { 0, { 0, 0, 0}}, // ( 98, 140) + { 0, { 0, 0, 0}}, // ( 99, 140) + { 0, { 0, 0, 0}}, // (100, 140) + { 0, { 0, 0, 0}}, // (101, 140) + { 0, { 0, 0, 0}}, // (102, 140) + { 0, { 0, 0, 0}}, // (103, 140) + { 0, { 0, 0, 0}}, // (104, 140) + { 0, { 0, 0, 0}}, // (105, 140) + { 0, { 0, 0, 0}}, // (106, 140) + { 0, { 0, 0, 0}}, // (107, 140) + { 0, { 0, 0, 0}}, // (108, 140) + { 0, { 0, 0, 0}}, // (109, 140) + { 0, { 0, 0, 0}}, // (110, 140) + { 0, { 0, 0, 0}}, // (111, 140) + { 0, { 0, 0, 0}}, // (112, 140) + { 0, { 0, 0, 0}}, // (113, 140) + { 0, { 0, 0, 0}}, // (114, 140) + { 0, { 0, 0, 0}}, // (115, 140) + { 0, { 0, 0, 0}}, // (116, 140) + { 0, { 0, 0, 0}}, // (117, 140) + { 0, { 0, 0, 0}}, // (118, 140) + { 0, { 0, 0, 0}}, // (119, 140) + { 0, { 0, 0, 0}}, // (120, 140) + { 0, { 0, 0, 0}}, // (121, 140) + { 0, { 0, 0, 0}}, // (122, 140) + { 0, { 0, 0, 0}}, // (123, 140) + { 0, { 0, 0, 0}}, // (124, 140) + { 0, { 0, 0, 0}}, // (125, 140) + { 0, { 0, 0, 0}}, // (126, 140) + { 0, { 0, 0, 0}}, // (127, 140) + { 0, { 0, 0, 0}}, // (128, 140) + { 0, { 0, 0, 0}}, // (129, 140) + { 0, { 0, 0, 0}}, // (130, 140) + { 0, { 0, 0, 0}}, // (131, 140) + { 0, { 0, 0, 0}}, // (132, 140) + { 0, { 0, 0, 0}}, // (133, 140) + { 0, { 0, 0, 0}}, // (134, 140) + { 0, { 0, 0, 0}}, // (135, 140) + { 0, { 0, 0, 0}}, // (136, 140) + { 0, { 0, 0, 0}}, // (137, 140) + { 0, { 0, 0, 0}}, // (138, 140) + { 0, { 0, 0, 0}}, // (139, 140) + { 0, { 0, 0, 0}}, // (140, 140) + { 0, { 0, 0, 0}}, // (141, 140) + { 0, { 0, 0, 0}}, // (142, 140) + { 0, { 0, 0, 0}}, // (143, 140) + { 0, { 0, 0, 0}}, // (144, 140) + { 0, { 0, 0, 0}}, // (145, 140) + { 0, { 0, 0, 0}}, // (146, 140) + { 0, { 0, 0, 0}}, // (147, 140) + { 0, { 0, 0, 0}}, // (148, 140) + { 0, { 0, 0, 0}}, // (149, 140) + { 0, { 0, 0, 0}}, // (150, 140) + { 0, { 0, 0, 0}}, // (151, 140) + { 0, { 0, 0, 0}}, // (152, 140) + { 0, { 0, 0, 0}}, // (153, 140) + { 0, { 0, 0, 0}}, // (154, 140) + { 0, { 0, 0, 0}}, // (155, 140) + { 0, { 0, 0, 0}}, // (156, 140) + { 0, { 0, 0, 0}}, // (157, 140) + { 0, { 0, 0, 0}}, // (158, 140) + { 0, { 0, 0, 0}}, // (159, 140) + { 0, { 0, 0, 0}}, // (160, 140) + { 9, { 0, 0, 0}}, // (161, 140) + {113, { 0, 0, 0}}, // (162, 140) + {128, { 0, 0, 0}}, // (163, 140) + {128, { 0, 0, 0}}, // (164, 140) + {128, { 0, 0, 0}}, // (165, 140) + {128, { 0, 0, 0}}, // (166, 140) + {128, { 0, 0, 0}}, // (167, 140) + {128, { 0, 0, 0}}, // (168, 140) + {128, { 0, 0, 0}}, // (169, 140) + {128, { 0, 0, 0}}, // (170, 140) + {128, { 0, 0, 0}}, // (171, 140) + {128, { 0, 0, 0}}, // (172, 140) + {128, { 0, 0, 0}}, // (173, 140) + {128, { 0, 0, 0}}, // (174, 140) + {128, { 0, 0, 0}}, // (175, 140) + {128, { 0, 0, 0}}, // (176, 140) + {128, { 0, 0, 0}}, // (177, 140) + {128, { 0, 0, 0}}, // (178, 140) + {128, { 0, 0, 0}}, // (179, 140) + {128, { 0, 0, 0}}, // ( 0, 141) + {128, { 0, 0, 0}}, // ( 1, 141) + {128, { 0, 0, 0}}, // ( 2, 141) + {128, { 0, 0, 0}}, // ( 3, 141) + {128, { 0, 0, 0}}, // ( 4, 141) + {128, { 0, 0, 0}}, // ( 5, 141) + {128, { 0, 0, 0}}, // ( 6, 141) + {128, { 0, 0, 0}}, // ( 7, 141) + {128, { 0, 0, 0}}, // ( 8, 141) + {128, { 0, 0, 0}}, // ( 9, 141) + {128, { 0, 0, 0}}, // ( 10, 141) + {128, { 0, 0, 0}}, // ( 11, 141) + {128, { 0, 0, 0}}, // ( 12, 141) + {128, { 0, 0, 0}}, // ( 13, 141) + {128, { 0, 0, 0}}, // ( 14, 141) + {128, { 0, 0, 0}}, // ( 15, 141) + {128, { 0, 0, 0}}, // ( 16, 141) + {128, { 0, 0, 0}}, // ( 17, 141) + { 85, { 0, 0, 0}}, // ( 18, 141) + { 0, { 0, 0, 0}}, // ( 19, 141) + { 0, { 0, 0, 0}}, // ( 20, 141) + { 0, { 0, 0, 0}}, // ( 21, 141) + { 0, { 0, 0, 0}}, // ( 22, 141) + { 0, { 0, 0, 0}}, // ( 23, 141) + { 0, { 0, 0, 0}}, // ( 24, 141) + { 0, { 0, 0, 0}}, // ( 25, 141) + { 0, { 0, 0, 0}}, // ( 26, 141) + { 0, { 0, 0, 0}}, // ( 27, 141) + { 0, { 0, 0, 0}}, // ( 28, 141) + { 0, { 0, 0, 0}}, // ( 29, 141) + { 0, { 0, 0, 0}}, // ( 30, 141) + { 0, { 0, 0, 0}}, // ( 31, 141) + { 0, { 0, 0, 0}}, // ( 32, 141) + { 0, { 0, 0, 0}}, // ( 33, 141) + { 0, { 0, 0, 0}}, // ( 34, 141) + { 0, { 0, 0, 0}}, // ( 35, 141) + { 0, { 0, 0, 0}}, // ( 36, 141) + { 0, { 0, 0, 0}}, // ( 37, 141) + { 0, { 0, 0, 0}}, // ( 38, 141) + { 0, { 0, 0, 0}}, // ( 39, 141) + { 0, { 0, 0, 0}}, // ( 40, 141) + { 0, { 0, 0, 0}}, // ( 41, 141) + { 0, { 0, 0, 0}}, // ( 42, 141) + { 0, { 0, 0, 0}}, // ( 43, 141) + { 0, { 0, 0, 0}}, // ( 44, 141) + { 0, { 0, 0, 0}}, // ( 45, 141) + { 0, { 0, 0, 0}}, // ( 46, 141) + { 0, { 0, 0, 0}}, // ( 47, 141) + { 0, { 0, 0, 0}}, // ( 48, 141) + { 0, { 0, 0, 0}}, // ( 49, 141) + { 0, { 0, 0, 0}}, // ( 50, 141) + { 0, { 0, 0, 0}}, // ( 51, 141) + { 0, { 0, 0, 0}}, // ( 52, 141) + { 0, { 0, 0, 0}}, // ( 53, 141) + { 0, { 0, 0, 0}}, // ( 54, 141) + { 0, { 0, 0, 0}}, // ( 55, 141) + { 0, { 0, 0, 0}}, // ( 56, 141) + { 0, { 0, 0, 0}}, // ( 57, 141) + { 0, { 0, 0, 0}}, // ( 58, 141) + { 0, { 0, 0, 0}}, // ( 59, 141) + { 0, { 0, 0, 0}}, // ( 60, 141) + { 0, { 0, 0, 0}}, // ( 61, 141) + { 0, { 0, 0, 0}}, // ( 62, 141) + { 0, { 0, 0, 0}}, // ( 63, 141) + { 0, { 0, 0, 0}}, // ( 64, 141) + { 0, { 0, 0, 0}}, // ( 65, 141) + { 0, { 0, 0, 0}}, // ( 66, 141) + { 0, { 0, 0, 0}}, // ( 67, 141) + { 0, { 0, 0, 0}}, // ( 68, 141) + { 0, { 0, 0, 0}}, // ( 69, 141) + { 0, { 0, 0, 0}}, // ( 70, 141) + { 0, { 0, 0, 0}}, // ( 71, 141) + { 0, { 0, 0, 0}}, // ( 72, 141) + { 0, { 0, 0, 0}}, // ( 73, 141) + { 0, { 0, 0, 0}}, // ( 74, 141) + { 0, { 0, 0, 0}}, // ( 75, 141) + { 0, { 0, 0, 0}}, // ( 76, 141) + { 0, { 0, 0, 0}}, // ( 77, 141) + { 0, { 0, 0, 0}}, // ( 78, 141) + { 0, { 0, 0, 0}}, // ( 79, 141) + { 0, { 0, 0, 0}}, // ( 80, 141) + { 0, { 0, 0, 0}}, // ( 81, 141) + { 0, { 0, 0, 0}}, // ( 82, 141) + { 0, { 0, 0, 0}}, // ( 83, 141) + { 0, { 0, 0, 0}}, // ( 84, 141) + { 0, { 0, 0, 0}}, // ( 85, 141) + { 0, { 0, 0, 0}}, // ( 86, 141) + { 0, { 0, 0, 0}}, // ( 87, 141) + { 0, { 0, 0, 0}}, // ( 88, 141) + { 0, { 0, 0, 0}}, // ( 89, 141) + { 0, { 0, 0, 0}}, // ( 90, 141) + { 0, { 0, 0, 0}}, // ( 91, 141) + { 0, { 0, 0, 0}}, // ( 92, 141) + { 0, { 0, 0, 0}}, // ( 93, 141) + { 0, { 0, 0, 0}}, // ( 94, 141) + { 0, { 0, 0, 0}}, // ( 95, 141) + { 0, { 0, 0, 0}}, // ( 96, 141) + { 0, { 0, 0, 0}}, // ( 97, 141) + { 0, { 0, 0, 0}}, // ( 98, 141) + { 0, { 0, 0, 0}}, // ( 99, 141) + { 0, { 0, 0, 0}}, // (100, 141) + { 0, { 0, 0, 0}}, // (101, 141) + { 0, { 0, 0, 0}}, // (102, 141) + { 0, { 0, 0, 0}}, // (103, 141) + { 0, { 0, 0, 0}}, // (104, 141) + { 0, { 0, 0, 0}}, // (105, 141) + { 0, { 0, 0, 0}}, // (106, 141) + { 0, { 0, 0, 0}}, // (107, 141) + { 0, { 0, 0, 0}}, // (108, 141) + { 0, { 0, 0, 0}}, // (109, 141) + { 0, { 0, 0, 0}}, // (110, 141) + { 0, { 0, 0, 0}}, // (111, 141) + { 0, { 0, 0, 0}}, // (112, 141) + { 0, { 0, 0, 0}}, // (113, 141) + { 0, { 0, 0, 0}}, // (114, 141) + { 0, { 0, 0, 0}}, // (115, 141) + { 0, { 0, 0, 0}}, // (116, 141) + { 0, { 0, 0, 0}}, // (117, 141) + { 0, { 0, 0, 0}}, // (118, 141) + { 0, { 0, 0, 0}}, // (119, 141) + { 0, { 0, 0, 0}}, // (120, 141) + { 0, { 0, 0, 0}}, // (121, 141) + { 0, { 0, 0, 0}}, // (122, 141) + { 0, { 0, 0, 0}}, // (123, 141) + { 0, { 0, 0, 0}}, // (124, 141) + { 0, { 0, 0, 0}}, // (125, 141) + { 0, { 0, 0, 0}}, // (126, 141) + { 0, { 0, 0, 0}}, // (127, 141) + { 0, { 0, 0, 0}}, // (128, 141) + { 0, { 0, 0, 0}}, // (129, 141) + { 0, { 0, 0, 0}}, // (130, 141) + { 0, { 0, 0, 0}}, // (131, 141) + { 0, { 0, 0, 0}}, // (132, 141) + { 0, { 0, 0, 0}}, // (133, 141) + { 0, { 0, 0, 0}}, // (134, 141) + { 0, { 0, 0, 0}}, // (135, 141) + { 0, { 0, 0, 0}}, // (136, 141) + { 0, { 0, 0, 0}}, // (137, 141) + { 0, { 0, 0, 0}}, // (138, 141) + { 0, { 0, 0, 0}}, // (139, 141) + { 0, { 0, 0, 0}}, // (140, 141) + { 0, { 0, 0, 0}}, // (141, 141) + { 0, { 0, 0, 0}}, // (142, 141) + { 0, { 0, 0, 0}}, // (143, 141) + { 0, { 0, 0, 0}}, // (144, 141) + { 0, { 0, 0, 0}}, // (145, 141) + { 0, { 0, 0, 0}}, // (146, 141) + { 0, { 0, 0, 0}}, // (147, 141) + { 0, { 0, 0, 0}}, // (148, 141) + { 0, { 0, 0, 0}}, // (149, 141) + { 0, { 0, 0, 0}}, // (150, 141) + { 0, { 0, 0, 0}}, // (151, 141) + { 0, { 0, 0, 0}}, // (152, 141) + { 0, { 0, 0, 0}}, // (153, 141) + { 0, { 0, 0, 0}}, // (154, 141) + { 0, { 0, 0, 0}}, // (155, 141) + { 0, { 0, 0, 0}}, // (156, 141) + { 0, { 0, 0, 0}}, // (157, 141) + { 0, { 0, 0, 0}}, // (158, 141) + { 0, { 0, 0, 0}}, // (159, 141) + { 0, { 0, 0, 0}}, // (160, 141) + { 84, { 0, 0, 0}}, // (161, 141) + {128, { 0, 0, 0}}, // (162, 141) + {128, { 0, 0, 0}}, // (163, 141) + {128, { 0, 0, 0}}, // (164, 141) + {128, { 0, 0, 0}}, // (165, 141) + {128, { 0, 0, 0}}, // (166, 141) + {128, { 0, 0, 0}}, // (167, 141) + {128, { 0, 0, 0}}, // (168, 141) + {128, { 0, 0, 0}}, // (169, 141) + {128, { 0, 0, 0}}, // (170, 141) + {128, { 0, 0, 0}}, // (171, 141) + {128, { 0, 0, 0}}, // (172, 141) + {128, { 0, 0, 0}}, // (173, 141) + {128, { 0, 0, 0}}, // (174, 141) + {128, { 0, 0, 0}}, // (175, 141) + {128, { 0, 0, 0}}, // (176, 141) + {128, { 0, 0, 0}}, // (177, 141) + {128, { 0, 0, 0}}, // (178, 141) + {128, { 0, 0, 0}}, // (179, 141) + {128, { 0, 0, 0}}, // ( 0, 142) + {128, { 0, 0, 0}}, // ( 1, 142) + {128, { 0, 0, 0}}, // ( 2, 142) + {128, { 0, 0, 0}}, // ( 3, 142) + {128, { 0, 0, 0}}, // ( 4, 142) + {128, { 0, 0, 0}}, // ( 5, 142) + {128, { 0, 0, 0}}, // ( 6, 142) + {128, { 0, 0, 0}}, // ( 7, 142) + {128, { 0, 0, 0}}, // ( 8, 142) + {128, { 0, 0, 0}}, // ( 9, 142) + {128, { 0, 0, 0}}, // ( 10, 142) + {128, { 0, 0, 0}}, // ( 11, 142) + {128, { 0, 0, 0}}, // ( 12, 142) + {128, { 0, 0, 0}}, // ( 13, 142) + {128, { 0, 0, 0}}, // ( 14, 142) + {128, { 0, 0, 0}}, // ( 15, 142) + {128, { 0, 0, 0}}, // ( 16, 142) + {128, { 0, 0, 0}}, // ( 17, 142) + {128, { 0, 0, 0}}, // ( 18, 142) + { 49, { 0, 0, 0}}, // ( 19, 142) + { 0, { 0, 0, 0}}, // ( 20, 142) + { 0, { 0, 0, 0}}, // ( 21, 142) + { 0, { 0, 0, 0}}, // ( 22, 142) + { 0, { 0, 0, 0}}, // ( 23, 142) + { 0, { 0, 0, 0}}, // ( 24, 142) + { 0, { 0, 0, 0}}, // ( 25, 142) + { 0, { 0, 0, 0}}, // ( 26, 142) + { 0, { 0, 0, 0}}, // ( 27, 142) + { 0, { 0, 0, 0}}, // ( 28, 142) + { 0, { 0, 0, 0}}, // ( 29, 142) + { 0, { 0, 0, 0}}, // ( 30, 142) + { 0, { 0, 0, 0}}, // ( 31, 142) + { 0, { 0, 0, 0}}, // ( 32, 142) + { 0, { 0, 0, 0}}, // ( 33, 142) + { 0, { 0, 0, 0}}, // ( 34, 142) + { 0, { 0, 0, 0}}, // ( 35, 142) + { 0, { 0, 0, 0}}, // ( 36, 142) + { 0, { 0, 0, 0}}, // ( 37, 142) + { 0, { 0, 0, 0}}, // ( 38, 142) + { 0, { 0, 0, 0}}, // ( 39, 142) + { 0, { 0, 0, 0}}, // ( 40, 142) + { 0, { 0, 0, 0}}, // ( 41, 142) + { 0, { 0, 0, 0}}, // ( 42, 142) + { 0, { 0, 0, 0}}, // ( 43, 142) + { 0, { 0, 0, 0}}, // ( 44, 142) + { 0, { 0, 0, 0}}, // ( 45, 142) + { 0, { 0, 0, 0}}, // ( 46, 142) + { 0, { 0, 0, 0}}, // ( 47, 142) + { 0, { 0, 0, 0}}, // ( 48, 142) + { 0, { 0, 0, 0}}, // ( 49, 142) + { 0, { 0, 0, 0}}, // ( 50, 142) + { 0, { 0, 0, 0}}, // ( 51, 142) + { 0, { 0, 0, 0}}, // ( 52, 142) + { 0, { 0, 0, 0}}, // ( 53, 142) + { 0, { 0, 0, 0}}, // ( 54, 142) + { 0, { 0, 0, 0}}, // ( 55, 142) + { 0, { 0, 0, 0}}, // ( 56, 142) + { 0, { 0, 0, 0}}, // ( 57, 142) + { 0, { 0, 0, 0}}, // ( 58, 142) + { 0, { 0, 0, 0}}, // ( 59, 142) + { 0, { 0, 0, 0}}, // ( 60, 142) + { 0, { 0, 0, 0}}, // ( 61, 142) + { 0, { 0, 0, 0}}, // ( 62, 142) + { 0, { 0, 0, 0}}, // ( 63, 142) + { 0, { 0, 0, 0}}, // ( 64, 142) + { 0, { 0, 0, 0}}, // ( 65, 142) + { 0, { 0, 0, 0}}, // ( 66, 142) + { 0, { 0, 0, 0}}, // ( 67, 142) + { 0, { 0, 0, 0}}, // ( 68, 142) + { 0, { 0, 0, 0}}, // ( 69, 142) + { 0, { 0, 0, 0}}, // ( 70, 142) + { 0, { 0, 0, 0}}, // ( 71, 142) + { 0, { 0, 0, 0}}, // ( 72, 142) + { 0, { 0, 0, 0}}, // ( 73, 142) + { 0, { 0, 0, 0}}, // ( 74, 142) + { 0, { 0, 0, 0}}, // ( 75, 142) + { 0, { 0, 0, 0}}, // ( 76, 142) + { 0, { 0, 0, 0}}, // ( 77, 142) + { 0, { 0, 0, 0}}, // ( 78, 142) + { 0, { 0, 0, 0}}, // ( 79, 142) + { 0, { 0, 0, 0}}, // ( 80, 142) + { 0, { 0, 0, 0}}, // ( 81, 142) + { 0, { 0, 0, 0}}, // ( 82, 142) + { 0, { 0, 0, 0}}, // ( 83, 142) + { 0, { 0, 0, 0}}, // ( 84, 142) + { 0, { 0, 0, 0}}, // ( 85, 142) + { 0, { 0, 0, 0}}, // ( 86, 142) + { 0, { 0, 0, 0}}, // ( 87, 142) + { 0, { 0, 0, 0}}, // ( 88, 142) + { 0, { 0, 0, 0}}, // ( 89, 142) + { 0, { 0, 0, 0}}, // ( 90, 142) + { 0, { 0, 0, 0}}, // ( 91, 142) + { 0, { 0, 0, 0}}, // ( 92, 142) + { 0, { 0, 0, 0}}, // ( 93, 142) + { 0, { 0, 0, 0}}, // ( 94, 142) + { 0, { 0, 0, 0}}, // ( 95, 142) + { 0, { 0, 0, 0}}, // ( 96, 142) + { 0, { 0, 0, 0}}, // ( 97, 142) + { 0, { 0, 0, 0}}, // ( 98, 142) + { 0, { 0, 0, 0}}, // ( 99, 142) + { 0, { 0, 0, 0}}, // (100, 142) + { 0, { 0, 0, 0}}, // (101, 142) + { 0, { 0, 0, 0}}, // (102, 142) + { 0, { 0, 0, 0}}, // (103, 142) + { 0, { 0, 0, 0}}, // (104, 142) + { 0, { 0, 0, 0}}, // (105, 142) + { 0, { 0, 0, 0}}, // (106, 142) + { 0, { 0, 0, 0}}, // (107, 142) + { 0, { 0, 0, 0}}, // (108, 142) + { 0, { 0, 0, 0}}, // (109, 142) + { 0, { 0, 0, 0}}, // (110, 142) + { 0, { 0, 0, 0}}, // (111, 142) + { 0, { 0, 0, 0}}, // (112, 142) + { 0, { 0, 0, 0}}, // (113, 142) + { 0, { 0, 0, 0}}, // (114, 142) + { 0, { 0, 0, 0}}, // (115, 142) + { 0, { 0, 0, 0}}, // (116, 142) + { 0, { 0, 0, 0}}, // (117, 142) + { 0, { 0, 0, 0}}, // (118, 142) + { 0, { 0, 0, 0}}, // (119, 142) + { 0, { 0, 0, 0}}, // (120, 142) + { 0, { 0, 0, 0}}, // (121, 142) + { 0, { 0, 0, 0}}, // (122, 142) + { 0, { 0, 0, 0}}, // (123, 142) + { 0, { 0, 0, 0}}, // (124, 142) + { 0, { 0, 0, 0}}, // (125, 142) + { 0, { 0, 0, 0}}, // (126, 142) + { 0, { 0, 0, 0}}, // (127, 142) + { 0, { 0, 0, 0}}, // (128, 142) + { 0, { 0, 0, 0}}, // (129, 142) + { 0, { 0, 0, 0}}, // (130, 142) + { 0, { 0, 0, 0}}, // (131, 142) + { 0, { 0, 0, 0}}, // (132, 142) + { 0, { 0, 0, 0}}, // (133, 142) + { 0, { 0, 0, 0}}, // (134, 142) + { 0, { 0, 0, 0}}, // (135, 142) + { 0, { 0, 0, 0}}, // (136, 142) + { 0, { 0, 0, 0}}, // (137, 142) + { 0, { 0, 0, 0}}, // (138, 142) + { 0, { 0, 0, 0}}, // (139, 142) + { 0, { 0, 0, 0}}, // (140, 142) + { 0, { 0, 0, 0}}, // (141, 142) + { 0, { 0, 0, 0}}, // (142, 142) + { 0, { 0, 0, 0}}, // (143, 142) + { 0, { 0, 0, 0}}, // (144, 142) + { 0, { 0, 0, 0}}, // (145, 142) + { 0, { 0, 0, 0}}, // (146, 142) + { 0, { 0, 0, 0}}, // (147, 142) + { 0, { 0, 0, 0}}, // (148, 142) + { 0, { 0, 0, 0}}, // (149, 142) + { 0, { 0, 0, 0}}, // (150, 142) + { 0, { 0, 0, 0}}, // (151, 142) + { 0, { 0, 0, 0}}, // (152, 142) + { 0, { 0, 0, 0}}, // (153, 142) + { 0, { 0, 0, 0}}, // (154, 142) + { 0, { 0, 0, 0}}, // (155, 142) + { 0, { 0, 0, 0}}, // (156, 142) + { 0, { 0, 0, 0}}, // (157, 142) + { 0, { 0, 0, 0}}, // (158, 142) + { 0, { 0, 0, 0}}, // (159, 142) + { 49, { 0, 0, 0}}, // (160, 142) + {128, { 0, 0, 0}}, // (161, 142) + {128, { 0, 0, 0}}, // (162, 142) + {128, { 0, 0, 0}}, // (163, 142) + {128, { 0, 0, 0}}, // (164, 142) + {128, { 0, 0, 0}}, // (165, 142) + {128, { 0, 0, 0}}, // (166, 142) + {128, { 0, 0, 0}}, // (167, 142) + {128, { 0, 0, 0}}, // (168, 142) + {128, { 0, 0, 0}}, // (169, 142) + {128, { 0, 0, 0}}, // (170, 142) + {128, { 0, 0, 0}}, // (171, 142) + {128, { 0, 0, 0}}, // (172, 142) + {128, { 0, 0, 0}}, // (173, 142) + {128, { 0, 0, 0}}, // (174, 142) + {128, { 0, 0, 0}}, // (175, 142) + {128, { 0, 0, 0}}, // (176, 142) + {128, { 0, 0, 0}}, // (177, 142) + {128, { 0, 0, 0}}, // (178, 142) + {128, { 0, 0, 0}}, // (179, 142) + {128, { 0, 0, 0}}, // ( 0, 143) + {128, { 0, 0, 0}}, // ( 1, 143) + {128, { 0, 0, 0}}, // ( 2, 143) + {128, { 0, 0, 0}}, // ( 3, 143) + {128, { 0, 0, 0}}, // ( 4, 143) + {128, { 0, 0, 0}}, // ( 5, 143) + {128, { 0, 0, 0}}, // ( 6, 143) + {128, { 0, 0, 0}}, // ( 7, 143) + {128, { 0, 0, 0}}, // ( 8, 143) + {128, { 0, 0, 0}}, // ( 9, 143) + {128, { 0, 0, 0}}, // ( 10, 143) + {128, { 0, 0, 0}}, // ( 11, 143) + {128, { 0, 0, 0}}, // ( 12, 143) + {128, { 0, 0, 0}}, // ( 13, 143) + {128, { 0, 0, 0}}, // ( 14, 143) + {128, { 0, 0, 0}}, // ( 15, 143) + {128, { 0, 0, 0}}, // ( 16, 143) + {128, { 0, 0, 0}}, // ( 17, 143) + {128, { 0, 0, 0}}, // ( 18, 143) + {123, { 0, 0, 0}}, // ( 19, 143) + { 24, { 0, 0, 0}}, // ( 20, 143) + { 0, { 0, 0, 0}}, // ( 21, 143) + { 0, { 0, 0, 0}}, // ( 22, 143) + { 0, { 0, 0, 0}}, // ( 23, 143) + { 0, { 0, 0, 0}}, // ( 24, 143) + { 0, { 0, 0, 0}}, // ( 25, 143) + { 0, { 0, 0, 0}}, // ( 26, 143) + { 0, { 0, 0, 0}}, // ( 27, 143) + { 0, { 0, 0, 0}}, // ( 28, 143) + { 0, { 0, 0, 0}}, // ( 29, 143) + { 0, { 0, 0, 0}}, // ( 30, 143) + { 0, { 0, 0, 0}}, // ( 31, 143) + { 0, { 0, 0, 0}}, // ( 32, 143) + { 0, { 0, 0, 0}}, // ( 33, 143) + { 0, { 0, 0, 0}}, // ( 34, 143) + { 0, { 0, 0, 0}}, // ( 35, 143) + { 0, { 0, 0, 0}}, // ( 36, 143) + { 0, { 0, 0, 0}}, // ( 37, 143) + { 0, { 0, 0, 0}}, // ( 38, 143) + { 0, { 0, 0, 0}}, // ( 39, 143) + { 0, { 0, 0, 0}}, // ( 40, 143) + { 0, { 0, 0, 0}}, // ( 41, 143) + { 0, { 0, 0, 0}}, // ( 42, 143) + { 0, { 0, 0, 0}}, // ( 43, 143) + { 0, { 0, 0, 0}}, // ( 44, 143) + { 0, { 0, 0, 0}}, // ( 45, 143) + { 0, { 0, 0, 0}}, // ( 46, 143) + { 0, { 0, 0, 0}}, // ( 47, 143) + { 0, { 0, 0, 0}}, // ( 48, 143) + { 0, { 0, 0, 0}}, // ( 49, 143) + { 0, { 0, 0, 0}}, // ( 50, 143) + { 0, { 0, 0, 0}}, // ( 51, 143) + { 0, { 0, 0, 0}}, // ( 52, 143) + { 0, { 0, 0, 0}}, // ( 53, 143) + { 0, { 0, 0, 0}}, // ( 54, 143) + { 0, { 0, 0, 0}}, // ( 55, 143) + { 0, { 0, 0, 0}}, // ( 56, 143) + { 0, { 0, 0, 0}}, // ( 57, 143) + { 0, { 0, 0, 0}}, // ( 58, 143) + { 0, { 0, 0, 0}}, // ( 59, 143) + { 0, { 0, 0, 0}}, // ( 60, 143) + { 0, { 0, 0, 0}}, // ( 61, 143) + { 0, { 0, 0, 0}}, // ( 62, 143) + { 0, { 0, 0, 0}}, // ( 63, 143) + { 0, { 0, 0, 0}}, // ( 64, 143) + { 0, { 0, 0, 0}}, // ( 65, 143) + { 0, { 0, 0, 0}}, // ( 66, 143) + { 0, { 0, 0, 0}}, // ( 67, 143) + { 0, { 0, 0, 0}}, // ( 68, 143) + { 0, { 0, 0, 0}}, // ( 69, 143) + { 0, { 0, 0, 0}}, // ( 70, 143) + { 0, { 0, 0, 0}}, // ( 71, 143) + { 0, { 0, 0, 0}}, // ( 72, 143) + { 0, { 0, 0, 0}}, // ( 73, 143) + { 0, { 0, 0, 0}}, // ( 74, 143) + { 0, { 0, 0, 0}}, // ( 75, 143) + { 0, { 0, 0, 0}}, // ( 76, 143) + { 0, { 0, 0, 0}}, // ( 77, 143) + { 0, { 0, 0, 0}}, // ( 78, 143) + { 0, { 0, 0, 0}}, // ( 79, 143) + { 0, { 0, 0, 0}}, // ( 80, 143) + { 0, { 0, 0, 0}}, // ( 81, 143) + { 0, { 0, 0, 0}}, // ( 82, 143) + { 0, { 0, 0, 0}}, // ( 83, 143) + { 0, { 0, 0, 0}}, // ( 84, 143) + { 0, { 0, 0, 0}}, // ( 85, 143) + { 0, { 0, 0, 0}}, // ( 86, 143) + { 0, { 0, 0, 0}}, // ( 87, 143) + { 0, { 0, 0, 0}}, // ( 88, 143) + { 0, { 0, 0, 0}}, // ( 89, 143) + { 0, { 0, 0, 0}}, // ( 90, 143) + { 0, { 0, 0, 0}}, // ( 91, 143) + { 0, { 0, 0, 0}}, // ( 92, 143) + { 0, { 0, 0, 0}}, // ( 93, 143) + { 0, { 0, 0, 0}}, // ( 94, 143) + { 0, { 0, 0, 0}}, // ( 95, 143) + { 0, { 0, 0, 0}}, // ( 96, 143) + { 0, { 0, 0, 0}}, // ( 97, 143) + { 0, { 0, 0, 0}}, // ( 98, 143) + { 0, { 0, 0, 0}}, // ( 99, 143) + { 0, { 0, 0, 0}}, // (100, 143) + { 0, { 0, 0, 0}}, // (101, 143) + { 0, { 0, 0, 0}}, // (102, 143) + { 0, { 0, 0, 0}}, // (103, 143) + { 0, { 0, 0, 0}}, // (104, 143) + { 0, { 0, 0, 0}}, // (105, 143) + { 0, { 0, 0, 0}}, // (106, 143) + { 0, { 0, 0, 0}}, // (107, 143) + { 0, { 0, 0, 0}}, // (108, 143) + { 0, { 0, 0, 0}}, // (109, 143) + { 0, { 0, 0, 0}}, // (110, 143) + { 0, { 0, 0, 0}}, // (111, 143) + { 0, { 0, 0, 0}}, // (112, 143) + { 0, { 0, 0, 0}}, // (113, 143) + { 0, { 0, 0, 0}}, // (114, 143) + { 0, { 0, 0, 0}}, // (115, 143) + { 0, { 0, 0, 0}}, // (116, 143) + { 0, { 0, 0, 0}}, // (117, 143) + { 0, { 0, 0, 0}}, // (118, 143) + { 0, { 0, 0, 0}}, // (119, 143) + { 0, { 0, 0, 0}}, // (120, 143) + { 0, { 0, 0, 0}}, // (121, 143) + { 0, { 0, 0, 0}}, // (122, 143) + { 0, { 0, 0, 0}}, // (123, 143) + { 0, { 0, 0, 0}}, // (124, 143) + { 0, { 0, 0, 0}}, // (125, 143) + { 0, { 0, 0, 0}}, // (126, 143) + { 0, { 0, 0, 0}}, // (127, 143) + { 0, { 0, 0, 0}}, // (128, 143) + { 0, { 0, 0, 0}}, // (129, 143) + { 0, { 0, 0, 0}}, // (130, 143) + { 0, { 0, 0, 0}}, // (131, 143) + { 0, { 0, 0, 0}}, // (132, 143) + { 0, { 0, 0, 0}}, // (133, 143) + { 0, { 0, 0, 0}}, // (134, 143) + { 0, { 0, 0, 0}}, // (135, 143) + { 0, { 0, 0, 0}}, // (136, 143) + { 0, { 0, 0, 0}}, // (137, 143) + { 0, { 0, 0, 0}}, // (138, 143) + { 0, { 0, 0, 0}}, // (139, 143) + { 0, { 0, 0, 0}}, // (140, 143) + { 0, { 0, 0, 0}}, // (141, 143) + { 0, { 0, 0, 0}}, // (142, 143) + { 0, { 0, 0, 0}}, // (143, 143) + { 0, { 0, 0, 0}}, // (144, 143) + { 0, { 0, 0, 0}}, // (145, 143) + { 0, { 0, 0, 0}}, // (146, 143) + { 0, { 0, 0, 0}}, // (147, 143) + { 0, { 0, 0, 0}}, // (148, 143) + { 0, { 0, 0, 0}}, // (149, 143) + { 0, { 0, 0, 0}}, // (150, 143) + { 0, { 0, 0, 0}}, // (151, 143) + { 0, { 0, 0, 0}}, // (152, 143) + { 0, { 0, 0, 0}}, // (153, 143) + { 0, { 0, 0, 0}}, // (154, 143) + { 0, { 0, 0, 0}}, // (155, 143) + { 0, { 0, 0, 0}}, // (156, 143) + { 0, { 0, 0, 0}}, // (157, 143) + { 0, { 0, 0, 0}}, // (158, 143) + { 24, { 0, 0, 0}}, // (159, 143) + {123, { 0, 0, 0}}, // (160, 143) + {128, { 0, 0, 0}}, // (161, 143) + {128, { 0, 0, 0}}, // (162, 143) + {128, { 0, 0, 0}}, // (163, 143) + {128, { 0, 0, 0}}, // (164, 143) + {128, { 0, 0, 0}}, // (165, 143) + {128, { 0, 0, 0}}, // (166, 143) + {128, { 0, 0, 0}}, // (167, 143) + {128, { 0, 0, 0}}, // (168, 143) + {128, { 0, 0, 0}}, // (169, 143) + {128, { 0, 0, 0}}, // (170, 143) + {128, { 0, 0, 0}}, // (171, 143) + {128, { 0, 0, 0}}, // (172, 143) + {128, { 0, 0, 0}}, // (173, 143) + {128, { 0, 0, 0}}, // (174, 143) + {128, { 0, 0, 0}}, // (175, 143) + {128, { 0, 0, 0}}, // (176, 143) + {128, { 0, 0, 0}}, // (177, 143) + {128, { 0, 0, 0}}, // (178, 143) + {128, { 0, 0, 0}}, // (179, 143) + {128, { 0, 0, 0}}, // ( 0, 144) + {128, { 0, 0, 0}}, // ( 1, 144) + {128, { 0, 0, 0}}, // ( 2, 144) + {128, { 0, 0, 0}}, // ( 3, 144) + {128, { 0, 0, 0}}, // ( 4, 144) + {128, { 0, 0, 0}}, // ( 5, 144) + {128, { 0, 0, 0}}, // ( 6, 144) + {128, { 0, 0, 0}}, // ( 7, 144) + {128, { 0, 0, 0}}, // ( 8, 144) + {128, { 0, 0, 0}}, // ( 9, 144) + {128, { 0, 0, 0}}, // ( 10, 144) + {128, { 0, 0, 0}}, // ( 11, 144) + {128, { 0, 0, 0}}, // ( 12, 144) + {128, { 0, 0, 0}}, // ( 13, 144) + {128, { 0, 0, 0}}, // ( 14, 144) + {128, { 0, 0, 0}}, // ( 15, 144) + {128, { 0, 0, 0}}, // ( 16, 144) + {128, { 0, 0, 0}}, // ( 17, 144) + {128, { 0, 0, 0}}, // ( 18, 144) + {128, { 0, 0, 0}}, // ( 19, 144) + {111, { 0, 0, 0}}, // ( 20, 144) + { 9, { 0, 0, 0}}, // ( 21, 144) + { 0, { 0, 0, 0}}, // ( 22, 144) + { 0, { 0, 0, 0}}, // ( 23, 144) + { 0, { 0, 0, 0}}, // ( 24, 144) + { 0, { 0, 0, 0}}, // ( 25, 144) + { 0, { 0, 0, 0}}, // ( 26, 144) + { 0, { 0, 0, 0}}, // ( 27, 144) + { 0, { 0, 0, 0}}, // ( 28, 144) + { 0, { 0, 0, 0}}, // ( 29, 144) + { 0, { 0, 0, 0}}, // ( 30, 144) + { 0, { 0, 0, 0}}, // ( 31, 144) + { 0, { 0, 0, 0}}, // ( 32, 144) + { 0, { 0, 0, 0}}, // ( 33, 144) + { 0, { 0, 0, 0}}, // ( 34, 144) + { 0, { 0, 0, 0}}, // ( 35, 144) + { 0, { 0, 0, 0}}, // ( 36, 144) + { 0, { 0, 0, 0}}, // ( 37, 144) + { 0, { 0, 0, 0}}, // ( 38, 144) + { 0, { 0, 0, 0}}, // ( 39, 144) + { 0, { 0, 0, 0}}, // ( 40, 144) + { 0, { 0, 0, 0}}, // ( 41, 144) + { 0, { 0, 0, 0}}, // ( 42, 144) + { 0, { 0, 0, 0}}, // ( 43, 144) + { 0, { 0, 0, 0}}, // ( 44, 144) + { 0, { 0, 0, 0}}, // ( 45, 144) + { 0, { 0, 0, 0}}, // ( 46, 144) + { 0, { 0, 0, 0}}, // ( 47, 144) + { 0, { 0, 0, 0}}, // ( 48, 144) + { 0, { 0, 0, 0}}, // ( 49, 144) + { 0, { 0, 0, 0}}, // ( 50, 144) + { 0, { 0, 0, 0}}, // ( 51, 144) + { 0, { 0, 0, 0}}, // ( 52, 144) + { 0, { 0, 0, 0}}, // ( 53, 144) + { 0, { 0, 0, 0}}, // ( 54, 144) + { 0, { 0, 0, 0}}, // ( 55, 144) + { 0, { 0, 0, 0}}, // ( 56, 144) + { 0, { 0, 0, 0}}, // ( 57, 144) + { 0, { 0, 0, 0}}, // ( 58, 144) + { 0, { 0, 0, 0}}, // ( 59, 144) + { 0, { 0, 0, 0}}, // ( 60, 144) + { 0, { 0, 0, 0}}, // ( 61, 144) + { 0, { 0, 0, 0}}, // ( 62, 144) + { 0, { 0, 0, 0}}, // ( 63, 144) + { 0, { 0, 0, 0}}, // ( 64, 144) + { 0, { 0, 0, 0}}, // ( 65, 144) + { 0, { 0, 0, 0}}, // ( 66, 144) + { 0, { 0, 0, 0}}, // ( 67, 144) + { 0, { 0, 0, 0}}, // ( 68, 144) + { 0, { 0, 0, 0}}, // ( 69, 144) + { 0, { 0, 0, 0}}, // ( 70, 144) + { 0, { 0, 0, 0}}, // ( 71, 144) + { 0, { 0, 0, 0}}, // ( 72, 144) + { 0, { 0, 0, 0}}, // ( 73, 144) + { 0, { 0, 0, 0}}, // ( 74, 144) + { 0, { 0, 0, 0}}, // ( 75, 144) + { 0, { 0, 0, 0}}, // ( 76, 144) + { 0, { 0, 0, 0}}, // ( 77, 144) + { 0, { 0, 0, 0}}, // ( 78, 144) + { 0, { 0, 0, 0}}, // ( 79, 144) + { 0, { 0, 0, 0}}, // ( 80, 144) + { 0, { 0, 0, 0}}, // ( 81, 144) + { 0, { 0, 0, 0}}, // ( 82, 144) + { 0, { 0, 0, 0}}, // ( 83, 144) + { 0, { 0, 0, 0}}, // ( 84, 144) + { 0, { 0, 0, 0}}, // ( 85, 144) + { 0, { 0, 0, 0}}, // ( 86, 144) + { 0, { 0, 0, 0}}, // ( 87, 144) + { 0, { 0, 0, 0}}, // ( 88, 144) + { 0, { 0, 0, 0}}, // ( 89, 144) + { 0, { 0, 0, 0}}, // ( 90, 144) + { 0, { 0, 0, 0}}, // ( 91, 144) + { 0, { 0, 0, 0}}, // ( 92, 144) + { 0, { 0, 0, 0}}, // ( 93, 144) + { 0, { 0, 0, 0}}, // ( 94, 144) + { 0, { 0, 0, 0}}, // ( 95, 144) + { 0, { 0, 0, 0}}, // ( 96, 144) + { 0, { 0, 0, 0}}, // ( 97, 144) + { 0, { 0, 0, 0}}, // ( 98, 144) + { 0, { 0, 0, 0}}, // ( 99, 144) + { 0, { 0, 0, 0}}, // (100, 144) + { 0, { 0, 0, 0}}, // (101, 144) + { 0, { 0, 0, 0}}, // (102, 144) + { 0, { 0, 0, 0}}, // (103, 144) + { 0, { 0, 0, 0}}, // (104, 144) + { 0, { 0, 0, 0}}, // (105, 144) + { 0, { 0, 0, 0}}, // (106, 144) + { 0, { 0, 0, 0}}, // (107, 144) + { 0, { 0, 0, 0}}, // (108, 144) + { 0, { 0, 0, 0}}, // (109, 144) + { 0, { 0, 0, 0}}, // (110, 144) + { 0, { 0, 0, 0}}, // (111, 144) + { 0, { 0, 0, 0}}, // (112, 144) + { 0, { 0, 0, 0}}, // (113, 144) + { 0, { 0, 0, 0}}, // (114, 144) + { 0, { 0, 0, 0}}, // (115, 144) + { 0, { 0, 0, 0}}, // (116, 144) + { 0, { 0, 0, 0}}, // (117, 144) + { 0, { 0, 0, 0}}, // (118, 144) + { 0, { 0, 0, 0}}, // (119, 144) + { 0, { 0, 0, 0}}, // (120, 144) + { 0, { 0, 0, 0}}, // (121, 144) + { 0, { 0, 0, 0}}, // (122, 144) + { 0, { 0, 0, 0}}, // (123, 144) + { 0, { 0, 0, 0}}, // (124, 144) + { 0, { 0, 0, 0}}, // (125, 144) + { 0, { 0, 0, 0}}, // (126, 144) + { 0, { 0, 0, 0}}, // (127, 144) + { 0, { 0, 0, 0}}, // (128, 144) + { 0, { 0, 0, 0}}, // (129, 144) + { 0, { 0, 0, 0}}, // (130, 144) + { 0, { 0, 0, 0}}, // (131, 144) + { 0, { 0, 0, 0}}, // (132, 144) + { 0, { 0, 0, 0}}, // (133, 144) + { 0, { 0, 0, 0}}, // (134, 144) + { 0, { 0, 0, 0}}, // (135, 144) + { 0, { 0, 0, 0}}, // (136, 144) + { 0, { 0, 0, 0}}, // (137, 144) + { 0, { 0, 0, 0}}, // (138, 144) + { 0, { 0, 0, 0}}, // (139, 144) + { 0, { 0, 0, 0}}, // (140, 144) + { 0, { 0, 0, 0}}, // (141, 144) + { 0, { 0, 0, 0}}, // (142, 144) + { 0, { 0, 0, 0}}, // (143, 144) + { 0, { 0, 0, 0}}, // (144, 144) + { 0, { 0, 0, 0}}, // (145, 144) + { 0, { 0, 0, 0}}, // (146, 144) + { 0, { 0, 0, 0}}, // (147, 144) + { 0, { 0, 0, 0}}, // (148, 144) + { 0, { 0, 0, 0}}, // (149, 144) + { 0, { 0, 0, 0}}, // (150, 144) + { 0, { 0, 0, 0}}, // (151, 144) + { 0, { 0, 0, 0}}, // (152, 144) + { 0, { 0, 0, 0}}, // (153, 144) + { 0, { 0, 0, 0}}, // (154, 144) + { 0, { 0, 0, 0}}, // (155, 144) + { 0, { 0, 0, 0}}, // (156, 144) + { 0, { 0, 0, 0}}, // (157, 144) + { 9, { 0, 0, 0}}, // (158, 144) + {111, { 0, 0, 0}}, // (159, 144) + {128, { 0, 0, 0}}, // (160, 144) + {128, { 0, 0, 0}}, // (161, 144) + {128, { 0, 0, 0}}, // (162, 144) + {128, { 0, 0, 0}}, // (163, 144) + {128, { 0, 0, 0}}, // (164, 144) + {128, { 0, 0, 0}}, // (165, 144) + {128, { 0, 0, 0}}, // (166, 144) + {128, { 0, 0, 0}}, // (167, 144) + {128, { 0, 0, 0}}, // (168, 144) + {128, { 0, 0, 0}}, // (169, 144) + {128, { 0, 0, 0}}, // (170, 144) + {128, { 0, 0, 0}}, // (171, 144) + {128, { 0, 0, 0}}, // (172, 144) + {128, { 0, 0, 0}}, // (173, 144) + {128, { 0, 0, 0}}, // (174, 144) + {128, { 0, 0, 0}}, // (175, 144) + {128, { 0, 0, 0}}, // (176, 144) + {128, { 0, 0, 0}}, // (177, 144) + {128, { 0, 0, 0}}, // (178, 144) + {128, { 0, 0, 0}}, // (179, 144) + {128, { 0, 0, 0}}, // ( 0, 145) + {128, { 0, 0, 0}}, // ( 1, 145) + {128, { 0, 0, 0}}, // ( 2, 145) + {128, { 0, 0, 0}}, // ( 3, 145) + {128, { 0, 0, 0}}, // ( 4, 145) + {128, { 0, 0, 0}}, // ( 5, 145) + {128, { 0, 0, 0}}, // ( 6, 145) + {128, { 0, 0, 0}}, // ( 7, 145) + {128, { 0, 0, 0}}, // ( 8, 145) + {128, { 0, 0, 0}}, // ( 9, 145) + {128, { 0, 0, 0}}, // ( 10, 145) + {128, { 0, 0, 0}}, // ( 11, 145) + {128, { 0, 0, 0}}, // ( 12, 145) + {128, { 0, 0, 0}}, // ( 13, 145) + {128, { 0, 0, 0}}, // ( 14, 145) + {128, { 0, 0, 0}}, // ( 15, 145) + {128, { 0, 0, 0}}, // ( 16, 145) + {128, { 0, 0, 0}}, // ( 17, 145) + {128, { 0, 0, 0}}, // ( 18, 145) + {128, { 0, 0, 0}}, // ( 19, 145) + {128, { 0, 0, 0}}, // ( 20, 145) + { 91, { 0, 0, 0}}, // ( 21, 145) + { 2, { 0, 0, 0}}, // ( 22, 145) + { 0, { 0, 0, 0}}, // ( 23, 145) + { 0, { 0, 0, 0}}, // ( 24, 145) + { 0, { 0, 0, 0}}, // ( 25, 145) + { 0, { 0, 0, 0}}, // ( 26, 145) + { 0, { 0, 0, 0}}, // ( 27, 145) + { 0, { 0, 0, 0}}, // ( 28, 145) + { 0, { 0, 0, 0}}, // ( 29, 145) + { 0, { 0, 0, 0}}, // ( 30, 145) + { 0, { 0, 0, 0}}, // ( 31, 145) + { 0, { 0, 0, 0}}, // ( 32, 145) + { 0, { 0, 0, 0}}, // ( 33, 145) + { 0, { 0, 0, 0}}, // ( 34, 145) + { 0, { 0, 0, 0}}, // ( 35, 145) + { 0, { 0, 0, 0}}, // ( 36, 145) + { 0, { 0, 0, 0}}, // ( 37, 145) + { 0, { 0, 0, 0}}, // ( 38, 145) + { 0, { 0, 0, 0}}, // ( 39, 145) + { 0, { 0, 0, 0}}, // ( 40, 145) + { 0, { 0, 0, 0}}, // ( 41, 145) + { 0, { 0, 0, 0}}, // ( 42, 145) + { 0, { 0, 0, 0}}, // ( 43, 145) + { 0, { 0, 0, 0}}, // ( 44, 145) + { 0, { 0, 0, 0}}, // ( 45, 145) + { 0, { 0, 0, 0}}, // ( 46, 145) + { 0, { 0, 0, 0}}, // ( 47, 145) + { 0, { 0, 0, 0}}, // ( 48, 145) + { 0, { 0, 0, 0}}, // ( 49, 145) + { 0, { 0, 0, 0}}, // ( 50, 145) + { 0, { 0, 0, 0}}, // ( 51, 145) + { 0, { 0, 0, 0}}, // ( 52, 145) + { 0, { 0, 0, 0}}, // ( 53, 145) + { 0, { 0, 0, 0}}, // ( 54, 145) + { 0, { 0, 0, 0}}, // ( 55, 145) + { 0, { 0, 0, 0}}, // ( 56, 145) + { 0, { 0, 0, 0}}, // ( 57, 145) + { 0, { 0, 0, 0}}, // ( 58, 145) + { 0, { 0, 0, 0}}, // ( 59, 145) + { 0, { 0, 0, 0}}, // ( 60, 145) + { 0, { 0, 0, 0}}, // ( 61, 145) + { 0, { 0, 0, 0}}, // ( 62, 145) + { 0, { 0, 0, 0}}, // ( 63, 145) + { 0, { 0, 0, 0}}, // ( 64, 145) + { 0, { 0, 0, 0}}, // ( 65, 145) + { 0, { 0, 0, 0}}, // ( 66, 145) + { 0, { 0, 0, 0}}, // ( 67, 145) + { 0, { 0, 0, 0}}, // ( 68, 145) + { 0, { 0, 0, 0}}, // ( 69, 145) + { 0, { 0, 0, 0}}, // ( 70, 145) + { 0, { 0, 0, 0}}, // ( 71, 145) + { 0, { 0, 0, 0}}, // ( 72, 145) + { 0, { 0, 0, 0}}, // ( 73, 145) + { 0, { 0, 0, 0}}, // ( 74, 145) + { 0, { 0, 0, 0}}, // ( 75, 145) + { 0, { 0, 0, 0}}, // ( 76, 145) + { 0, { 0, 0, 0}}, // ( 77, 145) + { 0, { 0, 0, 0}}, // ( 78, 145) + { 0, { 0, 0, 0}}, // ( 79, 145) + { 0, { 0, 0, 0}}, // ( 80, 145) + { 0, { 0, 0, 0}}, // ( 81, 145) + { 0, { 0, 0, 0}}, // ( 82, 145) + { 0, { 0, 0, 0}}, // ( 83, 145) + { 0, { 0, 0, 0}}, // ( 84, 145) + { 0, { 0, 0, 0}}, // ( 85, 145) + { 0, { 0, 0, 0}}, // ( 86, 145) + { 0, { 0, 0, 0}}, // ( 87, 145) + { 0, { 0, 0, 0}}, // ( 88, 145) + { 0, { 0, 0, 0}}, // ( 89, 145) + { 0, { 0, 0, 0}}, // ( 90, 145) + { 0, { 0, 0, 0}}, // ( 91, 145) + { 0, { 0, 0, 0}}, // ( 92, 145) + { 0, { 0, 0, 0}}, // ( 93, 145) + { 0, { 0, 0, 0}}, // ( 94, 145) + { 0, { 0, 0, 0}}, // ( 95, 145) + { 0, { 0, 0, 0}}, // ( 96, 145) + { 0, { 0, 0, 0}}, // ( 97, 145) + { 0, { 0, 0, 0}}, // ( 98, 145) + { 0, { 0, 0, 0}}, // ( 99, 145) + { 0, { 0, 0, 0}}, // (100, 145) + { 0, { 0, 0, 0}}, // (101, 145) + { 0, { 0, 0, 0}}, // (102, 145) + { 0, { 0, 0, 0}}, // (103, 145) + { 0, { 0, 0, 0}}, // (104, 145) + { 0, { 0, 0, 0}}, // (105, 145) + { 0, { 0, 0, 0}}, // (106, 145) + { 0, { 0, 0, 0}}, // (107, 145) + { 0, { 0, 0, 0}}, // (108, 145) + { 0, { 0, 0, 0}}, // (109, 145) + { 0, { 0, 0, 0}}, // (110, 145) + { 0, { 0, 0, 0}}, // (111, 145) + { 0, { 0, 0, 0}}, // (112, 145) + { 0, { 0, 0, 0}}, // (113, 145) + { 0, { 0, 0, 0}}, // (114, 145) + { 0, { 0, 0, 0}}, // (115, 145) + { 0, { 0, 0, 0}}, // (116, 145) + { 0, { 0, 0, 0}}, // (117, 145) + { 0, { 0, 0, 0}}, // (118, 145) + { 0, { 0, 0, 0}}, // (119, 145) + { 0, { 0, 0, 0}}, // (120, 145) + { 0, { 0, 0, 0}}, // (121, 145) + { 0, { 0, 0, 0}}, // (122, 145) + { 0, { 0, 0, 0}}, // (123, 145) + { 0, { 0, 0, 0}}, // (124, 145) + { 0, { 0, 0, 0}}, // (125, 145) + { 0, { 0, 0, 0}}, // (126, 145) + { 0, { 0, 0, 0}}, // (127, 145) + { 0, { 0, 0, 0}}, // (128, 145) + { 0, { 0, 0, 0}}, // (129, 145) + { 0, { 0, 0, 0}}, // (130, 145) + { 0, { 0, 0, 0}}, // (131, 145) + { 0, { 0, 0, 0}}, // (132, 145) + { 0, { 0, 0, 0}}, // (133, 145) + { 0, { 0, 0, 0}}, // (134, 145) + { 0, { 0, 0, 0}}, // (135, 145) + { 0, { 0, 0, 0}}, // (136, 145) + { 0, { 0, 0, 0}}, // (137, 145) + { 0, { 0, 0, 0}}, // (138, 145) + { 0, { 0, 0, 0}}, // (139, 145) + { 0, { 0, 0, 0}}, // (140, 145) + { 0, { 0, 0, 0}}, // (141, 145) + { 0, { 0, 0, 0}}, // (142, 145) + { 0, { 0, 0, 0}}, // (143, 145) + { 0, { 0, 0, 0}}, // (144, 145) + { 0, { 0, 0, 0}}, // (145, 145) + { 0, { 0, 0, 0}}, // (146, 145) + { 0, { 0, 0, 0}}, // (147, 145) + { 0, { 0, 0, 0}}, // (148, 145) + { 0, { 0, 0, 0}}, // (149, 145) + { 0, { 0, 0, 0}}, // (150, 145) + { 0, { 0, 0, 0}}, // (151, 145) + { 0, { 0, 0, 0}}, // (152, 145) + { 0, { 0, 0, 0}}, // (153, 145) + { 0, { 0, 0, 0}}, // (154, 145) + { 0, { 0, 0, 0}}, // (155, 145) + { 0, { 0, 0, 0}}, // (156, 145) + { 1, { 0, 0, 0}}, // (157, 145) + { 91, { 0, 0, 0}}, // (158, 145) + {128, { 0, 0, 0}}, // (159, 145) + {128, { 0, 0, 0}}, // (160, 145) + {128, { 0, 0, 0}}, // (161, 145) + {128, { 0, 0, 0}}, // (162, 145) + {128, { 0, 0, 0}}, // (163, 145) + {128, { 0, 0, 0}}, // (164, 145) + {128, { 0, 0, 0}}, // (165, 145) + {128, { 0, 0, 0}}, // (166, 145) + {128, { 0, 0, 0}}, // (167, 145) + {128, { 0, 0, 0}}, // (168, 145) + {128, { 0, 0, 0}}, // (169, 145) + {128, { 0, 0, 0}}, // (170, 145) + {128, { 0, 0, 0}}, // (171, 145) + {128, { 0, 0, 0}}, // (172, 145) + {128, { 0, 0, 0}}, // (173, 145) + {128, { 0, 0, 0}}, // (174, 145) + {128, { 0, 0, 0}}, // (175, 145) + {128, { 0, 0, 0}}, // (176, 145) + {128, { 0, 0, 0}}, // (177, 145) + {128, { 0, 0, 0}}, // (178, 145) + {128, { 0, 0, 0}}, // (179, 145) + {128, { 0, 0, 0}}, // ( 0, 146) + {128, { 0, 0, 0}}, // ( 1, 146) + {128, { 0, 0, 0}}, // ( 2, 146) + {128, { 0, 0, 0}}, // ( 3, 146) + {128, { 0, 0, 0}}, // ( 4, 146) + {128, { 0, 0, 0}}, // ( 5, 146) + {128, { 0, 0, 0}}, // ( 6, 146) + {128, { 0, 0, 0}}, // ( 7, 146) + {128, { 0, 0, 0}}, // ( 8, 146) + {128, { 0, 0, 0}}, // ( 9, 146) + {128, { 0, 0, 0}}, // ( 10, 146) + {128, { 0, 0, 0}}, // ( 11, 146) + {128, { 0, 0, 0}}, // ( 12, 146) + {128, { 0, 0, 0}}, // ( 13, 146) + {128, { 0, 0, 0}}, // ( 14, 146) + {128, { 0, 0, 0}}, // ( 15, 146) + {128, { 0, 0, 0}}, // ( 16, 146) + {128, { 0, 0, 0}}, // ( 17, 146) + {128, { 0, 0, 0}}, // ( 18, 146) + {128, { 0, 0, 0}}, // ( 19, 146) + {128, { 0, 0, 0}}, // ( 20, 146) + {128, { 0, 0, 0}}, // ( 21, 146) + { 68, { 0, 0, 0}}, // ( 22, 146) + { 0, { 0, 0, 0}}, // ( 23, 146) + { 0, { 0, 0, 0}}, // ( 24, 146) + { 0, { 0, 0, 0}}, // ( 25, 146) + { 0, { 0, 0, 0}}, // ( 26, 146) + { 0, { 0, 0, 0}}, // ( 27, 146) + { 0, { 0, 0, 0}}, // ( 28, 146) + { 0, { 0, 0, 0}}, // ( 29, 146) + { 0, { 0, 0, 0}}, // ( 30, 146) + { 0, { 0, 0, 0}}, // ( 31, 146) + { 0, { 0, 0, 0}}, // ( 32, 146) + { 0, { 0, 0, 0}}, // ( 33, 146) + { 0, { 0, 0, 0}}, // ( 34, 146) + { 0, { 0, 0, 0}}, // ( 35, 146) + { 0, { 0, 0, 0}}, // ( 36, 146) + { 0, { 0, 0, 0}}, // ( 37, 146) + { 0, { 0, 0, 0}}, // ( 38, 146) + { 0, { 0, 0, 0}}, // ( 39, 146) + { 0, { 0, 0, 0}}, // ( 40, 146) + { 0, { 0, 0, 0}}, // ( 41, 146) + { 0, { 0, 0, 0}}, // ( 42, 146) + { 0, { 0, 0, 0}}, // ( 43, 146) + { 0, { 0, 0, 0}}, // ( 44, 146) + { 0, { 0, 0, 0}}, // ( 45, 146) + { 0, { 0, 0, 0}}, // ( 46, 146) + { 0, { 0, 0, 0}}, // ( 47, 146) + { 0, { 0, 0, 0}}, // ( 48, 146) + { 0, { 0, 0, 0}}, // ( 49, 146) + { 0, { 0, 0, 0}}, // ( 50, 146) + { 0, { 0, 0, 0}}, // ( 51, 146) + { 0, { 0, 0, 0}}, // ( 52, 146) + { 0, { 0, 0, 0}}, // ( 53, 146) + { 0, { 0, 0, 0}}, // ( 54, 146) + { 0, { 0, 0, 0}}, // ( 55, 146) + { 0, { 0, 0, 0}}, // ( 56, 146) + { 0, { 0, 0, 0}}, // ( 57, 146) + { 0, { 0, 0, 0}}, // ( 58, 146) + { 0, { 0, 0, 0}}, // ( 59, 146) + { 0, { 0, 0, 0}}, // ( 60, 146) + { 0, { 0, 0, 0}}, // ( 61, 146) + { 0, { 0, 0, 0}}, // ( 62, 146) + { 0, { 0, 0, 0}}, // ( 63, 146) + { 0, { 0, 0, 0}}, // ( 64, 146) + { 0, { 0, 0, 0}}, // ( 65, 146) + { 0, { 0, 0, 0}}, // ( 66, 146) + { 0, { 0, 0, 0}}, // ( 67, 146) + { 0, { 0, 0, 0}}, // ( 68, 146) + { 0, { 0, 0, 0}}, // ( 69, 146) + { 0, { 0, 0, 0}}, // ( 70, 146) + { 0, { 0, 0, 0}}, // ( 71, 146) + { 0, { 0, 0, 0}}, // ( 72, 146) + { 0, { 0, 0, 0}}, // ( 73, 146) + { 0, { 0, 0, 0}}, // ( 74, 146) + { 0, { 0, 0, 0}}, // ( 75, 146) + { 0, { 0, 0, 0}}, // ( 76, 146) + { 0, { 0, 0, 0}}, // ( 77, 146) + { 0, { 0, 0, 0}}, // ( 78, 146) + { 0, { 0, 0, 0}}, // ( 79, 146) + { 0, { 0, 0, 0}}, // ( 80, 146) + { 0, { 0, 0, 0}}, // ( 81, 146) + { 0, { 0, 0, 0}}, // ( 82, 146) + { 0, { 0, 0, 0}}, // ( 83, 146) + { 0, { 0, 0, 0}}, // ( 84, 146) + { 0, { 0, 0, 0}}, // ( 85, 146) + { 0, { 0, 0, 0}}, // ( 86, 146) + { 0, { 0, 0, 0}}, // ( 87, 146) + { 0, { 0, 0, 0}}, // ( 88, 146) + { 0, { 0, 0, 0}}, // ( 89, 146) + { 0, { 0, 0, 0}}, // ( 90, 146) + { 0, { 0, 0, 0}}, // ( 91, 146) + { 0, { 0, 0, 0}}, // ( 92, 146) + { 0, { 0, 0, 0}}, // ( 93, 146) + { 0, { 0, 0, 0}}, // ( 94, 146) + { 0, { 0, 0, 0}}, // ( 95, 146) + { 0, { 0, 0, 0}}, // ( 96, 146) + { 0, { 0, 0, 0}}, // ( 97, 146) + { 0, { 0, 0, 0}}, // ( 98, 146) + { 0, { 0, 0, 0}}, // ( 99, 146) + { 0, { 0, 0, 0}}, // (100, 146) + { 0, { 0, 0, 0}}, // (101, 146) + { 0, { 0, 0, 0}}, // (102, 146) + { 0, { 0, 0, 0}}, // (103, 146) + { 0, { 0, 0, 0}}, // (104, 146) + { 0, { 0, 0, 0}}, // (105, 146) + { 0, { 0, 0, 0}}, // (106, 146) + { 0, { 0, 0, 0}}, // (107, 146) + { 0, { 0, 0, 0}}, // (108, 146) + { 0, { 0, 0, 0}}, // (109, 146) + { 0, { 0, 0, 0}}, // (110, 146) + { 0, { 0, 0, 0}}, // (111, 146) + { 0, { 0, 0, 0}}, // (112, 146) + { 0, { 0, 0, 0}}, // (113, 146) + { 0, { 0, 0, 0}}, // (114, 146) + { 0, { 0, 0, 0}}, // (115, 146) + { 0, { 0, 0, 0}}, // (116, 146) + { 0, { 0, 0, 0}}, // (117, 146) + { 0, { 0, 0, 0}}, // (118, 146) + { 0, { 0, 0, 0}}, // (119, 146) + { 0, { 0, 0, 0}}, // (120, 146) + { 0, { 0, 0, 0}}, // (121, 146) + { 0, { 0, 0, 0}}, // (122, 146) + { 0, { 0, 0, 0}}, // (123, 146) + { 0, { 0, 0, 0}}, // (124, 146) + { 0, { 0, 0, 0}}, // (125, 146) + { 0, { 0, 0, 0}}, // (126, 146) + { 0, { 0, 0, 0}}, // (127, 146) + { 0, { 0, 0, 0}}, // (128, 146) + { 0, { 0, 0, 0}}, // (129, 146) + { 0, { 0, 0, 0}}, // (130, 146) + { 0, { 0, 0, 0}}, // (131, 146) + { 0, { 0, 0, 0}}, // (132, 146) + { 0, { 0, 0, 0}}, // (133, 146) + { 0, { 0, 0, 0}}, // (134, 146) + { 0, { 0, 0, 0}}, // (135, 146) + { 0, { 0, 0, 0}}, // (136, 146) + { 0, { 0, 0, 0}}, // (137, 146) + { 0, { 0, 0, 0}}, // (138, 146) + { 0, { 0, 0, 0}}, // (139, 146) + { 0, { 0, 0, 0}}, // (140, 146) + { 0, { 0, 0, 0}}, // (141, 146) + { 0, { 0, 0, 0}}, // (142, 146) + { 0, { 0, 0, 0}}, // (143, 146) + { 0, { 0, 0, 0}}, // (144, 146) + { 0, { 0, 0, 0}}, // (145, 146) + { 0, { 0, 0, 0}}, // (146, 146) + { 0, { 0, 0, 0}}, // (147, 146) + { 0, { 0, 0, 0}}, // (148, 146) + { 0, { 0, 0, 0}}, // (149, 146) + { 0, { 0, 0, 0}}, // (150, 146) + { 0, { 0, 0, 0}}, // (151, 146) + { 0, { 0, 0, 0}}, // (152, 146) + { 0, { 0, 0, 0}}, // (153, 146) + { 0, { 0, 0, 0}}, // (154, 146) + { 0, { 0, 0, 0}}, // (155, 146) + { 0, { 0, 0, 0}}, // (156, 146) + { 68, { 0, 0, 0}}, // (157, 146) + {128, { 0, 0, 0}}, // (158, 146) + {128, { 0, 0, 0}}, // (159, 146) + {128, { 0, 0, 0}}, // (160, 146) + {128, { 0, 0, 0}}, // (161, 146) + {128, { 0, 0, 0}}, // (162, 146) + {128, { 0, 0, 0}}, // (163, 146) + {128, { 0, 0, 0}}, // (164, 146) + {128, { 0, 0, 0}}, // (165, 146) + {128, { 0, 0, 0}}, // (166, 146) + {128, { 0, 0, 0}}, // (167, 146) + {128, { 0, 0, 0}}, // (168, 146) + {128, { 0, 0, 0}}, // (169, 146) + {128, { 0, 0, 0}}, // (170, 146) + {128, { 0, 0, 0}}, // (171, 146) + {128, { 0, 0, 0}}, // (172, 146) + {128, { 0, 0, 0}}, // (173, 146) + {128, { 0, 0, 0}}, // (174, 146) + {128, { 0, 0, 0}}, // (175, 146) + {128, { 0, 0, 0}}, // (176, 146) + {128, { 0, 0, 0}}, // (177, 146) + {128, { 0, 0, 0}}, // (178, 146) + {128, { 0, 0, 0}}, // (179, 146) + {128, { 0, 0, 0}}, // ( 0, 147) + {128, { 0, 0, 0}}, // ( 1, 147) + {128, { 0, 0, 0}}, // ( 2, 147) + {128, { 0, 0, 0}}, // ( 3, 147) + {128, { 0, 0, 0}}, // ( 4, 147) + {128, { 0, 0, 0}}, // ( 5, 147) + {128, { 0, 0, 0}}, // ( 6, 147) + {128, { 0, 0, 0}}, // ( 7, 147) + {128, { 0, 0, 0}}, // ( 8, 147) + {128, { 0, 0, 0}}, // ( 9, 147) + {128, { 0, 0, 0}}, // ( 10, 147) + {128, { 0, 0, 0}}, // ( 11, 147) + {128, { 0, 0, 0}}, // ( 12, 147) + {128, { 0, 0, 0}}, // ( 13, 147) + {128, { 0, 0, 0}}, // ( 14, 147) + {128, { 0, 0, 0}}, // ( 15, 147) + {128, { 0, 0, 0}}, // ( 16, 147) + {128, { 0, 0, 0}}, // ( 17, 147) + {128, { 0, 0, 0}}, // ( 18, 147) + {128, { 0, 0, 0}}, // ( 19, 147) + {128, { 0, 0, 0}}, // ( 20, 147) + {128, { 0, 0, 0}}, // ( 21, 147) + {128, { 0, 0, 0}}, // ( 22, 147) + { 53, { 0, 0, 0}}, // ( 23, 147) + { 0, { 0, 0, 0}}, // ( 24, 147) + { 0, { 0, 0, 0}}, // ( 25, 147) + { 0, { 0, 0, 0}}, // ( 26, 147) + { 0, { 0, 0, 0}}, // ( 27, 147) + { 0, { 0, 0, 0}}, // ( 28, 147) + { 0, { 0, 0, 0}}, // ( 29, 147) + { 0, { 0, 0, 0}}, // ( 30, 147) + { 0, { 0, 0, 0}}, // ( 31, 147) + { 0, { 0, 0, 0}}, // ( 32, 147) + { 0, { 0, 0, 0}}, // ( 33, 147) + { 0, { 0, 0, 0}}, // ( 34, 147) + { 0, { 0, 0, 0}}, // ( 35, 147) + { 0, { 0, 0, 0}}, // ( 36, 147) + { 0, { 0, 0, 0}}, // ( 37, 147) + { 0, { 0, 0, 0}}, // ( 38, 147) + { 0, { 0, 0, 0}}, // ( 39, 147) + { 0, { 0, 0, 0}}, // ( 40, 147) + { 0, { 0, 0, 0}}, // ( 41, 147) + { 0, { 0, 0, 0}}, // ( 42, 147) + { 0, { 0, 0, 0}}, // ( 43, 147) + { 0, { 0, 0, 0}}, // ( 44, 147) + { 0, { 0, 0, 0}}, // ( 45, 147) + { 0, { 0, 0, 0}}, // ( 46, 147) + { 0, { 0, 0, 0}}, // ( 47, 147) + { 0, { 0, 0, 0}}, // ( 48, 147) + { 0, { 0, 0, 0}}, // ( 49, 147) + { 0, { 0, 0, 0}}, // ( 50, 147) + { 0, { 0, 0, 0}}, // ( 51, 147) + { 0, { 0, 0, 0}}, // ( 52, 147) + { 0, { 0, 0, 0}}, // ( 53, 147) + { 0, { 0, 0, 0}}, // ( 54, 147) + { 0, { 0, 0, 0}}, // ( 55, 147) + { 0, { 0, 0, 0}}, // ( 56, 147) + { 0, { 0, 0, 0}}, // ( 57, 147) + { 0, { 0, 0, 0}}, // ( 58, 147) + { 0, { 0, 0, 0}}, // ( 59, 147) + { 0, { 0, 0, 0}}, // ( 60, 147) + { 0, { 0, 0, 0}}, // ( 61, 147) + { 0, { 0, 0, 0}}, // ( 62, 147) + { 0, { 0, 0, 0}}, // ( 63, 147) + { 0, { 0, 0, 0}}, // ( 64, 147) + { 0, { 0, 0, 0}}, // ( 65, 147) + { 0, { 0, 0, 0}}, // ( 66, 147) + { 0, { 0, 0, 0}}, // ( 67, 147) + { 0, { 0, 0, 0}}, // ( 68, 147) + { 0, { 0, 0, 0}}, // ( 69, 147) + { 0, { 0, 0, 0}}, // ( 70, 147) + { 0, { 0, 0, 0}}, // ( 71, 147) + { 0, { 0, 0, 0}}, // ( 72, 147) + { 0, { 0, 0, 0}}, // ( 73, 147) + { 0, { 0, 0, 0}}, // ( 74, 147) + { 0, { 0, 0, 0}}, // ( 75, 147) + { 0, { 0, 0, 0}}, // ( 76, 147) + { 0, { 0, 0, 0}}, // ( 77, 147) + { 0, { 0, 0, 0}}, // ( 78, 147) + { 0, { 0, 0, 0}}, // ( 79, 147) + { 0, { 0, 0, 0}}, // ( 80, 147) + { 0, { 0, 0, 0}}, // ( 81, 147) + { 0, { 0, 0, 0}}, // ( 82, 147) + { 0, { 0, 0, 0}}, // ( 83, 147) + { 0, { 0, 0, 0}}, // ( 84, 147) + { 0, { 0, 0, 0}}, // ( 85, 147) + { 0, { 0, 0, 0}}, // ( 86, 147) + { 0, { 0, 0, 0}}, // ( 87, 147) + { 0, { 0, 0, 0}}, // ( 88, 147) + { 0, { 0, 0, 0}}, // ( 89, 147) + { 0, { 0, 0, 0}}, // ( 90, 147) + { 0, { 0, 0, 0}}, // ( 91, 147) + { 0, { 0, 0, 0}}, // ( 92, 147) + { 0, { 0, 0, 0}}, // ( 93, 147) + { 0, { 0, 0, 0}}, // ( 94, 147) + { 0, { 0, 0, 0}}, // ( 95, 147) + { 0, { 0, 0, 0}}, // ( 96, 147) + { 0, { 0, 0, 0}}, // ( 97, 147) + { 0, { 0, 0, 0}}, // ( 98, 147) + { 0, { 0, 0, 0}}, // ( 99, 147) + { 0, { 0, 0, 0}}, // (100, 147) + { 0, { 0, 0, 0}}, // (101, 147) + { 0, { 0, 0, 0}}, // (102, 147) + { 0, { 0, 0, 0}}, // (103, 147) + { 0, { 0, 0, 0}}, // (104, 147) + { 0, { 0, 0, 0}}, // (105, 147) + { 0, { 0, 0, 0}}, // (106, 147) + { 0, { 0, 0, 0}}, // (107, 147) + { 0, { 0, 0, 0}}, // (108, 147) + { 0, { 0, 0, 0}}, // (109, 147) + { 0, { 0, 0, 0}}, // (110, 147) + { 0, { 0, 0, 0}}, // (111, 147) + { 0, { 0, 0, 0}}, // (112, 147) + { 0, { 0, 0, 0}}, // (113, 147) + { 0, { 0, 0, 0}}, // (114, 147) + { 0, { 0, 0, 0}}, // (115, 147) + { 0, { 0, 0, 0}}, // (116, 147) + { 0, { 0, 0, 0}}, // (117, 147) + { 0, { 0, 0, 0}}, // (118, 147) + { 0, { 0, 0, 0}}, // (119, 147) + { 0, { 0, 0, 0}}, // (120, 147) + { 0, { 0, 0, 0}}, // (121, 147) + { 0, { 0, 0, 0}}, // (122, 147) + { 0, { 0, 0, 0}}, // (123, 147) + { 0, { 0, 0, 0}}, // (124, 147) + { 0, { 0, 0, 0}}, // (125, 147) + { 0, { 0, 0, 0}}, // (126, 147) + { 0, { 0, 0, 0}}, // (127, 147) + { 0, { 0, 0, 0}}, // (128, 147) + { 0, { 0, 0, 0}}, // (129, 147) + { 0, { 0, 0, 0}}, // (130, 147) + { 0, { 0, 0, 0}}, // (131, 147) + { 0, { 0, 0, 0}}, // (132, 147) + { 0, { 0, 0, 0}}, // (133, 147) + { 0, { 0, 0, 0}}, // (134, 147) + { 0, { 0, 0, 0}}, // (135, 147) + { 0, { 0, 0, 0}}, // (136, 147) + { 0, { 0, 0, 0}}, // (137, 147) + { 0, { 0, 0, 0}}, // (138, 147) + { 0, { 0, 0, 0}}, // (139, 147) + { 0, { 0, 0, 0}}, // (140, 147) + { 0, { 0, 0, 0}}, // (141, 147) + { 0, { 0, 0, 0}}, // (142, 147) + { 0, { 0, 0, 0}}, // (143, 147) + { 0, { 0, 0, 0}}, // (144, 147) + { 0, { 0, 0, 0}}, // (145, 147) + { 0, { 0, 0, 0}}, // (146, 147) + { 0, { 0, 0, 0}}, // (147, 147) + { 0, { 0, 0, 0}}, // (148, 147) + { 0, { 0, 0, 0}}, // (149, 147) + { 0, { 0, 0, 0}}, // (150, 147) + { 0, { 0, 0, 0}}, // (151, 147) + { 0, { 0, 0, 0}}, // (152, 147) + { 0, { 0, 0, 0}}, // (153, 147) + { 0, { 0, 0, 0}}, // (154, 147) + { 0, { 0, 0, 0}}, // (155, 147) + { 53, { 0, 0, 0}}, // (156, 147) + {128, { 0, 0, 0}}, // (157, 147) + {128, { 0, 0, 0}}, // (158, 147) + {128, { 0, 0, 0}}, // (159, 147) + {128, { 0, 0, 0}}, // (160, 147) + {128, { 0, 0, 0}}, // (161, 147) + {128, { 0, 0, 0}}, // (162, 147) + {128, { 0, 0, 0}}, // (163, 147) + {128, { 0, 0, 0}}, // (164, 147) + {128, { 0, 0, 0}}, // (165, 147) + {128, { 0, 0, 0}}, // (166, 147) + {128, { 0, 0, 0}}, // (167, 147) + {128, { 0, 0, 0}}, // (168, 147) + {128, { 0, 0, 0}}, // (169, 147) + {128, { 0, 0, 0}}, // (170, 147) + {128, { 0, 0, 0}}, // (171, 147) + {128, { 0, 0, 0}}, // (172, 147) + {128, { 0, 0, 0}}, // (173, 147) + {128, { 0, 0, 0}}, // (174, 147) + {128, { 0, 0, 0}}, // (175, 147) + {128, { 0, 0, 0}}, // (176, 147) + {128, { 0, 0, 0}}, // (177, 147) + {128, { 0, 0, 0}}, // (178, 147) + {128, { 0, 0, 0}}, // (179, 147) + {128, { 0, 0, 0}}, // ( 0, 148) + {128, { 0, 0, 0}}, // ( 1, 148) + {128, { 0, 0, 0}}, // ( 2, 148) + {128, { 0, 0, 0}}, // ( 3, 148) + {128, { 0, 0, 0}}, // ( 4, 148) + {128, { 0, 0, 0}}, // ( 5, 148) + {128, { 0, 0, 0}}, // ( 6, 148) + {128, { 0, 0, 0}}, // ( 7, 148) + {128, { 0, 0, 0}}, // ( 8, 148) + {128, { 0, 0, 0}}, // ( 9, 148) + {128, { 0, 0, 0}}, // ( 10, 148) + {128, { 0, 0, 0}}, // ( 11, 148) + {128, { 0, 0, 0}}, // ( 12, 148) + {128, { 0, 0, 0}}, // ( 13, 148) + {128, { 0, 0, 0}}, // ( 14, 148) + {128, { 0, 0, 0}}, // ( 15, 148) + {128, { 0, 0, 0}}, // ( 16, 148) + {128, { 0, 0, 0}}, // ( 17, 148) + {128, { 0, 0, 0}}, // ( 18, 148) + {128, { 0, 0, 0}}, // ( 19, 148) + {128, { 0, 0, 0}}, // ( 20, 148) + {128, { 0, 0, 0}}, // ( 21, 148) + {128, { 0, 0, 0}}, // ( 22, 148) + {126, { 0, 0, 0}}, // ( 23, 148) + { 39, { 0, 0, 0}}, // ( 24, 148) + { 0, { 0, 0, 0}}, // ( 25, 148) + { 0, { 0, 0, 0}}, // ( 26, 148) + { 0, { 0, 0, 0}}, // ( 27, 148) + { 0, { 0, 0, 0}}, // ( 28, 148) + { 0, { 0, 0, 0}}, // ( 29, 148) + { 0, { 0, 0, 0}}, // ( 30, 148) + { 0, { 0, 0, 0}}, // ( 31, 148) + { 0, { 0, 0, 0}}, // ( 32, 148) + { 0, { 0, 0, 0}}, // ( 33, 148) + { 0, { 0, 0, 0}}, // ( 34, 148) + { 0, { 0, 0, 0}}, // ( 35, 148) + { 0, { 0, 0, 0}}, // ( 36, 148) + { 0, { 0, 0, 0}}, // ( 37, 148) + { 0, { 0, 0, 0}}, // ( 38, 148) + { 0, { 0, 0, 0}}, // ( 39, 148) + { 0, { 0, 0, 0}}, // ( 40, 148) + { 0, { 0, 0, 0}}, // ( 41, 148) + { 0, { 0, 0, 0}}, // ( 42, 148) + { 0, { 0, 0, 0}}, // ( 43, 148) + { 0, { 0, 0, 0}}, // ( 44, 148) + { 0, { 0, 0, 0}}, // ( 45, 148) + { 0, { 0, 0, 0}}, // ( 46, 148) + { 0, { 0, 0, 0}}, // ( 47, 148) + { 0, { 0, 0, 0}}, // ( 48, 148) + { 0, { 0, 0, 0}}, // ( 49, 148) + { 0, { 0, 0, 0}}, // ( 50, 148) + { 0, { 0, 0, 0}}, // ( 51, 148) + { 0, { 0, 0, 0}}, // ( 52, 148) + { 0, { 0, 0, 0}}, // ( 53, 148) + { 0, { 0, 0, 0}}, // ( 54, 148) + { 0, { 0, 0, 0}}, // ( 55, 148) + { 0, { 0, 0, 0}}, // ( 56, 148) + { 0, { 0, 0, 0}}, // ( 57, 148) + { 0, { 0, 0, 0}}, // ( 58, 148) + { 0, { 0, 0, 0}}, // ( 59, 148) + { 0, { 0, 0, 0}}, // ( 60, 148) + { 0, { 0, 0, 0}}, // ( 61, 148) + { 0, { 0, 0, 0}}, // ( 62, 148) + { 0, { 0, 0, 0}}, // ( 63, 148) + { 0, { 0, 0, 0}}, // ( 64, 148) + { 0, { 0, 0, 0}}, // ( 65, 148) + { 0, { 0, 0, 0}}, // ( 66, 148) + { 0, { 0, 0, 0}}, // ( 67, 148) + { 0, { 0, 0, 0}}, // ( 68, 148) + { 0, { 0, 0, 0}}, // ( 69, 148) + { 0, { 0, 0, 0}}, // ( 70, 148) + { 0, { 0, 0, 0}}, // ( 71, 148) + { 0, { 0, 0, 0}}, // ( 72, 148) + { 0, { 0, 0, 0}}, // ( 73, 148) + { 0, { 0, 0, 0}}, // ( 74, 148) + { 0, { 0, 0, 0}}, // ( 75, 148) + { 0, { 0, 0, 0}}, // ( 76, 148) + { 0, { 0, 0, 0}}, // ( 77, 148) + { 0, { 0, 0, 0}}, // ( 78, 148) + { 0, { 0, 0, 0}}, // ( 79, 148) + { 0, { 0, 0, 0}}, // ( 80, 148) + { 0, { 0, 0, 0}}, // ( 81, 148) + { 0, { 0, 0, 0}}, // ( 82, 148) + { 0, { 0, 0, 0}}, // ( 83, 148) + { 0, { 0, 0, 0}}, // ( 84, 148) + { 0, { 0, 0, 0}}, // ( 85, 148) + { 0, { 0, 0, 0}}, // ( 86, 148) + { 0, { 0, 0, 0}}, // ( 87, 148) + { 0, { 0, 0, 0}}, // ( 88, 148) + { 0, { 0, 0, 0}}, // ( 89, 148) + { 0, { 0, 0, 0}}, // ( 90, 148) + { 0, { 0, 0, 0}}, // ( 91, 148) + { 0, { 0, 0, 0}}, // ( 92, 148) + { 0, { 0, 0, 0}}, // ( 93, 148) + { 0, { 0, 0, 0}}, // ( 94, 148) + { 0, { 0, 0, 0}}, // ( 95, 148) + { 0, { 0, 0, 0}}, // ( 96, 148) + { 0, { 0, 0, 0}}, // ( 97, 148) + { 0, { 0, 0, 0}}, // ( 98, 148) + { 0, { 0, 0, 0}}, // ( 99, 148) + { 0, { 0, 0, 0}}, // (100, 148) + { 0, { 0, 0, 0}}, // (101, 148) + { 0, { 0, 0, 0}}, // (102, 148) + { 0, { 0, 0, 0}}, // (103, 148) + { 0, { 0, 0, 0}}, // (104, 148) + { 0, { 0, 0, 0}}, // (105, 148) + { 0, { 0, 0, 0}}, // (106, 148) + { 0, { 0, 0, 0}}, // (107, 148) + { 0, { 0, 0, 0}}, // (108, 148) + { 0, { 0, 0, 0}}, // (109, 148) + { 0, { 0, 0, 0}}, // (110, 148) + { 0, { 0, 0, 0}}, // (111, 148) + { 0, { 0, 0, 0}}, // (112, 148) + { 0, { 0, 0, 0}}, // (113, 148) + { 0, { 0, 0, 0}}, // (114, 148) + { 0, { 0, 0, 0}}, // (115, 148) + { 0, { 0, 0, 0}}, // (116, 148) + { 0, { 0, 0, 0}}, // (117, 148) + { 0, { 0, 0, 0}}, // (118, 148) + { 0, { 0, 0, 0}}, // (119, 148) + { 0, { 0, 0, 0}}, // (120, 148) + { 0, { 0, 0, 0}}, // (121, 148) + { 0, { 0, 0, 0}}, // (122, 148) + { 0, { 0, 0, 0}}, // (123, 148) + { 0, { 0, 0, 0}}, // (124, 148) + { 0, { 0, 0, 0}}, // (125, 148) + { 0, { 0, 0, 0}}, // (126, 148) + { 0, { 0, 0, 0}}, // (127, 148) + { 0, { 0, 0, 0}}, // (128, 148) + { 0, { 0, 0, 0}}, // (129, 148) + { 0, { 0, 0, 0}}, // (130, 148) + { 0, { 0, 0, 0}}, // (131, 148) + { 0, { 0, 0, 0}}, // (132, 148) + { 0, { 0, 0, 0}}, // (133, 148) + { 0, { 0, 0, 0}}, // (134, 148) + { 0, { 0, 0, 0}}, // (135, 148) + { 0, { 0, 0, 0}}, // (136, 148) + { 0, { 0, 0, 0}}, // (137, 148) + { 0, { 0, 0, 0}}, // (138, 148) + { 0, { 0, 0, 0}}, // (139, 148) + { 0, { 0, 0, 0}}, // (140, 148) + { 0, { 0, 0, 0}}, // (141, 148) + { 0, { 0, 0, 0}}, // (142, 148) + { 0, { 0, 0, 0}}, // (143, 148) + { 0, { 0, 0, 0}}, // (144, 148) + { 0, { 0, 0, 0}}, // (145, 148) + { 0, { 0, 0, 0}}, // (146, 148) + { 0, { 0, 0, 0}}, // (147, 148) + { 0, { 0, 0, 0}}, // (148, 148) + { 0, { 0, 0, 0}}, // (149, 148) + { 0, { 0, 0, 0}}, // (150, 148) + { 0, { 0, 0, 0}}, // (151, 148) + { 0, { 0, 0, 0}}, // (152, 148) + { 0, { 0, 0, 0}}, // (153, 148) + { 0, { 0, 0, 0}}, // (154, 148) + { 39, { 0, 0, 0}}, // (155, 148) + {126, { 0, 0, 0}}, // (156, 148) + {128, { 0, 0, 0}}, // (157, 148) + {128, { 0, 0, 0}}, // (158, 148) + {128, { 0, 0, 0}}, // (159, 148) + {128, { 0, 0, 0}}, // (160, 148) + {128, { 0, 0, 0}}, // (161, 148) + {128, { 0, 0, 0}}, // (162, 148) + {128, { 0, 0, 0}}, // (163, 148) + {128, { 0, 0, 0}}, // (164, 148) + {128, { 0, 0, 0}}, // (165, 148) + {128, { 0, 0, 0}}, // (166, 148) + {128, { 0, 0, 0}}, // (167, 148) + {128, { 0, 0, 0}}, // (168, 148) + {128, { 0, 0, 0}}, // (169, 148) + {128, { 0, 0, 0}}, // (170, 148) + {128, { 0, 0, 0}}, // (171, 148) + {128, { 0, 0, 0}}, // (172, 148) + {128, { 0, 0, 0}}, // (173, 148) + {128, { 0, 0, 0}}, // (174, 148) + {128, { 0, 0, 0}}, // (175, 148) + {128, { 0, 0, 0}}, // (176, 148) + {128, { 0, 0, 0}}, // (177, 148) + {128, { 0, 0, 0}}, // (178, 148) + {128, { 0, 0, 0}}, // (179, 148) + {128, { 0, 0, 0}}, // ( 0, 149) + {128, { 0, 0, 0}}, // ( 1, 149) + {128, { 0, 0, 0}}, // ( 2, 149) + {128, { 0, 0, 0}}, // ( 3, 149) + {128, { 0, 0, 0}}, // ( 4, 149) + {128, { 0, 0, 0}}, // ( 5, 149) + {128, { 0, 0, 0}}, // ( 6, 149) + {128, { 0, 0, 0}}, // ( 7, 149) + {128, { 0, 0, 0}}, // ( 8, 149) + {128, { 0, 0, 0}}, // ( 9, 149) + {128, { 0, 0, 0}}, // ( 10, 149) + {128, { 0, 0, 0}}, // ( 11, 149) + {128, { 0, 0, 0}}, // ( 12, 149) + {128, { 0, 0, 0}}, // ( 13, 149) + {128, { 0, 0, 0}}, // ( 14, 149) + {128, { 0, 0, 0}}, // ( 15, 149) + {128, { 0, 0, 0}}, // ( 16, 149) + {128, { 0, 0, 0}}, // ( 17, 149) + {128, { 0, 0, 0}}, // ( 18, 149) + {128, { 0, 0, 0}}, // ( 19, 149) + {128, { 0, 0, 0}}, // ( 20, 149) + {128, { 0, 0, 0}}, // ( 21, 149) + {128, { 0, 0, 0}}, // ( 22, 149) + {128, { 0, 0, 0}}, // ( 23, 149) + {123, { 0, 0, 0}}, // ( 24, 149) + { 28, { 0, 0, 0}}, // ( 25, 149) + { 0, { 0, 0, 0}}, // ( 26, 149) + { 0, { 0, 0, 0}}, // ( 27, 149) + { 0, { 0, 0, 0}}, // ( 28, 149) + { 0, { 0, 0, 0}}, // ( 29, 149) + { 0, { 0, 0, 0}}, // ( 30, 149) + { 0, { 0, 0, 0}}, // ( 31, 149) + { 0, { 0, 0, 0}}, // ( 32, 149) + { 0, { 0, 0, 0}}, // ( 33, 149) + { 0, { 0, 0, 0}}, // ( 34, 149) + { 0, { 0, 0, 0}}, // ( 35, 149) + { 0, { 0, 0, 0}}, // ( 36, 149) + { 0, { 0, 0, 0}}, // ( 37, 149) + { 0, { 0, 0, 0}}, // ( 38, 149) + { 0, { 0, 0, 0}}, // ( 39, 149) + { 0, { 0, 0, 0}}, // ( 40, 149) + { 0, { 0, 0, 0}}, // ( 41, 149) + { 0, { 0, 0, 0}}, // ( 42, 149) + { 0, { 0, 0, 0}}, // ( 43, 149) + { 0, { 0, 0, 0}}, // ( 44, 149) + { 0, { 0, 0, 0}}, // ( 45, 149) + { 0, { 0, 0, 0}}, // ( 46, 149) + { 0, { 0, 0, 0}}, // ( 47, 149) + { 0, { 0, 0, 0}}, // ( 48, 149) + { 0, { 0, 0, 0}}, // ( 49, 149) + { 0, { 0, 0, 0}}, // ( 50, 149) + { 0, { 0, 0, 0}}, // ( 51, 149) + { 0, { 0, 0, 0}}, // ( 52, 149) + { 0, { 0, 0, 0}}, // ( 53, 149) + { 0, { 0, 0, 0}}, // ( 54, 149) + { 0, { 0, 0, 0}}, // ( 55, 149) + { 0, { 0, 0, 0}}, // ( 56, 149) + { 0, { 0, 0, 0}}, // ( 57, 149) + { 0, { 0, 0, 0}}, // ( 58, 149) + { 0, { 0, 0, 0}}, // ( 59, 149) + { 0, { 0, 0, 0}}, // ( 60, 149) + { 0, { 0, 0, 0}}, // ( 61, 149) + { 0, { 0, 0, 0}}, // ( 62, 149) + { 0, { 0, 0, 0}}, // ( 63, 149) + { 0, { 0, 0, 0}}, // ( 64, 149) + { 0, { 0, 0, 0}}, // ( 65, 149) + { 0, { 0, 0, 0}}, // ( 66, 149) + { 0, { 0, 0, 0}}, // ( 67, 149) + { 0, { 0, 0, 0}}, // ( 68, 149) + { 0, { 0, 0, 0}}, // ( 69, 149) + { 0, { 0, 0, 0}}, // ( 70, 149) + { 0, { 0, 0, 0}}, // ( 71, 149) + { 0, { 0, 0, 0}}, // ( 72, 149) + { 0, { 0, 0, 0}}, // ( 73, 149) + { 0, { 0, 0, 0}}, // ( 74, 149) + { 0, { 0, 0, 0}}, // ( 75, 149) + { 0, { 0, 0, 0}}, // ( 76, 149) + { 0, { 0, 0, 0}}, // ( 77, 149) + { 0, { 0, 0, 0}}, // ( 78, 149) + { 0, { 0, 0, 0}}, // ( 79, 149) + { 0, { 0, 0, 0}}, // ( 80, 149) + { 0, { 0, 0, 0}}, // ( 81, 149) + { 0, { 0, 0, 0}}, // ( 82, 149) + { 0, { 0, 0, 0}}, // ( 83, 149) + { 0, { 0, 0, 0}}, // ( 84, 149) + { 0, { 0, 0, 0}}, // ( 85, 149) + { 0, { 0, 0, 0}}, // ( 86, 149) + { 0, { 0, 0, 0}}, // ( 87, 149) + { 0, { 0, 0, 0}}, // ( 88, 149) + { 0, { 0, 0, 0}}, // ( 89, 149) + { 0, { 0, 0, 0}}, // ( 90, 149) + { 0, { 0, 0, 0}}, // ( 91, 149) + { 0, { 0, 0, 0}}, // ( 92, 149) + { 0, { 0, 0, 0}}, // ( 93, 149) + { 0, { 0, 0, 0}}, // ( 94, 149) + { 0, { 0, 0, 0}}, // ( 95, 149) + { 0, { 0, 0, 0}}, // ( 96, 149) + { 0, { 0, 0, 0}}, // ( 97, 149) + { 0, { 0, 0, 0}}, // ( 98, 149) + { 0, { 0, 0, 0}}, // ( 99, 149) + { 0, { 0, 0, 0}}, // (100, 149) + { 0, { 0, 0, 0}}, // (101, 149) + { 0, { 0, 0, 0}}, // (102, 149) + { 0, { 0, 0, 0}}, // (103, 149) + { 0, { 0, 0, 0}}, // (104, 149) + { 0, { 0, 0, 0}}, // (105, 149) + { 0, { 0, 0, 0}}, // (106, 149) + { 0, { 0, 0, 0}}, // (107, 149) + { 0, { 0, 0, 0}}, // (108, 149) + { 0, { 0, 0, 0}}, // (109, 149) + { 0, { 0, 0, 0}}, // (110, 149) + { 0, { 0, 0, 0}}, // (111, 149) + { 0, { 0, 0, 0}}, // (112, 149) + { 0, { 0, 0, 0}}, // (113, 149) + { 0, { 0, 0, 0}}, // (114, 149) + { 0, { 0, 0, 0}}, // (115, 149) + { 0, { 0, 0, 0}}, // (116, 149) + { 0, { 0, 0, 0}}, // (117, 149) + { 0, { 0, 0, 0}}, // (118, 149) + { 0, { 0, 0, 0}}, // (119, 149) + { 0, { 0, 0, 0}}, // (120, 149) + { 0, { 0, 0, 0}}, // (121, 149) + { 0, { 0, 0, 0}}, // (122, 149) + { 0, { 0, 0, 0}}, // (123, 149) + { 0, { 0, 0, 0}}, // (124, 149) + { 0, { 0, 0, 0}}, // (125, 149) + { 0, { 0, 0, 0}}, // (126, 149) + { 0, { 0, 0, 0}}, // (127, 149) + { 0, { 0, 0, 0}}, // (128, 149) + { 0, { 0, 0, 0}}, // (129, 149) + { 0, { 0, 0, 0}}, // (130, 149) + { 0, { 0, 0, 0}}, // (131, 149) + { 0, { 0, 0, 0}}, // (132, 149) + { 0, { 0, 0, 0}}, // (133, 149) + { 0, { 0, 0, 0}}, // (134, 149) + { 0, { 0, 0, 0}}, // (135, 149) + { 0, { 0, 0, 0}}, // (136, 149) + { 0, { 0, 0, 0}}, // (137, 149) + { 0, { 0, 0, 0}}, // (138, 149) + { 0, { 0, 0, 0}}, // (139, 149) + { 0, { 0, 0, 0}}, // (140, 149) + { 0, { 0, 0, 0}}, // (141, 149) + { 0, { 0, 0, 0}}, // (142, 149) + { 0, { 0, 0, 0}}, // (143, 149) + { 0, { 0, 0, 0}}, // (144, 149) + { 0, { 0, 0, 0}}, // (145, 149) + { 0, { 0, 0, 0}}, // (146, 149) + { 0, { 0, 0, 0}}, // (147, 149) + { 0, { 0, 0, 0}}, // (148, 149) + { 0, { 0, 0, 0}}, // (149, 149) + { 0, { 0, 0, 0}}, // (150, 149) + { 0, { 0, 0, 0}}, // (151, 149) + { 0, { 0, 0, 0}}, // (152, 149) + { 0, { 0, 0, 0}}, // (153, 149) + { 28, { 0, 0, 0}}, // (154, 149) + {123, { 0, 0, 0}}, // (155, 149) + {128, { 0, 0, 0}}, // (156, 149) + {128, { 0, 0, 0}}, // (157, 149) + {128, { 0, 0, 0}}, // (158, 149) + {128, { 0, 0, 0}}, // (159, 149) + {128, { 0, 0, 0}}, // (160, 149) + {128, { 0, 0, 0}}, // (161, 149) + {128, { 0, 0, 0}}, // (162, 149) + {128, { 0, 0, 0}}, // (163, 149) + {128, { 0, 0, 0}}, // (164, 149) + {128, { 0, 0, 0}}, // (165, 149) + {128, { 0, 0, 0}}, // (166, 149) + {128, { 0, 0, 0}}, // (167, 149) + {128, { 0, 0, 0}}, // (168, 149) + {128, { 0, 0, 0}}, // (169, 149) + {128, { 0, 0, 0}}, // (170, 149) + {128, { 0, 0, 0}}, // (171, 149) + {128, { 0, 0, 0}}, // (172, 149) + {128, { 0, 0, 0}}, // (173, 149) + {128, { 0, 0, 0}}, // (174, 149) + {128, { 0, 0, 0}}, // (175, 149) + {128, { 0, 0, 0}}, // (176, 149) + {128, { 0, 0, 0}}, // (177, 149) + {128, { 0, 0, 0}}, // (178, 149) + {128, { 0, 0, 0}}, // (179, 149) + {128, { 0, 0, 0}}, // ( 0, 150) + {128, { 0, 0, 0}}, // ( 1, 150) + {128, { 0, 0, 0}}, // ( 2, 150) + {128, { 0, 0, 0}}, // ( 3, 150) + {128, { 0, 0, 0}}, // ( 4, 150) + {128, { 0, 0, 0}}, // ( 5, 150) + {128, { 0, 0, 0}}, // ( 6, 150) + {128, { 0, 0, 0}}, // ( 7, 150) + {128, { 0, 0, 0}}, // ( 8, 150) + {128, { 0, 0, 0}}, // ( 9, 150) + {128, { 0, 0, 0}}, // ( 10, 150) + {128, { 0, 0, 0}}, // ( 11, 150) + {128, { 0, 0, 0}}, // ( 12, 150) + {128, { 0, 0, 0}}, // ( 13, 150) + {128, { 0, 0, 0}}, // ( 14, 150) + {128, { 0, 0, 0}}, // ( 15, 150) + {128, { 0, 0, 0}}, // ( 16, 150) + {128, { 0, 0, 0}}, // ( 17, 150) + {128, { 0, 0, 0}}, // ( 18, 150) + {128, { 0, 0, 0}}, // ( 19, 150) + {128, { 0, 0, 0}}, // ( 20, 150) + {128, { 0, 0, 0}}, // ( 21, 150) + {128, { 0, 0, 0}}, // ( 22, 150) + {128, { 0, 0, 0}}, // ( 23, 150) + {128, { 0, 0, 0}}, // ( 24, 150) + {120, { 0, 0, 0}}, // ( 25, 150) + { 24, { 0, 0, 0}}, // ( 26, 150) + { 0, { 0, 0, 0}}, // ( 27, 150) + { 0, { 0, 0, 0}}, // ( 28, 150) + { 0, { 0, 0, 0}}, // ( 29, 150) + { 0, { 0, 0, 0}}, // ( 30, 150) + { 0, { 0, 0, 0}}, // ( 31, 150) + { 0, { 0, 0, 0}}, // ( 32, 150) + { 0, { 0, 0, 0}}, // ( 33, 150) + { 0, { 0, 0, 0}}, // ( 34, 150) + { 0, { 0, 0, 0}}, // ( 35, 150) + { 0, { 0, 0, 0}}, // ( 36, 150) + { 0, { 0, 0, 0}}, // ( 37, 150) + { 0, { 0, 0, 0}}, // ( 38, 150) + { 0, { 0, 0, 0}}, // ( 39, 150) + { 0, { 0, 0, 0}}, // ( 40, 150) + { 0, { 0, 0, 0}}, // ( 41, 150) + { 0, { 0, 0, 0}}, // ( 42, 150) + { 0, { 0, 0, 0}}, // ( 43, 150) + { 0, { 0, 0, 0}}, // ( 44, 150) + { 0, { 0, 0, 0}}, // ( 45, 150) + { 0, { 0, 0, 0}}, // ( 46, 150) + { 0, { 0, 0, 0}}, // ( 47, 150) + { 0, { 0, 0, 0}}, // ( 48, 150) + { 0, { 0, 0, 0}}, // ( 49, 150) + { 0, { 0, 0, 0}}, // ( 50, 150) + { 0, { 0, 0, 0}}, // ( 51, 150) + { 0, { 0, 0, 0}}, // ( 52, 150) + { 0, { 0, 0, 0}}, // ( 53, 150) + { 0, { 0, 0, 0}}, // ( 54, 150) + { 0, { 0, 0, 0}}, // ( 55, 150) + { 0, { 0, 0, 0}}, // ( 56, 150) + { 0, { 0, 0, 0}}, // ( 57, 150) + { 0, { 0, 0, 0}}, // ( 58, 150) + { 0, { 0, 0, 0}}, // ( 59, 150) + { 0, { 0, 0, 0}}, // ( 60, 150) + { 0, { 0, 0, 0}}, // ( 61, 150) + { 0, { 0, 0, 0}}, // ( 62, 150) + { 0, { 0, 0, 0}}, // ( 63, 150) + { 0, { 0, 0, 0}}, // ( 64, 150) + { 0, { 0, 0, 0}}, // ( 65, 150) + { 0, { 0, 0, 0}}, // ( 66, 150) + { 0, { 0, 0, 0}}, // ( 67, 150) + { 0, { 0, 0, 0}}, // ( 68, 150) + { 0, { 0, 0, 0}}, // ( 69, 150) + { 0, { 0, 0, 0}}, // ( 70, 150) + { 0, { 0, 0, 0}}, // ( 71, 150) + { 0, { 0, 0, 0}}, // ( 72, 150) + { 0, { 0, 0, 0}}, // ( 73, 150) + { 0, { 0, 0, 0}}, // ( 74, 150) + { 0, { 0, 0, 0}}, // ( 75, 150) + { 0, { 0, 0, 0}}, // ( 76, 150) + { 0, { 0, 0, 0}}, // ( 77, 150) + { 0, { 0, 0, 0}}, // ( 78, 150) + { 0, { 0, 0, 0}}, // ( 79, 150) + { 0, { 0, 0, 0}}, // ( 80, 150) + { 0, { 0, 0, 0}}, // ( 81, 150) + { 0, { 0, 0, 0}}, // ( 82, 150) + { 0, { 0, 0, 0}}, // ( 83, 150) + { 0, { 0, 0, 0}}, // ( 84, 150) + { 0, { 0, 0, 0}}, // ( 85, 150) + { 0, { 0, 0, 0}}, // ( 86, 150) + { 0, { 0, 0, 0}}, // ( 87, 150) + { 0, { 0, 0, 0}}, // ( 88, 150) + { 0, { 0, 0, 0}}, // ( 89, 150) + { 0, { 0, 0, 0}}, // ( 90, 150) + { 0, { 0, 0, 0}}, // ( 91, 150) + { 0, { 0, 0, 0}}, // ( 92, 150) + { 0, { 0, 0, 0}}, // ( 93, 150) + { 0, { 0, 0, 0}}, // ( 94, 150) + { 0, { 0, 0, 0}}, // ( 95, 150) + { 0, { 0, 0, 0}}, // ( 96, 150) + { 0, { 0, 0, 0}}, // ( 97, 150) + { 0, { 0, 0, 0}}, // ( 98, 150) + { 0, { 0, 0, 0}}, // ( 99, 150) + { 0, { 0, 0, 0}}, // (100, 150) + { 0, { 0, 0, 0}}, // (101, 150) + { 0, { 0, 0, 0}}, // (102, 150) + { 0, { 0, 0, 0}}, // (103, 150) + { 0, { 0, 0, 0}}, // (104, 150) + { 0, { 0, 0, 0}}, // (105, 150) + { 0, { 0, 0, 0}}, // (106, 150) + { 0, { 0, 0, 0}}, // (107, 150) + { 0, { 0, 0, 0}}, // (108, 150) + { 0, { 0, 0, 0}}, // (109, 150) + { 0, { 0, 0, 0}}, // (110, 150) + { 0, { 0, 0, 0}}, // (111, 150) + { 0, { 0, 0, 0}}, // (112, 150) + { 0, { 0, 0, 0}}, // (113, 150) + { 0, { 0, 0, 0}}, // (114, 150) + { 0, { 0, 0, 0}}, // (115, 150) + { 0, { 0, 0, 0}}, // (116, 150) + { 0, { 0, 0, 0}}, // (117, 150) + { 0, { 0, 0, 0}}, // (118, 150) + { 0, { 0, 0, 0}}, // (119, 150) + { 0, { 0, 0, 0}}, // (120, 150) + { 0, { 0, 0, 0}}, // (121, 150) + { 0, { 0, 0, 0}}, // (122, 150) + { 0, { 0, 0, 0}}, // (123, 150) + { 0, { 0, 0, 0}}, // (124, 150) + { 0, { 0, 0, 0}}, // (125, 150) + { 0, { 0, 0, 0}}, // (126, 150) + { 0, { 0, 0, 0}}, // (127, 150) + { 0, { 0, 0, 0}}, // (128, 150) + { 0, { 0, 0, 0}}, // (129, 150) + { 0, { 0, 0, 0}}, // (130, 150) + { 0, { 0, 0, 0}}, // (131, 150) + { 0, { 0, 0, 0}}, // (132, 150) + { 0, { 0, 0, 0}}, // (133, 150) + { 0, { 0, 0, 0}}, // (134, 150) + { 0, { 0, 0, 0}}, // (135, 150) + { 0, { 0, 0, 0}}, // (136, 150) + { 0, { 0, 0, 0}}, // (137, 150) + { 0, { 0, 0, 0}}, // (138, 150) + { 0, { 0, 0, 0}}, // (139, 150) + { 0, { 0, 0, 0}}, // (140, 150) + { 0, { 0, 0, 0}}, // (141, 150) + { 0, { 0, 0, 0}}, // (142, 150) + { 0, { 0, 0, 0}}, // (143, 150) + { 0, { 0, 0, 0}}, // (144, 150) + { 0, { 0, 0, 0}}, // (145, 150) + { 0, { 0, 0, 0}}, // (146, 150) + { 0, { 0, 0, 0}}, // (147, 150) + { 0, { 0, 0, 0}}, // (148, 150) + { 0, { 0, 0, 0}}, // (149, 150) + { 0, { 0, 0, 0}}, // (150, 150) + { 0, { 0, 0, 0}}, // (151, 150) + { 0, { 0, 0, 0}}, // (152, 150) + { 24, { 0, 0, 0}}, // (153, 150) + {120, { 0, 0, 0}}, // (154, 150) + {128, { 0, 0, 0}}, // (155, 150) + {128, { 0, 0, 0}}, // (156, 150) + {128, { 0, 0, 0}}, // (157, 150) + {128, { 0, 0, 0}}, // (158, 150) + {128, { 0, 0, 0}}, // (159, 150) + {128, { 0, 0, 0}}, // (160, 150) + {128, { 0, 0, 0}}, // (161, 150) + {128, { 0, 0, 0}}, // (162, 150) + {128, { 0, 0, 0}}, // (163, 150) + {128, { 0, 0, 0}}, // (164, 150) + {128, { 0, 0, 0}}, // (165, 150) + {128, { 0, 0, 0}}, // (166, 150) + {128, { 0, 0, 0}}, // (167, 150) + {128, { 0, 0, 0}}, // (168, 150) + {128, { 0, 0, 0}}, // (169, 150) + {128, { 0, 0, 0}}, // (170, 150) + {128, { 0, 0, 0}}, // (171, 150) + {128, { 0, 0, 0}}, // (172, 150) + {128, { 0, 0, 0}}, // (173, 150) + {128, { 0, 0, 0}}, // (174, 150) + {128, { 0, 0, 0}}, // (175, 150) + {128, { 0, 0, 0}}, // (176, 150) + {128, { 0, 0, 0}}, // (177, 150) + {128, { 0, 0, 0}}, // (178, 150) + {128, { 0, 0, 0}}, // (179, 150) + {128, { 0, 0, 0}}, // ( 0, 151) + {128, { 0, 0, 0}}, // ( 1, 151) + {128, { 0, 0, 0}}, // ( 2, 151) + {128, { 0, 0, 0}}, // ( 3, 151) + {128, { 0, 0, 0}}, // ( 4, 151) + {128, { 0, 0, 0}}, // ( 5, 151) + {128, { 0, 0, 0}}, // ( 6, 151) + {128, { 0, 0, 0}}, // ( 7, 151) + {128, { 0, 0, 0}}, // ( 8, 151) + {128, { 0, 0, 0}}, // ( 9, 151) + {128, { 0, 0, 0}}, // ( 10, 151) + {128, { 0, 0, 0}}, // ( 11, 151) + {128, { 0, 0, 0}}, // ( 12, 151) + {128, { 0, 0, 0}}, // ( 13, 151) + {128, { 0, 0, 0}}, // ( 14, 151) + {128, { 0, 0, 0}}, // ( 15, 151) + {128, { 0, 0, 0}}, // ( 16, 151) + {128, { 0, 0, 0}}, // ( 17, 151) + {128, { 0, 0, 0}}, // ( 18, 151) + {128, { 0, 0, 0}}, // ( 19, 151) + {128, { 0, 0, 0}}, // ( 20, 151) + {128, { 0, 0, 0}}, // ( 21, 151) + {128, { 0, 0, 0}}, // ( 22, 151) + {128, { 0, 0, 0}}, // ( 23, 151) + {128, { 0, 0, 0}}, // ( 24, 151) + {128, { 0, 0, 0}}, // ( 25, 151) + {117, { 0, 0, 0}}, // ( 26, 151) + { 21, { 0, 0, 0}}, // ( 27, 151) + { 0, { 0, 0, 0}}, // ( 28, 151) + { 0, { 0, 0, 0}}, // ( 29, 151) + { 0, { 0, 0, 0}}, // ( 30, 151) + { 0, { 0, 0, 0}}, // ( 31, 151) + { 0, { 0, 0, 0}}, // ( 32, 151) + { 0, { 0, 0, 0}}, // ( 33, 151) + { 0, { 0, 0, 0}}, // ( 34, 151) + { 0, { 0, 0, 0}}, // ( 35, 151) + { 0, { 0, 0, 0}}, // ( 36, 151) + { 0, { 0, 0, 0}}, // ( 37, 151) + { 0, { 0, 0, 0}}, // ( 38, 151) + { 0, { 0, 0, 0}}, // ( 39, 151) + { 0, { 0, 0, 0}}, // ( 40, 151) + { 0, { 0, 0, 0}}, // ( 41, 151) + { 0, { 0, 0, 0}}, // ( 42, 151) + { 0, { 0, 0, 0}}, // ( 43, 151) + { 0, { 0, 0, 0}}, // ( 44, 151) + { 0, { 0, 0, 0}}, // ( 45, 151) + { 0, { 0, 0, 0}}, // ( 46, 151) + { 0, { 0, 0, 0}}, // ( 47, 151) + { 0, { 0, 0, 0}}, // ( 48, 151) + { 0, { 0, 0, 0}}, // ( 49, 151) + { 0, { 0, 0, 0}}, // ( 50, 151) + { 0, { 0, 0, 0}}, // ( 51, 151) + { 0, { 0, 0, 0}}, // ( 52, 151) + { 0, { 0, 0, 0}}, // ( 53, 151) + { 0, { 0, 0, 0}}, // ( 54, 151) + { 0, { 0, 0, 0}}, // ( 55, 151) + { 0, { 0, 0, 0}}, // ( 56, 151) + { 0, { 0, 0, 0}}, // ( 57, 151) + { 0, { 0, 0, 0}}, // ( 58, 151) + { 0, { 0, 0, 0}}, // ( 59, 151) + { 0, { 0, 0, 0}}, // ( 60, 151) + { 0, { 0, 0, 0}}, // ( 61, 151) + { 0, { 0, 0, 0}}, // ( 62, 151) + { 0, { 0, 0, 0}}, // ( 63, 151) + { 0, { 0, 0, 0}}, // ( 64, 151) + { 0, { 0, 0, 0}}, // ( 65, 151) + { 0, { 0, 0, 0}}, // ( 66, 151) + { 0, { 0, 0, 0}}, // ( 67, 151) + { 0, { 0, 0, 0}}, // ( 68, 151) + { 0, { 0, 0, 0}}, // ( 69, 151) + { 0, { 0, 0, 0}}, // ( 70, 151) + { 0, { 0, 0, 0}}, // ( 71, 151) + { 0, { 0, 0, 0}}, // ( 72, 151) + { 0, { 0, 0, 0}}, // ( 73, 151) + { 0, { 0, 0, 0}}, // ( 74, 151) + { 0, { 0, 0, 0}}, // ( 75, 151) + { 0, { 0, 0, 0}}, // ( 76, 151) + { 0, { 0, 0, 0}}, // ( 77, 151) + { 0, { 0, 0, 0}}, // ( 78, 151) + { 0, { 0, 0, 0}}, // ( 79, 151) + { 0, { 0, 0, 0}}, // ( 80, 151) + { 0, { 0, 0, 0}}, // ( 81, 151) + { 0, { 0, 0, 0}}, // ( 82, 151) + { 0, { 0, 0, 0}}, // ( 83, 151) + { 0, { 0, 0, 0}}, // ( 84, 151) + { 0, { 0, 0, 0}}, // ( 85, 151) + { 0, { 0, 0, 0}}, // ( 86, 151) + { 0, { 0, 0, 0}}, // ( 87, 151) + { 0, { 0, 0, 0}}, // ( 88, 151) + { 0, { 0, 0, 0}}, // ( 89, 151) + { 0, { 0, 0, 0}}, // ( 90, 151) + { 0, { 0, 0, 0}}, // ( 91, 151) + { 0, { 0, 0, 0}}, // ( 92, 151) + { 0, { 0, 0, 0}}, // ( 93, 151) + { 0, { 0, 0, 0}}, // ( 94, 151) + { 0, { 0, 0, 0}}, // ( 95, 151) + { 0, { 0, 0, 0}}, // ( 96, 151) + { 0, { 0, 0, 0}}, // ( 97, 151) + { 0, { 0, 0, 0}}, // ( 98, 151) + { 0, { 0, 0, 0}}, // ( 99, 151) + { 0, { 0, 0, 0}}, // (100, 151) + { 0, { 0, 0, 0}}, // (101, 151) + { 0, { 0, 0, 0}}, // (102, 151) + { 0, { 0, 0, 0}}, // (103, 151) + { 0, { 0, 0, 0}}, // (104, 151) + { 0, { 0, 0, 0}}, // (105, 151) + { 0, { 0, 0, 0}}, // (106, 151) + { 0, { 0, 0, 0}}, // (107, 151) + { 0, { 0, 0, 0}}, // (108, 151) + { 0, { 0, 0, 0}}, // (109, 151) + { 0, { 0, 0, 0}}, // (110, 151) + { 0, { 0, 0, 0}}, // (111, 151) + { 0, { 0, 0, 0}}, // (112, 151) + { 0, { 0, 0, 0}}, // (113, 151) + { 0, { 0, 0, 0}}, // (114, 151) + { 0, { 0, 0, 0}}, // (115, 151) + { 0, { 0, 0, 0}}, // (116, 151) + { 0, { 0, 0, 0}}, // (117, 151) + { 0, { 0, 0, 0}}, // (118, 151) + { 0, { 0, 0, 0}}, // (119, 151) + { 0, { 0, 0, 0}}, // (120, 151) + { 0, { 0, 0, 0}}, // (121, 151) + { 0, { 0, 0, 0}}, // (122, 151) + { 0, { 0, 0, 0}}, // (123, 151) + { 0, { 0, 0, 0}}, // (124, 151) + { 0, { 0, 0, 0}}, // (125, 151) + { 0, { 0, 0, 0}}, // (126, 151) + { 0, { 0, 0, 0}}, // (127, 151) + { 0, { 0, 0, 0}}, // (128, 151) + { 0, { 0, 0, 0}}, // (129, 151) + { 0, { 0, 0, 0}}, // (130, 151) + { 0, { 0, 0, 0}}, // (131, 151) + { 0, { 0, 0, 0}}, // (132, 151) + { 0, { 0, 0, 0}}, // (133, 151) + { 0, { 0, 0, 0}}, // (134, 151) + { 0, { 0, 0, 0}}, // (135, 151) + { 0, { 0, 0, 0}}, // (136, 151) + { 0, { 0, 0, 0}}, // (137, 151) + { 0, { 0, 0, 0}}, // (138, 151) + { 0, { 0, 0, 0}}, // (139, 151) + { 0, { 0, 0, 0}}, // (140, 151) + { 0, { 0, 0, 0}}, // (141, 151) + { 0, { 0, 0, 0}}, // (142, 151) + { 0, { 0, 0, 0}}, // (143, 151) + { 0, { 0, 0, 0}}, // (144, 151) + { 0, { 0, 0, 0}}, // (145, 151) + { 0, { 0, 0, 0}}, // (146, 151) + { 0, { 0, 0, 0}}, // (147, 151) + { 0, { 0, 0, 0}}, // (148, 151) + { 0, { 0, 0, 0}}, // (149, 151) + { 0, { 0, 0, 0}}, // (150, 151) + { 0, { 0, 0, 0}}, // (151, 151) + { 21, { 0, 0, 0}}, // (152, 151) + {117, { 0, 0, 0}}, // (153, 151) + {128, { 0, 0, 0}}, // (154, 151) + {128, { 0, 0, 0}}, // (155, 151) + {128, { 0, 0, 0}}, // (156, 151) + {128, { 0, 0, 0}}, // (157, 151) + {128, { 0, 0, 0}}, // (158, 151) + {128, { 0, 0, 0}}, // (159, 151) + {128, { 0, 0, 0}}, // (160, 151) + {128, { 0, 0, 0}}, // (161, 151) + {128, { 0, 0, 0}}, // (162, 151) + {128, { 0, 0, 0}}, // (163, 151) + {128, { 0, 0, 0}}, // (164, 151) + {128, { 0, 0, 0}}, // (165, 151) + {128, { 0, 0, 0}}, // (166, 151) + {128, { 0, 0, 0}}, // (167, 151) + {128, { 0, 0, 0}}, // (168, 151) + {128, { 0, 0, 0}}, // (169, 151) + {128, { 0, 0, 0}}, // (170, 151) + {128, { 0, 0, 0}}, // (171, 151) + {128, { 0, 0, 0}}, // (172, 151) + {128, { 0, 0, 0}}, // (173, 151) + {128, { 0, 0, 0}}, // (174, 151) + {128, { 0, 0, 0}}, // (175, 151) + {128, { 0, 0, 0}}, // (176, 151) + {128, { 0, 0, 0}}, // (177, 151) + {128, { 0, 0, 0}}, // (178, 151) + {128, { 0, 0, 0}}, // (179, 151) + {128, { 0, 0, 0}}, // ( 0, 152) + {128, { 0, 0, 0}}, // ( 1, 152) + {128, { 0, 0, 0}}, // ( 2, 152) + {128, { 0, 0, 0}}, // ( 3, 152) + {128, { 0, 0, 0}}, // ( 4, 152) + {128, { 0, 0, 0}}, // ( 5, 152) + {128, { 0, 0, 0}}, // ( 6, 152) + {128, { 0, 0, 0}}, // ( 7, 152) + {128, { 0, 0, 0}}, // ( 8, 152) + {128, { 0, 0, 0}}, // ( 9, 152) + {128, { 0, 0, 0}}, // ( 10, 152) + {128, { 0, 0, 0}}, // ( 11, 152) + {128, { 0, 0, 0}}, // ( 12, 152) + {128, { 0, 0, 0}}, // ( 13, 152) + {128, { 0, 0, 0}}, // ( 14, 152) + {128, { 0, 0, 0}}, // ( 15, 152) + {128, { 0, 0, 0}}, // ( 16, 152) + {128, { 0, 0, 0}}, // ( 17, 152) + {128, { 0, 0, 0}}, // ( 18, 152) + {128, { 0, 0, 0}}, // ( 19, 152) + {128, { 0, 0, 0}}, // ( 20, 152) + {128, { 0, 0, 0}}, // ( 21, 152) + {128, { 0, 0, 0}}, // ( 22, 152) + {128, { 0, 0, 0}}, // ( 23, 152) + {128, { 0, 0, 0}}, // ( 24, 152) + {128, { 0, 0, 0}}, // ( 25, 152) + {128, { 0, 0, 0}}, // ( 26, 152) + {115, { 0, 0, 0}}, // ( 27, 152) + { 21, { 0, 0, 0}}, // ( 28, 152) + { 0, { 0, 0, 0}}, // ( 29, 152) + { 0, { 0, 0, 0}}, // ( 30, 152) + { 0, { 0, 0, 0}}, // ( 31, 152) + { 0, { 0, 0, 0}}, // ( 32, 152) + { 0, { 0, 0, 0}}, // ( 33, 152) + { 0, { 0, 0, 0}}, // ( 34, 152) + { 0, { 0, 0, 0}}, // ( 35, 152) + { 0, { 0, 0, 0}}, // ( 36, 152) + { 0, { 0, 0, 0}}, // ( 37, 152) + { 0, { 0, 0, 0}}, // ( 38, 152) + { 0, { 0, 0, 0}}, // ( 39, 152) + { 0, { 0, 0, 0}}, // ( 40, 152) + { 0, { 0, 0, 0}}, // ( 41, 152) + { 0, { 0, 0, 0}}, // ( 42, 152) + { 0, { 0, 0, 0}}, // ( 43, 152) + { 0, { 0, 0, 0}}, // ( 44, 152) + { 0, { 0, 0, 0}}, // ( 45, 152) + { 0, { 0, 0, 0}}, // ( 46, 152) + { 0, { 0, 0, 0}}, // ( 47, 152) + { 0, { 0, 0, 0}}, // ( 48, 152) + { 0, { 0, 0, 0}}, // ( 49, 152) + { 0, { 0, 0, 0}}, // ( 50, 152) + { 0, { 0, 0, 0}}, // ( 51, 152) + { 0, { 0, 0, 0}}, // ( 52, 152) + { 0, { 0, 0, 0}}, // ( 53, 152) + { 0, { 0, 0, 0}}, // ( 54, 152) + { 0, { 0, 0, 0}}, // ( 55, 152) + { 0, { 0, 0, 0}}, // ( 56, 152) + { 0, { 0, 0, 0}}, // ( 57, 152) + { 0, { 0, 0, 0}}, // ( 58, 152) + { 0, { 0, 0, 0}}, // ( 59, 152) + { 0, { 0, 0, 0}}, // ( 60, 152) + { 0, { 0, 0, 0}}, // ( 61, 152) + { 0, { 0, 0, 0}}, // ( 62, 152) + { 0, { 0, 0, 0}}, // ( 63, 152) + { 0, { 0, 0, 0}}, // ( 64, 152) + { 0, { 0, 0, 0}}, // ( 65, 152) + { 0, { 0, 0, 0}}, // ( 66, 152) + { 0, { 0, 0, 0}}, // ( 67, 152) + { 0, { 0, 0, 0}}, // ( 68, 152) + { 0, { 0, 0, 0}}, // ( 69, 152) + { 0, { 0, 0, 0}}, // ( 70, 152) + { 0, { 0, 0, 0}}, // ( 71, 152) + { 0, { 0, 0, 0}}, // ( 72, 152) + { 0, { 0, 0, 0}}, // ( 73, 152) + { 0, { 0, 0, 0}}, // ( 74, 152) + { 0, { 0, 0, 0}}, // ( 75, 152) + { 0, { 0, 0, 0}}, // ( 76, 152) + { 0, { 0, 0, 0}}, // ( 77, 152) + { 0, { 0, 0, 0}}, // ( 78, 152) + { 0, { 0, 0, 0}}, // ( 79, 152) + { 0, { 0, 0, 0}}, // ( 80, 152) + { 0, { 0, 0, 0}}, // ( 81, 152) + { 0, { 0, 0, 0}}, // ( 82, 152) + { 0, { 0, 0, 0}}, // ( 83, 152) + { 0, { 0, 0, 0}}, // ( 84, 152) + { 0, { 0, 0, 0}}, // ( 85, 152) + { 0, { 0, 0, 0}}, // ( 86, 152) + { 0, { 0, 0, 0}}, // ( 87, 152) + { 0, { 0, 0, 0}}, // ( 88, 152) + { 0, { 0, 0, 0}}, // ( 89, 152) + { 0, { 0, 0, 0}}, // ( 90, 152) + { 0, { 0, 0, 0}}, // ( 91, 152) + { 0, { 0, 0, 0}}, // ( 92, 152) + { 0, { 0, 0, 0}}, // ( 93, 152) + { 0, { 0, 0, 0}}, // ( 94, 152) + { 0, { 0, 0, 0}}, // ( 95, 152) + { 0, { 0, 0, 0}}, // ( 96, 152) + { 0, { 0, 0, 0}}, // ( 97, 152) + { 0, { 0, 0, 0}}, // ( 98, 152) + { 0, { 0, 0, 0}}, // ( 99, 152) + { 0, { 0, 0, 0}}, // (100, 152) + { 0, { 0, 0, 0}}, // (101, 152) + { 0, { 0, 0, 0}}, // (102, 152) + { 0, { 0, 0, 0}}, // (103, 152) + { 0, { 0, 0, 0}}, // (104, 152) + { 0, { 0, 0, 0}}, // (105, 152) + { 0, { 0, 0, 0}}, // (106, 152) + { 0, { 0, 0, 0}}, // (107, 152) + { 0, { 0, 0, 0}}, // (108, 152) + { 0, { 0, 0, 0}}, // (109, 152) + { 0, { 0, 0, 0}}, // (110, 152) + { 0, { 0, 0, 0}}, // (111, 152) + { 0, { 0, 0, 0}}, // (112, 152) + { 0, { 0, 0, 0}}, // (113, 152) + { 0, { 0, 0, 0}}, // (114, 152) + { 0, { 0, 0, 0}}, // (115, 152) + { 0, { 0, 0, 0}}, // (116, 152) + { 0, { 0, 0, 0}}, // (117, 152) + { 0, { 0, 0, 0}}, // (118, 152) + { 0, { 0, 0, 0}}, // (119, 152) + { 0, { 0, 0, 0}}, // (120, 152) + { 0, { 0, 0, 0}}, // (121, 152) + { 0, { 0, 0, 0}}, // (122, 152) + { 0, { 0, 0, 0}}, // (123, 152) + { 0, { 0, 0, 0}}, // (124, 152) + { 0, { 0, 0, 0}}, // (125, 152) + { 0, { 0, 0, 0}}, // (126, 152) + { 0, { 0, 0, 0}}, // (127, 152) + { 0, { 0, 0, 0}}, // (128, 152) + { 0, { 0, 0, 0}}, // (129, 152) + { 0, { 0, 0, 0}}, // (130, 152) + { 0, { 0, 0, 0}}, // (131, 152) + { 0, { 0, 0, 0}}, // (132, 152) + { 0, { 0, 0, 0}}, // (133, 152) + { 0, { 0, 0, 0}}, // (134, 152) + { 0, { 0, 0, 0}}, // (135, 152) + { 0, { 0, 0, 0}}, // (136, 152) + { 0, { 0, 0, 0}}, // (137, 152) + { 0, { 0, 0, 0}}, // (138, 152) + { 0, { 0, 0, 0}}, // (139, 152) + { 0, { 0, 0, 0}}, // (140, 152) + { 0, { 0, 0, 0}}, // (141, 152) + { 0, { 0, 0, 0}}, // (142, 152) + { 0, { 0, 0, 0}}, // (143, 152) + { 0, { 0, 0, 0}}, // (144, 152) + { 0, { 0, 0, 0}}, // (145, 152) + { 0, { 0, 0, 0}}, // (146, 152) + { 0, { 0, 0, 0}}, // (147, 152) + { 0, { 0, 0, 0}}, // (148, 152) + { 0, { 0, 0, 0}}, // (149, 152) + { 0, { 0, 0, 0}}, // (150, 152) + { 21, { 0, 0, 0}}, // (151, 152) + {115, { 0, 0, 0}}, // (152, 152) + {128, { 0, 0, 0}}, // (153, 152) + {128, { 0, 0, 0}}, // (154, 152) + {128, { 0, 0, 0}}, // (155, 152) + {128, { 0, 0, 0}}, // (156, 152) + {128, { 0, 0, 0}}, // (157, 152) + {128, { 0, 0, 0}}, // (158, 152) + {128, { 0, 0, 0}}, // (159, 152) + {128, { 0, 0, 0}}, // (160, 152) + {128, { 0, 0, 0}}, // (161, 152) + {128, { 0, 0, 0}}, // (162, 152) + {128, { 0, 0, 0}}, // (163, 152) + {128, { 0, 0, 0}}, // (164, 152) + {128, { 0, 0, 0}}, // (165, 152) + {128, { 0, 0, 0}}, // (166, 152) + {128, { 0, 0, 0}}, // (167, 152) + {128, { 0, 0, 0}}, // (168, 152) + {128, { 0, 0, 0}}, // (169, 152) + {128, { 0, 0, 0}}, // (170, 152) + {128, { 0, 0, 0}}, // (171, 152) + {128, { 0, 0, 0}}, // (172, 152) + {128, { 0, 0, 0}}, // (173, 152) + {128, { 0, 0, 0}}, // (174, 152) + {128, { 0, 0, 0}}, // (175, 152) + {128, { 0, 0, 0}}, // (176, 152) + {128, { 0, 0, 0}}, // (177, 152) + {128, { 0, 0, 0}}, // (178, 152) + {128, { 0, 0, 0}}, // (179, 152) + {128, { 0, 0, 0}}, // ( 0, 153) + {128, { 0, 0, 0}}, // ( 1, 153) + {128, { 0, 0, 0}}, // ( 2, 153) + {128, { 0, 0, 0}}, // ( 3, 153) + {128, { 0, 0, 0}}, // ( 4, 153) + {128, { 0, 0, 0}}, // ( 5, 153) + {128, { 0, 0, 0}}, // ( 6, 153) + {128, { 0, 0, 0}}, // ( 7, 153) + {128, { 0, 0, 0}}, // ( 8, 153) + {128, { 0, 0, 0}}, // ( 9, 153) + {128, { 0, 0, 0}}, // ( 10, 153) + {128, { 0, 0, 0}}, // ( 11, 153) + {128, { 0, 0, 0}}, // ( 12, 153) + {128, { 0, 0, 0}}, // ( 13, 153) + {128, { 0, 0, 0}}, // ( 14, 153) + {128, { 0, 0, 0}}, // ( 15, 153) + {128, { 0, 0, 0}}, // ( 16, 153) + {128, { 0, 0, 0}}, // ( 17, 153) + {128, { 0, 0, 0}}, // ( 18, 153) + {128, { 0, 0, 0}}, // ( 19, 153) + {128, { 0, 0, 0}}, // ( 20, 153) + {128, { 0, 0, 0}}, // ( 21, 153) + {128, { 0, 0, 0}}, // ( 22, 153) + {128, { 0, 0, 0}}, // ( 23, 153) + {128, { 0, 0, 0}}, // ( 24, 153) + {128, { 0, 0, 0}}, // ( 25, 153) + {128, { 0, 0, 0}}, // ( 26, 153) + {128, { 0, 0, 0}}, // ( 27, 153) + {117, { 0, 0, 0}}, // ( 28, 153) + { 25, { 0, 0, 0}}, // ( 29, 153) + { 0, { 0, 0, 0}}, // ( 30, 153) + { 0, { 0, 0, 0}}, // ( 31, 153) + { 0, { 0, 0, 0}}, // ( 32, 153) + { 0, { 0, 0, 0}}, // ( 33, 153) + { 0, { 0, 0, 0}}, // ( 34, 153) + { 0, { 0, 0, 0}}, // ( 35, 153) + { 0, { 0, 0, 0}}, // ( 36, 153) + { 0, { 0, 0, 0}}, // ( 37, 153) + { 0, { 0, 0, 0}}, // ( 38, 153) + { 0, { 0, 0, 0}}, // ( 39, 153) + { 0, { 0, 0, 0}}, // ( 40, 153) + { 0, { 0, 0, 0}}, // ( 41, 153) + { 0, { 0, 0, 0}}, // ( 42, 153) + { 0, { 0, 0, 0}}, // ( 43, 153) + { 0, { 0, 0, 0}}, // ( 44, 153) + { 0, { 0, 0, 0}}, // ( 45, 153) + { 0, { 0, 0, 0}}, // ( 46, 153) + { 0, { 0, 0, 0}}, // ( 47, 153) + { 0, { 0, 0, 0}}, // ( 48, 153) + { 0, { 0, 0, 0}}, // ( 49, 153) + { 0, { 0, 0, 0}}, // ( 50, 153) + { 0, { 0, 0, 0}}, // ( 51, 153) + { 0, { 0, 0, 0}}, // ( 52, 153) + { 0, { 0, 0, 0}}, // ( 53, 153) + { 0, { 0, 0, 0}}, // ( 54, 153) + { 0, { 0, 0, 0}}, // ( 55, 153) + { 0, { 0, 0, 0}}, // ( 56, 153) + { 0, { 0, 0, 0}}, // ( 57, 153) + { 0, { 0, 0, 0}}, // ( 58, 153) + { 0, { 0, 0, 0}}, // ( 59, 153) + { 0, { 0, 0, 0}}, // ( 60, 153) + { 0, { 0, 0, 0}}, // ( 61, 153) + { 0, { 0, 0, 0}}, // ( 62, 153) + { 0, { 0, 0, 0}}, // ( 63, 153) + { 0, { 0, 0, 0}}, // ( 64, 153) + { 0, { 0, 0, 0}}, // ( 65, 153) + { 0, { 0, 0, 0}}, // ( 66, 153) + { 0, { 0, 0, 0}}, // ( 67, 153) + { 0, { 0, 0, 0}}, // ( 68, 153) + { 0, { 0, 0, 0}}, // ( 69, 153) + { 0, { 0, 0, 0}}, // ( 70, 153) + { 0, { 0, 0, 0}}, // ( 71, 153) + { 0, { 0, 0, 0}}, // ( 72, 153) + { 0, { 0, 0, 0}}, // ( 73, 153) + { 0, { 0, 0, 0}}, // ( 74, 153) + { 0, { 0, 0, 0}}, // ( 75, 153) + { 0, { 0, 0, 0}}, // ( 76, 153) + { 0, { 0, 0, 0}}, // ( 77, 153) + { 0, { 0, 0, 0}}, // ( 78, 153) + { 0, { 0, 0, 0}}, // ( 79, 153) + { 0, { 0, 0, 0}}, // ( 80, 153) + { 0, { 0, 0, 0}}, // ( 81, 153) + { 0, { 0, 0, 0}}, // ( 82, 153) + { 0, { 0, 0, 0}}, // ( 83, 153) + { 0, { 0, 0, 0}}, // ( 84, 153) + { 0, { 0, 0, 0}}, // ( 85, 153) + { 0, { 0, 0, 0}}, // ( 86, 153) + { 0, { 0, 0, 0}}, // ( 87, 153) + { 0, { 0, 0, 0}}, // ( 88, 153) + { 0, { 0, 0, 0}}, // ( 89, 153) + { 0, { 0, 0, 0}}, // ( 90, 153) + { 0, { 0, 0, 0}}, // ( 91, 153) + { 0, { 0, 0, 0}}, // ( 92, 153) + { 0, { 0, 0, 0}}, // ( 93, 153) + { 0, { 0, 0, 0}}, // ( 94, 153) + { 0, { 0, 0, 0}}, // ( 95, 153) + { 0, { 0, 0, 0}}, // ( 96, 153) + { 0, { 0, 0, 0}}, // ( 97, 153) + { 0, { 0, 0, 0}}, // ( 98, 153) + { 0, { 0, 0, 0}}, // ( 99, 153) + { 0, { 0, 0, 0}}, // (100, 153) + { 0, { 0, 0, 0}}, // (101, 153) + { 0, { 0, 0, 0}}, // (102, 153) + { 0, { 0, 0, 0}}, // (103, 153) + { 0, { 0, 0, 0}}, // (104, 153) + { 0, { 0, 0, 0}}, // (105, 153) + { 0, { 0, 0, 0}}, // (106, 153) + { 0, { 0, 0, 0}}, // (107, 153) + { 0, { 0, 0, 0}}, // (108, 153) + { 0, { 0, 0, 0}}, // (109, 153) + { 0, { 0, 0, 0}}, // (110, 153) + { 0, { 0, 0, 0}}, // (111, 153) + { 0, { 0, 0, 0}}, // (112, 153) + { 0, { 0, 0, 0}}, // (113, 153) + { 0, { 0, 0, 0}}, // (114, 153) + { 0, { 0, 0, 0}}, // (115, 153) + { 0, { 0, 0, 0}}, // (116, 153) + { 0, { 0, 0, 0}}, // (117, 153) + { 0, { 0, 0, 0}}, // (118, 153) + { 0, { 0, 0, 0}}, // (119, 153) + { 0, { 0, 0, 0}}, // (120, 153) + { 0, { 0, 0, 0}}, // (121, 153) + { 0, { 0, 0, 0}}, // (122, 153) + { 0, { 0, 0, 0}}, // (123, 153) + { 0, { 0, 0, 0}}, // (124, 153) + { 0, { 0, 0, 0}}, // (125, 153) + { 0, { 0, 0, 0}}, // (126, 153) + { 0, { 0, 0, 0}}, // (127, 153) + { 0, { 0, 0, 0}}, // (128, 153) + { 0, { 0, 0, 0}}, // (129, 153) + { 0, { 0, 0, 0}}, // (130, 153) + { 0, { 0, 0, 0}}, // (131, 153) + { 0, { 0, 0, 0}}, // (132, 153) + { 0, { 0, 0, 0}}, // (133, 153) + { 0, { 0, 0, 0}}, // (134, 153) + { 0, { 0, 0, 0}}, // (135, 153) + { 0, { 0, 0, 0}}, // (136, 153) + { 0, { 0, 0, 0}}, // (137, 153) + { 0, { 0, 0, 0}}, // (138, 153) + { 0, { 0, 0, 0}}, // (139, 153) + { 0, { 0, 0, 0}}, // (140, 153) + { 0, { 0, 0, 0}}, // (141, 153) + { 0, { 0, 0, 0}}, // (142, 153) + { 0, { 0, 0, 0}}, // (143, 153) + { 0, { 0, 0, 0}}, // (144, 153) + { 0, { 0, 0, 0}}, // (145, 153) + { 0, { 0, 0, 0}}, // (146, 153) + { 0, { 0, 0, 0}}, // (147, 153) + { 0, { 0, 0, 0}}, // (148, 153) + { 0, { 0, 0, 0}}, // (149, 153) + { 25, { 0, 0, 0}}, // (150, 153) + {117, { 0, 0, 0}}, // (151, 153) + {128, { 0, 0, 0}}, // (152, 153) + {128, { 0, 0, 0}}, // (153, 153) + {128, { 0, 0, 0}}, // (154, 153) + {128, { 0, 0, 0}}, // (155, 153) + {128, { 0, 0, 0}}, // (156, 153) + {128, { 0, 0, 0}}, // (157, 153) + {128, { 0, 0, 0}}, // (158, 153) + {128, { 0, 0, 0}}, // (159, 153) + {128, { 0, 0, 0}}, // (160, 153) + {128, { 0, 0, 0}}, // (161, 153) + {128, { 0, 0, 0}}, // (162, 153) + {128, { 0, 0, 0}}, // (163, 153) + {128, { 0, 0, 0}}, // (164, 153) + {128, { 0, 0, 0}}, // (165, 153) + {128, { 0, 0, 0}}, // (166, 153) + {128, { 0, 0, 0}}, // (167, 153) + {128, { 0, 0, 0}}, // (168, 153) + {128, { 0, 0, 0}}, // (169, 153) + {128, { 0, 0, 0}}, // (170, 153) + {128, { 0, 0, 0}}, // (171, 153) + {128, { 0, 0, 0}}, // (172, 153) + {128, { 0, 0, 0}}, // (173, 153) + {128, { 0, 0, 0}}, // (174, 153) + {128, { 0, 0, 0}}, // (175, 153) + {128, { 0, 0, 0}}, // (176, 153) + {128, { 0, 0, 0}}, // (177, 153) + {128, { 0, 0, 0}}, // (178, 153) + {128, { 0, 0, 0}}, // (179, 153) + {128, { 0, 0, 0}}, // ( 0, 154) + {128, { 0, 0, 0}}, // ( 1, 154) + {128, { 0, 0, 0}}, // ( 2, 154) + {128, { 0, 0, 0}}, // ( 3, 154) + {128, { 0, 0, 0}}, // ( 4, 154) + {128, { 0, 0, 0}}, // ( 5, 154) + {128, { 0, 0, 0}}, // ( 6, 154) + {128, { 0, 0, 0}}, // ( 7, 154) + {128, { 0, 0, 0}}, // ( 8, 154) + {128, { 0, 0, 0}}, // ( 9, 154) + {128, { 0, 0, 0}}, // ( 10, 154) + {128, { 0, 0, 0}}, // ( 11, 154) + {128, { 0, 0, 0}}, // ( 12, 154) + {128, { 0, 0, 0}}, // ( 13, 154) + {128, { 0, 0, 0}}, // ( 14, 154) + {128, { 0, 0, 0}}, // ( 15, 154) + {128, { 0, 0, 0}}, // ( 16, 154) + {128, { 0, 0, 0}}, // ( 17, 154) + {128, { 0, 0, 0}}, // ( 18, 154) + {128, { 0, 0, 0}}, // ( 19, 154) + {128, { 0, 0, 0}}, // ( 20, 154) + {128, { 0, 0, 0}}, // ( 21, 154) + {128, { 0, 0, 0}}, // ( 22, 154) + {128, { 0, 0, 0}}, // ( 23, 154) + {128, { 0, 0, 0}}, // ( 24, 154) + {128, { 0, 0, 0}}, // ( 25, 154) + {128, { 0, 0, 0}}, // ( 26, 154) + {128, { 0, 0, 0}}, // ( 27, 154) + {128, { 0, 0, 0}}, // ( 28, 154) + {120, { 0, 0, 0}}, // ( 29, 154) + { 29, { 0, 0, 0}}, // ( 30, 154) + { 0, { 0, 0, 0}}, // ( 31, 154) + { 0, { 0, 0, 0}}, // ( 32, 154) + { 0, { 0, 0, 0}}, // ( 33, 154) + { 0, { 0, 0, 0}}, // ( 34, 154) + { 0, { 0, 0, 0}}, // ( 35, 154) + { 0, { 0, 0, 0}}, // ( 36, 154) + { 0, { 0, 0, 0}}, // ( 37, 154) + { 0, { 0, 0, 0}}, // ( 38, 154) + { 0, { 0, 0, 0}}, // ( 39, 154) + { 0, { 0, 0, 0}}, // ( 40, 154) + { 0, { 0, 0, 0}}, // ( 41, 154) + { 0, { 0, 0, 0}}, // ( 42, 154) + { 0, { 0, 0, 0}}, // ( 43, 154) + { 0, { 0, 0, 0}}, // ( 44, 154) + { 0, { 0, 0, 0}}, // ( 45, 154) + { 0, { 0, 0, 0}}, // ( 46, 154) + { 0, { 0, 0, 0}}, // ( 47, 154) + { 0, { 0, 0, 0}}, // ( 48, 154) + { 0, { 0, 0, 0}}, // ( 49, 154) + { 0, { 0, 0, 0}}, // ( 50, 154) + { 0, { 0, 0, 0}}, // ( 51, 154) + { 0, { 0, 0, 0}}, // ( 52, 154) + { 0, { 0, 0, 0}}, // ( 53, 154) + { 0, { 0, 0, 0}}, // ( 54, 154) + { 0, { 0, 0, 0}}, // ( 55, 154) + { 0, { 0, 0, 0}}, // ( 56, 154) + { 0, { 0, 0, 0}}, // ( 57, 154) + { 0, { 0, 0, 0}}, // ( 58, 154) + { 0, { 0, 0, 0}}, // ( 59, 154) + { 0, { 0, 0, 0}}, // ( 60, 154) + { 0, { 0, 0, 0}}, // ( 61, 154) + { 0, { 0, 0, 0}}, // ( 62, 154) + { 0, { 0, 0, 0}}, // ( 63, 154) + { 0, { 0, 0, 0}}, // ( 64, 154) + { 0, { 0, 0, 0}}, // ( 65, 154) + { 0, { 0, 0, 0}}, // ( 66, 154) + { 0, { 0, 0, 0}}, // ( 67, 154) + { 0, { 0, 0, 0}}, // ( 68, 154) + { 0, { 0, 0, 0}}, // ( 69, 154) + { 0, { 0, 0, 0}}, // ( 70, 154) + { 0, { 0, 0, 0}}, // ( 71, 154) + { 0, { 0, 0, 0}}, // ( 72, 154) + { 0, { 0, 0, 0}}, // ( 73, 154) + { 0, { 0, 0, 0}}, // ( 74, 154) + { 0, { 0, 0, 0}}, // ( 75, 154) + { 0, { 0, 0, 0}}, // ( 76, 154) + { 0, { 0, 0, 0}}, // ( 77, 154) + { 0, { 0, 0, 0}}, // ( 78, 154) + { 0, { 0, 0, 0}}, // ( 79, 154) + { 0, { 0, 0, 0}}, // ( 80, 154) + { 0, { 0, 0, 0}}, // ( 81, 154) + { 0, { 0, 0, 0}}, // ( 82, 154) + { 0, { 0, 0, 0}}, // ( 83, 154) + { 0, { 0, 0, 0}}, // ( 84, 154) + { 0, { 0, 0, 0}}, // ( 85, 154) + { 0, { 0, 0, 0}}, // ( 86, 154) + { 0, { 0, 0, 0}}, // ( 87, 154) + { 0, { 0, 0, 0}}, // ( 88, 154) + { 0, { 0, 0, 0}}, // ( 89, 154) + { 0, { 0, 0, 0}}, // ( 90, 154) + { 0, { 0, 0, 0}}, // ( 91, 154) + { 0, { 0, 0, 0}}, // ( 92, 154) + { 0, { 0, 0, 0}}, // ( 93, 154) + { 0, { 0, 0, 0}}, // ( 94, 154) + { 0, { 0, 0, 0}}, // ( 95, 154) + { 0, { 0, 0, 0}}, // ( 96, 154) + { 0, { 0, 0, 0}}, // ( 97, 154) + { 0, { 0, 0, 0}}, // ( 98, 154) + { 0, { 0, 0, 0}}, // ( 99, 154) + { 0, { 0, 0, 0}}, // (100, 154) + { 0, { 0, 0, 0}}, // (101, 154) + { 0, { 0, 0, 0}}, // (102, 154) + { 0, { 0, 0, 0}}, // (103, 154) + { 0, { 0, 0, 0}}, // (104, 154) + { 0, { 0, 0, 0}}, // (105, 154) + { 0, { 0, 0, 0}}, // (106, 154) + { 0, { 0, 0, 0}}, // (107, 154) + { 0, { 0, 0, 0}}, // (108, 154) + { 0, { 0, 0, 0}}, // (109, 154) + { 0, { 0, 0, 0}}, // (110, 154) + { 0, { 0, 0, 0}}, // (111, 154) + { 0, { 0, 0, 0}}, // (112, 154) + { 0, { 0, 0, 0}}, // (113, 154) + { 0, { 0, 0, 0}}, // (114, 154) + { 0, { 0, 0, 0}}, // (115, 154) + { 0, { 0, 0, 0}}, // (116, 154) + { 0, { 0, 0, 0}}, // (117, 154) + { 0, { 0, 0, 0}}, // (118, 154) + { 0, { 0, 0, 0}}, // (119, 154) + { 0, { 0, 0, 0}}, // (120, 154) + { 0, { 0, 0, 0}}, // (121, 154) + { 0, { 0, 0, 0}}, // (122, 154) + { 0, { 0, 0, 0}}, // (123, 154) + { 0, { 0, 0, 0}}, // (124, 154) + { 0, { 0, 0, 0}}, // (125, 154) + { 0, { 0, 0, 0}}, // (126, 154) + { 0, { 0, 0, 0}}, // (127, 154) + { 0, { 0, 0, 0}}, // (128, 154) + { 0, { 0, 0, 0}}, // (129, 154) + { 0, { 0, 0, 0}}, // (130, 154) + { 0, { 0, 0, 0}}, // (131, 154) + { 0, { 0, 0, 0}}, // (132, 154) + { 0, { 0, 0, 0}}, // (133, 154) + { 0, { 0, 0, 0}}, // (134, 154) + { 0, { 0, 0, 0}}, // (135, 154) + { 0, { 0, 0, 0}}, // (136, 154) + { 0, { 0, 0, 0}}, // (137, 154) + { 0, { 0, 0, 0}}, // (138, 154) + { 0, { 0, 0, 0}}, // (139, 154) + { 0, { 0, 0, 0}}, // (140, 154) + { 0, { 0, 0, 0}}, // (141, 154) + { 0, { 0, 0, 0}}, // (142, 154) + { 0, { 0, 0, 0}}, // (143, 154) + { 0, { 0, 0, 0}}, // (144, 154) + { 0, { 0, 0, 0}}, // (145, 154) + { 0, { 0, 0, 0}}, // (146, 154) + { 0, { 0, 0, 0}}, // (147, 154) + { 0, { 0, 0, 0}}, // (148, 154) + { 29, { 0, 0, 0}}, // (149, 154) + {120, { 0, 0, 0}}, // (150, 154) + {128, { 0, 0, 0}}, // (151, 154) + {128, { 0, 0, 0}}, // (152, 154) + {128, { 0, 0, 0}}, // (153, 154) + {128, { 0, 0, 0}}, // (154, 154) + {128, { 0, 0, 0}}, // (155, 154) + {128, { 0, 0, 0}}, // (156, 154) + {128, { 0, 0, 0}}, // (157, 154) + {128, { 0, 0, 0}}, // (158, 154) + {128, { 0, 0, 0}}, // (159, 154) + {128, { 0, 0, 0}}, // (160, 154) + {128, { 0, 0, 0}}, // (161, 154) + {128, { 0, 0, 0}}, // (162, 154) + {128, { 0, 0, 0}}, // (163, 154) + {128, { 0, 0, 0}}, // (164, 154) + {128, { 0, 0, 0}}, // (165, 154) + {128, { 0, 0, 0}}, // (166, 154) + {128, { 0, 0, 0}}, // (167, 154) + {128, { 0, 0, 0}}, // (168, 154) + {128, { 0, 0, 0}}, // (169, 154) + {128, { 0, 0, 0}}, // (170, 154) + {128, { 0, 0, 0}}, // (171, 154) + {128, { 0, 0, 0}}, // (172, 154) + {128, { 0, 0, 0}}, // (173, 154) + {128, { 0, 0, 0}}, // (174, 154) + {128, { 0, 0, 0}}, // (175, 154) + {128, { 0, 0, 0}}, // (176, 154) + {128, { 0, 0, 0}}, // (177, 154) + {128, { 0, 0, 0}}, // (178, 154) + {128, { 0, 0, 0}}, // (179, 154) + {128, { 0, 0, 0}}, // ( 0, 155) + {128, { 0, 0, 0}}, // ( 1, 155) + {128, { 0, 0, 0}}, // ( 2, 155) + {128, { 0, 0, 0}}, // ( 3, 155) + {128, { 0, 0, 0}}, // ( 4, 155) + {128, { 0, 0, 0}}, // ( 5, 155) + {128, { 0, 0, 0}}, // ( 6, 155) + {128, { 0, 0, 0}}, // ( 7, 155) + {128, { 0, 0, 0}}, // ( 8, 155) + {128, { 0, 0, 0}}, // ( 9, 155) + {128, { 0, 0, 0}}, // ( 10, 155) + {128, { 0, 0, 0}}, // ( 11, 155) + {128, { 0, 0, 0}}, // ( 12, 155) + {128, { 0, 0, 0}}, // ( 13, 155) + {128, { 0, 0, 0}}, // ( 14, 155) + {128, { 0, 0, 0}}, // ( 15, 155) + {128, { 0, 0, 0}}, // ( 16, 155) + {128, { 0, 0, 0}}, // ( 17, 155) + {128, { 0, 0, 0}}, // ( 18, 155) + {128, { 0, 0, 0}}, // ( 19, 155) + {128, { 0, 0, 0}}, // ( 20, 155) + {128, { 0, 0, 0}}, // ( 21, 155) + {128, { 0, 0, 0}}, // ( 22, 155) + {128, { 0, 0, 0}}, // ( 23, 155) + {128, { 0, 0, 0}}, // ( 24, 155) + {128, { 0, 0, 0}}, // ( 25, 155) + {128, { 0, 0, 0}}, // ( 26, 155) + {128, { 0, 0, 0}}, // ( 27, 155) + {128, { 0, 0, 0}}, // ( 28, 155) + {128, { 0, 0, 0}}, // ( 29, 155) + {122, { 0, 0, 0}}, // ( 30, 155) + { 36, { 0, 0, 0}}, // ( 31, 155) + { 0, { 0, 0, 0}}, // ( 32, 155) + { 0, { 0, 0, 0}}, // ( 33, 155) + { 0, { 0, 0, 0}}, // ( 34, 155) + { 0, { 0, 0, 0}}, // ( 35, 155) + { 0, { 0, 0, 0}}, // ( 36, 155) + { 0, { 0, 0, 0}}, // ( 37, 155) + { 0, { 0, 0, 0}}, // ( 38, 155) + { 0, { 0, 0, 0}}, // ( 39, 155) + { 0, { 0, 0, 0}}, // ( 40, 155) + { 0, { 0, 0, 0}}, // ( 41, 155) + { 0, { 0, 0, 0}}, // ( 42, 155) + { 0, { 0, 0, 0}}, // ( 43, 155) + { 0, { 0, 0, 0}}, // ( 44, 155) + { 0, { 0, 0, 0}}, // ( 45, 155) + { 0, { 0, 0, 0}}, // ( 46, 155) + { 0, { 0, 0, 0}}, // ( 47, 155) + { 0, { 0, 0, 0}}, // ( 48, 155) + { 0, { 0, 0, 0}}, // ( 49, 155) + { 0, { 0, 0, 0}}, // ( 50, 155) + { 0, { 0, 0, 0}}, // ( 51, 155) + { 0, { 0, 0, 0}}, // ( 52, 155) + { 0, { 0, 0, 0}}, // ( 53, 155) + { 0, { 0, 0, 0}}, // ( 54, 155) + { 0, { 0, 0, 0}}, // ( 55, 155) + { 0, { 0, 0, 0}}, // ( 56, 155) + { 0, { 0, 0, 0}}, // ( 57, 155) + { 0, { 0, 0, 0}}, // ( 58, 155) + { 0, { 0, 0, 0}}, // ( 59, 155) + { 0, { 0, 0, 0}}, // ( 60, 155) + { 0, { 0, 0, 0}}, // ( 61, 155) + { 0, { 0, 0, 0}}, // ( 62, 155) + { 0, { 0, 0, 0}}, // ( 63, 155) + { 0, { 0, 0, 0}}, // ( 64, 155) + { 0, { 0, 0, 0}}, // ( 65, 155) + { 0, { 0, 0, 0}}, // ( 66, 155) + { 0, { 0, 0, 0}}, // ( 67, 155) + { 0, { 0, 0, 0}}, // ( 68, 155) + { 0, { 0, 0, 0}}, // ( 69, 155) + { 0, { 0, 0, 0}}, // ( 70, 155) + { 0, { 0, 0, 0}}, // ( 71, 155) + { 0, { 0, 0, 0}}, // ( 72, 155) + { 0, { 0, 0, 0}}, // ( 73, 155) + { 0, { 0, 0, 0}}, // ( 74, 155) + { 0, { 0, 0, 0}}, // ( 75, 155) + { 0, { 0, 0, 0}}, // ( 76, 155) + { 0, { 0, 0, 0}}, // ( 77, 155) + { 0, { 0, 0, 0}}, // ( 78, 155) + { 0, { 0, 0, 0}}, // ( 79, 155) + { 0, { 0, 0, 0}}, // ( 80, 155) + { 0, { 0, 0, 0}}, // ( 81, 155) + { 0, { 0, 0, 0}}, // ( 82, 155) + { 0, { 0, 0, 0}}, // ( 83, 155) + { 0, { 0, 0, 0}}, // ( 84, 155) + { 0, { 0, 0, 0}}, // ( 85, 155) + { 0, { 0, 0, 0}}, // ( 86, 155) + { 0, { 0, 0, 0}}, // ( 87, 155) + { 0, { 0, 0, 0}}, // ( 88, 155) + { 0, { 0, 0, 0}}, // ( 89, 155) + { 0, { 0, 0, 0}}, // ( 90, 155) + { 0, { 0, 0, 0}}, // ( 91, 155) + { 0, { 0, 0, 0}}, // ( 92, 155) + { 0, { 0, 0, 0}}, // ( 93, 155) + { 0, { 0, 0, 0}}, // ( 94, 155) + { 0, { 0, 0, 0}}, // ( 95, 155) + { 0, { 0, 0, 0}}, // ( 96, 155) + { 0, { 0, 0, 0}}, // ( 97, 155) + { 0, { 0, 0, 0}}, // ( 98, 155) + { 0, { 0, 0, 0}}, // ( 99, 155) + { 0, { 0, 0, 0}}, // (100, 155) + { 0, { 0, 0, 0}}, // (101, 155) + { 0, { 0, 0, 0}}, // (102, 155) + { 0, { 0, 0, 0}}, // (103, 155) + { 0, { 0, 0, 0}}, // (104, 155) + { 0, { 0, 0, 0}}, // (105, 155) + { 0, { 0, 0, 0}}, // (106, 155) + { 0, { 0, 0, 0}}, // (107, 155) + { 0, { 0, 0, 0}}, // (108, 155) + { 0, { 0, 0, 0}}, // (109, 155) + { 0, { 0, 0, 0}}, // (110, 155) + { 0, { 0, 0, 0}}, // (111, 155) + { 0, { 0, 0, 0}}, // (112, 155) + { 0, { 0, 0, 0}}, // (113, 155) + { 0, { 0, 0, 0}}, // (114, 155) + { 0, { 0, 0, 0}}, // (115, 155) + { 0, { 0, 0, 0}}, // (116, 155) + { 0, { 0, 0, 0}}, // (117, 155) + { 0, { 0, 0, 0}}, // (118, 155) + { 0, { 0, 0, 0}}, // (119, 155) + { 0, { 0, 0, 0}}, // (120, 155) + { 0, { 0, 0, 0}}, // (121, 155) + { 0, { 0, 0, 0}}, // (122, 155) + { 0, { 0, 0, 0}}, // (123, 155) + { 0, { 0, 0, 0}}, // (124, 155) + { 0, { 0, 0, 0}}, // (125, 155) + { 0, { 0, 0, 0}}, // (126, 155) + { 0, { 0, 0, 0}}, // (127, 155) + { 0, { 0, 0, 0}}, // (128, 155) + { 0, { 0, 0, 0}}, // (129, 155) + { 0, { 0, 0, 0}}, // (130, 155) + { 0, { 0, 0, 0}}, // (131, 155) + { 0, { 0, 0, 0}}, // (132, 155) + { 0, { 0, 0, 0}}, // (133, 155) + { 0, { 0, 0, 0}}, // (134, 155) + { 0, { 0, 0, 0}}, // (135, 155) + { 0, { 0, 0, 0}}, // (136, 155) + { 0, { 0, 0, 0}}, // (137, 155) + { 0, { 0, 0, 0}}, // (138, 155) + { 0, { 0, 0, 0}}, // (139, 155) + { 0, { 0, 0, 0}}, // (140, 155) + { 0, { 0, 0, 0}}, // (141, 155) + { 0, { 0, 0, 0}}, // (142, 155) + { 0, { 0, 0, 0}}, // (143, 155) + { 0, { 0, 0, 0}}, // (144, 155) + { 0, { 0, 0, 0}}, // (145, 155) + { 0, { 0, 0, 0}}, // (146, 155) + { 0, { 0, 0, 0}}, // (147, 155) + { 36, { 0, 0, 0}}, // (148, 155) + {122, { 0, 0, 0}}, // (149, 155) + {128, { 0, 0, 0}}, // (150, 155) + {128, { 0, 0, 0}}, // (151, 155) + {128, { 0, 0, 0}}, // (152, 155) + {128, { 0, 0, 0}}, // (153, 155) + {128, { 0, 0, 0}}, // (154, 155) + {128, { 0, 0, 0}}, // (155, 155) + {128, { 0, 0, 0}}, // (156, 155) + {128, { 0, 0, 0}}, // (157, 155) + {128, { 0, 0, 0}}, // (158, 155) + {128, { 0, 0, 0}}, // (159, 155) + {128, { 0, 0, 0}}, // (160, 155) + {128, { 0, 0, 0}}, // (161, 155) + {128, { 0, 0, 0}}, // (162, 155) + {128, { 0, 0, 0}}, // (163, 155) + {128, { 0, 0, 0}}, // (164, 155) + {128, { 0, 0, 0}}, // (165, 155) + {128, { 0, 0, 0}}, // (166, 155) + {128, { 0, 0, 0}}, // (167, 155) + {128, { 0, 0, 0}}, // (168, 155) + {128, { 0, 0, 0}}, // (169, 155) + {128, { 0, 0, 0}}, // (170, 155) + {128, { 0, 0, 0}}, // (171, 155) + {128, { 0, 0, 0}}, // (172, 155) + {128, { 0, 0, 0}}, // (173, 155) + {128, { 0, 0, 0}}, // (174, 155) + {128, { 0, 0, 0}}, // (175, 155) + {128, { 0, 0, 0}}, // (176, 155) + {128, { 0, 0, 0}}, // (177, 155) + {128, { 0, 0, 0}}, // (178, 155) + {128, { 0, 0, 0}}, // (179, 155) + {128, { 0, 0, 0}}, // ( 0, 156) + {128, { 0, 0, 0}}, // ( 1, 156) + {128, { 0, 0, 0}}, // ( 2, 156) + {128, { 0, 0, 0}}, // ( 3, 156) + {128, { 0, 0, 0}}, // ( 4, 156) + {128, { 0, 0, 0}}, // ( 5, 156) + {128, { 0, 0, 0}}, // ( 6, 156) + {128, { 0, 0, 0}}, // ( 7, 156) + {128, { 0, 0, 0}}, // ( 8, 156) + {128, { 0, 0, 0}}, // ( 9, 156) + {128, { 0, 0, 0}}, // ( 10, 156) + {128, { 0, 0, 0}}, // ( 11, 156) + {128, { 0, 0, 0}}, // ( 12, 156) + {128, { 0, 0, 0}}, // ( 13, 156) + {128, { 0, 0, 0}}, // ( 14, 156) + {128, { 0, 0, 0}}, // ( 15, 156) + {128, { 0, 0, 0}}, // ( 16, 156) + {128, { 0, 0, 0}}, // ( 17, 156) + {128, { 0, 0, 0}}, // ( 18, 156) + {128, { 0, 0, 0}}, // ( 19, 156) + {128, { 0, 0, 0}}, // ( 20, 156) + {128, { 0, 0, 0}}, // ( 21, 156) + {128, { 0, 0, 0}}, // ( 22, 156) + {128, { 0, 0, 0}}, // ( 23, 156) + {128, { 0, 0, 0}}, // ( 24, 156) + {128, { 0, 0, 0}}, // ( 25, 156) + {128, { 0, 0, 0}}, // ( 26, 156) + {128, { 0, 0, 0}}, // ( 27, 156) + {128, { 0, 0, 0}}, // ( 28, 156) + {128, { 0, 0, 0}}, // ( 29, 156) + {128, { 0, 0, 0}}, // ( 30, 156) + {126, { 0, 0, 0}}, // ( 31, 156) + { 49, { 0, 0, 0}}, // ( 32, 156) + { 0, { 0, 0, 0}}, // ( 33, 156) + { 0, { 0, 0, 0}}, // ( 34, 156) + { 0, { 0, 0, 0}}, // ( 35, 156) + { 0, { 0, 0, 0}}, // ( 36, 156) + { 0, { 0, 0, 0}}, // ( 37, 156) + { 0, { 0, 0, 0}}, // ( 38, 156) + { 0, { 0, 0, 0}}, // ( 39, 156) + { 0, { 0, 0, 0}}, // ( 40, 156) + { 0, { 0, 0, 0}}, // ( 41, 156) + { 0, { 0, 0, 0}}, // ( 42, 156) + { 0, { 0, 0, 0}}, // ( 43, 156) + { 0, { 0, 0, 0}}, // ( 44, 156) + { 0, { 0, 0, 0}}, // ( 45, 156) + { 0, { 0, 0, 0}}, // ( 46, 156) + { 0, { 0, 0, 0}}, // ( 47, 156) + { 0, { 0, 0, 0}}, // ( 48, 156) + { 0, { 0, 0, 0}}, // ( 49, 156) + { 0, { 0, 0, 0}}, // ( 50, 156) + { 0, { 0, 0, 0}}, // ( 51, 156) + { 0, { 0, 0, 0}}, // ( 52, 156) + { 0, { 0, 0, 0}}, // ( 53, 156) + { 0, { 0, 0, 0}}, // ( 54, 156) + { 0, { 0, 0, 0}}, // ( 55, 156) + { 0, { 0, 0, 0}}, // ( 56, 156) + { 0, { 0, 0, 0}}, // ( 57, 156) + { 0, { 0, 0, 0}}, // ( 58, 156) + { 0, { 0, 0, 0}}, // ( 59, 156) + { 0, { 0, 0, 0}}, // ( 60, 156) + { 0, { 0, 0, 0}}, // ( 61, 156) + { 0, { 0, 0, 0}}, // ( 62, 156) + { 0, { 0, 0, 0}}, // ( 63, 156) + { 0, { 0, 0, 0}}, // ( 64, 156) + { 0, { 0, 0, 0}}, // ( 65, 156) + { 0, { 0, 0, 0}}, // ( 66, 156) + { 0, { 0, 0, 0}}, // ( 67, 156) + { 0, { 0, 0, 0}}, // ( 68, 156) + { 0, { 0, 0, 0}}, // ( 69, 156) + { 0, { 0, 0, 0}}, // ( 70, 156) + { 0, { 0, 0, 0}}, // ( 71, 156) + { 0, { 0, 0, 0}}, // ( 72, 156) + { 0, { 0, 0, 0}}, // ( 73, 156) + { 0, { 0, 0, 0}}, // ( 74, 156) + { 0, { 0, 0, 0}}, // ( 75, 156) + { 0, { 0, 0, 0}}, // ( 76, 156) + { 0, { 0, 0, 0}}, // ( 77, 156) + { 0, { 0, 0, 0}}, // ( 78, 156) + { 0, { 0, 0, 0}}, // ( 79, 156) + { 0, { 0, 0, 0}}, // ( 80, 156) + { 0, { 0, 0, 0}}, // ( 81, 156) + { 0, { 0, 0, 0}}, // ( 82, 156) + { 0, { 0, 0, 0}}, // ( 83, 156) + { 0, { 0, 0, 0}}, // ( 84, 156) + { 0, { 0, 0, 0}}, // ( 85, 156) + { 0, { 0, 0, 0}}, // ( 86, 156) + { 0, { 0, 0, 0}}, // ( 87, 156) + { 0, { 0, 0, 0}}, // ( 88, 156) + { 0, { 0, 0, 0}}, // ( 89, 156) + { 0, { 0, 0, 0}}, // ( 90, 156) + { 0, { 0, 0, 0}}, // ( 91, 156) + { 0, { 0, 0, 0}}, // ( 92, 156) + { 0, { 0, 0, 0}}, // ( 93, 156) + { 0, { 0, 0, 0}}, // ( 94, 156) + { 0, { 0, 0, 0}}, // ( 95, 156) + { 0, { 0, 0, 0}}, // ( 96, 156) + { 0, { 0, 0, 0}}, // ( 97, 156) + { 0, { 0, 0, 0}}, // ( 98, 156) + { 0, { 0, 0, 0}}, // ( 99, 156) + { 0, { 0, 0, 0}}, // (100, 156) + { 0, { 0, 0, 0}}, // (101, 156) + { 0, { 0, 0, 0}}, // (102, 156) + { 0, { 0, 0, 0}}, // (103, 156) + { 0, { 0, 0, 0}}, // (104, 156) + { 0, { 0, 0, 0}}, // (105, 156) + { 0, { 0, 0, 0}}, // (106, 156) + { 0, { 0, 0, 0}}, // (107, 156) + { 0, { 0, 0, 0}}, // (108, 156) + { 0, { 0, 0, 0}}, // (109, 156) + { 0, { 0, 0, 0}}, // (110, 156) + { 0, { 0, 0, 0}}, // (111, 156) + { 0, { 0, 0, 0}}, // (112, 156) + { 0, { 0, 0, 0}}, // (113, 156) + { 0, { 0, 0, 0}}, // (114, 156) + { 0, { 0, 0, 0}}, // (115, 156) + { 0, { 0, 0, 0}}, // (116, 156) + { 0, { 0, 0, 0}}, // (117, 156) + { 0, { 0, 0, 0}}, // (118, 156) + { 0, { 0, 0, 0}}, // (119, 156) + { 0, { 0, 0, 0}}, // (120, 156) + { 0, { 0, 0, 0}}, // (121, 156) + { 0, { 0, 0, 0}}, // (122, 156) + { 0, { 0, 0, 0}}, // (123, 156) + { 0, { 0, 0, 0}}, // (124, 156) + { 0, { 0, 0, 0}}, // (125, 156) + { 0, { 0, 0, 0}}, // (126, 156) + { 0, { 0, 0, 0}}, // (127, 156) + { 0, { 0, 0, 0}}, // (128, 156) + { 0, { 0, 0, 0}}, // (129, 156) + { 0, { 0, 0, 0}}, // (130, 156) + { 0, { 0, 0, 0}}, // (131, 156) + { 0, { 0, 0, 0}}, // (132, 156) + { 0, { 0, 0, 0}}, // (133, 156) + { 0, { 0, 0, 0}}, // (134, 156) + { 0, { 0, 0, 0}}, // (135, 156) + { 0, { 0, 0, 0}}, // (136, 156) + { 0, { 0, 0, 0}}, // (137, 156) + { 0, { 0, 0, 0}}, // (138, 156) + { 0, { 0, 0, 0}}, // (139, 156) + { 0, { 0, 0, 0}}, // (140, 156) + { 0, { 0, 0, 0}}, // (141, 156) + { 0, { 0, 0, 0}}, // (142, 156) + { 0, { 0, 0, 0}}, // (143, 156) + { 0, { 0, 0, 0}}, // (144, 156) + { 0, { 0, 0, 0}}, // (145, 156) + { 0, { 0, 0, 0}}, // (146, 156) + { 49, { 0, 0, 0}}, // (147, 156) + {125, { 0, 0, 0}}, // (148, 156) + {128, { 0, 0, 0}}, // (149, 156) + {128, { 0, 0, 0}}, // (150, 156) + {128, { 0, 0, 0}}, // (151, 156) + {128, { 0, 0, 0}}, // (152, 156) + {128, { 0, 0, 0}}, // (153, 156) + {128, { 0, 0, 0}}, // (154, 156) + {128, { 0, 0, 0}}, // (155, 156) + {128, { 0, 0, 0}}, // (156, 156) + {128, { 0, 0, 0}}, // (157, 156) + {128, { 0, 0, 0}}, // (158, 156) + {128, { 0, 0, 0}}, // (159, 156) + {128, { 0, 0, 0}}, // (160, 156) + {128, { 0, 0, 0}}, // (161, 156) + {128, { 0, 0, 0}}, // (162, 156) + {128, { 0, 0, 0}}, // (163, 156) + {128, { 0, 0, 0}}, // (164, 156) + {128, { 0, 0, 0}}, // (165, 156) + {128, { 0, 0, 0}}, // (166, 156) + {128, { 0, 0, 0}}, // (167, 156) + {128, { 0, 0, 0}}, // (168, 156) + {128, { 0, 0, 0}}, // (169, 156) + {128, { 0, 0, 0}}, // (170, 156) + {128, { 0, 0, 0}}, // (171, 156) + {128, { 0, 0, 0}}, // (172, 156) + {128, { 0, 0, 0}}, // (173, 156) + {128, { 0, 0, 0}}, // (174, 156) + {128, { 0, 0, 0}}, // (175, 156) + {128, { 0, 0, 0}}, // (176, 156) + {128, { 0, 0, 0}}, // (177, 156) + {128, { 0, 0, 0}}, // (178, 156) + {128, { 0, 0, 0}}, // (179, 156) + {128, { 0, 0, 0}}, // ( 0, 157) + {128, { 0, 0, 0}}, // ( 1, 157) + {128, { 0, 0, 0}}, // ( 2, 157) + {128, { 0, 0, 0}}, // ( 3, 157) + {128, { 0, 0, 0}}, // ( 4, 157) + {128, { 0, 0, 0}}, // ( 5, 157) + {128, { 0, 0, 0}}, // ( 6, 157) + {128, { 0, 0, 0}}, // ( 7, 157) + {128, { 0, 0, 0}}, // ( 8, 157) + {128, { 0, 0, 0}}, // ( 9, 157) + {128, { 0, 0, 0}}, // ( 10, 157) + {128, { 0, 0, 0}}, // ( 11, 157) + {128, { 0, 0, 0}}, // ( 12, 157) + {128, { 0, 0, 0}}, // ( 13, 157) + {128, { 0, 0, 0}}, // ( 14, 157) + {128, { 0, 0, 0}}, // ( 15, 157) + {128, { 0, 0, 0}}, // ( 16, 157) + {128, { 0, 0, 0}}, // ( 17, 157) + {128, { 0, 0, 0}}, // ( 18, 157) + {128, { 0, 0, 0}}, // ( 19, 157) + {128, { 0, 0, 0}}, // ( 20, 157) + {128, { 0, 0, 0}}, // ( 21, 157) + {128, { 0, 0, 0}}, // ( 22, 157) + {128, { 0, 0, 0}}, // ( 23, 157) + {128, { 0, 0, 0}}, // ( 24, 157) + {128, { 0, 0, 0}}, // ( 25, 157) + {128, { 0, 0, 0}}, // ( 26, 157) + {128, { 0, 0, 0}}, // ( 27, 157) + {128, { 0, 0, 0}}, // ( 28, 157) + {128, { 0, 0, 0}}, // ( 29, 157) + {128, { 0, 0, 0}}, // ( 30, 157) + {128, { 0, 0, 0}}, // ( 31, 157) + {128, { 0, 0, 0}}, // ( 32, 157) + { 69, { 0, 0, 0}}, // ( 33, 157) + { 1, { 0, 0, 0}}, // ( 34, 157) + { 0, { 0, 0, 0}}, // ( 35, 157) + { 0, { 0, 0, 0}}, // ( 36, 157) + { 0, { 0, 0, 0}}, // ( 37, 157) + { 0, { 0, 0, 0}}, // ( 38, 157) + { 0, { 0, 0, 0}}, // ( 39, 157) + { 0, { 0, 0, 0}}, // ( 40, 157) + { 0, { 0, 0, 0}}, // ( 41, 157) + { 0, { 0, 0, 0}}, // ( 42, 157) + { 0, { 0, 0, 0}}, // ( 43, 157) + { 0, { 0, 0, 0}}, // ( 44, 157) + { 0, { 0, 0, 0}}, // ( 45, 157) + { 0, { 0, 0, 0}}, // ( 46, 157) + { 0, { 0, 0, 0}}, // ( 47, 157) + { 0, { 0, 0, 0}}, // ( 48, 157) + { 0, { 0, 0, 0}}, // ( 49, 157) + { 0, { 0, 0, 0}}, // ( 50, 157) + { 0, { 0, 0, 0}}, // ( 51, 157) + { 0, { 0, 0, 0}}, // ( 52, 157) + { 0, { 0, 0, 0}}, // ( 53, 157) + { 0, { 0, 0, 0}}, // ( 54, 157) + { 0, { 0, 0, 0}}, // ( 55, 157) + { 0, { 0, 0, 0}}, // ( 56, 157) + { 0, { 0, 0, 0}}, // ( 57, 157) + { 0, { 0, 0, 0}}, // ( 58, 157) + { 0, { 0, 0, 0}}, // ( 59, 157) + { 0, { 0, 0, 0}}, // ( 60, 157) + { 0, { 0, 0, 0}}, // ( 61, 157) + { 0, { 0, 0, 0}}, // ( 62, 157) + { 0, { 0, 0, 0}}, // ( 63, 157) + { 0, { 0, 0, 0}}, // ( 64, 157) + { 0, { 0, 0, 0}}, // ( 65, 157) + { 0, { 0, 0, 0}}, // ( 66, 157) + { 0, { 0, 0, 0}}, // ( 67, 157) + { 0, { 0, 0, 0}}, // ( 68, 157) + { 0, { 0, 0, 0}}, // ( 69, 157) + { 0, { 0, 0, 0}}, // ( 70, 157) + { 0, { 0, 0, 0}}, // ( 71, 157) + { 0, { 0, 0, 0}}, // ( 72, 157) + { 0, { 0, 0, 0}}, // ( 73, 157) + { 0, { 0, 0, 0}}, // ( 74, 157) + { 0, { 0, 0, 0}}, // ( 75, 157) + { 0, { 0, 0, 0}}, // ( 76, 157) + { 0, { 0, 0, 0}}, // ( 77, 157) + { 0, { 0, 0, 0}}, // ( 78, 157) + { 0, { 0, 0, 0}}, // ( 79, 157) + { 0, { 0, 0, 0}}, // ( 80, 157) + { 0, { 0, 0, 0}}, // ( 81, 157) + { 0, { 0, 0, 0}}, // ( 82, 157) + { 0, { 0, 0, 0}}, // ( 83, 157) + { 0, { 0, 0, 0}}, // ( 84, 157) + { 0, { 0, 0, 0}}, // ( 85, 157) + { 0, { 0, 0, 0}}, // ( 86, 157) + { 0, { 0, 0, 0}}, // ( 87, 157) + { 0, { 0, 0, 0}}, // ( 88, 157) + { 0, { 0, 0, 0}}, // ( 89, 157) + { 0, { 0, 0, 0}}, // ( 90, 157) + { 0, { 0, 0, 0}}, // ( 91, 157) + { 0, { 0, 0, 0}}, // ( 92, 157) + { 0, { 0, 0, 0}}, // ( 93, 157) + { 0, { 0, 0, 0}}, // ( 94, 157) + { 0, { 0, 0, 0}}, // ( 95, 157) + { 0, { 0, 0, 0}}, // ( 96, 157) + { 0, { 0, 0, 0}}, // ( 97, 157) + { 0, { 0, 0, 0}}, // ( 98, 157) + { 0, { 0, 0, 0}}, // ( 99, 157) + { 0, { 0, 0, 0}}, // (100, 157) + { 0, { 0, 0, 0}}, // (101, 157) + { 0, { 0, 0, 0}}, // (102, 157) + { 0, { 0, 0, 0}}, // (103, 157) + { 0, { 0, 0, 0}}, // (104, 157) + { 0, { 0, 0, 0}}, // (105, 157) + { 0, { 0, 0, 0}}, // (106, 157) + { 0, { 0, 0, 0}}, // (107, 157) + { 0, { 0, 0, 0}}, // (108, 157) + { 0, { 0, 0, 0}}, // (109, 157) + { 0, { 0, 0, 0}}, // (110, 157) + { 0, { 0, 0, 0}}, // (111, 157) + { 0, { 0, 0, 0}}, // (112, 157) + { 0, { 0, 0, 0}}, // (113, 157) + { 0, { 0, 0, 0}}, // (114, 157) + { 0, { 0, 0, 0}}, // (115, 157) + { 0, { 0, 0, 0}}, // (116, 157) + { 0, { 0, 0, 0}}, // (117, 157) + { 0, { 0, 0, 0}}, // (118, 157) + { 0, { 0, 0, 0}}, // (119, 157) + { 0, { 0, 0, 0}}, // (120, 157) + { 0, { 0, 0, 0}}, // (121, 157) + { 0, { 0, 0, 0}}, // (122, 157) + { 0, { 0, 0, 0}}, // (123, 157) + { 0, { 0, 0, 0}}, // (124, 157) + { 0, { 0, 0, 0}}, // (125, 157) + { 0, { 0, 0, 0}}, // (126, 157) + { 0, { 0, 0, 0}}, // (127, 157) + { 0, { 0, 0, 0}}, // (128, 157) + { 0, { 0, 0, 0}}, // (129, 157) + { 0, { 0, 0, 0}}, // (130, 157) + { 0, { 0, 0, 0}}, // (131, 157) + { 0, { 0, 0, 0}}, // (132, 157) + { 0, { 0, 0, 0}}, // (133, 157) + { 0, { 0, 0, 0}}, // (134, 157) + { 0, { 0, 0, 0}}, // (135, 157) + { 0, { 0, 0, 0}}, // (136, 157) + { 0, { 0, 0, 0}}, // (137, 157) + { 0, { 0, 0, 0}}, // (138, 157) + { 0, { 0, 0, 0}}, // (139, 157) + { 0, { 0, 0, 0}}, // (140, 157) + { 0, { 0, 0, 0}}, // (141, 157) + { 0, { 0, 0, 0}}, // (142, 157) + { 0, { 0, 0, 0}}, // (143, 157) + { 0, { 0, 0, 0}}, // (144, 157) + { 1, { 0, 0, 0}}, // (145, 157) + { 68, { 0, 0, 0}}, // (146, 157) + {128, { 0, 0, 0}}, // (147, 157) + {128, { 0, 0, 0}}, // (148, 157) + {128, { 0, 0, 0}}, // (149, 157) + {128, { 0, 0, 0}}, // (150, 157) + {128, { 0, 0, 0}}, // (151, 157) + {128, { 0, 0, 0}}, // (152, 157) + {128, { 0, 0, 0}}, // (153, 157) + {128, { 0, 0, 0}}, // (154, 157) + {128, { 0, 0, 0}}, // (155, 157) + {128, { 0, 0, 0}}, // (156, 157) + {128, { 0, 0, 0}}, // (157, 157) + {128, { 0, 0, 0}}, // (158, 157) + {128, { 0, 0, 0}}, // (159, 157) + {128, { 0, 0, 0}}, // (160, 157) + {128, { 0, 0, 0}}, // (161, 157) + {128, { 0, 0, 0}}, // (162, 157) + {128, { 0, 0, 0}}, // (163, 157) + {128, { 0, 0, 0}}, // (164, 157) + {128, { 0, 0, 0}}, // (165, 157) + {128, { 0, 0, 0}}, // (166, 157) + {128, { 0, 0, 0}}, // (167, 157) + {128, { 0, 0, 0}}, // (168, 157) + {128, { 0, 0, 0}}, // (169, 157) + {128, { 0, 0, 0}}, // (170, 157) + {128, { 0, 0, 0}}, // (171, 157) + {128, { 0, 0, 0}}, // (172, 157) + {128, { 0, 0, 0}}, // (173, 157) + {128, { 0, 0, 0}}, // (174, 157) + {128, { 0, 0, 0}}, // (175, 157) + {128, { 0, 0, 0}}, // (176, 157) + {128, { 0, 0, 0}}, // (177, 157) + {128, { 0, 0, 0}}, // (178, 157) + {128, { 0, 0, 0}}, // (179, 157) + {128, { 0, 0, 0}}, // ( 0, 158) + {128, { 0, 0, 0}}, // ( 1, 158) + {128, { 0, 0, 0}}, // ( 2, 158) + {128, { 0, 0, 0}}, // ( 3, 158) + {128, { 0, 0, 0}}, // ( 4, 158) + {128, { 0, 0, 0}}, // ( 5, 158) + {128, { 0, 0, 0}}, // ( 6, 158) + {128, { 0, 0, 0}}, // ( 7, 158) + {128, { 0, 0, 0}}, // ( 8, 158) + {128, { 0, 0, 0}}, // ( 9, 158) + {128, { 0, 0, 0}}, // ( 10, 158) + {128, { 0, 0, 0}}, // ( 11, 158) + {128, { 0, 0, 0}}, // ( 12, 158) + {128, { 0, 0, 0}}, // ( 13, 158) + {128, { 0, 0, 0}}, // ( 14, 158) + {128, { 0, 0, 0}}, // ( 15, 158) + {128, { 0, 0, 0}}, // ( 16, 158) + {128, { 0, 0, 0}}, // ( 17, 158) + {128, { 0, 0, 0}}, // ( 18, 158) + {128, { 0, 0, 0}}, // ( 19, 158) + {128, { 0, 0, 0}}, // ( 20, 158) + {128, { 0, 0, 0}}, // ( 21, 158) + {128, { 0, 0, 0}}, // ( 22, 158) + {128, { 0, 0, 0}}, // ( 23, 158) + {128, { 0, 0, 0}}, // ( 24, 158) + {128, { 0, 0, 0}}, // ( 25, 158) + {128, { 0, 0, 0}}, // ( 26, 158) + {128, { 0, 0, 0}}, // ( 27, 158) + {128, { 0, 0, 0}}, // ( 28, 158) + {128, { 0, 0, 0}}, // ( 29, 158) + {128, { 0, 0, 0}}, // ( 30, 158) + {128, { 0, 0, 0}}, // ( 31, 158) + {128, { 0, 0, 0}}, // ( 32, 158) + {128, { 0, 0, 0}}, // ( 33, 158) + { 90, { 0, 0, 0}}, // ( 34, 158) + { 8, { 0, 0, 0}}, // ( 35, 158) + { 0, { 0, 0, 0}}, // ( 36, 158) + { 0, { 0, 0, 0}}, // ( 37, 158) + { 0, { 0, 0, 0}}, // ( 38, 158) + { 0, { 0, 0, 0}}, // ( 39, 158) + { 0, { 0, 0, 0}}, // ( 40, 158) + { 0, { 0, 0, 0}}, // ( 41, 158) + { 0, { 0, 0, 0}}, // ( 42, 158) + { 0, { 0, 0, 0}}, // ( 43, 158) + { 0, { 0, 0, 0}}, // ( 44, 158) + { 0, { 0, 0, 0}}, // ( 45, 158) + { 0, { 0, 0, 0}}, // ( 46, 158) + { 0, { 0, 0, 0}}, // ( 47, 158) + { 0, { 0, 0, 0}}, // ( 48, 158) + { 0, { 0, 0, 0}}, // ( 49, 158) + { 0, { 0, 0, 0}}, // ( 50, 158) + { 0, { 0, 0, 0}}, // ( 51, 158) + { 0, { 0, 0, 0}}, // ( 52, 158) + { 0, { 0, 0, 0}}, // ( 53, 158) + { 0, { 0, 0, 0}}, // ( 54, 158) + { 0, { 0, 0, 0}}, // ( 55, 158) + { 0, { 0, 0, 0}}, // ( 56, 158) + { 0, { 0, 0, 0}}, // ( 57, 158) + { 0, { 0, 0, 0}}, // ( 58, 158) + { 0, { 0, 0, 0}}, // ( 59, 158) + { 0, { 0, 0, 0}}, // ( 60, 158) + { 0, { 0, 0, 0}}, // ( 61, 158) + { 0, { 0, 0, 0}}, // ( 62, 158) + { 0, { 0, 0, 0}}, // ( 63, 158) + { 0, { 0, 0, 0}}, // ( 64, 158) + { 0, { 0, 0, 0}}, // ( 65, 158) + { 0, { 0, 0, 0}}, // ( 66, 158) + { 0, { 0, 0, 0}}, // ( 67, 158) + { 0, { 0, 0, 0}}, // ( 68, 158) + { 0, { 0, 0, 0}}, // ( 69, 158) + { 0, { 0, 0, 0}}, // ( 70, 158) + { 0, { 0, 0, 0}}, // ( 71, 158) + { 0, { 0, 0, 0}}, // ( 72, 158) + { 0, { 0, 0, 0}}, // ( 73, 158) + { 0, { 0, 0, 0}}, // ( 74, 158) + { 0, { 0, 0, 0}}, // ( 75, 158) + { 0, { 0, 0, 0}}, // ( 76, 158) + { 0, { 0, 0, 0}}, // ( 77, 158) + { 0, { 0, 0, 0}}, // ( 78, 158) + { 0, { 0, 0, 0}}, // ( 79, 158) + { 0, { 0, 0, 0}}, // ( 80, 158) + { 0, { 0, 0, 0}}, // ( 81, 158) + { 0, { 0, 0, 0}}, // ( 82, 158) + { 0, { 0, 0, 0}}, // ( 83, 158) + { 0, { 0, 0, 0}}, // ( 84, 158) + { 0, { 0, 0, 0}}, // ( 85, 158) + { 0, { 0, 0, 0}}, // ( 86, 158) + { 0, { 0, 0, 0}}, // ( 87, 158) + { 0, { 0, 0, 0}}, // ( 88, 158) + { 0, { 0, 0, 0}}, // ( 89, 158) + { 0, { 0, 0, 0}}, // ( 90, 158) + { 0, { 0, 0, 0}}, // ( 91, 158) + { 0, { 0, 0, 0}}, // ( 92, 158) + { 0, { 0, 0, 0}}, // ( 93, 158) + { 0, { 0, 0, 0}}, // ( 94, 158) + { 0, { 0, 0, 0}}, // ( 95, 158) + { 0, { 0, 0, 0}}, // ( 96, 158) + { 0, { 0, 0, 0}}, // ( 97, 158) + { 0, { 0, 0, 0}}, // ( 98, 158) + { 0, { 0, 0, 0}}, // ( 99, 158) + { 0, { 0, 0, 0}}, // (100, 158) + { 0, { 0, 0, 0}}, // (101, 158) + { 0, { 0, 0, 0}}, // (102, 158) + { 0, { 0, 0, 0}}, // (103, 158) + { 0, { 0, 0, 0}}, // (104, 158) + { 0, { 0, 0, 0}}, // (105, 158) + { 0, { 0, 0, 0}}, // (106, 158) + { 0, { 0, 0, 0}}, // (107, 158) + { 0, { 0, 0, 0}}, // (108, 158) + { 0, { 0, 0, 0}}, // (109, 158) + { 0, { 0, 0, 0}}, // (110, 158) + { 0, { 0, 0, 0}}, // (111, 158) + { 0, { 0, 0, 0}}, // (112, 158) + { 0, { 0, 0, 0}}, // (113, 158) + { 0, { 0, 0, 0}}, // (114, 158) + { 0, { 0, 0, 0}}, // (115, 158) + { 0, { 0, 0, 0}}, // (116, 158) + { 0, { 0, 0, 0}}, // (117, 158) + { 0, { 0, 0, 0}}, // (118, 158) + { 0, { 0, 0, 0}}, // (119, 158) + { 0, { 0, 0, 0}}, // (120, 158) + { 0, { 0, 0, 0}}, // (121, 158) + { 0, { 0, 0, 0}}, // (122, 158) + { 0, { 0, 0, 0}}, // (123, 158) + { 0, { 0, 0, 0}}, // (124, 158) + { 0, { 0, 0, 0}}, // (125, 158) + { 0, { 0, 0, 0}}, // (126, 158) + { 0, { 0, 0, 0}}, // (127, 158) + { 0, { 0, 0, 0}}, // (128, 158) + { 0, { 0, 0, 0}}, // (129, 158) + { 0, { 0, 0, 0}}, // (130, 158) + { 0, { 0, 0, 0}}, // (131, 158) + { 0, { 0, 0, 0}}, // (132, 158) + { 0, { 0, 0, 0}}, // (133, 158) + { 0, { 0, 0, 0}}, // (134, 158) + { 0, { 0, 0, 0}}, // (135, 158) + { 0, { 0, 0, 0}}, // (136, 158) + { 0, { 0, 0, 0}}, // (137, 158) + { 0, { 0, 0, 0}}, // (138, 158) + { 0, { 0, 0, 0}}, // (139, 158) + { 0, { 0, 0, 0}}, // (140, 158) + { 0, { 0, 0, 0}}, // (141, 158) + { 0, { 0, 0, 0}}, // (142, 158) + { 0, { 0, 0, 0}}, // (143, 158) + { 8, { 0, 0, 0}}, // (144, 158) + { 89, { 0, 0, 0}}, // (145, 158) + {128, { 0, 0, 0}}, // (146, 158) + {128, { 0, 0, 0}}, // (147, 158) + {128, { 0, 0, 0}}, // (148, 158) + {128, { 0, 0, 0}}, // (149, 158) + {128, { 0, 0, 0}}, // (150, 158) + {128, { 0, 0, 0}}, // (151, 158) + {128, { 0, 0, 0}}, // (152, 158) + {128, { 0, 0, 0}}, // (153, 158) + {128, { 0, 0, 0}}, // (154, 158) + {128, { 0, 0, 0}}, // (155, 158) + {128, { 0, 0, 0}}, // (156, 158) + {128, { 0, 0, 0}}, // (157, 158) + {128, { 0, 0, 0}}, // (158, 158) + {128, { 0, 0, 0}}, // (159, 158) + {128, { 0, 0, 0}}, // (160, 158) + {128, { 0, 0, 0}}, // (161, 158) + {128, { 0, 0, 0}}, // (162, 158) + {128, { 0, 0, 0}}, // (163, 158) + {128, { 0, 0, 0}}, // (164, 158) + {128, { 0, 0, 0}}, // (165, 158) + {128, { 0, 0, 0}}, // (166, 158) + {128, { 0, 0, 0}}, // (167, 158) + {128, { 0, 0, 0}}, // (168, 158) + {128, { 0, 0, 0}}, // (169, 158) + {128, { 0, 0, 0}}, // (170, 158) + {128, { 0, 0, 0}}, // (171, 158) + {128, { 0, 0, 0}}, // (172, 158) + {128, { 0, 0, 0}}, // (173, 158) + {128, { 0, 0, 0}}, // (174, 158) + {128, { 0, 0, 0}}, // (175, 158) + {128, { 0, 0, 0}}, // (176, 158) + {128, { 0, 0, 0}}, // (177, 158) + {128, { 0, 0, 0}}, // (178, 158) + {128, { 0, 0, 0}}, // (179, 158) + {128, { 0, 0, 0}}, // ( 0, 159) + {128, { 0, 0, 0}}, // ( 1, 159) + {128, { 0, 0, 0}}, // ( 2, 159) + {128, { 0, 0, 0}}, // ( 3, 159) + {128, { 0, 0, 0}}, // ( 4, 159) + {128, { 0, 0, 0}}, // ( 5, 159) + {128, { 0, 0, 0}}, // ( 6, 159) + {128, { 0, 0, 0}}, // ( 7, 159) + {128, { 0, 0, 0}}, // ( 8, 159) + {128, { 0, 0, 0}}, // ( 9, 159) + {128, { 0, 0, 0}}, // ( 10, 159) + {128, { 0, 0, 0}}, // ( 11, 159) + {128, { 0, 0, 0}}, // ( 12, 159) + {128, { 0, 0, 0}}, // ( 13, 159) + {128, { 0, 0, 0}}, // ( 14, 159) + {128, { 0, 0, 0}}, // ( 15, 159) + {128, { 0, 0, 0}}, // ( 16, 159) + {128, { 0, 0, 0}}, // ( 17, 159) + {128, { 0, 0, 0}}, // ( 18, 159) + {128, { 0, 0, 0}}, // ( 19, 159) + {128, { 0, 0, 0}}, // ( 20, 159) + {128, { 0, 0, 0}}, // ( 21, 159) + {128, { 0, 0, 0}}, // ( 22, 159) + {128, { 0, 0, 0}}, // ( 23, 159) + {128, { 0, 0, 0}}, // ( 24, 159) + {128, { 0, 0, 0}}, // ( 25, 159) + {128, { 0, 0, 0}}, // ( 26, 159) + {128, { 0, 0, 0}}, // ( 27, 159) + {128, { 0, 0, 0}}, // ( 28, 159) + {128, { 0, 0, 0}}, // ( 29, 159) + {128, { 0, 0, 0}}, // ( 30, 159) + {128, { 0, 0, 0}}, // ( 31, 159) + {128, { 0, 0, 0}}, // ( 32, 159) + {128, { 0, 0, 0}}, // ( 33, 159) + {128, { 0, 0, 0}}, // ( 34, 159) + {108, { 0, 0, 0}}, // ( 35, 159) + { 22, { 0, 0, 0}}, // ( 36, 159) + { 0, { 0, 0, 0}}, // ( 37, 159) + { 0, { 0, 0, 0}}, // ( 38, 159) + { 0, { 0, 0, 0}}, // ( 39, 159) + { 0, { 0, 0, 0}}, // ( 40, 159) + { 0, { 0, 0, 0}}, // ( 41, 159) + { 0, { 0, 0, 0}}, // ( 42, 159) + { 0, { 0, 0, 0}}, // ( 43, 159) + { 0, { 0, 0, 0}}, // ( 44, 159) + { 0, { 0, 0, 0}}, // ( 45, 159) + { 0, { 0, 0, 0}}, // ( 46, 159) + { 0, { 0, 0, 0}}, // ( 47, 159) + { 0, { 0, 0, 0}}, // ( 48, 159) + { 0, { 0, 0, 0}}, // ( 49, 159) + { 0, { 0, 0, 0}}, // ( 50, 159) + { 0, { 0, 0, 0}}, // ( 51, 159) + { 0, { 0, 0, 0}}, // ( 52, 159) + { 0, { 0, 0, 0}}, // ( 53, 159) + { 0, { 0, 0, 0}}, // ( 54, 159) + { 0, { 0, 0, 0}}, // ( 55, 159) + { 0, { 0, 0, 0}}, // ( 56, 159) + { 0, { 0, 0, 0}}, // ( 57, 159) + { 0, { 0, 0, 0}}, // ( 58, 159) + { 0, { 0, 0, 0}}, // ( 59, 159) + { 0, { 0, 0, 0}}, // ( 60, 159) + { 0, { 0, 0, 0}}, // ( 61, 159) + { 0, { 0, 0, 0}}, // ( 62, 159) + { 0, { 0, 0, 0}}, // ( 63, 159) + { 0, { 0, 0, 0}}, // ( 64, 159) + { 0, { 0, 0, 0}}, // ( 65, 159) + { 0, { 0, 0, 0}}, // ( 66, 159) + { 0, { 0, 0, 0}}, // ( 67, 159) + { 0, { 0, 0, 0}}, // ( 68, 159) + { 0, { 0, 0, 0}}, // ( 69, 159) + { 0, { 0, 0, 0}}, // ( 70, 159) + { 0, { 0, 0, 0}}, // ( 71, 159) + { 0, { 0, 0, 0}}, // ( 72, 159) + { 0, { 0, 0, 0}}, // ( 73, 159) + { 0, { 0, 0, 0}}, // ( 74, 159) + { 0, { 0, 0, 0}}, // ( 75, 159) + { 0, { 0, 0, 0}}, // ( 76, 159) + { 0, { 0, 0, 0}}, // ( 77, 159) + { 0, { 0, 0, 0}}, // ( 78, 159) + { 0, { 0, 0, 0}}, // ( 79, 159) + { 0, { 0, 0, 0}}, // ( 80, 159) + { 0, { 0, 0, 0}}, // ( 81, 159) + { 0, { 0, 0, 0}}, // ( 82, 159) + { 0, { 0, 0, 0}}, // ( 83, 159) + { 0, { 0, 0, 0}}, // ( 84, 159) + { 0, { 0, 0, 0}}, // ( 85, 159) + { 0, { 0, 0, 0}}, // ( 86, 159) + { 0, { 0, 0, 0}}, // ( 87, 159) + { 0, { 0, 0, 0}}, // ( 88, 159) + { 0, { 0, 0, 0}}, // ( 89, 159) + { 0, { 0, 0, 0}}, // ( 90, 159) + { 0, { 0, 0, 0}}, // ( 91, 159) + { 0, { 0, 0, 0}}, // ( 92, 159) + { 0, { 0, 0, 0}}, // ( 93, 159) + { 0, { 0, 0, 0}}, // ( 94, 159) + { 0, { 0, 0, 0}}, // ( 95, 159) + { 0, { 0, 0, 0}}, // ( 96, 159) + { 0, { 0, 0, 0}}, // ( 97, 159) + { 0, { 0, 0, 0}}, // ( 98, 159) + { 0, { 0, 0, 0}}, // ( 99, 159) + { 0, { 0, 0, 0}}, // (100, 159) + { 0, { 0, 0, 0}}, // (101, 159) + { 0, { 0, 0, 0}}, // (102, 159) + { 0, { 0, 0, 0}}, // (103, 159) + { 0, { 0, 0, 0}}, // (104, 159) + { 0, { 0, 0, 0}}, // (105, 159) + { 0, { 0, 0, 0}}, // (106, 159) + { 0, { 0, 0, 0}}, // (107, 159) + { 0, { 0, 0, 0}}, // (108, 159) + { 0, { 0, 0, 0}}, // (109, 159) + { 0, { 0, 0, 0}}, // (110, 159) + { 0, { 0, 0, 0}}, // (111, 159) + { 0, { 0, 0, 0}}, // (112, 159) + { 0, { 0, 0, 0}}, // (113, 159) + { 0, { 0, 0, 0}}, // (114, 159) + { 0, { 0, 0, 0}}, // (115, 159) + { 0, { 0, 0, 0}}, // (116, 159) + { 0, { 0, 0, 0}}, // (117, 159) + { 0, { 0, 0, 0}}, // (118, 159) + { 0, { 0, 0, 0}}, // (119, 159) + { 0, { 0, 0, 0}}, // (120, 159) + { 0, { 0, 0, 0}}, // (121, 159) + { 0, { 0, 0, 0}}, // (122, 159) + { 0, { 0, 0, 0}}, // (123, 159) + { 0, { 0, 0, 0}}, // (124, 159) + { 0, { 0, 0, 0}}, // (125, 159) + { 0, { 0, 0, 0}}, // (126, 159) + { 0, { 0, 0, 0}}, // (127, 159) + { 0, { 0, 0, 0}}, // (128, 159) + { 0, { 0, 0, 0}}, // (129, 159) + { 0, { 0, 0, 0}}, // (130, 159) + { 0, { 0, 0, 0}}, // (131, 159) + { 0, { 0, 0, 0}}, // (132, 159) + { 0, { 0, 0, 0}}, // (133, 159) + { 0, { 0, 0, 0}}, // (134, 159) + { 0, { 0, 0, 0}}, // (135, 159) + { 0, { 0, 0, 0}}, // (136, 159) + { 0, { 0, 0, 0}}, // (137, 159) + { 0, { 0, 0, 0}}, // (138, 159) + { 0, { 0, 0, 0}}, // (139, 159) + { 0, { 0, 0, 0}}, // (140, 159) + { 0, { 0, 0, 0}}, // (141, 159) + { 0, { 0, 0, 0}}, // (142, 159) + { 22, { 0, 0, 0}}, // (143, 159) + {108, { 0, 0, 0}}, // (144, 159) + {128, { 0, 0, 0}}, // (145, 159) + {128, { 0, 0, 0}}, // (146, 159) + {128, { 0, 0, 0}}, // (147, 159) + {128, { 0, 0, 0}}, // (148, 159) + {128, { 0, 0, 0}}, // (149, 159) + {128, { 0, 0, 0}}, // (150, 159) + {128, { 0, 0, 0}}, // (151, 159) + {128, { 0, 0, 0}}, // (152, 159) + {128, { 0, 0, 0}}, // (153, 159) + {128, { 0, 0, 0}}, // (154, 159) + {128, { 0, 0, 0}}, // (155, 159) + {128, { 0, 0, 0}}, // (156, 159) + {128, { 0, 0, 0}}, // (157, 159) + {128, { 0, 0, 0}}, // (158, 159) + {128, { 0, 0, 0}}, // (159, 159) + {128, { 0, 0, 0}}, // (160, 159) + {128, { 0, 0, 0}}, // (161, 159) + {128, { 0, 0, 0}}, // (162, 159) + {128, { 0, 0, 0}}, // (163, 159) + {128, { 0, 0, 0}}, // (164, 159) + {128, { 0, 0, 0}}, // (165, 159) + {128, { 0, 0, 0}}, // (166, 159) + {128, { 0, 0, 0}}, // (167, 159) + {128, { 0, 0, 0}}, // (168, 159) + {128, { 0, 0, 0}}, // (169, 159) + {128, { 0, 0, 0}}, // (170, 159) + {128, { 0, 0, 0}}, // (171, 159) + {128, { 0, 0, 0}}, // (172, 159) + {128, { 0, 0, 0}}, // (173, 159) + {128, { 0, 0, 0}}, // (174, 159) + {128, { 0, 0, 0}}, // (175, 159) + {128, { 0, 0, 0}}, // (176, 159) + {128, { 0, 0, 0}}, // (177, 159) + {128, { 0, 0, 0}}, // (178, 159) + {128, { 0, 0, 0}}, // (179, 159) + {128, { 0, 0, 0}}, // ( 0, 160) + {128, { 0, 0, 0}}, // ( 1, 160) + {128, { 0, 0, 0}}, // ( 2, 160) + {128, { 0, 0, 0}}, // ( 3, 160) + {128, { 0, 0, 0}}, // ( 4, 160) + {128, { 0, 0, 0}}, // ( 5, 160) + {128, { 0, 0, 0}}, // ( 6, 160) + {128, { 0, 0, 0}}, // ( 7, 160) + {128, { 0, 0, 0}}, // ( 8, 160) + {128, { 0, 0, 0}}, // ( 9, 160) + {128, { 0, 0, 0}}, // ( 10, 160) + {128, { 0, 0, 0}}, // ( 11, 160) + {128, { 0, 0, 0}}, // ( 12, 160) + {128, { 0, 0, 0}}, // ( 13, 160) + {128, { 0, 0, 0}}, // ( 14, 160) + {128, { 0, 0, 0}}, // ( 15, 160) + {128, { 0, 0, 0}}, // ( 16, 160) + {128, { 0, 0, 0}}, // ( 17, 160) + {128, { 0, 0, 0}}, // ( 18, 160) + {128, { 0, 0, 0}}, // ( 19, 160) + {128, { 0, 0, 0}}, // ( 20, 160) + {128, { 0, 0, 0}}, // ( 21, 160) + {128, { 0, 0, 0}}, // ( 22, 160) + {128, { 0, 0, 0}}, // ( 23, 160) + {128, { 0, 0, 0}}, // ( 24, 160) + {128, { 0, 0, 0}}, // ( 25, 160) + {128, { 0, 0, 0}}, // ( 26, 160) + {128, { 0, 0, 0}}, // ( 27, 160) + {128, { 0, 0, 0}}, // ( 28, 160) + {128, { 0, 0, 0}}, // ( 29, 160) + {128, { 0, 0, 0}}, // ( 30, 160) + {128, { 0, 0, 0}}, // ( 31, 160) + {128, { 0, 0, 0}}, // ( 32, 160) + {128, { 0, 0, 0}}, // ( 33, 160) + {128, { 0, 0, 0}}, // ( 34, 160) + {128, { 0, 0, 0}}, // ( 35, 160) + {123, { 0, 0, 0}}, // ( 36, 160) + { 48, { 0, 0, 0}}, // ( 37, 160) + { 0, { 0, 0, 0}}, // ( 38, 160) + { 0, { 0, 0, 0}}, // ( 39, 160) + { 0, { 0, 0, 0}}, // ( 40, 160) + { 0, { 0, 0, 0}}, // ( 41, 160) + { 0, { 0, 0, 0}}, // ( 42, 160) + { 0, { 0, 0, 0}}, // ( 43, 160) + { 0, { 0, 0, 0}}, // ( 44, 160) + { 0, { 0, 0, 0}}, // ( 45, 160) + { 0, { 0, 0, 0}}, // ( 46, 160) + { 0, { 0, 0, 0}}, // ( 47, 160) + { 0, { 0, 0, 0}}, // ( 48, 160) + { 0, { 0, 0, 0}}, // ( 49, 160) + { 0, { 0, 0, 0}}, // ( 50, 160) + { 0, { 0, 0, 0}}, // ( 51, 160) + { 0, { 0, 0, 0}}, // ( 52, 160) + { 0, { 0, 0, 0}}, // ( 53, 160) + { 0, { 0, 0, 0}}, // ( 54, 160) + { 0, { 0, 0, 0}}, // ( 55, 160) + { 0, { 0, 0, 0}}, // ( 56, 160) + { 0, { 0, 0, 0}}, // ( 57, 160) + { 0, { 0, 0, 0}}, // ( 58, 160) + { 0, { 0, 0, 0}}, // ( 59, 160) + { 0, { 0, 0, 0}}, // ( 60, 160) + { 0, { 0, 0, 0}}, // ( 61, 160) + { 0, { 0, 0, 0}}, // ( 62, 160) + { 0, { 0, 0, 0}}, // ( 63, 160) + { 0, { 0, 0, 0}}, // ( 64, 160) + { 0, { 0, 0, 0}}, // ( 65, 160) + { 0, { 0, 0, 0}}, // ( 66, 160) + { 0, { 0, 0, 0}}, // ( 67, 160) + { 0, { 0, 0, 0}}, // ( 68, 160) + { 0, { 0, 0, 0}}, // ( 69, 160) + { 0, { 0, 0, 0}}, // ( 70, 160) + { 0, { 0, 0, 0}}, // ( 71, 160) + { 0, { 0, 0, 0}}, // ( 72, 160) + { 0, { 0, 0, 0}}, // ( 73, 160) + { 0, { 0, 0, 0}}, // ( 74, 160) + { 0, { 0, 0, 0}}, // ( 75, 160) + { 0, { 0, 0, 0}}, // ( 76, 160) + { 0, { 0, 0, 0}}, // ( 77, 160) + { 0, { 0, 0, 0}}, // ( 78, 160) + { 0, { 0, 0, 0}}, // ( 79, 160) + { 0, { 0, 0, 0}}, // ( 80, 160) + { 0, { 0, 0, 0}}, // ( 81, 160) + { 0, { 0, 0, 0}}, // ( 82, 160) + { 0, { 0, 0, 0}}, // ( 83, 160) + { 0, { 0, 0, 0}}, // ( 84, 160) + { 0, { 0, 0, 0}}, // ( 85, 160) + { 0, { 0, 0, 0}}, // ( 86, 160) + { 0, { 0, 0, 0}}, // ( 87, 160) + { 0, { 0, 0, 0}}, // ( 88, 160) + { 0, { 0, 0, 0}}, // ( 89, 160) + { 0, { 0, 0, 0}}, // ( 90, 160) + { 0, { 0, 0, 0}}, // ( 91, 160) + { 0, { 0, 0, 0}}, // ( 92, 160) + { 0, { 0, 0, 0}}, // ( 93, 160) + { 0, { 0, 0, 0}}, // ( 94, 160) + { 0, { 0, 0, 0}}, // ( 95, 160) + { 0, { 0, 0, 0}}, // ( 96, 160) + { 0, { 0, 0, 0}}, // ( 97, 160) + { 0, { 0, 0, 0}}, // ( 98, 160) + { 0, { 0, 0, 0}}, // ( 99, 160) + { 0, { 0, 0, 0}}, // (100, 160) + { 0, { 0, 0, 0}}, // (101, 160) + { 0, { 0, 0, 0}}, // (102, 160) + { 0, { 0, 0, 0}}, // (103, 160) + { 0, { 0, 0, 0}}, // (104, 160) + { 0, { 0, 0, 0}}, // (105, 160) + { 0, { 0, 0, 0}}, // (106, 160) + { 0, { 0, 0, 0}}, // (107, 160) + { 0, { 0, 0, 0}}, // (108, 160) + { 0, { 0, 0, 0}}, // (109, 160) + { 0, { 0, 0, 0}}, // (110, 160) + { 0, { 0, 0, 0}}, // (111, 160) + { 0, { 0, 0, 0}}, // (112, 160) + { 0, { 0, 0, 0}}, // (113, 160) + { 0, { 0, 0, 0}}, // (114, 160) + { 0, { 0, 0, 0}}, // (115, 160) + { 0, { 0, 0, 0}}, // (116, 160) + { 0, { 0, 0, 0}}, // (117, 160) + { 0, { 0, 0, 0}}, // (118, 160) + { 0, { 0, 0, 0}}, // (119, 160) + { 0, { 0, 0, 0}}, // (120, 160) + { 0, { 0, 0, 0}}, // (121, 160) + { 0, { 0, 0, 0}}, // (122, 160) + { 0, { 0, 0, 0}}, // (123, 160) + { 0, { 0, 0, 0}}, // (124, 160) + { 0, { 0, 0, 0}}, // (125, 160) + { 0, { 0, 0, 0}}, // (126, 160) + { 0, { 0, 0, 0}}, // (127, 160) + { 0, { 0, 0, 0}}, // (128, 160) + { 0, { 0, 0, 0}}, // (129, 160) + { 0, { 0, 0, 0}}, // (130, 160) + { 0, { 0, 0, 0}}, // (131, 160) + { 0, { 0, 0, 0}}, // (132, 160) + { 0, { 0, 0, 0}}, // (133, 160) + { 0, { 0, 0, 0}}, // (134, 160) + { 0, { 0, 0, 0}}, // (135, 160) + { 0, { 0, 0, 0}}, // (136, 160) + { 0, { 0, 0, 0}}, // (137, 160) + { 0, { 0, 0, 0}}, // (138, 160) + { 0, { 0, 0, 0}}, // (139, 160) + { 0, { 0, 0, 0}}, // (140, 160) + { 0, { 0, 0, 0}}, // (141, 160) + { 48, { 0, 0, 0}}, // (142, 160) + {123, { 0, 0, 0}}, // (143, 160) + {128, { 0, 0, 0}}, // (144, 160) + {128, { 0, 0, 0}}, // (145, 160) + {128, { 0, 0, 0}}, // (146, 160) + {128, { 0, 0, 0}}, // (147, 160) + {128, { 0, 0, 0}}, // (148, 160) + {128, { 0, 0, 0}}, // (149, 160) + {128, { 0, 0, 0}}, // (150, 160) + {128, { 0, 0, 0}}, // (151, 160) + {128, { 0, 0, 0}}, // (152, 160) + {128, { 0, 0, 0}}, // (153, 160) + {128, { 0, 0, 0}}, // (154, 160) + {128, { 0, 0, 0}}, // (155, 160) + {128, { 0, 0, 0}}, // (156, 160) + {128, { 0, 0, 0}}, // (157, 160) + {128, { 0, 0, 0}}, // (158, 160) + {128, { 0, 0, 0}}, // (159, 160) + {128, { 0, 0, 0}}, // (160, 160) + {128, { 0, 0, 0}}, // (161, 160) + {128, { 0, 0, 0}}, // (162, 160) + {128, { 0, 0, 0}}, // (163, 160) + {128, { 0, 0, 0}}, // (164, 160) + {128, { 0, 0, 0}}, // (165, 160) + {128, { 0, 0, 0}}, // (166, 160) + {128, { 0, 0, 0}}, // (167, 160) + {128, { 0, 0, 0}}, // (168, 160) + {128, { 0, 0, 0}}, // (169, 160) + {128, { 0, 0, 0}}, // (170, 160) + {128, { 0, 0, 0}}, // (171, 160) + {128, { 0, 0, 0}}, // (172, 160) + {128, { 0, 0, 0}}, // (173, 160) + {128, { 0, 0, 0}}, // (174, 160) + {128, { 0, 0, 0}}, // (175, 160) + {128, { 0, 0, 0}}, // (176, 160) + {128, { 0, 0, 0}}, // (177, 160) + {128, { 0, 0, 0}}, // (178, 160) + {128, { 0, 0, 0}}, // (179, 160) + {128, { 0, 0, 0}}, // ( 0, 161) + {128, { 0, 0, 0}}, // ( 1, 161) + {128, { 0, 0, 0}}, // ( 2, 161) + {128, { 0, 0, 0}}, // ( 3, 161) + {128, { 0, 0, 0}}, // ( 4, 161) + {128, { 0, 0, 0}}, // ( 5, 161) + {128, { 0, 0, 0}}, // ( 6, 161) + {128, { 0, 0, 0}}, // ( 7, 161) + {128, { 0, 0, 0}}, // ( 8, 161) + {128, { 0, 0, 0}}, // ( 9, 161) + {128, { 0, 0, 0}}, // ( 10, 161) + {128, { 0, 0, 0}}, // ( 11, 161) + {128, { 0, 0, 0}}, // ( 12, 161) + {128, { 0, 0, 0}}, // ( 13, 161) + {128, { 0, 0, 0}}, // ( 14, 161) + {128, { 0, 0, 0}}, // ( 15, 161) + {128, { 0, 0, 0}}, // ( 16, 161) + {128, { 0, 0, 0}}, // ( 17, 161) + {128, { 0, 0, 0}}, // ( 18, 161) + {128, { 0, 0, 0}}, // ( 19, 161) + {128, { 0, 0, 0}}, // ( 20, 161) + {128, { 0, 0, 0}}, // ( 21, 161) + {128, { 0, 0, 0}}, // ( 22, 161) + {128, { 0, 0, 0}}, // ( 23, 161) + {128, { 0, 0, 0}}, // ( 24, 161) + {128, { 0, 0, 0}}, // ( 25, 161) + {128, { 0, 0, 0}}, // ( 26, 161) + {128, { 0, 0, 0}}, // ( 27, 161) + {128, { 0, 0, 0}}, // ( 28, 161) + {128, { 0, 0, 0}}, // ( 29, 161) + {128, { 0, 0, 0}}, // ( 30, 161) + {128, { 0, 0, 0}}, // ( 31, 161) + {128, { 0, 0, 0}}, // ( 32, 161) + {128, { 0, 0, 0}}, // ( 33, 161) + {128, { 0, 0, 0}}, // ( 34, 161) + {128, { 0, 0, 0}}, // ( 35, 161) + {128, { 0, 0, 0}}, // ( 36, 161) + {128, { 0, 0, 0}}, // ( 37, 161) + { 85, { 0, 0, 0}}, // ( 38, 161) + { 9, { 0, 0, 0}}, // ( 39, 161) + { 0, { 0, 0, 0}}, // ( 40, 161) + { 0, { 0, 0, 0}}, // ( 41, 161) + { 0, { 0, 0, 0}}, // ( 42, 161) + { 0, { 0, 0, 0}}, // ( 43, 161) + { 0, { 0, 0, 0}}, // ( 44, 161) + { 0, { 0, 0, 0}}, // ( 45, 161) + { 0, { 0, 0, 0}}, // ( 46, 161) + { 0, { 0, 0, 0}}, // ( 47, 161) + { 0, { 0, 0, 0}}, // ( 48, 161) + { 0, { 0, 0, 0}}, // ( 49, 161) + { 0, { 0, 0, 0}}, // ( 50, 161) + { 0, { 0, 0, 0}}, // ( 51, 161) + { 0, { 0, 0, 0}}, // ( 52, 161) + { 0, { 0, 0, 0}}, // ( 53, 161) + { 0, { 0, 0, 0}}, // ( 54, 161) + { 0, { 0, 0, 0}}, // ( 55, 161) + { 0, { 0, 0, 0}}, // ( 56, 161) + { 0, { 0, 0, 0}}, // ( 57, 161) + { 0, { 0, 0, 0}}, // ( 58, 161) + { 0, { 0, 0, 0}}, // ( 59, 161) + { 0, { 0, 0, 0}}, // ( 60, 161) + { 0, { 0, 0, 0}}, // ( 61, 161) + { 0, { 0, 0, 0}}, // ( 62, 161) + { 0, { 0, 0, 0}}, // ( 63, 161) + { 0, { 0, 0, 0}}, // ( 64, 161) + { 0, { 0, 0, 0}}, // ( 65, 161) + { 0, { 0, 0, 0}}, // ( 66, 161) + { 0, { 0, 0, 0}}, // ( 67, 161) + { 0, { 0, 0, 0}}, // ( 68, 161) + { 0, { 0, 0, 0}}, // ( 69, 161) + { 0, { 0, 0, 0}}, // ( 70, 161) + { 0, { 0, 0, 0}}, // ( 71, 161) + { 0, { 0, 0, 0}}, // ( 72, 161) + { 0, { 0, 0, 0}}, // ( 73, 161) + { 0, { 0, 0, 0}}, // ( 74, 161) + { 0, { 0, 0, 0}}, // ( 75, 161) + { 0, { 0, 0, 0}}, // ( 76, 161) + { 0, { 0, 0, 0}}, // ( 77, 161) + { 0, { 0, 0, 0}}, // ( 78, 161) + { 0, { 0, 0, 0}}, // ( 79, 161) + { 0, { 0, 0, 0}}, // ( 80, 161) + { 0, { 0, 0, 0}}, // ( 81, 161) + { 0, { 0, 0, 0}}, // ( 82, 161) + { 0, { 0, 0, 0}}, // ( 83, 161) + { 0, { 0, 0, 0}}, // ( 84, 161) + { 0, { 0, 0, 0}}, // ( 85, 161) + { 0, { 0, 0, 0}}, // ( 86, 161) + { 0, { 0, 0, 0}}, // ( 87, 161) + { 0, { 0, 0, 0}}, // ( 88, 161) + { 0, { 0, 0, 0}}, // ( 89, 161) + { 0, { 0, 0, 0}}, // ( 90, 161) + { 0, { 0, 0, 0}}, // ( 91, 161) + { 0, { 0, 0, 0}}, // ( 92, 161) + { 0, { 0, 0, 0}}, // ( 93, 161) + { 0, { 0, 0, 0}}, // ( 94, 161) + { 0, { 0, 0, 0}}, // ( 95, 161) + { 0, { 0, 0, 0}}, // ( 96, 161) + { 0, { 0, 0, 0}}, // ( 97, 161) + { 0, { 0, 0, 0}}, // ( 98, 161) + { 0, { 0, 0, 0}}, // ( 99, 161) + { 0, { 0, 0, 0}}, // (100, 161) + { 0, { 0, 0, 0}}, // (101, 161) + { 0, { 0, 0, 0}}, // (102, 161) + { 0, { 0, 0, 0}}, // (103, 161) + { 0, { 0, 0, 0}}, // (104, 161) + { 0, { 0, 0, 0}}, // (105, 161) + { 0, { 0, 0, 0}}, // (106, 161) + { 0, { 0, 0, 0}}, // (107, 161) + { 0, { 0, 0, 0}}, // (108, 161) + { 0, { 0, 0, 0}}, // (109, 161) + { 0, { 0, 0, 0}}, // (110, 161) + { 0, { 0, 0, 0}}, // (111, 161) + { 0, { 0, 0, 0}}, // (112, 161) + { 0, { 0, 0, 0}}, // (113, 161) + { 0, { 0, 0, 0}}, // (114, 161) + { 0, { 0, 0, 0}}, // (115, 161) + { 0, { 0, 0, 0}}, // (116, 161) + { 0, { 0, 0, 0}}, // (117, 161) + { 0, { 0, 0, 0}}, // (118, 161) + { 0, { 0, 0, 0}}, // (119, 161) + { 0, { 0, 0, 0}}, // (120, 161) + { 0, { 0, 0, 0}}, // (121, 161) + { 0, { 0, 0, 0}}, // (122, 161) + { 0, { 0, 0, 0}}, // (123, 161) + { 0, { 0, 0, 0}}, // (124, 161) + { 0, { 0, 0, 0}}, // (125, 161) + { 0, { 0, 0, 0}}, // (126, 161) + { 0, { 0, 0, 0}}, // (127, 161) + { 0, { 0, 0, 0}}, // (128, 161) + { 0, { 0, 0, 0}}, // (129, 161) + { 0, { 0, 0, 0}}, // (130, 161) + { 0, { 0, 0, 0}}, // (131, 161) + { 0, { 0, 0, 0}}, // (132, 161) + { 0, { 0, 0, 0}}, // (133, 161) + { 0, { 0, 0, 0}}, // (134, 161) + { 0, { 0, 0, 0}}, // (135, 161) + { 0, { 0, 0, 0}}, // (136, 161) + { 0, { 0, 0, 0}}, // (137, 161) + { 0, { 0, 0, 0}}, // (138, 161) + { 0, { 0, 0, 0}}, // (139, 161) + { 8, { 0, 0, 0}}, // (140, 161) + { 85, { 0, 0, 0}}, // (141, 161) + {128, { 0, 0, 0}}, // (142, 161) + {128, { 0, 0, 0}}, // (143, 161) + {128, { 0, 0, 0}}, // (144, 161) + {128, { 0, 0, 0}}, // (145, 161) + {128, { 0, 0, 0}}, // (146, 161) + {128, { 0, 0, 0}}, // (147, 161) + {128, { 0, 0, 0}}, // (148, 161) + {128, { 0, 0, 0}}, // (149, 161) + {128, { 0, 0, 0}}, // (150, 161) + {128, { 0, 0, 0}}, // (151, 161) + {128, { 0, 0, 0}}, // (152, 161) + {128, { 0, 0, 0}}, // (153, 161) + {128, { 0, 0, 0}}, // (154, 161) + {128, { 0, 0, 0}}, // (155, 161) + {128, { 0, 0, 0}}, // (156, 161) + {128, { 0, 0, 0}}, // (157, 161) + {128, { 0, 0, 0}}, // (158, 161) + {128, { 0, 0, 0}}, // (159, 161) + {128, { 0, 0, 0}}, // (160, 161) + {128, { 0, 0, 0}}, // (161, 161) + {128, { 0, 0, 0}}, // (162, 161) + {128, { 0, 0, 0}}, // (163, 161) + {128, { 0, 0, 0}}, // (164, 161) + {128, { 0, 0, 0}}, // (165, 161) + {128, { 0, 0, 0}}, // (166, 161) + {128, { 0, 0, 0}}, // (167, 161) + {128, { 0, 0, 0}}, // (168, 161) + {128, { 0, 0, 0}}, // (169, 161) + {128, { 0, 0, 0}}, // (170, 161) + {128, { 0, 0, 0}}, // (171, 161) + {128, { 0, 0, 0}}, // (172, 161) + {128, { 0, 0, 0}}, // (173, 161) + {128, { 0, 0, 0}}, // (174, 161) + {128, { 0, 0, 0}}, // (175, 161) + {128, { 0, 0, 0}}, // (176, 161) + {128, { 0, 0, 0}}, // (177, 161) + {128, { 0, 0, 0}}, // (178, 161) + {128, { 0, 0, 0}}, // (179, 161) + {128, { 0, 0, 0}}, // ( 0, 162) + {128, { 0, 0, 0}}, // ( 1, 162) + {128, { 0, 0, 0}}, // ( 2, 162) + {128, { 0, 0, 0}}, // ( 3, 162) + {128, { 0, 0, 0}}, // ( 4, 162) + {128, { 0, 0, 0}}, // ( 5, 162) + {128, { 0, 0, 0}}, // ( 6, 162) + {128, { 0, 0, 0}}, // ( 7, 162) + {128, { 0, 0, 0}}, // ( 8, 162) + {128, { 0, 0, 0}}, // ( 9, 162) + {128, { 0, 0, 0}}, // ( 10, 162) + {128, { 0, 0, 0}}, // ( 11, 162) + {128, { 0, 0, 0}}, // ( 12, 162) + {128, { 0, 0, 0}}, // ( 13, 162) + {128, { 0, 0, 0}}, // ( 14, 162) + {128, { 0, 0, 0}}, // ( 15, 162) + {128, { 0, 0, 0}}, // ( 16, 162) + {128, { 0, 0, 0}}, // ( 17, 162) + {128, { 0, 0, 0}}, // ( 18, 162) + {128, { 0, 0, 0}}, // ( 19, 162) + {128, { 0, 0, 0}}, // ( 20, 162) + {128, { 0, 0, 0}}, // ( 21, 162) + {128, { 0, 0, 0}}, // ( 22, 162) + {128, { 0, 0, 0}}, // ( 23, 162) + {128, { 0, 0, 0}}, // ( 24, 162) + {128, { 0, 0, 0}}, // ( 25, 162) + {128, { 0, 0, 0}}, // ( 26, 162) + {128, { 0, 0, 0}}, // ( 27, 162) + {128, { 0, 0, 0}}, // ( 28, 162) + {128, { 0, 0, 0}}, // ( 29, 162) + {128, { 0, 0, 0}}, // ( 30, 162) + {128, { 0, 0, 0}}, // ( 31, 162) + {128, { 0, 0, 0}}, // ( 32, 162) + {128, { 0, 0, 0}}, // ( 33, 162) + {128, { 0, 0, 0}}, // ( 34, 162) + {128, { 0, 0, 0}}, // ( 35, 162) + {128, { 0, 0, 0}}, // ( 36, 162) + {128, { 0, 0, 0}}, // ( 37, 162) + {128, { 0, 0, 0}}, // ( 38, 162) + {113, { 0, 0, 0}}, // ( 39, 162) + { 32, { 0, 0, 0}}, // ( 40, 162) + { 0, { 0, 0, 0}}, // ( 41, 162) + { 0, { 0, 0, 0}}, // ( 42, 162) + { 0, { 0, 0, 0}}, // ( 43, 162) + { 0, { 0, 0, 0}}, // ( 44, 162) + { 0, { 0, 0, 0}}, // ( 45, 162) + { 0, { 0, 0, 0}}, // ( 46, 162) + { 0, { 0, 0, 0}}, // ( 47, 162) + { 0, { 0, 0, 0}}, // ( 48, 162) + { 0, { 0, 0, 0}}, // ( 49, 162) + { 0, { 0, 0, 0}}, // ( 50, 162) + { 0, { 0, 0, 0}}, // ( 51, 162) + { 0, { 0, 0, 0}}, // ( 52, 162) + { 0, { 0, 0, 0}}, // ( 53, 162) + { 0, { 0, 0, 0}}, // ( 54, 162) + { 0, { 0, 0, 0}}, // ( 55, 162) + { 0, { 0, 0, 0}}, // ( 56, 162) + { 0, { 0, 0, 0}}, // ( 57, 162) + { 0, { 0, 0, 0}}, // ( 58, 162) + { 0, { 0, 0, 0}}, // ( 59, 162) + { 0, { 0, 0, 0}}, // ( 60, 162) + { 0, { 0, 0, 0}}, // ( 61, 162) + { 0, { 0, 0, 0}}, // ( 62, 162) + { 0, { 0, 0, 0}}, // ( 63, 162) + { 0, { 0, 0, 0}}, // ( 64, 162) + { 0, { 0, 0, 0}}, // ( 65, 162) + { 0, { 0, 0, 0}}, // ( 66, 162) + { 0, { 0, 0, 0}}, // ( 67, 162) + { 0, { 0, 0, 0}}, // ( 68, 162) + { 0, { 0, 0, 0}}, // ( 69, 162) + { 0, { 0, 0, 0}}, // ( 70, 162) + { 0, { 0, 0, 0}}, // ( 71, 162) + { 0, { 0, 0, 0}}, // ( 72, 162) + { 0, { 0, 0, 0}}, // ( 73, 162) + { 0, { 0, 0, 0}}, // ( 74, 162) + { 0, { 0, 0, 0}}, // ( 75, 162) + { 0, { 0, 0, 0}}, // ( 76, 162) + { 0, { 0, 0, 0}}, // ( 77, 162) + { 0, { 0, 0, 0}}, // ( 78, 162) + { 0, { 0, 0, 0}}, // ( 79, 162) + { 0, { 0, 0, 0}}, // ( 80, 162) + { 0, { 0, 0, 0}}, // ( 81, 162) + { 0, { 0, 0, 0}}, // ( 82, 162) + { 0, { 0, 0, 0}}, // ( 83, 162) + { 0, { 0, 0, 0}}, // ( 84, 162) + { 0, { 0, 0, 0}}, // ( 85, 162) + { 0, { 0, 0, 0}}, // ( 86, 162) + { 0, { 0, 0, 0}}, // ( 87, 162) + { 0, { 0, 0, 0}}, // ( 88, 162) + { 0, { 0, 0, 0}}, // ( 89, 162) + { 0, { 0, 0, 0}}, // ( 90, 162) + { 0, { 0, 0, 0}}, // ( 91, 162) + { 0, { 0, 0, 0}}, // ( 92, 162) + { 0, { 0, 0, 0}}, // ( 93, 162) + { 0, { 0, 0, 0}}, // ( 94, 162) + { 0, { 0, 0, 0}}, // ( 95, 162) + { 0, { 0, 0, 0}}, // ( 96, 162) + { 0, { 0, 0, 0}}, // ( 97, 162) + { 0, { 0, 0, 0}}, // ( 98, 162) + { 0, { 0, 0, 0}}, // ( 99, 162) + { 0, { 0, 0, 0}}, // (100, 162) + { 0, { 0, 0, 0}}, // (101, 162) + { 0, { 0, 0, 0}}, // (102, 162) + { 0, { 0, 0, 0}}, // (103, 162) + { 0, { 0, 0, 0}}, // (104, 162) + { 0, { 0, 0, 0}}, // (105, 162) + { 0, { 0, 0, 0}}, // (106, 162) + { 0, { 0, 0, 0}}, // (107, 162) + { 0, { 0, 0, 0}}, // (108, 162) + { 0, { 0, 0, 0}}, // (109, 162) + { 0, { 0, 0, 0}}, // (110, 162) + { 0, { 0, 0, 0}}, // (111, 162) + { 0, { 0, 0, 0}}, // (112, 162) + { 0, { 0, 0, 0}}, // (113, 162) + { 0, { 0, 0, 0}}, // (114, 162) + { 0, { 0, 0, 0}}, // (115, 162) + { 0, { 0, 0, 0}}, // (116, 162) + { 0, { 0, 0, 0}}, // (117, 162) + { 0, { 0, 0, 0}}, // (118, 162) + { 0, { 0, 0, 0}}, // (119, 162) + { 0, { 0, 0, 0}}, // (120, 162) + { 0, { 0, 0, 0}}, // (121, 162) + { 0, { 0, 0, 0}}, // (122, 162) + { 0, { 0, 0, 0}}, // (123, 162) + { 0, { 0, 0, 0}}, // (124, 162) + { 0, { 0, 0, 0}}, // (125, 162) + { 0, { 0, 0, 0}}, // (126, 162) + { 0, { 0, 0, 0}}, // (127, 162) + { 0, { 0, 0, 0}}, // (128, 162) + { 0, { 0, 0, 0}}, // (129, 162) + { 0, { 0, 0, 0}}, // (130, 162) + { 0, { 0, 0, 0}}, // (131, 162) + { 0, { 0, 0, 0}}, // (132, 162) + { 0, { 0, 0, 0}}, // (133, 162) + { 0, { 0, 0, 0}}, // (134, 162) + { 0, { 0, 0, 0}}, // (135, 162) + { 0, { 0, 0, 0}}, // (136, 162) + { 0, { 0, 0, 0}}, // (137, 162) + { 0, { 0, 0, 0}}, // (138, 162) + { 32, { 0, 0, 0}}, // (139, 162) + {113, { 0, 0, 0}}, // (140, 162) + {128, { 0, 0, 0}}, // (141, 162) + {128, { 0, 0, 0}}, // (142, 162) + {128, { 0, 0, 0}}, // (143, 162) + {128, { 0, 0, 0}}, // (144, 162) + {128, { 0, 0, 0}}, // (145, 162) + {128, { 0, 0, 0}}, // (146, 162) + {128, { 0, 0, 0}}, // (147, 162) + {128, { 0, 0, 0}}, // (148, 162) + {128, { 0, 0, 0}}, // (149, 162) + {128, { 0, 0, 0}}, // (150, 162) + {128, { 0, 0, 0}}, // (151, 162) + {128, { 0, 0, 0}}, // (152, 162) + {128, { 0, 0, 0}}, // (153, 162) + {128, { 0, 0, 0}}, // (154, 162) + {128, { 0, 0, 0}}, // (155, 162) + {128, { 0, 0, 0}}, // (156, 162) + {128, { 0, 0, 0}}, // (157, 162) + {128, { 0, 0, 0}}, // (158, 162) + {128, { 0, 0, 0}}, // (159, 162) + {128, { 0, 0, 0}}, // (160, 162) + {128, { 0, 0, 0}}, // (161, 162) + {128, { 0, 0, 0}}, // (162, 162) + {128, { 0, 0, 0}}, // (163, 162) + {128, { 0, 0, 0}}, // (164, 162) + {128, { 0, 0, 0}}, // (165, 162) + {128, { 0, 0, 0}}, // (166, 162) + {128, { 0, 0, 0}}, // (167, 162) + {128, { 0, 0, 0}}, // (168, 162) + {128, { 0, 0, 0}}, // (169, 162) + {128, { 0, 0, 0}}, // (170, 162) + {128, { 0, 0, 0}}, // (171, 162) + {128, { 0, 0, 0}}, // (172, 162) + {128, { 0, 0, 0}}, // (173, 162) + {128, { 0, 0, 0}}, // (174, 162) + {128, { 0, 0, 0}}, // (175, 162) + {128, { 0, 0, 0}}, // (176, 162) + {128, { 0, 0, 0}}, // (177, 162) + {128, { 0, 0, 0}}, // (178, 162) + {128, { 0, 0, 0}}, // (179, 162) + {128, { 0, 0, 0}}, // ( 0, 163) + {128, { 0, 0, 0}}, // ( 1, 163) + {128, { 0, 0, 0}}, // ( 2, 163) + {128, { 0, 0, 0}}, // ( 3, 163) + {128, { 0, 0, 0}}, // ( 4, 163) + {128, { 0, 0, 0}}, // ( 5, 163) + {128, { 0, 0, 0}}, // ( 6, 163) + {128, { 0, 0, 0}}, // ( 7, 163) + {128, { 0, 0, 0}}, // ( 8, 163) + {128, { 0, 0, 0}}, // ( 9, 163) + {128, { 0, 0, 0}}, // ( 10, 163) + {128, { 0, 0, 0}}, // ( 11, 163) + {128, { 0, 0, 0}}, // ( 12, 163) + {128, { 0, 0, 0}}, // ( 13, 163) + {128, { 0, 0, 0}}, // ( 14, 163) + {128, { 0, 0, 0}}, // ( 15, 163) + {128, { 0, 0, 0}}, // ( 16, 163) + {128, { 0, 0, 0}}, // ( 17, 163) + {128, { 0, 0, 0}}, // ( 18, 163) + {128, { 0, 0, 0}}, // ( 19, 163) + {128, { 0, 0, 0}}, // ( 20, 163) + {128, { 0, 0, 0}}, // ( 21, 163) + {128, { 0, 0, 0}}, // ( 22, 163) + {128, { 0, 0, 0}}, // ( 23, 163) + {128, { 0, 0, 0}}, // ( 24, 163) + {128, { 0, 0, 0}}, // ( 25, 163) + {128, { 0, 0, 0}}, // ( 26, 163) + {128, { 0, 0, 0}}, // ( 27, 163) + {128, { 0, 0, 0}}, // ( 28, 163) + {128, { 0, 0, 0}}, // ( 29, 163) + {128, { 0, 0, 0}}, // ( 30, 163) + {128, { 0, 0, 0}}, // ( 31, 163) + {128, { 0, 0, 0}}, // ( 32, 163) + {128, { 0, 0, 0}}, // ( 33, 163) + {128, { 0, 0, 0}}, // ( 34, 163) + {128, { 0, 0, 0}}, // ( 35, 163) + {128, { 0, 0, 0}}, // ( 36, 163) + {128, { 0, 0, 0}}, // ( 37, 163) + {128, { 0, 0, 0}}, // ( 38, 163) + {128, { 0, 0, 0}}, // ( 39, 163) + {127, { 0, 0, 0}}, // ( 40, 163) + { 74, { 0, 0, 0}}, // ( 41, 163) + { 7, { 0, 0, 0}}, // ( 42, 163) + { 0, { 0, 0, 0}}, // ( 43, 163) + { 0, { 0, 0, 0}}, // ( 44, 163) + { 0, { 0, 0, 0}}, // ( 45, 163) + { 0, { 0, 0, 0}}, // ( 46, 163) + { 0, { 0, 0, 0}}, // ( 47, 163) + { 0, { 0, 0, 0}}, // ( 48, 163) + { 0, { 0, 0, 0}}, // ( 49, 163) + { 0, { 0, 0, 0}}, // ( 50, 163) + { 0, { 0, 0, 0}}, // ( 51, 163) + { 0, { 0, 0, 0}}, // ( 52, 163) + { 0, { 0, 0, 0}}, // ( 53, 163) + { 0, { 0, 0, 0}}, // ( 54, 163) + { 0, { 0, 0, 0}}, // ( 55, 163) + { 0, { 0, 0, 0}}, // ( 56, 163) + { 0, { 0, 0, 0}}, // ( 57, 163) + { 0, { 0, 0, 0}}, // ( 58, 163) + { 0, { 0, 0, 0}}, // ( 59, 163) + { 0, { 0, 0, 0}}, // ( 60, 163) + { 0, { 0, 0, 0}}, // ( 61, 163) + { 0, { 0, 0, 0}}, // ( 62, 163) + { 0, { 0, 0, 0}}, // ( 63, 163) + { 0, { 0, 0, 0}}, // ( 64, 163) + { 0, { 0, 0, 0}}, // ( 65, 163) + { 0, { 0, 0, 0}}, // ( 66, 163) + { 0, { 0, 0, 0}}, // ( 67, 163) + { 0, { 0, 0, 0}}, // ( 68, 163) + { 0, { 0, 0, 0}}, // ( 69, 163) + { 0, { 0, 0, 0}}, // ( 70, 163) + { 0, { 0, 0, 0}}, // ( 71, 163) + { 0, { 0, 0, 0}}, // ( 72, 163) + { 0, { 0, 0, 0}}, // ( 73, 163) + { 0, { 0, 0, 0}}, // ( 74, 163) + { 0, { 0, 0, 0}}, // ( 75, 163) + { 0, { 0, 0, 0}}, // ( 76, 163) + { 0, { 0, 0, 0}}, // ( 77, 163) + { 0, { 0, 0, 0}}, // ( 78, 163) + { 0, { 0, 0, 0}}, // ( 79, 163) + { 0, { 0, 0, 0}}, // ( 80, 163) + { 0, { 0, 0, 0}}, // ( 81, 163) + { 0, { 0, 0, 0}}, // ( 82, 163) + { 0, { 0, 0, 0}}, // ( 83, 163) + { 0, { 0, 0, 0}}, // ( 84, 163) + { 0, { 0, 0, 0}}, // ( 85, 163) + { 0, { 0, 0, 0}}, // ( 86, 163) + { 0, { 0, 0, 0}}, // ( 87, 163) + { 0, { 0, 0, 0}}, // ( 88, 163) + { 0, { 0, 0, 0}}, // ( 89, 163) + { 0, { 0, 0, 0}}, // ( 90, 163) + { 0, { 0, 0, 0}}, // ( 91, 163) + { 0, { 0, 0, 0}}, // ( 92, 163) + { 0, { 0, 0, 0}}, // ( 93, 163) + { 0, { 0, 0, 0}}, // ( 94, 163) + { 0, { 0, 0, 0}}, // ( 95, 163) + { 0, { 0, 0, 0}}, // ( 96, 163) + { 0, { 0, 0, 0}}, // ( 97, 163) + { 0, { 0, 0, 0}}, // ( 98, 163) + { 0, { 0, 0, 0}}, // ( 99, 163) + { 0, { 0, 0, 0}}, // (100, 163) + { 0, { 0, 0, 0}}, // (101, 163) + { 0, { 0, 0, 0}}, // (102, 163) + { 0, { 0, 0, 0}}, // (103, 163) + { 0, { 0, 0, 0}}, // (104, 163) + { 0, { 0, 0, 0}}, // (105, 163) + { 0, { 0, 0, 0}}, // (106, 163) + { 0, { 0, 0, 0}}, // (107, 163) + { 0, { 0, 0, 0}}, // (108, 163) + { 0, { 0, 0, 0}}, // (109, 163) + { 0, { 0, 0, 0}}, // (110, 163) + { 0, { 0, 0, 0}}, // (111, 163) + { 0, { 0, 0, 0}}, // (112, 163) + { 0, { 0, 0, 0}}, // (113, 163) + { 0, { 0, 0, 0}}, // (114, 163) + { 0, { 0, 0, 0}}, // (115, 163) + { 0, { 0, 0, 0}}, // (116, 163) + { 0, { 0, 0, 0}}, // (117, 163) + { 0, { 0, 0, 0}}, // (118, 163) + { 0, { 0, 0, 0}}, // (119, 163) + { 0, { 0, 0, 0}}, // (120, 163) + { 0, { 0, 0, 0}}, // (121, 163) + { 0, { 0, 0, 0}}, // (122, 163) + { 0, { 0, 0, 0}}, // (123, 163) + { 0, { 0, 0, 0}}, // (124, 163) + { 0, { 0, 0, 0}}, // (125, 163) + { 0, { 0, 0, 0}}, // (126, 163) + { 0, { 0, 0, 0}}, // (127, 163) + { 0, { 0, 0, 0}}, // (128, 163) + { 0, { 0, 0, 0}}, // (129, 163) + { 0, { 0, 0, 0}}, // (130, 163) + { 0, { 0, 0, 0}}, // (131, 163) + { 0, { 0, 0, 0}}, // (132, 163) + { 0, { 0, 0, 0}}, // (133, 163) + { 0, { 0, 0, 0}}, // (134, 163) + { 0, { 0, 0, 0}}, // (135, 163) + { 0, { 0, 0, 0}}, // (136, 163) + { 7, { 0, 0, 0}}, // (137, 163) + { 74, { 0, 0, 0}}, // (138, 163) + {127, { 0, 0, 0}}, // (139, 163) + {128, { 0, 0, 0}}, // (140, 163) + {128, { 0, 0, 0}}, // (141, 163) + {128, { 0, 0, 0}}, // (142, 163) + {128, { 0, 0, 0}}, // (143, 163) + {128, { 0, 0, 0}}, // (144, 163) + {128, { 0, 0, 0}}, // (145, 163) + {128, { 0, 0, 0}}, // (146, 163) + {128, { 0, 0, 0}}, // (147, 163) + {128, { 0, 0, 0}}, // (148, 163) + {128, { 0, 0, 0}}, // (149, 163) + {128, { 0, 0, 0}}, // (150, 163) + {128, { 0, 0, 0}}, // (151, 163) + {128, { 0, 0, 0}}, // (152, 163) + {128, { 0, 0, 0}}, // (153, 163) + {128, { 0, 0, 0}}, // (154, 163) + {128, { 0, 0, 0}}, // (155, 163) + {128, { 0, 0, 0}}, // (156, 163) + {128, { 0, 0, 0}}, // (157, 163) + {128, { 0, 0, 0}}, // (158, 163) + {128, { 0, 0, 0}}, // (159, 163) + {128, { 0, 0, 0}}, // (160, 163) + {128, { 0, 0, 0}}, // (161, 163) + {128, { 0, 0, 0}}, // (162, 163) + {128, { 0, 0, 0}}, // (163, 163) + {128, { 0, 0, 0}}, // (164, 163) + {128, { 0, 0, 0}}, // (165, 163) + {128, { 0, 0, 0}}, // (166, 163) + {128, { 0, 0, 0}}, // (167, 163) + {128, { 0, 0, 0}}, // (168, 163) + {128, { 0, 0, 0}}, // (169, 163) + {128, { 0, 0, 0}}, // (170, 163) + {128, { 0, 0, 0}}, // (171, 163) + {128, { 0, 0, 0}}, // (172, 163) + {128, { 0, 0, 0}}, // (173, 163) + {128, { 0, 0, 0}}, // (174, 163) + {128, { 0, 0, 0}}, // (175, 163) + {128, { 0, 0, 0}}, // (176, 163) + {128, { 0, 0, 0}}, // (177, 163) + {128, { 0, 0, 0}}, // (178, 163) + {128, { 0, 0, 0}}, // (179, 163) + {128, { 0, 0, 0}}, // ( 0, 164) + {128, { 0, 0, 0}}, // ( 1, 164) + {128, { 0, 0, 0}}, // ( 2, 164) + {128, { 0, 0, 0}}, // ( 3, 164) + {128, { 0, 0, 0}}, // ( 4, 164) + {128, { 0, 0, 0}}, // ( 5, 164) + {128, { 0, 0, 0}}, // ( 6, 164) + {128, { 0, 0, 0}}, // ( 7, 164) + {128, { 0, 0, 0}}, // ( 8, 164) + {128, { 0, 0, 0}}, // ( 9, 164) + {128, { 0, 0, 0}}, // ( 10, 164) + {128, { 0, 0, 0}}, // ( 11, 164) + {128, { 0, 0, 0}}, // ( 12, 164) + {128, { 0, 0, 0}}, // ( 13, 164) + {128, { 0, 0, 0}}, // ( 14, 164) + {128, { 0, 0, 0}}, // ( 15, 164) + {128, { 0, 0, 0}}, // ( 16, 164) + {128, { 0, 0, 0}}, // ( 17, 164) + {128, { 0, 0, 0}}, // ( 18, 164) + {128, { 0, 0, 0}}, // ( 19, 164) + {128, { 0, 0, 0}}, // ( 20, 164) + {128, { 0, 0, 0}}, // ( 21, 164) + {128, { 0, 0, 0}}, // ( 22, 164) + {128, { 0, 0, 0}}, // ( 23, 164) + {128, { 0, 0, 0}}, // ( 24, 164) + {128, { 0, 0, 0}}, // ( 25, 164) + {128, { 0, 0, 0}}, // ( 26, 164) + {128, { 0, 0, 0}}, // ( 27, 164) + {128, { 0, 0, 0}}, // ( 28, 164) + {128, { 0, 0, 0}}, // ( 29, 164) + {128, { 0, 0, 0}}, // ( 30, 164) + {128, { 0, 0, 0}}, // ( 31, 164) + {128, { 0, 0, 0}}, // ( 32, 164) + {128, { 0, 0, 0}}, // ( 33, 164) + {128, { 0, 0, 0}}, // ( 34, 164) + {128, { 0, 0, 0}}, // ( 35, 164) + {128, { 0, 0, 0}}, // ( 36, 164) + {128, { 0, 0, 0}}, // ( 37, 164) + {128, { 0, 0, 0}}, // ( 38, 164) + {128, { 0, 0, 0}}, // ( 39, 164) + {128, { 0, 0, 0}}, // ( 40, 164) + {128, { 0, 0, 0}}, // ( 41, 164) + {113, { 0, 0, 0}}, // ( 42, 164) + { 38, { 0, 0, 0}}, // ( 43, 164) + { 0, { 0, 0, 0}}, // ( 44, 164) + { 0, { 0, 0, 0}}, // ( 45, 164) + { 0, { 0, 0, 0}}, // ( 46, 164) + { 0, { 0, 0, 0}}, // ( 47, 164) + { 0, { 0, 0, 0}}, // ( 48, 164) + { 0, { 0, 0, 0}}, // ( 49, 164) + { 0, { 0, 0, 0}}, // ( 50, 164) + { 0, { 0, 0, 0}}, // ( 51, 164) + { 0, { 0, 0, 0}}, // ( 52, 164) + { 0, { 0, 0, 0}}, // ( 53, 164) + { 0, { 0, 0, 0}}, // ( 54, 164) + { 0, { 0, 0, 0}}, // ( 55, 164) + { 0, { 0, 0, 0}}, // ( 56, 164) + { 0, { 0, 0, 0}}, // ( 57, 164) + { 0, { 0, 0, 0}}, // ( 58, 164) + { 0, { 0, 0, 0}}, // ( 59, 164) + { 0, { 0, 0, 0}}, // ( 60, 164) + { 0, { 0, 0, 0}}, // ( 61, 164) + { 0, { 0, 0, 0}}, // ( 62, 164) + { 0, { 0, 0, 0}}, // ( 63, 164) + { 0, { 0, 0, 0}}, // ( 64, 164) + { 0, { 0, 0, 0}}, // ( 65, 164) + { 0, { 0, 0, 0}}, // ( 66, 164) + { 0, { 0, 0, 0}}, // ( 67, 164) + { 0, { 0, 0, 0}}, // ( 68, 164) + { 0, { 0, 0, 0}}, // ( 69, 164) + { 0, { 0, 0, 0}}, // ( 70, 164) + { 0, { 0, 0, 0}}, // ( 71, 164) + { 0, { 0, 0, 0}}, // ( 72, 164) + { 0, { 0, 0, 0}}, // ( 73, 164) + { 0, { 0, 0, 0}}, // ( 74, 164) + { 0, { 0, 0, 0}}, // ( 75, 164) + { 0, { 0, 0, 0}}, // ( 76, 164) + { 0, { 0, 0, 0}}, // ( 77, 164) + { 0, { 0, 0, 0}}, // ( 78, 164) + { 0, { 0, 0, 0}}, // ( 79, 164) + { 0, { 0, 0, 0}}, // ( 80, 164) + { 0, { 0, 0, 0}}, // ( 81, 164) + { 0, { 0, 0, 0}}, // ( 82, 164) + { 0, { 0, 0, 0}}, // ( 83, 164) + { 0, { 0, 0, 0}}, // ( 84, 164) + { 0, { 0, 0, 0}}, // ( 85, 164) + { 0, { 0, 0, 0}}, // ( 86, 164) + { 0, { 0, 0, 0}}, // ( 87, 164) + { 0, { 0, 0, 0}}, // ( 88, 164) + { 0, { 0, 0, 0}}, // ( 89, 164) + { 0, { 0, 0, 0}}, // ( 90, 164) + { 0, { 0, 0, 0}}, // ( 91, 164) + { 0, { 0, 0, 0}}, // ( 92, 164) + { 0, { 0, 0, 0}}, // ( 93, 164) + { 0, { 0, 0, 0}}, // ( 94, 164) + { 0, { 0, 0, 0}}, // ( 95, 164) + { 0, { 0, 0, 0}}, // ( 96, 164) + { 0, { 0, 0, 0}}, // ( 97, 164) + { 0, { 0, 0, 0}}, // ( 98, 164) + { 0, { 0, 0, 0}}, // ( 99, 164) + { 0, { 0, 0, 0}}, // (100, 164) + { 0, { 0, 0, 0}}, // (101, 164) + { 0, { 0, 0, 0}}, // (102, 164) + { 0, { 0, 0, 0}}, // (103, 164) + { 0, { 0, 0, 0}}, // (104, 164) + { 0, { 0, 0, 0}}, // (105, 164) + { 0, { 0, 0, 0}}, // (106, 164) + { 0, { 0, 0, 0}}, // (107, 164) + { 0, { 0, 0, 0}}, // (108, 164) + { 0, { 0, 0, 0}}, // (109, 164) + { 0, { 0, 0, 0}}, // (110, 164) + { 0, { 0, 0, 0}}, // (111, 164) + { 0, { 0, 0, 0}}, // (112, 164) + { 0, { 0, 0, 0}}, // (113, 164) + { 0, { 0, 0, 0}}, // (114, 164) + { 0, { 0, 0, 0}}, // (115, 164) + { 0, { 0, 0, 0}}, // (116, 164) + { 0, { 0, 0, 0}}, // (117, 164) + { 0, { 0, 0, 0}}, // (118, 164) + { 0, { 0, 0, 0}}, // (119, 164) + { 0, { 0, 0, 0}}, // (120, 164) + { 0, { 0, 0, 0}}, // (121, 164) + { 0, { 0, 0, 0}}, // (122, 164) + { 0, { 0, 0, 0}}, // (123, 164) + { 0, { 0, 0, 0}}, // (124, 164) + { 0, { 0, 0, 0}}, // (125, 164) + { 0, { 0, 0, 0}}, // (126, 164) + { 0, { 0, 0, 0}}, // (127, 164) + { 0, { 0, 0, 0}}, // (128, 164) + { 0, { 0, 0, 0}}, // (129, 164) + { 0, { 0, 0, 0}}, // (130, 164) + { 0, { 0, 0, 0}}, // (131, 164) + { 0, { 0, 0, 0}}, // (132, 164) + { 0, { 0, 0, 0}}, // (133, 164) + { 0, { 0, 0, 0}}, // (134, 164) + { 0, { 0, 0, 0}}, // (135, 164) + { 38, { 0, 0, 0}}, // (136, 164) + {113, { 0, 0, 0}}, // (137, 164) + {128, { 0, 0, 0}}, // (138, 164) + {128, { 0, 0, 0}}, // (139, 164) + {128, { 0, 0, 0}}, // (140, 164) + {128, { 0, 0, 0}}, // (141, 164) + {128, { 0, 0, 0}}, // (142, 164) + {128, { 0, 0, 0}}, // (143, 164) + {128, { 0, 0, 0}}, // (144, 164) + {128, { 0, 0, 0}}, // (145, 164) + {128, { 0, 0, 0}}, // (146, 164) + {128, { 0, 0, 0}}, // (147, 164) + {128, { 0, 0, 0}}, // (148, 164) + {128, { 0, 0, 0}}, // (149, 164) + {128, { 0, 0, 0}}, // (150, 164) + {128, { 0, 0, 0}}, // (151, 164) + {128, { 0, 0, 0}}, // (152, 164) + {128, { 0, 0, 0}}, // (153, 164) + {128, { 0, 0, 0}}, // (154, 164) + {128, { 0, 0, 0}}, // (155, 164) + {128, { 0, 0, 0}}, // (156, 164) + {128, { 0, 0, 0}}, // (157, 164) + {128, { 0, 0, 0}}, // (158, 164) + {128, { 0, 0, 0}}, // (159, 164) + {128, { 0, 0, 0}}, // (160, 164) + {128, { 0, 0, 0}}, // (161, 164) + {128, { 0, 0, 0}}, // (162, 164) + {128, { 0, 0, 0}}, // (163, 164) + {128, { 0, 0, 0}}, // (164, 164) + {128, { 0, 0, 0}}, // (165, 164) + {128, { 0, 0, 0}}, // (166, 164) + {128, { 0, 0, 0}}, // (167, 164) + {128, { 0, 0, 0}}, // (168, 164) + {128, { 0, 0, 0}}, // (169, 164) + {128, { 0, 0, 0}}, // (170, 164) + {128, { 0, 0, 0}}, // (171, 164) + {128, { 0, 0, 0}}, // (172, 164) + {128, { 0, 0, 0}}, // (173, 164) + {128, { 0, 0, 0}}, // (174, 164) + {128, { 0, 0, 0}}, // (175, 164) + {128, { 0, 0, 0}}, // (176, 164) + {128, { 0, 0, 0}}, // (177, 164) + {128, { 0, 0, 0}}, // (178, 164) + {128, { 0, 0, 0}}, // (179, 164) + {128, { 0, 0, 0}}, // ( 0, 165) + {128, { 0, 0, 0}}, // ( 1, 165) + {128, { 0, 0, 0}}, // ( 2, 165) + {128, { 0, 0, 0}}, // ( 3, 165) + {128, { 0, 0, 0}}, // ( 4, 165) + {128, { 0, 0, 0}}, // ( 5, 165) + {128, { 0, 0, 0}}, // ( 6, 165) + {128, { 0, 0, 0}}, // ( 7, 165) + {128, { 0, 0, 0}}, // ( 8, 165) + {128, { 0, 0, 0}}, // ( 9, 165) + {128, { 0, 0, 0}}, // ( 10, 165) + {128, { 0, 0, 0}}, // ( 11, 165) + {128, { 0, 0, 0}}, // ( 12, 165) + {128, { 0, 0, 0}}, // ( 13, 165) + {128, { 0, 0, 0}}, // ( 14, 165) + {128, { 0, 0, 0}}, // ( 15, 165) + {128, { 0, 0, 0}}, // ( 16, 165) + {128, { 0, 0, 0}}, // ( 17, 165) + {128, { 0, 0, 0}}, // ( 18, 165) + {128, { 0, 0, 0}}, // ( 19, 165) + {128, { 0, 0, 0}}, // ( 20, 165) + {128, { 0, 0, 0}}, // ( 21, 165) + {128, { 0, 0, 0}}, // ( 22, 165) + {128, { 0, 0, 0}}, // ( 23, 165) + {128, { 0, 0, 0}}, // ( 24, 165) + {128, { 0, 0, 0}}, // ( 25, 165) + {128, { 0, 0, 0}}, // ( 26, 165) + {128, { 0, 0, 0}}, // ( 27, 165) + {128, { 0, 0, 0}}, // ( 28, 165) + {128, { 0, 0, 0}}, // ( 29, 165) + {128, { 0, 0, 0}}, // ( 30, 165) + {128, { 0, 0, 0}}, // ( 31, 165) + {128, { 0, 0, 0}}, // ( 32, 165) + {128, { 0, 0, 0}}, // ( 33, 165) + {128, { 0, 0, 0}}, // ( 34, 165) + {128, { 0, 0, 0}}, // ( 35, 165) + {128, { 0, 0, 0}}, // ( 36, 165) + {128, { 0, 0, 0}}, // ( 37, 165) + {128, { 0, 0, 0}}, // ( 38, 165) + {128, { 0, 0, 0}}, // ( 39, 165) + {128, { 0, 0, 0}}, // ( 40, 165) + {128, { 0, 0, 0}}, // ( 41, 165) + {128, { 0, 0, 0}}, // ( 42, 165) + {128, { 0, 0, 0}}, // ( 43, 165) + { 85, { 0, 0, 0}}, // ( 44, 165) + { 15, { 0, 0, 0}}, // ( 45, 165) + { 0, { 0, 0, 0}}, // ( 46, 165) + { 0, { 0, 0, 0}}, // ( 47, 165) + { 0, { 0, 0, 0}}, // ( 48, 165) + { 0, { 0, 0, 0}}, // ( 49, 165) + { 0, { 0, 0, 0}}, // ( 50, 165) + { 0, { 0, 0, 0}}, // ( 51, 165) + { 0, { 0, 0, 0}}, // ( 52, 165) + { 0, { 0, 0, 0}}, // ( 53, 165) + { 0, { 0, 0, 0}}, // ( 54, 165) + { 0, { 0, 0, 0}}, // ( 55, 165) + { 0, { 0, 0, 0}}, // ( 56, 165) + { 0, { 0, 0, 0}}, // ( 57, 165) + { 0, { 0, 0, 0}}, // ( 58, 165) + { 0, { 0, 0, 0}}, // ( 59, 165) + { 0, { 0, 0, 0}}, // ( 60, 165) + { 0, { 0, 0, 0}}, // ( 61, 165) + { 0, { 0, 0, 0}}, // ( 62, 165) + { 0, { 0, 0, 0}}, // ( 63, 165) + { 0, { 0, 0, 0}}, // ( 64, 165) + { 0, { 0, 0, 0}}, // ( 65, 165) + { 0, { 0, 0, 0}}, // ( 66, 165) + { 0, { 0, 0, 0}}, // ( 67, 165) + { 0, { 0, 0, 0}}, // ( 68, 165) + { 0, { 0, 0, 0}}, // ( 69, 165) + { 0, { 0, 0, 0}}, // ( 70, 165) + { 0, { 0, 0, 0}}, // ( 71, 165) + { 0, { 0, 0, 0}}, // ( 72, 165) + { 0, { 0, 0, 0}}, // ( 73, 165) + { 0, { 0, 0, 0}}, // ( 74, 165) + { 0, { 0, 0, 0}}, // ( 75, 165) + { 0, { 0, 0, 0}}, // ( 76, 165) + { 0, { 0, 0, 0}}, // ( 77, 165) + { 0, { 0, 0, 0}}, // ( 78, 165) + { 0, { 0, 0, 0}}, // ( 79, 165) + { 0, { 0, 0, 0}}, // ( 80, 165) + { 0, { 0, 0, 0}}, // ( 81, 165) + { 0, { 0, 0, 0}}, // ( 82, 165) + { 0, { 0, 0, 0}}, // ( 83, 165) + { 0, { 0, 0, 0}}, // ( 84, 165) + { 0, { 0, 0, 0}}, // ( 85, 165) + { 0, { 0, 0, 0}}, // ( 86, 165) + { 0, { 0, 0, 0}}, // ( 87, 165) + { 0, { 0, 0, 0}}, // ( 88, 165) + { 0, { 0, 0, 0}}, // ( 89, 165) + { 0, { 0, 0, 0}}, // ( 90, 165) + { 0, { 0, 0, 0}}, // ( 91, 165) + { 0, { 0, 0, 0}}, // ( 92, 165) + { 0, { 0, 0, 0}}, // ( 93, 165) + { 0, { 0, 0, 0}}, // ( 94, 165) + { 0, { 0, 0, 0}}, // ( 95, 165) + { 0, { 0, 0, 0}}, // ( 96, 165) + { 0, { 0, 0, 0}}, // ( 97, 165) + { 0, { 0, 0, 0}}, // ( 98, 165) + { 0, { 0, 0, 0}}, // ( 99, 165) + { 0, { 0, 0, 0}}, // (100, 165) + { 0, { 0, 0, 0}}, // (101, 165) + { 0, { 0, 0, 0}}, // (102, 165) + { 0, { 0, 0, 0}}, // (103, 165) + { 0, { 0, 0, 0}}, // (104, 165) + { 0, { 0, 0, 0}}, // (105, 165) + { 0, { 0, 0, 0}}, // (106, 165) + { 0, { 0, 0, 0}}, // (107, 165) + { 0, { 0, 0, 0}}, // (108, 165) + { 0, { 0, 0, 0}}, // (109, 165) + { 0, { 0, 0, 0}}, // (110, 165) + { 0, { 0, 0, 0}}, // (111, 165) + { 0, { 0, 0, 0}}, // (112, 165) + { 0, { 0, 0, 0}}, // (113, 165) + { 0, { 0, 0, 0}}, // (114, 165) + { 0, { 0, 0, 0}}, // (115, 165) + { 0, { 0, 0, 0}}, // (116, 165) + { 0, { 0, 0, 0}}, // (117, 165) + { 0, { 0, 0, 0}}, // (118, 165) + { 0, { 0, 0, 0}}, // (119, 165) + { 0, { 0, 0, 0}}, // (120, 165) + { 0, { 0, 0, 0}}, // (121, 165) + { 0, { 0, 0, 0}}, // (122, 165) + { 0, { 0, 0, 0}}, // (123, 165) + { 0, { 0, 0, 0}}, // (124, 165) + { 0, { 0, 0, 0}}, // (125, 165) + { 0, { 0, 0, 0}}, // (126, 165) + { 0, { 0, 0, 0}}, // (127, 165) + { 0, { 0, 0, 0}}, // (128, 165) + { 0, { 0, 0, 0}}, // (129, 165) + { 0, { 0, 0, 0}}, // (130, 165) + { 0, { 0, 0, 0}}, // (131, 165) + { 0, { 0, 0, 0}}, // (132, 165) + { 0, { 0, 0, 0}}, // (133, 165) + { 15, { 0, 0, 0}}, // (134, 165) + { 85, { 0, 0, 0}}, // (135, 165) + {128, { 0, 0, 0}}, // (136, 165) + {128, { 0, 0, 0}}, // (137, 165) + {128, { 0, 0, 0}}, // (138, 165) + {128, { 0, 0, 0}}, // (139, 165) + {128, { 0, 0, 0}}, // (140, 165) + {128, { 0, 0, 0}}, // (141, 165) + {128, { 0, 0, 0}}, // (142, 165) + {128, { 0, 0, 0}}, // (143, 165) + {128, { 0, 0, 0}}, // (144, 165) + {128, { 0, 0, 0}}, // (145, 165) + {128, { 0, 0, 0}}, // (146, 165) + {128, { 0, 0, 0}}, // (147, 165) + {128, { 0, 0, 0}}, // (148, 165) + {128, { 0, 0, 0}}, // (149, 165) + {128, { 0, 0, 0}}, // (150, 165) + {128, { 0, 0, 0}}, // (151, 165) + {128, { 0, 0, 0}}, // (152, 165) + {128, { 0, 0, 0}}, // (153, 165) + {128, { 0, 0, 0}}, // (154, 165) + {128, { 0, 0, 0}}, // (155, 165) + {128, { 0, 0, 0}}, // (156, 165) + {128, { 0, 0, 0}}, // (157, 165) + {128, { 0, 0, 0}}, // (158, 165) + {128, { 0, 0, 0}}, // (159, 165) + {128, { 0, 0, 0}}, // (160, 165) + {128, { 0, 0, 0}}, // (161, 165) + {128, { 0, 0, 0}}, // (162, 165) + {128, { 0, 0, 0}}, // (163, 165) + {128, { 0, 0, 0}}, // (164, 165) + {128, { 0, 0, 0}}, // (165, 165) + {128, { 0, 0, 0}}, // (166, 165) + {128, { 0, 0, 0}}, // (167, 165) + {128, { 0, 0, 0}}, // (168, 165) + {128, { 0, 0, 0}}, // (169, 165) + {128, { 0, 0, 0}}, // (170, 165) + {128, { 0, 0, 0}}, // (171, 165) + {128, { 0, 0, 0}}, // (172, 165) + {128, { 0, 0, 0}}, // (173, 165) + {128, { 0, 0, 0}}, // (174, 165) + {128, { 0, 0, 0}}, // (175, 165) + {128, { 0, 0, 0}}, // (176, 165) + {128, { 0, 0, 0}}, // (177, 165) + {128, { 0, 0, 0}}, // (178, 165) + {128, { 0, 0, 0}}, // (179, 165) + {128, { 0, 0, 0}}, // ( 0, 166) + {128, { 0, 0, 0}}, // ( 1, 166) + {128, { 0, 0, 0}}, // ( 2, 166) + {128, { 0, 0, 0}}, // ( 3, 166) + {128, { 0, 0, 0}}, // ( 4, 166) + {128, { 0, 0, 0}}, // ( 5, 166) + {128, { 0, 0, 0}}, // ( 6, 166) + {128, { 0, 0, 0}}, // ( 7, 166) + {128, { 0, 0, 0}}, // ( 8, 166) + {128, { 0, 0, 0}}, // ( 9, 166) + {128, { 0, 0, 0}}, // ( 10, 166) + {128, { 0, 0, 0}}, // ( 11, 166) + {128, { 0, 0, 0}}, // ( 12, 166) + {128, { 0, 0, 0}}, // ( 13, 166) + {128, { 0, 0, 0}}, // ( 14, 166) + {128, { 0, 0, 0}}, // ( 15, 166) + {128, { 0, 0, 0}}, // ( 16, 166) + {128, { 0, 0, 0}}, // ( 17, 166) + {128, { 0, 0, 0}}, // ( 18, 166) + {128, { 0, 0, 0}}, // ( 19, 166) + {128, { 0, 0, 0}}, // ( 20, 166) + {128, { 0, 0, 0}}, // ( 21, 166) + {128, { 0, 0, 0}}, // ( 22, 166) + {128, { 0, 0, 0}}, // ( 23, 166) + {128, { 0, 0, 0}}, // ( 24, 166) + {128, { 0, 0, 0}}, // ( 25, 166) + {128, { 0, 0, 0}}, // ( 26, 166) + {128, { 0, 0, 0}}, // ( 27, 166) + {128, { 0, 0, 0}}, // ( 28, 166) + {128, { 0, 0, 0}}, // ( 29, 166) + {128, { 0, 0, 0}}, // ( 30, 166) + {128, { 0, 0, 0}}, // ( 31, 166) + {128, { 0, 0, 0}}, // ( 32, 166) + {128, { 0, 0, 0}}, // ( 33, 166) + {128, { 0, 0, 0}}, // ( 34, 166) + {128, { 0, 0, 0}}, // ( 35, 166) + {128, { 0, 0, 0}}, // ( 36, 166) + {128, { 0, 0, 0}}, // ( 37, 166) + {128, { 0, 0, 0}}, // ( 38, 166) + {128, { 0, 0, 0}}, // ( 39, 166) + {128, { 0, 0, 0}}, // ( 40, 166) + {128, { 0, 0, 0}}, // ( 41, 166) + {128, { 0, 0, 0}}, // ( 42, 166) + {128, { 0, 0, 0}}, // ( 43, 166) + {128, { 0, 0, 0}}, // ( 44, 166) + {123, { 0, 0, 0}}, // ( 45, 166) + { 66, { 0, 0, 0}}, // ( 46, 166) + { 6, { 0, 0, 0}}, // ( 47, 166) + { 0, { 0, 0, 0}}, // ( 48, 166) + { 0, { 0, 0, 0}}, // ( 49, 166) + { 0, { 0, 0, 0}}, // ( 50, 166) + { 0, { 0, 0, 0}}, // ( 51, 166) + { 0, { 0, 0, 0}}, // ( 52, 166) + { 0, { 0, 0, 0}}, // ( 53, 166) + { 0, { 0, 0, 0}}, // ( 54, 166) + { 0, { 0, 0, 0}}, // ( 55, 166) + { 0, { 0, 0, 0}}, // ( 56, 166) + { 0, { 0, 0, 0}}, // ( 57, 166) + { 0, { 0, 0, 0}}, // ( 58, 166) + { 0, { 0, 0, 0}}, // ( 59, 166) + { 0, { 0, 0, 0}}, // ( 60, 166) + { 0, { 0, 0, 0}}, // ( 61, 166) + { 0, { 0, 0, 0}}, // ( 62, 166) + { 0, { 0, 0, 0}}, // ( 63, 166) + { 0, { 0, 0, 0}}, // ( 64, 166) + { 0, { 0, 0, 0}}, // ( 65, 166) + { 0, { 0, 0, 0}}, // ( 66, 166) + { 0, { 0, 0, 0}}, // ( 67, 166) + { 0, { 0, 0, 0}}, // ( 68, 166) + { 0, { 0, 0, 0}}, // ( 69, 166) + { 0, { 0, 0, 0}}, // ( 70, 166) + { 0, { 0, 0, 0}}, // ( 71, 166) + { 0, { 0, 0, 0}}, // ( 72, 166) + { 0, { 0, 0, 0}}, // ( 73, 166) + { 0, { 0, 0, 0}}, // ( 74, 166) + { 0, { 0, 0, 0}}, // ( 75, 166) + { 0, { 0, 0, 0}}, // ( 76, 166) + { 0, { 0, 0, 0}}, // ( 77, 166) + { 0, { 0, 0, 0}}, // ( 78, 166) + { 0, { 0, 0, 0}}, // ( 79, 166) + { 0, { 0, 0, 0}}, // ( 80, 166) + { 0, { 0, 0, 0}}, // ( 81, 166) + { 0, { 0, 0, 0}}, // ( 82, 166) + { 0, { 0, 0, 0}}, // ( 83, 166) + { 0, { 0, 0, 0}}, // ( 84, 166) + { 0, { 0, 0, 0}}, // ( 85, 166) + { 0, { 0, 0, 0}}, // ( 86, 166) + { 0, { 0, 0, 0}}, // ( 87, 166) + { 0, { 0, 0, 0}}, // ( 88, 166) + { 0, { 0, 0, 0}}, // ( 89, 166) + { 0, { 0, 0, 0}}, // ( 90, 166) + { 0, { 0, 0, 0}}, // ( 91, 166) + { 0, { 0, 0, 0}}, // ( 92, 166) + { 0, { 0, 0, 0}}, // ( 93, 166) + { 0, { 0, 0, 0}}, // ( 94, 166) + { 0, { 0, 0, 0}}, // ( 95, 166) + { 0, { 0, 0, 0}}, // ( 96, 166) + { 0, { 0, 0, 0}}, // ( 97, 166) + { 0, { 0, 0, 0}}, // ( 98, 166) + { 0, { 0, 0, 0}}, // ( 99, 166) + { 0, { 0, 0, 0}}, // (100, 166) + { 0, { 0, 0, 0}}, // (101, 166) + { 0, { 0, 0, 0}}, // (102, 166) + { 0, { 0, 0, 0}}, // (103, 166) + { 0, { 0, 0, 0}}, // (104, 166) + { 0, { 0, 0, 0}}, // (105, 166) + { 0, { 0, 0, 0}}, // (106, 166) + { 0, { 0, 0, 0}}, // (107, 166) + { 0, { 0, 0, 0}}, // (108, 166) + { 0, { 0, 0, 0}}, // (109, 166) + { 0, { 0, 0, 0}}, // (110, 166) + { 0, { 0, 0, 0}}, // (111, 166) + { 0, { 0, 0, 0}}, // (112, 166) + { 0, { 0, 0, 0}}, // (113, 166) + { 0, { 0, 0, 0}}, // (114, 166) + { 0, { 0, 0, 0}}, // (115, 166) + { 0, { 0, 0, 0}}, // (116, 166) + { 0, { 0, 0, 0}}, // (117, 166) + { 0, { 0, 0, 0}}, // (118, 166) + { 0, { 0, 0, 0}}, // (119, 166) + { 0, { 0, 0, 0}}, // (120, 166) + { 0, { 0, 0, 0}}, // (121, 166) + { 0, { 0, 0, 0}}, // (122, 166) + { 0, { 0, 0, 0}}, // (123, 166) + { 0, { 0, 0, 0}}, // (124, 166) + { 0, { 0, 0, 0}}, // (125, 166) + { 0, { 0, 0, 0}}, // (126, 166) + { 0, { 0, 0, 0}}, // (127, 166) + { 0, { 0, 0, 0}}, // (128, 166) + { 0, { 0, 0, 0}}, // (129, 166) + { 0, { 0, 0, 0}}, // (130, 166) + { 0, { 0, 0, 0}}, // (131, 166) + { 6, { 0, 0, 0}}, // (132, 166) + { 66, { 0, 0, 0}}, // (133, 166) + {123, { 0, 0, 0}}, // (134, 166) + {128, { 0, 0, 0}}, // (135, 166) + {128, { 0, 0, 0}}, // (136, 166) + {128, { 0, 0, 0}}, // (137, 166) + {128, { 0, 0, 0}}, // (138, 166) + {128, { 0, 0, 0}}, // (139, 166) + {128, { 0, 0, 0}}, // (140, 166) + {128, { 0, 0, 0}}, // (141, 166) + {128, { 0, 0, 0}}, // (142, 166) + {128, { 0, 0, 0}}, // (143, 166) + {128, { 0, 0, 0}}, // (144, 166) + {128, { 0, 0, 0}}, // (145, 166) + {128, { 0, 0, 0}}, // (146, 166) + {128, { 0, 0, 0}}, // (147, 166) + {128, { 0, 0, 0}}, // (148, 166) + {128, { 0, 0, 0}}, // (149, 166) + {128, { 0, 0, 0}}, // (150, 166) + {128, { 0, 0, 0}}, // (151, 166) + {128, { 0, 0, 0}}, // (152, 166) + {128, { 0, 0, 0}}, // (153, 166) + {128, { 0, 0, 0}}, // (154, 166) + {128, { 0, 0, 0}}, // (155, 166) + {128, { 0, 0, 0}}, // (156, 166) + {128, { 0, 0, 0}}, // (157, 166) + {128, { 0, 0, 0}}, // (158, 166) + {128, { 0, 0, 0}}, // (159, 166) + {128, { 0, 0, 0}}, // (160, 166) + {128, { 0, 0, 0}}, // (161, 166) + {128, { 0, 0, 0}}, // (162, 166) + {128, { 0, 0, 0}}, // (163, 166) + {128, { 0, 0, 0}}, // (164, 166) + {128, { 0, 0, 0}}, // (165, 166) + {128, { 0, 0, 0}}, // (166, 166) + {128, { 0, 0, 0}}, // (167, 166) + {128, { 0, 0, 0}}, // (168, 166) + {128, { 0, 0, 0}}, // (169, 166) + {128, { 0, 0, 0}}, // (170, 166) + {128, { 0, 0, 0}}, // (171, 166) + {128, { 0, 0, 0}}, // (172, 166) + {128, { 0, 0, 0}}, // (173, 166) + {128, { 0, 0, 0}}, // (174, 166) + {128, { 0, 0, 0}}, // (175, 166) + {128, { 0, 0, 0}}, // (176, 166) + {128, { 0, 0, 0}}, // (177, 166) + {128, { 0, 0, 0}}, // (178, 166) + {128, { 0, 0, 0}}, // (179, 166) + {128, { 0, 0, 0}}, // ( 0, 167) + {128, { 0, 0, 0}}, // ( 1, 167) + {128, { 0, 0, 0}}, // ( 2, 167) + {128, { 0, 0, 0}}, // ( 3, 167) + {128, { 0, 0, 0}}, // ( 4, 167) + {128, { 0, 0, 0}}, // ( 5, 167) + {128, { 0, 0, 0}}, // ( 6, 167) + {128, { 0, 0, 0}}, // ( 7, 167) + {128, { 0, 0, 0}}, // ( 8, 167) + {128, { 0, 0, 0}}, // ( 9, 167) + {128, { 0, 0, 0}}, // ( 10, 167) + {128, { 0, 0, 0}}, // ( 11, 167) + {128, { 0, 0, 0}}, // ( 12, 167) + {128, { 0, 0, 0}}, // ( 13, 167) + {128, { 0, 0, 0}}, // ( 14, 167) + {128, { 0, 0, 0}}, // ( 15, 167) + {128, { 0, 0, 0}}, // ( 16, 167) + {128, { 0, 0, 0}}, // ( 17, 167) + {128, { 0, 0, 0}}, // ( 18, 167) + {128, { 0, 0, 0}}, // ( 19, 167) + {128, { 0, 0, 0}}, // ( 20, 167) + {128, { 0, 0, 0}}, // ( 21, 167) + {128, { 0, 0, 0}}, // ( 22, 167) + {128, { 0, 0, 0}}, // ( 23, 167) + {128, { 0, 0, 0}}, // ( 24, 167) + {128, { 0, 0, 0}}, // ( 25, 167) + {128, { 0, 0, 0}}, // ( 26, 167) + {128, { 0, 0, 0}}, // ( 27, 167) + {128, { 0, 0, 0}}, // ( 28, 167) + {128, { 0, 0, 0}}, // ( 29, 167) + {128, { 0, 0, 0}}, // ( 30, 167) + {128, { 0, 0, 0}}, // ( 31, 167) + {128, { 0, 0, 0}}, // ( 32, 167) + {128, { 0, 0, 0}}, // ( 33, 167) + {128, { 0, 0, 0}}, // ( 34, 167) + {128, { 0, 0, 0}}, // ( 35, 167) + {128, { 0, 0, 0}}, // ( 36, 167) + {128, { 0, 0, 0}}, // ( 37, 167) + {128, { 0, 0, 0}}, // ( 38, 167) + {128, { 0, 0, 0}}, // ( 39, 167) + {128, { 0, 0, 0}}, // ( 40, 167) + {128, { 0, 0, 0}}, // ( 41, 167) + {128, { 0, 0, 0}}, // ( 42, 167) + {128, { 0, 0, 0}}, // ( 43, 167) + {128, { 0, 0, 0}}, // ( 44, 167) + {128, { 0, 0, 0}}, // ( 45, 167) + {128, { 0, 0, 0}}, // ( 46, 167) + {115, { 0, 0, 0}}, // ( 47, 167) + { 51, { 0, 0, 0}}, // ( 48, 167) + { 2, { 0, 0, 0}}, // ( 49, 167) + { 0, { 0, 0, 0}}, // ( 50, 167) + { 0, { 0, 0, 0}}, // ( 51, 167) + { 0, { 0, 0, 0}}, // ( 52, 167) + { 0, { 0, 0, 0}}, // ( 53, 167) + { 0, { 0, 0, 0}}, // ( 54, 167) + { 0, { 0, 0, 0}}, // ( 55, 167) + { 0, { 0, 0, 0}}, // ( 56, 167) + { 0, { 0, 0, 0}}, // ( 57, 167) + { 0, { 0, 0, 0}}, // ( 58, 167) + { 0, { 0, 0, 0}}, // ( 59, 167) + { 0, { 0, 0, 0}}, // ( 60, 167) + { 0, { 0, 0, 0}}, // ( 61, 167) + { 0, { 0, 0, 0}}, // ( 62, 167) + { 0, { 0, 0, 0}}, // ( 63, 167) + { 0, { 0, 0, 0}}, // ( 64, 167) + { 0, { 0, 0, 0}}, // ( 65, 167) + { 0, { 0, 0, 0}}, // ( 66, 167) + { 0, { 0, 0, 0}}, // ( 67, 167) + { 0, { 0, 0, 0}}, // ( 68, 167) + { 0, { 0, 0, 0}}, // ( 69, 167) + { 0, { 0, 0, 0}}, // ( 70, 167) + { 0, { 0, 0, 0}}, // ( 71, 167) + { 0, { 0, 0, 0}}, // ( 72, 167) + { 0, { 0, 0, 0}}, // ( 73, 167) + { 0, { 0, 0, 0}}, // ( 74, 167) + { 0, { 0, 0, 0}}, // ( 75, 167) + { 0, { 0, 0, 0}}, // ( 76, 167) + { 0, { 0, 0, 0}}, // ( 77, 167) + { 0, { 0, 0, 0}}, // ( 78, 167) + { 0, { 0, 0, 0}}, // ( 79, 167) + { 0, { 0, 0, 0}}, // ( 80, 167) + { 0, { 0, 0, 0}}, // ( 81, 167) + { 0, { 0, 0, 0}}, // ( 82, 167) + { 0, { 0, 0, 0}}, // ( 83, 167) + { 0, { 0, 0, 0}}, // ( 84, 167) + { 0, { 0, 0, 0}}, // ( 85, 167) + { 0, { 0, 0, 0}}, // ( 86, 167) + { 0, { 0, 0, 0}}, // ( 87, 167) + { 0, { 0, 0, 0}}, // ( 88, 167) + { 0, { 0, 0, 0}}, // ( 89, 167) + { 0, { 0, 0, 0}}, // ( 90, 167) + { 0, { 0, 0, 0}}, // ( 91, 167) + { 0, { 0, 0, 0}}, // ( 92, 167) + { 0, { 0, 0, 0}}, // ( 93, 167) + { 0, { 0, 0, 0}}, // ( 94, 167) + { 0, { 0, 0, 0}}, // ( 95, 167) + { 0, { 0, 0, 0}}, // ( 96, 167) + { 0, { 0, 0, 0}}, // ( 97, 167) + { 0, { 0, 0, 0}}, // ( 98, 167) + { 0, { 0, 0, 0}}, // ( 99, 167) + { 0, { 0, 0, 0}}, // (100, 167) + { 0, { 0, 0, 0}}, // (101, 167) + { 0, { 0, 0, 0}}, // (102, 167) + { 0, { 0, 0, 0}}, // (103, 167) + { 0, { 0, 0, 0}}, // (104, 167) + { 0, { 0, 0, 0}}, // (105, 167) + { 0, { 0, 0, 0}}, // (106, 167) + { 0, { 0, 0, 0}}, // (107, 167) + { 0, { 0, 0, 0}}, // (108, 167) + { 0, { 0, 0, 0}}, // (109, 167) + { 0, { 0, 0, 0}}, // (110, 167) + { 0, { 0, 0, 0}}, // (111, 167) + { 0, { 0, 0, 0}}, // (112, 167) + { 0, { 0, 0, 0}}, // (113, 167) + { 0, { 0, 0, 0}}, // (114, 167) + { 0, { 0, 0, 0}}, // (115, 167) + { 0, { 0, 0, 0}}, // (116, 167) + { 0, { 0, 0, 0}}, // (117, 167) + { 0, { 0, 0, 0}}, // (118, 167) + { 0, { 0, 0, 0}}, // (119, 167) + { 0, { 0, 0, 0}}, // (120, 167) + { 0, { 0, 0, 0}}, // (121, 167) + { 0, { 0, 0, 0}}, // (122, 167) + { 0, { 0, 0, 0}}, // (123, 167) + { 0, { 0, 0, 0}}, // (124, 167) + { 0, { 0, 0, 0}}, // (125, 167) + { 0, { 0, 0, 0}}, // (126, 167) + { 0, { 0, 0, 0}}, // (127, 167) + { 0, { 0, 0, 0}}, // (128, 167) + { 0, { 0, 0, 0}}, // (129, 167) + { 2, { 0, 0, 0}}, // (130, 167) + { 50, { 0, 0, 0}}, // (131, 167) + {115, { 0, 0, 0}}, // (132, 167) + {128, { 0, 0, 0}}, // (133, 167) + {128, { 0, 0, 0}}, // (134, 167) + {128, { 0, 0, 0}}, // (135, 167) + {128, { 0, 0, 0}}, // (136, 167) + {128, { 0, 0, 0}}, // (137, 167) + {128, { 0, 0, 0}}, // (138, 167) + {128, { 0, 0, 0}}, // (139, 167) + {128, { 0, 0, 0}}, // (140, 167) + {128, { 0, 0, 0}}, // (141, 167) + {128, { 0, 0, 0}}, // (142, 167) + {128, { 0, 0, 0}}, // (143, 167) + {128, { 0, 0, 0}}, // (144, 167) + {128, { 0, 0, 0}}, // (145, 167) + {128, { 0, 0, 0}}, // (146, 167) + {128, { 0, 0, 0}}, // (147, 167) + {128, { 0, 0, 0}}, // (148, 167) + {128, { 0, 0, 0}}, // (149, 167) + {128, { 0, 0, 0}}, // (150, 167) + {128, { 0, 0, 0}}, // (151, 167) + {128, { 0, 0, 0}}, // (152, 167) + {128, { 0, 0, 0}}, // (153, 167) + {128, { 0, 0, 0}}, // (154, 167) + {128, { 0, 0, 0}}, // (155, 167) + {128, { 0, 0, 0}}, // (156, 167) + {128, { 0, 0, 0}}, // (157, 167) + {128, { 0, 0, 0}}, // (158, 167) + {128, { 0, 0, 0}}, // (159, 167) + {128, { 0, 0, 0}}, // (160, 167) + {128, { 0, 0, 0}}, // (161, 167) + {128, { 0, 0, 0}}, // (162, 167) + {128, { 0, 0, 0}}, // (163, 167) + {128, { 0, 0, 0}}, // (164, 167) + {128, { 0, 0, 0}}, // (165, 167) + {128, { 0, 0, 0}}, // (166, 167) + {128, { 0, 0, 0}}, // (167, 167) + {128, { 0, 0, 0}}, // (168, 167) + {128, { 0, 0, 0}}, // (169, 167) + {128, { 0, 0, 0}}, // (170, 167) + {128, { 0, 0, 0}}, // (171, 167) + {128, { 0, 0, 0}}, // (172, 167) + {128, { 0, 0, 0}}, // (173, 167) + {128, { 0, 0, 0}}, // (174, 167) + {128, { 0, 0, 0}}, // (175, 167) + {128, { 0, 0, 0}}, // (176, 167) + {128, { 0, 0, 0}}, // (177, 167) + {128, { 0, 0, 0}}, // (178, 167) + {128, { 0, 0, 0}}, // (179, 167) + {128, { 0, 0, 0}}, // ( 0, 168) + {128, { 0, 0, 0}}, // ( 1, 168) + {128, { 0, 0, 0}}, // ( 2, 168) + {128, { 0, 0, 0}}, // ( 3, 168) + {128, { 0, 0, 0}}, // ( 4, 168) + {128, { 0, 0, 0}}, // ( 5, 168) + {128, { 0, 0, 0}}, // ( 6, 168) + {128, { 0, 0, 0}}, // ( 7, 168) + {128, { 0, 0, 0}}, // ( 8, 168) + {128, { 0, 0, 0}}, // ( 9, 168) + {128, { 0, 0, 0}}, // ( 10, 168) + {128, { 0, 0, 0}}, // ( 11, 168) + {128, { 0, 0, 0}}, // ( 12, 168) + {128, { 0, 0, 0}}, // ( 13, 168) + {128, { 0, 0, 0}}, // ( 14, 168) + {128, { 0, 0, 0}}, // ( 15, 168) + {128, { 0, 0, 0}}, // ( 16, 168) + {128, { 0, 0, 0}}, // ( 17, 168) + {128, { 0, 0, 0}}, // ( 18, 168) + {128, { 0, 0, 0}}, // ( 19, 168) + {128, { 0, 0, 0}}, // ( 20, 168) + {128, { 0, 0, 0}}, // ( 21, 168) + {128, { 0, 0, 0}}, // ( 22, 168) + {128, { 0, 0, 0}}, // ( 23, 168) + {128, { 0, 0, 0}}, // ( 24, 168) + {128, { 0, 0, 0}}, // ( 25, 168) + {128, { 0, 0, 0}}, // ( 26, 168) + {128, { 0, 0, 0}}, // ( 27, 168) + {128, { 0, 0, 0}}, // ( 28, 168) + {128, { 0, 0, 0}}, // ( 29, 168) + {128, { 0, 0, 0}}, // ( 30, 168) + {128, { 0, 0, 0}}, // ( 31, 168) + {128, { 0, 0, 0}}, // ( 32, 168) + {128, { 0, 0, 0}}, // ( 33, 168) + {128, { 0, 0, 0}}, // ( 34, 168) + {128, { 0, 0, 0}}, // ( 35, 168) + {128, { 0, 0, 0}}, // ( 36, 168) + {128, { 0, 0, 0}}, // ( 37, 168) + {128, { 0, 0, 0}}, // ( 38, 168) + {128, { 0, 0, 0}}, // ( 39, 168) + {128, { 0, 0, 0}}, // ( 40, 168) + {128, { 0, 0, 0}}, // ( 41, 168) + {128, { 0, 0, 0}}, // ( 42, 168) + {128, { 0, 0, 0}}, // ( 43, 168) + {128, { 0, 0, 0}}, // ( 44, 168) + {128, { 0, 0, 0}}, // ( 45, 168) + {128, { 0, 0, 0}}, // ( 46, 168) + {128, { 0, 0, 0}}, // ( 47, 168) + {128, { 0, 0, 0}}, // ( 48, 168) + {110, { 0, 0, 0}}, // ( 49, 168) + { 47, { 0, 0, 0}}, // ( 50, 168) + { 2, { 0, 0, 0}}, // ( 51, 168) + { 0, { 0, 0, 0}}, // ( 52, 168) + { 0, { 0, 0, 0}}, // ( 53, 168) + { 0, { 0, 0, 0}}, // ( 54, 168) + { 0, { 0, 0, 0}}, // ( 55, 168) + { 0, { 0, 0, 0}}, // ( 56, 168) + { 0, { 0, 0, 0}}, // ( 57, 168) + { 0, { 0, 0, 0}}, // ( 58, 168) + { 0, { 0, 0, 0}}, // ( 59, 168) + { 0, { 0, 0, 0}}, // ( 60, 168) + { 0, { 0, 0, 0}}, // ( 61, 168) + { 0, { 0, 0, 0}}, // ( 62, 168) + { 0, { 0, 0, 0}}, // ( 63, 168) + { 0, { 0, 0, 0}}, // ( 64, 168) + { 0, { 0, 0, 0}}, // ( 65, 168) + { 0, { 0, 0, 0}}, // ( 66, 168) + { 0, { 0, 0, 0}}, // ( 67, 168) + { 0, { 0, 0, 0}}, // ( 68, 168) + { 0, { 0, 0, 0}}, // ( 69, 168) + { 0, { 0, 0, 0}}, // ( 70, 168) + { 0, { 0, 0, 0}}, // ( 71, 168) + { 0, { 0, 0, 0}}, // ( 72, 168) + { 0, { 0, 0, 0}}, // ( 73, 168) + { 0, { 0, 0, 0}}, // ( 74, 168) + { 0, { 0, 0, 0}}, // ( 75, 168) + { 0, { 0, 0, 0}}, // ( 76, 168) + { 0, { 0, 0, 0}}, // ( 77, 168) + { 0, { 0, 0, 0}}, // ( 78, 168) + { 0, { 0, 0, 0}}, // ( 79, 168) + { 0, { 0, 0, 0}}, // ( 80, 168) + { 0, { 0, 0, 0}}, // ( 81, 168) + { 0, { 0, 0, 0}}, // ( 82, 168) + { 0, { 0, 0, 0}}, // ( 83, 168) + { 0, { 0, 0, 0}}, // ( 84, 168) + { 0, { 0, 0, 0}}, // ( 85, 168) + { 0, { 0, 0, 0}}, // ( 86, 168) + { 0, { 0, 0, 0}}, // ( 87, 168) + { 0, { 0, 0, 0}}, // ( 88, 168) + { 0, { 0, 0, 0}}, // ( 89, 168) + { 0, { 0, 0, 0}}, // ( 90, 168) + { 0, { 0, 0, 0}}, // ( 91, 168) + { 0, { 0, 0, 0}}, // ( 92, 168) + { 0, { 0, 0, 0}}, // ( 93, 168) + { 0, { 0, 0, 0}}, // ( 94, 168) + { 0, { 0, 0, 0}}, // ( 95, 168) + { 0, { 0, 0, 0}}, // ( 96, 168) + { 0, { 0, 0, 0}}, // ( 97, 168) + { 0, { 0, 0, 0}}, // ( 98, 168) + { 0, { 0, 0, 0}}, // ( 99, 168) + { 0, { 0, 0, 0}}, // (100, 168) + { 0, { 0, 0, 0}}, // (101, 168) + { 0, { 0, 0, 0}}, // (102, 168) + { 0, { 0, 0, 0}}, // (103, 168) + { 0, { 0, 0, 0}}, // (104, 168) + { 0, { 0, 0, 0}}, // (105, 168) + { 0, { 0, 0, 0}}, // (106, 168) + { 0, { 0, 0, 0}}, // (107, 168) + { 0, { 0, 0, 0}}, // (108, 168) + { 0, { 0, 0, 0}}, // (109, 168) + { 0, { 0, 0, 0}}, // (110, 168) + { 0, { 0, 0, 0}}, // (111, 168) + { 0, { 0, 0, 0}}, // (112, 168) + { 0, { 0, 0, 0}}, // (113, 168) + { 0, { 0, 0, 0}}, // (114, 168) + { 0, { 0, 0, 0}}, // (115, 168) + { 0, { 0, 0, 0}}, // (116, 168) + { 0, { 0, 0, 0}}, // (117, 168) + { 0, { 0, 0, 0}}, // (118, 168) + { 0, { 0, 0, 0}}, // (119, 168) + { 0, { 0, 0, 0}}, // (120, 168) + { 0, { 0, 0, 0}}, // (121, 168) + { 0, { 0, 0, 0}}, // (122, 168) + { 0, { 0, 0, 0}}, // (123, 168) + { 0, { 0, 0, 0}}, // (124, 168) + { 0, { 0, 0, 0}}, // (125, 168) + { 0, { 0, 0, 0}}, // (126, 168) + { 0, { 0, 0, 0}}, // (127, 168) + { 2, { 0, 0, 0}}, // (128, 168) + { 47, { 0, 0, 0}}, // (129, 168) + {110, { 0, 0, 0}}, // (130, 168) + {128, { 0, 0, 0}}, // (131, 168) + {128, { 0, 0, 0}}, // (132, 168) + {128, { 0, 0, 0}}, // (133, 168) + {128, { 0, 0, 0}}, // (134, 168) + {128, { 0, 0, 0}}, // (135, 168) + {128, { 0, 0, 0}}, // (136, 168) + {128, { 0, 0, 0}}, // (137, 168) + {128, { 0, 0, 0}}, // (138, 168) + {128, { 0, 0, 0}}, // (139, 168) + {128, { 0, 0, 0}}, // (140, 168) + {128, { 0, 0, 0}}, // (141, 168) + {128, { 0, 0, 0}}, // (142, 168) + {128, { 0, 0, 0}}, // (143, 168) + {128, { 0, 0, 0}}, // (144, 168) + {128, { 0, 0, 0}}, // (145, 168) + {128, { 0, 0, 0}}, // (146, 168) + {128, { 0, 0, 0}}, // (147, 168) + {128, { 0, 0, 0}}, // (148, 168) + {128, { 0, 0, 0}}, // (149, 168) + {128, { 0, 0, 0}}, // (150, 168) + {128, { 0, 0, 0}}, // (151, 168) + {128, { 0, 0, 0}}, // (152, 168) + {128, { 0, 0, 0}}, // (153, 168) + {128, { 0, 0, 0}}, // (154, 168) + {128, { 0, 0, 0}}, // (155, 168) + {128, { 0, 0, 0}}, // (156, 168) + {128, { 0, 0, 0}}, // (157, 168) + {128, { 0, 0, 0}}, // (158, 168) + {128, { 0, 0, 0}}, // (159, 168) + {128, { 0, 0, 0}}, // (160, 168) + {128, { 0, 0, 0}}, // (161, 168) + {128, { 0, 0, 0}}, // (162, 168) + {128, { 0, 0, 0}}, // (163, 168) + {128, { 0, 0, 0}}, // (164, 168) + {128, { 0, 0, 0}}, // (165, 168) + {128, { 0, 0, 0}}, // (166, 168) + {128, { 0, 0, 0}}, // (167, 168) + {128, { 0, 0, 0}}, // (168, 168) + {128, { 0, 0, 0}}, // (169, 168) + {128, { 0, 0, 0}}, // (170, 168) + {128, { 0, 0, 0}}, // (171, 168) + {128, { 0, 0, 0}}, // (172, 168) + {128, { 0, 0, 0}}, // (173, 168) + {128, { 0, 0, 0}}, // (174, 168) + {128, { 0, 0, 0}}, // (175, 168) + {128, { 0, 0, 0}}, // (176, 168) + {128, { 0, 0, 0}}, // (177, 168) + {128, { 0, 0, 0}}, // (178, 168) + {128, { 0, 0, 0}}, // (179, 168) + {128, { 0, 0, 0}}, // ( 0, 169) + {128, { 0, 0, 0}}, // ( 1, 169) + {128, { 0, 0, 0}}, // ( 2, 169) + {128, { 0, 0, 0}}, // ( 3, 169) + {128, { 0, 0, 0}}, // ( 4, 169) + {128, { 0, 0, 0}}, // ( 5, 169) + {128, { 0, 0, 0}}, // ( 6, 169) + {128, { 0, 0, 0}}, // ( 7, 169) + {128, { 0, 0, 0}}, // ( 8, 169) + {128, { 0, 0, 0}}, // ( 9, 169) + {128, { 0, 0, 0}}, // ( 10, 169) + {128, { 0, 0, 0}}, // ( 11, 169) + {128, { 0, 0, 0}}, // ( 12, 169) + {128, { 0, 0, 0}}, // ( 13, 169) + {128, { 0, 0, 0}}, // ( 14, 169) + {128, { 0, 0, 0}}, // ( 15, 169) + {128, { 0, 0, 0}}, // ( 16, 169) + {128, { 0, 0, 0}}, // ( 17, 169) + {128, { 0, 0, 0}}, // ( 18, 169) + {128, { 0, 0, 0}}, // ( 19, 169) + {128, { 0, 0, 0}}, // ( 20, 169) + {128, { 0, 0, 0}}, // ( 21, 169) + {128, { 0, 0, 0}}, // ( 22, 169) + {128, { 0, 0, 0}}, // ( 23, 169) + {128, { 0, 0, 0}}, // ( 24, 169) + {128, { 0, 0, 0}}, // ( 25, 169) + {128, { 0, 0, 0}}, // ( 26, 169) + {128, { 0, 0, 0}}, // ( 27, 169) + {128, { 0, 0, 0}}, // ( 28, 169) + {128, { 0, 0, 0}}, // ( 29, 169) + {128, { 0, 0, 0}}, // ( 30, 169) + {128, { 0, 0, 0}}, // ( 31, 169) + {128, { 0, 0, 0}}, // ( 32, 169) + {128, { 0, 0, 0}}, // ( 33, 169) + {128, { 0, 0, 0}}, // ( 34, 169) + {128, { 0, 0, 0}}, // ( 35, 169) + {128, { 0, 0, 0}}, // ( 36, 169) + {128, { 0, 0, 0}}, // ( 37, 169) + {128, { 0, 0, 0}}, // ( 38, 169) + {128, { 0, 0, 0}}, // ( 39, 169) + {128, { 0, 0, 0}}, // ( 40, 169) + {128, { 0, 0, 0}}, // ( 41, 169) + {128, { 0, 0, 0}}, // ( 42, 169) + {128, { 0, 0, 0}}, // ( 43, 169) + {128, { 0, 0, 0}}, // ( 44, 169) + {128, { 0, 0, 0}}, // ( 45, 169) + {128, { 0, 0, 0}}, // ( 46, 169) + {128, { 0, 0, 0}}, // ( 47, 169) + {128, { 0, 0, 0}}, // ( 48, 169) + {128, { 0, 0, 0}}, // ( 49, 169) + {128, { 0, 0, 0}}, // ( 50, 169) + {108, { 0, 0, 0}}, // ( 51, 169) + { 50, { 0, 0, 0}}, // ( 52, 169) + { 4, { 0, 0, 0}}, // ( 53, 169) + { 0, { 0, 0, 0}}, // ( 54, 169) + { 0, { 0, 0, 0}}, // ( 55, 169) + { 0, { 0, 0, 0}}, // ( 56, 169) + { 0, { 0, 0, 0}}, // ( 57, 169) + { 0, { 0, 0, 0}}, // ( 58, 169) + { 0, { 0, 0, 0}}, // ( 59, 169) + { 0, { 0, 0, 0}}, // ( 60, 169) + { 0, { 0, 0, 0}}, // ( 61, 169) + { 0, { 0, 0, 0}}, // ( 62, 169) + { 0, { 0, 0, 0}}, // ( 63, 169) + { 0, { 0, 0, 0}}, // ( 64, 169) + { 0, { 0, 0, 0}}, // ( 65, 169) + { 0, { 0, 0, 0}}, // ( 66, 169) + { 0, { 0, 0, 0}}, // ( 67, 169) + { 0, { 0, 0, 0}}, // ( 68, 169) + { 0, { 0, 0, 0}}, // ( 69, 169) + { 0, { 0, 0, 0}}, // ( 70, 169) + { 0, { 0, 0, 0}}, // ( 71, 169) + { 0, { 0, 0, 0}}, // ( 72, 169) + { 0, { 0, 0, 0}}, // ( 73, 169) + { 0, { 0, 0, 0}}, // ( 74, 169) + { 0, { 0, 0, 0}}, // ( 75, 169) + { 0, { 0, 0, 0}}, // ( 76, 169) + { 0, { 0, 0, 0}}, // ( 77, 169) + { 0, { 0, 0, 0}}, // ( 78, 169) + { 0, { 0, 0, 0}}, // ( 79, 169) + { 0, { 0, 0, 0}}, // ( 80, 169) + { 0, { 0, 0, 0}}, // ( 81, 169) + { 0, { 0, 0, 0}}, // ( 82, 169) + { 0, { 0, 0, 0}}, // ( 83, 169) + { 0, { 0, 0, 0}}, // ( 84, 169) + { 0, { 0, 0, 0}}, // ( 85, 169) + { 0, { 0, 0, 0}}, // ( 86, 169) + { 0, { 0, 0, 0}}, // ( 87, 169) + { 0, { 0, 0, 0}}, // ( 88, 169) + { 0, { 0, 0, 0}}, // ( 89, 169) + { 0, { 0, 0, 0}}, // ( 90, 169) + { 0, { 0, 0, 0}}, // ( 91, 169) + { 0, { 0, 0, 0}}, // ( 92, 169) + { 0, { 0, 0, 0}}, // ( 93, 169) + { 0, { 0, 0, 0}}, // ( 94, 169) + { 0, { 0, 0, 0}}, // ( 95, 169) + { 0, { 0, 0, 0}}, // ( 96, 169) + { 0, { 0, 0, 0}}, // ( 97, 169) + { 0, { 0, 0, 0}}, // ( 98, 169) + { 0, { 0, 0, 0}}, // ( 99, 169) + { 0, { 0, 0, 0}}, // (100, 169) + { 0, { 0, 0, 0}}, // (101, 169) + { 0, { 0, 0, 0}}, // (102, 169) + { 0, { 0, 0, 0}}, // (103, 169) + { 0, { 0, 0, 0}}, // (104, 169) + { 0, { 0, 0, 0}}, // (105, 169) + { 0, { 0, 0, 0}}, // (106, 169) + { 0, { 0, 0, 0}}, // (107, 169) + { 0, { 0, 0, 0}}, // (108, 169) + { 0, { 0, 0, 0}}, // (109, 169) + { 0, { 0, 0, 0}}, // (110, 169) + { 0, { 0, 0, 0}}, // (111, 169) + { 0, { 0, 0, 0}}, // (112, 169) + { 0, { 0, 0, 0}}, // (113, 169) + { 0, { 0, 0, 0}}, // (114, 169) + { 0, { 0, 0, 0}}, // (115, 169) + { 0, { 0, 0, 0}}, // (116, 169) + { 0, { 0, 0, 0}}, // (117, 169) + { 0, { 0, 0, 0}}, // (118, 169) + { 0, { 0, 0, 0}}, // (119, 169) + { 0, { 0, 0, 0}}, // (120, 169) + { 0, { 0, 0, 0}}, // (121, 169) + { 0, { 0, 0, 0}}, // (122, 169) + { 0, { 0, 0, 0}}, // (123, 169) + { 0, { 0, 0, 0}}, // (124, 169) + { 0, { 0, 0, 0}}, // (125, 169) + { 4, { 0, 0, 0}}, // (126, 169) + { 50, { 0, 0, 0}}, // (127, 169) + {108, { 0, 0, 0}}, // (128, 169) + {128, { 0, 0, 0}}, // (129, 169) + {128, { 0, 0, 0}}, // (130, 169) + {128, { 0, 0, 0}}, // (131, 169) + {128, { 0, 0, 0}}, // (132, 169) + {128, { 0, 0, 0}}, // (133, 169) + {128, { 0, 0, 0}}, // (134, 169) + {128, { 0, 0, 0}}, // (135, 169) + {128, { 0, 0, 0}}, // (136, 169) + {128, { 0, 0, 0}}, // (137, 169) + {128, { 0, 0, 0}}, // (138, 169) + {128, { 0, 0, 0}}, // (139, 169) + {128, { 0, 0, 0}}, // (140, 169) + {128, { 0, 0, 0}}, // (141, 169) + {128, { 0, 0, 0}}, // (142, 169) + {128, { 0, 0, 0}}, // (143, 169) + {128, { 0, 0, 0}}, // (144, 169) + {128, { 0, 0, 0}}, // (145, 169) + {128, { 0, 0, 0}}, // (146, 169) + {128, { 0, 0, 0}}, // (147, 169) + {128, { 0, 0, 0}}, // (148, 169) + {128, { 0, 0, 0}}, // (149, 169) + {128, { 0, 0, 0}}, // (150, 169) + {128, { 0, 0, 0}}, // (151, 169) + {128, { 0, 0, 0}}, // (152, 169) + {128, { 0, 0, 0}}, // (153, 169) + {128, { 0, 0, 0}}, // (154, 169) + {128, { 0, 0, 0}}, // (155, 169) + {128, { 0, 0, 0}}, // (156, 169) + {128, { 0, 0, 0}}, // (157, 169) + {128, { 0, 0, 0}}, // (158, 169) + {128, { 0, 0, 0}}, // (159, 169) + {128, { 0, 0, 0}}, // (160, 169) + {128, { 0, 0, 0}}, // (161, 169) + {128, { 0, 0, 0}}, // (162, 169) + {128, { 0, 0, 0}}, // (163, 169) + {128, { 0, 0, 0}}, // (164, 169) + {128, { 0, 0, 0}}, // (165, 169) + {128, { 0, 0, 0}}, // (166, 169) + {128, { 0, 0, 0}}, // (167, 169) + {128, { 0, 0, 0}}, // (168, 169) + {128, { 0, 0, 0}}, // (169, 169) + {128, { 0, 0, 0}}, // (170, 169) + {128, { 0, 0, 0}}, // (171, 169) + {128, { 0, 0, 0}}, // (172, 169) + {128, { 0, 0, 0}}, // (173, 169) + {128, { 0, 0, 0}}, // (174, 169) + {128, { 0, 0, 0}}, // (175, 169) + {128, { 0, 0, 0}}, // (176, 169) + {128, { 0, 0, 0}}, // (177, 169) + {128, { 0, 0, 0}}, // (178, 169) + {128, { 0, 0, 0}}, // (179, 169) + {128, { 0, 0, 0}}, // ( 0, 170) + {128, { 0, 0, 0}}, // ( 1, 170) + {128, { 0, 0, 0}}, // ( 2, 170) + {128, { 0, 0, 0}}, // ( 3, 170) + {128, { 0, 0, 0}}, // ( 4, 170) + {128, { 0, 0, 0}}, // ( 5, 170) + {128, { 0, 0, 0}}, // ( 6, 170) + {128, { 0, 0, 0}}, // ( 7, 170) + {128, { 0, 0, 0}}, // ( 8, 170) + {128, { 0, 0, 0}}, // ( 9, 170) + {128, { 0, 0, 0}}, // ( 10, 170) + {128, { 0, 0, 0}}, // ( 11, 170) + {128, { 0, 0, 0}}, // ( 12, 170) + {128, { 0, 0, 0}}, // ( 13, 170) + {128, { 0, 0, 0}}, // ( 14, 170) + {128, { 0, 0, 0}}, // ( 15, 170) + {128, { 0, 0, 0}}, // ( 16, 170) + {128, { 0, 0, 0}}, // ( 17, 170) + {128, { 0, 0, 0}}, // ( 18, 170) + {128, { 0, 0, 0}}, // ( 19, 170) + {128, { 0, 0, 0}}, // ( 20, 170) + {128, { 0, 0, 0}}, // ( 21, 170) + {128, { 0, 0, 0}}, // ( 22, 170) + {128, { 0, 0, 0}}, // ( 23, 170) + {128, { 0, 0, 0}}, // ( 24, 170) + {128, { 0, 0, 0}}, // ( 25, 170) + {128, { 0, 0, 0}}, // ( 26, 170) + {128, { 0, 0, 0}}, // ( 27, 170) + {128, { 0, 0, 0}}, // ( 28, 170) + {128, { 0, 0, 0}}, // ( 29, 170) + {128, { 0, 0, 0}}, // ( 30, 170) + {128, { 0, 0, 0}}, // ( 31, 170) + {128, { 0, 0, 0}}, // ( 32, 170) + {128, { 0, 0, 0}}, // ( 33, 170) + {128, { 0, 0, 0}}, // ( 34, 170) + {128, { 0, 0, 0}}, // ( 35, 170) + {128, { 0, 0, 0}}, // ( 36, 170) + {128, { 0, 0, 0}}, // ( 37, 170) + {128, { 0, 0, 0}}, // ( 38, 170) + {128, { 0, 0, 0}}, // ( 39, 170) + {128, { 0, 0, 0}}, // ( 40, 170) + {128, { 0, 0, 0}}, // ( 41, 170) + {128, { 0, 0, 0}}, // ( 42, 170) + {128, { 0, 0, 0}}, // ( 43, 170) + {128, { 0, 0, 0}}, // ( 44, 170) + {128, { 0, 0, 0}}, // ( 45, 170) + {128, { 0, 0, 0}}, // ( 46, 170) + {128, { 0, 0, 0}}, // ( 47, 170) + {128, { 0, 0, 0}}, // ( 48, 170) + {128, { 0, 0, 0}}, // ( 49, 170) + {128, { 0, 0, 0}}, // ( 50, 170) + {128, { 0, 0, 0}}, // ( 51, 170) + {128, { 0, 0, 0}}, // ( 52, 170) + {116, { 0, 0, 0}}, // ( 53, 170) + { 61, { 0, 0, 0}}, // ( 54, 170) + { 9, { 0, 0, 0}}, // ( 55, 170) + { 0, { 0, 0, 0}}, // ( 56, 170) + { 0, { 0, 0, 0}}, // ( 57, 170) + { 0, { 0, 0, 0}}, // ( 58, 170) + { 0, { 0, 0, 0}}, // ( 59, 170) + { 0, { 0, 0, 0}}, // ( 60, 170) + { 0, { 0, 0, 0}}, // ( 61, 170) + { 0, { 0, 0, 0}}, // ( 62, 170) + { 0, { 0, 0, 0}}, // ( 63, 170) + { 0, { 0, 0, 0}}, // ( 64, 170) + { 0, { 0, 0, 0}}, // ( 65, 170) + { 0, { 0, 0, 0}}, // ( 66, 170) + { 0, { 0, 0, 0}}, // ( 67, 170) + { 0, { 0, 0, 0}}, // ( 68, 170) + { 0, { 0, 0, 0}}, // ( 69, 170) + { 0, { 0, 0, 0}}, // ( 70, 170) + { 0, { 0, 0, 0}}, // ( 71, 170) + { 0, { 0, 0, 0}}, // ( 72, 170) + { 0, { 0, 0, 0}}, // ( 73, 170) + { 0, { 0, 0, 0}}, // ( 74, 170) + { 0, { 0, 0, 0}}, // ( 75, 170) + { 0, { 0, 0, 0}}, // ( 76, 170) + { 0, { 0, 0, 0}}, // ( 77, 170) + { 0, { 0, 0, 0}}, // ( 78, 170) + { 0, { 0, 0, 0}}, // ( 79, 170) + { 0, { 0, 0, 0}}, // ( 80, 170) + { 0, { 0, 0, 0}}, // ( 81, 170) + { 0, { 0, 0, 0}}, // ( 82, 170) + { 0, { 0, 0, 0}}, // ( 83, 170) + { 0, { 0, 0, 0}}, // ( 84, 170) + { 0, { 0, 0, 0}}, // ( 85, 170) + { 0, { 0, 0, 0}}, // ( 86, 170) + { 0, { 0, 0, 0}}, // ( 87, 170) + { 0, { 0, 0, 0}}, // ( 88, 170) + { 0, { 0, 0, 0}}, // ( 89, 170) + { 0, { 0, 0, 0}}, // ( 90, 170) + { 0, { 0, 0, 0}}, // ( 91, 170) + { 0, { 0, 0, 0}}, // ( 92, 170) + { 0, { 0, 0, 0}}, // ( 93, 170) + { 0, { 0, 0, 0}}, // ( 94, 170) + { 0, { 0, 0, 0}}, // ( 95, 170) + { 0, { 0, 0, 0}}, // ( 96, 170) + { 0, { 0, 0, 0}}, // ( 97, 170) + { 0, { 0, 0, 0}}, // ( 98, 170) + { 0, { 0, 0, 0}}, // ( 99, 170) + { 0, { 0, 0, 0}}, // (100, 170) + { 0, { 0, 0, 0}}, // (101, 170) + { 0, { 0, 0, 0}}, // (102, 170) + { 0, { 0, 0, 0}}, // (103, 170) + { 0, { 0, 0, 0}}, // (104, 170) + { 0, { 0, 0, 0}}, // (105, 170) + { 0, { 0, 0, 0}}, // (106, 170) + { 0, { 0, 0, 0}}, // (107, 170) + { 0, { 0, 0, 0}}, // (108, 170) + { 0, { 0, 0, 0}}, // (109, 170) + { 0, { 0, 0, 0}}, // (110, 170) + { 0, { 0, 0, 0}}, // (111, 170) + { 0, { 0, 0, 0}}, // (112, 170) + { 0, { 0, 0, 0}}, // (113, 170) + { 0, { 0, 0, 0}}, // (114, 170) + { 0, { 0, 0, 0}}, // (115, 170) + { 0, { 0, 0, 0}}, // (116, 170) + { 0, { 0, 0, 0}}, // (117, 170) + { 0, { 0, 0, 0}}, // (118, 170) + { 0, { 0, 0, 0}}, // (119, 170) + { 0, { 0, 0, 0}}, // (120, 170) + { 0, { 0, 0, 0}}, // (121, 170) + { 0, { 0, 0, 0}}, // (122, 170) + { 0, { 0, 0, 0}}, // (123, 170) + { 9, { 0, 0, 0}}, // (124, 170) + { 61, { 0, 0, 0}}, // (125, 170) + {116, { 0, 0, 0}}, // (126, 170) + {128, { 0, 0, 0}}, // (127, 170) + {128, { 0, 0, 0}}, // (128, 170) + {128, { 0, 0, 0}}, // (129, 170) + {128, { 0, 0, 0}}, // (130, 170) + {128, { 0, 0, 0}}, // (131, 170) + {128, { 0, 0, 0}}, // (132, 170) + {128, { 0, 0, 0}}, // (133, 170) + {128, { 0, 0, 0}}, // (134, 170) + {128, { 0, 0, 0}}, // (135, 170) + {128, { 0, 0, 0}}, // (136, 170) + {128, { 0, 0, 0}}, // (137, 170) + {128, { 0, 0, 0}}, // (138, 170) + {128, { 0, 0, 0}}, // (139, 170) + {128, { 0, 0, 0}}, // (140, 170) + {128, { 0, 0, 0}}, // (141, 170) + {128, { 0, 0, 0}}, // (142, 170) + {128, { 0, 0, 0}}, // (143, 170) + {128, { 0, 0, 0}}, // (144, 170) + {128, { 0, 0, 0}}, // (145, 170) + {128, { 0, 0, 0}}, // (146, 170) + {128, { 0, 0, 0}}, // (147, 170) + {128, { 0, 0, 0}}, // (148, 170) + {128, { 0, 0, 0}}, // (149, 170) + {128, { 0, 0, 0}}, // (150, 170) + {128, { 0, 0, 0}}, // (151, 170) + {128, { 0, 0, 0}}, // (152, 170) + {128, { 0, 0, 0}}, // (153, 170) + {128, { 0, 0, 0}}, // (154, 170) + {128, { 0, 0, 0}}, // (155, 170) + {128, { 0, 0, 0}}, // (156, 170) + {128, { 0, 0, 0}}, // (157, 170) + {128, { 0, 0, 0}}, // (158, 170) + {128, { 0, 0, 0}}, // (159, 170) + {128, { 0, 0, 0}}, // (160, 170) + {128, { 0, 0, 0}}, // (161, 170) + {128, { 0, 0, 0}}, // (162, 170) + {128, { 0, 0, 0}}, // (163, 170) + {128, { 0, 0, 0}}, // (164, 170) + {128, { 0, 0, 0}}, // (165, 170) + {128, { 0, 0, 0}}, // (166, 170) + {128, { 0, 0, 0}}, // (167, 170) + {128, { 0, 0, 0}}, // (168, 170) + {128, { 0, 0, 0}}, // (169, 170) + {128, { 0, 0, 0}}, // (170, 170) + {128, { 0, 0, 0}}, // (171, 170) + {128, { 0, 0, 0}}, // (172, 170) + {128, { 0, 0, 0}}, // (173, 170) + {128, { 0, 0, 0}}, // (174, 170) + {128, { 0, 0, 0}}, // (175, 170) + {128, { 0, 0, 0}}, // (176, 170) + {128, { 0, 0, 0}}, // (177, 170) + {128, { 0, 0, 0}}, // (178, 170) + {128, { 0, 0, 0}}, // (179, 170) + {128, { 0, 0, 0}}, // ( 0, 171) + {128, { 0, 0, 0}}, // ( 1, 171) + {128, { 0, 0, 0}}, // ( 2, 171) + {128, { 0, 0, 0}}, // ( 3, 171) + {128, { 0, 0, 0}}, // ( 4, 171) + {128, { 0, 0, 0}}, // ( 5, 171) + {128, { 0, 0, 0}}, // ( 6, 171) + {128, { 0, 0, 0}}, // ( 7, 171) + {128, { 0, 0, 0}}, // ( 8, 171) + {128, { 0, 0, 0}}, // ( 9, 171) + {128, { 0, 0, 0}}, // ( 10, 171) + {128, { 0, 0, 0}}, // ( 11, 171) + {128, { 0, 0, 0}}, // ( 12, 171) + {128, { 0, 0, 0}}, // ( 13, 171) + {128, { 0, 0, 0}}, // ( 14, 171) + {128, { 0, 0, 0}}, // ( 15, 171) + {128, { 0, 0, 0}}, // ( 16, 171) + {128, { 0, 0, 0}}, // ( 17, 171) + {128, { 0, 0, 0}}, // ( 18, 171) + {128, { 0, 0, 0}}, // ( 19, 171) + {128, { 0, 0, 0}}, // ( 20, 171) + {128, { 0, 0, 0}}, // ( 21, 171) + {128, { 0, 0, 0}}, // ( 22, 171) + {128, { 0, 0, 0}}, // ( 23, 171) + {128, { 0, 0, 0}}, // ( 24, 171) + {128, { 0, 0, 0}}, // ( 25, 171) + {128, { 0, 0, 0}}, // ( 26, 171) + {128, { 0, 0, 0}}, // ( 27, 171) + {128, { 0, 0, 0}}, // ( 28, 171) + {128, { 0, 0, 0}}, // ( 29, 171) + {128, { 0, 0, 0}}, // ( 30, 171) + {128, { 0, 0, 0}}, // ( 31, 171) + {128, { 0, 0, 0}}, // ( 32, 171) + {128, { 0, 0, 0}}, // ( 33, 171) + {128, { 0, 0, 0}}, // ( 34, 171) + {128, { 0, 0, 0}}, // ( 35, 171) + {128, { 0, 0, 0}}, // ( 36, 171) + {128, { 0, 0, 0}}, // ( 37, 171) + {128, { 0, 0, 0}}, // ( 38, 171) + {128, { 0, 0, 0}}, // ( 39, 171) + {128, { 0, 0, 0}}, // ( 40, 171) + {128, { 0, 0, 0}}, // ( 41, 171) + {128, { 0, 0, 0}}, // ( 42, 171) + {128, { 0, 0, 0}}, // ( 43, 171) + {128, { 0, 0, 0}}, // ( 44, 171) + {128, { 0, 0, 0}}, // ( 45, 171) + {128, { 0, 0, 0}}, // ( 46, 171) + {128, { 0, 0, 0}}, // ( 47, 171) + {128, { 0, 0, 0}}, // ( 48, 171) + {128, { 0, 0, 0}}, // ( 49, 171) + {128, { 0, 0, 0}}, // ( 50, 171) + {128, { 0, 0, 0}}, // ( 51, 171) + {128, { 0, 0, 0}}, // ( 52, 171) + {128, { 0, 0, 0}}, // ( 53, 171) + {128, { 0, 0, 0}}, // ( 54, 171) + {122, { 0, 0, 0}}, // ( 55, 171) + { 79, { 0, 0, 0}}, // ( 56, 171) + { 29, { 0, 0, 0}}, // ( 57, 171) + { 0, { 0, 0, 0}}, // ( 58, 171) + { 0, { 0, 0, 0}}, // ( 59, 171) + { 0, { 0, 0, 0}}, // ( 60, 171) + { 0, { 0, 0, 0}}, // ( 61, 171) + { 0, { 0, 0, 0}}, // ( 62, 171) + { 0, { 0, 0, 0}}, // ( 63, 171) + { 0, { 0, 0, 0}}, // ( 64, 171) + { 0, { 0, 0, 0}}, // ( 65, 171) + { 0, { 0, 0, 0}}, // ( 66, 171) + { 0, { 0, 0, 0}}, // ( 67, 171) + { 0, { 0, 0, 0}}, // ( 68, 171) + { 0, { 0, 0, 0}}, // ( 69, 171) + { 0, { 0, 0, 0}}, // ( 70, 171) + { 0, { 0, 0, 0}}, // ( 71, 171) + { 0, { 0, 0, 0}}, // ( 72, 171) + { 0, { 0, 0, 0}}, // ( 73, 171) + { 0, { 0, 0, 0}}, // ( 74, 171) + { 0, { 0, 0, 0}}, // ( 75, 171) + { 0, { 0, 0, 0}}, // ( 76, 171) + { 0, { 0, 0, 0}}, // ( 77, 171) + { 0, { 0, 0, 0}}, // ( 78, 171) + { 0, { 0, 0, 0}}, // ( 79, 171) + { 0, { 0, 0, 0}}, // ( 80, 171) + { 0, { 0, 0, 0}}, // ( 81, 171) + { 0, { 0, 0, 0}}, // ( 82, 171) + { 0, { 0, 0, 0}}, // ( 83, 171) + { 0, { 0, 0, 0}}, // ( 84, 171) + { 0, { 0, 0, 0}}, // ( 85, 171) + { 0, { 0, 0, 0}}, // ( 86, 171) + { 0, { 0, 0, 0}}, // ( 87, 171) + { 0, { 0, 0, 0}}, // ( 88, 171) + { 0, { 0, 0, 0}}, // ( 89, 171) + { 0, { 0, 0, 0}}, // ( 90, 171) + { 0, { 0, 0, 0}}, // ( 91, 171) + { 0, { 0, 0, 0}}, // ( 92, 171) + { 0, { 0, 0, 0}}, // ( 93, 171) + { 0, { 0, 0, 0}}, // ( 94, 171) + { 0, { 0, 0, 0}}, // ( 95, 171) + { 0, { 0, 0, 0}}, // ( 96, 171) + { 0, { 0, 0, 0}}, // ( 97, 171) + { 0, { 0, 0, 0}}, // ( 98, 171) + { 0, { 0, 0, 0}}, // ( 99, 171) + { 0, { 0, 0, 0}}, // (100, 171) + { 0, { 0, 0, 0}}, // (101, 171) + { 0, { 0, 0, 0}}, // (102, 171) + { 0, { 0, 0, 0}}, // (103, 171) + { 0, { 0, 0, 0}}, // (104, 171) + { 0, { 0, 0, 0}}, // (105, 171) + { 0, { 0, 0, 0}}, // (106, 171) + { 0, { 0, 0, 0}}, // (107, 171) + { 0, { 0, 0, 0}}, // (108, 171) + { 0, { 0, 0, 0}}, // (109, 171) + { 0, { 0, 0, 0}}, // (110, 171) + { 0, { 0, 0, 0}}, // (111, 171) + { 0, { 0, 0, 0}}, // (112, 171) + { 0, { 0, 0, 0}}, // (113, 171) + { 0, { 0, 0, 0}}, // (114, 171) + { 0, { 0, 0, 0}}, // (115, 171) + { 0, { 0, 0, 0}}, // (116, 171) + { 0, { 0, 0, 0}}, // (117, 171) + { 0, { 0, 0, 0}}, // (118, 171) + { 0, { 0, 0, 0}}, // (119, 171) + { 0, { 0, 0, 0}}, // (120, 171) + { 0, { 0, 0, 0}}, // (121, 171) + { 29, { 0, 0, 0}}, // (122, 171) + { 79, { 0, 0, 0}}, // (123, 171) + {122, { 0, 0, 0}}, // (124, 171) + {128, { 0, 0, 0}}, // (125, 171) + {128, { 0, 0, 0}}, // (126, 171) + {128, { 0, 0, 0}}, // (127, 171) + {128, { 0, 0, 0}}, // (128, 171) + {128, { 0, 0, 0}}, // (129, 171) + {128, { 0, 0, 0}}, // (130, 171) + {128, { 0, 0, 0}}, // (131, 171) + {128, { 0, 0, 0}}, // (132, 171) + {128, { 0, 0, 0}}, // (133, 171) + {128, { 0, 0, 0}}, // (134, 171) + {128, { 0, 0, 0}}, // (135, 171) + {128, { 0, 0, 0}}, // (136, 171) + {128, { 0, 0, 0}}, // (137, 171) + {128, { 0, 0, 0}}, // (138, 171) + {128, { 0, 0, 0}}, // (139, 171) + {128, { 0, 0, 0}}, // (140, 171) + {128, { 0, 0, 0}}, // (141, 171) + {128, { 0, 0, 0}}, // (142, 171) + {128, { 0, 0, 0}}, // (143, 171) + {128, { 0, 0, 0}}, // (144, 171) + {128, { 0, 0, 0}}, // (145, 171) + {128, { 0, 0, 0}}, // (146, 171) + {128, { 0, 0, 0}}, // (147, 171) + {128, { 0, 0, 0}}, // (148, 171) + {128, { 0, 0, 0}}, // (149, 171) + {128, { 0, 0, 0}}, // (150, 171) + {128, { 0, 0, 0}}, // (151, 171) + {128, { 0, 0, 0}}, // (152, 171) + {128, { 0, 0, 0}}, // (153, 171) + {128, { 0, 0, 0}}, // (154, 171) + {128, { 0, 0, 0}}, // (155, 171) + {128, { 0, 0, 0}}, // (156, 171) + {128, { 0, 0, 0}}, // (157, 171) + {128, { 0, 0, 0}}, // (158, 171) + {128, { 0, 0, 0}}, // (159, 171) + {128, { 0, 0, 0}}, // (160, 171) + {128, { 0, 0, 0}}, // (161, 171) + {128, { 0, 0, 0}}, // (162, 171) + {128, { 0, 0, 0}}, // (163, 171) + {128, { 0, 0, 0}}, // (164, 171) + {128, { 0, 0, 0}}, // (165, 171) + {128, { 0, 0, 0}}, // (166, 171) + {128, { 0, 0, 0}}, // (167, 171) + {128, { 0, 0, 0}}, // (168, 171) + {128, { 0, 0, 0}}, // (169, 171) + {128, { 0, 0, 0}}, // (170, 171) + {128, { 0, 0, 0}}, // (171, 171) + {128, { 0, 0, 0}}, // (172, 171) + {128, { 0, 0, 0}}, // (173, 171) + {128, { 0, 0, 0}}, // (174, 171) + {128, { 0, 0, 0}}, // (175, 171) + {128, { 0, 0, 0}}, // (176, 171) + {128, { 0, 0, 0}}, // (177, 171) + {128, { 0, 0, 0}}, // (178, 171) + {128, { 0, 0, 0}}, // (179, 171) + {128, { 0, 0, 0}}, // ( 0, 172) + {128, { 0, 0, 0}}, // ( 1, 172) + {128, { 0, 0, 0}}, // ( 2, 172) + {128, { 0, 0, 0}}, // ( 3, 172) + {128, { 0, 0, 0}}, // ( 4, 172) + {128, { 0, 0, 0}}, // ( 5, 172) + {128, { 0, 0, 0}}, // ( 6, 172) + {128, { 0, 0, 0}}, // ( 7, 172) + {128, { 0, 0, 0}}, // ( 8, 172) + {128, { 0, 0, 0}}, // ( 9, 172) + {128, { 0, 0, 0}}, // ( 10, 172) + {128, { 0, 0, 0}}, // ( 11, 172) + {128, { 0, 0, 0}}, // ( 12, 172) + {128, { 0, 0, 0}}, // ( 13, 172) + {128, { 0, 0, 0}}, // ( 14, 172) + {128, { 0, 0, 0}}, // ( 15, 172) + {128, { 0, 0, 0}}, // ( 16, 172) + {128, { 0, 0, 0}}, // ( 17, 172) + {128, { 0, 0, 0}}, // ( 18, 172) + {128, { 0, 0, 0}}, // ( 19, 172) + {128, { 0, 0, 0}}, // ( 20, 172) + {128, { 0, 0, 0}}, // ( 21, 172) + {128, { 0, 0, 0}}, // ( 22, 172) + {128, { 0, 0, 0}}, // ( 23, 172) + {128, { 0, 0, 0}}, // ( 24, 172) + {128, { 0, 0, 0}}, // ( 25, 172) + {128, { 0, 0, 0}}, // ( 26, 172) + {128, { 0, 0, 0}}, // ( 27, 172) + {128, { 0, 0, 0}}, // ( 28, 172) + {128, { 0, 0, 0}}, // ( 29, 172) + {128, { 0, 0, 0}}, // ( 30, 172) + {128, { 0, 0, 0}}, // ( 31, 172) + {128, { 0, 0, 0}}, // ( 32, 172) + {128, { 0, 0, 0}}, // ( 33, 172) + {128, { 0, 0, 0}}, // ( 34, 172) + {128, { 0, 0, 0}}, // ( 35, 172) + {128, { 0, 0, 0}}, // ( 36, 172) + {128, { 0, 0, 0}}, // ( 37, 172) + {128, { 0, 0, 0}}, // ( 38, 172) + {128, { 0, 0, 0}}, // ( 39, 172) + {128, { 0, 0, 0}}, // ( 40, 172) + {128, { 0, 0, 0}}, // ( 41, 172) + {128, { 0, 0, 0}}, // ( 42, 172) + {128, { 0, 0, 0}}, // ( 43, 172) + {128, { 0, 0, 0}}, // ( 44, 172) + {128, { 0, 0, 0}}, // ( 45, 172) + {128, { 0, 0, 0}}, // ( 46, 172) + {128, { 0, 0, 0}}, // ( 47, 172) + {128, { 0, 0, 0}}, // ( 48, 172) + {128, { 0, 0, 0}}, // ( 49, 172) + {128, { 0, 0, 0}}, // ( 50, 172) + {128, { 0, 0, 0}}, // ( 51, 172) + {128, { 0, 0, 0}}, // ( 52, 172) + {128, { 0, 0, 0}}, // ( 53, 172) + {128, { 0, 0, 0}}, // ( 54, 172) + {128, { 0, 0, 0}}, // ( 55, 172) + {128, { 0, 0, 0}}, // ( 56, 172) + {128, { 0, 0, 0}}, // ( 57, 172) + {105, { 0, 0, 0}}, // ( 58, 172) + { 55, { 0, 0, 0}}, // ( 59, 172) + { 11, { 0, 0, 0}}, // ( 60, 172) + { 0, { 0, 0, 0}}, // ( 61, 172) + { 0, { 0, 0, 0}}, // ( 62, 172) + { 0, { 0, 0, 0}}, // ( 63, 172) + { 0, { 0, 0, 0}}, // ( 64, 172) + { 0, { 0, 0, 0}}, // ( 65, 172) + { 0, { 0, 0, 0}}, // ( 66, 172) + { 0, { 0, 0, 0}}, // ( 67, 172) + { 0, { 0, 0, 0}}, // ( 68, 172) + { 0, { 0, 0, 0}}, // ( 69, 172) + { 0, { 0, 0, 0}}, // ( 70, 172) + { 0, { 0, 0, 0}}, // ( 71, 172) + { 0, { 0, 0, 0}}, // ( 72, 172) + { 0, { 0, 0, 0}}, // ( 73, 172) + { 0, { 0, 0, 0}}, // ( 74, 172) + { 0, { 0, 0, 0}}, // ( 75, 172) + { 0, { 0, 0, 0}}, // ( 76, 172) + { 0, { 0, 0, 0}}, // ( 77, 172) + { 0, { 0, 0, 0}}, // ( 78, 172) + { 0, { 0, 0, 0}}, // ( 79, 172) + { 0, { 0, 0, 0}}, // ( 80, 172) + { 0, { 0, 0, 0}}, // ( 81, 172) + { 0, { 0, 0, 0}}, // ( 82, 172) + { 0, { 0, 0, 0}}, // ( 83, 172) + { 0, { 0, 0, 0}}, // ( 84, 172) + { 0, { 0, 0, 0}}, // ( 85, 172) + { 0, { 0, 0, 0}}, // ( 86, 172) + { 0, { 0, 0, 0}}, // ( 87, 172) + { 0, { 0, 0, 0}}, // ( 88, 172) + { 0, { 0, 0, 0}}, // ( 89, 172) + { 0, { 0, 0, 0}}, // ( 90, 172) + { 0, { 0, 0, 0}}, // ( 91, 172) + { 0, { 0, 0, 0}}, // ( 92, 172) + { 0, { 0, 0, 0}}, // ( 93, 172) + { 0, { 0, 0, 0}}, // ( 94, 172) + { 0, { 0, 0, 0}}, // ( 95, 172) + { 0, { 0, 0, 0}}, // ( 96, 172) + { 0, { 0, 0, 0}}, // ( 97, 172) + { 0, { 0, 0, 0}}, // ( 98, 172) + { 0, { 0, 0, 0}}, // ( 99, 172) + { 0, { 0, 0, 0}}, // (100, 172) + { 0, { 0, 0, 0}}, // (101, 172) + { 0, { 0, 0, 0}}, // (102, 172) + { 0, { 0, 0, 0}}, // (103, 172) + { 0, { 0, 0, 0}}, // (104, 172) + { 0, { 0, 0, 0}}, // (105, 172) + { 0, { 0, 0, 0}}, // (106, 172) + { 0, { 0, 0, 0}}, // (107, 172) + { 0, { 0, 0, 0}}, // (108, 172) + { 0, { 0, 0, 0}}, // (109, 172) + { 0, { 0, 0, 0}}, // (110, 172) + { 0, { 0, 0, 0}}, // (111, 172) + { 0, { 0, 0, 0}}, // (112, 172) + { 0, { 0, 0, 0}}, // (113, 172) + { 0, { 0, 0, 0}}, // (114, 172) + { 0, { 0, 0, 0}}, // (115, 172) + { 0, { 0, 0, 0}}, // (116, 172) + { 0, { 0, 0, 0}}, // (117, 172) + { 0, { 0, 0, 0}}, // (118, 172) + { 11, { 0, 0, 0}}, // (119, 172) + { 55, { 0, 0, 0}}, // (120, 172) + {105, { 0, 0, 0}}, // (121, 172) + {128, { 0, 0, 0}}, // (122, 172) + {128, { 0, 0, 0}}, // (123, 172) + {128, { 0, 0, 0}}, // (124, 172) + {128, { 0, 0, 0}}, // (125, 172) + {128, { 0, 0, 0}}, // (126, 172) + {128, { 0, 0, 0}}, // (127, 172) + {128, { 0, 0, 0}}, // (128, 172) + {128, { 0, 0, 0}}, // (129, 172) + {128, { 0, 0, 0}}, // (130, 172) + {128, { 0, 0, 0}}, // (131, 172) + {128, { 0, 0, 0}}, // (132, 172) + {128, { 0, 0, 0}}, // (133, 172) + {128, { 0, 0, 0}}, // (134, 172) + {128, { 0, 0, 0}}, // (135, 172) + {128, { 0, 0, 0}}, // (136, 172) + {128, { 0, 0, 0}}, // (137, 172) + {128, { 0, 0, 0}}, // (138, 172) + {128, { 0, 0, 0}}, // (139, 172) + {128, { 0, 0, 0}}, // (140, 172) + {128, { 0, 0, 0}}, // (141, 172) + {128, { 0, 0, 0}}, // (142, 172) + {128, { 0, 0, 0}}, // (143, 172) + {128, { 0, 0, 0}}, // (144, 172) + {128, { 0, 0, 0}}, // (145, 172) + {128, { 0, 0, 0}}, // (146, 172) + {128, { 0, 0, 0}}, // (147, 172) + {128, { 0, 0, 0}}, // (148, 172) + {128, { 0, 0, 0}}, // (149, 172) + {128, { 0, 0, 0}}, // (150, 172) + {128, { 0, 0, 0}}, // (151, 172) + {128, { 0, 0, 0}}, // (152, 172) + {128, { 0, 0, 0}}, // (153, 172) + {128, { 0, 0, 0}}, // (154, 172) + {128, { 0, 0, 0}}, // (155, 172) + {128, { 0, 0, 0}}, // (156, 172) + {128, { 0, 0, 0}}, // (157, 172) + {128, { 0, 0, 0}}, // (158, 172) + {128, { 0, 0, 0}}, // (159, 172) + {128, { 0, 0, 0}}, // (160, 172) + {128, { 0, 0, 0}}, // (161, 172) + {128, { 0, 0, 0}}, // (162, 172) + {128, { 0, 0, 0}}, // (163, 172) + {128, { 0, 0, 0}}, // (164, 172) + {128, { 0, 0, 0}}, // (165, 172) + {128, { 0, 0, 0}}, // (166, 172) + {128, { 0, 0, 0}}, // (167, 172) + {128, { 0, 0, 0}}, // (168, 172) + {128, { 0, 0, 0}}, // (169, 172) + {128, { 0, 0, 0}}, // (170, 172) + {128, { 0, 0, 0}}, // (171, 172) + {128, { 0, 0, 0}}, // (172, 172) + {128, { 0, 0, 0}}, // (173, 172) + {128, { 0, 0, 0}}, // (174, 172) + {128, { 0, 0, 0}}, // (175, 172) + {128, { 0, 0, 0}}, // (176, 172) + {128, { 0, 0, 0}}, // (177, 172) + {128, { 0, 0, 0}}, // (178, 172) + {128, { 0, 0, 0}}, // (179, 172) + {128, { 0, 0, 0}}, // ( 0, 173) + {128, { 0, 0, 0}}, // ( 1, 173) + {128, { 0, 0, 0}}, // ( 2, 173) + {128, { 0, 0, 0}}, // ( 3, 173) + {128, { 0, 0, 0}}, // ( 4, 173) + {128, { 0, 0, 0}}, // ( 5, 173) + {128, { 0, 0, 0}}, // ( 6, 173) + {128, { 0, 0, 0}}, // ( 7, 173) + {128, { 0, 0, 0}}, // ( 8, 173) + {128, { 0, 0, 0}}, // ( 9, 173) + {128, { 0, 0, 0}}, // ( 10, 173) + {128, { 0, 0, 0}}, // ( 11, 173) + {128, { 0, 0, 0}}, // ( 12, 173) + {128, { 0, 0, 0}}, // ( 13, 173) + {128, { 0, 0, 0}}, // ( 14, 173) + {128, { 0, 0, 0}}, // ( 15, 173) + {128, { 0, 0, 0}}, // ( 16, 173) + {128, { 0, 0, 0}}, // ( 17, 173) + {128, { 0, 0, 0}}, // ( 18, 173) + {128, { 0, 0, 0}}, // ( 19, 173) + {128, { 0, 0, 0}}, // ( 20, 173) + {128, { 0, 0, 0}}, // ( 21, 173) + {128, { 0, 0, 0}}, // ( 22, 173) + {128, { 0, 0, 0}}, // ( 23, 173) + {128, { 0, 0, 0}}, // ( 24, 173) + {128, { 0, 0, 0}}, // ( 25, 173) + {128, { 0, 0, 0}}, // ( 26, 173) + {128, { 0, 0, 0}}, // ( 27, 173) + {128, { 0, 0, 0}}, // ( 28, 173) + {128, { 0, 0, 0}}, // ( 29, 173) + {128, { 0, 0, 0}}, // ( 30, 173) + {128, { 0, 0, 0}}, // ( 31, 173) + {128, { 0, 0, 0}}, // ( 32, 173) + {128, { 0, 0, 0}}, // ( 33, 173) + {128, { 0, 0, 0}}, // ( 34, 173) + {128, { 0, 0, 0}}, // ( 35, 173) + {128, { 0, 0, 0}}, // ( 36, 173) + {128, { 0, 0, 0}}, // ( 37, 173) + {128, { 0, 0, 0}}, // ( 38, 173) + {128, { 0, 0, 0}}, // ( 39, 173) + {128, { 0, 0, 0}}, // ( 40, 173) + {128, { 0, 0, 0}}, // ( 41, 173) + {128, { 0, 0, 0}}, // ( 42, 173) + {128, { 0, 0, 0}}, // ( 43, 173) + {128, { 0, 0, 0}}, // ( 44, 173) + {128, { 0, 0, 0}}, // ( 45, 173) + {128, { 0, 0, 0}}, // ( 46, 173) + {128, { 0, 0, 0}}, // ( 47, 173) + {128, { 0, 0, 0}}, // ( 48, 173) + {128, { 0, 0, 0}}, // ( 49, 173) + {128, { 0, 0, 0}}, // ( 50, 173) + {128, { 0, 0, 0}}, // ( 51, 173) + {128, { 0, 0, 0}}, // ( 52, 173) + {128, { 0, 0, 0}}, // ( 53, 173) + {128, { 0, 0, 0}}, // ( 54, 173) + {128, { 0, 0, 0}}, // ( 55, 173) + {128, { 0, 0, 0}}, // ( 56, 173) + {128, { 0, 0, 0}}, // ( 57, 173) + {128, { 0, 0, 0}}, // ( 58, 173) + {128, { 0, 0, 0}}, // ( 59, 173) + {126, { 0, 0, 0}}, // ( 60, 173) + { 92, { 0, 0, 0}}, // ( 61, 173) + { 50, { 0, 0, 0}}, // ( 62, 173) + { 10, { 0, 0, 0}}, // ( 63, 173) + { 0, { 0, 0, 0}}, // ( 64, 173) + { 0, { 0, 0, 0}}, // ( 65, 173) + { 0, { 0, 0, 0}}, // ( 66, 173) + { 0, { 0, 0, 0}}, // ( 67, 173) + { 0, { 0, 0, 0}}, // ( 68, 173) + { 0, { 0, 0, 0}}, // ( 69, 173) + { 0, { 0, 0, 0}}, // ( 70, 173) + { 0, { 0, 0, 0}}, // ( 71, 173) + { 0, { 0, 0, 0}}, // ( 72, 173) + { 0, { 0, 0, 0}}, // ( 73, 173) + { 0, { 0, 0, 0}}, // ( 74, 173) + { 0, { 0, 0, 0}}, // ( 75, 173) + { 0, { 0, 0, 0}}, // ( 76, 173) + { 0, { 0, 0, 0}}, // ( 77, 173) + { 0, { 0, 0, 0}}, // ( 78, 173) + { 0, { 0, 0, 0}}, // ( 79, 173) + { 0, { 0, 0, 0}}, // ( 80, 173) + { 0, { 0, 0, 0}}, // ( 81, 173) + { 0, { 0, 0, 0}}, // ( 82, 173) + { 0, { 0, 0, 0}}, // ( 83, 173) + { 0, { 0, 0, 0}}, // ( 84, 173) + { 0, { 0, 0, 0}}, // ( 85, 173) + { 0, { 0, 0, 0}}, // ( 86, 173) + { 0, { 0, 0, 0}}, // ( 87, 173) + { 0, { 0, 0, 0}}, // ( 88, 173) + { 0, { 0, 0, 0}}, // ( 89, 173) + { 0, { 0, 0, 0}}, // ( 90, 173) + { 0, { 0, 0, 0}}, // ( 91, 173) + { 0, { 0, 0, 0}}, // ( 92, 173) + { 0, { 0, 0, 0}}, // ( 93, 173) + { 0, { 0, 0, 0}}, // ( 94, 173) + { 0, { 0, 0, 0}}, // ( 95, 173) + { 0, { 0, 0, 0}}, // ( 96, 173) + { 0, { 0, 0, 0}}, // ( 97, 173) + { 0, { 0, 0, 0}}, // ( 98, 173) + { 0, { 0, 0, 0}}, // ( 99, 173) + { 0, { 0, 0, 0}}, // (100, 173) + { 0, { 0, 0, 0}}, // (101, 173) + { 0, { 0, 0, 0}}, // (102, 173) + { 0, { 0, 0, 0}}, // (103, 173) + { 0, { 0, 0, 0}}, // (104, 173) + { 0, { 0, 0, 0}}, // (105, 173) + { 0, { 0, 0, 0}}, // (106, 173) + { 0, { 0, 0, 0}}, // (107, 173) + { 0, { 0, 0, 0}}, // (108, 173) + { 0, { 0, 0, 0}}, // (109, 173) + { 0, { 0, 0, 0}}, // (110, 173) + { 0, { 0, 0, 0}}, // (111, 173) + { 0, { 0, 0, 0}}, // (112, 173) + { 0, { 0, 0, 0}}, // (113, 173) + { 0, { 0, 0, 0}}, // (114, 173) + { 0, { 0, 0, 0}}, // (115, 173) + { 10, { 0, 0, 0}}, // (116, 173) + { 50, { 0, 0, 0}}, // (117, 173) + { 92, { 0, 0, 0}}, // (118, 173) + {126, { 0, 0, 0}}, // (119, 173) + {128, { 0, 0, 0}}, // (120, 173) + {128, { 0, 0, 0}}, // (121, 173) + {128, { 0, 0, 0}}, // (122, 173) + {128, { 0, 0, 0}}, // (123, 173) + {128, { 0, 0, 0}}, // (124, 173) + {128, { 0, 0, 0}}, // (125, 173) + {128, { 0, 0, 0}}, // (126, 173) + {128, { 0, 0, 0}}, // (127, 173) + {128, { 0, 0, 0}}, // (128, 173) + {128, { 0, 0, 0}}, // (129, 173) + {128, { 0, 0, 0}}, // (130, 173) + {128, { 0, 0, 0}}, // (131, 173) + {128, { 0, 0, 0}}, // (132, 173) + {128, { 0, 0, 0}}, // (133, 173) + {128, { 0, 0, 0}}, // (134, 173) + {128, { 0, 0, 0}}, // (135, 173) + {128, { 0, 0, 0}}, // (136, 173) + {128, { 0, 0, 0}}, // (137, 173) + {128, { 0, 0, 0}}, // (138, 173) + {128, { 0, 0, 0}}, // (139, 173) + {128, { 0, 0, 0}}, // (140, 173) + {128, { 0, 0, 0}}, // (141, 173) + {128, { 0, 0, 0}}, // (142, 173) + {128, { 0, 0, 0}}, // (143, 173) + {128, { 0, 0, 0}}, // (144, 173) + {128, { 0, 0, 0}}, // (145, 173) + {128, { 0, 0, 0}}, // (146, 173) + {128, { 0, 0, 0}}, // (147, 173) + {128, { 0, 0, 0}}, // (148, 173) + {128, { 0, 0, 0}}, // (149, 173) + {128, { 0, 0, 0}}, // (150, 173) + {128, { 0, 0, 0}}, // (151, 173) + {128, { 0, 0, 0}}, // (152, 173) + {128, { 0, 0, 0}}, // (153, 173) + {128, { 0, 0, 0}}, // (154, 173) + {128, { 0, 0, 0}}, // (155, 173) + {128, { 0, 0, 0}}, // (156, 173) + {128, { 0, 0, 0}}, // (157, 173) + {128, { 0, 0, 0}}, // (158, 173) + {128, { 0, 0, 0}}, // (159, 173) + {128, { 0, 0, 0}}, // (160, 173) + {128, { 0, 0, 0}}, // (161, 173) + {128, { 0, 0, 0}}, // (162, 173) + {128, { 0, 0, 0}}, // (163, 173) + {128, { 0, 0, 0}}, // (164, 173) + {128, { 0, 0, 0}}, // (165, 173) + {128, { 0, 0, 0}}, // (166, 173) + {128, { 0, 0, 0}}, // (167, 173) + {128, { 0, 0, 0}}, // (168, 173) + {128, { 0, 0, 0}}, // (169, 173) + {128, { 0, 0, 0}}, // (170, 173) + {128, { 0, 0, 0}}, // (171, 173) + {128, { 0, 0, 0}}, // (172, 173) + {128, { 0, 0, 0}}, // (173, 173) + {128, { 0, 0, 0}}, // (174, 173) + {128, { 0, 0, 0}}, // (175, 173) + {128, { 0, 0, 0}}, // (176, 173) + {128, { 0, 0, 0}}, // (177, 173) + {128, { 0, 0, 0}}, // (178, 173) + {128, { 0, 0, 0}}, // (179, 173) + {128, { 0, 0, 0}}, // ( 0, 174) + {128, { 0, 0, 0}}, // ( 1, 174) + {128, { 0, 0, 0}}, // ( 2, 174) + {128, { 0, 0, 0}}, // ( 3, 174) + {128, { 0, 0, 0}}, // ( 4, 174) + {128, { 0, 0, 0}}, // ( 5, 174) + {128, { 0, 0, 0}}, // ( 6, 174) + {128, { 0, 0, 0}}, // ( 7, 174) + {128, { 0, 0, 0}}, // ( 8, 174) + {128, { 0, 0, 0}}, // ( 9, 174) + {128, { 0, 0, 0}}, // ( 10, 174) + {128, { 0, 0, 0}}, // ( 11, 174) + {128, { 0, 0, 0}}, // ( 12, 174) + {128, { 0, 0, 0}}, // ( 13, 174) + {128, { 0, 0, 0}}, // ( 14, 174) + {128, { 0, 0, 0}}, // ( 15, 174) + {128, { 0, 0, 0}}, // ( 16, 174) + {128, { 0, 0, 0}}, // ( 17, 174) + {128, { 0, 0, 0}}, // ( 18, 174) + {128, { 0, 0, 0}}, // ( 19, 174) + {128, { 0, 0, 0}}, // ( 20, 174) + {128, { 0, 0, 0}}, // ( 21, 174) + {128, { 0, 0, 0}}, // ( 22, 174) + {128, { 0, 0, 0}}, // ( 23, 174) + {128, { 0, 0, 0}}, // ( 24, 174) + {128, { 0, 0, 0}}, // ( 25, 174) + {128, { 0, 0, 0}}, // ( 26, 174) + {128, { 0, 0, 0}}, // ( 27, 174) + {128, { 0, 0, 0}}, // ( 28, 174) + {128, { 0, 0, 0}}, // ( 29, 174) + {128, { 0, 0, 0}}, // ( 30, 174) + {128, { 0, 0, 0}}, // ( 31, 174) + {128, { 0, 0, 0}}, // ( 32, 174) + {128, { 0, 0, 0}}, // ( 33, 174) + {128, { 0, 0, 0}}, // ( 34, 174) + {128, { 0, 0, 0}}, // ( 35, 174) + {128, { 0, 0, 0}}, // ( 36, 174) + {128, { 0, 0, 0}}, // ( 37, 174) + {128, { 0, 0, 0}}, // ( 38, 174) + {128, { 0, 0, 0}}, // ( 39, 174) + {128, { 0, 0, 0}}, // ( 40, 174) + {128, { 0, 0, 0}}, // ( 41, 174) + {128, { 0, 0, 0}}, // ( 42, 174) + {128, { 0, 0, 0}}, // ( 43, 174) + {128, { 0, 0, 0}}, // ( 44, 174) + {128, { 0, 0, 0}}, // ( 45, 174) + {128, { 0, 0, 0}}, // ( 46, 174) + {128, { 0, 0, 0}}, // ( 47, 174) + {128, { 0, 0, 0}}, // ( 48, 174) + {128, { 0, 0, 0}}, // ( 49, 174) + {128, { 0, 0, 0}}, // ( 50, 174) + {128, { 0, 0, 0}}, // ( 51, 174) + {128, { 0, 0, 0}}, // ( 52, 174) + {128, { 0, 0, 0}}, // ( 53, 174) + {128, { 0, 0, 0}}, // ( 54, 174) + {128, { 0, 0, 0}}, // ( 55, 174) + {128, { 0, 0, 0}}, // ( 56, 174) + {128, { 0, 0, 0}}, // ( 57, 174) + {128, { 0, 0, 0}}, // ( 58, 174) + {128, { 0, 0, 0}}, // ( 59, 174) + {128, { 0, 0, 0}}, // ( 60, 174) + {128, { 0, 0, 0}}, // ( 61, 174) + {128, { 0, 0, 0}}, // ( 62, 174) + {126, { 0, 0, 0}}, // ( 63, 174) + { 97, { 0, 0, 0}}, // ( 64, 174) + { 59, { 0, 0, 0}}, // ( 65, 174) + { 23, { 0, 0, 0}}, // ( 66, 174) + { 0, { 0, 0, 0}}, // ( 67, 174) + { 0, { 0, 0, 0}}, // ( 68, 174) + { 0, { 0, 0, 0}}, // ( 69, 174) + { 0, { 0, 0, 0}}, // ( 70, 174) + { 0, { 0, 0, 0}}, // ( 71, 174) + { 0, { 0, 0, 0}}, // ( 72, 174) + { 0, { 0, 0, 0}}, // ( 73, 174) + { 0, { 0, 0, 0}}, // ( 74, 174) + { 0, { 0, 0, 0}}, // ( 75, 174) + { 0, { 0, 0, 0}}, // ( 76, 174) + { 0, { 0, 0, 0}}, // ( 77, 174) + { 0, { 0, 0, 0}}, // ( 78, 174) + { 0, { 0, 0, 0}}, // ( 79, 174) + { 0, { 0, 0, 0}}, // ( 80, 174) + { 0, { 0, 0, 0}}, // ( 81, 174) + { 0, { 0, 0, 0}}, // ( 82, 174) + { 0, { 0, 0, 0}}, // ( 83, 174) + { 0, { 0, 0, 0}}, // ( 84, 174) + { 0, { 0, 0, 0}}, // ( 85, 174) + { 0, { 0, 0, 0}}, // ( 86, 174) + { 0, { 0, 0, 0}}, // ( 87, 174) + { 0, { 0, 0, 0}}, // ( 88, 174) + { 0, { 0, 0, 0}}, // ( 89, 174) + { 0, { 0, 0, 0}}, // ( 90, 174) + { 0, { 0, 0, 0}}, // ( 91, 174) + { 0, { 0, 0, 0}}, // ( 92, 174) + { 0, { 0, 0, 0}}, // ( 93, 174) + { 0, { 0, 0, 0}}, // ( 94, 174) + { 0, { 0, 0, 0}}, // ( 95, 174) + { 0, { 0, 0, 0}}, // ( 96, 174) + { 0, { 0, 0, 0}}, // ( 97, 174) + { 0, { 0, 0, 0}}, // ( 98, 174) + { 0, { 0, 0, 0}}, // ( 99, 174) + { 0, { 0, 0, 0}}, // (100, 174) + { 0, { 0, 0, 0}}, // (101, 174) + { 0, { 0, 0, 0}}, // (102, 174) + { 0, { 0, 0, 0}}, // (103, 174) + { 0, { 0, 0, 0}}, // (104, 174) + { 0, { 0, 0, 0}}, // (105, 174) + { 0, { 0, 0, 0}}, // (106, 174) + { 0, { 0, 0, 0}}, // (107, 174) + { 0, { 0, 0, 0}}, // (108, 174) + { 0, { 0, 0, 0}}, // (109, 174) + { 0, { 0, 0, 0}}, // (110, 174) + { 0, { 0, 0, 0}}, // (111, 174) + { 0, { 0, 0, 0}}, // (112, 174) + { 23, { 0, 0, 0}}, // (113, 174) + { 59, { 0, 0, 0}}, // (114, 174) + { 96, { 0, 0, 0}}, // (115, 174) + {126, { 0, 0, 0}}, // (116, 174) + {128, { 0, 0, 0}}, // (117, 174) + {128, { 0, 0, 0}}, // (118, 174) + {128, { 0, 0, 0}}, // (119, 174) + {128, { 0, 0, 0}}, // (120, 174) + {128, { 0, 0, 0}}, // (121, 174) + {128, { 0, 0, 0}}, // (122, 174) + {128, { 0, 0, 0}}, // (123, 174) + {128, { 0, 0, 0}}, // (124, 174) + {128, { 0, 0, 0}}, // (125, 174) + {128, { 0, 0, 0}}, // (126, 174) + {128, { 0, 0, 0}}, // (127, 174) + {128, { 0, 0, 0}}, // (128, 174) + {128, { 0, 0, 0}}, // (129, 174) + {128, { 0, 0, 0}}, // (130, 174) + {128, { 0, 0, 0}}, // (131, 174) + {128, { 0, 0, 0}}, // (132, 174) + {128, { 0, 0, 0}}, // (133, 174) + {128, { 0, 0, 0}}, // (134, 174) + {128, { 0, 0, 0}}, // (135, 174) + {128, { 0, 0, 0}}, // (136, 174) + {128, { 0, 0, 0}}, // (137, 174) + {128, { 0, 0, 0}}, // (138, 174) + {128, { 0, 0, 0}}, // (139, 174) + {128, { 0, 0, 0}}, // (140, 174) + {128, { 0, 0, 0}}, // (141, 174) + {128, { 0, 0, 0}}, // (142, 174) + {128, { 0, 0, 0}}, // (143, 174) + {128, { 0, 0, 0}}, // (144, 174) + {128, { 0, 0, 0}}, // (145, 174) + {128, { 0, 0, 0}}, // (146, 174) + {128, { 0, 0, 0}}, // (147, 174) + {128, { 0, 0, 0}}, // (148, 174) + {128, { 0, 0, 0}}, // (149, 174) + {128, { 0, 0, 0}}, // (150, 174) + {128, { 0, 0, 0}}, // (151, 174) + {128, { 0, 0, 0}}, // (152, 174) + {128, { 0, 0, 0}}, // (153, 174) + {128, { 0, 0, 0}}, // (154, 174) + {128, { 0, 0, 0}}, // (155, 174) + {128, { 0, 0, 0}}, // (156, 174) + {128, { 0, 0, 0}}, // (157, 174) + {128, { 0, 0, 0}}, // (158, 174) + {128, { 0, 0, 0}}, // (159, 174) + {128, { 0, 0, 0}}, // (160, 174) + {128, { 0, 0, 0}}, // (161, 174) + {128, { 0, 0, 0}}, // (162, 174) + {128, { 0, 0, 0}}, // (163, 174) + {128, { 0, 0, 0}}, // (164, 174) + {128, { 0, 0, 0}}, // (165, 174) + {128, { 0, 0, 0}}, // (166, 174) + {128, { 0, 0, 0}}, // (167, 174) + {128, { 0, 0, 0}}, // (168, 174) + {128, { 0, 0, 0}}, // (169, 174) + {128, { 0, 0, 0}}, // (170, 174) + {128, { 0, 0, 0}}, // (171, 174) + {128, { 0, 0, 0}}, // (172, 174) + {128, { 0, 0, 0}}, // (173, 174) + {128, { 0, 0, 0}}, // (174, 174) + {128, { 0, 0, 0}}, // (175, 174) + {128, { 0, 0, 0}}, // (176, 174) + {128, { 0, 0, 0}}, // (177, 174) + {128, { 0, 0, 0}}, // (178, 174) + {128, { 0, 0, 0}}, // (179, 174) + {128, { 0, 0, 0}}, // ( 0, 175) + {128, { 0, 0, 0}}, // ( 1, 175) + {128, { 0, 0, 0}}, // ( 2, 175) + {128, { 0, 0, 0}}, // ( 3, 175) + {128, { 0, 0, 0}}, // ( 4, 175) + {128, { 0, 0, 0}}, // ( 5, 175) + {128, { 0, 0, 0}}, // ( 6, 175) + {128, { 0, 0, 0}}, // ( 7, 175) + {128, { 0, 0, 0}}, // ( 8, 175) + {128, { 0, 0, 0}}, // ( 9, 175) + {128, { 0, 0, 0}}, // ( 10, 175) + {128, { 0, 0, 0}}, // ( 11, 175) + {128, { 0, 0, 0}}, // ( 12, 175) + {128, { 0, 0, 0}}, // ( 13, 175) + {128, { 0, 0, 0}}, // ( 14, 175) + {128, { 0, 0, 0}}, // ( 15, 175) + {128, { 0, 0, 0}}, // ( 16, 175) + {128, { 0, 0, 0}}, // ( 17, 175) + {128, { 0, 0, 0}}, // ( 18, 175) + {128, { 0, 0, 0}}, // ( 19, 175) + {128, { 0, 0, 0}}, // ( 20, 175) + {128, { 0, 0, 0}}, // ( 21, 175) + {128, { 0, 0, 0}}, // ( 22, 175) + {128, { 0, 0, 0}}, // ( 23, 175) + {128, { 0, 0, 0}}, // ( 24, 175) + {128, { 0, 0, 0}}, // ( 25, 175) + {128, { 0, 0, 0}}, // ( 26, 175) + {128, { 0, 0, 0}}, // ( 27, 175) + {128, { 0, 0, 0}}, // ( 28, 175) + {128, { 0, 0, 0}}, // ( 29, 175) + {128, { 0, 0, 0}}, // ( 30, 175) + {128, { 0, 0, 0}}, // ( 31, 175) + {128, { 0, 0, 0}}, // ( 32, 175) + {128, { 0, 0, 0}}, // ( 33, 175) + {128, { 0, 0, 0}}, // ( 34, 175) + {128, { 0, 0, 0}}, // ( 35, 175) + {128, { 0, 0, 0}}, // ( 36, 175) + {128, { 0, 0, 0}}, // ( 37, 175) + {128, { 0, 0, 0}}, // ( 38, 175) + {128, { 0, 0, 0}}, // ( 39, 175) + {128, { 0, 0, 0}}, // ( 40, 175) + {128, { 0, 0, 0}}, // ( 41, 175) + {128, { 0, 0, 0}}, // ( 42, 175) + {128, { 0, 0, 0}}, // ( 43, 175) + {128, { 0, 0, 0}}, // ( 44, 175) + {128, { 0, 0, 0}}, // ( 45, 175) + {128, { 0, 0, 0}}, // ( 46, 175) + {128, { 0, 0, 0}}, // ( 47, 175) + {128, { 0, 0, 0}}, // ( 48, 175) + {128, { 0, 0, 0}}, // ( 49, 175) + {128, { 0, 0, 0}}, // ( 50, 175) + {128, { 0, 0, 0}}, // ( 51, 175) + {128, { 0, 0, 0}}, // ( 52, 175) + {128, { 0, 0, 0}}, // ( 53, 175) + {128, { 0, 0, 0}}, // ( 54, 175) + {128, { 0, 0, 0}}, // ( 55, 175) + {128, { 0, 0, 0}}, // ( 56, 175) + {128, { 0, 0, 0}}, // ( 57, 175) + {128, { 0, 0, 0}}, // ( 58, 175) + {128, { 0, 0, 0}}, // ( 59, 175) + {128, { 0, 0, 0}}, // ( 60, 175) + {128, { 0, 0, 0}}, // ( 61, 175) + {128, { 0, 0, 0}}, // ( 62, 175) + {128, { 0, 0, 0}}, // ( 63, 175) + {128, { 0, 0, 0}}, // ( 64, 175) + {128, { 0, 0, 0}}, // ( 65, 175) + {128, { 0, 0, 0}}, // ( 66, 175) + {116, { 0, 0, 0}}, // ( 67, 175) + { 83, { 0, 0, 0}}, // ( 68, 175) + { 55, { 0, 0, 0}}, // ( 69, 175) + { 25, { 0, 0, 0}}, // ( 70, 175) + { 2, { 0, 0, 0}}, // ( 71, 175) + { 0, { 0, 0, 0}}, // ( 72, 175) + { 0, { 0, 0, 0}}, // ( 73, 175) + { 0, { 0, 0, 0}}, // ( 74, 175) + { 0, { 0, 0, 0}}, // ( 75, 175) + { 0, { 0, 0, 0}}, // ( 76, 175) + { 0, { 0, 0, 0}}, // ( 77, 175) + { 0, { 0, 0, 0}}, // ( 78, 175) + { 0, { 0, 0, 0}}, // ( 79, 175) + { 0, { 0, 0, 0}}, // ( 80, 175) + { 0, { 0, 0, 0}}, // ( 81, 175) + { 0, { 0, 0, 0}}, // ( 82, 175) + { 0, { 0, 0, 0}}, // ( 83, 175) + { 0, { 0, 0, 0}}, // ( 84, 175) + { 0, { 0, 0, 0}}, // ( 85, 175) + { 0, { 0, 0, 0}}, // ( 86, 175) + { 0, { 0, 0, 0}}, // ( 87, 175) + { 0, { 0, 0, 0}}, // ( 88, 175) + { 0, { 0, 0, 0}}, // ( 89, 175) + { 0, { 0, 0, 0}}, // ( 90, 175) + { 0, { 0, 0, 0}}, // ( 91, 175) + { 0, { 0, 0, 0}}, // ( 92, 175) + { 0, { 0, 0, 0}}, // ( 93, 175) + { 0, { 0, 0, 0}}, // ( 94, 175) + { 0, { 0, 0, 0}}, // ( 95, 175) + { 0, { 0, 0, 0}}, // ( 96, 175) + { 0, { 0, 0, 0}}, // ( 97, 175) + { 0, { 0, 0, 0}}, // ( 98, 175) + { 0, { 0, 0, 0}}, // ( 99, 175) + { 0, { 0, 0, 0}}, // (100, 175) + { 0, { 0, 0, 0}}, // (101, 175) + { 0, { 0, 0, 0}}, // (102, 175) + { 0, { 0, 0, 0}}, // (103, 175) + { 0, { 0, 0, 0}}, // (104, 175) + { 0, { 0, 0, 0}}, // (105, 175) + { 0, { 0, 0, 0}}, // (106, 175) + { 0, { 0, 0, 0}}, // (107, 175) + { 2, { 0, 0, 0}}, // (108, 175) + { 25, { 0, 0, 0}}, // (109, 175) + { 55, { 0, 0, 0}}, // (110, 175) + { 83, { 0, 0, 0}}, // (111, 175) + {116, { 0, 0, 0}}, // (112, 175) + {128, { 0, 0, 0}}, // (113, 175) + {128, { 0, 0, 0}}, // (114, 175) + {128, { 0, 0, 0}}, // (115, 175) + {128, { 0, 0, 0}}, // (116, 175) + {128, { 0, 0, 0}}, // (117, 175) + {128, { 0, 0, 0}}, // (118, 175) + {128, { 0, 0, 0}}, // (119, 175) + {128, { 0, 0, 0}}, // (120, 175) + {128, { 0, 0, 0}}, // (121, 175) + {128, { 0, 0, 0}}, // (122, 175) + {128, { 0, 0, 0}}, // (123, 175) + {128, { 0, 0, 0}}, // (124, 175) + {128, { 0, 0, 0}}, // (125, 175) + {128, { 0, 0, 0}}, // (126, 175) + {128, { 0, 0, 0}}, // (127, 175) + {128, { 0, 0, 0}}, // (128, 175) + {128, { 0, 0, 0}}, // (129, 175) + {128, { 0, 0, 0}}, // (130, 175) + {128, { 0, 0, 0}}, // (131, 175) + {128, { 0, 0, 0}}, // (132, 175) + {128, { 0, 0, 0}}, // (133, 175) + {128, { 0, 0, 0}}, // (134, 175) + {128, { 0, 0, 0}}, // (135, 175) + {128, { 0, 0, 0}}, // (136, 175) + {128, { 0, 0, 0}}, // (137, 175) + {128, { 0, 0, 0}}, // (138, 175) + {128, { 0, 0, 0}}, // (139, 175) + {128, { 0, 0, 0}}, // (140, 175) + {128, { 0, 0, 0}}, // (141, 175) + {128, { 0, 0, 0}}, // (142, 175) + {128, { 0, 0, 0}}, // (143, 175) + {128, { 0, 0, 0}}, // (144, 175) + {128, { 0, 0, 0}}, // (145, 175) + {128, { 0, 0, 0}}, // (146, 175) + {128, { 0, 0, 0}}, // (147, 175) + {128, { 0, 0, 0}}, // (148, 175) + {128, { 0, 0, 0}}, // (149, 175) + {128, { 0, 0, 0}}, // (150, 175) + {128, { 0, 0, 0}}, // (151, 175) + {128, { 0, 0, 0}}, // (152, 175) + {128, { 0, 0, 0}}, // (153, 175) + {128, { 0, 0, 0}}, // (154, 175) + {128, { 0, 0, 0}}, // (155, 175) + {128, { 0, 0, 0}}, // (156, 175) + {128, { 0, 0, 0}}, // (157, 175) + {128, { 0, 0, 0}}, // (158, 175) + {128, { 0, 0, 0}}, // (159, 175) + {128, { 0, 0, 0}}, // (160, 175) + {128, { 0, 0, 0}}, // (161, 175) + {128, { 0, 0, 0}}, // (162, 175) + {128, { 0, 0, 0}}, // (163, 175) + {128, { 0, 0, 0}}, // (164, 175) + {128, { 0, 0, 0}}, // (165, 175) + {128, { 0, 0, 0}}, // (166, 175) + {128, { 0, 0, 0}}, // (167, 175) + {128, { 0, 0, 0}}, // (168, 175) + {128, { 0, 0, 0}}, // (169, 175) + {128, { 0, 0, 0}}, // (170, 175) + {128, { 0, 0, 0}}, // (171, 175) + {128, { 0, 0, 0}}, // (172, 175) + {128, { 0, 0, 0}}, // (173, 175) + {128, { 0, 0, 0}}, // (174, 175) + {128, { 0, 0, 0}}, // (175, 175) + {128, { 0, 0, 0}}, // (176, 175) + {128, { 0, 0, 0}}, // (177, 175) + {128, { 0, 0, 0}}, // (178, 175) + {128, { 0, 0, 0}}, // (179, 175) + {128, { 0, 0, 0}}, // ( 0, 176) + {128, { 0, 0, 0}}, // ( 1, 176) + {128, { 0, 0, 0}}, // ( 2, 176) + {128, { 0, 0, 0}}, // ( 3, 176) + {128, { 0, 0, 0}}, // ( 4, 176) + {128, { 0, 0, 0}}, // ( 5, 176) + {128, { 0, 0, 0}}, // ( 6, 176) + {128, { 0, 0, 0}}, // ( 7, 176) + {128, { 0, 0, 0}}, // ( 8, 176) + {128, { 0, 0, 0}}, // ( 9, 176) + {128, { 0, 0, 0}}, // ( 10, 176) + {128, { 0, 0, 0}}, // ( 11, 176) + {128, { 0, 0, 0}}, // ( 12, 176) + {128, { 0, 0, 0}}, // ( 13, 176) + {128, { 0, 0, 0}}, // ( 14, 176) + {128, { 0, 0, 0}}, // ( 15, 176) + {128, { 0, 0, 0}}, // ( 16, 176) + {128, { 0, 0, 0}}, // ( 17, 176) + {128, { 0, 0, 0}}, // ( 18, 176) + {128, { 0, 0, 0}}, // ( 19, 176) + {128, { 0, 0, 0}}, // ( 20, 176) + {128, { 0, 0, 0}}, // ( 21, 176) + {128, { 0, 0, 0}}, // ( 22, 176) + {128, { 0, 0, 0}}, // ( 23, 176) + {128, { 0, 0, 0}}, // ( 24, 176) + {128, { 0, 0, 0}}, // ( 25, 176) + {128, { 0, 0, 0}}, // ( 26, 176) + {128, { 0, 0, 0}}, // ( 27, 176) + {128, { 0, 0, 0}}, // ( 28, 176) + {128, { 0, 0, 0}}, // ( 29, 176) + {128, { 0, 0, 0}}, // ( 30, 176) + {128, { 0, 0, 0}}, // ( 31, 176) + {128, { 0, 0, 0}}, // ( 32, 176) + {128, { 0, 0, 0}}, // ( 33, 176) + {128, { 0, 0, 0}}, // ( 34, 176) + {128, { 0, 0, 0}}, // ( 35, 176) + {128, { 0, 0, 0}}, // ( 36, 176) + {128, { 0, 0, 0}}, // ( 37, 176) + {128, { 0, 0, 0}}, // ( 38, 176) + {128, { 0, 0, 0}}, // ( 39, 176) + {128, { 0, 0, 0}}, // ( 40, 176) + {128, { 0, 0, 0}}, // ( 41, 176) + {128, { 0, 0, 0}}, // ( 42, 176) + {128, { 0, 0, 0}}, // ( 43, 176) + {128, { 0, 0, 0}}, // ( 44, 176) + {128, { 0, 0, 0}}, // ( 45, 176) + {128, { 0, 0, 0}}, // ( 46, 176) + {128, { 0, 0, 0}}, // ( 47, 176) + {128, { 0, 0, 0}}, // ( 48, 176) + {128, { 0, 0, 0}}, // ( 49, 176) + {128, { 0, 0, 0}}, // ( 50, 176) + {128, { 0, 0, 0}}, // ( 51, 176) + {128, { 0, 0, 0}}, // ( 52, 176) + {128, { 0, 0, 0}}, // ( 53, 176) + {128, { 0, 0, 0}}, // ( 54, 176) + {128, { 0, 0, 0}}, // ( 55, 176) + {128, { 0, 0, 0}}, // ( 56, 176) + {128, { 0, 0, 0}}, // ( 57, 176) + {128, { 0, 0, 0}}, // ( 58, 176) + {128, { 0, 0, 0}}, // ( 59, 176) + {128, { 0, 0, 0}}, // ( 60, 176) + {128, { 0, 0, 0}}, // ( 61, 176) + {128, { 0, 0, 0}}, // ( 62, 176) + {128, { 0, 0, 0}}, // ( 63, 176) + {128, { 0, 0, 0}}, // ( 64, 176) + {128, { 0, 0, 0}}, // ( 65, 176) + {128, { 0, 0, 0}}, // ( 66, 176) + {128, { 0, 0, 0}}, // ( 67, 176) + {128, { 0, 0, 0}}, // ( 68, 176) + {128, { 0, 0, 0}}, // ( 69, 176) + {128, { 0, 0, 0}}, // ( 70, 176) + {121, { 0, 0, 0}}, // ( 71, 176) + { 95, { 0, 0, 0}}, // ( 72, 176) + { 72, { 0, 0, 0}}, // ( 73, 176) + { 50, { 0, 0, 0}}, // ( 74, 176) + { 26, { 0, 0, 0}}, // ( 75, 176) + { 5, { 0, 0, 0}}, // ( 76, 176) + { 0, { 0, 0, 0}}, // ( 77, 176) + { 0, { 0, 0, 0}}, // ( 78, 176) + { 0, { 0, 0, 0}}, // ( 79, 176) + { 0, { 0, 0, 0}}, // ( 80, 176) + { 0, { 0, 0, 0}}, // ( 81, 176) + { 0, { 0, 0, 0}}, // ( 82, 176) + { 0, { 0, 0, 0}}, // ( 83, 176) + { 0, { 0, 0, 0}}, // ( 84, 176) + { 0, { 0, 0, 0}}, // ( 85, 176) + { 0, { 0, 0, 0}}, // ( 86, 176) + { 0, { 0, 0, 0}}, // ( 87, 176) + { 0, { 0, 0, 0}}, // ( 88, 176) + { 0, { 0, 0, 0}}, // ( 89, 176) + { 0, { 0, 0, 0}}, // ( 90, 176) + { 0, { 0, 0, 0}}, // ( 91, 176) + { 0, { 0, 0, 0}}, // ( 92, 176) + { 0, { 0, 0, 0}}, // ( 93, 176) + { 0, { 0, 0, 0}}, // ( 94, 176) + { 0, { 0, 0, 0}}, // ( 95, 176) + { 0, { 0, 0, 0}}, // ( 96, 176) + { 0, { 0, 0, 0}}, // ( 97, 176) + { 0, { 0, 0, 0}}, // ( 98, 176) + { 0, { 0, 0, 0}}, // ( 99, 176) + { 0, { 0, 0, 0}}, // (100, 176) + { 0, { 0, 0, 0}}, // (101, 176) + { 0, { 0, 0, 0}}, // (102, 176) + { 5, { 0, 0, 0}}, // (103, 176) + { 26, { 0, 0, 0}}, // (104, 176) + { 50, { 0, 0, 0}}, // (105, 176) + { 72, { 0, 0, 0}}, // (106, 176) + { 95, { 0, 0, 0}}, // (107, 176) + {121, { 0, 0, 0}}, // (108, 176) + {128, { 0, 0, 0}}, // (109, 176) + {128, { 0, 0, 0}}, // (110, 176) + {128, { 0, 0, 0}}, // (111, 176) + {128, { 0, 0, 0}}, // (112, 176) + {128, { 0, 0, 0}}, // (113, 176) + {128, { 0, 0, 0}}, // (114, 176) + {128, { 0, 0, 0}}, // (115, 176) + {128, { 0, 0, 0}}, // (116, 176) + {128, { 0, 0, 0}}, // (117, 176) + {128, { 0, 0, 0}}, // (118, 176) + {128, { 0, 0, 0}}, // (119, 176) + {128, { 0, 0, 0}}, // (120, 176) + {128, { 0, 0, 0}}, // (121, 176) + {128, { 0, 0, 0}}, // (122, 176) + {128, { 0, 0, 0}}, // (123, 176) + {128, { 0, 0, 0}}, // (124, 176) + {128, { 0, 0, 0}}, // (125, 176) + {128, { 0, 0, 0}}, // (126, 176) + {128, { 0, 0, 0}}, // (127, 176) + {128, { 0, 0, 0}}, // (128, 176) + {128, { 0, 0, 0}}, // (129, 176) + {128, { 0, 0, 0}}, // (130, 176) + {128, { 0, 0, 0}}, // (131, 176) + {128, { 0, 0, 0}}, // (132, 176) + {128, { 0, 0, 0}}, // (133, 176) + {128, { 0, 0, 0}}, // (134, 176) + {128, { 0, 0, 0}}, // (135, 176) + {128, { 0, 0, 0}}, // (136, 176) + {128, { 0, 0, 0}}, // (137, 176) + {128, { 0, 0, 0}}, // (138, 176) + {128, { 0, 0, 0}}, // (139, 176) + {128, { 0, 0, 0}}, // (140, 176) + {128, { 0, 0, 0}}, // (141, 176) + {128, { 0, 0, 0}}, // (142, 176) + {128, { 0, 0, 0}}, // (143, 176) + {128, { 0, 0, 0}}, // (144, 176) + {128, { 0, 0, 0}}, // (145, 176) + {128, { 0, 0, 0}}, // (146, 176) + {128, { 0, 0, 0}}, // (147, 176) + {128, { 0, 0, 0}}, // (148, 176) + {128, { 0, 0, 0}}, // (149, 176) + {128, { 0, 0, 0}}, // (150, 176) + {128, { 0, 0, 0}}, // (151, 176) + {128, { 0, 0, 0}}, // (152, 176) + {128, { 0, 0, 0}}, // (153, 176) + {128, { 0, 0, 0}}, // (154, 176) + {128, { 0, 0, 0}}, // (155, 176) + {128, { 0, 0, 0}}, // (156, 176) + {128, { 0, 0, 0}}, // (157, 176) + {128, { 0, 0, 0}}, // (158, 176) + {128, { 0, 0, 0}}, // (159, 176) + {128, { 0, 0, 0}}, // (160, 176) + {128, { 0, 0, 0}}, // (161, 176) + {128, { 0, 0, 0}}, // (162, 176) + {128, { 0, 0, 0}}, // (163, 176) + {128, { 0, 0, 0}}, // (164, 176) + {128, { 0, 0, 0}}, // (165, 176) + {128, { 0, 0, 0}}, // (166, 176) + {128, { 0, 0, 0}}, // (167, 176) + {128, { 0, 0, 0}}, // (168, 176) + {128, { 0, 0, 0}}, // (169, 176) + {128, { 0, 0, 0}}, // (170, 176) + {128, { 0, 0, 0}}, // (171, 176) + {128, { 0, 0, 0}}, // (172, 176) + {128, { 0, 0, 0}}, // (173, 176) + {128, { 0, 0, 0}}, // (174, 176) + {128, { 0, 0, 0}}, // (175, 176) + {128, { 0, 0, 0}}, // (176, 176) + {128, { 0, 0, 0}}, // (177, 176) + {128, { 0, 0, 0}}, // (178, 176) + {128, { 0, 0, 0}}, // (179, 176) + {128, { 0, 0, 0}}, // ( 0, 177) + {128, { 0, 0, 0}}, // ( 1, 177) + {128, { 0, 0, 0}}, // ( 2, 177) + {128, { 0, 0, 0}}, // ( 3, 177) + {128, { 0, 0, 0}}, // ( 4, 177) + {128, { 0, 0, 0}}, // ( 5, 177) + {128, { 0, 0, 0}}, // ( 6, 177) + {128, { 0, 0, 0}}, // ( 7, 177) + {128, { 0, 0, 0}}, // ( 8, 177) + {128, { 0, 0, 0}}, // ( 9, 177) + {128, { 0, 0, 0}}, // ( 10, 177) + {128, { 0, 0, 0}}, // ( 11, 177) + {128, { 0, 0, 0}}, // ( 12, 177) + {128, { 0, 0, 0}}, // ( 13, 177) + {128, { 0, 0, 0}}, // ( 14, 177) + {128, { 0, 0, 0}}, // ( 15, 177) + {128, { 0, 0, 0}}, // ( 16, 177) + {128, { 0, 0, 0}}, // ( 17, 177) + {128, { 0, 0, 0}}, // ( 18, 177) + {128, { 0, 0, 0}}, // ( 19, 177) + {128, { 0, 0, 0}}, // ( 20, 177) + {128, { 0, 0, 0}}, // ( 21, 177) + {128, { 0, 0, 0}}, // ( 22, 177) + {128, { 0, 0, 0}}, // ( 23, 177) + {128, { 0, 0, 0}}, // ( 24, 177) + {128, { 0, 0, 0}}, // ( 25, 177) + {128, { 0, 0, 0}}, // ( 26, 177) + {128, { 0, 0, 0}}, // ( 27, 177) + {128, { 0, 0, 0}}, // ( 28, 177) + {128, { 0, 0, 0}}, // ( 29, 177) + {128, { 0, 0, 0}}, // ( 30, 177) + {128, { 0, 0, 0}}, // ( 31, 177) + {128, { 0, 0, 0}}, // ( 32, 177) + {128, { 0, 0, 0}}, // ( 33, 177) + {128, { 0, 0, 0}}, // ( 34, 177) + {128, { 0, 0, 0}}, // ( 35, 177) + {128, { 0, 0, 0}}, // ( 36, 177) + {128, { 0, 0, 0}}, // ( 37, 177) + {128, { 0, 0, 0}}, // ( 38, 177) + {128, { 0, 0, 0}}, // ( 39, 177) + {128, { 0, 0, 0}}, // ( 40, 177) + {128, { 0, 0, 0}}, // ( 41, 177) + {128, { 0, 0, 0}}, // ( 42, 177) + {128, { 0, 0, 0}}, // ( 43, 177) + {128, { 0, 0, 0}}, // ( 44, 177) + {128, { 0, 0, 0}}, // ( 45, 177) + {128, { 0, 0, 0}}, // ( 46, 177) + {128, { 0, 0, 0}}, // ( 47, 177) + {128, { 0, 0, 0}}, // ( 48, 177) + {128, { 0, 0, 0}}, // ( 49, 177) + {128, { 0, 0, 0}}, // ( 50, 177) + {128, { 0, 0, 0}}, // ( 51, 177) + {128, { 0, 0, 0}}, // ( 52, 177) + {128, { 0, 0, 0}}, // ( 53, 177) + {128, { 0, 0, 0}}, // ( 54, 177) + {128, { 0, 0, 0}}, // ( 55, 177) + {128, { 0, 0, 0}}, // ( 56, 177) + {128, { 0, 0, 0}}, // ( 57, 177) + {128, { 0, 0, 0}}, // ( 58, 177) + {128, { 0, 0, 0}}, // ( 59, 177) + {128, { 0, 0, 0}}, // ( 60, 177) + {128, { 0, 0, 0}}, // ( 61, 177) + {128, { 0, 0, 0}}, // ( 62, 177) + {128, { 0, 0, 0}}, // ( 63, 177) + {128, { 0, 0, 0}}, // ( 64, 177) + {128, { 0, 0, 0}}, // ( 65, 177) + {128, { 0, 0, 0}}, // ( 66, 177) + {128, { 0, 0, 0}}, // ( 67, 177) + {128, { 0, 0, 0}}, // ( 68, 177) + {128, { 0, 0, 0}}, // ( 69, 177) + {128, { 0, 0, 0}}, // ( 70, 177) + {128, { 0, 0, 0}}, // ( 71, 177) + {128, { 0, 0, 0}}, // ( 72, 177) + {128, { 0, 0, 0}}, // ( 73, 177) + {128, { 0, 0, 0}}, // ( 74, 177) + {128, { 0, 0, 0}}, // ( 75, 177) + {127, { 0, 0, 0}}, // ( 76, 177) + {113, { 0, 0, 0}}, // ( 77, 177) + { 95, { 0, 0, 0}}, // ( 78, 177) + { 80, { 0, 0, 0}}, // ( 79, 177) + { 65, { 0, 0, 0}}, // ( 80, 177) + { 53, { 0, 0, 0}}, // ( 81, 177) + { 44, { 0, 0, 0}}, // ( 82, 177) + { 33, { 0, 0, 0}}, // ( 83, 177) + { 24, { 0, 0, 0}}, // ( 84, 177) + { 17, { 0, 0, 0}}, // ( 85, 177) + { 9, { 0, 0, 0}}, // ( 86, 177) + { 9, { 0, 0, 0}}, // ( 87, 177) + { 6, { 0, 0, 0}}, // ( 88, 177) + { 0, { 0, 0, 0}}, // ( 89, 177) + { 0, { 0, 0, 0}}, // ( 90, 177) + { 6, { 0, 0, 0}}, // ( 91, 177) + { 9, { 0, 0, 0}}, // ( 92, 177) + { 9, { 0, 0, 0}}, // ( 93, 177) + { 17, { 0, 0, 0}}, // ( 94, 177) + { 24, { 0, 0, 0}}, // ( 95, 177) + { 33, { 0, 0, 0}}, // ( 96, 177) + { 44, { 0, 0, 0}}, // ( 97, 177) + { 53, { 0, 0, 0}}, // ( 98, 177) + { 65, { 0, 0, 0}}, // ( 99, 177) + { 80, { 0, 0, 0}}, // (100, 177) + { 95, { 0, 0, 0}}, // (101, 177) + {113, { 0, 0, 0}}, // (102, 177) + {127, { 0, 0, 0}}, // (103, 177) + {128, { 0, 0, 0}}, // (104, 177) + {128, { 0, 0, 0}}, // (105, 177) + {128, { 0, 0, 0}}, // (106, 177) + {128, { 0, 0, 0}}, // (107, 177) + {128, { 0, 0, 0}}, // (108, 177) + {128, { 0, 0, 0}}, // (109, 177) + {128, { 0, 0, 0}}, // (110, 177) + {128, { 0, 0, 0}}, // (111, 177) + {128, { 0, 0, 0}}, // (112, 177) + {128, { 0, 0, 0}}, // (113, 177) + {128, { 0, 0, 0}}, // (114, 177) + {128, { 0, 0, 0}}, // (115, 177) + {128, { 0, 0, 0}}, // (116, 177) + {128, { 0, 0, 0}}, // (117, 177) + {128, { 0, 0, 0}}, // (118, 177) + {128, { 0, 0, 0}}, // (119, 177) + {128, { 0, 0, 0}}, // (120, 177) + {128, { 0, 0, 0}}, // (121, 177) + {128, { 0, 0, 0}}, // (122, 177) + {128, { 0, 0, 0}}, // (123, 177) + {128, { 0, 0, 0}}, // (124, 177) + {128, { 0, 0, 0}}, // (125, 177) + {128, { 0, 0, 0}}, // (126, 177) + {128, { 0, 0, 0}}, // (127, 177) + {128, { 0, 0, 0}}, // (128, 177) + {128, { 0, 0, 0}}, // (129, 177) + {128, { 0, 0, 0}}, // (130, 177) + {128, { 0, 0, 0}}, // (131, 177) + {128, { 0, 0, 0}}, // (132, 177) + {128, { 0, 0, 0}}, // (133, 177) + {128, { 0, 0, 0}}, // (134, 177) + {128, { 0, 0, 0}}, // (135, 177) + {128, { 0, 0, 0}}, // (136, 177) + {128, { 0, 0, 0}}, // (137, 177) + {128, { 0, 0, 0}}, // (138, 177) + {128, { 0, 0, 0}}, // (139, 177) + {128, { 0, 0, 0}}, // (140, 177) + {128, { 0, 0, 0}}, // (141, 177) + {128, { 0, 0, 0}}, // (142, 177) + {128, { 0, 0, 0}}, // (143, 177) + {128, { 0, 0, 0}}, // (144, 177) + {128, { 0, 0, 0}}, // (145, 177) + {128, { 0, 0, 0}}, // (146, 177) + {128, { 0, 0, 0}}, // (147, 177) + {128, { 0, 0, 0}}, // (148, 177) + {128, { 0, 0, 0}}, // (149, 177) + {128, { 0, 0, 0}}, // (150, 177) + {128, { 0, 0, 0}}, // (151, 177) + {128, { 0, 0, 0}}, // (152, 177) + {128, { 0, 0, 0}}, // (153, 177) + {128, { 0, 0, 0}}, // (154, 177) + {128, { 0, 0, 0}}, // (155, 177) + {128, { 0, 0, 0}}, // (156, 177) + {128, { 0, 0, 0}}, // (157, 177) + {128, { 0, 0, 0}}, // (158, 177) + {128, { 0, 0, 0}}, // (159, 177) + {128, { 0, 0, 0}}, // (160, 177) + {128, { 0, 0, 0}}, // (161, 177) + {128, { 0, 0, 0}}, // (162, 177) + {128, { 0, 0, 0}}, // (163, 177) + {128, { 0, 0, 0}}, // (164, 177) + {128, { 0, 0, 0}}, // (165, 177) + {128, { 0, 0, 0}}, // (166, 177) + {128, { 0, 0, 0}}, // (167, 177) + {128, { 0, 0, 0}}, // (168, 177) + {128, { 0, 0, 0}}, // (169, 177) + {128, { 0, 0, 0}}, // (170, 177) + {128, { 0, 0, 0}}, // (171, 177) + {128, { 0, 0, 0}}, // (172, 177) + {128, { 0, 0, 0}}, // (173, 177) + {128, { 0, 0, 0}}, // (174, 177) + {128, { 0, 0, 0}}, // (175, 177) + {128, { 0, 0, 0}}, // (176, 177) + {128, { 0, 0, 0}}, // (177, 177) + {128, { 0, 0, 0}}, // (178, 177) + {128, { 0, 0, 0}}, // (179, 177) + {128, { 0, 0, 0}}, // ( 0, 178) + {128, { 0, 0, 0}}, // ( 1, 178) + {128, { 0, 0, 0}}, // ( 2, 178) + {128, { 0, 0, 0}}, // ( 3, 178) + {128, { 0, 0, 0}}, // ( 4, 178) + {128, { 0, 0, 0}}, // ( 5, 178) + {128, { 0, 0, 0}}, // ( 6, 178) + {128, { 0, 0, 0}}, // ( 7, 178) + {128, { 0, 0, 0}}, // ( 8, 178) + {128, { 0, 0, 0}}, // ( 9, 178) + {128, { 0, 0, 0}}, // ( 10, 178) + {128, { 0, 0, 0}}, // ( 11, 178) + {128, { 0, 0, 0}}, // ( 12, 178) + {128, { 0, 0, 0}}, // ( 13, 178) + {128, { 0, 0, 0}}, // ( 14, 178) + {128, { 0, 0, 0}}, // ( 15, 178) + {128, { 0, 0, 0}}, // ( 16, 178) + {128, { 0, 0, 0}}, // ( 17, 178) + {128, { 0, 0, 0}}, // ( 18, 178) + {128, { 0, 0, 0}}, // ( 19, 178) + {128, { 0, 0, 0}}, // ( 20, 178) + {128, { 0, 0, 0}}, // ( 21, 178) + {128, { 0, 0, 0}}, // ( 22, 178) + {128, { 0, 0, 0}}, // ( 23, 178) + {128, { 0, 0, 0}}, // ( 24, 178) + {128, { 0, 0, 0}}, // ( 25, 178) + {128, { 0, 0, 0}}, // ( 26, 178) + {128, { 0, 0, 0}}, // ( 27, 178) + {128, { 0, 0, 0}}, // ( 28, 178) + {128, { 0, 0, 0}}, // ( 29, 178) + {128, { 0, 0, 0}}, // ( 30, 178) + {128, { 0, 0, 0}}, // ( 31, 178) + {128, { 0, 0, 0}}, // ( 32, 178) + {128, { 0, 0, 0}}, // ( 33, 178) + {128, { 0, 0, 0}}, // ( 34, 178) + {128, { 0, 0, 0}}, // ( 35, 178) + {128, { 0, 0, 0}}, // ( 36, 178) + {128, { 0, 0, 0}}, // ( 37, 178) + {128, { 0, 0, 0}}, // ( 38, 178) + {128, { 0, 0, 0}}, // ( 39, 178) + {128, { 0, 0, 0}}, // ( 40, 178) + {128, { 0, 0, 0}}, // ( 41, 178) + {128, { 0, 0, 0}}, // ( 42, 178) + {128, { 0, 0, 0}}, // ( 43, 178) + {128, { 0, 0, 0}}, // ( 44, 178) + {128, { 0, 0, 0}}, // ( 45, 178) + {128, { 0, 0, 0}}, // ( 46, 178) + {128, { 0, 0, 0}}, // ( 47, 178) + {128, { 0, 0, 0}}, // ( 48, 178) + {128, { 0, 0, 0}}, // ( 49, 178) + {128, { 0, 0, 0}}, // ( 50, 178) + {128, { 0, 0, 0}}, // ( 51, 178) + {128, { 0, 0, 0}}, // ( 52, 178) + {128, { 0, 0, 0}}, // ( 53, 178) + {128, { 0, 0, 0}}, // ( 54, 178) + {128, { 0, 0, 0}}, // ( 55, 178) + {128, { 0, 0, 0}}, // ( 56, 178) + {128, { 0, 0, 0}}, // ( 57, 178) + {128, { 0, 0, 0}}, // ( 58, 178) + {128, { 0, 0, 0}}, // ( 59, 178) + {128, { 0, 0, 0}}, // ( 60, 178) + {128, { 0, 0, 0}}, // ( 61, 178) + {128, { 0, 0, 0}}, // ( 62, 178) + {128, { 0, 0, 0}}, // ( 63, 178) + {128, { 0, 0, 0}}, // ( 64, 178) + {128, { 0, 0, 0}}, // ( 65, 178) + {128, { 0, 0, 0}}, // ( 66, 178) + {128, { 0, 0, 0}}, // ( 67, 178) + {128, { 0, 0, 0}}, // ( 68, 178) + {128, { 0, 0, 0}}, // ( 69, 178) + {128, { 0, 0, 0}}, // ( 70, 178) + {128, { 0, 0, 0}}, // ( 71, 178) + {128, { 0, 0, 0}}, // ( 72, 178) + {128, { 0, 0, 0}}, // ( 73, 178) + {128, { 0, 0, 0}}, // ( 74, 178) + {128, { 0, 0, 0}}, // ( 75, 178) + {128, { 0, 0, 0}}, // ( 76, 178) + {128, { 0, 0, 0}}, // ( 77, 178) + {128, { 0, 0, 0}}, // ( 78, 178) + {128, { 0, 0, 0}}, // ( 79, 178) + {128, { 0, 0, 0}}, // ( 80, 178) + {128, { 0, 0, 0}}, // ( 81, 178) + {128, { 0, 0, 0}}, // ( 82, 178) + {128, { 0, 0, 0}}, // ( 83, 178) + {128, { 0, 0, 0}}, // ( 84, 178) + {128, { 0, 0, 0}}, // ( 85, 178) + {128, { 0, 0, 0}}, // ( 86, 178) + {128, { 0, 0, 0}}, // ( 87, 178) + {128, { 0, 0, 0}}, // ( 88, 178) + {128, { 0, 0, 0}}, // ( 89, 178) + {128, { 0, 0, 0}}, // ( 90, 178) + {128, { 0, 0, 0}}, // ( 91, 178) + {128, { 0, 0, 0}}, // ( 92, 178) + {128, { 0, 0, 0}}, // ( 93, 178) + {128, { 0, 0, 0}}, // ( 94, 178) + {128, { 0, 0, 0}}, // ( 95, 178) + {128, { 0, 0, 0}}, // ( 96, 178) + {128, { 0, 0, 0}}, // ( 97, 178) + {128, { 0, 0, 0}}, // ( 98, 178) + {128, { 0, 0, 0}}, // ( 99, 178) + {128, { 0, 0, 0}}, // (100, 178) + {128, { 0, 0, 0}}, // (101, 178) + {128, { 0, 0, 0}}, // (102, 178) + {128, { 0, 0, 0}}, // (103, 178) + {128, { 0, 0, 0}}, // (104, 178) + {128, { 0, 0, 0}}, // (105, 178) + {128, { 0, 0, 0}}, // (106, 178) + {128, { 0, 0, 0}}, // (107, 178) + {128, { 0, 0, 0}}, // (108, 178) + {128, { 0, 0, 0}}, // (109, 178) + {128, { 0, 0, 0}}, // (110, 178) + {128, { 0, 0, 0}}, // (111, 178) + {128, { 0, 0, 0}}, // (112, 178) + {128, { 0, 0, 0}}, // (113, 178) + {128, { 0, 0, 0}}, // (114, 178) + {128, { 0, 0, 0}}, // (115, 178) + {128, { 0, 0, 0}}, // (116, 178) + {128, { 0, 0, 0}}, // (117, 178) + {128, { 0, 0, 0}}, // (118, 178) + {128, { 0, 0, 0}}, // (119, 178) + {128, { 0, 0, 0}}, // (120, 178) + {128, { 0, 0, 0}}, // (121, 178) + {128, { 0, 0, 0}}, // (122, 178) + {128, { 0, 0, 0}}, // (123, 178) + {128, { 0, 0, 0}}, // (124, 178) + {128, { 0, 0, 0}}, // (125, 178) + {128, { 0, 0, 0}}, // (126, 178) + {128, { 0, 0, 0}}, // (127, 178) + {128, { 0, 0, 0}}, // (128, 178) + {128, { 0, 0, 0}}, // (129, 178) + {128, { 0, 0, 0}}, // (130, 178) + {128, { 0, 0, 0}}, // (131, 178) + {128, { 0, 0, 0}}, // (132, 178) + {128, { 0, 0, 0}}, // (133, 178) + {128, { 0, 0, 0}}, // (134, 178) + {128, { 0, 0, 0}}, // (135, 178) + {128, { 0, 0, 0}}, // (136, 178) + {128, { 0, 0, 0}}, // (137, 178) + {128, { 0, 0, 0}}, // (138, 178) + {128, { 0, 0, 0}}, // (139, 178) + {128, { 0, 0, 0}}, // (140, 178) + {128, { 0, 0, 0}}, // (141, 178) + {128, { 0, 0, 0}}, // (142, 178) + {128, { 0, 0, 0}}, // (143, 178) + {128, { 0, 0, 0}}, // (144, 178) + {128, { 0, 0, 0}}, // (145, 178) + {128, { 0, 0, 0}}, // (146, 178) + {128, { 0, 0, 0}}, // (147, 178) + {128, { 0, 0, 0}}, // (148, 178) + {128, { 0, 0, 0}}, // (149, 178) + {128, { 0, 0, 0}}, // (150, 178) + {128, { 0, 0, 0}}, // (151, 178) + {128, { 0, 0, 0}}, // (152, 178) + {128, { 0, 0, 0}}, // (153, 178) + {128, { 0, 0, 0}}, // (154, 178) + {128, { 0, 0, 0}}, // (155, 178) + {128, { 0, 0, 0}}, // (156, 178) + {128, { 0, 0, 0}}, // (157, 178) + {128, { 0, 0, 0}}, // (158, 178) + {128, { 0, 0, 0}}, // (159, 178) + {128, { 0, 0, 0}}, // (160, 178) + {128, { 0, 0, 0}}, // (161, 178) + {128, { 0, 0, 0}}, // (162, 178) + {128, { 0, 0, 0}}, // (163, 178) + {128, { 0, 0, 0}}, // (164, 178) + {128, { 0, 0, 0}}, // (165, 178) + {128, { 0, 0, 0}}, // (166, 178) + {128, { 0, 0, 0}}, // (167, 178) + {128, { 0, 0, 0}}, // (168, 178) + {128, { 0, 0, 0}}, // (169, 178) + {128, { 0, 0, 0}}, // (170, 178) + {128, { 0, 0, 0}}, // (171, 178) + {128, { 0, 0, 0}}, // (172, 178) + {128, { 0, 0, 0}}, // (173, 178) + {128, { 0, 0, 0}}, // (174, 178) + {128, { 0, 0, 0}}, // (175, 178) + {128, { 0, 0, 0}}, // (176, 178) + {128, { 0, 0, 0}}, // (177, 178) + {128, { 0, 0, 0}}, // (178, 178) + {128, { 0, 0, 0}}, // (179, 178) + {128, { 0, 0, 0}}, // ( 0, 179) + {128, { 0, 0, 0}}, // ( 1, 179) + {128, { 0, 0, 0}}, // ( 2, 179) + {128, { 0, 0, 0}}, // ( 3, 179) + {128, { 0, 0, 0}}, // ( 4, 179) + {128, { 0, 0, 0}}, // ( 5, 179) + {128, { 0, 0, 0}}, // ( 6, 179) + {128, { 0, 0, 0}}, // ( 7, 179) + {128, { 0, 0, 0}}, // ( 8, 179) + {128, { 0, 0, 0}}, // ( 9, 179) + {128, { 0, 0, 0}}, // ( 10, 179) + {128, { 0, 0, 0}}, // ( 11, 179) + {128, { 0, 0, 0}}, // ( 12, 179) + {128, { 0, 0, 0}}, // ( 13, 179) + {128, { 0, 0, 0}}, // ( 14, 179) + {128, { 0, 0, 0}}, // ( 15, 179) + {128, { 0, 0, 0}}, // ( 16, 179) + {128, { 0, 0, 0}}, // ( 17, 179) + {128, { 0, 0, 0}}, // ( 18, 179) + {128, { 0, 0, 0}}, // ( 19, 179) + {128, { 0, 0, 0}}, // ( 20, 179) + {128, { 0, 0, 0}}, // ( 21, 179) + {128, { 0, 0, 0}}, // ( 22, 179) + {128, { 0, 0, 0}}, // ( 23, 179) + {128, { 0, 0, 0}}, // ( 24, 179) + {128, { 0, 0, 0}}, // ( 25, 179) + {128, { 0, 0, 0}}, // ( 26, 179) + {128, { 0, 0, 0}}, // ( 27, 179) + {128, { 0, 0, 0}}, // ( 28, 179) + {128, { 0, 0, 0}}, // ( 29, 179) + {128, { 0, 0, 0}}, // ( 30, 179) + {128, { 0, 0, 0}}, // ( 31, 179) + {128, { 0, 0, 0}}, // ( 32, 179) + {128, { 0, 0, 0}}, // ( 33, 179) + {128, { 0, 0, 0}}, // ( 34, 179) + {128, { 0, 0, 0}}, // ( 35, 179) + {128, { 0, 0, 0}}, // ( 36, 179) + {128, { 0, 0, 0}}, // ( 37, 179) + {128, { 0, 0, 0}}, // ( 38, 179) + {128, { 0, 0, 0}}, // ( 39, 179) + {128, { 0, 0, 0}}, // ( 40, 179) + {128, { 0, 0, 0}}, // ( 41, 179) + {128, { 0, 0, 0}}, // ( 42, 179) + {128, { 0, 0, 0}}, // ( 43, 179) + {128, { 0, 0, 0}}, // ( 44, 179) + {128, { 0, 0, 0}}, // ( 45, 179) + {128, { 0, 0, 0}}, // ( 46, 179) + {128, { 0, 0, 0}}, // ( 47, 179) + {128, { 0, 0, 0}}, // ( 48, 179) + {128, { 0, 0, 0}}, // ( 49, 179) + {128, { 0, 0, 0}}, // ( 50, 179) + {128, { 0, 0, 0}}, // ( 51, 179) + {128, { 0, 0, 0}}, // ( 52, 179) + {128, { 0, 0, 0}}, // ( 53, 179) + {128, { 0, 0, 0}}, // ( 54, 179) + {128, { 0, 0, 0}}, // ( 55, 179) + {128, { 0, 0, 0}}, // ( 56, 179) + {128, { 0, 0, 0}}, // ( 57, 179) + {128, { 0, 0, 0}}, // ( 58, 179) + {128, { 0, 0, 0}}, // ( 59, 179) + {128, { 0, 0, 0}}, // ( 60, 179) + {128, { 0, 0, 0}}, // ( 61, 179) + {128, { 0, 0, 0}}, // ( 62, 179) + {128, { 0, 0, 0}}, // ( 63, 179) + {128, { 0, 0, 0}}, // ( 64, 179) + {128, { 0, 0, 0}}, // ( 65, 179) + {128, { 0, 0, 0}}, // ( 66, 179) + {128, { 0, 0, 0}}, // ( 67, 179) + {128, { 0, 0, 0}}, // ( 68, 179) + {128, { 0, 0, 0}}, // ( 69, 179) + {128, { 0, 0, 0}}, // ( 70, 179) + {128, { 0, 0, 0}}, // ( 71, 179) + {128, { 0, 0, 0}}, // ( 72, 179) + {128, { 0, 0, 0}}, // ( 73, 179) + {128, { 0, 0, 0}}, // ( 74, 179) + {128, { 0, 0, 0}}, // ( 75, 179) + {128, { 0, 0, 0}}, // ( 76, 179) + {128, { 0, 0, 0}}, // ( 77, 179) + {128, { 0, 0, 0}}, // ( 78, 179) + {128, { 0, 0, 0}}, // ( 79, 179) + {128, { 0, 0, 0}}, // ( 80, 179) + {128, { 0, 0, 0}}, // ( 81, 179) + {128, { 0, 0, 0}}, // ( 82, 179) + {128, { 0, 0, 0}}, // ( 83, 179) + {128, { 0, 0, 0}}, // ( 84, 179) + {128, { 0, 0, 0}}, // ( 85, 179) + {128, { 0, 0, 0}}, // ( 86, 179) + {128, { 0, 0, 0}}, // ( 87, 179) + {128, { 0, 0, 0}}, // ( 88, 179) + {128, { 0, 0, 0}}, // ( 89, 179) + {128, { 0, 0, 0}}, // ( 90, 179) + {128, { 0, 0, 0}}, // ( 91, 179) + {128, { 0, 0, 0}}, // ( 92, 179) + {128, { 0, 0, 0}}, // ( 93, 179) + {128, { 0, 0, 0}}, // ( 94, 179) + {128, { 0, 0, 0}}, // ( 95, 179) + {128, { 0, 0, 0}}, // ( 96, 179) + {128, { 0, 0, 0}}, // ( 97, 179) + {128, { 0, 0, 0}}, // ( 98, 179) + {128, { 0, 0, 0}}, // ( 99, 179) + {128, { 0, 0, 0}}, // (100, 179) + {128, { 0, 0, 0}}, // (101, 179) + {128, { 0, 0, 0}}, // (102, 179) + {128, { 0, 0, 0}}, // (103, 179) + {128, { 0, 0, 0}}, // (104, 179) + {128, { 0, 0, 0}}, // (105, 179) + {128, { 0, 0, 0}}, // (106, 179) + {128, { 0, 0, 0}}, // (107, 179) + {128, { 0, 0, 0}}, // (108, 179) + {128, { 0, 0, 0}}, // (109, 179) + {128, { 0, 0, 0}}, // (110, 179) + {128, { 0, 0, 0}}, // (111, 179) + {128, { 0, 0, 0}}, // (112, 179) + {128, { 0, 0, 0}}, // (113, 179) + {128, { 0, 0, 0}}, // (114, 179) + {128, { 0, 0, 0}}, // (115, 179) + {128, { 0, 0, 0}}, // (116, 179) + {128, { 0, 0, 0}}, // (117, 179) + {128, { 0, 0, 0}}, // (118, 179) + {128, { 0, 0, 0}}, // (119, 179) + {128, { 0, 0, 0}}, // (120, 179) + {128, { 0, 0, 0}}, // (121, 179) + {128, { 0, 0, 0}}, // (122, 179) + {128, { 0, 0, 0}}, // (123, 179) + {128, { 0, 0, 0}}, // (124, 179) + {128, { 0, 0, 0}}, // (125, 179) + {128, { 0, 0, 0}}, // (126, 179) + {128, { 0, 0, 0}}, // (127, 179) + {128, { 0, 0, 0}}, // (128, 179) + {128, { 0, 0, 0}}, // (129, 179) + {128, { 0, 0, 0}}, // (130, 179) + {128, { 0, 0, 0}}, // (131, 179) + {128, { 0, 0, 0}}, // (132, 179) + {128, { 0, 0, 0}}, // (133, 179) + {128, { 0, 0, 0}}, // (134, 179) + {128, { 0, 0, 0}}, // (135, 179) + {128, { 0, 0, 0}}, // (136, 179) + {128, { 0, 0, 0}}, // (137, 179) + {128, { 0, 0, 0}}, // (138, 179) + {128, { 0, 0, 0}}, // (139, 179) + {128, { 0, 0, 0}}, // (140, 179) + {128, { 0, 0, 0}}, // (141, 179) + {128, { 0, 0, 0}}, // (142, 179) + {128, { 0, 0, 0}}, // (143, 179) + {128, { 0, 0, 0}}, // (144, 179) + {128, { 0, 0, 0}}, // (145, 179) + {128, { 0, 0, 0}}, // (146, 179) + {128, { 0, 0, 0}}, // (147, 179) + {128, { 0, 0, 0}}, // (148, 179) + {128, { 0, 0, 0}}, // (149, 179) + {128, { 0, 0, 0}}, // (150, 179) + {128, { 0, 0, 0}}, // (151, 179) + {128, { 0, 0, 0}}, // (152, 179) + {128, { 0, 0, 0}}, // (153, 179) + {128, { 0, 0, 0}}, // (154, 179) + {128, { 0, 0, 0}}, // (155, 179) + {128, { 0, 0, 0}}, // (156, 179) + {128, { 0, 0, 0}}, // (157, 179) + {128, { 0, 0, 0}}, // (158, 179) + {128, { 0, 0, 0}}, // (159, 179) + {128, { 0, 0, 0}}, // (160, 179) + {128, { 0, 0, 0}}, // (161, 179) + {128, { 0, 0, 0}}, // (162, 179) + {128, { 0, 0, 0}}, // (163, 179) + {128, { 0, 0, 0}}, // (164, 179) + {128, { 0, 0, 0}}, // (165, 179) + {128, { 0, 0, 0}}, // (166, 179) + {128, { 0, 0, 0}}, // (167, 179) + {128, { 0, 0, 0}}, // (168, 179) + {128, { 0, 0, 0}}, // (169, 179) + {128, { 0, 0, 0}}, // (170, 179) + {128, { 0, 0, 0}}, // (171, 179) + {128, { 0, 0, 0}}, // (172, 179) + {128, { 0, 0, 0}}, // (173, 179) + {128, { 0, 0, 0}}, // (174, 179) + {128, { 0, 0, 0}}, // (175, 179) + {128, { 0, 0, 0}}, // (176, 179) + {128, { 0, 0, 0}}, // (177, 179) + {128, { 0, 0, 0}}, // (178, 179) + {128, { 0, 0, 0}}, // (179, 179) +}; diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs index 3cfc261f9b746..7665c0fba3a9f 100644 --- a/hw/gpio/Makefile.objs +++ b/hw/gpio/Makefile.objs @@ -5,8 +5,14 @@ common-obj-$(CONFIG_ZAURUS) += zaurus.o common-obj-$(CONFIG_E500) += mpc8xxx.o common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o +<<<<<<< HEAD common-obj-$(CONFIG_OMAP) += omap_gpio.o common-obj-$(CONFIG_IMX) += imx_gpio.o common-obj-$(CONFIG_RASPI) += bcm2835_gpio.o common-obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o common-obj-$(CONFIG_ASPEED_SOC) += aspeed_gpio.o +======= +obj-$(CONFIG_OMAP) += omap_gpio.o +obj-$(CONFIG_IMX) += imx_gpio.o +obj-$(CONFIG_STM32) += stm32_gpio.o stm32_afio.o stm32_exti.o +>>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/gpio/stm32_afio.c b/hw/gpio/stm32_afio.c new file mode 100644 index 0000000000000..f4e9b373829ec --- /dev/null +++ b/hw/gpio/stm32_afio.c @@ -0,0 +1,305 @@ +/* + * STM32 Microcontroller AFIO (Alternate Function I/O) module + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "qemu/bitops.h" + + + +/* DEFINITIONS */ + +#define AFIO_EVCR_OFFSET 0x00 + +#define AFIO_MAPR_OFFSET 0x04 +#define AFIO_MAPR_USART3_REMAP_START 4 +#define AFIO_MAPR_USART3_REMAP_MASK 0x00000030 +#define AFIO_MAPR_USART2_REMAP_BIT 3 +#define AFIO_MAPR_USART1_REMAP_BIT 2 + +#define AFIO_EXTICR_START 0x08 +#define AFIO_EXTICR_COUNT 4 + +#define AFIO_EXTICR1_OFFSET 0x08 +#define AFIO_EXTICR2_OFFSET 0x0c +#define AFIO_EXTICR3_OFFSET 0x10 +#define AFIO_EXTICR4_OFFSET 0x14 + +#define AFIO_EXTI_PER_CR 4 + +struct Stm32Afio { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + void *stm32_rcc_prop; + void *stm32_exti_prop; + + /* Private */ + MemoryRegion iomem; + + Stm32Rcc *stm32_rcc; + + Stm32Gpio *gpio[STM32_GPIO_COUNT]; + Stm32Exti *exti; + + uint32_t + USART1_REMAP, + USART2_REMAP, + USART3_REMAP, + AFIO_MAPR, + AFIO_EXTICR[AFIO_EXTICR_COUNT]; +}; + + + + + + +/* REGISTER IMPLEMENTATION */ + +static uint32_t stm32_afio_AFIO_MAPR_read(Stm32Afio *s) +{ + return (s->USART1_REMAP << AFIO_MAPR_USART1_REMAP_BIT) | + (s->USART2_REMAP << AFIO_MAPR_USART2_REMAP_BIT) | + (s->USART3_REMAP << AFIO_MAPR_USART3_REMAP_START); +} + +static void stm32_afio_AFIO_MAPR_write(Stm32Afio *s, uint32_t new_value, + bool init) +{ + s->USART1_REMAP = extract32(s->AFIO_MAPR, AFIO_MAPR_USART1_REMAP_BIT, 1); + s->USART2_REMAP = extract32(s->AFIO_MAPR, AFIO_MAPR_USART2_REMAP_BIT, 1); + s->USART3_REMAP = (new_value & AFIO_MAPR_USART3_REMAP_MASK) >> AFIO_MAPR_USART3_REMAP_START; +} + +/* Write the External Interrupt Configuration Register. + * There are four of these registers, each of which configures + * four EXTI interrupt lines. Each line is represented by four bits, which + * indicate which GPIO the line is connected to. When the register is + * written, the changes are propagated to the EXTI module. + */ +static void stm32_afio_AFIO_EXTICR_write(Stm32Afio *s, unsigned index, + uint32_t new_value, bool init) +{ + int i; + unsigned exti_line; + unsigned start; + unsigned old_gpio_index, new_gpio_index; + + assert(index < AFIO_EXTICR_COUNT); + + /* Loop through the four EXTI lines controlled by this register. */ + for(i = 0; i < AFIO_EXTI_PER_CR; i++) { + /* For each line, notify the EXTI module. This shouldn't + * happen often, so we update all four, even if they all don't + * change. */ + exti_line = (index * AFIO_EXTI_PER_CR) + i; + start = i * 4; + + if(!init) { + old_gpio_index = (s->AFIO_EXTICR[index] >> start) & 0xf; + sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio[old_gpio_index]), + exti_line, + NULL); + } + new_gpio_index = (new_value >> start) & 0xf; + sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio[new_gpio_index]), + exti_line, + qdev_get_gpio_in(DEVICE(s->exti), exti_line)); + } + + s->AFIO_EXTICR[index] = new_value; +} + +static uint64_t stm32_afio_read(void *opaque, hwaddr offset, + unsigned size) +{ + Stm32Afio *s = (Stm32Afio *)opaque; + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, STM32_AFIO_PERIPH); + + switch (offset) { + case AFIO_EVCR_OFFSET: + STM32_NOT_IMPL_REG(offset, size); + break; + case AFIO_MAPR_OFFSET: + return stm32_afio_AFIO_MAPR_read(s); + case AFIO_EXTICR1_OFFSET: + return s->AFIO_EXTICR[0]; + case AFIO_EXTICR2_OFFSET: + return s->AFIO_EXTICR[1]; + case AFIO_EXTICR3_OFFSET: + return s->AFIO_EXTICR[2]; + case AFIO_EXTICR4_OFFSET: + return s->AFIO_EXTICR[3]; + default: + STM32_BAD_REG(offset, size); + return 0; + } +} + +static void stm32_afio_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + Stm32Afio *s = (Stm32Afio *)opaque; + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, STM32_AFIO_PERIPH); + + switch (offset) { + case AFIO_EVCR_OFFSET: + STM32_NOT_IMPL_REG(offset, size); + break; + case AFIO_MAPR_OFFSET: + stm32_afio_AFIO_MAPR_write(s, value, false); + break; + case AFIO_EXTICR1_OFFSET: + stm32_afio_AFIO_EXTICR_write(s, 0, value, false); + break; + case AFIO_EXTICR2_OFFSET: + stm32_afio_AFIO_EXTICR_write(s, 1, value, false); + break; + case AFIO_EXTICR3_OFFSET: + stm32_afio_AFIO_EXTICR_write(s, 2, value, false); + break; + case AFIO_EXTICR4_OFFSET: + stm32_afio_AFIO_EXTICR_write(s, 3, value, false); + break; + default: + STM32_BAD_REG(offset, size); + break; + } +} + +static const MemoryRegionOps stm32_afio_ops = { + .read = stm32_afio_read, + .write = stm32_afio_write, + .valid.min_access_size = 4, + .valid.max_access_size = 4, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void stm32_afio_reset(DeviceState *dev) +{ + Stm32Afio *s = STM32_AFIO(dev); + + stm32_afio_AFIO_MAPR_write(s, 0x00000000, true); + stm32_afio_AFIO_EXTICR_write(s, 0, 0x00000000, true); + stm32_afio_AFIO_EXTICR_write(s, 1, 0x00000000, true); + stm32_afio_AFIO_EXTICR_write(s, 2, 0x00000000, true); + stm32_afio_AFIO_EXTICR_write(s, 3, 0x00000000, true); +} + + + + + + +/* PUBLIC FUNCTIONS */ + +uint32_t stm32_afio_get_periph_map(Stm32Afio *s, stm32_periph_t periph) +{ + switch(periph) { + case STM32_UART1: + return s->USART1_REMAP; + case STM32_UART2: + return s->USART2_REMAP; + case STM32_UART3: + return s->USART3_REMAP; + default: + hw_error("Invalid peripheral"); + break; + } +} + + + + +/* DEVICE INITIALIZATION */ + +static int stm32_afio_init(SysBusDevice *dev) +{ + Stm32Afio *s = STM32_AFIO(dev); + + s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_afio_ops, s, + "afio", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + return 0; +} + +static Property stm32_afio_properties[] = { + DEFINE_PROP_PTR("stm32_rcc", Stm32Afio, stm32_rcc_prop), + DEFINE_PROP_END_OF_LIST() +}; + +static void add_gpio_link(Stm32Afio *s, int gpio_index, const char *link_name) +{ + object_property_add_link(OBJECT(s), link_name, TYPE_STM32_GPIO, + (Object **)&s->gpio[gpio_index], + object_property_allow_set_link, + OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); +} + +static void stm32_afio_instance_init(Object *obj) +{ + Stm32Afio *s = STM32_AFIO(obj); + + add_gpio_link(s, 0, "gpio[a]"); + add_gpio_link(s, 1, "gpio[b]"); + add_gpio_link(s, 2, "gpio[c]"); + add_gpio_link(s, 3, "gpio[d]"); + add_gpio_link(s, 4, "gpio[e]"); + add_gpio_link(s, 5, "gpio[f]"); + add_gpio_link(s, 6, "gpio[g]"); + + object_property_add_link(obj, "exti", TYPE_STM32_EXTI, + (Object **)&s->exti, + object_property_allow_set_link, + OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); + +} + +static void stm32_afio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_afio_init; + dc->reset = stm32_afio_reset; + dc->props = stm32_afio_properties; +} + +static TypeInfo stm32_afio_info = { + .name = TYPE_STM32_AFIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Afio), + .instance_init = stm32_afio_instance_init, + .class_init = stm32_afio_class_init +}; + +static void stm32_afio_register_types(void) +{ + type_register_static(&stm32_afio_info); +} + +type_init(stm32_afio_register_types) diff --git a/hw/gpio/stm32_exti.c b/hw/gpio/stm32_exti.c new file mode 100644 index 0000000000000..a8c0665a88139 --- /dev/null +++ b/hw/gpio/stm32_exti.c @@ -0,0 +1,331 @@ +/* + * STM32 Microcontroller EXTI (External Interrupt/Event Controller) module + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/arm/stm32.h" +#include "hw/arm/stm32f4xx.h" +#include "qemu/bitops.h" + + + + +/* DEFINITIONS*/ + +#define EXTI_IMR_OFFSET 0x00 + +#define EXTI_EMR_OFFSET 0x04 + +#define EXTI_RTSR_OFFSET 0x08 + +#define EXTI_FTSR_OFFSET 0x0c + +#define EXTI_SWIER_OFFSET 0x10 + +#define EXTI_PR_OFFSET 0x14 + +/* There are 20 lines for CL devices. Non-CL devices have only 19, but it + * doesn't hurt to handle the maximum possible. */ +#define EXTI_LINE_COUNT 20 + +/* The number of IRQ sources from the EXTI controller */ +#define EXTI_IRQ_COUNT 14 + + +struct Stm32Exti { + /* Inherited */ + SysBusDevice busdev; + + /* Private */ + MemoryRegion iomem; + + uint32_t + EXTI_IMR, + EXTI_RTSR, + EXTI_FTSR, + EXTI_SWIER, + EXTI_PR; + + qemu_irq irq[EXTI_IRQ_COUNT]; +}; + +static void stm32_exti_change_EXTI_PR_bit(Stm32Exti *s, unsigned pos, + unsigned new_bit_value); + + + +/* HELPER FUNCTIONS */ + +/* Call when the EXTI shouldbe tri */ +static void stm32_exti_trigger(Stm32Exti *s, int line) +{ + /* Make sure the interrupt for this EXTI line has been enabled. */ + if(s->EXTI_IMR & BIT(line)) { + /* Set the Pending flag for this line, which will trigger the interrupt + * (if the flag isn't already set). */ + stm32_exti_change_EXTI_PR_bit(s, line, 1); + } +} + +/* We will assume that this handler will only be called if the pin actually + * changed state. */ +static void stm32_exti_gpio_in_handler(void *opaque, int n, int level) +{ + Stm32Exti *s = (Stm32Exti *)opaque; + unsigned pin = n; + + assert(pin < STM32_GPIO_PIN_COUNT); + + /* Check the level - if it is rising, then trigger an interrupt if the + * corresponding Rising Trigger Selection Register flag is set. Otherwise, + * trigger if the Falling Trigger Selection Register flag is set. + */ + if((level && (s->EXTI_RTSR & BIT(pin))) || + (!level && (s->EXTI_FTSR & BIT(pin)))) { + stm32_exti_trigger(s, pin); + } +} + + + + +/* REGISTER IMPLEMENTATION */ + +/* Update a Trigger Selection Register (both the Rising and Falling TSR + * registers are handled by this routine). + */ +static void update_TSR_bit(Stm32Exti *s, uint32_t *tsr_register, unsigned pos, + unsigned new_bit_value) +{ + assert((new_bit_value == 0) || (new_bit_value == 1)); + assert(pos < EXTI_LINE_COUNT); + + if(new_bit_value != extract32(*tsr_register, pos, 1)) { + /* According to the documentation, the Pending register is cleared when + * the "sensitivity of the edge detector changes. Is this right??? */ + stm32_exti_change_EXTI_PR_bit(s, pos, 0); + } + *tsr_register = deposit32(*tsr_register, pos, 1, new_bit_value); +} + +/* Update the Pending Register. This will trigger an interrupt if a bit is + * set. + */ +static void stm32_exti_change_EXTI_PR_bit(Stm32Exti *s, unsigned pos, + unsigned new_bit_value) +{ + unsigned old_bit_value; + + assert((new_bit_value == 0) || (new_bit_value == 1)); + assert(pos < EXTI_LINE_COUNT); + + old_bit_value = extract32(s->EXTI_PR, pos, 1); + + /* Only continue if the PR bit is actually changing value. */ + if(new_bit_value != old_bit_value) { + /* If the bit is being reset, the corresponding Software Interrupt Event + * Register bit is automatically reset. + */ + if(!new_bit_value) { + s->EXTI_SWIER &= ~BIT(pos); + } + + /* Update the IRQ for this EXTI line. Some lines share the same + * NVIC IRQ. + */ + if(pos <= 4) { + /* EXTI0 - EXTI4 each have their own NVIC IRQ */ + qemu_set_irq(s->irq[pos], new_bit_value); + } else if(pos <= 9) { + /* EXTI5 - EXTI9 share an NVIC IRQ */ + qemu_set_irq(s->irq[5], new_bit_value); + } else if(pos <= 15) { + /* EXTI10 - EXTI15 share an NVIC IRQ */ + qemu_set_irq(s->irq[6], new_bit_value); + } else if(pos == 16) { + /* PVD IRQ */ + qemu_set_irq(s->irq[7], new_bit_value); + } else if(pos == 17) { + /* RTCAlarm IRQ */ + qemu_set_irq(s->irq[8], new_bit_value); + } else if(pos == 18) { + /* OTG_FS_WKUP IRQ */ + qemu_set_irq(s->irq[9], new_bit_value); + } else { + assert(false); + } + + /* Update the register. */ + s->EXTI_PR = deposit32(s->EXTI_PR, pos, 1, new_bit_value); + } +} + +static uint64_t stm32_exti_read(void *opaque, hwaddr offset, + unsigned size) +{ + Stm32Exti *s = (Stm32Exti *)opaque; + + assert(size == 4); + + switch (offset) { + case EXTI_IMR_OFFSET: + return s->EXTI_IMR; + case EXTI_EMR_OFFSET: + /* Do nothing, events are not implemented yet. */ + return 0; + case EXTI_RTSR_OFFSET: + return s->EXTI_RTSR; + case EXTI_FTSR_OFFSET: + return s->EXTI_FTSR; + case EXTI_SWIER_OFFSET: + return s->EXTI_SWIER; + case EXTI_PR_OFFSET: + return s->EXTI_PR; + default: + STM32_BAD_REG(offset, size); + return 0; + } +} + +static void stm32_exti_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + Stm32Exti *s = (Stm32Exti *)opaque; + int pos, bit_value; + + assert(size == 4); + + if(offset <= EXTI_EMR_OFFSET) { + switch (offset) { + case EXTI_IMR_OFFSET: + s->EXTI_IMR = value; + break; + case EXTI_EMR_OFFSET: + /* Do nothing, events are not implemented yet. + * But we don't want to throw an error. */ + break; + default: + STM32_BAD_REG(offset, size); + break; + } + } else { + /* These registers all contain one bit per EXTI line. We will loop + * through each line and then update each bit in the appropriate + * register. + */ + for(pos = 0; pos < EXTI_LINE_COUNT; pos++) { + bit_value = extract32(value, pos, 1); + + switch (offset) { + case EXTI_RTSR_OFFSET: + update_TSR_bit(s, &(s->EXTI_RTSR), pos, bit_value); + break; + case EXTI_FTSR_OFFSET: + update_TSR_bit(s, &(s->EXTI_FTSR), pos, bit_value); + break; + case EXTI_SWIER_OFFSET: + /* If the Software Interrupt Event Register is changed + * from 0 to 1, trigger an interrupt. Changing the + * bit to 0 does nothing. */ + if(bit_value == 1) { + if((s->EXTI_SWIER & BIT(pos)) == 0) { + s->EXTI_SWIER |= BIT(pos); + stm32_exti_trigger(s, pos); + } + } + break; + case EXTI_PR_OFFSET: + /* When a 1 is written to a PR bit, it actually clears the + * PR bit. */ + if(bit_value == 1) { + stm32_exti_change_EXTI_PR_bit(s, pos, 0); + } + break; + default: + STM32_BAD_REG(offset, size); + break; + } + } + } +} + +static const MemoryRegionOps stm32_exti_ops = { + .read = stm32_exti_read, + .write = stm32_exti_write, + .valid.min_access_size = 4, + .valid.max_access_size = 4, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void stm32_exti_reset(DeviceState *dev) +{ + Stm32Exti *s = STM32_EXTI(dev); + + s->EXTI_IMR = 0x00000000; + s->EXTI_RTSR = 0x00000000; + s->EXTI_FTSR = 0x00000000; + s->EXTI_SWIER = 0x00000000; + s->EXTI_PR = 0x00000000; +} + + +/* DEVICE INITIALIZATION */ + +static int stm32_exti_init(SysBusDevice *dev) +{ + int i; + + Stm32Exti *s = STM32_EXTI(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_exti_ops, s, + "exti", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + for(i = 0; i < EXTI_IRQ_COUNT; i++) { + sysbus_init_irq(dev, &s->irq[i]); + } + + /* Create the handlers to handle GPIO input pin changes. */ + qdev_init_gpio_in(DEVICE(dev), stm32_exti_gpio_in_handler, STM32_GPIO_PIN_COUNT); + + return 0; +} + +static void stm32_exti_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_exti_init; + dc->reset = stm32_exti_reset; +} + +static TypeInfo stm32_exti_info = { + .name = TYPE_STM32_EXTI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Exti), + .class_init = stm32_exti_class_init +}; + +static void stm32_exti_register_types(void) +{ + type_register_static(&stm32_exti_info); +} + +type_init(stm32_exti_register_types) diff --git a/hw/gpio/stm32_gpio.c b/hw/gpio/stm32_gpio.c new file mode 100644 index 0000000000000..11ebbe7bb902d --- /dev/null +++ b/hw/gpio/stm32_gpio.c @@ -0,0 +1,358 @@ +/* + * STM32 Microcontroller GPIO (General Purpose I/O) module + * + * Copyright (C) 2010 Andre Beckus + * + * Source code based on pl061.c + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "qemu/bitops.h" + + + + +/* DEFINITIONS*/ + +#define GPIOx_CRL_OFFSET 0x00 +#define GPIOx_CRH_OFFSET 0x04 +#define GPIOx_IDR_OFFSET 0x08 +#define GPIOx_ODR_OFFSET 0x0c +#define GPIOx_BSRR_OFFSET 0x10 +#define GPIOx_BRR_OFFSET 0x14 +#define GPIOx_LCKR_OFFSET 0x18 + +struct Stm32Gpio { + /* Inherited */ + SysBusDevice busdev; + + /* Properties */ + stm32_periph_t periph; + void *stm32_rcc_prop; + + /* Private */ + MemoryRegion iomem; + + Stm32Rcc *stm32_rcc; + + + uint32_t GPIOx_CRy[2]; /* CRL = 0, CRH = 1 */ + uint32_t GPIOx_ODR; + + uint16_t in; + uint16_t dir_mask; /* input = 0, output = 1 */ + + /* IRQs used to communicate with the machine implementation. + * There is one IRQ for each pin. Note that for pins configured + * as inputs, the output IRQ state has no meaning. Perhaps + * the output should be updated to match the input in this case.... + */ + qemu_irq out_irq[STM32_GPIO_PIN_COUNT]; + + /* IRQs which relay input pin changes to other STM32 peripherals */ + qemu_irq in_irq[STM32_GPIO_PIN_COUNT]; +}; + + + +/* CALLBACKs */ + +/* Trigger fired when a GPIO input pin changes state (based + * on an external stimulus from the machine). + */ +static void stm32_gpio_in_trigger(void *opaque, int irq, int level) +{ + Stm32Gpio *s = opaque; + unsigned pin = irq; + + assert(pin < STM32_GPIO_PIN_COUNT); + + /* Update internal pin state. */ + s->in |= (level ? 1 : 0) << pin; + + /* Propagate the trigger to the input IRQs. */ + qemu_set_irq(s->in_irq[pin], level); +} + + + +/* HELPER FUNCTIONS */ + +/* Gets the four configuration bits for the pin from the CRL or CRH + * register. + */ +static uint8_t stm32_gpio_get_pin_config(Stm32Gpio *s, unsigned pin) { + /* Simplify extract logic by combining both 32 bit regiters into + * one 64 bit value. + */ + uint64_t cr_64 = ((uint64_t)s->GPIOx_CRy[1] << 32) | + s->GPIOx_CRy[0]; + return extract64(cr_64, pin * 4, 4); +} + + + + + +/* REGISTER IMPLEMENTATION */ + +/* Update the CRL or CRH Configuration Register */ +static void stm32_gpio_update_dir(Stm32Gpio *s, int cr_index) +{ + unsigned start_pin, pin, pin_dir; + + assert((cr_index == 0) || (cr_index == 1)); + + /* Update the direction mask */ + start_pin = cr_index * 8; + for(pin=start_pin; pin < start_pin + 8; pin++) { + pin_dir = stm32_gpio_get_mode_bits(s, pin); + /* If the mode is 0, the pin is input. Otherwise, it + * is output. + */ + s->dir_mask |= (pin_dir ? 1 : 0) << pin; + } +} + +/* Write the Output Data Register. + * Propagates the changes to the output IRQs. + * Perhaps we should also update the input to match the output for + * pins configured as outputs... */ +static void stm32_gpio_GPIOx_ODR_write(Stm32Gpio *s, uint32_t new_value) +{ + uint32_t old_value; + uint16_t changed, changed_out; + unsigned pin; + + old_value = s->GPIOx_ODR; + + /* Update register value. Per documentation, the upper 16 bits + * always read as 0. */ + s->GPIOx_ODR = new_value & 0x0000ffff; + + /* Get pins that changed value */ + changed = old_value ^ new_value; + + /* Get changed pins that are outputs - we will not touch input pins */ + changed_out = changed & s->dir_mask; + + if (changed_out) { + for (pin = 0; pin < STM32_GPIO_PIN_COUNT; pin++) { + /* If the value of this pin has changed, then update + * the output IRQ. + */ + if (changed_out & BIT(pin)) { + qemu_set_irq( + /* The "irq_intercept_out" command in the qtest + framework overwrites the out IRQ array in the + NamedGPIOList structure (via the + qemu_irq_intercept_out procedure). So we need + to reference this structure directly (rather than + use our local s->out_irq array) in order for + the unit tests to work. This is something of a hack, + but I don't have a solution yet. */ + s->busdev.parent_obj.gpios.lh_first->out[pin], + (s->GPIOx_ODR & BIT(pin)) ? 1 : 0); + } + } + } +} + +static uint64_t stm32_gpio_read(void *opaque, hwaddr offset, + unsigned size) +{ + Stm32Gpio *s = (Stm32Gpio *)opaque; + + assert(size == 4); + + switch (offset) { + case GPIOx_CRL_OFFSET: + return s->GPIOx_CRy[0]; + case GPIOx_CRH_OFFSET: + return s->GPIOx_CRy[1]; + case GPIOx_IDR_OFFSET: + return s->in; + case GPIOx_ODR_OFFSET: + return s->GPIOx_ODR; + case GPIOx_BSRR_OFFSET: + STM32_WARN_WO_REG(offset); + return 0; + case GPIOx_BRR_OFFSET: + STM32_WARN_WO_REG(offset); + return 0; + case GPIOx_LCKR_OFFSET: + /* Locking is not yet implemented */ + return 0; + default: + STM32_BAD_REG(offset, size); + return 0; + } +} + +static void stm32_gpio_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + uint32_t set_mask, reset_mask; + Stm32Gpio *s = (Stm32Gpio *)opaque; + + assert(size == 4); + + stm32_rcc_check_periph_clk((Stm32Rcc *)s->stm32_rcc, s->periph); + + switch (offset) { + case GPIOx_CRL_OFFSET: + s->GPIOx_CRy[0] = value; + stm32_gpio_update_dir(s, 0); + break; + case GPIOx_CRH_OFFSET: + s->GPIOx_CRy[1] = value; + stm32_gpio_update_dir(s, 1); + break; + case GPIOx_IDR_OFFSET: + STM32_WARN_RO_REG(offset); + break; + case GPIOx_ODR_OFFSET: + stm32_gpio_GPIOx_ODR_write(s, value); + break; + case GPIOx_BSRR_OFFSET: + /* Setting a bit sets or resets the corresponding bit in the output + * register. The lower 16 bits perform resets, and the upper 16 + * bits perform sets. Register is write-only and so does not need + * to store a value. Sets take priority over resets, so we do + * resets first. + */ + set_mask = value & 0x0000ffff; + reset_mask = ~(value >> 16) & 0x0000ffff; + stm32_gpio_GPIOx_ODR_write(s, + (s->GPIOx_ODR & reset_mask) | set_mask); + break; + case GPIOx_BRR_OFFSET: + /* Setting a bit resets the corresponding bit in the output + * register. Register is write-only and so does not need to store + * a value. */ + reset_mask = ~value & 0x0000ffff; + stm32_gpio_GPIOx_ODR_write(s, s->GPIOx_ODR & reset_mask); + break; + case GPIOx_LCKR_OFFSET: + /* Locking is not implemented */ + STM32_NOT_IMPL_REG(offset, size); + break; + default: + STM32_BAD_REG(offset, size); + break; + } +} + +static const MemoryRegionOps stm32_gpio_ops = { + .read = stm32_gpio_read, + .write = stm32_gpio_write, + .valid.min_access_size = 4, + .valid.max_access_size = 4, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void stm32_gpio_reset(DeviceState *dev) +{ + int pin; + Stm32Gpio *s = STM32_GPIO(dev); + + s->GPIOx_CRy[0] = 0x44444444; + s->GPIOx_CRy[1] = 0x44444444; + s->GPIOx_ODR = 0; + s->dir_mask = 0; /* input = 0, output = 1 */ + + for(pin = 0; pin < STM32_GPIO_PIN_COUNT; pin++) { + qemu_irq_lower(s->out_irq[pin]); + } + + /* Leave input state as it is - only outputs and config are affected + * by the GPIO reset. */ +} + + + + + + +/* PUBLIC FUNCTIONS */ + +uint8_t stm32_gpio_get_config_bits(Stm32Gpio *s, unsigned pin) { + return (stm32_gpio_get_pin_config(s, pin) >> 2) & 0x3; +} + +uint8_t stm32_gpio_get_mode_bits(Stm32Gpio *s, unsigned pin) { + return stm32_gpio_get_pin_config(s, pin) & 0x3; +} + + + + + + +/* DEVICE INITIALIZATION */ + +static int stm32_gpio_init(SysBusDevice *dev) +{ + unsigned pin; + Stm32Gpio *s = STM32_GPIO(dev); + + s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; + + memory_region_init_io(&s->iomem, OBJECT(s), &stm32_gpio_ops, s, + "gpio", 0x03ff); + sysbus_init_mmio(dev, &s->iomem); + + qdev_init_gpio_in(DEVICE(dev), stm32_gpio_in_trigger, STM32_GPIO_PIN_COUNT); + qdev_init_gpio_out(DEVICE(dev), s->out_irq, STM32_GPIO_PIN_COUNT); + + for(pin = 0; pin < STM32_GPIO_PIN_COUNT; pin++) { + sysbus_init_irq(dev, &s->in_irq[pin]); + } + + return 0; +} + +static Property stm32_gpio_properties[] = { + DEFINE_PROP_PERIPH_T("periph", Stm32Gpio, periph, STM32_PERIPH_UNDEFINED), + DEFINE_PROP_PTR("stm32_rcc", Stm32Gpio, stm32_rcc_prop), + DEFINE_PROP_END_OF_LIST() +}; + +static void stm32_gpio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stm32_gpio_init; + dc->reset = stm32_gpio_reset; + dc->props = stm32_gpio_properties; +} + +static TypeInfo stm32_gpio_info = { + .name = TYPE_STM32_GPIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(Stm32Gpio), + .class_init = stm32_gpio_class_init +}; + +static void stm32_gpio_register_types(void) +{ + type_register_static(&stm32_gpio_info); +} + +type_init(stm32_gpio_register_types) diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c new file mode 100644 index 0000000000000..07d36ca169df5 --- /dev/null +++ b/hw/i386/kvm/pci-assign.c @@ -0,0 +1,1901 @@ +/* + * Copyright (c) 2007, Neocleus Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * + * Assign a PCI device from the host to a guest VM. + * + * This implementation uses the classic device assignment interface of KVM + * and is only available on x86 hosts. It is expected to be obsoleted by VFIO + * based device assignment. + * + * Adapted for KVM (qemu-kvm) by Qumranet. QEMU version was based on qemu-kvm + * revision 4144fe9d48. See its repository for the history. + * + * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) + * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) + * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) + * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) + * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) + */ +#include +#include +#include +#include +#include +#include "hw/hw.h" +#include "hw/i386/pc.h" +#include "qemu/error-report.h" +#include "ui/console.h" +#include "hw/loader.h" +#include "monitor/monitor.h" +#include "qemu/range.h" +#include "sysemu/sysemu.h" +#include "hw/pci/pci.h" +#include "hw/pci/msi.h" +#include "kvm_i386.h" +#include "hw/pci/pci-assign.h" + +#define MSIX_PAGE_SIZE 0x1000 + +/* From linux/ioport.h */ +#define IORESOURCE_IO 0x00000100 /* Resource type */ +#define IORESOURCE_MEM 0x00000200 +#define IORESOURCE_IRQ 0x00000400 +#define IORESOURCE_DMA 0x00000800 +#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */ +#define IORESOURCE_MEM_64 0x00100000 + +typedef struct PCIRegion { + int type; /* Memory or port I/O */ + int valid; + uint64_t base_addr; + uint64_t size; /* size of the region */ + int resource_fd; +} PCIRegion; + +typedef struct PCIDevRegions { + uint8_t bus, dev, func; /* Bus inside domain, device and function */ + int irq; /* IRQ number */ + uint16_t region_number; /* number of active regions */ + + /* Port I/O or MMIO Regions */ + PCIRegion regions[PCI_NUM_REGIONS - 1]; + int config_fd; +} PCIDevRegions; + +typedef struct AssignedDevRegion { + MemoryRegion container; + MemoryRegion real_iomem; + union { + uint8_t *r_virtbase; /* mmapped access address for memory regions */ + uint32_t r_baseport; /* the base guest port for I/O regions */ + } u; + pcibus_t e_size; /* emulated size of region in bytes */ + pcibus_t r_size; /* real size of region in bytes */ + PCIRegion *region; +} AssignedDevRegion; + +#define ASSIGNED_DEVICE_PREFER_MSI_BIT 0 +#define ASSIGNED_DEVICE_SHARE_INTX_BIT 1 + +#define ASSIGNED_DEVICE_PREFER_MSI_MASK (1 << ASSIGNED_DEVICE_PREFER_MSI_BIT) +#define ASSIGNED_DEVICE_SHARE_INTX_MASK (1 << ASSIGNED_DEVICE_SHARE_INTX_BIT) + +typedef struct MSIXTableEntry { + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t data; + uint32_t ctrl; +} MSIXTableEntry; + +typedef enum AssignedIRQType { + ASSIGNED_IRQ_NONE = 0, + ASSIGNED_IRQ_INTX_HOST_INTX, + ASSIGNED_IRQ_INTX_HOST_MSI, + ASSIGNED_IRQ_MSI, + ASSIGNED_IRQ_MSIX +} AssignedIRQType; + +typedef struct AssignedDevice { + PCIDevice dev; + PCIHostDeviceAddress host; + uint32_t dev_id; + uint32_t features; + int intpin; + AssignedDevRegion v_addrs[PCI_NUM_REGIONS - 1]; + PCIDevRegions real_device; + PCIINTxRoute intx_route; + AssignedIRQType assigned_irq_type; + struct { +#define ASSIGNED_DEVICE_CAP_MSI (1 << 0) +#define ASSIGNED_DEVICE_CAP_MSIX (1 << 1) + uint32_t available; +#define ASSIGNED_DEVICE_MSI_ENABLED (1 << 0) +#define ASSIGNED_DEVICE_MSIX_ENABLED (1 << 1) +#define ASSIGNED_DEVICE_MSIX_MASKED (1 << 2) + uint32_t state; + } cap; + uint8_t emulate_config_read[PCI_CONFIG_SPACE_SIZE]; + uint8_t emulate_config_write[PCI_CONFIG_SPACE_SIZE]; + int msi_virq_nr; + int *msi_virq; + MSIXTableEntry *msix_table; + hwaddr msix_table_addr; + uint16_t msix_max; + MemoryRegion mmio; + char *configfd_name; + int32_t bootindex; +} AssignedDevice; + +#define TYPE_PCI_ASSIGN "kvm-pci-assign" +#define PCI_ASSIGN(obj) OBJECT_CHECK(AssignedDevice, (obj), TYPE_PCI_ASSIGN) + +static void assigned_dev_update_irq_routing(PCIDevice *dev); + +static void assigned_dev_load_option_rom(AssignedDevice *dev); + +static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev); + +static uint64_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region, + hwaddr addr, int size, + uint64_t *data) +{ + uint64_t val = 0; + int fd = dev_region->region->resource_fd; + + if (data) { + DEBUG("pwrite data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx + ", addr="TARGET_FMT_plx"\n", *data, size, addr, addr); + if (pwrite(fd, data, size, addr) != size) { + error_report("%s - pwrite failed %s", __func__, strerror(errno)); + } + } else { + if (pread(fd, &val, size, addr) != size) { + error_report("%s - pread failed %s", __func__, strerror(errno)); + val = (1UL << (size * 8)) - 1; + } + DEBUG("pread val=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx + ", addr=" TARGET_FMT_plx "\n", val, size, addr, addr); + } + return val; +} + +static void assigned_dev_ioport_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + assigned_dev_ioport_rw(opaque, addr, size, &data); +} + +static uint64_t assigned_dev_ioport_read(void *opaque, + hwaddr addr, unsigned size) +{ + return assigned_dev_ioport_rw(opaque, addr, size, NULL); +} + +static uint32_t slow_bar_readb(void *opaque, hwaddr addr) +{ + AssignedDevRegion *d = opaque; + uint8_t *in = d->u.r_virtbase + addr; + uint32_t r; + + r = *in; + DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r); + + return r; +} + +static uint32_t slow_bar_readw(void *opaque, hwaddr addr) +{ + AssignedDevRegion *d = opaque; + uint16_t *in = (uint16_t *)(d->u.r_virtbase + addr); + uint32_t r; + + r = *in; + DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r); + + return r; +} + +static uint32_t slow_bar_readl(void *opaque, hwaddr addr) +{ + AssignedDevRegion *d = opaque; + uint32_t *in = (uint32_t *)(d->u.r_virtbase + addr); + uint32_t r; + + r = *in; + DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r); + + return r; +} + +static void slow_bar_writeb(void *opaque, hwaddr addr, uint32_t val) +{ + AssignedDevRegion *d = opaque; + uint8_t *out = d->u.r_virtbase + addr; + + DEBUG("addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr, val); + *out = val; +} + +static void slow_bar_writew(void *opaque, hwaddr addr, uint32_t val) +{ + AssignedDevRegion *d = opaque; + uint16_t *out = (uint16_t *)(d->u.r_virtbase + addr); + + DEBUG("addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr, val); + *out = val; +} + +static void slow_bar_writel(void *opaque, hwaddr addr, uint32_t val) +{ + AssignedDevRegion *d = opaque; + uint32_t *out = (uint32_t *)(d->u.r_virtbase + addr); + + DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, val); + *out = val; +} + +static const MemoryRegionOps slow_bar_ops = { + .old_mmio = { + .read = { slow_bar_readb, slow_bar_readw, slow_bar_readl, }, + .write = { slow_bar_writeb, slow_bar_writew, slow_bar_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num, + pcibus_t e_size) +{ + AssignedDevice *r_dev = PCI_ASSIGN(pci_dev); + AssignedDevRegion *region = &r_dev->v_addrs[region_num]; + PCIRegion *real_region = &r_dev->real_device.regions[region_num]; + + if (e_size > 0) { + memory_region_init(®ion->container, OBJECT(pci_dev), + "assigned-dev-container", e_size); + memory_region_add_subregion(®ion->container, 0, ®ion->real_iomem); + + /* deal with MSI-X MMIO page */ + if (real_region->base_addr <= r_dev->msix_table_addr && + real_region->base_addr + real_region->size > + r_dev->msix_table_addr) { + uint64_t offset = r_dev->msix_table_addr - real_region->base_addr; + + memory_region_add_subregion_overlap(®ion->container, + offset, + &r_dev->mmio, + 1); + } + } +} + +static const MemoryRegionOps assigned_dev_ioport_ops = { + .read = assigned_dev_ioport_read, + .write = assigned_dev_ioport_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void assigned_dev_ioport_setup(PCIDevice *pci_dev, int region_num, + pcibus_t size) +{ + AssignedDevice *r_dev = PCI_ASSIGN(pci_dev); + AssignedDevRegion *region = &r_dev->v_addrs[region_num]; + + region->e_size = size; + memory_region_init(®ion->container, OBJECT(pci_dev), + "assigned-dev-container", size); + memory_region_init_io(®ion->real_iomem, OBJECT(pci_dev), + &assigned_dev_ioport_ops, r_dev->v_addrs + region_num, + "assigned-dev-iomem", size); + memory_region_add_subregion(®ion->container, 0, ®ion->real_iomem); +} + +static uint32_t assigned_dev_pci_read(PCIDevice *d, int pos, int len) +{ + AssignedDevice *pci_dev = PCI_ASSIGN(d); + uint32_t val; + ssize_t ret; + int fd = pci_dev->real_device.config_fd; + +again: + ret = pread(fd, &val, len, pos); + if (ret != len) { + if ((ret < 0) && (errno == EINTR || errno == EAGAIN)) { + goto again; + } + + hw_error("pci read failed, ret = %zd errno = %d\n", ret, errno); + } + + return val; +} + +static uint8_t assigned_dev_pci_read_byte(PCIDevice *d, int pos) +{ + return (uint8_t)assigned_dev_pci_read(d, pos, 1); +} + +static void assigned_dev_pci_write(PCIDevice *d, int pos, uint32_t val, int len) +{ + AssignedDevice *pci_dev = PCI_ASSIGN(d); + ssize_t ret; + int fd = pci_dev->real_device.config_fd; + +again: + ret = pwrite(fd, &val, len, pos); + if (ret != len) { + if ((ret < 0) && (errno == EINTR || errno == EAGAIN)) { + goto again; + } + + hw_error("pci write failed, ret = %zd errno = %d\n", ret, errno); + } +} + +static void assigned_dev_emulate_config_read(AssignedDevice *dev, + uint32_t offset, uint32_t len) +{ + memset(dev->emulate_config_read + offset, 0xff, len); +} + +static void assigned_dev_direct_config_read(AssignedDevice *dev, + uint32_t offset, uint32_t len) +{ + memset(dev->emulate_config_read + offset, 0, len); +} + +static void assigned_dev_direct_config_write(AssignedDevice *dev, + uint32_t offset, uint32_t len) +{ + memset(dev->emulate_config_write + offset, 0, len); +} + +static uint8_t pci_find_cap_offset(PCIDevice *d, uint8_t cap, uint8_t start) +{ + int id; + int max_cap = 48; + int pos = start ? start : PCI_CAPABILITY_LIST; + int status; + + status = assigned_dev_pci_read_byte(d, PCI_STATUS); + if ((status & PCI_STATUS_CAP_LIST) == 0) { + return 0; + } + + while (max_cap--) { + pos = assigned_dev_pci_read_byte(d, pos); + if (pos < 0x40) { + break; + } + + pos &= ~3; + id = assigned_dev_pci_read_byte(d, pos + PCI_CAP_LIST_ID); + + if (id == 0xff) { + break; + } + if (id == cap) { + return pos; + } + + pos += PCI_CAP_LIST_NEXT; + } + return 0; +} + +static void assigned_dev_register_regions(PCIRegion *io_regions, + unsigned long regions_num, + AssignedDevice *pci_dev, + Error **errp) +{ + uint32_t i; + PCIRegion *cur_region = io_regions; + + for (i = 0; i < regions_num; i++, cur_region++) { + if (!cur_region->valid) { + continue; + } + + /* handle memory io regions */ + if (cur_region->type & IORESOURCE_MEM) { + int t = PCI_BASE_ADDRESS_SPACE_MEMORY; + if (cur_region->type & IORESOURCE_PREFETCH) { + t |= PCI_BASE_ADDRESS_MEM_PREFETCH; + } + if (cur_region->type & IORESOURCE_MEM_64) { + t |= PCI_BASE_ADDRESS_MEM_TYPE_64; + } + + /* map physical memory */ + pci_dev->v_addrs[i].u.r_virtbase = mmap(NULL, cur_region->size, + PROT_WRITE | PROT_READ, + MAP_SHARED, + cur_region->resource_fd, + (off_t)0); + + if (pci_dev->v_addrs[i].u.r_virtbase == MAP_FAILED) { + pci_dev->v_addrs[i].u.r_virtbase = NULL; + error_setg_errno(errp, errno, "Couldn't mmap 0x%" PRIx64 "!", + cur_region->base_addr); + return; + } + + pci_dev->v_addrs[i].r_size = cur_region->size; + pci_dev->v_addrs[i].e_size = 0; + + /* add offset */ + pci_dev->v_addrs[i].u.r_virtbase += + (cur_region->base_addr & 0xFFF); + + if (cur_region->size & 0xFFF) { + error_report("PCI region %d at address 0x%" PRIx64 " has " + "size 0x%" PRIx64 ", which is not a multiple of " + "4K. You might experience some performance hit " + "due to that.", + i, cur_region->base_addr, cur_region->size); + memory_region_init_io(&pci_dev->v_addrs[i].real_iomem, + OBJECT(pci_dev), &slow_bar_ops, + &pci_dev->v_addrs[i], + "assigned-dev-slow-bar", + cur_region->size); + } else { + void *virtbase = pci_dev->v_addrs[i].u.r_virtbase; + char name[32]; + snprintf(name, sizeof(name), "%s.bar%d", + object_get_typename(OBJECT(pci_dev)), i); + memory_region_init_ram_ptr(&pci_dev->v_addrs[i].real_iomem, + OBJECT(pci_dev), name, + cur_region->size, virtbase); + vmstate_register_ram(&pci_dev->v_addrs[i].real_iomem, + &pci_dev->dev.qdev); + } + + assigned_dev_iomem_setup(&pci_dev->dev, i, cur_region->size); + pci_register_bar((PCIDevice *) pci_dev, i, t, + &pci_dev->v_addrs[i].container); + continue; + } else { + /* handle port io regions */ + uint32_t val; + int ret; + + /* Test kernel support for ioport resource read/write. Old + * kernels return EIO. New kernels only allow 1/2/4 byte reads + * so should return EINVAL for a 3 byte read */ + ret = pread(pci_dev->v_addrs[i].region->resource_fd, &val, 3, 0); + if (ret >= 0) { + error_report("Unexpected return from I/O port read: %d", ret); + abort(); + } else if (errno != EINVAL) { + error_report("Kernel doesn't support ioport resource " + "access, hiding this region."); + close(pci_dev->v_addrs[i].region->resource_fd); + cur_region->valid = 0; + continue; + } + + pci_dev->v_addrs[i].u.r_baseport = cur_region->base_addr; + pci_dev->v_addrs[i].r_size = cur_region->size; + pci_dev->v_addrs[i].e_size = 0; + + assigned_dev_ioport_setup(&pci_dev->dev, i, cur_region->size); + pci_register_bar((PCIDevice *) pci_dev, i, + PCI_BASE_ADDRESS_SPACE_IO, + &pci_dev->v_addrs[i].container); + } + } + + /* success */ +} + +static void get_real_id(const char *devpath, const char *idname, uint16_t *val, + Error **errp) +{ + FILE *f; + char name[128]; + long id; + + snprintf(name, sizeof(name), "%s%s", devpath, idname); + f = fopen(name, "r"); + if (f == NULL) { + error_setg_file_open(errp, errno, name); + return; + } + if (fscanf(f, "%li\n", &id) == 1) { + *val = id; + } else { + error_setg(errp, "Failed to parse contents of '%s'", name); + } + fclose(f); +} + +static void get_real_vendor_id(const char *devpath, uint16_t *val, + Error **errp) +{ + get_real_id(devpath, "vendor", val, errp); +} + +static void get_real_device_id(const char *devpath, uint16_t *val, + Error **errp) +{ + get_real_id(devpath, "device", val, errp); +} + +static void get_real_device(AssignedDevice *pci_dev, Error **errp) +{ + char dir[128], name[128]; + int fd, r = 0; + FILE *f; + uint64_t start, end, size, flags; + uint16_t id; + PCIRegion *rp; + PCIDevRegions *dev = &pci_dev->real_device; + Error *local_err = NULL; + + dev->region_number = 0; + + snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/", + pci_dev->host.domain, pci_dev->host.bus, + pci_dev->host.slot, pci_dev->host.function); + + snprintf(name, sizeof(name), "%sconfig", dir); + + if (pci_dev->configfd_name && *pci_dev->configfd_name) { + dev->config_fd = monitor_fd_param(cur_mon, pci_dev->configfd_name, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } else { + dev->config_fd = open(name, O_RDWR); + + if (dev->config_fd == -1) { + error_setg_file_open(errp, errno, name); + return; + } + } +again: + r = read(dev->config_fd, pci_dev->dev.config, + pci_config_size(&pci_dev->dev)); + if (r < 0) { + if (errno == EINTR || errno == EAGAIN) { + goto again; + } + error_setg_errno(errp, errno, "read(\"%s\")", + (pci_dev->configfd_name && *pci_dev->configfd_name) ? + pci_dev->configfd_name : name); + return; + } + + /* Restore or clear multifunction, this is always controlled by qemu */ + if (pci_dev->dev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) { + pci_dev->dev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION; + } else { + pci_dev->dev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION; + } + + /* Clear host resource mapping info. If we choose not to register a + * BAR, such as might be the case with the option ROM, we can get + * confusing, unwritable, residual addresses from the host here. */ + memset(&pci_dev->dev.config[PCI_BASE_ADDRESS_0], 0, 24); + memset(&pci_dev->dev.config[PCI_ROM_ADDRESS], 0, 4); + + snprintf(name, sizeof(name), "%sresource", dir); + + f = fopen(name, "r"); + if (f == NULL) { + error_setg_file_open(errp, errno, name); + return; + } + + for (r = 0; r < PCI_ROM_SLOT; r++) { + if (fscanf(f, "%" SCNi64 " %" SCNi64 " %" SCNi64 "\n", + &start, &end, &flags) != 3) { + break; + } + + rp = dev->regions + r; + rp->valid = 0; + rp->resource_fd = -1; + size = end - start + 1; + flags &= IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH + | IORESOURCE_MEM_64; + if (size == 0 || (flags & ~IORESOURCE_PREFETCH) == 0) { + continue; + } + if (flags & IORESOURCE_MEM) { + flags &= ~IORESOURCE_IO; + } else { + flags &= ~IORESOURCE_PREFETCH; + } + snprintf(name, sizeof(name), "%sresource%d", dir, r); + fd = open(name, O_RDWR); + if (fd == -1) { + continue; + } + rp->resource_fd = fd; + + rp->type = flags; + rp->valid = 1; + rp->base_addr = start; + rp->size = size; + pci_dev->v_addrs[r].region = rp; + DEBUG("region %d size %" PRIu64 " start 0x%" PRIx64 + " type %d resource_fd %d\n", + r, rp->size, start, rp->type, rp->resource_fd); + } + + fclose(f); + + /* read and fill vendor ID */ + get_real_vendor_id(dir, &id, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + pci_dev->dev.config[0] = id & 0xff; + pci_dev->dev.config[1] = (id & 0xff00) >> 8; + + /* read and fill device ID */ + get_real_device_id(dir, &id, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + pci_dev->dev.config[2] = id & 0xff; + pci_dev->dev.config[3] = (id & 0xff00) >> 8; + + pci_word_test_and_clear_mask(pci_dev->emulate_config_write + PCI_COMMAND, + PCI_COMMAND_MASTER | PCI_COMMAND_INTX_DISABLE); + + dev->region_number = r; +} + +static void free_msi_virqs(AssignedDevice *dev) +{ + int i; + + for (i = 0; i < dev->msi_virq_nr; i++) { + if (dev->msi_virq[i] >= 0) { + kvm_irqchip_release_virq(kvm_state, dev->msi_virq[i]); + dev->msi_virq[i] = -1; + } + } + g_free(dev->msi_virq); + dev->msi_virq = NULL; + dev->msi_virq_nr = 0; +} + +static void free_assigned_device(AssignedDevice *dev) +{ + int i; + + if (dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) { + assigned_dev_unregister_msix_mmio(dev); + } + for (i = 0; i < dev->real_device.region_number; i++) { + PCIRegion *pci_region = &dev->real_device.regions[i]; + AssignedDevRegion *region = &dev->v_addrs[i]; + + if (!pci_region->valid) { + continue; + } + if (pci_region->type & IORESOURCE_IO) { + if (region->u.r_baseport) { + memory_region_del_subregion(®ion->container, + ®ion->real_iomem); + } + } else if (pci_region->type & IORESOURCE_MEM) { + if (region->u.r_virtbase) { + memory_region_del_subregion(®ion->container, + ®ion->real_iomem); + + /* Remove MSI-X table subregion */ + if (pci_region->base_addr <= dev->msix_table_addr && + pci_region->base_addr + pci_region->size > + dev->msix_table_addr) { + memory_region_del_subregion(®ion->container, + &dev->mmio); + } + if (munmap(region->u.r_virtbase, + (pci_region->size + 0xFFF) & 0xFFFFF000)) { + error_report("Failed to unmap assigned device region: %s", + strerror(errno)); + } + } + } + if (pci_region->resource_fd >= 0) { + close(pci_region->resource_fd); + } + } + + if (dev->real_device.config_fd >= 0) { + close(dev->real_device.config_fd); + } + + free_msi_virqs(dev); +} + +/* This function tries to determine the cause of the PCI assignment failure. It + * always returns the cause as a dynamically allocated, human readable string. + * If the function fails to determine the cause for any internal reason, then + * the returned string will state that fact. + */ +static char *assign_failed_examine(const AssignedDevice *dev) +{ + char name[PATH_MAX], dir[PATH_MAX], driver[PATH_MAX] = {}, *ns; + uint16_t vendor_id, device_id; + int r; + Error *local_err = NULL; + + snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/", + dev->host.domain, dev->host.bus, dev->host.slot, + dev->host.function); + + snprintf(name, sizeof(name), "%sdriver", dir); + + r = readlink(name, driver, sizeof(driver)); + if ((r <= 0) || r >= sizeof(driver)) { + goto fail; + } + + driver[r] = 0; + ns = strrchr(driver, '/'); + if (!ns) { + goto fail; + } + + ns++; + + if ((get_real_vendor_id(dir, &vendor_id, &local_err), local_err) || + (get_real_device_id(dir, &device_id, &local_err), local_err)) { + /* We're already analyzing an assignment error, so we suppress this + * one just like the others above. + */ + error_free(local_err); + goto fail; + } + + return g_strdup_printf( + "*** The driver '%s' is occupying your device %04x:%02x:%02x.%x.\n" + "***\n" + "*** You can try the following commands to free it:\n" + "***\n" + "*** $ echo \"%04x %04x\" > /sys/bus/pci/drivers/pci-stub/new_id\n" + "*** $ echo \"%04x:%02x:%02x.%x\" > /sys/bus/pci/drivers/%s/unbind\n" + "*** $ echo \"%04x:%02x:%02x.%x\" > /sys/bus/pci/drivers/" + "pci-stub/bind\n" + "*** $ echo \"%04x %04x\" > /sys/bus/pci/drivers/pci-stub/remove_id\n" + "***", + ns, dev->host.domain, dev->host.bus, dev->host.slot, + dev->host.function, vendor_id, device_id, + dev->host.domain, dev->host.bus, dev->host.slot, dev->host.function, + ns, dev->host.domain, dev->host.bus, dev->host.slot, + dev->host.function, vendor_id, device_id); + +fail: + return g_strdup("Couldn't find out why."); +} + +static void assign_device(AssignedDevice *dev, Error **errp) +{ + uint32_t flags = KVM_DEV_ASSIGN_ENABLE_IOMMU; + int r; + + /* Only pass non-zero PCI segment to capable module */ + if (!kvm_check_extension(kvm_state, KVM_CAP_PCI_SEGMENT) && + dev->host.domain) { + error_setg(errp, "Can't assign device inside non-zero PCI segment " + "as this KVM module doesn't support it."); + return; + } + + if (!kvm_check_extension(kvm_state, KVM_CAP_IOMMU)) { + error_setg(errp, "No IOMMU found. Unable to assign device \"%s\"", + dev->dev.qdev.id); + return; + } + + if (dev->features & ASSIGNED_DEVICE_SHARE_INTX_MASK && + kvm_has_intx_set_mask()) { + flags |= KVM_DEV_ASSIGN_PCI_2_3; + } + + r = kvm_device_pci_assign(kvm_state, &dev->host, flags, &dev->dev_id); + if (r < 0) { + switch (r) { + case -EBUSY: { + char *cause; + + cause = assign_failed_examine(dev); + error_setg_errno(errp, -r, "Failed to assign device \"%s\"\n%s", + dev->dev.qdev.id, cause); + g_free(cause); + break; + } + default: + error_setg_errno(errp, -r, "Failed to assign device \"%s\"", + dev->dev.qdev.id); + break; + } + } +} + +static void verify_irqchip_in_kernel(Error **errp) +{ + if (kvm_irqchip_in_kernel()) { + return; + } + error_setg(errp, "pci-assign requires KVM with in-kernel irqchip enabled"); +} + +static int assign_intx(AssignedDevice *dev, Error **errp) +{ + AssignedIRQType new_type; + PCIINTxRoute intx_route; + bool intx_host_msi; + int r; + Error *local_err = NULL; + + /* Interrupt PIN 0 means don't use INTx */ + if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) { + pci_device_set_intx_routing_notifier(&dev->dev, NULL); + return 0; + } + + verify_irqchip_in_kernel(&local_err); + if (local_err) { + error_propagate(errp, local_err); + return -ENOTSUP; + } + + pci_device_set_intx_routing_notifier(&dev->dev, + assigned_dev_update_irq_routing); + + intx_route = pci_device_route_intx_to_irq(&dev->dev, dev->intpin); + assert(intx_route.mode != PCI_INTX_INVERTED); + + if (!pci_intx_route_changed(&dev->intx_route, &intx_route)) { + return 0; + } + + switch (dev->assigned_irq_type) { + case ASSIGNED_IRQ_INTX_HOST_INTX: + case ASSIGNED_IRQ_INTX_HOST_MSI: + intx_host_msi = dev->assigned_irq_type == ASSIGNED_IRQ_INTX_HOST_MSI; + r = kvm_device_intx_deassign(kvm_state, dev->dev_id, intx_host_msi); + break; + case ASSIGNED_IRQ_MSI: + r = kvm_device_msi_deassign(kvm_state, dev->dev_id); + break; + case ASSIGNED_IRQ_MSIX: + r = kvm_device_msix_deassign(kvm_state, dev->dev_id); + break; + default: + r = 0; + break; + } + if (r) { + perror("assign_intx: deassignment of previous interrupt failed"); + } + dev->assigned_irq_type = ASSIGNED_IRQ_NONE; + + if (intx_route.mode == PCI_INTX_DISABLED) { + dev->intx_route = intx_route; + return 0; + } + +retry: + if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK && + dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) { + intx_host_msi = true; + new_type = ASSIGNED_IRQ_INTX_HOST_MSI; + } else { + intx_host_msi = false; + new_type = ASSIGNED_IRQ_INTX_HOST_INTX; + } + + r = kvm_device_intx_assign(kvm_state, dev->dev_id, intx_host_msi, + intx_route.irq); + if (r < 0) { + if (r == -EIO && !(dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK) && + dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) { + /* Retry with host-side MSI. There might be an IRQ conflict and + * either the kernel or the device doesn't support sharing. */ + error_report("Host-side INTx sharing not supported, " + "using MSI instead"); + error_printf("Some devices do not work properly in this mode.\n"); + dev->features |= ASSIGNED_DEVICE_PREFER_MSI_MASK; + goto retry; + } + error_setg_errno(errp, -r, + "Failed to assign irq for \"%s\"\n" + "Perhaps you are assigning a device " + "that shares an IRQ with another device?", + dev->dev.qdev.id); + return r; + } + + dev->intx_route = intx_route; + dev->assigned_irq_type = new_type; + return r; +} + +static void deassign_device(AssignedDevice *dev) +{ + int r; + + r = kvm_device_pci_deassign(kvm_state, dev->dev_id); + assert(r == 0); +} + +/* The pci config space got updated. Check if irq numbers have changed + * for our devices + */ +static void assigned_dev_update_irq_routing(PCIDevice *dev) +{ + AssignedDevice *assigned_dev = PCI_ASSIGN(dev); + Error *err = NULL; + int r; + + r = assign_intx(assigned_dev, &err); + if (r < 0) { + error_report_err(err); + err = NULL; + qdev_unplug(&dev->qdev, &err); + assert(!err); + } +} + +static void assigned_dev_update_msi(PCIDevice *pci_dev) +{ + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); + uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + + PCI_MSI_FLAGS); + int r; + + /* Some guests gratuitously disable MSI even if they're not using it, + * try to catch this by only deassigning irqs if the guest is using + * MSI or intends to start. */ + if (assigned_dev->assigned_irq_type == ASSIGNED_IRQ_MSI || + (ctrl_byte & PCI_MSI_FLAGS_ENABLE)) { + r = kvm_device_msi_deassign(kvm_state, assigned_dev->dev_id); + /* -ENXIO means no assigned irq */ + if (r && r != -ENXIO) { + perror("assigned_dev_update_msi: deassign irq"); + } + + free_msi_virqs(assigned_dev); + + assigned_dev->assigned_irq_type = ASSIGNED_IRQ_NONE; + pci_device_set_intx_routing_notifier(pci_dev, NULL); + } + + if (ctrl_byte & PCI_MSI_FLAGS_ENABLE) { + MSIMessage msg = msi_get_message(pci_dev, 0); + int virq; + + virq = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev); + if (virq < 0) { + perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route"); + return; + } + + assigned_dev->msi_virq = g_malloc(sizeof(*assigned_dev->msi_virq)); + assigned_dev->msi_virq_nr = 1; + assigned_dev->msi_virq[0] = virq; + if (kvm_device_msi_assign(kvm_state, assigned_dev->dev_id, virq) < 0) { + perror("assigned_dev_update_msi: kvm_device_msi_assign"); + } + + assigned_dev->intx_route.mode = PCI_INTX_DISABLED; + assigned_dev->intx_route.irq = -1; + assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSI; + } else { + Error *local_err = NULL; + + assign_intx(assigned_dev, &local_err); + if (local_err) { + error_report_err(local_err); + } + } +} + +static void assigned_dev_update_msi_msg(PCIDevice *pci_dev) +{ + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); + uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + + PCI_MSI_FLAGS); + + if (assigned_dev->assigned_irq_type != ASSIGNED_IRQ_MSI || + !(ctrl_byte & PCI_MSI_FLAGS_ENABLE)) { + return; + } + + kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0], + msi_get_message(pci_dev, 0), pci_dev); +} + +static bool assigned_dev_msix_masked(MSIXTableEntry *entry) +{ + return (entry->ctrl & cpu_to_le32(0x1)) != 0; +} + +/* + * When MSI-X is first enabled the vector table typically has all the + * vectors masked, so we can't use that as the obvious test to figure out + * how many vectors to initially enable. Instead we look at the data field + * because this is what worked for pci-assign for a long time. This makes + * sure the physical MSI-X state tracks the guest's view, which is important + * for some VF/PF and PF/fw communication channels. + */ +static bool assigned_dev_msix_skipped(MSIXTableEntry *entry) +{ + return !entry->data; +} + +static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) +{ + AssignedDevice *adev = PCI_ASSIGN(pci_dev); + uint16_t entries_nr = 0; + int i, r = 0; + MSIXTableEntry *entry = adev->msix_table; + MSIMessage msg; + + /* Get the usable entry number for allocating */ + for (i = 0; i < adev->msix_max; i++, entry++) { + if (assigned_dev_msix_skipped(entry)) { + continue; + } + entries_nr++; + } + + DEBUG("MSI-X entries: %d\n", entries_nr); + + /* It's valid to enable MSI-X with all entries masked */ + if (!entries_nr) { + return 0; + } + + r = kvm_device_msix_init_vectors(kvm_state, adev->dev_id, entries_nr); + if (r != 0) { + error_report("fail to set MSI-X entry number for MSIX! %s", + strerror(-r)); + return r; + } + + free_msi_virqs(adev); + + adev->msi_virq_nr = adev->msix_max; + adev->msi_virq = g_malloc(adev->msix_max * sizeof(*adev->msi_virq)); + + entry = adev->msix_table; + for (i = 0; i < adev->msix_max; i++, entry++) { + adev->msi_virq[i] = -1; + + if (assigned_dev_msix_skipped(entry)) { + continue; + } + + msg.address = entry->addr_lo | ((uint64_t)entry->addr_hi << 32); + msg.data = entry->data; + r = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev); + if (r < 0) { + return r; + } + adev->msi_virq[i] = r; + + DEBUG("MSI-X vector %d, gsi %d, addr %08x_%08x, data %08x\n", i, + r, entry->addr_hi, entry->addr_lo, entry->data); + + r = kvm_device_msix_set_vector(kvm_state, adev->dev_id, i, + adev->msi_virq[i]); + if (r) { + error_report("fail to set MSI-X entry! %s", strerror(-r)); + break; + } + } + + return r; +} + +static void assigned_dev_update_msix(PCIDevice *pci_dev) +{ + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); + uint16_t ctrl_word = pci_get_word(pci_dev->config + pci_dev->msix_cap + + PCI_MSIX_FLAGS); + int r; + + /* Some guests gratuitously disable MSIX even if they're not using it, + * try to catch this by only deassigning irqs if the guest is using + * MSIX or intends to start. */ + if ((assigned_dev->assigned_irq_type == ASSIGNED_IRQ_MSIX) || + (ctrl_word & PCI_MSIX_FLAGS_ENABLE)) { + r = kvm_device_msix_deassign(kvm_state, assigned_dev->dev_id); + /* -ENXIO means no assigned irq */ + if (r && r != -ENXIO) { + perror("assigned_dev_update_msix: deassign irq"); + } + + free_msi_virqs(assigned_dev); + + assigned_dev->assigned_irq_type = ASSIGNED_IRQ_NONE; + pci_device_set_intx_routing_notifier(pci_dev, NULL); + } + + if (ctrl_word & PCI_MSIX_FLAGS_ENABLE) { + if (assigned_dev_update_msix_mmio(pci_dev) < 0) { + perror("assigned_dev_update_msix_mmio"); + return; + } + + if (assigned_dev->msi_virq_nr > 0) { + if (kvm_device_msix_assign(kvm_state, assigned_dev->dev_id) < 0) { + perror("assigned_dev_enable_msix: assign irq"); + return; + } + } + assigned_dev->intx_route.mode = PCI_INTX_DISABLED; + assigned_dev->intx_route.irq = -1; + assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSIX; + } else { + Error *local_err = NULL; + + assign_intx(assigned_dev, &local_err); + if (local_err) { + error_report_err(local_err); + } + } +} + +static uint32_t assigned_dev_pci_read_config(PCIDevice *pci_dev, + uint32_t address, int len) +{ + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); + uint32_t virt_val = pci_default_read_config(pci_dev, address, len); + uint32_t real_val, emulate_mask, full_emulation_mask; + + emulate_mask = 0; + memcpy(&emulate_mask, assigned_dev->emulate_config_read + address, len); + emulate_mask = le32_to_cpu(emulate_mask); + + full_emulation_mask = 0xffffffff >> (32 - len * 8); + + if (emulate_mask != full_emulation_mask) { + real_val = assigned_dev_pci_read(pci_dev, address, len); + return (virt_val & emulate_mask) | (real_val & ~emulate_mask); + } else { + return virt_val; + } +} + +static void assigned_dev_pci_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) +{ + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); + uint16_t old_cmd = pci_get_word(pci_dev->config + PCI_COMMAND); + uint32_t emulate_mask, full_emulation_mask; + int ret; + + pci_default_write_config(pci_dev, address, val, len); + + if (kvm_has_intx_set_mask() && + range_covers_byte(address, len, PCI_COMMAND + 1)) { + bool intx_masked = (pci_get_word(pci_dev->config + PCI_COMMAND) & + PCI_COMMAND_INTX_DISABLE); + + if (intx_masked != !!(old_cmd & PCI_COMMAND_INTX_DISABLE)) { + ret = kvm_device_intx_set_mask(kvm_state, assigned_dev->dev_id, + intx_masked); + if (ret) { + perror("assigned_dev_pci_write_config: set intx mask"); + } + } + } + if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) { + if (range_covers_byte(address, len, + pci_dev->msi_cap + PCI_MSI_FLAGS)) { + assigned_dev_update_msi(pci_dev); + } else if (ranges_overlap(address, len, /* 32bit MSI only */ + pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, 6)) { + assigned_dev_update_msi_msg(pci_dev); + } + } + if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) { + if (range_covers_byte(address, len, + pci_dev->msix_cap + PCI_MSIX_FLAGS + 1)) { + assigned_dev_update_msix(pci_dev); + } + } + + emulate_mask = 0; + memcpy(&emulate_mask, assigned_dev->emulate_config_write + address, len); + emulate_mask = le32_to_cpu(emulate_mask); + + full_emulation_mask = 0xffffffff >> (32 - len * 8); + + if (emulate_mask != full_emulation_mask) { + if (emulate_mask) { + val &= ~emulate_mask; + val |= assigned_dev_pci_read(pci_dev, address, len) & emulate_mask; + } + assigned_dev_pci_write(pci_dev, address, val, len); + } +} + +static void assigned_dev_setup_cap_read(AssignedDevice *dev, uint32_t offset, + uint32_t len) +{ + assigned_dev_direct_config_read(dev, offset, len); + assigned_dev_emulate_config_read(dev, offset + PCI_CAP_LIST_NEXT, 1); +} + +static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp) +{ + AssignedDevice *dev = PCI_ASSIGN(pci_dev); + PCIRegion *pci_region = dev->real_device.regions; + int ret, pos; + Error *local_err = NULL; + + /* Clear initial capabilities pointer and status copied from hw */ + pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0); + pci_set_word(pci_dev->config + PCI_STATUS, + pci_get_word(pci_dev->config + PCI_STATUS) & + ~PCI_STATUS_CAP_LIST); + + /* Expose MSI capability + * MSI capability is the 1st capability in capability config */ + pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0); + if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) { + verify_irqchip_in_kernel(&local_err); + if (local_err) { + error_propagate(errp, local_err); + return -ENOTSUP; + } + dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI; + /* Only 32-bit/no-mask currently supported */ + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSI, pos, 10, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + pci_dev->msi_cap = pos; + + pci_set_word(pci_dev->config + pos + PCI_MSI_FLAGS, + pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS) & + PCI_MSI_FLAGS_QMASK); + pci_set_long(pci_dev->config + pos + PCI_MSI_ADDRESS_LO, 0); + pci_set_word(pci_dev->config + pos + PCI_MSI_DATA_32, 0); + + /* Set writable fields */ + pci_set_word(pci_dev->wmask + pos + PCI_MSI_FLAGS, + PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); + pci_set_long(pci_dev->wmask + pos + PCI_MSI_ADDRESS_LO, 0xfffffffc); + pci_set_word(pci_dev->wmask + pos + PCI_MSI_DATA_32, 0xffff); + } + /* Expose MSI-X capability */ + pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX, 0); + if (pos != 0 && kvm_device_msix_supported(kvm_state)) { + int bar_nr; + uint32_t msix_table_entry; + uint16_t msix_max; + + verify_irqchip_in_kernel(&local_err); + if (local_err) { + error_propagate(errp, local_err); + return -ENOTSUP; + } + dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX; + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSIX, pos, 12, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + pci_dev->msix_cap = pos; + + msix_max = (pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & + PCI_MSIX_FLAGS_QSIZE) + 1; + msix_max = MIN(msix_max, KVM_MAX_MSIX_PER_DEV); + pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, msix_max - 1); + + /* Only enable and function mask bits are writable */ + pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS, + PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); + + msix_table_entry = pci_get_long(pci_dev->config + pos + PCI_MSIX_TABLE); + bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK; + msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK; + dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry; + dev->msix_max = msix_max; + } + + /* Minimal PM support, nothing writable, device appears to NAK changes */ + pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PM, 0); + if (pos) { + uint16_t pmc; + + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + + assigned_dev_setup_cap_read(dev, pos, PCI_PM_SIZEOF); + + pmc = pci_get_word(pci_dev->config + pos + PCI_CAP_FLAGS); + pmc &= (PCI_PM_CAP_VER_MASK | PCI_PM_CAP_DSI); + pci_set_word(pci_dev->config + pos + PCI_CAP_FLAGS, pmc); + + /* assign_device will bring the device up to D0, so we don't need + * to worry about doing that ourselves here. */ + pci_set_word(pci_dev->config + pos + PCI_PM_CTRL, + PCI_PM_CTRL_NO_SOFT_RESET); + + pci_set_byte(pci_dev->config + pos + PCI_PM_PPB_EXTENSIONS, 0); + pci_set_byte(pci_dev->config + pos + PCI_PM_DATA_REGISTER, 0); + } + + pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_EXP, 0); + if (pos) { + uint8_t version, size = 0; + uint16_t type, devctl, lnksta; + uint32_t devcap, lnkcap; + + version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS); + version &= PCI_EXP_FLAGS_VERS; + if (version == 1) { + size = 0x14; + } else if (version == 2) { + /* + * Check for non-std size, accept reduced size to 0x34, + * which is what bcm5761 implemented, violating the + * PCIe v3.0 spec that regs should exist and be read as 0, + * not optionally provided and shorten the struct size. + */ + size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - pos); + if (size < 0x34) { + error_setg(errp, "Invalid size PCIe cap-id 0x%x", + PCI_CAP_ID_EXP); + return -EINVAL; + } else if (size != 0x3c) { + error_report("WARNING, %s: PCIe cap-id 0x%x has " + "non-standard size 0x%x; std size should be 0x3c", + __func__, PCI_CAP_ID_EXP, size); + } + } else if (version == 0) { + uint16_t vid, did; + vid = pci_get_word(pci_dev->config + PCI_VENDOR_ID); + did = pci_get_word(pci_dev->config + PCI_DEVICE_ID); + if (vid == PCI_VENDOR_ID_INTEL && did == 0x10ed) { + /* + * quirk for Intel 82599 VF with invalid PCIe capability + * version, should really be version 2 (same as PF) + */ + size = 0x3c; + } + } + + if (size == 0) { + error_setg(errp, "Unsupported PCI express capability version %d", + version); + return -EINVAL; + } + + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_EXP, pos, size, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + + assigned_dev_setup_cap_read(dev, pos, size); + + type = pci_get_word(pci_dev->config + pos + PCI_EXP_FLAGS); + type = (type & PCI_EXP_FLAGS_TYPE) >> 4; + if (type != PCI_EXP_TYPE_ENDPOINT && + type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) { + error_setg(errp, "Device assignment only supports endpoint " + "assignment, device type %d", type); + return -EINVAL; + } + + /* capabilities, pass existing read-only copy + * PCI_EXP_FLAGS_IRQ: updated by hardware, should be direct read */ + + /* device capabilities: hide FLR */ + devcap = pci_get_long(pci_dev->config + pos + PCI_EXP_DEVCAP); + devcap &= ~PCI_EXP_DEVCAP_FLR; + pci_set_long(pci_dev->config + pos + PCI_EXP_DEVCAP, devcap); + + /* device control: clear all error reporting enable bits, leaving + * only a few host values. Note, these are + * all writable, but not passed to hw. + */ + devctl = pci_get_word(pci_dev->config + pos + PCI_EXP_DEVCTL); + devctl = (devctl & (PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_PAYLOAD)) | + PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN; + pci_set_word(pci_dev->config + pos + PCI_EXP_DEVCTL, devctl); + devctl = PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_AUX_PME; + pci_set_word(pci_dev->wmask + pos + PCI_EXP_DEVCTL, ~devctl); + + /* Clear device status */ + pci_set_word(pci_dev->config + pos + PCI_EXP_DEVSTA, 0); + + /* Link capabilities, expose links and latencues, clear reporting */ + lnkcap = pci_get_long(pci_dev->config + pos + PCI_EXP_LNKCAP); + lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW | + PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL | + PCI_EXP_LNKCAP_L1EL); + pci_set_long(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap); + + /* Link control, pass existing read-only copy. Should be writable? */ + + /* Link status, only expose current speed and width */ + lnksta = pci_get_word(pci_dev->config + pos + PCI_EXP_LNKSTA); + lnksta &= (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW); + pci_set_word(pci_dev->config + pos + PCI_EXP_LNKSTA, lnksta); + + if (version >= 2) { + /* Slot capabilities, control, status - not needed for endpoints */ + pci_set_long(pci_dev->config + pos + PCI_EXP_SLTCAP, 0); + pci_set_word(pci_dev->config + pos + PCI_EXP_SLTCTL, 0); + pci_set_word(pci_dev->config + pos + PCI_EXP_SLTSTA, 0); + + /* Root control, capabilities, status - not needed for endpoints */ + pci_set_word(pci_dev->config + pos + PCI_EXP_RTCTL, 0); + pci_set_word(pci_dev->config + pos + PCI_EXP_RTCAP, 0); + pci_set_long(pci_dev->config + pos + PCI_EXP_RTSTA, 0); + + /* Device capabilities/control 2, pass existing read-only copy */ + /* Link control 2, pass existing read-only copy */ + } + } + + pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PCIX, 0); + if (pos) { + uint16_t cmd; + uint32_t status; + + /* Only expose the minimum, 8 byte capability */ + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PCIX, pos, 8, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + + assigned_dev_setup_cap_read(dev, pos, 8); + + /* Command register, clear upper bits, including extended modes */ + cmd = pci_get_word(pci_dev->config + pos + PCI_X_CMD); + cmd &= (PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO | PCI_X_CMD_MAX_READ | + PCI_X_CMD_MAX_SPLIT); + pci_set_word(pci_dev->config + pos + PCI_X_CMD, cmd); + + /* Status register, update with emulated PCI bus location, clear + * error bits, leave the rest. */ + status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS); + status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN); + status |= pci_requester_id(pci_dev); + status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL | + PCI_X_STATUS_SPL_ERR); + pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status); + } + + pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0); + if (pos) { + /* Direct R/W passthrough */ + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VPD, pos, 8, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + + assigned_dev_setup_cap_read(dev, pos, 8); + + /* direct write for cap content */ + assigned_dev_direct_config_write(dev, pos + 2, 6); + } + + /* Devices can have multiple vendor capabilities, get them all */ + for (pos = 0; (pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VNDR, pos)); + pos += PCI_CAP_LIST_NEXT) { + uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS); + /* Direct R/W passthrough */ + ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VNDR, pos, len, + &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return ret; + } + + assigned_dev_setup_cap_read(dev, pos, len); + + /* direct write for cap content */ + assigned_dev_direct_config_write(dev, pos + 2, len - 2); + } + + /* If real and virtual capability list status bits differ, virtualize the + * access. */ + if ((pci_get_word(pci_dev->config + PCI_STATUS) & PCI_STATUS_CAP_LIST) != + (assigned_dev_pci_read_byte(pci_dev, PCI_STATUS) & + PCI_STATUS_CAP_LIST)) { + dev->emulate_config_read[PCI_STATUS] |= PCI_STATUS_CAP_LIST; + } + + return 0; +} + +static uint64_t +assigned_dev_msix_mmio_read(void *opaque, hwaddr addr, + unsigned size) +{ + AssignedDevice *adev = opaque; + uint64_t val; + + memcpy(&val, (void *)((uint8_t *)adev->msix_table + addr), size); + + return val; +} + +static void assigned_dev_msix_mmio_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + AssignedDevice *adev = opaque; + PCIDevice *pdev = &adev->dev; + uint16_t ctrl; + MSIXTableEntry orig; + int i = addr >> 4; + + if (i >= adev->msix_max) { + return; /* Drop write */ + } + + ctrl = pci_get_word(pdev->config + pdev->msix_cap + PCI_MSIX_FLAGS); + + DEBUG("write to MSI-X table offset 0x%lx, val 0x%lx\n", addr, val); + + if (ctrl & PCI_MSIX_FLAGS_ENABLE) { + orig = adev->msix_table[i]; + } + + memcpy((uint8_t *)adev->msix_table + addr, &val, size); + + if (ctrl & PCI_MSIX_FLAGS_ENABLE) { + MSIXTableEntry *entry = &adev->msix_table[i]; + + if (!assigned_dev_msix_masked(&orig) && + assigned_dev_msix_masked(entry)) { + /* + * Vector masked, disable it + * + * XXX It's not clear if we can or should actually attempt + * to mask or disable the interrupt. KVM doesn't have + * support for pending bits and kvm_assign_set_msix_entry + * doesn't modify the device hardware mask. Interrupts + * while masked are simply not injected to the guest, so + * are lost. Can we get away with always injecting an + * interrupt on unmask? + */ + } else if (assigned_dev_msix_masked(&orig) && + !assigned_dev_msix_masked(entry)) { + /* Vector unmasked */ + if (i >= adev->msi_virq_nr || adev->msi_virq[i] < 0) { + /* Previously unassigned vector, start from scratch */ + assigned_dev_update_msix(pdev); + return; + } else { + /* Update an existing, previously masked vector */ + MSIMessage msg; + int ret; + + msg.address = entry->addr_lo | + ((uint64_t)entry->addr_hi << 32); + msg.data = entry->data; + + ret = kvm_irqchip_update_msi_route(kvm_state, + adev->msi_virq[i], msg, + pdev); + if (ret) { + error_report("Error updating irq routing entry (%d)", ret); + } + } + } + } +} + +static const MemoryRegionOps assigned_dev_msix_mmio_ops = { + .read = assigned_dev_msix_mmio_read, + .write = assigned_dev_msix_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, +}; + +static void assigned_dev_msix_reset(AssignedDevice *dev) +{ + MSIXTableEntry *entry; + int i; + + if (!dev->msix_table) { + return; + } + + memset(dev->msix_table, 0, MSIX_PAGE_SIZE); + + for (i = 0, entry = dev->msix_table; i < dev->msix_max; i++, entry++) { + entry->ctrl = cpu_to_le32(0x1); /* Masked */ + } +} + +static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp) +{ + dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); + if (dev->msix_table == MAP_FAILED) { + error_setg_errno(errp, errno, "failed to allocate msix_table"); + dev->msix_table = NULL; + return; + } + + assigned_dev_msix_reset(dev); + + memory_region_init_io(&dev->mmio, OBJECT(dev), &assigned_dev_msix_mmio_ops, + dev, "assigned-dev-msix", MSIX_PAGE_SIZE); +} + +static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev) +{ + if (!dev->msix_table) { + return; + } + + if (munmap(dev->msix_table, MSIX_PAGE_SIZE) == -1) { + error_report("error unmapping msix_table! %s", strerror(errno)); + } + dev->msix_table = NULL; +} + +static const VMStateDescription vmstate_assigned_device = { + .name = "pci-assign", + .unmigratable = 1, +}; + +static void reset_assigned_device(DeviceState *dev) +{ + PCIDevice *pci_dev = PCI_DEVICE(dev); + AssignedDevice *adev = PCI_ASSIGN(pci_dev); + char reset_file[64]; + const char reset[] = "1"; + int fd, ret; + + /* + * If a guest is reset without being shutdown, MSI/MSI-X can still + * be running. We want to return the device to a known state on + * reset, so disable those here. We especially do not want MSI-X + * enabled since it lives in MMIO space, which is about to get + * disabled. + */ + if (adev->assigned_irq_type == ASSIGNED_IRQ_MSIX) { + uint16_t ctrl = pci_get_word(pci_dev->config + + pci_dev->msix_cap + PCI_MSIX_FLAGS); + + pci_set_word(pci_dev->config + pci_dev->msix_cap + PCI_MSIX_FLAGS, + ctrl & ~PCI_MSIX_FLAGS_ENABLE); + assigned_dev_update_msix(pci_dev); + } else if (adev->assigned_irq_type == ASSIGNED_IRQ_MSI) { + uint8_t ctrl = pci_get_byte(pci_dev->config + + pci_dev->msi_cap + PCI_MSI_FLAGS); + + pci_set_byte(pci_dev->config + pci_dev->msi_cap + PCI_MSI_FLAGS, + ctrl & ~PCI_MSI_FLAGS_ENABLE); + assigned_dev_update_msi(pci_dev); + } + + snprintf(reset_file, sizeof(reset_file), + "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/reset", + adev->host.domain, adev->host.bus, adev->host.slot, + adev->host.function); + + /* + * Issue a device reset via pci-sysfs. Note that we use write(2) here + * and ignore the return value because some kernels have a bug that + * returns 0 rather than bytes written on success, sending us into an + * infinite retry loop using other write mechanisms. + */ + fd = open(reset_file, O_WRONLY); + if (fd != -1) { + ret = write(fd, reset, strlen(reset)); + (void)ret; + close(fd); + } + + /* + * When a 0 is written to the bus master register, the device is logically + * disconnected from the PCI bus. This avoids further DMA transfers. + */ + assigned_dev_pci_write_config(pci_dev, PCI_COMMAND, 0, 1); +} + +static void assigned_realize(struct PCIDevice *pci_dev, Error **errp) +{ + AssignedDevice *dev = PCI_ASSIGN(pci_dev); + uint8_t e_intx; + int r; + Error *local_err = NULL; + + if (!kvm_enabled()) { + error_setg(&local_err, "pci-assign requires KVM support"); + goto exit_with_error; + } + + if (!dev->host.domain && !dev->host.bus && !dev->host.slot && + !dev->host.function) { + error_setg(&local_err, "no host device specified"); + goto exit_with_error; + } + + /* + * Set up basic config space access control. Will be further refined during + * device initialization. + */ + assigned_dev_emulate_config_read(dev, 0, PCI_CONFIG_SPACE_SIZE); + assigned_dev_direct_config_read(dev, PCI_STATUS, 2); + assigned_dev_direct_config_read(dev, PCI_REVISION_ID, 1); + assigned_dev_direct_config_read(dev, PCI_CLASS_PROG, 3); + assigned_dev_direct_config_read(dev, PCI_CACHE_LINE_SIZE, 1); + assigned_dev_direct_config_read(dev, PCI_LATENCY_TIMER, 1); + assigned_dev_direct_config_read(dev, PCI_BIST, 1); + assigned_dev_direct_config_read(dev, PCI_CARDBUS_CIS, 4); + assigned_dev_direct_config_read(dev, PCI_SUBSYSTEM_VENDOR_ID, 2); + assigned_dev_direct_config_read(dev, PCI_SUBSYSTEM_ID, 2); + assigned_dev_direct_config_read(dev, PCI_CAPABILITY_LIST + 1, 7); + assigned_dev_direct_config_read(dev, PCI_MIN_GNT, 1); + assigned_dev_direct_config_read(dev, PCI_MAX_LAT, 1); + memcpy(dev->emulate_config_write, dev->emulate_config_read, + sizeof(dev->emulate_config_read)); + + get_real_device(dev, &local_err); + if (local_err) { + goto out; + } + + if (assigned_device_pci_cap_init(pci_dev, &local_err) < 0) { + goto out; + } + + /* intercept MSI-X entry page in the MMIO */ + if (dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) { + assigned_dev_register_msix_mmio(dev, &local_err); + if (local_err) { + goto out; + } + } + + /* handle real device's MMIO/PIO BARs */ + assigned_dev_register_regions(dev->real_device.regions, + dev->real_device.region_number, dev, + &local_err); + if (local_err) { + goto out; + } + + /* handle interrupt routing */ + e_intx = dev->dev.config[PCI_INTERRUPT_PIN] - 1; + dev->intpin = e_intx; + dev->intx_route.mode = PCI_INTX_DISABLED; + dev->intx_route.irq = -1; + + /* assign device to guest */ + assign_device(dev, &local_err); + if (local_err) { + goto out; + } + + /* assign legacy INTx to the device */ + r = assign_intx(dev, &local_err); + if (r < 0) { + goto assigned_out; + } + + assigned_dev_load_option_rom(dev); + + return; + +assigned_out: + deassign_device(dev); + +out: + free_assigned_device(dev); + +exit_with_error: + assert(local_err); + error_propagate(errp, local_err); +} + +static void assigned_exitfn(struct PCIDevice *pci_dev) +{ + AssignedDevice *dev = PCI_ASSIGN(pci_dev); + + deassign_device(dev); + free_assigned_device(dev); +} + +static void assigned_dev_instance_init(Object *obj) +{ + PCIDevice *pci_dev = PCI_DEVICE(obj); + AssignedDevice *d = PCI_ASSIGN(pci_dev); + + device_add_bootindex_property(obj, &d->bootindex, + "bootindex", NULL, + &pci_dev->qdev, NULL); +} + +static Property assigned_dev_properties[] = { + DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host), + DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features, + ASSIGNED_DEVICE_PREFER_MSI_BIT, false), + DEFINE_PROP_BIT("share_intx", AssignedDevice, features, + ASSIGNED_DEVICE_SHARE_INTX_BIT, true), + DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name), + DEFINE_PROP_END_OF_LIST(), +}; + +static void assign_class_init(ObjectClass *klass, void *data) +{ + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + + k->realize = assigned_realize; + k->exit = assigned_exitfn; + k->config_read = assigned_dev_pci_read_config; + k->config_write = assigned_dev_pci_write_config; + dc->props = assigned_dev_properties; + dc->vmsd = &vmstate_assigned_device; + dc->reset = reset_assigned_device; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->desc = "KVM-based PCI passthrough"; +} + +static const TypeInfo assign_info = { + .name = TYPE_PCI_ASSIGN, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(AssignedDevice), + .class_init = assign_class_init, + .instance_init = assigned_dev_instance_init, +}; + +static void assign_register_types(void) +{ + type_register_static(&assign_info); +} + +type_init(assign_register_types) + +static void assigned_dev_load_option_rom(AssignedDevice *dev) +{ + int size = 0; + &error_abort); + + pci_assign_dev_load_option_rom(&dev->dev, OBJECT(dev), &size, + dev->host.domain, dev->host.bus, + dev->host.slot, dev->host.function); + + if (!size) { + error_report("pci-assign: Invalid ROM."); + } +} diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5143c516531ec..e190ca281d215 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -662,7 +662,13 @@ void pc_cmos_init(PCMachineState *pcms, object_property_set_link(OBJECT(pcms), OBJECT(s), "rtc_state", &error_abort); +<<<<<<< HEAD set_boot_dev(s, MACHINE(pcms)->boot_order, &error_fatal); +======= + set_boot_dev(s, MACHINE(pcms)->boot_order, &local_err); + if (local_err) { + error_report_err(local_err); +>>>>>>> 919b29ba7d... Pebble Qemu val = 0; val |= 0x02; /* FPU is there */ diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 22dee0e76c628..a25dcdad8e53b 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -71,7 +71,7 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; #endif /* PC hardware initialisation */ -static void pc_init1(MachineState *machine, +static void pc_init1(MachineState *machine) const char *host_type, const char *pci_type) { PCMachineState *pcms = PC_MACHINE(machine); @@ -808,6 +808,196 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2, pc_i440fx_1_0_machine_options); +<<<<<<< HEAD +======= +#define PC_COMPAT_0_15 \ + PC_COMPAT_1_0 + +static void pc_i440fx_0_15_machine_options(MachineClass *m) +{ + pc_i440fx_1_0_machine_options(m); + m->hw_version = "0.15"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_15); +} + +DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2, + pc_i440fx_0_15_machine_options); + + +#define PC_COMPAT_0_14 \ + PC_COMPAT_0_15 \ + {\ + .driver = "virtio-blk-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "virtio-serial-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "virtio-net-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "virtio-balloon-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "qxl",\ + .property = "revision",\ + .value = stringify(2),\ + },{\ + .driver = "qxl-vga",\ + .property = "revision",\ + .value = stringify(2),\ + }, + +static void pc_i440fx_0_14_machine_options(MachineClass *m) +{ + pc_i440fx_0_15_machine_options(m); + m->hw_version = "0.14"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_14); +} + +DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2, + pc_i440fx_0_14_machine_options); + + +#define PC_COMPAT_0_13 \ + PC_COMPAT_0_14 \ + {\ + .driver = TYPE_PCI_DEVICE,\ + .property = "command_serr_enable",\ + .value = "off",\ + },{\ + .driver = "AC97",\ + .property = "use_broken_id",\ + .value = stringify(1),\ + },{\ + .driver = "virtio-9p-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + },{\ + .driver = "VGA",\ + .property = "rombar",\ + .value = stringify(0),\ + },{\ + .driver = "vmware-svga",\ + .property = "rombar",\ + .value = stringify(0),\ + }, + +static void pc_i440fx_0_13_machine_options(MachineClass *m) +{ + pc_i440fx_0_14_machine_options(m); + m->hw_version = "0.13"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_13); +} + +DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13, + pc_i440fx_0_13_machine_options); + + +#define PC_COMPAT_0_12 \ + PC_COMPAT_0_13 \ + {\ + .driver = "virtio-serial-pci",\ + .property = "max_ports",\ + .value = stringify(1),\ + },{\ + .driver = "virtio-serial-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + },{\ + .driver = "usb-mouse",\ + .property = "serial",\ + .value = "1",\ + },{\ + .driver = "usb-tablet",\ + .property = "serial",\ + .value = "1",\ + },{\ + .driver = "usb-kbd",\ + .property = "serial",\ + .value = "1",\ + }, + +static void pc_i440fx_0_12_machine_options(MachineClass *m) +{ + pc_i440fx_0_13_machine_options(m); + m->hw_version = "0.12"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_12); +} + +DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13, + pc_i440fx_0_12_machine_options); + + +#define PC_COMPAT_0_11 \ + PC_COMPAT_0_12 \ + {\ + .driver = "virtio-blk-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + },{\ + .driver = TYPE_PCI_DEVICE,\ + .property = "rombar",\ + .value = stringify(0),\ + },{\ + .driver = "ide-drive",\ + .property = "ver",\ + .value = "0.11",\ + },{\ + .driver = "scsi-disk",\ + .property = "ver",\ + .value = "0.11",\ + }, +static void pc_i440fx_0_11_machine_options(MachineClass *m) +{ + pc_i440fx_0_12_machine_options(m); + m->hw_version = "0.11"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_11); +} + +DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13, + pc_i440fx_0_11_machine_options); + + +#define PC_COMPAT_0_10 \ + PC_COMPAT_0_11 \ + {\ + .driver = "virtio-blk-pci",\ + .property = "class",\ + .value = stringify(PCI_CLASS_STORAGE_OTHER),\ + },{\ + .driver = "virtio-serial-pci",\ + .property = "class",\ + .value = stringify(PCI_CLASS_DISPLAY_OTHER),\ + },{\ + .driver = "virtio-net-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + },{\ + .driver = "ide-drive",\ + .property = "ver",\ + .value = "0.10",\ + },{\ + .driver = "scsi-disk",\ + .property = "ver",\ + .value = "0.10",\ + }, + +static void pc_i440fx_0_10_machine_options(MachineClass *m) +{ + pc_i440fx_0_11_machine_options(m); + m->hw_version = "0.10"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_10); +} + +DEFINE_I440FX_MACHINE(v0_10, "pc-0.10", pc_compat_0_13, + pc_i440fx_0_10_machine_options); + +>>>>>>> 919b29ba7d... Pebble Qemu typedef struct { uint16_t gpu_device_id; uint16_t pch_device_id; @@ -862,7 +1052,6 @@ static const IGDDeviceIDInfo igd_combo_id_infos[] = { {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */ {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */ {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */ -}; static void isa_bridge_class_init(ObjectClass *klass, void *data) { @@ -873,7 +1062,6 @@ static void isa_bridge_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); k->vendor_id = PCI_VENDOR_ID_INTEL; k->class_id = PCI_CLASS_BRIDGE_ISA; -}; static TypeInfo isa_bridge_info = { .name = "igd-passthrough-isa-bridge", @@ -893,6 +1081,10 @@ static void pt_graphics_register_types(void) type_init(pt_graphics_register_types) void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id) + pc_i440fx_0_10_machine_options); + + +static void isapc_machine_options(MachineClass *m) { struct PCIDevice *bridge_dev; int i, num; diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 13d91e109ab3e..7e22fca99b0eb 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -1308,11 +1308,41 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot) trace_handle_cmd_badmap(s, port, cmd_len); goto out; } +<<<<<<< HEAD if (trace_event_get_state_backends(TRACE_HANDLE_CMD_FIS_DUMP)) { char *pretty_fis = ahci_pretty_buffer_fis(cmd_fis, 0x80); trace_handle_cmd_fis_dump(s, port, pretty_fis); g_free(pretty_fis); } +======= + cmd = get_cmd_header(s, port, slot); + /* remember current slot handle for later */ + s->dev[port].cur_cmd = cmd; + + /* The device we are working for */ + ide_state = &s->dev[port].port.ifs[0]; + if (!ide_state->blk) { + DPRINTF(port, "error: guest accessed unused port"); + return -1; + } + + tbl_addr = le64_to_cpu(cmd->tbl_addr); + cmd_len = 0x80; + cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len, + DMA_DIRECTION_FROM_DEVICE); + if (!cmd_fis) { + DPRINTF(port, "error: guest passed us an invalid cmd fis\n"); + return -1; + } else if (cmd_len != 0x80) { + ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR); + DPRINTF(port, "error: dma_memory_map failed: " + "(len(%02"PRIx64") != 0x80)\n", + cmd_len); + goto out; + } + debug_print_fis(cmd_fis, 0x80); + +>>>>>>> 919b29ba7d... Pebble Qemu switch (cmd_fis[0]) { case SATA_FIS_TYPE_REGISTER_H2D: handle_reg_h2d_fis(s, port, slot, cmd_fis); diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index c60dc6b5e6e51..4edc3f71ecf2e 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -32,7 +32,12 @@ /* #define DEBUG_GIC */ #ifdef DEBUG_GIC +<<<<<<< HEAD #define DEBUG_GIC_GATE 1 +======= +#define DPRINTF(fmt, ...) \ +do { printf("DEBUG_GIC: " fmt , ## __VA_ARGS__); usleep(100);} while (0) +>>>>>>> 919b29ba7d... Pebble Qemu #else #define DEBUG_GIC_GATE 0 #endif @@ -459,6 +464,7 @@ static int gic_get_group_priority(GICState *s, int cpu, int irq) assert(bpr >= 0); } else { bpr = s->bpr[cpu]; + return GIC_GET_PRIORITY(irq, cpu); } /* a BPR of 0 means the group priority bits are [7:1]; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 1ad35e55292b7..84945fd0424bf 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -16,6 +16,7 @@ #include "hw/sysbus.h" #include "migration/vmstate.h" #include "qemu/timer.h" +<<<<<<< HEAD #include "hw/intc/armv7m_nvic.h" #include "hw/irq.h" #include "hw/qdev-properties.h" @@ -35,6 +36,57 @@ * and one for the unused exception number 0). * * NVIC_MAX_IRQ is the highest permitted number of external IRQ lines. +======= +#include "hw/arm/arm.h" +#include "exec/address-spaces.h" +#include "gic_internal.h" +#include "sysemu/sysemu.h" + +//#define DEBUG_ARMV7M_NVIC +#ifdef DEBUG_ARMV7M_NVIC + +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("ARMV7M_NVIC: " fmt , ## __VA_ARGS__); \ + /* usleep(1000); */ /* the usleep causes watchdogs :( */ \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + + +typedef struct { + GICState gic; + struct { + uint32_t control; + uint32_t reload; + int64_t tick; + QEMUTimer *timer; + } systick; + uint16_t aircr_reg; /* low word of Application Interrupt and Reset Control Register */ + MemoryRegion sysregmem; + MemoryRegion gic_iomem_alias; + MemoryRegion container; + uint32_t num_irq; + qemu_irq sysresetreq; + uint32_t scr_reg; /* contents of SCR register */ + /* set true if we executed a WFI instruction with the SLEEPDEEP bit set in the SCR */ + bool in_deep_sleep; + // Set true if we execute a WFI instruction with both SLEEPDEEP bit set in the SCR + // and PDDS (Power Down Deep Sleep) bit is set in the PWR_CR register + bool in_standby; + // Properties + void *stm32_pwr_prop; + // output IRQs + qemu_irq cpu_wakeup_out; + qemu_irq power_out; +} nvic_state; + +#define TYPE_NVIC "armv7m_nvic" +/** + * NVICClass: + * @parent_reset: the parent class' reset handler. +>>>>>>> 919b29ba7d... Pebble Qemu * * NVIC_MAX_VECTORS is the highest permitted number of exceptions. * @@ -64,6 +116,7 @@ static const uint8_t nvic_id[] = { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 }; +<<<<<<< HEAD static int nvic_pending_prio(NVICState *s) { /* return the group priority of the current pending interrupt, @@ -143,6 +196,13 @@ static bool exc_is_banked(int exc) exc == ARMV7M_EXCP_PENDSV || exc == ARMV7M_EXCP_SYSTICK; } +======= +/* SCR register definitions */ +#define SCR_REG_SLEEPDEEP 0x00000004 + +/* qemu timers run at 1GHz. We want something closer to 1MHz. */ +#define SYSTICK_SCALE 1000ULL +>>>>>>> 919b29ba7d... Pebble Qemu /* Return a mask word which clears the subpriority bits from * a priority value for an M-profile exception, leaving only @@ -378,6 +438,7 @@ static inline int nvic_exec_prio(NVICState *s) bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure) { +<<<<<<< HEAD /* Return true if the requested execution priority is negative * for the specified security state, ie that security state * has an active NMI or HardFault or has set its FAULTMASK. @@ -390,6 +451,18 @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure) if (s->cpu->env.v7m.faultmask[secure]) { return true; +======= + nvic_state *s = (nvic_state *)opaque; + s->systick.control |= SYSTICK_COUNTFLAG; + if (s->systick.control & SYSTICK_TICKINT) { + if (!s->in_deep_sleep) { + /* NOTE: In deep sleep mode, all peripherals are off (no clocks), so + * no IRQs should be made pending. Eventually, we should gate all + * peripherals according to deep sleep mode, but SysTick is a good + * important start. */ + armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK); + } +>>>>>>> 919b29ba7d... Pebble Qemu } if (secure ? s->sec_vectors[ARMV7M_EXCP_HARD].active : @@ -922,8 +995,34 @@ bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure) vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; +<<<<<<< HEAD return vec->enabled && exc_group_prio(s, vec->prio, secure) < running; +======= +/* Set the base priority */ +void armv7m_nvic_set_base_priority(void *opaque, unsigned int priority) +{ + nvic_state *s = (nvic_state *)opaque; + if (priority == 0) { + s->gic.priority_mask[0] = 0x100; + } else { + /* Pay only attention to the priority group when masking interrupts */ + uint32_t group_setting = (s->aircr_reg >> 8) & 0x03; + uint32_t group_mask = (0x0FF << (group_setting + 1)) & 0x0FF; + s->gic.priority_mask[0] = priority & group_mask; /* TODO: Make this more general */ + } + gic_update(&s->gic); +} + +/* The external routines use the hardware vector numbering, ie. the first + IRQ is #16. The internal GIC routines use #32 as the first IRQ. */ +void armv7m_nvic_set_pending(void *opaque, int irq) +{ + nvic_state *s = (nvic_state *)opaque; + if (irq >= 16) + irq += 16; + gic_set_pending_private(&s->gic, 0, irq); +>>>>>>> 919b29ba7d... Pebble Qemu } /* callback when external interrupt line is changed */ @@ -938,6 +1037,7 @@ static void set_irq_level(void *opaque, int n, int level) trace_nvic_set_irq_level(n, level); +<<<<<<< HEAD /* The pending status of an external interrupt is * latched on rising edge and exception handler return. * @@ -952,6 +1052,28 @@ static void set_irq_level(void *opaque, int n, int level) armv7m_nvic_set_pending(s, n, false); } } +======= + /* We can't be in deep sleep mode anymore because we received an interrupt + * Actually, the correct way to do this to match the hardware exactly would be to fall + * out of deep sleep even if an interrupt is pending - regardless if it is active or + * not or masked due to BASEPRI. This would involved moving this reset of deep sleep + * mode higher up the call chain, perhaps in arm_gic.c, where we get notification of + * interrupts that change to pending state. */ + s->in_deep_sleep = false; + if (s->in_standby) { + qemu_set_irq(s->power_out, true); + s->in_standby = false; + } + + irq = gic_acknowledge_irq(&s->gic, 0, MEMTXATTRS_UNSPECIFIED); + if (irq == 1023) { + hw_error("Interrupt but no vector\n"); + } + if (irq >= 32) { + irq -= 16; + } + return irq; +>>>>>>> 919b29ba7d... Pebble Qemu } /* callback when external NMI line is changed */ @@ -972,7 +1094,46 @@ static void nvic_nmi_trigger(void *opaque, int n, int level) } } +<<<<<<< HEAD static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) +======= +void armv7m_nvic_cpu_executed_wfi(void *opaque) +{ + nvic_state *s = (nvic_state *)opaque; + if ((s->scr_reg & SCR_REG_SLEEPDEEP) != 0) { + s->in_deep_sleep = true; + if (s->stm32_pwr_prop && f2xx_pwr_powerdown_deepsleep(s->stm32_pwr_prop)) { + s->in_standby = true; + // For now, this is an easy way to disable nearly all interrupts from waking up + // the CPU. Technically, this is not correct and we should allow specific ones + // through (some RTC interrupts, etc.). + armv7m_nvic_set_base_priority(opaque, 0x01); + + // Inform peripherals that the power is off + qemu_set_irq(s->power_out, false); + } + } +} + +// ----------------------------------------------------------------------------- +// Called when the WKUP pin changes state (GPIO A0) +static void nvic_wakeup_in_cb(void *opaque, int n, int level) +{ + nvic_state *s = (nvic_state *)opaque; + + // If we are in standby mode, wake up the CPU + if (level && s->in_standby) { + s->in_standby = false; + s->in_deep_sleep = false; + qemu_set_irq(s->power_out, true); + qemu_set_irq(s->cpu_wakeup_out, level); + } else if (!level) { + qemu_set_irq(s->cpu_wakeup_out, level); + } +} + +static uint32_t nvic_readl(nvic_state *s, uint32_t offset) +>>>>>>> 919b29ba7d... Pebble Qemu { ARMCPU *cpu = s->cpu; uint32_t val; @@ -1053,6 +1214,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) /* STTNS: RES0 for the Main Extension */ return val; case 0xd08: /* Vector Table Offset. */ +<<<<<<< HEAD return cpu->env.v7m.vecbase[attrs.secure]; case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */ val = 0xfa050000 | (s->prigroup[attrs.secure] << 8); @@ -1085,6 +1247,19 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { goto bad_offset; } +======= + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.vecbase; + case 0xd0c: /* Application Interrupt/Reset Control. */ + return 0xfa050000 | s->aircr_reg; + case 0xd10: /* System Control. */ + return s->scr_reg; + break; + case 0xd14: /* Configuration Control. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.ccr; + case 0xd24: /* System Handler Status. */ +>>>>>>> 919b29ba7d... Pebble Qemu val = 0; if (attrs.secure) { if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { @@ -1196,6 +1371,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) val |= (1 << 8); } return val; +<<<<<<< HEAD case 0xd2c: /* Hard Fault Status. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; @@ -1221,6 +1397,26 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) /* TODO: Implement fault status registers. */ qemu_log_mask(LOG_UNIMP, "Aux Fault status registers unimplemented\n"); +======= + case 0xd28: /* Configurable Fault Status. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.cfsr; + case 0xd2c: /* Hard Fault Status. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.hfsr; + case 0xd30: /* Debug Fault Status. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.dfsr; + case 0xd34: /* MemManage Address. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.mmfar; + case 0xd38: /* Bus Fault Address. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.bfar; + case 0xd3c: /* Aux Fault Status. */ + /* TODO: Implement fault status registers. */ + qemu_log_mask(LOG_UNIMP, "AUX fault status registers unimplemented\n"); +>>>>>>> 919b29ba7d... Pebble Qemu return 0; case 0xd40: /* PFR0. */ return cpu->id_pfr0; @@ -1247,6 +1443,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) case 0xd6c: /* ISAR3. */ return cpu->isar.id_isar3; case 0xd70: /* ISAR4. */ +<<<<<<< HEAD return cpu->isar.id_isar4; case 0xd74: /* ISAR5. */ return cpu->isar.id_isar5; @@ -1459,6 +1656,42 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) return cpu->isar.mvfr1; case 0xf48: /* MVFR2 */ return cpu->isar.mvfr2; +======= + return 0x01310102; + case 0xd90: /* MPU type register. */ + cpu = ARM_CPU(current_cpu); + return cpu->pmsav7_dregion << 8; + case 0xd94: /* MPU control register. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.v7m.mpu_ctrl; + case 0xd98: /* MPU_RNR. */ + cpu = ARM_CPU(current_cpu); + return cpu->env.cp15.c6_rgnr; + case 0xd9c: /* MPU_RBAR: MPU region base address register. */ + case 0xda4: /* MPU_RBAR_A1. */ + case 0xdac: /* MPU_RBAR_A2. */ + case 0xdb4: /* MPU_RBAR_A3. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + return 0; + } + val = cpu->env.pmsav7.drbar[cpu->env.cp15.c6_rgnr]; + val |= (cpu->env.cp15.c6_rgnr ) & 0xf; + return val; + case 0xda0: /* MPU_RASR: MPU region attribute and size register. */ + case 0xda8: /* MPU_RASR_A1. */ + case 0xdb0: /* MPU_RASR_A2. */ + case 0xdb8: /* MPU_RASR_A3. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + return 0; + } + val = cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr]; + val <<= 16; + val |= cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]; + return val; + /* TODO: Implement debug registers. */ +>>>>>>> 919b29ba7d... Pebble Qemu default: bad_offset: qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); @@ -1885,6 +2118,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, cpu->env.sau.rnr = value; } break; +<<<<<<< HEAD case 0xddc: /* SAU_RBAR */ { int region = cpu->env.sau.rnr; @@ -1894,6 +2128,24 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } if (!attrs.secure) { return; +======= + case 0xd08: /* Vector Table Offset. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.vecbase = value & 0xffffff80; + break; + case 0xd0c: /* Application Interrupt/Reset Control. */ + if ((value >> 16) == 0x05fa) { + if (value & 4) { + qemu_irq_pulse(s->sysresetreq); + } + if (value & 2) { + qemu_log_mask(LOG_UNIMP, "VECTCLRACTIVE unimplemented\n"); + } + if (value & 1) { + qemu_system_reset_request(); + } + s->aircr_reg = value & 0x00700; /* keep only the bits we suport */ +>>>>>>> 919b29ba7d... Pebble Qemu } if (region >= cpu->sau_sregion) { return; @@ -1901,6 +2153,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, cpu->env.sau.rbar[region] = value & ~0x1f; tlb_flush(CPU(cpu)); break; +<<<<<<< HEAD } case 0xde0: /* SAU_RLAR */ { @@ -1917,6 +2170,14 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } cpu->env.sau.rlar[region] = value & ~0x1c; tlb_flush(CPU(cpu)); +======= + case 0xd10: /* System Control. */ + s->scr_reg = value; + break; + case 0xd14: /* Configuration Control. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.ccr = value & CCR_STKALIGN; +>>>>>>> 919b29ba7d... Pebble Qemu break; } case 0xde4: /* SFSR */ @@ -1928,6 +2189,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } cpu->env.v7m.sfsr &= ~value; /* W1C */ break; +<<<<<<< HEAD case 0xde8: /* SFAR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; @@ -1936,6 +2198,104 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, return; } cpu->env.v7m.sfsr = value; +======= + case 0xd28: /* Configurable Fault Status. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.cfsr &= ~value; + DPRINTF("writel:cfsr now: %08X\n", cpu->env.v7m.cfsr); + break; + case 0xd2c: /* Hard Fault Status. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.hfsr &= ~value; + DPRINTF("writel:hfsr now: %08X\n", cpu->env.v7m.hfsr); + break; + case 0xd30: /* Debug Fault Status. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.dfsr &= ~value; + DPRINTF("writel:dfsr now: %08X\n", cpu->env.v7m.dfsr); + break; + case 0xd34: /* Mem Manage Address. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.mmfar = value; + DPRINTF("writel:mmfar now: %08X\n", cpu->env.v7m.mmfar); + break; + case 0xd38: /* Bus Fault Address. */ + cpu = ARM_CPU(current_cpu); + cpu->env.v7m.bfar = value; + DPRINTF("writel:bfar now: %08X\n", cpu->env.v7m.bfar); + break; + case 0xd3c: /* Aux Fault Status. */ + qemu_log_mask(LOG_UNIMP, + "NVIC: AUX fault status registers unimplemented\n"); + break; + case 0xd94: /* MPU control register. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + DPRINTF("writel:mpu_ctrl -- no regions!\n"); + break; + } + cpu->env.v7m.mpu_ctrl = value & 0x7; + if (cpu->env.v7m.mpu_ctrl & MPU_CTRL_ENABLE) { + cpu->env.cp15.sctlr_ns |= SCTLR_M; + } else { + cpu->env.cp15.sctlr_ns &= ~SCTLR_M; + } + /* TODO: mimic MPU_CTRL_HFNMIENA */ + if (cpu->env.v7m.mpu_ctrl & MPU_CTRL_PRIVDEFENA) { + cpu->env.cp15.sctlr_ns |= SCTLR_BR; + } else { + cpu->env.cp15.sctlr_ns &= ~SCTLR_BR; + } + /* This may enable/disable the MMU, so do a TLB flush. */ + DPRINTF("writel:mpu_ctrl now: %08X\n", cpu->env.v7m.mpu_ctrl); + DPRINTF("writel:sctlr_ns now: %016llX\n", cpu->env.cp15.sctlr_ns); + tlb_flush(CPU(cpu), 1); + break; + case 0xd98: /* MPU_RNR. */ + cpu = ARM_CPU(current_cpu); + value &= 0xff; + if (value < cpu->pmsav7_dregion) { + cpu->env.cp15.c6_rgnr = value; + } + DPRINTF("writel:mpu_rnr, region now: %u\n", cpu->env.cp15.c6_rgnr); + break; + case 0xd9c: /* MPU_RBAR: MPU region base address register. */ + case 0xda4: /* MPU_RBAR_A1. */ + case 0xdac: /* MPU_RBAR_A2. */ + case 0xdb4: /* MPU_RBAR_A3. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + DPRINTF("writel:mpu_rbar (%02X) -- no regions!\n", offset); + break; + } + if (value & 0x10) { + /* region update */ + uint32_t region = value & 0x0f; + if (region < cpu->pmsav7_dregion) { + cpu->env.cp15.c6_rgnr = region; + } + DPRINTF("writel:mpu_rbar (%04X), region now: %u\n", offset, cpu->env.cp15.c6_rgnr); + } + value &= ~0x1f; + cpu->env.pmsav7.drbar[cpu->env.cp15.c6_rgnr] = value; + DPRINTF("writel:mpu_rbar (%04X), region(%u) now %08X\n", offset, cpu->env.cp15.c6_rgnr, cpu->env.pmsav7.drbar[cpu->env.cp15.c6_rgnr]); + tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ + break; + case 0xda0: /* MPU_RSAR: MPU region attribute and size register. */ + case 0xda8: /* MPU_RSAR_A1. */ + case 0xdb0: /* MPU_RSAR_A2. */ + case 0xdb8: /* MPU_RSAR_A3. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + DPRINTF("writel:mpu_rsar (%02X) -- no regions!\n", offset); + break; + } + cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr] = value >> 16; + cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr] = value & 0xffff; + DPRINTF("writel:mpu_rsar (%04X), region(%u), dracr now %04X\n", offset, cpu->env.cp15.c6_rgnr, cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr]); + DPRINTF("writel:mpu_rsar (%04X), region(%u), drsr now %04X\n", offset, cpu->env.cp15.c6_rgnr, cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]); + tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ +>>>>>>> 919b29ba7d... Pebble Qemu break; case 0xf00: /* Software Triggered Interrupt Register */ { @@ -2099,6 +2459,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, uint32_t offset = addr; unsigned i, startvec, end; uint32_t val; + ARMCPU *cpu; if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) { /* Generate BusFault for unprivileged accesses */ @@ -2177,6 +2538,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, } val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank)); } +<<<<<<< HEAD break; case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */ if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) { @@ -2196,6 +2558,25 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK; } val = extract32(val, (offset - 0xd28) * 8, size * 8); +======= + return val; + case 0xd28 ... 0xd2b: /* Configurable Fault Status. */ + cpu = ARM_CPU(current_cpu); + return extract32(cpu->env.v7m.cfsr, (offset - 0xd28) * 8, size * 8); + case 0xda0 ... 0xdb7: /* MPU_RSAR and aliases. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + break; + } + if ((size == 2) && (offset & 7) == 0) { + val = cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]; + return val & 0xffff; + } + if ((size == 2) && (offset & 7) == 2) { + val = cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr]; + return val & 0xffff; + } +>>>>>>> 919b29ba7d... Pebble Qemu break; case 0xfe0 ... 0xfff: /* ID. */ if (offset & 3) { @@ -2226,6 +2607,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, { NVICState *s = (NVICState *)opaque; uint32_t offset = addr; +<<<<<<< HEAD unsigned i, startvec, end; unsigned setval = 0; @@ -2235,6 +2617,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, /* Generate BusFault for unprivileged accesses */ return MEMTX_ERROR; } +======= + int i; + ARMCPU *cpu; +>>>>>>> 919b29ba7d... Pebble Qemu switch (offset) { case 0x100 ... 0x13f: /* NVIC Set enable */ @@ -2298,6 +2684,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, } set_prio(s, hdlidx, sbank, newprio); } +<<<<<<< HEAD nvic_irq_update(s); goto exit_ok; case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */ @@ -2323,6 +2710,43 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK); } goto exit_ok; +======= + gic_update(&s->gic); + return; + case 0xd28 ... 0xd2b: /* Configurable Fault Status. */ + if (size == 1) { + value <<= (offset - 0xd28) * 8; + offset &= ~3; + size = 4; + break; + } + if ((size == 2) && ((offset & 1) == 0)) { + value <<= (offset - 0xd28) * 8; + offset &= ~3; + size = 4; + break; + } + break; + case 0xda0 ... 0xdb7: /* MPU_RSAR and aliases. */ + cpu = ARM_CPU(current_cpu); + if (cpu->pmsav7_dregion == 0) { + break; + } + if ((size == 2) && (offset & 7) == 0) { + value |= cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr] << 16; + offset &= ~2; + size = 4; + break; + } + if ((size == 2) && (offset & 7) == 2) { + value <<= 16; + value |= cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]; + offset &= ~2; + size = 4; + break; + } + break; +>>>>>>> 919b29ba7d... Pebble Qemu } if (size == 4) { nvic_writel(s, offset, value, attrs); @@ -2598,6 +3022,7 @@ static void armv7m_nvic_reset(DeviceState *dev) * We updated state that affects the CPU's MMUidx and thus its hflags; * and we can't guarantee that we run before the CPU reset function. */ +<<<<<<< HEAD arm_rebuild_hflags(&s->cpu->env); } @@ -2614,6 +3039,18 @@ static void nvic_systick_trigger(void *opaque, int n, int level) */ armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, n); } +======= + s->gic.cpu_ctlr[0] = GICC_CTLR_EN_GRP0; + s->gic.priority_mask[0] = 0x100; + /* The NVIC as a whole is always enabled. */ + s->gic.ctlr = 1; + systick_reset(s); + + s->scr_reg = 0; + s->in_deep_sleep = false; + s->in_standby = false; + qemu_set_irq(s->power_out, true); +>>>>>>> 919b29ba7d... Pebble Qemu } static void armv7m_nvic_realize(DeviceState *dev, Error **errp) @@ -2702,6 +3139,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s, "nvic_sysregs", 0x1000); memory_region_add_subregion(&s->container, 0, &s->sysregmem); +<<<<<<< HEAD memory_region_init_io(&s->systickmem, OBJECT(s), &nvic_systick_ops, s, @@ -2723,6 +3161,30 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) } sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container); +======= + /* Alias the GIC region so we can get only the section of it + * we need, and layer it on top of the system register region. + */ + memory_region_init_alias(&s->gic_iomem_alias, OBJECT(s), + "nvic-gic", &s->gic.iomem, + 0x100, 0xc00); + memory_region_add_subregion_overlap(&s->container, 0x100, + &s->gic_iomem_alias, 1); + /* Map the whole thing into system memory at the location required + * by the v7M architecture. + */ + memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container); + s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s); + + // Create the input handler to be notified when the WKUP pin gets asserted + qdev_init_gpio_in_named(dev, nvic_wakeup_in_cb, "wakeup_in", 1); + + // This is the handler that will wakeup the CPU + qdev_init_gpio_out_named(dev, &s->cpu_wakeup_out, "wakeup_out", 1); + + // This is the handler that informs peripherals that the power is on/off + qdev_init_gpio_out_named(dev, &s->power_out, "power_out", 1); +>>>>>>> 919b29ba7d... Pebble Qemu } static void armv7m_nvic_instance_init(Object *obj) @@ -2750,6 +3212,11 @@ static void armv7m_nvic_instance_init(Object *obj) qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1); } +static Property armv7m_nvic_properties[] = { + DEFINE_PROP_PTR("stm32_pwr", nvic_state, stm32_pwr_prop), + DEFINE_PROP_END_OF_LIST(), +}; + static void armv7m_nvic_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2758,6 +3225,7 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, props_nvic); dc->reset = armv7m_nvic_reset; dc->realize = armv7m_nvic_realize; + dc->props = armv7m_nvic_properties; } static const TypeInfo armv7m_nvic_info = { diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 6d91cd8309d5d..8589ebe8a04d3 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1958,6 +1958,14 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size) return -1; } + /* Pad to minimum Ethernet frame length */ + if (size < sizeof(min_buf)) { + memcpy(min_buf, buf, size); + memset(&min_buf[size], 0, sizeof(min_buf) - size); + buf = min_buf; + size = sizeof(min_buf); + } + if (s->peer_has_vhdr) { net_rx_pkt_set_vhdr(s->rx_pkt, (struct virtio_net_hdr *)buf); buf += sizeof(struct virtio_net_hdr); diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs index 07a85f1967a80..9b1637f2b2102 100644 --- a/hw/ssi/Makefile.objs +++ b/hw/ssi/Makefile.objs @@ -6,5 +6,12 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o common-obj-$(CONFIG_MSF2) += mss-spi.o +<<<<<<< HEAD common-obj-$(CONFIG_OMAP) += omap_spi.o common-obj-$(CONFIG_IMX) += imx_spi.o +======= +obj-$(CONFIG_OMAP) += omap_spi.o + +obj-y += stm32f2xx_spi.o +obj-y += stm32f412_qspi.o +>>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c index cd6e8443db300..58fe4780c3a7f 100644 --- a/hw/ssi/stm32f2xx_spi.c +++ b/hw/ssi/stm32f2xx_spi.c @@ -1,7 +1,12 @@ +<<<<<<< HEAD /* * STM32F405 SPI * * Copyright (c) 2014 Alistair Francis +======= +/*- + * Copyright (c) 2013 +>>>>>>> 919b29ba7d... Pebble Qemu * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -15,6 +20,7 @@ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +<<<<<<< HEAD * 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, @@ -161,12 +167,145 @@ static void stm32f2xx_spi_write(void *opaque, hwaddr addr, default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr); +======= + * 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. + */ +/* + * QEMU model of the stm32f2xx SPI controller. + */ + +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/ssi.h" + +#define R_CR1 (0x00 / 4) +#define R_CR1_DFF (1 << 11) +#define R_CR1_LSBFIRST (1 << 7) +#define R_CR1_SPE (1 << 6) +#define R_CR2 (0x04 / 4) + +#define R_SR (0x08 / 4) +#define R_SR_RESET 0x0002 +#define R_SR_MASK 0x01FF +#define R_SR_OVR (1 << 6) +#define R_SR_TXE (1 << 1) +#define R_SR_RXNE (1 << 0) + +#define R_DR (0x0C / 4) +#define R_CRCPR (0x10 / 4) +#define R_CRCPR_RESET 0x0007 +#define R_RXCRCR (0x14 / 4) +#define R_TXCRCR (0x18 / 4) +#define R_I2SCFGR (0x1C / 4) +#define R_I2SPR (0x20 / 4) +#define R_I2SPR_RESET 0x0002 +#define R_MAX (0x24 / 4) + +typedef struct stm32f2xx_spi_s { + SysBusDevice busdev; + MemoryRegion iomem; + qemu_irq irq; + + SSIBus *spi; + + stm32_periph_t periph; + + int32_t rx; + int rx_full; + uint16_t regs[R_MAX]; +} Stm32Spi; + +static uint64_t +stm32f2xx_spi_read(void *arg, hwaddr offset, unsigned size) +{ + Stm32Spi *s = arg; + uint16_t r = UINT16_MAX; + + if (!(size == 1 || size == 2 || size == 4 || (offset & 0x3) != 0)) { + STM32_BAD_REG(offset, size); + } + offset >>= 2; + if (offset < R_MAX) { + r = s->regs[offset]; + } else { + stm32_hw_warn("Out of range SPI write, offset 0x%x", (unsigned)offset<<2); + } + switch (offset) { + case R_DR: + s->regs[R_SR] &= ~R_SR_RXNE; + } + return r; +} + +static uint8_t +bitswap(uint8_t val) +{ + return ((val * 0x0802LU & 0x22110LU) | (val * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; +} + +static void +stm32f2xx_spi_write(void *arg, hwaddr addr, uint64_t data, unsigned size) +{ + struct stm32f2xx_spi_s *s = (struct stm32f2xx_spi_s *)arg; + int offset = addr & 0x3; + + /* SPI registers are all at most 16 bits wide */ + data &= 0xFFFFF; + addr >>= 2; + + switch (size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + + switch (addr) { + case R_CR1: + if ((data & R_CR1_DFF) != s->regs[R_CR1] && (s->regs[R_CR1] & R_CR1_SPE) != 0) + qemu_log_mask(LOG_GUEST_ERROR, "cannot change DFF with SPE set\n"); + if (data & R_CR1_DFF) + qemu_log_mask(LOG_UNIMP, "f2xx DFF 16-bit mode not implemented\n"); + s->regs[R_CR1] = data; + break; + case R_DR: + s->regs[R_SR] &= ~R_SR_TXE; + if (s->regs[R_SR] & R_SR_RXNE) { + s->regs[R_SR] |= R_SR_OVR; + } + if (s->regs[R_CR1] & R_CR1_LSBFIRST) { + s->regs[R_DR] = bitswap(ssi_transfer(s->spi, bitswap(data))); + } else { + s->regs[R_DR] = ssi_transfer(s->spi, data); + } + + s->regs[R_SR] |= R_SR_RXNE; + s->regs[R_SR] |= R_SR_TXE; + break; + default: + if (addr < ARRAY_SIZE(s->regs)) { + s->regs[addr] = data; + } else { + STM32_BAD_REG(addr, size); + } +>>>>>>> 919b29ba7d... Pebble Qemu } } static const MemoryRegionOps stm32f2xx_spi_ops = { .read = stm32f2xx_spi_read, .write = stm32f2xx_spi_write, +<<<<<<< HEAD .endianness = DEVICE_NATIVE_ENDIAN, }; @@ -219,8 +358,80 @@ static const TypeInfo stm32f2xx_spi_info = { }; static void stm32f2xx_spi_register_types(void) +======= + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void +stm32f2xx_spi_reset(DeviceState *dev) +{ + struct stm32f2xx_spi_s *s = FROM_SYSBUS(struct stm32f2xx_spi_s, + SYS_BUS_DEVICE(dev)); + + s->regs[R_SR] = R_SR_RESET; + switch (s->periph) { + case 0: + break; + case 1: + break; + default: + break; + } +} + +static int +stm32f2xx_spi_init(SysBusDevice *dev) +{ + struct stm32f2xx_spi_s *s = FROM_SYSBUS(struct stm32f2xx_spi_s, dev); + + memory_region_init_io(&s->iomem, NULL, &stm32f2xx_spi_ops, s, "spi", 0x3ff); + sysbus_init_mmio(dev, &s->iomem); + sysbus_init_irq(dev, &s->irq); + s->spi = ssi_create_bus(DEVICE(dev), "ssi"); + + return 0; +} + + +static Property stm32f2xx_spi_properties[] = { + DEFINE_PROP_INT32("periph", struct stm32f2xx_spi_s, periph, -1), + DEFINE_PROP_END_OF_LIST() +}; + +static void +stm32f2xx_spi_class_init(ObjectClass *c, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(c); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); + + sc->init = stm32f2xx_spi_init; + dc->reset = stm32f2xx_spi_reset; + dc->props = stm32f2xx_spi_properties; +} + +static const TypeInfo stm32f2xx_spi_info = { + .name = "stm32f2xx_spi", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct stm32f2xx_spi_s), + .class_init = stm32f2xx_spi_class_init +}; + +static void +stm32f2xx_spi_register_types(void) +>>>>>>> 919b29ba7d... Pebble Qemu { type_register_static(&stm32f2xx_spi_info); } type_init(stm32f2xx_spi_register_types) +<<<<<<< HEAD +======= + +/* + * + */ +/* + * Serial peripheral interface (SPI) RM0033 section 25 + */ + +>>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/ssi/stm32f412_qspi.c b/hw/ssi/stm32f412_qspi.c new file mode 100644 index 0000000000000..7ded2c0ce7528 --- /dev/null +++ b/hw/ssi/stm32f412_qspi.c @@ -0,0 +1,347 @@ +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/ssi.h" + +#ifndef STM32F412_QSPI_ERR_DEBUG +#define STM32F412_QSPI_ERR_DEBUG 0 +#endif + +// The usleep() helps MacOS stdout from freezing when printing a lot +#define DB_PRINT_L(level, ...) do { \ + if (STM32F412_QSPI_ERR_DEBUG > (level)) { \ + fprintf(stderr, "%d: %s: ", level, __func__); \ + fprintf(stderr, ## __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + usleep(1000); \ + } \ +} while (0); + +// Control +#define R_CR (0x00 / 4) +#define CR_MATCH_MODE_MASK (0x01 << 23) + +// Device configure +#define R_DCR (0x04 / 4) + +// Status +#define R_SR (0x08 / 4) +#define R_SR_TEF (1 << 0) +#define R_SR_TCF (1 << 1) +#define R_SR_FTF (1 << 2) +#define R_SR_SMF (1 << 3) +#define R_SR_TOF (1 << 4) +#define R_SR_BSY (1 << 5) + +// Flag clear +#define R_FCR (0x0c / 4) +#define R_FCR_CTOF (1 << 4) +#define R_FCR_CSMF (1 << 3) +#define R_FCR_CTCF (1 << 1) +#define R_FCR_CTEF (1 << 0) + +// Data length +#define R_DLR (0x10 / 4) + +// Communication config +#define R_CCR (0x14 / 4) +#define CCR_INSTR_MASK (0xff << 0) +#define CCR_IMODE_MASK (0x3 << 8) +#define CCR_ADMODE_MASK (0x3 << 10) +#define CCR_ADSIZE_MASK (0x3 << 12) +#define CCR_MODE_MASK (0x3 << 26) + +#define CCR_IMODE_NONE (0x0 << 8) +#define CCR_IMODE_ONELINE (0x1 << 8) +#define CCR_IMODE_TWOLINE (0x2 << 8) +#define CCR_IMODE_FOURLINE (0x3 << 8) + +#define CCR_ADMODE_NONE (0x0 << 10) +#define CCR_ADMODE_ONELINE (0x1 << 10) +#define CCR_ADMODE_TWOLINE (0x2 << 10) +#define CCR_ADMODE_FOURLINE (0x3 << 10) + +#define CCR_ADSIZE_8 (0x0 << 12) +#define CCR_ADSIZE_16 (0x1 << 12) +#define CCR_ADSIZE_24 (0x2 << 12) +#define CCR_ADSIZE_32 (0x3 << 12) + +#define CCR_MODE_INDIRECT_WRITE (0x00 << 26) +#define CCR_MODE_INDIRECT_READ (0x01 << 26) +#define CCR_MODE_AUTOMATIC_POLL (0x2 << 26) +#define CCR_MODE_MEMORY_MAPPED (0x3 << 26) + +// Address +#define R_AR (0x18 / 4) + +// Alternate bytes +#define R_ABR (0x1c / 4) + +// Data +#define R_DR (0x20 / 4) + +// Polling status mask +#define R_PSMKR (0x24 / 4) + +// Polling status match +#define R_PSMAR (0x28 / 4) + +// Polling interval +#define R_PIR (0x2c / 4) + +// Low power timeout +#define R_LPTR (0x30 / 4) + +#define R_MAX (0x34 / 4) + +typedef enum { + STATE_IDLE, + STATE_WRITE, + STATE_READ, + STATE_READ_WHOAMI, +} Stm32f412State; + +typedef enum { + CS_STATE_LOW = 0, + CS_STATE_HIGH = 1, +} CsState; + +typedef struct stm32f412_qspi_s { + SysBusDevice busdev; + MemoryRegion iomem; + qemu_irq irq; + + SSIBus *qspi; + + uint32_t regs[R_MAX]; + + qemu_irq cs_irq; + CsState cs_state; + + int64_t tx_remaining; +} Stm32f412Qspi; + +static uint32_t +stm32f412_auto_poll(Stm32f412Qspi *s, uint8_t reg) +{ + bool set; + + bool and_match = (s->regs[R_CR] & CR_MATCH_MODE_MASK) == 0; + uint32_t match = s->regs[R_PSMAR]; + uint32_t mask = s->regs[R_PSMKR]; + if (and_match) { + // All bits in match need to be set after mask + set = (reg & mask) == match; + } else { + // Any bits in match can be set after mask + set = ((reg & mask) & match) != 0; + } + DB_PRINT_L(1, "Auto Poll %s", set ? "Success" : "Fail"); + return set; +} + +static bool +stm32f412_in_CCR_mode(Stm32f412Qspi *s, uint32_t mode) +{ + return (s->regs[R_CCR] & CCR_MODE_MASK) == mode; +} + +static void +stm32f412_set_cs(Stm32f412Qspi *s, CsState state) +{ + if (s->cs_state != state) { + qemu_set_irq(s->cs_irq, state == CS_STATE_HIGH); + s->cs_state = state; + } +} + +static uint64_t +stm32f412_qspi_read(void *arg, hwaddr offset, unsigned size) +{ + Stm32f412Qspi *s = arg; + uint32_t r = UINT32_MAX; + + offset >>= 2; + + if (offset < R_MAX) { + switch (offset) { + case R_DR: + DB_PRINT_L(1, "Read %u of %"PRIi64" remaining", size, s->tx_remaining); + r = ssi_transfer(s->qspi, 0); + s->tx_remaining -= size; + break; + case R_SR: { + if (stm32f412_in_CCR_mode(s, CCR_MODE_AUTOMATIC_POLL)) { + DB_PRINT_L(2, "POLL STATUS REG. Command? %d", s->cs_state == CS_STATE_LOW); + stm32f412_set_cs(s, CS_STATE_LOW); + ssi_transfer(s->qspi, s->regs[R_CCR] & CCR_INSTR_MASK); + uint8_t reg = ssi_transfer(s->qspi, 0); + stm32f412_set_cs(s, CS_STATE_HIGH); + DB_PRINT_L(2, "REG: 0x%"PRIx8, reg); + if (stm32f412_auto_poll(s, reg)) { + // Success, set the SMF bit and exit auto poll mode + s->regs[R_SR] |= R_SR_SMF; + s->regs[R_CCR] &= ~CCR_MODE_AUTOMATIC_POLL; + } + } + r = s->regs[R_SR]; + break; + } + default: + r = s->regs[offset]; + break; + } + } else { + stm32_hw_warn("Out of range QSPI register 0x%x", (unsigned)offset); + } + + if (s->tx_remaining <= 0) { + stm32f412_set_cs(s, CS_STATE_HIGH); + s->regs[R_SR] &= ~R_SR_TCF; + s->regs[R_SR] &= ~R_SR_BSY; + } + + return r; +} + +static void +stm32f412_CCR_write(Stm32f412Qspi *s, uint32_t CCR, unsigned size) +{ + if ((CCR & CCR_ADMODE_MASK) != CCR_ADMODE_NONE) { + uint8_t addrsize = ((CCR & CCR_ADSIZE_MASK) >> 12) + 1; + DB_PRINT_L(1, "Adding %"PRIu8" for address", addrsize); + s->tx_remaining += addrsize; + } + if ((CCR & CCR_MODE_MASK) != CCR_MODE_AUTOMATIC_POLL) { + if ((CCR & CCR_IMODE_MASK) != CCR_IMODE_NONE) { + DB_PRINT_L(1, "Command 0x%x to tx %"PRIi64" B\n", CCR & CCR_INSTR_MASK, s->tx_remaining); + stm32f412_set_cs(s, CS_STATE_LOW); + ssi_transfer(s->qspi, CCR & CCR_INSTR_MASK); + } + } + s->regs[R_CCR] = CCR; +} + +static void +stm32f412_qspi_xfer(Stm32f412Qspi *s, uint32_t data, unsigned size) +{ + for (int i = 0; i < size; ++i) { + uint8_t val = (data >> (i*8)) & 0xff; + ssi_transfer(s->qspi, val); + } +} + +static void +stm32f412_qspi_write(void *arg, hwaddr addr, uint64_t data, unsigned size) +{ + Stm32f412Qspi *s = arg; + + addr >>= 2; + + switch (addr) { + case R_FCR: // Flag clear register + s->regs[R_SR] &= ~(data); + break; + case R_CCR: // Send command + stm32f412_CCR_write(s, data, size); + break; + case R_AR: // Send address + s->regs[R_AR] = data; + uint8_t addrsize = ((s->regs[R_CCR] & CCR_ADSIZE_MASK) >> 12) + 1; + stm32f412_qspi_xfer(s, data, addrsize); + s->tx_remaining -= addrsize; + break; + case R_DR: // Data register + DB_PRINT_L(2, "Write %u of %"PRIi64" remaining\n", size, s->tx_remaining); + s->regs[R_DR] = 0; + stm32f412_qspi_xfer(s, data, size); + s->tx_remaining -= size; + break; + case R_DLR: + s->tx_remaining = data + 1; + DB_PRINT_L(1, "Set DLR to %"PRIu64" + 1", data); + break; + case R_CR: + case R_DCR: + case R_SR: + case R_ABR: + case R_PSMKR: + case R_PSMAR: + case R_PIR: + case R_LPTR: + case R_MAX: + default: + s->regs[addr] = data; + break; + } + + if (s->tx_remaining <= 0) { + stm32f412_set_cs(s, CS_STATE_HIGH); + } + + s->regs[R_SR] |= R_SR_TCF; +} + +static const MemoryRegionOps stm32f412_qspi_ops = { + .read = stm32f412_qspi_read, + .write = stm32f412_qspi_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void +stm32f412_qspi_reset(DeviceState *dev) +{ + struct stm32f412_qspi_s *s = FROM_SYSBUS(struct stm32f412_qspi_s, + SYS_BUS_DEVICE(dev)); + + //s->regs[R_SR] = R_SR_RESET; + s->cs_state = CS_STATE_HIGH; + s->tx_remaining = 0; +} + +static int +stm32f412_qspi_init(SysBusDevice *dev) +{ + struct stm32f412_qspi_s *s = FROM_SYSBUS(struct stm32f412_qspi_s, dev); + + memory_region_init_io(&s->iomem, NULL, &stm32f412_qspi_ops, s, "qspi", 0x3ff); + sysbus_init_mmio(dev, &s->iomem); + sysbus_init_irq(dev, &s->irq); + s->qspi = ssi_create_bus(DEVICE(dev), "ssi"); + + s->cs_state = CS_STATE_HIGH; + s->tx_remaining = 0; + + qdev_init_gpio_out_named(DEVICE(dev), &s->cs_irq, "qspi-gpio-cs", 1); + + return 0; +} + +static Property stm32f412_qspi_properties[] = { + DEFINE_PROP_END_OF_LIST() +}; + +static void +stm32f412_qspi_class_init(ObjectClass *c, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(c); + SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); + + sc->init = stm32f412_qspi_init; + dc->reset = stm32f412_qspi_reset; + dc->props = stm32f412_qspi_properties; +} + +static const TypeInfo stm32f412_qspi_info = { + .name = "stm32f412_qspi", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct stm32f412_qspi_s), + .class_init = stm32f412_qspi_class_init +}; + +static void +stm32f412_qspi_register_types(void) +{ + type_register_static(&stm32f412_qspi_info); +} + +type_init(stm32f412_qspi_register_types) diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index ce2b48b88bca5..65f21d7b75e7a 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -14,6 +14,7 @@ #include "target/arm/cpu-qom.h" #include "qemu/notify.h" +<<<<<<< HEAD:include/hw/arm/boot.h typedef enum { ARM_ENDIANNESS_UNKNOWN = 0, ARM_ENDIANNESS_LE, @@ -30,6 +31,24 @@ typedef enum { * Load the guest image for an ARMv7M system. This must be called by * any ARMv7M board. (This is necessary to ensure that the CPU resets * correctly on system reset, as well as for kernel loading.) +======= +/* armv7m.c */ +DeviceState *armv7m_init(Object *parent, MemoryRegion *system_memory, + int flash_size, int sram_size, int num_irq, + const char *kernel_filename, const char *cpu_model); + +DeviceState *armv7m_translated_init(Object *parent, MemoryRegion *system_memory, + int flash_size, int sram_size, int num_irq, + const char *kernel_filename, + uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, + const char *cpu_model, + ARMCPU **cpu_device); + +/* + * struct used as a parameter of the arm_load_kernel machine init + * done notifier +>>>>>>> 919b29ba7d... Pebble Qemu:include/hw/arm/arm.h */ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size); diff --git a/include/hw/arm/stm32.h b/include/hw/arm/stm32.h new file mode 100644 index 0000000000000..0ad9a8e044163 --- /dev/null +++ b/include/hw/arm/stm32.h @@ -0,0 +1,554 @@ +/* + * STM32 Microcontroller + * + * Copyright (C) 2010 Andre Beckus + * + * Implementation based on ST Microelectronics "RM0008 Reference Manual Rev 10" + * + * 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 . + */ + +#ifndef STM32_H +#define STM32_H + +#include "qemu/timer.h" +#include "hw/arm/arm.h" +#include "qemu-common.h" +#include "hw/sysbus.h" +#include "qemu/log.h" +#include "sysemu/char.h" + + +#define ENUM_STRING(x) [x] = #x +#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0])) + +/* COMMON */ +#define BYTE_ACCESS_SIZE 1 +#define HALFWORD_ACCESS_SIZE 2 +#define WORD_ACCESS_SIZE 4 + +#define STM32_FLASH_ADDR_START (0x08000000) + +/* VALUE_BETWEEN is inclusive */ +#define VALUE_BETWEEN(value, start, end) ((value >= start) && (value <= end)) + +#define GET_BIT_MASK(position, value) ((value ? 1 : 0) << position) +#define GET_BIT_MASK_ONE(position) (1 << position) +#define GET_BIT_MASK_ZERO(position) (~(1 << position)) +#define GET_BIT_VALUE(value, position) \ + ((value & GET_BIT_MASK_ONE(position)) >> position) +#define IS_BIT_SET(value, position) ((value & GET_BIT_MASK_ONE(position)) != 0) +#define IS_BIT_RESET(value, position) ((value & GET_BIT_MASK_ONE(position)) ==0) +#define SET_BIT(var, position) var |= GET_BIT_MASK_ONE(position) +#define RESET_BIT(var, position) var &= GET_BIT_MASK_ZERO(position) + +/* Can be true, false, 0, or 1 */ +#define CHANGE_BIT(var, position, new_value) \ + var = new_value ? \ + (var | GET_BIT_MASK_ONE(position)) : \ + (var & GET_BIT_MASK_ZERO(position)) +#define CHANGE_BITS(var, start, mask, new_value) \ + var = (var & ~mask) | ((new_value << start) & mask) + +void stm32_hw_warn(const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 1, 2))); + +#define stm32_unimp(x...) qemu_log_mask(LOG_UNIMP, x) + + + + +/* PERIPHERALS - COMMON */ +/* Indexes used for accessing a GPIO array */ +#define STM32_GPIOA_INDEX 0 +#define STM32_GPIOB_INDEX 1 +#define STM32_GPIOC_INDEX 2 +#define STM32_GPIOD_INDEX 3 +#define STM32_GPIOE_INDEX 4 +#define STM32_GPIOF_INDEX 5 +#define STM32_GPIOG_INDEX 6 +#define STM32_GPIOH_INDEX 7 +#define STM32_GPIOI_INDEX 8 + +/* Indexes used for accessing a UART array */ +#define STM32_UART1_INDEX 0 +#define STM32_UART2_INDEX 1 +#define STM32_UART3_INDEX 2 +#define STM32_UART4_INDEX 3 +#define STM32_UART5_INDEX 4 +#define STM32_UART6_INDEX 5 + +/* Used for uniquely identifying a peripheral */ +typedef int32_t stm32_periph_t; + +#define DEFINE_PROP_PERIPH_T DEFINE_PROP_INT32 +#define QDEV_PROP_SET_PERIPH_T qdev_prop_set_int32 + +enum { + STM32_PERIPH_UNDEFINED = -1, + STM32_RCC_PERIPH = 0, + STM32_GPIOA, + STM32_GPIOB, + STM32_GPIOC, + STM32_GPIOD, + STM32_GPIOE, + STM32_GPIOF, + STM32_GPIOG, + STM32_GPIOH, + STM32_GPIOI, + STM32_GPIOJ, + STM32_GPIOK, + STM32_SYSCFG, + STM32_AFIO_PERIPH, + STM32_UART1, + STM32_UART2, + STM32_UART3, + STM32_UART4, + STM32_UART5, + STM32_UART6, + STM32_UART7, + STM32_UART8, + STM32_ADC1, + STM32_ADC2, + STM32_ADC3, + STM32_DAC, + STM32_TIM1, + STM32_TIM2, + STM32_TIM3, + STM32_TIM4, + STM32_TIM5, + STM32_TIM6, + STM32_TIM7, + STM32_TIM8, + STM32_TIM9, + STM32_TIM10, + STM32_TIM11, + STM32_TIM12, + STM32_TIM13, + STM32_TIM14, + STM32_BKP, + STM32_PWR, + STM32_I2C1, + STM32_I2C2, + STM32_I2C3, + STM32_I2C4, + STM32_I2S2, + STM32_I2S3, + STM32_WWDG, + STM32_CAN1, + STM32_CAN2, + STM32_CAN, + STM32_USB, + STM32_SPI1, + STM32_SPI2, + STM32_SPI3, + STM32_EXTI_PERIPH, + STM32_SDIO, + STM32_FSMC, + STM32_RTC, + STM32_CRC, + STM32_DMA1, + STM32_DMA2, + STM32_DCMI_PERIPH, + STM32_CRYP_PERIPH, + STM32_HASH_PERIPH, + STM32_RNG_PERIPH, + STM32_QSPI, + STM32_LPTIM1, + + STM32_PERIPH_COUNT, +}; + +const char *stm32_periph_name(stm32_periph_t periph); + +/* Convert between a GPIO array index and stm32_periph_t, and vice-versa */ +#define STM32_GPIO_INDEX_FROM_PERIPH(gpio_periph) (gpio_periph - STM32_GPIOA) +#define STM32_GPIO_PERIPH_FROM_INDEX(gpio_index) (STM32_GPIOA + gpio_index) + + + + +/* REGISTER HELPERS */ +/* Macros used for converting a half-word into a word. + * Assume that memory alignment can be determined by looking at offset + * i.e. the base address should always be 4 byte aligned. + * Also assume that odd offsets will never occur + * i.e. all offsets must be 2 byte aligned. + */ +#define STM32_REG_READH_VALUE(offset, value32) \ + ((offset & 3) ? \ + (value32 & 0xffff0000) >> 16 : \ + value32 & 0x0000ffff) +#define STM32_REG_WRITEH_VALUE(offset, old_value32, new_value32) \ + ((offset & 3) ? \ + (old_value32 & 0x0000ffff) | ((new_value32 & 0x0000ffff) << 16) : \ + (old_value32 & 0xffff0000) | (new_value32 & 0x0000ffff) ) + +/* Error handlers */ +# define STM32_BAD_REG(offset, size) \ + hw_error("%s: Bad register 0x%x - size %u\n", __FUNCTION__, (int)offset, size) +# define STM32_WARN_RO_REG(offset) \ + qemu_log_mask(LOG_GUEST_ERROR, "%s: Read-only register 0x%x\n", \ + __FUNCTION__, (int)offset) +# define STM32_WARN_WO_REG(offset) \ + qemu_log_mask(LOG_GUEST_ERROR, "%s: Write-only register 0x%x\n", \ + __FUNCTION__, (int)offset) +# define STM32_NOT_IMPL_REG(offset, size) \ + hw_error("%s: Not implemented yet 0x%x - size %u\n", __FUNCTION__, (int)offset, size) + + + + +/* IRQs */ +#define STM32_PVD_IRQ 1 +#define STM32_TAMP_STAMP_IRQ 2 +#define STM32_RTC_WKUP_IRQ 3 +#define STM32_RCC_IRQ 5 +#define STM32_EXTI0_IRQ 6 +#define STM32_EXTI1_IRQ 7 +#define STM32_EXTI2_IRQ 8 +#define STM32_EXTI3_IRQ 9 +#define STM32_EXTI4_IRQ 10 + +#define STM32_DMA1_STREAM0_IRQ 11 +#define STM32_DMA1_STREAM1_IRQ 12 +#define STM32_DMA1_STREAM2_IRQ 13 +#define STM32_DMA1_STREAM3_IRQ 14 +#define STM32_DMA1_STREAM4_IRQ 15 +#define STM32_DMA1_STREAM5_IRQ 16 +#define STM32_DMA1_STREAM6_IRQ 17 + +#define STM32_EXTI9_5_IRQ 23 +#define STM32_TIM1_BRK_TIM9_IRQ 24 +#define STM32_TIM1_UP_TIM10_IRQ 25 +#define STM32_TIM1_TRG_COM_TIM11_IRQ 26 +#define STM32_TIM1_CC_IRQ 27 +#define STM32_TIM2_IRQ 28 +#define STM32_TIM3_IRQ 29 +#define STM32_TIM4_IRQ 30 + +#define STM32_I2C1_EV_IRQ 31 +#define STM32_I2C1_ER_IRQ 32 +#define STM32_I2C2_EV_IRQ 33 +#define STM32_I2C2_ER_IRQ 34 + +#define STM32_SPI1_IRQ 35 +#define STM32_SPI2_IRQ 36 + +#define STM32_UART1_IRQ 37 +#define STM32_UART2_IRQ 38 +#define STM32_UART3_IRQ 39 +#define STM32_EXTI15_10_IRQ 40 +#define STM32_RTCAlarm_IRQ 41 +#define STM32_OTG_FS_WKUP_IRQ 42 +#define STM32_TIM8_BRK_TIM12_IRQ 43 +#define STM32_TIM8_UP_TIM13_IRQ 44 +#define STM32_TIM8_TRG_COMM_TIM14_IRQ 45 + +#define STM32_DMA1_STREAM7_IRQ 47 + +#define STM32_TIM5_IRQ 50 +#define STM32_SPI3_IRQ 51 +#define STM32_UART4_IRQ 52 +#define STM32_UART5_IRQ 53 +#define STM32_TIM6_IRQ 54 +#define STM32_TIM7_IRQ 55 + +#define STM32_DMA2_STREAM0_IRQ 56 +#define STM32_DMA2_STREAM1_IRQ 57 +#define STM32_DMA2_STREAM2_IRQ 58 +#define STM32_DMA2_STREAM3_IRQ 59 +#define STM32_DMA2_STREAM4_IRQ 60 + +#define STM32_ETH_WKUP_IRQ 62 + +#define STM32_DMA2_STREAM5_IRQ 68 +#define STM32_DMA2_STREAM6_IRQ 69 +#define STM32_DMA2_STREAM7_IRQ 70 + +#define STM32_UART6_IRQ 71 + +#define STM32_I2C3_EV_IRQ 72 +#define STM32_I2C3_ER_IRQ 73 + +#define STM32_SPI4_IRQ 84 +#define STM32_SPI5_IRQ 85 +#define STM32_SPI6_IRQ 86 + +#define STM32_QSPI_IRQ 92 +#define STM32_LPTIM1_IRQ 93 + +#define STM32_I2C4_EV_IRQ 95 +#define STM32_I2C4_ER_IRQ 96 + +#define STM32_MAX_IRQ 127 + + + +/* EXTI */ +typedef struct Stm32Exti Stm32Exti; + +#define TYPE_STM32_EXTI "stm32-exti" +#define STM32_EXTI(obj) OBJECT_CHECK(Stm32Exti, (obj), TYPE_STM32_EXTI) + +/* Assigns the specified EXTI line to the specified GPIO. */ +void stm32_exti_set_gpio(Stm32Exti *s, unsigned exti_line, const uint8_t gpio_index); + +/* Unassigns the specified EXTI line from the specified GPIO. */ +void stm32_exti_reset_gpio(Stm32Exti *s, unsigned exti_line, const uint8_t gpio_index); + + + +/* RTC */ +// Set the value of one of the QEMU specific extra RTC backup registers. The idx value starts +// at 0 for the first extra register +void f2xx_rtc_set_extra_bkup_reg(void *opaque, uint32_t idx, uint32_t value); + + +/* GPIO */ +typedef struct Stm32Gpio Stm32Gpio; + +#define TYPE_STM32_GPIO "stm32-gpio" +#define STM32_GPIO(obj) OBJECT_CHECK(Stm32Gpio, (obj), TYPE_STM32_GPIO) + +#define STM32_GPIO_COUNT (STM32_GPIOG - STM32_GPIOA + 1) +#define STM32_GPIO_PIN_COUNT 16 + + +/* Sets the EXTI IRQ for the specified pin. When a change occurs + * on this pin, and interrupt will be generated on this IRQ. + */ +void stm32_gpio_set_exti_irq(Stm32Gpio *s, unsigned pin, qemu_irq in_irq); + +/* GPIO pin mode */ +#define STM32_GPIO_MODE_IN 0 +#define STM32_GPIO_MODE_OUT_10MHZ 1 +#define STM32_GPIO_MODE_OUT_2MHZ 2 +#define STM32_GPIO_MODE_OUT_50MHZ 3 +uint8_t stm32_gpio_get_mode_bits(Stm32Gpio *s, unsigned pin); + +/* GPIO pin config */ +#define STM32_GPIO_IN_ANALOG 0 +#define STM32_GPIO_IN_FLOAT 1 +#define STM32_GPIO_IN_PULLUPDOWN 2 +#define STM32_GPIO_OUT_PUSHPULL 0 +#define STM32_GPIO_OUT_OPENDRAIN 1 +#define STM32_GPIO_OUT_ALT_PUSHPULL 2 +#define STM32_GPIO_OUT_ALT_OPEN 3 +uint8_t stm32_gpio_get_config_bits(Stm32Gpio *s, unsigned pin); + + + + +/* GPIO - f2xx */ +typedef struct stm32f2xx_gpio stm32f2xx_gpio; +void f2xx_gpio_exti_set(stm32f2xx_gpio *, unsigned, qemu_irq); +void f2xx_gpio_wake_set(stm32f2xx_gpio *, unsigned, qemu_irq); + + + + +/* RCC */ +typedef struct Stm32Rcc Stm32Rcc; + +#define TYPE_STM32_RCC "stm32-rcc" +#define STM32_RCC(obj) OBJECT_CHECK(Stm32Rcc, (obj), TYPE_STM32_RCC) + +/* Checks if the specified peripheral clock is enabled. + * Generates a hardware error if not. + */ +void stm32_rcc_check_periph_clk(Stm32Rcc *s, stm32_periph_t periph); + +/* Sets the IRQ to be called when the specified peripheral clock changes + * frequency. */ +void stm32_rcc_set_periph_clk_irq( + Stm32Rcc *s, + stm32_periph_t periph, + qemu_irq periph_irq); + +/* Gets the frequency of the specified peripheral clock. */ +uint32_t stm32_rcc_get_periph_freq( + Stm32Rcc *s, + stm32_periph_t periph); + + + +/* TIM */ +typedef struct Stm32Timer Stm32Timer; +#define STM32_TIM_COUNT 14 + + +/* LPTIM */ +typedef struct Stm32F7xxLPTimer Stm32F7xxLPTimer; + + +/* UART */ +#define STM32_UART_COUNT 5 + +typedef struct Stm32Uart Stm32Uart; + +#define TYPE_STM32_UART "stm32-uart" +#define STM32_UART(obj) OBJECT_CHECK(Stm32Uart, (obj), TYPE_STM32_UART) + +/* Connects the character driver to the specified UART. The + * board's pin mapping should be passed in. This will be used to + * verify the correct mapping is configured by the software. + */ +void stm32_uart_connect(Stm32Uart *s, CharDriverState *chr, + uint32_t afio_board_map); + +/* Low level methods that let you connect a UART device to any other instance + * that has read/write handlers. These can be used in place of stm32_uart_connect + * if not connecting to a CharDriverState instance. */ +void stm32_uart_set_write_handler(Stm32Uart *s, void *obj, + int (*chr_write_handler)(void *chr_write_obj, const uint8_t *buf, int len)); +void stm32_uart_get_rcv_handlers(Stm32Uart *s, IOCanReadHandler **can_read, + IOReadHandler **read, IOEventHandler **event); + +void stm32_create_uart_dev( + Object *stm32_container, + stm32_periph_t periph, + int uart_num, + DeviceState *rcc_dev, + DeviceState **gpio_dev, + DeviceState *afio_dev, + hwaddr addr, + qemu_irq irq); + + +/* STM32F7xx UART */ +#define STM32F7XX_UART_COUNT 8 + +typedef struct Stm32F7xxUart Stm32F7xxUart; + +#define TYPE_STM32F7XX_UART "stm32f7xx-uart" +#define STM32F7XX_UART(obj) OBJECT_CHECK(Stm32F7xxUart, (obj), TYPE_STM32F7XX_UART) + +/* Connects the character driver to the specified UART. The + * board's pin mapping should be passed in. This will be used to + * verify the correct mapping is configured by the software. + */ +void stm32f7xx_uart_connect(Stm32F7xxUart *s, CharDriverState *chr, + uint32_t afio_board_map); + +/* Low level methods that let you connect a UART device to any other instance + * that has read/write handlers. These can be used in place of stm32_uart_connect + * if not connecting to a CharDriverState instance. */ +void stm32f7xx_uart_set_write_handler(Stm32F7xxUart *s, void *obj, + int (*chr_write_handler)(void *chr_write_obj, const uint8_t *buf, int len)); +void stm32f7xx_uart_get_rcv_handlers(Stm32F7xxUart *s, IOCanReadHandler **can_read, + IOReadHandler **read, IOEventHandler **event); + +void stm32f7xx_create_uart_dev( + Object *stm32_container, + stm32_periph_t periph, + int uart_num, + DeviceState *rcc_dev, + DeviceState **gpio_dev, + DeviceState *afio_dev, + hwaddr addr, + qemu_irq irq); + + +/* AFIO */ +#define TYPE_STM32_AFIO "stm32-afio" +#define STM32_AFIO(obj) OBJECT_CHECK(Stm32Afio, (obj), TYPE_STM32_AFIO) + +typedef struct Stm32Afio Stm32Afio; + +/* AFIO Peripheral Mapping */ +#define STM32_USART1_NO_REMAP 0 +#define STM32_USART1_REMAP 1 + +#define STM32_USART2_NO_REMAP 0 +#define STM32_USART2_REMAP 1 + +#define STM32_USART3_NO_REMAP 0 +#define STM32_USART3_PARTIAL_REMAP 1 +#define STM32_USART3_FULL_REMAP 3 + +/* Gets the pin mapping for the specified peripheral. Will return one + * of the mapping values defined above. */ +uint32_t stm32_afio_get_periph_map(Stm32Afio *s, int32_t periph_num); + +void stm32_afio_uart_check_tx_pin_callback(Stm32Uart *s); + + + + +/* STM32 PERIPHERALS - GENERAL */ +DeviceState *stm32_init_periph(DeviceState *dev, stm32_periph_t periph, + hwaddr addr, qemu_irq irq); + + +/* STM32 MICROCONTROLLER - GENERAL */ +typedef struct Stm32 Stm32; + +/* Initialize the STM32 microcontroller. Returns arrays + * of GPIOs and UARTs so that connections can be made. */ +void stm32f1xx_init( + ram_addr_t flash_size, + ram_addr_t ram_size, + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + Stm32Uart **stm32_uart, + uint32_t osc_freq, + uint32_t osc32_freq); + +struct stm32f2xx; +void stm32f2xx_init( + ram_addr_t flash_size, + ram_addr_t ram_size, + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + Stm32Uart **stm32_uart, + Stm32Timer **stm32_timer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f2xx *stm, + ARMCPU **cpu); + +struct stm32f4xx; +void stm32f4xx_init( + ram_addr_t flash_size, + ram_addr_t ram_size, + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + const uint32_t *gpio_idr_masks, + Stm32Uart **stm32_uart, + Stm32Timer **stm32_timer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f4xx *stm, + ARMCPU **cpu); + +struct stm32f7xx; +void stm32f7xx_init( + ram_addr_t flash_size, + ram_addr_t ram_size, + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + const uint32_t *gpio_idr_masks, + Stm32F7xxUart **stm32_uart, + Stm32Timer **stm32_timer, + Stm32F7xxLPTimer **lptimer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f7xx *stm, + ARMCPU **cpu); + +#endif /* STM32_H */ diff --git a/include/hw/arm/stm32_clktree.h b/include/hw/arm/stm32_clktree.h new file mode 100644 index 0000000000000..7740cf15cd764 --- /dev/null +++ b/include/hw/arm/stm32_clktree.h @@ -0,0 +1,82 @@ +/* + * Basic Clock Tree Building Blocks + * + * Copyright (C) 2012 Andre Beckus + * + * Source code roughly based on omap_clk.c + * + * 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 . + */ + +#ifndef STM32_CLKTREE_H +#define STM32_CLKTREE_H + +#include "qemu-common.h" + +#define CLKTREE_MAX_IRQ 16 +#define CLKTREE_MAX_OUTPUT 24 +#define CLKTREE_MAX_INPUT 24 + +/* Use this when calling clktree_create_clk and clktree_set_selected_input */ +#define CLKTREE_NO_INPUT -1 + +/* Use this when calling clktree_create_clk */ +#define CLKTREE_NO_MAX_FREQ UINT32_MAX + +typedef struct Clk *Clk; + +/* Check if the clock output is enabled. */ +bool clktree_is_enabled(Clk clk); + +/* Get the clock's output frequency. This will be 0 if: + * - No clock is selected as an input. + * - The clock output is not enabled. + * - The multiplier is set to 0. + */ +uint32_t clktree_get_output_freq(Clk clk); + +/* Add an IRQ to receive notifications when the clock frequency is updated. */ +void clktree_adduser(Clk clk, qemu_irq user); + +/* Create a source clock (e.g. oscillator) with the given frequency. */ +Clk clktree_create_src_clk( + const char *name, + uint32_t src_freq, + bool enabled); + +/* Create a clock. The vararg parameter specifies all of the source clocks + * (use NULL to indicate the end of the list). A warning will be generated if + * the output frequency of the clock ever exceeds max_output_freq. */ +Clk clktree_create_clk( + const char *name, + uint16_t multiplier, + uint16_t divisor, + bool enabled, + uint32_t max_output_freq, + int selected_input, + ...); + +/* Set the multiplier and divider scales. */ +void clktree_set_scale(Clk clk, uint16_t multiplier, uint16_t divisor); + +/* Enable or disable the clock output. */ +void clktree_set_enabled(Clk clk, bool enabled); + +/* Selects the specified input clock. selected_input should be 0 to select the + * first input clock passed in to clktree_create_clk, 1 for the second input + * clock, and so on. Pass in CLKTREE_NO_INPUT to not select any input + * (i.e. input frequency will be 0). */ +void clktree_set_selected_input(Clk clk, int selected_input); + +#endif /* STM32_CLKTREE_H */ diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h index 2136a2d5e4cd2..2cbf0ed41ecd4 100644 --- a/include/hw/block/flash.h +++ b/include/hw/block/flash.h @@ -27,6 +27,7 @@ MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl); void pflash_cfi01_legacy_drive(PFlashCFI01 *dev, DriveInfo *dinfo); /* pflash_cfi02.c */ +<<<<<<< HEAD #define TYPE_PFLASH_CFI02 "cfi.pflash02" #define PFLASH_CFI02(obj) \ @@ -46,6 +47,29 @@ PFlashCFI02 *pflash_cfi02_register(hwaddr base, uint16_t unlock_addr0, uint16_t unlock_addr1, int be); +======= +pflash_t *pflash_cfi02_register(hwaddr base, + DeviceState *qdev, const char *name, + hwaddr size, + BlockBackend *blk, uint32_t sector_len, + int nb_blocs, int nb_mappings, int width, + uint16_t id0, uint16_t id1, + uint16_t id2, uint16_t id3, + uint16_t unlock_addr0, uint16_t unlock_addr1, + int be); + +/* pflash_jedec_424.c */ +pflash_t *pflash_jedec_424_register(hwaddr base, + DeviceState *qdev, const char *name, + hwaddr size, + BlockBackend *blk, + uint32_t sector_len, int nb_blocs, uint32_t bank_size, + int bank_width, uint16_t id0, uint16_t id1, + uint16_t id2, uint16_t id3, int be); + +MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl); +MemoryRegion *pflash_jedec_424_get_memory(pflash_t *fl); +>>>>>>> 919b29ba7d... Pebble Qemu /* nand.c */ DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id); @@ -79,4 +103,7 @@ uint8_t ecc_digest(ECCState *s, uint8_t sample); void ecc_reset(ECCState *s); extern VMStateDescription vmstate_ecc_state; +typedef struct f2xx_flash f2xx_flash_t; +f2xx_flash_t *f2xx_flash_register(BlockBackend *blk, hwaddr base, + hwaddr size); #endif diff --git a/include/hw/irq.h b/include/hw/irq.h index 24ba0ece11664..d4d97f5f5a714 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -53,6 +53,14 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); /* For internal use in qtest. Similar to qemu_irq_split, but operating on an existing vector of qemu_irq. */ -void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); +typedef struct IRQInterceptData { + qemu_irq *old_irqs; + int id; +} IRQInterceptData; + +void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, + int id, int n); +void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, + int id, int n); #endif diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1405b8a990a18..198ee5a0d4ccf 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -144,6 +144,7 @@ typedef struct NamedGPIOList NamedGPIOList; struct NamedGPIOList { char *name; qemu_irq *in; + qemu_irq *out; int num_in; int num_out; QLIST_ENTRY(NamedGPIOList) node; diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index c4a1c0adfa5a1..44693fb306986 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -68,7 +68,14 @@ struct SysBusDevice { uint32_t pio[QDEV_MAX_PIO]; }; +<<<<<<< HEAD typedef void FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque); +======= +/* Macros to compensate for lack of type inheritance in C. */ +#define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev) + +typedef int FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque); +>>>>>>> 919b29ba7d... Pebble Qemu void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory); MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n); diff --git a/monitor.c b/monitor.c new file mode 100644 index 0000000000000..4e62100805d27 --- /dev/null +++ b/monitor.c @@ -0,0 +1,4244 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * 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 +#include "hw/hw.h" +#include "monitor/qdev.h" +#include "hw/usb.h" +#include "hw/i386/pc.h" +#include "hw/pci/pci.h" +#include "sysemu/watchdog.h" +#include "hw/loader.h" +#include "exec/gdbstub.h" +#include "net/net.h" +#include "net/slirp.h" +#include "sysemu/char.h" +#include "ui/qemu-spice.h" +#include "sysemu/sysemu.h" +#include "sysemu/numa.h" +#include "monitor/monitor.h" +#include "qemu/readline.h" +#include "ui/console.h" +#include "ui/input.h" +#include "sysemu/blockdev.h" +#include "audio/audio.h" +#include "disas/disas.h" +#include "sysemu/balloon.h" +#include "qemu/timer.h" +#include "migration/migration.h" +#include "sysemu/kvm.h" +#include "qemu/acl.h" +#include "sysemu/tpm.h" +#include "qapi/qmp/qerror.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/qlist.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qstring.h" +#include "qapi/qmp/qjson.h" +#include "qapi/qmp/json-streamer.h" +#include "qapi/qmp/json-parser.h" +#include +#include "qemu/osdep.h" +#include "cpu.h" +#include "trace.h" +#include "trace/control.h" +#include "monitor/hmp-target.h" +#ifdef CONFIG_TRACE_SIMPLE +#include "trace/simple.h" +#endif +#include "exec/memory.h" +#include "qmp-commands.h" +#include "hmp.h" +#include "qemu/thread.h" +#include "block/qapi.h" +#include "qapi/qmp-event.h" +#include "qapi-event.h" +#include "qmp-introspect.h" +#include "sysemu/block-backend.h" + +/* for hmp_info_irq/pic */ +#if defined(TARGET_SPARC) +#include "hw/sparc/sun4m.h" +#endif +#include "hw/lm32/lm32_pic.h" + +#if defined(TARGET_S390X) +#include "hw/s390x/storage-keys.h" +#endif + +/* + * Supported types: + * + * 'F' filename + * 'B' block device name + * 's' string (accept optional quote) + * 'S' it just appends the rest of the string (accept optional quote) + * 'O' option string of the form NAME=VALUE,... + * parsed according to QemuOptsList given by its name + * Example: 'device:O' uses qemu_device_opts. + * Restriction: only lists with empty desc are supported + * TODO lift the restriction + * 'i' 32 bit integer + * 'l' target long (32 or 64 bit) + * 'M' Non-negative target long (32 or 64 bit), in user mode the + * value is multiplied by 2^20 (think Mebibyte) + * 'o' octets (aka bytes) + * user mode accepts an optional E, e, P, p, T, t, G, g, M, m, + * K, k suffix, which multiplies the value by 2^60 for suffixes E + * and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t, + * 2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k + * 'T' double + * user mode accepts an optional ms, us, ns suffix, + * which divides the value by 1e3, 1e6, 1e9, respectively + * '/' optional gdb-like print format (like "/10x") + * + * '?' optional type (for all types, except '/') + * '.' other form of optional type (for 'i' and 'l') + * 'b' boolean + * user mode accepts "on" or "off" + * '-' optional parameter (eg. '-f') + * + */ + +typedef struct mon_cmd_t { + const char *name; + const char *args_type; + const char *params; + const char *help; + union { + void (*cmd)(Monitor *mon, const QDict *qdict); + void (*cmd_new)(QDict *params, QObject **ret_data, Error **errp); + } mhandler; + /* @sub_table is a list of 2nd level of commands. If it do not exist, + * mhandler should be used. If it exist, sub_table[?].mhandler should be + * used, and mhandler of 1st level plays the role of help function. + */ + struct mon_cmd_t *sub_table; + void (*command_completion)(ReadLineState *rs, int nb_args, const char *str); +} mon_cmd_t; + +/* file descriptors passed via SCM_RIGHTS */ +typedef struct mon_fd_t mon_fd_t; +struct mon_fd_t { + char *name; + int fd; + QLIST_ENTRY(mon_fd_t) next; +}; + +/* file descriptor associated with a file descriptor set */ +typedef struct MonFdsetFd MonFdsetFd; +struct MonFdsetFd { + int fd; + bool removed; + char *opaque; + QLIST_ENTRY(MonFdsetFd) next; +}; + +/* file descriptor set containing fds passed via SCM_RIGHTS */ +typedef struct MonFdset MonFdset; +struct MonFdset { + int64_t id; + QLIST_HEAD(, MonFdsetFd) fds; + QLIST_HEAD(, MonFdsetFd) dup_fds; + QLIST_ENTRY(MonFdset) next; +}; + +typedef struct { + QObject *id; + JSONMessageParser parser; + /* + * When a client connects, we're in capabilities negotiation mode. + * When command qmp_capabilities succeeds, we go into command + * mode. + */ + bool in_command_mode; /* are we in command mode? */ +} MonitorQMP; + +/* + * To prevent flooding clients, events can be throttled. The + * throttling is calculated globally, rather than per-Monitor + * instance. + */ +typedef struct MonitorQAPIEventState { + QAPIEvent event; /* Throttling state for this event type and... */ + QDict *data; /* ... data, see qapi_event_throttle_equal() */ + QEMUTimer *timer; /* Timer for handling delayed events */ + QDict *qdict; /* Delayed event (if any) */ +} MonitorQAPIEventState; + +typedef struct { + int64_t rate; /* Minimum time (in ns) between two events */ +} MonitorQAPIEventConf; + +struct Monitor { + CharDriverState *chr; + int reset_seen; + int flags; + int suspend_cnt; + bool skip_flush; + + QemuMutex out_lock; + QString *outbuf; + guint out_watch; + + /* Read under either BQL or out_lock, written with BQL+out_lock. */ + int mux_out; + + ReadLineState *rs; + MonitorQMP qmp; + CPUState *mon_cpu; + BlockCompletionFunc *password_completion_cb; + void *password_opaque; + mon_cmd_t *cmd_table; + QLIST_HEAD(,mon_fd_t) fds; + QLIST_ENTRY(Monitor) entry; +}; + +/* QMP checker flags */ +#define QMP_ACCEPT_UNKNOWNS 1 + +/* Protects mon_list, monitor_event_state. */ +static QemuMutex monitor_lock; + +static QLIST_HEAD(mon_list, Monitor) mon_list; +static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets; +static int mon_refcount; + +static mon_cmd_t mon_cmds[]; +static mon_cmd_t info_cmds[]; + +static const mon_cmd_t qmp_cmds[]; + +Monitor *cur_mon; + +static void monitor_command_cb(void *opaque, const char *cmdline, + void *readline_opaque); + +/** + * Is @mon a QMP monitor? + */ +static inline bool monitor_is_qmp(const Monitor *mon) +{ + return (mon->flags & MONITOR_USE_CONTROL); +} + +/** + * Is the current monitor, if any, a QMP monitor? + */ +bool monitor_cur_is_qmp(void) +{ + return cur_mon && monitor_is_qmp(cur_mon); +} + +void monitor_read_command(Monitor *mon, int show_prompt) +{ + if (!mon->rs) + return; + + readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL); + if (show_prompt) + readline_show_prompt(mon->rs); +} + +int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, + void *opaque) +{ + if (mon->rs) { + readline_start(mon->rs, "Password: ", 1, readline_func, opaque); + /* prompt is printed on return from the command handler */ + return 0; + } else { + monitor_printf(mon, "terminal does not support password prompting\n"); + return -ENOTTY; + } +} + +static void monitor_flush_locked(Monitor *mon); + +static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond, + void *opaque) +{ + Monitor *mon = opaque; + + qemu_mutex_lock(&mon->out_lock); + mon->out_watch = 0; + monitor_flush_locked(mon); + qemu_mutex_unlock(&mon->out_lock); + return FALSE; +} + +/* Called with mon->out_lock held. */ +static void monitor_flush_locked(Monitor *mon) +{ + int rc; + size_t len; + const char *buf; + + if (mon->skip_flush) { + return; + } + + buf = qstring_get_str(mon->outbuf); + len = qstring_get_length(mon->outbuf); + + if (len && !mon->mux_out) { + rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len); + if ((rc < 0 && errno != EAGAIN) || (rc == len)) { + /* all flushed or error */ + QDECREF(mon->outbuf); + mon->outbuf = qstring_new(); + return; + } + if (rc > 0) { + /* partinal write */ + QString *tmp = qstring_from_str(buf + rc); + QDECREF(mon->outbuf); + mon->outbuf = tmp; + } + if (mon->out_watch == 0) { + mon->out_watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT|G_IO_HUP, + monitor_unblocked, mon); + } + } +} + +void monitor_flush(Monitor *mon) +{ + qemu_mutex_lock(&mon->out_lock); + monitor_flush_locked(mon); + qemu_mutex_unlock(&mon->out_lock); +} + +/* flush at every end of line */ +static void monitor_puts(Monitor *mon, const char *str) +{ + char c; + + qemu_mutex_lock(&mon->out_lock); + for(;;) { + c = *str++; + if (c == '\0') + break; + if (c == '\n') { + qstring_append_chr(mon->outbuf, '\r'); + } + qstring_append_chr(mon->outbuf, c); + if (c == '\n') { + monitor_flush_locked(mon); + } + } + qemu_mutex_unlock(&mon->out_lock); +} + +void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) +{ + char *buf; + + if (!mon) + return; + + if (monitor_is_qmp(mon)) { + return; + } + + buf = g_strdup_vprintf(fmt, ap); + monitor_puts(mon, buf); + g_free(buf); +} + +void monitor_printf(Monitor *mon, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + monitor_vprintf(mon, fmt, ap); + va_end(ap); +} + +int monitor_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + monitor_vprintf((Monitor *)stream, fmt, ap); + va_end(ap); + return 0; +} + +static void monitor_json_emitter(Monitor *mon, const QObject *data) +{ + QString *json; + + json = mon->flags & MONITOR_USE_PRETTY ? qobject_to_json_pretty(data) : + qobject_to_json(data); + assert(json != NULL); + + qstring_append_chr(json, '\n'); + monitor_puts(mon, qstring_get_str(json)); + + QDECREF(json); +} + +static QDict *build_qmp_error_dict(Error *err) +{ + QObject *obj; + + obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }", + ErrorClass_lookup[error_get_class(err)], + error_get_pretty(err)); + + return qobject_to_qdict(obj); +} + +static void monitor_protocol_emitter(Monitor *mon, QObject *data, + Error *err) +{ + QDict *qmp; + + trace_monitor_protocol_emitter(mon); + + if (!err) { + /* success response */ + qmp = qdict_new(); + if (data) { + qobject_incref(data); + qdict_put_obj(qmp, "return", data); + } else { + /* return an empty QDict by default */ + qdict_put(qmp, "return", qdict_new()); + } + } else { + /* error response */ + qmp = build_qmp_error_dict(err); + } + + if (mon->qmp.id) { + qdict_put_obj(qmp, "id", mon->qmp.id); + mon->qmp.id = NULL; + } + + monitor_json_emitter(mon, QOBJECT(qmp)); + QDECREF(qmp); +} + + +static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT_MAX] = { + /* Limit guest-triggerable events to 1 per second */ + [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS }, + [QAPI_EVENT_WATCHDOG] = { 1000 * SCALE_MS }, + [QAPI_EVENT_BALLOON_CHANGE] = { 1000 * SCALE_MS }, + [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS }, + [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS }, + [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS }, +}; + +GHashTable *monitor_qapi_event_state; + +/* + * Emits the event to every monitor instance, @event is only used for trace + * Called with monitor_lock held. + */ +static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) +{ + Monitor *mon; + + trace_monitor_protocol_event_emit(event, qdict); + QLIST_FOREACH(mon, &mon_list, entry) { + if (monitor_is_qmp(mon) && mon->qmp.in_command_mode) { + monitor_json_emitter(mon, QOBJECT(qdict)); + } + } +} + +static void monitor_qapi_event_handler(void *opaque); + +/* + * Queue a new event for emission to Monitor instances, + * applying any rate limiting if required. + */ +static void +monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp) +{ + MonitorQAPIEventConf *evconf; + MonitorQAPIEventState *evstate; + + assert(event < QAPI_EVENT_MAX); + evconf = &monitor_qapi_event_conf[event]; + trace_monitor_protocol_event_queue(event, qdict, evconf->rate); + + qemu_mutex_lock(&monitor_lock); + + if (!evconf->rate) { + /* Unthrottled event */ + monitor_qapi_event_emit(event, qdict); + } else { + QDict *data = qobject_to_qdict(qdict_get(qdict, "data")); + MonitorQAPIEventState key = { .event = event, .data = data }; + + evstate = g_hash_table_lookup(monitor_qapi_event_state, &key); + assert(!evstate || timer_pending(evstate->timer)); + + if (evstate) { + /* + * Timer is pending for (at least) evconf->rate ns after + * last send. Store event for sending when timer fires, + * replacing a prior stored event if any. + */ + QDECREF(evstate->qdict); + evstate->qdict = qdict; + QINCREF(evstate->qdict); + } else { + /* + * Last send was (at least) evconf->rate ns ago. + * Send immediately, and arm the timer to call + * monitor_qapi_event_handler() in evconf->rate ns. Any + * events arriving before then will be delayed until then. + */ + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + + monitor_qapi_event_emit(event, qdict); + + evstate = g_new(MonitorQAPIEventState, 1); + evstate->event = event; + evstate->data = data; + QINCREF(evstate->data); + evstate->qdict = NULL; + evstate->timer = timer_new_ns(QEMU_CLOCK_REALTIME, + monitor_qapi_event_handler, + evstate); + g_hash_table_add(monitor_qapi_event_state, evstate); + timer_mod_ns(evstate->timer, now + evconf->rate); + } + } + + qemu_mutex_unlock(&monitor_lock); +} + +/* + * This function runs evconf->rate ns after sending a throttled + * event. + * If another event has since been stored, send it. + */ +static void monitor_qapi_event_handler(void *opaque) +{ + MonitorQAPIEventState *evstate = opaque; + MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event]; + + trace_monitor_protocol_event_handler(evstate->event, evstate->qdict); + qemu_mutex_lock(&monitor_lock); + + if (evstate->qdict) { + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + + monitor_qapi_event_emit(evstate->event, evstate->qdict); + QDECREF(evstate->qdict); + evstate->qdict = NULL; + timer_mod_ns(evstate->timer, now + evconf->rate); + } else { + g_hash_table_remove(monitor_qapi_event_state, evstate); + QDECREF(evstate->data); + timer_free(evstate->timer); + g_free(evstate); + } + + qemu_mutex_unlock(&monitor_lock); +} + +static unsigned int qapi_event_throttle_hash(const void *key) +{ + const MonitorQAPIEventState *evstate = key; + unsigned int hash = evstate->event * 255; + + if (evstate->event == QAPI_EVENT_VSERPORT_CHANGE) { + hash += g_str_hash(qdict_get_str(evstate->data, "id")); + } + + return hash; +} + +static gboolean qapi_event_throttle_equal(const void *a, const void *b) +{ + const MonitorQAPIEventState *eva = a; + const MonitorQAPIEventState *evb = b; + + if (eva->event != evb->event) { + return FALSE; + } + + if (eva->event == QAPI_EVENT_VSERPORT_CHANGE) { + return !strcmp(qdict_get_str(eva->data, "id"), + qdict_get_str(evb->data, "id")); + } + + return TRUE; +} + +static void monitor_qapi_event_init(void) +{ + monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash, + qapi_event_throttle_equal); + qmp_event_set_func_emit(monitor_qapi_event_queue); +} + +static void qmp_capabilities(QDict *params, QObject **ret_data, Error **errp) +{ + cur_mon->qmp.in_command_mode = true; +} + +static void handle_hmp_command(Monitor *mon, const char *cmdline); + +static void monitor_data_init(Monitor *mon) +{ + memset(mon, 0, sizeof(Monitor)); + qemu_mutex_init(&mon->out_lock); + mon->outbuf = qstring_new(); + /* Use *mon_cmds by default. */ + mon->cmd_table = mon_cmds; +} + +static void monitor_data_destroy(Monitor *mon) +{ + QDECREF(mon->outbuf); + qemu_mutex_destroy(&mon->out_lock); +} + +char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, + int64_t cpu_index, Error **errp) +{ + char *output = NULL; + Monitor *old_mon, hmp; + + monitor_data_init(&hmp); + hmp.skip_flush = true; + + old_mon = cur_mon; + cur_mon = &hmp; + + if (has_cpu_index) { + int ret = monitor_set_cpu(cpu_index); + if (ret < 0) { + cur_mon = old_mon; + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", + "a CPU number"); + goto out; + } + } + + handle_hmp_command(&hmp, command_line); + cur_mon = old_mon; + + qemu_mutex_lock(&hmp.out_lock); + if (qstring_get_length(hmp.outbuf) > 0) { + output = g_strdup(qstring_get_str(hmp.outbuf)); + } else { + output = g_strdup(""); + } + qemu_mutex_unlock(&hmp.out_lock); + +out: + monitor_data_destroy(&hmp); + return output; +} + +static int compare_cmd(const char *name, const char *list) +{ + const char *p, *pstart; + int len; + len = strlen(name); + p = list; + for(;;) { + pstart = p; + p = strchr(p, '|'); + if (!p) + p = pstart + strlen(pstart); + if ((p - pstart) == len && !memcmp(pstart, name, len)) + return 1; + if (*p == '\0') + break; + p++; + } + return 0; +} + +static int get_str(char *buf, int buf_size, const char **pp) +{ + const char *p; + char *q; + int c; + + q = buf; + p = *pp; + while (qemu_isspace(*p)) { + p++; + } + if (*p == '\0') { + fail: + *q = '\0'; + *pp = p; + return -1; + } + if (*p == '\"') { + p++; + while (*p != '\0' && *p != '\"') { + if (*p == '\\') { + p++; + c = *p++; + switch (c) { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case '\\': + case '\'': + case '\"': + break; + default: + printf("unsupported escape code: '\\%c'\n", c); + goto fail; + } + if ((q - buf) < buf_size - 1) { + *q++ = c; + } + } else { + if ((q - buf) < buf_size - 1) { + *q++ = *p; + } + p++; + } + } + if (*p != '\"') { + printf("unterminated string\n"); + goto fail; + } + p++; + } else { + while (*p != '\0' && !qemu_isspace(*p)) { + if ((q - buf) < buf_size - 1) { + *q++ = *p; + } + p++; + } + } + *q = '\0'; + *pp = p; + return 0; +} + +#define MAX_ARGS 16 + +static void free_cmdline_args(char **args, int nb_args) +{ + int i; + + assert(nb_args <= MAX_ARGS); + + for (i = 0; i < nb_args; i++) { + g_free(args[i]); + } + +} + +/* + * Parse the command line to get valid args. + * @cmdline: command line to be parsed. + * @pnb_args: location to store the number of args, must NOT be NULL. + * @args: location to store the args, which should be freed by caller, must + * NOT be NULL. + * + * Returns 0 on success, negative on failure. + * + * NOTE: this parser is an approximate form of the real command parser. Number + * of args have a limit of MAX_ARGS. If cmdline contains more, it will + * return with failure. + */ +static int parse_cmdline(const char *cmdline, + int *pnb_args, char **args) +{ + const char *p; + int nb_args, ret; + char buf[1024]; + + p = cmdline; + nb_args = 0; + for (;;) { + while (qemu_isspace(*p)) { + p++; + } + if (*p == '\0') { + break; + } + if (nb_args >= MAX_ARGS) { + goto fail; + } + ret = get_str(buf, sizeof(buf), &p); + if (ret < 0) { + goto fail; + } + args[nb_args] = g_strdup(buf); + nb_args++; + } + *pnb_args = nb_args; + return 0; + + fail: + free_cmdline_args(args, nb_args); + return -1; +} + +static void help_cmd_dump_one(Monitor *mon, + const mon_cmd_t *cmd, + char **prefix_args, + int prefix_args_nb) +{ + int i; + + for (i = 0; i < prefix_args_nb; i++) { + monitor_printf(mon, "%s ", prefix_args[i]); + } + monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help); +} + +/* @args[@arg_index] is the valid command need to find in @cmds */ +static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds, + char **args, int nb_args, int arg_index) +{ + const mon_cmd_t *cmd; + + /* No valid arg need to compare with, dump all in *cmds */ + if (arg_index >= nb_args) { + for (cmd = cmds; cmd->name != NULL; cmd++) { + help_cmd_dump_one(mon, cmd, args, arg_index); + } + return; + } + + /* Find one entry to dump */ + for (cmd = cmds; cmd->name != NULL; cmd++) { + if (compare_cmd(args[arg_index], cmd->name)) { + if (cmd->sub_table) { + /* continue with next arg */ + help_cmd_dump(mon, cmd->sub_table, + args, nb_args, arg_index + 1); + } else { + help_cmd_dump_one(mon, cmd, args, arg_index); + } + break; + } + } +} + +static void help_cmd(Monitor *mon, const char *name) +{ + char *args[MAX_ARGS]; + int nb_args = 0; + + /* 1. parse user input */ + if (name) { + /* special case for log, directly dump and return */ + if (!strcmp(name, "log")) { + const QEMULogItem *item; + monitor_printf(mon, "Log items (comma separated):\n"); + monitor_printf(mon, "%-10s %s\n", "none", "remove all logs"); + for (item = qemu_log_items; item->mask != 0; item++) { + monitor_printf(mon, "%-10s %s\n", item->name, item->help); + } + return; + } + + if (parse_cmdline(name, &nb_args, args) < 0) { + return; + } + } + + /* 2. dump the contents according to parsed args */ + help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0); + + free_cmdline_args(args, nb_args); +} + +static void do_help_cmd(Monitor *mon, const QDict *qdict) +{ + help_cmd(mon, qdict_get_try_str(qdict, "name")); +} + +static void hmp_trace_event(Monitor *mon, const QDict *qdict) +{ + const char *tp_name = qdict_get_str(qdict, "name"); + bool new_state = qdict_get_bool(qdict, "option"); + Error *local_err = NULL; + + qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err); + if (local_err) { + error_report_err(local_err); + } +} + +#ifdef CONFIG_TRACE_SIMPLE +static void hmp_trace_file(Monitor *mon, const QDict *qdict) +{ + const char *op = qdict_get_try_str(qdict, "op"); + const char *arg = qdict_get_try_str(qdict, "arg"); + + if (!op) { + st_print_trace_file_status((FILE *)mon, &monitor_fprintf); + } else if (!strcmp(op, "on")) { + st_set_trace_file_enabled(true); + } else if (!strcmp(op, "off")) { + st_set_trace_file_enabled(false); + } else if (!strcmp(op, "flush")) { + st_flush_trace_buffer(); + } else if (!strcmp(op, "set")) { + if (arg) { + st_set_trace_file(arg); + } + } else { + monitor_printf(mon, "unexpected argument \"%s\"\n", op); + help_cmd(mon, "trace-file"); + } +} +#endif + +static void hmp_info_help(Monitor *mon, const QDict *qdict) +{ + help_cmd(mon, "info"); +} + +CommandInfoList *qmp_query_commands(Error **errp) +{ + CommandInfoList *info, *cmd_list = NULL; + const mon_cmd_t *cmd; + + for (cmd = qmp_cmds; cmd->name != NULL; cmd++) { + info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(cmd->name); + + info->next = cmd_list; + cmd_list = info; + } + + return cmd_list; +} + +EventInfoList *qmp_query_events(Error **errp) +{ + EventInfoList *info, *ev_list = NULL; + QAPIEvent e; + + for (e = 0 ; e < QAPI_EVENT_MAX ; e++) { + const char *event_name = QAPIEvent_lookup[e]; + assert(event_name != NULL); + info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(event_name); + + info->next = ev_list; + ev_list = info; + } + + return ev_list; +} + +/* + * Minor hack: generated marshalling suppressed for this command + * ('gen': false in the schema) so we can parse the JSON string + * directly into QObject instead of first parsing it with + * visit_type_SchemaInfoList() into a SchemaInfoList, then marshal it + * to QObject with generated output marshallers, every time. Instead, + * we do it in test-qmp-input-visitor.c, just to make sure + * qapi-introspect.py's output actually conforms to the schema. + */ +static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data, + Error **errp) +{ + *ret_data = qobject_from_json(qmp_schema_json); +} + +/* set the current CPU defined by the user */ +int monitor_set_cpu(int cpu_index) +{ + CPUState *cpu; + + cpu = qemu_get_cpu(cpu_index); + if (cpu == NULL) { + return -1; + } + cur_mon->mon_cpu = cpu; + return 0; +} + +CPUState *mon_get_cpu(void) +{ + if (!cur_mon->mon_cpu) { + monitor_set_cpu(0); + } + cpu_synchronize_state(cur_mon->mon_cpu); + return cur_mon->mon_cpu; +} + +CPUArchState *mon_get_cpu_env(void) +{ + return mon_get_cpu()->env_ptr; +} + +int monitor_get_cpu_index(void) +{ + return mon_get_cpu()->cpu_index; +} + +static void hmp_info_registers(Monitor *mon, const QDict *qdict) +{ + cpu_dump_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU); +} + +static void hmp_info_jit(Monitor *mon, const QDict *qdict) +{ + dump_exec_info((FILE *)mon, monitor_fprintf); + dump_drift_info((FILE *)mon, monitor_fprintf); +} + +static void hmp_info_opcount(Monitor *mon, const QDict *qdict) +{ + dump_opcount_info((FILE *)mon, monitor_fprintf); +} + +static void hmp_info_history(Monitor *mon, const QDict *qdict) +{ + int i; + const char *str; + + if (!mon->rs) + return; + i = 0; + for(;;) { + str = readline_get_history(mon->rs, i); + if (!str) + break; + monitor_printf(mon, "%d: '%s'\n", i, str); + i++; + } +} + +static void hmp_info_cpustats(Monitor *mon, const QDict *qdict) +{ + cpu_dump_statistics(mon_get_cpu(), (FILE *)mon, &monitor_fprintf, 0); +} + +static void hmp_info_trace_events(Monitor *mon, const QDict *qdict) +{ + TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL); + TraceEventInfoList *elem; + + for (elem = events; elem != NULL; elem = elem->next) { + monitor_printf(mon, "%s : state %u\n", + elem->value->name, + elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0); + } + qapi_free_TraceEventInfoList(events); +} + +void qmp_client_migrate_info(const char *protocol, const char *hostname, + bool has_port, int64_t port, + bool has_tls_port, int64_t tls_port, + bool has_cert_subject, const char *cert_subject, + Error **errp) +{ + if (strcmp(protocol, "spice") == 0) { + if (!qemu_using_spice(errp)) { + return; + } + + if (!has_port && !has_tls_port) { + error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port"); + return; + } + + if (qemu_spice_migrate_info(hostname, + has_port ? port : -1, + has_tls_port ? tls_port : -1, + cert_subject)) { + error_setg(errp, QERR_UNDEFINED_ERROR); + return; + } + return; + } + + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice"); +} + +static void hmp_logfile(Monitor *mon, const QDict *qdict) +{ + qemu_set_log_filename(qdict_get_str(qdict, "filename")); +} + +static void hmp_log(Monitor *mon, const QDict *qdict) +{ + int mask; + const char *items = qdict_get_str(qdict, "items"); + + if (!strcmp(items, "none")) { + mask = 0; + } else { + mask = qemu_str_to_log_mask(items); + if (!mask) { + help_cmd(mon, "log"); + return; + } + } + qemu_set_log(mask); +} + +static void hmp_singlestep(Monitor *mon, const QDict *qdict) +{ + const char *option = qdict_get_try_str(qdict, "option"); + if (!option || !strcmp(option, "on")) { + singlestep = 1; + } else if (!strcmp(option, "off")) { + singlestep = 0; + } else { + monitor_printf(mon, "unexpected option %s\n", option); + } +} + +static void hmp_gdbserver(Monitor *mon, const QDict *qdict) +{ + const char *device = qdict_get_try_str(qdict, "device"); + if (!device) + device = "tcp::" DEFAULT_GDBSTUB_PORT; + if (gdbserver_start(device) < 0) { + monitor_printf(mon, "Could not open gdbserver on device '%s'\n", + device); + } else if (strcmp(device, "none") == 0) { + monitor_printf(mon, "Disabled gdbserver\n"); + } else { + monitor_printf(mon, "Waiting for gdb connection on device '%s'\n", + device); + } +} + +static void hmp_watchdog_action(Monitor *mon, const QDict *qdict) +{ + const char *action = qdict_get_str(qdict, "action"); + if (select_watchdog_action(action) == -1) { + monitor_printf(mon, "Unknown watchdog action '%s'\n", action); + } +} + +static void monitor_printc(Monitor *mon, int c) +{ + monitor_printf(mon, "'"); + switch(c) { + case '\'': + monitor_printf(mon, "\\'"); + break; + case '\\': + monitor_printf(mon, "\\\\"); + break; + case '\n': + monitor_printf(mon, "\\n"); + break; + case '\r': + monitor_printf(mon, "\\r"); + break; + default: + if (c >= 32 && c <= 126) { + monitor_printf(mon, "%c", c); + } else { + monitor_printf(mon, "\\x%02x", c); + } + break; + } + monitor_printf(mon, "'"); +} + +static void memory_dump(Monitor *mon, int count, int format, int wsize, + hwaddr addr, int is_physical) +{ + int l, line_size, i, max_digits, len; + uint8_t buf[16]; + uint64_t v; + + if (format == 'i') { + int flags = 0; +#ifdef TARGET_I386 + CPUArchState *env = mon_get_cpu_env(); + if (wsize == 2) { + flags = 1; + } else if (wsize == 4) { + flags = 0; + } else { + /* as default we use the current CS size */ + flags = 0; + if (env) { +#ifdef TARGET_X86_64 + if ((env->efer & MSR_EFER_LMA) && + (env->segs[R_CS].flags & DESC_L_MASK)) + flags = 2; + else +#endif + if (!(env->segs[R_CS].flags & DESC_B_MASK)) + flags = 1; + } + } +#endif +#ifdef TARGET_PPC + CPUArchState *env = mon_get_cpu_env(); + flags = msr_le << 16; + flags |= env->bfd_mach; +#endif + monitor_disas(mon, mon_get_cpu(), addr, count, is_physical, flags); + return; + } + + len = wsize * count; + if (wsize == 1) + line_size = 8; + else + line_size = 16; + max_digits = 0; + + switch(format) { + case 'o': + max_digits = (wsize * 8 + 2) / 3; + break; + default: + case 'x': + max_digits = (wsize * 8) / 4; + break; + case 'u': + case 'd': + max_digits = (wsize * 8 * 10 + 32) / 33; + break; + case 'c': + wsize = 1; + break; + } + + while (len > 0) { + if (is_physical) + monitor_printf(mon, TARGET_FMT_plx ":", addr); + else + monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr); + l = len; + if (l > line_size) + l = line_size; + if (is_physical) { + cpu_physical_memory_read(addr, buf, l); + } else { + if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) { + monitor_printf(mon, " Cannot access memory\n"); + break; + } + } + i = 0; + while (i < l) { + switch(wsize) { + default: + case 1: + v = ldub_p(buf + i); + break; + case 2: + v = lduw_p(buf + i); + break; + case 4: + v = (uint32_t)ldl_p(buf + i); + break; + case 8: + v = ldq_p(buf + i); + break; + } + monitor_printf(mon, " "); + switch(format) { + case 'o': + monitor_printf(mon, "%#*" PRIo64, max_digits, v); + break; + case 'x': + monitor_printf(mon, "0x%0*" PRIx64, max_digits, v); + break; + case 'u': + monitor_printf(mon, "%*" PRIu64, max_digits, v); + break; + case 'd': + monitor_printf(mon, "%*" PRId64, max_digits, v); + break; + case 'c': + monitor_printc(mon, v); + break; + } + i += wsize; + } + monitor_printf(mon, "\n"); + addr += l; + len -= l; + } +} + +static void hmp_memory_dump(Monitor *mon, const QDict *qdict) +{ + int count = qdict_get_int(qdict, "count"); + int format = qdict_get_int(qdict, "format"); + int size = qdict_get_int(qdict, "size"); + target_long addr = qdict_get_int(qdict, "addr"); + + memory_dump(mon, count, format, size, addr, 0); +} + +static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict) +{ + int count = qdict_get_int(qdict, "count"); + int format = qdict_get_int(qdict, "format"); + int size = qdict_get_int(qdict, "size"); + hwaddr addr = qdict_get_int(qdict, "addr"); + + memory_dump(mon, count, format, size, addr, 1); +} + +static void do_print(Monitor *mon, const QDict *qdict) +{ + int format = qdict_get_int(qdict, "format"); + hwaddr val = qdict_get_int(qdict, "val"); + + switch(format) { + case 'o': + monitor_printf(mon, "%#" HWADDR_PRIo, val); + break; + case 'x': + monitor_printf(mon, "%#" HWADDR_PRIx, val); + break; + case 'u': + monitor_printf(mon, "%" HWADDR_PRIu, val); + break; + default: + case 'd': + monitor_printf(mon, "%" HWADDR_PRId, val); + break; + case 'c': + monitor_printc(mon, val); + break; + } + monitor_printf(mon, "\n"); +} + +static void hmp_sum(Monitor *mon, const QDict *qdict) +{ + uint32_t addr; + uint16_t sum; + uint32_t start = qdict_get_int(qdict, "start"); + uint32_t size = qdict_get_int(qdict, "size"); + + sum = 0; + for(addr = start; addr < (start + size); addr++) { + uint8_t val = address_space_ldub(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, NULL); + /* BSD sum algorithm ('sum' Unix command) */ + sum = (sum >> 1) | (sum << 15); + sum += val; + } + monitor_printf(mon, "%05d\n", sum); +} + +static int mouse_button_state; + +static void hmp_mouse_move(Monitor *mon, const QDict *qdict) +{ + int dx, dy, dz, button; + const char *dx_str = qdict_get_str(qdict, "dx_str"); + const char *dy_str = qdict_get_str(qdict, "dy_str"); + const char *dz_str = qdict_get_try_str(qdict, "dz_str"); + + dx = strtol(dx_str, NULL, 0); + dy = strtol(dy_str, NULL, 0); + qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx); + qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy); + + if (dz_str) { + dz = strtol(dz_str, NULL, 0); + if (dz != 0) { + button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; + qemu_input_queue_btn(NULL, button, true); + qemu_input_event_sync(); + qemu_input_queue_btn(NULL, button, false); + } + } + qemu_input_event_sync(); +} + +static void hmp_mouse_button(Monitor *mon, const QDict *qdict) +{ + static uint32_t bmap[INPUT_BUTTON_MAX] = { + [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, + [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, + [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, + }; + int button_state = qdict_get_int(qdict, "button_state"); + + if (mouse_button_state == button_state) { + return; + } + qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state); + qemu_input_event_sync(); + mouse_button_state = button_state; +} + +static void hmp_ioport_read(Monitor *mon, const QDict *qdict) +{ + int size = qdict_get_int(qdict, "size"); + int addr = qdict_get_int(qdict, "addr"); + int has_index = qdict_haskey(qdict, "index"); + uint32_t val; + int suffix; + + if (has_index) { + int index = qdict_get_int(qdict, "index"); + cpu_outb(addr & IOPORTS_MASK, index & 0xff); + addr++; + } + addr &= 0xffff; + + switch(size) { + default: + case 1: + val = cpu_inb(addr); + suffix = 'b'; + break; + case 2: + val = cpu_inw(addr); + suffix = 'w'; + break; + case 4: + val = cpu_inl(addr); + suffix = 'l'; + break; + } + monitor_printf(mon, "port%c[0x%04x] = %#0*x\n", + suffix, addr, size * 2, val); +} + +static void hmp_ioport_write(Monitor *mon, const QDict *qdict) +{ + int size = qdict_get_int(qdict, "size"); + int addr = qdict_get_int(qdict, "addr"); + int val = qdict_get_int(qdict, "val"); + + addr &= IOPORTS_MASK; + + switch (size) { + default: + case 1: + cpu_outb(addr, val); + break; + case 2: + cpu_outw(addr, val); + break; + case 4: + cpu_outl(addr, val); + break; + } +} + +static void hmp_boot_set(Monitor *mon, const QDict *qdict) +{ + Error *local_err = NULL; + const char *bootdevice = qdict_get_str(qdict, "bootdevice"); + + qemu_boot_set(bootdevice, &local_err); + if (local_err) { + monitor_printf(mon, "%s\n", error_get_pretty(local_err)); + error_free(local_err); + } else { + monitor_printf(mon, "boot device list now set to %s\n", bootdevice); + } +} + +static void hmp_info_mtree(Monitor *mon, const QDict *qdict) +{ + mtree_info((fprintf_function)monitor_printf, mon); +} + +static void hmp_info_numa(Monitor *mon, const QDict *qdict) +{ + int i; + CPUState *cpu; + uint64_t *node_mem; + + node_mem = g_new0(uint64_t, nb_numa_nodes); + query_numa_node_mem(node_mem); + monitor_printf(mon, "%d nodes\n", nb_numa_nodes); + for (i = 0; i < nb_numa_nodes; i++) { + monitor_printf(mon, "node %d cpus:", i); + CPU_FOREACH(cpu) { + if (cpu->numa_node == i) { + monitor_printf(mon, " %d", cpu->cpu_index); + } + } + monitor_printf(mon, "\n"); + monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i, + node_mem[i] >> 20); + } + g_free(node_mem); +} + +#ifdef CONFIG_PROFILER + +int64_t tcg_time; +int64_t dev_time; + +static void hmp_info_profile(Monitor *mon, const QDict *qdict) +{ + monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n", + dev_time, dev_time / (double)get_ticks_per_sec()); + monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n", + tcg_time, tcg_time / (double)get_ticks_per_sec()); + tcg_time = 0; + dev_time = 0; +} +#else +static void hmp_info_profile(Monitor *mon, const QDict *qdict) +{ + monitor_printf(mon, "Internal profiler not compiled\n"); +} +#endif + +/* Capture support */ +static QLIST_HEAD (capture_list_head, CaptureState) capture_head; + +static void hmp_info_capture(Monitor *mon, const QDict *qdict) +{ + int i; + CaptureState *s; + + for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { + monitor_printf(mon, "[%d]: ", i); + s->ops.info (s->opaque); + } +} + +static void hmp_stopcapture(Monitor *mon, const QDict *qdict) +{ + int i; + int n = qdict_get_int(qdict, "n"); + CaptureState *s; + + for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { + if (i == n) { + s->ops.destroy (s->opaque); + QLIST_REMOVE (s, entries); + g_free (s); + return; + } + } +} + +static void hmp_wavcapture(Monitor *mon, const QDict *qdict) +{ + const char *path = qdict_get_str(qdict, "path"); + int has_freq = qdict_haskey(qdict, "freq"); + int freq = qdict_get_try_int(qdict, "freq", -1); + int has_bits = qdict_haskey(qdict, "bits"); + int bits = qdict_get_try_int(qdict, "bits", -1); + int has_channels = qdict_haskey(qdict, "nchannels"); + int nchannels = qdict_get_try_int(qdict, "nchannels", -1); + CaptureState *s; + + s = g_malloc0 (sizeof (*s)); + + freq = has_freq ? freq : 44100; + bits = has_bits ? bits : 16; + nchannels = has_channels ? nchannels : 2; + + if (wav_start_capture (s, path, freq, bits, nchannels)) { + monitor_printf(mon, "Failed to add wave capture\n"); + g_free (s); + return; + } + QLIST_INSERT_HEAD (&capture_head, s, entries); +} + +static qemu_acl *find_acl(Monitor *mon, const char *name) +{ + qemu_acl *acl = qemu_acl_find(name); + + if (!acl) { + monitor_printf(mon, "acl: unknown list '%s'\n", name); + } + return acl; +} + +static void hmp_acl_show(Monitor *mon, const QDict *qdict) +{ + const char *aclname = qdict_get_str(qdict, "aclname"); + qemu_acl *acl = find_acl(mon, aclname); + qemu_acl_entry *entry; + int i = 0; + + if (acl) { + monitor_printf(mon, "policy: %s\n", + acl->defaultDeny ? "deny" : "allow"); + QTAILQ_FOREACH(entry, &acl->entries, next) { + i++; + monitor_printf(mon, "%d: %s %s\n", i, + entry->deny ? "deny" : "allow", entry->match); + } + } +} + +static void hmp_acl_reset(Monitor *mon, const QDict *qdict) +{ + const char *aclname = qdict_get_str(qdict, "aclname"); + qemu_acl *acl = find_acl(mon, aclname); + + if (acl) { + qemu_acl_reset(acl); + monitor_printf(mon, "acl: removed all rules\n"); + } +} + +static void hmp_acl_policy(Monitor *mon, const QDict *qdict) +{ + const char *aclname = qdict_get_str(qdict, "aclname"); + const char *policy = qdict_get_str(qdict, "policy"); + qemu_acl *acl = find_acl(mon, aclname); + + if (acl) { + if (strcmp(policy, "allow") == 0) { + acl->defaultDeny = 0; + monitor_printf(mon, "acl: policy set to 'allow'\n"); + } else if (strcmp(policy, "deny") == 0) { + acl->defaultDeny = 1; + monitor_printf(mon, "acl: policy set to 'deny'\n"); + } else { + monitor_printf(mon, "acl: unknown policy '%s', " + "expected 'deny' or 'allow'\n", policy); + } + } +} + +static void hmp_acl_add(Monitor *mon, const QDict *qdict) +{ + const char *aclname = qdict_get_str(qdict, "aclname"); + const char *match = qdict_get_str(qdict, "match"); + const char *policy = qdict_get_str(qdict, "policy"); + int has_index = qdict_haskey(qdict, "index"); + int index = qdict_get_try_int(qdict, "index", -1); + qemu_acl *acl = find_acl(mon, aclname); + int deny, ret; + + if (acl) { + if (strcmp(policy, "allow") == 0) { + deny = 0; + } else if (strcmp(policy, "deny") == 0) { + deny = 1; + } else { + monitor_printf(mon, "acl: unknown policy '%s', " + "expected 'deny' or 'allow'\n", policy); + return; + } + if (has_index) + ret = qemu_acl_insert(acl, deny, match, index); + else + ret = qemu_acl_append(acl, deny, match); + if (ret < 0) + monitor_printf(mon, "acl: unable to add acl entry\n"); + else + monitor_printf(mon, "acl: added rule at position %d\n", ret); + } +} + +static void hmp_acl_remove(Monitor *mon, const QDict *qdict) +{ + const char *aclname = qdict_get_str(qdict, "aclname"); + const char *match = qdict_get_str(qdict, "match"); + qemu_acl *acl = find_acl(mon, aclname); + int ret; + + if (acl) { + ret = qemu_acl_remove(acl, match); + if (ret < 0) + monitor_printf(mon, "acl: no matching acl entry\n"); + else + monitor_printf(mon, "acl: removed rule at position %d\n", ret); + } +} + +void qmp_getfd(const char *fdname, Error **errp) +{ + mon_fd_t *monfd; + int fd; + + fd = qemu_chr_fe_get_msgfd(cur_mon->chr); + if (fd == -1) { + error_setg(errp, QERR_FD_NOT_SUPPLIED); + return; + } + + if (qemu_isdigit(fdname[0])) { + close(fd); + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname", + "a name not starting with a digit"); + return; + } + + QLIST_FOREACH(monfd, &cur_mon->fds, next) { + if (strcmp(monfd->name, fdname) != 0) { + continue; + } + + close(monfd->fd); + monfd->fd = fd; + return; + } + + monfd = g_malloc0(sizeof(mon_fd_t)); + monfd->name = g_strdup(fdname); + monfd->fd = fd; + + QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next); +} + +void qmp_closefd(const char *fdname, Error **errp) +{ + mon_fd_t *monfd; + + QLIST_FOREACH(monfd, &cur_mon->fds, next) { + if (strcmp(monfd->name, fdname) != 0) { + continue; + } + + QLIST_REMOVE(monfd, next); + close(monfd->fd); + g_free(monfd->name); + g_free(monfd); + return; + } + + error_setg(errp, QERR_FD_NOT_FOUND, fdname); +} + +static void hmp_loadvm(Monitor *mon, const QDict *qdict) +{ + int saved_vm_running = runstate_is_running(); + const char *name = qdict_get_str(qdict, "name"); + + vm_stop(RUN_STATE_RESTORE_VM); + + if (load_vmstate(name) == 0 && saved_vm_running) { + vm_start(); + } +} + +int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) +{ + mon_fd_t *monfd; + + QLIST_FOREACH(monfd, &mon->fds, next) { + int fd; + + if (strcmp(monfd->name, fdname) != 0) { + continue; + } + + fd = monfd->fd; + + /* caller takes ownership of fd */ + QLIST_REMOVE(monfd, next); + g_free(monfd->name); + g_free(monfd); + + return fd; + } + + error_setg(errp, "File descriptor named '%s' has not been found", fdname); + return -1; +} + +static void monitor_fdset_cleanup(MonFdset *mon_fdset) +{ + MonFdsetFd *mon_fdset_fd; + MonFdsetFd *mon_fdset_fd_next; + + QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) { + if ((mon_fdset_fd->removed || + (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) && + runstate_is_running()) { + close(mon_fdset_fd->fd); + g_free(mon_fdset_fd->opaque); + QLIST_REMOVE(mon_fdset_fd, next); + g_free(mon_fdset_fd); + } + } + + if (QLIST_EMPTY(&mon_fdset->fds) && QLIST_EMPTY(&mon_fdset->dup_fds)) { + QLIST_REMOVE(mon_fdset, next); + g_free(mon_fdset); + } +} + +static void monitor_fdsets_cleanup(void) +{ + MonFdset *mon_fdset; + MonFdset *mon_fdset_next; + + QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) { + monitor_fdset_cleanup(mon_fdset); + } +} + +AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, + const char *opaque, Error **errp) +{ + int fd; + Monitor *mon = cur_mon; + AddfdInfo *fdinfo; + + fd = qemu_chr_fe_get_msgfd(mon->chr); + if (fd == -1) { + error_setg(errp, QERR_FD_NOT_SUPPLIED); + goto error; + } + + fdinfo = monitor_fdset_add_fd(fd, has_fdset_id, fdset_id, + has_opaque, opaque, errp); + if (fdinfo) { + return fdinfo; + } + +error: + if (fd != -1) { + close(fd); + } + return NULL; +} + +void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) +{ + MonFdset *mon_fdset; + MonFdsetFd *mon_fdset_fd; + char fd_str[60]; + + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + if (mon_fdset->id != fdset_id) { + continue; + } + QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { + if (has_fd) { + if (mon_fdset_fd->fd != fd) { + continue; + } + mon_fdset_fd->removed = true; + break; + } else { + mon_fdset_fd->removed = true; + } + } + if (has_fd && !mon_fdset_fd) { + goto error; + } + monitor_fdset_cleanup(mon_fdset); + return; + } + +error: + if (has_fd) { + snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64, + fdset_id, fd); + } else { + snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64, fdset_id); + } + error_setg(errp, QERR_FD_NOT_FOUND, fd_str); +} + +FdsetInfoList *qmp_query_fdsets(Error **errp) +{ + MonFdset *mon_fdset; + MonFdsetFd *mon_fdset_fd; + FdsetInfoList *fdset_list = NULL; + + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info)); + FdsetFdInfoList *fdsetfd_list = NULL; + + fdset_info->value = g_malloc0(sizeof(*fdset_info->value)); + fdset_info->value->fdset_id = mon_fdset->id; + + QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { + FdsetFdInfoList *fdsetfd_info; + + fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info)); + fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value)); + fdsetfd_info->value->fd = mon_fdset_fd->fd; + if (mon_fdset_fd->opaque) { + fdsetfd_info->value->has_opaque = true; + fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque); + } else { + fdsetfd_info->value->has_opaque = false; + } + + fdsetfd_info->next = fdsetfd_list; + fdsetfd_list = fdsetfd_info; + } + + fdset_info->value->fds = fdsetfd_list; + + fdset_info->next = fdset_list; + fdset_list = fdset_info; + } + + return fdset_list; +} + +AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id, + bool has_opaque, const char *opaque, + Error **errp) +{ + MonFdset *mon_fdset = NULL; + MonFdsetFd *mon_fdset_fd; + AddfdInfo *fdinfo; + + if (has_fdset_id) { + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + /* Break if match found or match impossible due to ordering by ID */ + if (fdset_id <= mon_fdset->id) { + if (fdset_id < mon_fdset->id) { + mon_fdset = NULL; + } + break; + } + } + } + + if (mon_fdset == NULL) { + int64_t fdset_id_prev = -1; + MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets); + + if (has_fdset_id) { + if (fdset_id < 0) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id", + "a non-negative value"); + return NULL; + } + /* Use specified fdset ID */ + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + mon_fdset_cur = mon_fdset; + if (fdset_id < mon_fdset_cur->id) { + break; + } + } + } else { + /* Use first available fdset ID */ + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + mon_fdset_cur = mon_fdset; + if (fdset_id_prev == mon_fdset_cur->id - 1) { + fdset_id_prev = mon_fdset_cur->id; + continue; + } + break; + } + } + + mon_fdset = g_malloc0(sizeof(*mon_fdset)); + if (has_fdset_id) { + mon_fdset->id = fdset_id; + } else { + mon_fdset->id = fdset_id_prev + 1; + } + + /* The fdset list is ordered by fdset ID */ + if (!mon_fdset_cur) { + QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next); + } else if (mon_fdset->id < mon_fdset_cur->id) { + QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next); + } else { + QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next); + } + } + + mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd)); + mon_fdset_fd->fd = fd; + mon_fdset_fd->removed = false; + if (has_opaque) { + mon_fdset_fd->opaque = g_strdup(opaque); + } + QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next); + + fdinfo = g_malloc0(sizeof(*fdinfo)); + fdinfo->fdset_id = mon_fdset->id; + fdinfo->fd = mon_fdset_fd->fd; + + return fdinfo; +} + +int monitor_fdset_get_fd(int64_t fdset_id, int flags) +{ +#ifndef _WIN32 + MonFdset *mon_fdset; + MonFdsetFd *mon_fdset_fd; + int mon_fd_flags; + + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + if (mon_fdset->id != fdset_id) { + continue; + } + QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { + mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL); + if (mon_fd_flags == -1) { + return -1; + } + + if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) { + return mon_fdset_fd->fd; + } + } + errno = EACCES; + return -1; + } +#endif + + errno = ENOENT; + return -1; +} + +int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd) +{ + MonFdset *mon_fdset; + MonFdsetFd *mon_fdset_fd_dup; + + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + if (mon_fdset->id != fdset_id) { + continue; + } + QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { + if (mon_fdset_fd_dup->fd == dup_fd) { + return -1; + } + } + mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup)); + mon_fdset_fd_dup->fd = dup_fd; + QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next); + return 0; + } + return -1; +} + +static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove) +{ + MonFdset *mon_fdset; + MonFdsetFd *mon_fdset_fd_dup; + + QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { + QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { + if (mon_fdset_fd_dup->fd == dup_fd) { + if (remove) { + QLIST_REMOVE(mon_fdset_fd_dup, next); + if (QLIST_EMPTY(&mon_fdset->dup_fds)) { + monitor_fdset_cleanup(mon_fdset); + } + return -1; + } else { + return mon_fdset->id; + } + } + } + } + return -1; +} + +int monitor_fdset_dup_fd_find(int dup_fd) +{ + return monitor_fdset_dup_fd_find_remove(dup_fd, false); +} + +void monitor_fdset_dup_fd_remove(int dup_fd) +{ + monitor_fdset_dup_fd_find_remove(dup_fd, true); +} + +int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp) +{ + int fd; + Error *local_err = NULL; + + if (!qemu_isdigit(fdname[0]) && mon) { + fd = monitor_get_fd(mon, fdname, &local_err); + } else { + fd = qemu_parse_fd(fdname); + if (fd == -1) { + error_setg(&local_err, "Invalid file descriptor number '%s'", + fdname); + } + } + if (local_err) { + error_propagate(errp, local_err); + assert(fd == -1); + } else { + assert(fd != -1); + } + + return fd; +} + +/* Please update hmp-commands.hx when adding or changing commands */ +static mon_cmd_t info_cmds[] = { +#include "hmp-commands-info.h" + { NULL, NULL, }, +}; + +/* mon_cmds and info_cmds would be sorted at runtime */ +static mon_cmd_t mon_cmds[] = { +#include "hmp-commands.h" + { NULL, NULL, }, +}; + +static const mon_cmd_t qmp_cmds[] = { +#include "qmp-commands-old.h" + { /* NULL */ }, +}; + +/*******************************************************************/ + +static const char *pch; +static sigjmp_buf expr_env; + +static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN +expr_error(Monitor *mon, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + monitor_vprintf(mon, fmt, ap); + monitor_printf(mon, "\n"); + va_end(ap); + siglongjmp(expr_env, 1); +} + +/* return 0 if OK, -1 if not found */ +static int get_monitor_def(target_long *pval, const char *name) +{ + const MonitorDef *md = target_monitor_defs(); + void *ptr; + uint64_t tmp = 0; + int ret; + + if (md == NULL) { + return -1; + } + + for(; md->name != NULL; md++) { + if (compare_cmd(name, md->name)) { + if (md->get_value) { + *pval = md->get_value(md, md->offset); + } else { + CPUArchState *env = mon_get_cpu_env(); + ptr = (uint8_t *)env + md->offset; + switch(md->type) { + case MD_I32: + *pval = *(int32_t *)ptr; + break; + case MD_TLONG: + *pval = *(target_long *)ptr; + break; + default: + *pval = 0; + break; + } + } + return 0; + } + } + + ret = target_get_monitor_def(mon_get_cpu(), name, &tmp); + if (!ret) { + *pval = (target_long) tmp; + } + + return ret; +} + +static void next(void) +{ + if (*pch != '\0') { + pch++; + while (qemu_isspace(*pch)) + pch++; + } +} + +static int64_t expr_sum(Monitor *mon); + +static int64_t expr_unary(Monitor *mon) +{ + int64_t n; + char *p; + int ret; + + switch(*pch) { + case '+': + next(); + n = expr_unary(mon); + break; + case '-': + next(); + n = -expr_unary(mon); + break; + case '~': + next(); + n = ~expr_unary(mon); + break; + case '(': + next(); + n = expr_sum(mon); + if (*pch != ')') { + expr_error(mon, "')' expected"); + } + next(); + break; + case '\'': + pch++; + if (*pch == '\0') + expr_error(mon, "character constant expected"); + n = *pch; + pch++; + if (*pch != '\'') + expr_error(mon, "missing terminating \' character"); + next(); + break; + case '$': + { + char buf[128], *q; + target_long reg=0; + + pch++; + q = buf; + while ((*pch >= 'a' && *pch <= 'z') || + (*pch >= 'A' && *pch <= 'Z') || + (*pch >= '0' && *pch <= '9') || + *pch == '_' || *pch == '.') { + if ((q - buf) < sizeof(buf) - 1) + *q++ = *pch; + pch++; + } + while (qemu_isspace(*pch)) + pch++; + *q = 0; + ret = get_monitor_def(®, buf); + if (ret < 0) + expr_error(mon, "unknown register"); + n = reg; + } + break; + case '\0': + expr_error(mon, "unexpected end of expression"); + n = 0; + break; + default: + errno = 0; + n = strtoull(pch, &p, 0); + if (errno == ERANGE) { + expr_error(mon, "number too large"); + } + if (pch == p) { + expr_error(mon, "invalid char '%c' in expression", *p); + } + pch = p; + while (qemu_isspace(*pch)) + pch++; + break; + } + return n; +} + + +static int64_t expr_prod(Monitor *mon) +{ + int64_t val, val2; + int op; + + val = expr_unary(mon); + for(;;) { + op = *pch; + if (op != '*' && op != '/' && op != '%') + break; + next(); + val2 = expr_unary(mon); + switch(op) { + default: + case '*': + val *= val2; + break; + case '/': + case '%': + if (val2 == 0) + expr_error(mon, "division by zero"); + if (op == '/') + val /= val2; + else + val %= val2; + break; + } + } + return val; +} + +static int64_t expr_logic(Monitor *mon) +{ + int64_t val, val2; + int op; + + val = expr_prod(mon); + for(;;) { + op = *pch; + if (op != '&' && op != '|' && op != '^') + break; + next(); + val2 = expr_prod(mon); + switch(op) { + default: + case '&': + val &= val2; + break; + case '|': + val |= val2; + break; + case '^': + val ^= val2; + break; + } + } + return val; +} + +static int64_t expr_sum(Monitor *mon) +{ + int64_t val, val2; + int op; + + val = expr_logic(mon); + for(;;) { + op = *pch; + if (op != '+' && op != '-') + break; + next(); + val2 = expr_logic(mon); + if (op == '+') + val += val2; + else + val -= val2; + } + return val; +} + +static int get_expr(Monitor *mon, int64_t *pval, const char **pp) +{ + pch = *pp; + if (sigsetjmp(expr_env, 0)) { + *pp = pch; + return -1; + } + while (qemu_isspace(*pch)) + pch++; + *pval = expr_sum(mon); + *pp = pch; + return 0; +} + +static int get_double(Monitor *mon, double *pval, const char **pp) +{ + const char *p = *pp; + char *tailp; + double d; + + d = strtod(p, &tailp); + if (tailp == p) { + monitor_printf(mon, "Number expected\n"); + return -1; + } + if (d != d || d - d != 0) { + /* NaN or infinity */ + monitor_printf(mon, "Bad number\n"); + return -1; + } + *pval = d; + *pp = tailp; + return 0; +} + +/* + * Store the command-name in cmdname, and return a pointer to + * the remaining of the command string. + */ +static const char *get_command_name(const char *cmdline, + char *cmdname, size_t nlen) +{ + size_t len; + const char *p, *pstart; + + p = cmdline; + while (qemu_isspace(*p)) + p++; + if (*p == '\0') + return NULL; + pstart = p; + while (*p != '\0' && *p != '/' && !qemu_isspace(*p)) + p++; + len = p - pstart; + if (len > nlen - 1) + len = nlen - 1; + memcpy(cmdname, pstart, len); + cmdname[len] = '\0'; + return p; +} + +/** + * Read key of 'type' into 'key' and return the current + * 'type' pointer. + */ +static char *key_get_info(const char *type, char **key) +{ + size_t len; + char *p, *str; + + if (*type == ',') + type++; + + p = strchr(type, ':'); + if (!p) { + *key = NULL; + return NULL; + } + len = p - type; + + str = g_malloc(len + 1); + memcpy(str, type, len); + str[len] = '\0'; + + *key = str; + return ++p; +} + +static int default_fmt_format = 'x'; +static int default_fmt_size = 4; + +static int is_valid_option(const char *c, const char *typestr) +{ + char option[3]; + + option[0] = '-'; + option[1] = *c; + option[2] = '\0'; + + typestr = strstr(typestr, option); + return (typestr != NULL); +} + +static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table, + const char *cmdname) +{ + const mon_cmd_t *cmd; + + for (cmd = disp_table; cmd->name != NULL; cmd++) { + if (compare_cmd(cmdname, cmd->name)) { + return cmd; + } + } + + return NULL; +} + +static const mon_cmd_t *qmp_find_cmd(const char *cmdname) +{ + return search_dispatch_table(qmp_cmds, cmdname); +} + +/* + * Parse command name from @cmdp according to command table @table. + * If blank, return NULL. + * Else, if no valid command can be found, report to @mon, and return + * NULL. + * Else, change @cmdp to point right behind the name, and return its + * command table entry. + * Do not assume the return value points into @table! It doesn't when + * the command is found in a sub-command table. + */ +static const mon_cmd_t *monitor_parse_command(Monitor *mon, + const char **cmdp, + mon_cmd_t *table) +{ + const char *p; + const mon_cmd_t *cmd; + char cmdname[256]; + + /* extract the command name */ + p = get_command_name(*cmdp, cmdname, sizeof(cmdname)); + if (!p) + return NULL; + + cmd = search_dispatch_table(table, cmdname); + if (!cmd) { + monitor_printf(mon, "unknown command: '%.*s'\n", + (int)(p - *cmdp), *cmdp); + return NULL; + } + + /* filter out following useless space */ + while (qemu_isspace(*p)) { + p++; + } + + *cmdp = p; + /* search sub command */ + if (cmd->sub_table != NULL && *p != '\0') { + return monitor_parse_command(mon, cmdp, cmd->sub_table); + } + + return cmd; +} + +/* + * Parse arguments for @cmd. + * If it can't be parsed, report to @mon, and return NULL. + * Else, insert command arguments into a QDict, and return it. + * Note: On success, caller has to free the QDict structure. + */ + +static QDict *monitor_parse_arguments(Monitor *mon, + const char **endp, + const mon_cmd_t *cmd) +{ + const char *typestr; + char *key; + int c; + const char *p = *endp; + char buf[1024]; + QDict *qdict = qdict_new(); + + /* parse the parameters */ + typestr = cmd->args_type; + for(;;) { + typestr = key_get_info(typestr, &key); + if (!typestr) + break; + c = *typestr; + typestr++; + switch(c) { + case 'F': + case 'B': + case 's': + { + int ret; + + while (qemu_isspace(*p)) + p++; + if (*typestr == '?') { + typestr++; + if (*p == '\0') { + /* no optional string: NULL argument */ + break; + } + } + ret = get_str(buf, sizeof(buf), &p); + if (ret < 0) { + switch(c) { + case 'F': + monitor_printf(mon, "%s: filename expected\n", + cmd->name); + break; + case 'B': + monitor_printf(mon, "%s: block device name expected\n", + cmd->name); + break; + default: + monitor_printf(mon, "%s: string expected\n", cmd->name); + break; + } + goto fail; + } + qdict_put(qdict, key, qstring_from_str(buf)); + } + break; + case 'O': + { + QemuOptsList *opts_list; + QemuOpts *opts; + + opts_list = qemu_find_opts(key); + if (!opts_list || opts_list->desc->name) { + goto bad_type; + } + while (qemu_isspace(*p)) { + p++; + } + if (!*p) + break; + if (get_str(buf, sizeof(buf), &p) < 0) { + goto fail; + } + opts = qemu_opts_parse_noisily(opts_list, buf, true); + if (!opts) { + goto fail; + } + qemu_opts_to_qdict(opts, qdict); + qemu_opts_del(opts); + } + break; + case '/': + { + int count, format, size; + + while (qemu_isspace(*p)) + p++; + if (*p == '/') { + /* format found */ + p++; + count = 1; + if (qemu_isdigit(*p)) { + count = 0; + while (qemu_isdigit(*p)) { + count = count * 10 + (*p - '0'); + p++; + } + } + size = -1; + format = -1; + for(;;) { + switch(*p) { + case 'o': + case 'd': + case 'u': + case 'x': + case 'i': + case 'c': + format = *p++; + break; + case 'b': + size = 1; + p++; + break; + case 'h': + size = 2; + p++; + break; + case 'w': + size = 4; + p++; + break; + case 'g': + case 'L': + size = 8; + p++; + break; + default: + goto next; + } + } + next: + if (*p != '\0' && !qemu_isspace(*p)) { + monitor_printf(mon, "invalid char in format: '%c'\n", + *p); + goto fail; + } + if (format < 0) + format = default_fmt_format; + if (format != 'i') { + /* for 'i', not specifying a size gives -1 as size */ + if (size < 0) + size = default_fmt_size; + default_fmt_size = size; + } + default_fmt_format = format; + } else { + count = 1; + format = default_fmt_format; + if (format != 'i') { + size = default_fmt_size; + } else { + size = -1; + } + } + qdict_put(qdict, "count", qint_from_int(count)); + qdict_put(qdict, "format", qint_from_int(format)); + qdict_put(qdict, "size", qint_from_int(size)); + } + break; + case 'i': + case 'l': + case 'M': + { + int64_t val; + + while (qemu_isspace(*p)) + p++; + if (*typestr == '?' || *typestr == '.') { + if (*typestr == '?') { + if (*p == '\0') { + typestr++; + break; + } + } else { + if (*p == '.') { + p++; + while (qemu_isspace(*p)) + p++; + } else { + typestr++; + break; + } + } + typestr++; + } + if (get_expr(mon, &val, &p)) + goto fail; + /* Check if 'i' is greater than 32-bit */ + if ((c == 'i') && ((val >> 32) & 0xffffffff)) { + monitor_printf(mon, "\'%s\' has failed: ", cmd->name); + monitor_printf(mon, "integer is for 32-bit values\n"); + goto fail; + } else if (c == 'M') { + if (val < 0) { + monitor_printf(mon, "enter a positive value\n"); + goto fail; + } + val <<= 20; + } + qdict_put(qdict, key, qint_from_int(val)); + } + break; + case 'o': + { + int64_t val; + char *end; + + while (qemu_isspace(*p)) { + p++; + } + if (*typestr == '?') { + typestr++; + if (*p == '\0') { + break; + } + } + val = qemu_strtosz(p, &end); + if (val < 0) { + monitor_printf(mon, "invalid size\n"); + goto fail; + } + qdict_put(qdict, key, qint_from_int(val)); + p = end; + } + break; + case 'T': + { + double val; + + while (qemu_isspace(*p)) + p++; + if (*typestr == '?') { + typestr++; + if (*p == '\0') { + break; + } + } + if (get_double(mon, &val, &p) < 0) { + goto fail; + } + if (p[0] && p[1] == 's') { + switch (*p) { + case 'm': + val /= 1e3; p += 2; break; + case 'u': + val /= 1e6; p += 2; break; + case 'n': + val /= 1e9; p += 2; break; + } + } + if (*p && !qemu_isspace(*p)) { + monitor_printf(mon, "Unknown unit suffix\n"); + goto fail; + } + qdict_put(qdict, key, qfloat_from_double(val)); + } + break; + case 'b': + { + const char *beg; + bool val; + + while (qemu_isspace(*p)) { + p++; + } + beg = p; + while (qemu_isgraph(*p)) { + p++; + } + if (p - beg == 2 && !memcmp(beg, "on", p - beg)) { + val = true; + } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) { + val = false; + } else { + monitor_printf(mon, "Expected 'on' or 'off'\n"); + goto fail; + } + qdict_put(qdict, key, qbool_from_bool(val)); + } + break; + case '-': + { + const char *tmp = p; + int skip_key = 0; + /* option */ + + c = *typestr++; + if (c == '\0') + goto bad_type; + while (qemu_isspace(*p)) + p++; + if (*p == '-') { + p++; + if(c != *p) { + if(!is_valid_option(p, typestr)) { + + monitor_printf(mon, "%s: unsupported option -%c\n", + cmd->name, *p); + goto fail; + } else { + skip_key = 1; + } + } + if(skip_key) { + p = tmp; + } else { + /* has option */ + p++; + qdict_put(qdict, key, qbool_from_bool(true)); + } + } + } + break; + case 'S': + { + /* package all remaining string */ + int len; + + while (qemu_isspace(*p)) { + p++; + } + if (*typestr == '?') { + typestr++; + if (*p == '\0') { + /* no remaining string: NULL argument */ + break; + } + } + len = strlen(p); + if (len <= 0) { + monitor_printf(mon, "%s: string expected\n", + cmd->name); + goto fail; + } + qdict_put(qdict, key, qstring_from_str(p)); + p += len; + } + break; + default: + bad_type: + monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c); + goto fail; + } + g_free(key); + key = NULL; + } + /* check that all arguments were parsed */ + while (qemu_isspace(*p)) + p++; + if (*p != '\0') { + monitor_printf(mon, "%s: extraneous characters at the end of line\n", + cmd->name); + goto fail; + } + + return qdict; + +fail: + QDECREF(qdict); + g_free(key); + return NULL; +} + +static void handle_hmp_command(Monitor *mon, const char *cmdline) +{ + QDict *qdict; + const mon_cmd_t *cmd; + + cmd = monitor_parse_command(mon, &cmdline, mon->cmd_table); + if (!cmd) { + return; + } + + qdict = monitor_parse_arguments(mon, &cmdline, cmd); + if (!qdict) { + monitor_printf(mon, "Try \"help %s\" for more information\n", + cmd->name); + return; + } + + cmd->mhandler.cmd(mon, qdict); + QDECREF(qdict); +} + +static void cmd_completion(Monitor *mon, const char *name, const char *list) +{ + const char *p, *pstart; + char cmd[128]; + int len; + + p = list; + for(;;) { + pstart = p; + p = strchr(p, '|'); + if (!p) + p = pstart + strlen(pstart); + len = p - pstart; + if (len > sizeof(cmd) - 2) + len = sizeof(cmd) - 2; + memcpy(cmd, pstart, len); + cmd[len] = '\0'; + if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { + readline_add_completion(mon->rs, cmd); + } + if (*p == '\0') + break; + p++; + } +} + +static void file_completion(Monitor *mon, const char *input) +{ + DIR *ffs; + struct dirent *d; + char path[1024]; + char file[1024], file_prefix[1024]; + int input_path_len; + const char *p; + + p = strrchr(input, '/'); + if (!p) { + input_path_len = 0; + pstrcpy(file_prefix, sizeof(file_prefix), input); + pstrcpy(path, sizeof(path), "."); + } else { + input_path_len = p - input + 1; + memcpy(path, input, input_path_len); + if (input_path_len > sizeof(path) - 1) + input_path_len = sizeof(path) - 1; + path[input_path_len] = '\0'; + pstrcpy(file_prefix, sizeof(file_prefix), p + 1); + } + + ffs = opendir(path); + if (!ffs) + return; + for(;;) { + struct stat sb; + d = readdir(ffs); + if (!d) + break; + + if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) { + continue; + } + + if (strstart(d->d_name, file_prefix, NULL)) { + memcpy(file, input, input_path_len); + if (input_path_len < sizeof(file)) + pstrcpy(file + input_path_len, sizeof(file) - input_path_len, + d->d_name); + /* stat the file to find out if it's a directory. + * In that case add a slash to speed up typing long paths + */ + if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) { + pstrcat(file, sizeof(file), "/"); + } + readline_add_completion(mon->rs, file); + } + } + closedir(ffs); +} + +static const char *next_arg_type(const char *typestr) +{ + const char *p = strchr(typestr, ':'); + return (p != NULL ? ++p : typestr); +} + +static void add_completion_option(ReadLineState *rs, const char *str, + const char *option) +{ + if (!str || !option) { + return; + } + if (!strncmp(option, str, strlen(str))) { + readline_add_completion(rs, option); + } +} + +void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str) +{ + size_t len; + ChardevBackendInfoList *list, *start; + + if (nb_args != 2) { + return; + } + len = strlen(str); + readline_set_completion_index(rs, len); + + start = list = qmp_query_chardev_backends(NULL); + while (list) { + const char *chr_name = list->value->name; + + if (!strncmp(chr_name, str, len)) { + readline_add_completion(rs, chr_name); + } + list = list->next; + } + qapi_free_ChardevBackendInfoList(start); +} + +void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) +{ + size_t len; + int i; + + if (nb_args != 2) { + return; + } + len = strlen(str); + readline_set_completion_index(rs, len); + for (i = 0; NetClientOptionsKind_lookup[i]; i++) { + add_completion_option(rs, str, NetClientOptionsKind_lookup[i]); + } +} + +void device_add_completion(ReadLineState *rs, int nb_args, const char *str) +{ + GSList *list, *elt; + size_t len; + + if (nb_args != 2) { + return; + } + + len = strlen(str); + readline_set_completion_index(rs, len); + list = elt = object_class_get_list(TYPE_DEVICE, false); + while (elt) { + const char *name; + DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data, + TYPE_DEVICE); + name = object_class_get_name(OBJECT_CLASS(dc)); + + if (!dc->cannot_instantiate_with_device_add_yet + && !strncmp(name, str, len)) { + readline_add_completion(rs, name); + } + elt = elt->next; + } + g_slist_free(list); +} + +void object_add_completion(ReadLineState *rs, int nb_args, const char *str) +{ + GSList *list, *elt; + size_t len; + + if (nb_args != 2) { + return; + } + + len = strlen(str); + readline_set_completion_index(rs, len); + list = elt = object_class_get_list(TYPE_USER_CREATABLE, false); + while (elt) { + const char *name; + + name = object_class_get_name(OBJECT_CLASS(elt->data)); + if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) { + readline_add_completion(rs, name); + } + elt = elt->next; + } + g_slist_free(list); +} + +static void peripheral_device_del_completion(ReadLineState *rs, + const char *str, size_t len) +{ + Object *peripheral = container_get(qdev_get_machine(), "/peripheral"); + GSList *list, *item; + + list = qdev_build_hotpluggable_device_list(peripheral); + if (!list) { + return; + } + + for (item = list; item; item = g_slist_next(item)) { + DeviceState *dev = item->data; + + if (dev->id && !strncmp(str, dev->id, len)) { + readline_add_completion(rs, dev->id); + } + } + + g_slist_free(list); +} + +void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) +{ + size_t len; + ChardevInfoList *list, *start; + + if (nb_args != 2) { + return; + } + len = strlen(str); + readline_set_completion_index(rs, len); + + start = list = qmp_query_chardev(NULL); + while (list) { + ChardevInfo *chr = list->value; + + if (!strncmp(chr->label, str, len)) { + readline_add_completion(rs, chr->label); + } + list = list->next; + } + qapi_free_ChardevInfoList(start); +} + +static void ringbuf_completion(ReadLineState *rs, const char *str) +{ + size_t len; + ChardevInfoList *list, *start; + + len = strlen(str); + readline_set_completion_index(rs, len); + + start = list = qmp_query_chardev(NULL); + while (list) { + ChardevInfo *chr_info = list->value; + + if (!strncmp(chr_info->label, str, len)) { + CharDriverState *chr = qemu_chr_find(chr_info->label); + if (chr && chr_is_ringbuf(chr)) { + readline_add_completion(rs, chr_info->label); + } + } + list = list->next; + } + qapi_free_ChardevInfoList(start); +} + +void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args != 2) { + return; + } + ringbuf_completion(rs, str); +} + +void device_del_completion(ReadLineState *rs, int nb_args, const char *str) +{ + size_t len; + + if (nb_args != 2) { + return; + } + + len = strlen(str); + readline_set_completion_index(rs, len); + peripheral_device_del_completion(rs, str, len); +} + +void object_del_completion(ReadLineState *rs, int nb_args, const char *str) +{ + ObjectPropertyInfoList *list, *start; + size_t len; + + if (nb_args != 2) { + return; + } + len = strlen(str); + readline_set_completion_index(rs, len); + + start = list = qmp_qom_list("/objects", NULL); + while (list) { + ObjectPropertyInfo *info = list->value; + + if (!strncmp(info->type, "child<", 5) + && !strncmp(info->name, str, len)) { + readline_add_completion(rs, info->name); + } + list = list->next; + } + qapi_free_ObjectPropertyInfoList(start); +} + +void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) +{ + int i; + char *sep; + size_t len; + + if (nb_args != 2) { + return; + } + sep = strrchr(str, '-'); + if (sep) { + str = sep + 1; + } + len = strlen(str); + readline_set_completion_index(rs, len); + for (i = 0; i < Q_KEY_CODE_MAX; i++) { + if (!strncmp(str, QKeyCode_lookup[i], len)) { + readline_add_completion(rs, QKeyCode_lookup[i]); + } + } +} + +void set_link_completion(ReadLineState *rs, int nb_args, const char *str) +{ + size_t len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + NetClientState *ncs[MAX_QUEUE_NUM]; + int count, i; + count = qemu_find_net_clients_except(NULL, ncs, + NET_CLIENT_OPTIONS_KIND_NONE, + MAX_QUEUE_NUM); + for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { + const char *name = ncs[i]->name; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + } else if (nb_args == 3) { + add_completion_option(rs, str, "on"); + add_completion_option(rs, str, "off"); + } +} + +void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) +{ + int len, count, i; + NetClientState *ncs[MAX_QUEUE_NUM]; + + if (nb_args != 2) { + return; + } + + len = strlen(str); + readline_set_completion_index(rs, len); + count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC, + MAX_QUEUE_NUM); + for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { + QemuOpts *opts; + const char *name = ncs[i]->name; + if (strncmp(str, name, len)) { + continue; + } + opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name); + if (opts) { + readline_add_completion(rs, name); + } + } +} + +void trace_event_completion(ReadLineState *rs, int nb_args, const char *str) +{ + size_t len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + TraceEventID id; + for (id = 0; id < trace_event_count(); id++) { + const char *event_name = trace_event_get_name(trace_event_id(id)); + if (!strncmp(str, event_name, len)) { + readline_add_completion(rs, event_name); + } + } + } else if (nb_args == 3) { + add_completion_option(rs, str, "on"); + add_completion_option(rs, str, "off"); + } +} + +void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) +{ + int i; + + if (nb_args != 2) { + return; + } + readline_set_completion_index(rs, strlen(str)); + for (i = 0; WatchdogExpirationAction_lookup[i]; i++) { + add_completion_option(rs, str, WatchdogExpirationAction_lookup[i]); + } +} + +void migrate_set_capability_completion(ReadLineState *rs, int nb_args, + const char *str) +{ + size_t len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + int i; + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + const char *name = MigrationCapability_lookup[i]; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + } else if (nb_args == 3) { + add_completion_option(rs, str, "on"); + add_completion_option(rs, str, "off"); + } +} + +void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, + const char *str) +{ + size_t len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + int i; + for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) { + const char *name = MigrationParameter_lookup[i]; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + } +} + +void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str) +{ + int i; + size_t len; + if (nb_args != 2) { + return; + } + len = strlen(str); + readline_set_completion_index(rs, len); + for (i = 0; host_net_devices[i]; i++) { + if (!strncmp(host_net_devices[i], str, len)) { + readline_add_completion(rs, host_net_devices[i]); + } + } +} + +void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) +{ + NetClientState *ncs[MAX_QUEUE_NUM]; + int count, i, len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + count = qemu_find_net_clients_except(NULL, ncs, + NET_CLIENT_OPTIONS_KIND_NONE, + MAX_QUEUE_NUM); + for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { + int id; + char name[16]; + + if (net_hub_id_for_client(ncs[i], &id)) { + continue; + } + snprintf(name, sizeof(name), "%d", id); + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + return; + } else if (nb_args == 3) { + count = qemu_find_net_clients_except(NULL, ncs, + NET_CLIENT_OPTIONS_KIND_NIC, + MAX_QUEUE_NUM); + for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { + int id; + const char *name; + + if (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT || + net_hub_id_for_client(ncs[i], &id)) { + continue; + } + name = ncs[i]->name; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + return; + } +} + +static void vm_completion(ReadLineState *rs, const char *str) +{ + size_t len; + BlockDriverState *bs = NULL; + + len = strlen(str); + readline_set_completion_index(rs, len); + while ((bs = bdrv_next(bs))) { + SnapshotInfoList *snapshots, *snapshot; + AioContext *ctx = bdrv_get_aio_context(bs); + bool ok = false; + + aio_context_acquire(ctx); + if (bdrv_can_snapshot(bs)) { + ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0; + } + aio_context_release(ctx); + if (!ok) { + continue; + } + + snapshot = snapshots; + while (snapshot) { + char *completion = snapshot->value->name; + if (!strncmp(str, completion, len)) { + readline_add_completion(rs, completion); + } + completion = snapshot->value->id; + if (!strncmp(str, completion, len)) { + readline_add_completion(rs, completion); + } + snapshot = snapshot->next; + } + qapi_free_SnapshotInfoList(snapshots); + } + +} + +void delvm_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args == 2) { + vm_completion(rs, str); + } +} + +void loadvm_completion(ReadLineState *rs, int nb_args, const char *str) +{ + if (nb_args == 2) { + vm_completion(rs, str); + } +} + +static void monitor_find_completion_by_table(Monitor *mon, + const mon_cmd_t *cmd_table, + char **args, + int nb_args) +{ + const char *cmdname; + int i; + const char *ptype, *str, *name; + const mon_cmd_t *cmd; + BlockDriverState *bs; + + if (nb_args <= 1) { + /* command completion */ + if (nb_args == 0) + cmdname = ""; + else + cmdname = args[0]; + readline_set_completion_index(mon->rs, strlen(cmdname)); + for (cmd = cmd_table; cmd->name != NULL; cmd++) { + cmd_completion(mon, cmdname, cmd->name); + } + } else { + /* find the command */ + for (cmd = cmd_table; cmd->name != NULL; cmd++) { + if (compare_cmd(args[0], cmd->name)) { + break; + } + } + if (!cmd->name) { + return; + } + + if (cmd->sub_table) { + /* do the job again */ + monitor_find_completion_by_table(mon, cmd->sub_table, + &args[1], nb_args - 1); + return; + } + if (cmd->command_completion) { + cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]); + return; + } + + ptype = next_arg_type(cmd->args_type); + for(i = 0; i < nb_args - 2; i++) { + if (*ptype != '\0') { + ptype = next_arg_type(ptype); + while (*ptype == '?') + ptype = next_arg_type(ptype); + } + } + str = args[nb_args - 1]; + while (*ptype == '-' && ptype[1] != '\0') { + ptype = next_arg_type(ptype); + } + switch(*ptype) { + case 'F': + /* file completion */ + readline_set_completion_index(mon->rs, strlen(str)); + file_completion(mon, str); + break; + case 'B': + /* block device name completion */ + readline_set_completion_index(mon->rs, strlen(str)); + for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) { + name = bdrv_get_device_name(bs); + if (str[0] == '\0' || + !strncmp(name, str, strlen(str))) { + readline_add_completion(mon->rs, name); + } + } + break; + case 's': + case 'S': + if (!strcmp(cmd->name, "help|?")) { + monitor_find_completion_by_table(mon, cmd_table, + &args[1], nb_args - 1); + } + break; + default: + break; + } + } +} + +static void monitor_find_completion(void *opaque, + const char *cmdline) +{ + Monitor *mon = opaque; + char *args[MAX_ARGS]; + int nb_args, len; + + /* 1. parse the cmdline */ + if (parse_cmdline(cmdline, &nb_args, args) < 0) { + return; + } + + /* if the line ends with a space, it means we want to complete the + next arg */ + len = strlen(cmdline); + if (len > 0 && qemu_isspace(cmdline[len - 1])) { + if (nb_args >= MAX_ARGS) { + goto cleanup; + } + args[nb_args++] = g_strdup(""); + } + + /* 2. auto complete according to args */ + monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args); + +cleanup: + free_cmdline_args(args, nb_args); +} + +static int monitor_can_read(void *opaque) +{ + Monitor *mon = opaque; + + return (mon->suspend_cnt == 0) ? 1 : 0; +} + +static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd, + Error **errp) +{ + bool is_cap = cmd->mhandler.cmd_new == qmp_capabilities; + + if (is_cap && mon->qmp.in_command_mode) { + error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, + "Capabilities negotiation is already complete, command " + "'%s' ignored", cmd->name); + return true; + } + if (!is_cap && !mon->qmp.in_command_mode) { + error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, + "Expecting capabilities negotiation with " + "'qmp_capabilities' before command '%s'", cmd->name); + return true; + } + return false; +} + +/* + * Argument validation rules: + * + * 1. The argument must exist in cmd_args qdict + * 2. The argument type must be the expected one + * + * Special case: If the argument doesn't exist in cmd_args and + * the QMP_ACCEPT_UNKNOWNS flag is set, then the + * checking is skipped for it. + */ +static void check_client_args_type(const QDict *client_args, + const QDict *cmd_args, int flags, + Error **errp) +{ + const QDictEntry *ent; + + for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){ + QObject *obj; + QString *arg_type; + const QObject *client_arg = qdict_entry_value(ent); + const char *client_arg_name = qdict_entry_key(ent); + + obj = qdict_get(cmd_args, client_arg_name); + if (!obj) { + if (flags & QMP_ACCEPT_UNKNOWNS) { + /* handler accepts unknowns */ + continue; + } + /* client arg doesn't exist */ + error_setg(errp, QERR_INVALID_PARAMETER, client_arg_name); + return; + } + + arg_type = qobject_to_qstring(obj); + assert(arg_type != NULL); + + /* check if argument's type is correct */ + switch (qstring_get_str(arg_type)[0]) { + case 'F': + case 'B': + case 's': + if (qobject_type(client_arg) != QTYPE_QSTRING) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, + client_arg_name, "string"); + return; + } + break; + case 'i': + case 'l': + case 'M': + case 'o': + if (qobject_type(client_arg) != QTYPE_QINT) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, + client_arg_name, "int"); + return; + } + break; + case 'T': + if (qobject_type(client_arg) != QTYPE_QINT && + qobject_type(client_arg) != QTYPE_QFLOAT) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, + client_arg_name, "number"); + return; + } + break; + case 'b': + case '-': + if (qobject_type(client_arg) != QTYPE_QBOOL) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, + client_arg_name, "bool"); + return; + } + break; + case 'O': + assert(flags & QMP_ACCEPT_UNKNOWNS); + break; + case 'q': + /* Any QObject can be passed. */ + break; + case '/': + case '.': + /* + * These types are not supported by QMP and thus are not + * handled here. Fall through. + */ + default: + abort(); + } + } +} + +/* + * - Check if the client has passed all mandatory args + * - Set special flags for argument validation + */ +static void check_mandatory_args(const QDict *cmd_args, + const QDict *client_args, int *flags, + Error **errp) +{ + const QDictEntry *ent; + + for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) { + const char *cmd_arg_name = qdict_entry_key(ent); + QString *type = qobject_to_qstring(qdict_entry_value(ent)); + assert(type != NULL); + + if (qstring_get_str(type)[0] == 'O') { + assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0); + *flags |= QMP_ACCEPT_UNKNOWNS; + } else if (qstring_get_str(type)[0] != '-' && + qstring_get_str(type)[1] != '?' && + !qdict_haskey(client_args, cmd_arg_name)) { + error_setg(errp, QERR_MISSING_PARAMETER, cmd_arg_name); + return; + } + } +} + +static QDict *qdict_from_args_type(const char *args_type) +{ + int i; + QDict *qdict; + QString *key, *type, *cur_qs; + + assert(args_type != NULL); + + qdict = qdict_new(); + + if (args_type == NULL || args_type[0] == '\0') { + /* no args, empty qdict */ + goto out; + } + + key = qstring_new(); + type = qstring_new(); + + cur_qs = key; + + for (i = 0;; i++) { + switch (args_type[i]) { + case ',': + case '\0': + qdict_put(qdict, qstring_get_str(key), type); + QDECREF(key); + if (args_type[i] == '\0') { + goto out; + } + type = qstring_new(); /* qdict has ref */ + cur_qs = key = qstring_new(); + break; + case ':': + cur_qs = type; + break; + default: + qstring_append_chr(cur_qs, args_type[i]); + break; + } + } + +out: + return qdict; +} + +/* + * Client argument checking rules: + * + * 1. Client must provide all mandatory arguments + * 2. Each argument provided by the client must be expected + * 3. Each argument provided by the client must have the type expected + * by the command + */ +static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args, + Error **errp) +{ + Error *err = NULL; + int flags; + QDict *cmd_args; + + cmd_args = qdict_from_args_type(cmd->args_type); + + flags = 0; + check_mandatory_args(cmd_args, client_args, &flags, &err); + if (err) { + goto out; + } + + check_client_args_type(client_args, cmd_args, flags, &err); + +out: + error_propagate(errp, err); + QDECREF(cmd_args); +} + +/* + * Input object checking rules + * + * 1. Input object must be a dict + * 2. The "execute" key must exist + * 3. The "execute" key must be a string + * 4. If the "arguments" key exists, it must be a dict + * 5. If the "id" key exists, it can be anything (ie. json-value) + * 6. Any argument not listed above is considered invalid + */ +static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp) +{ + const QDictEntry *ent; + int has_exec_key = 0; + QDict *input_dict; + + if (qobject_type(input_obj) != QTYPE_QDICT) { + error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "object"); + return NULL; + } + + input_dict = qobject_to_qdict(input_obj); + + for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){ + const char *arg_name = qdict_entry_key(ent); + const QObject *arg_obj = qdict_entry_value(ent); + + if (!strcmp(arg_name, "execute")) { + if (qobject_type(arg_obj) != QTYPE_QSTRING) { + error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, + "execute", "string"); + return NULL; + } + has_exec_key = 1; + } else if (!strcmp(arg_name, "arguments")) { + if (qobject_type(arg_obj) != QTYPE_QDICT) { + error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, + "arguments", "object"); + return NULL; + } + } else if (!strcmp(arg_name, "id")) { + /* Any string is acceptable as "id", so nothing to check */ + } else { + error_setg(errp, QERR_QMP_EXTRA_MEMBER, arg_name); + return NULL; + } + } + + if (!has_exec_key) { + error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute"); + return NULL; + } + + return input_dict; +} + +static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens) +{ + Error *local_err = NULL; + QObject *obj, *data; + QDict *input, *args; + const mon_cmd_t *cmd; + const char *cmd_name; + Monitor *mon = cur_mon; + + args = input = NULL; + data = NULL; + + obj = json_parser_parse(tokens, NULL); + if (!obj) { + // FIXME: should be triggered in json_parser_parse() + error_setg(&local_err, QERR_JSON_PARSING); + goto err_out; + } + + input = qmp_check_input_obj(obj, &local_err); + if (!input) { + qobject_decref(obj); + goto err_out; + } + + mon->qmp.id = qdict_get(input, "id"); + qobject_incref(mon->qmp.id); + + cmd_name = qdict_get_str(input, "execute"); + trace_handle_qmp_command(mon, cmd_name); + cmd = qmp_find_cmd(cmd_name); + if (!cmd) { + error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND, + "The command %s has not been found", cmd_name); + goto err_out; + } + if (invalid_qmp_mode(mon, cmd, &local_err)) { + goto err_out; + } + + obj = qdict_get(input, "arguments"); + if (!obj) { + args = qdict_new(); + } else { + args = qobject_to_qdict(obj); + QINCREF(args); + } + + qmp_check_client_args(cmd, args, &local_err); + if (local_err) { + goto err_out; + } + + cmd->mhandler.cmd_new(args, &data, &local_err); + +err_out: + monitor_protocol_emitter(mon, data, local_err); + qobject_decref(data); + error_free(local_err); + QDECREF(input); + QDECREF(args); +} + +static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size) +{ + Monitor *old_mon = cur_mon; + + cur_mon = opaque; + + json_message_parser_feed(&cur_mon->qmp.parser, (const char *) buf, size); + + cur_mon = old_mon; +} + +static void monitor_read(void *opaque, const uint8_t *buf, int size) +{ + Monitor *old_mon = cur_mon; + int i; + + cur_mon = opaque; + + if (cur_mon->rs) { + for (i = 0; i < size; i++) + readline_handle_byte(cur_mon->rs, buf[i]); + } else { + if (size == 0 || buf[size - 1] != 0) + monitor_printf(cur_mon, "corrupted command\n"); + else + handle_hmp_command(cur_mon, (char *)buf); + } + + cur_mon = old_mon; +} + +static void monitor_command_cb(void *opaque, const char *cmdline, + void *readline_opaque) +{ + Monitor *mon = opaque; + + monitor_suspend(mon); + handle_hmp_command(mon, cmdline); + monitor_resume(mon); +} + +int monitor_suspend(Monitor *mon) +{ + if (!mon->rs) + return -ENOTTY; + mon->suspend_cnt++; + return 0; +} + +void monitor_resume(Monitor *mon) +{ + if (!mon->rs) + return; + if (--mon->suspend_cnt == 0) + readline_show_prompt(mon->rs); +} + +static QObject *get_qmp_greeting(void) +{ + QObject *ver = NULL; + + qmp_marshal_query_version(NULL, &ver, NULL); + return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver); +} + +static void monitor_qmp_event(void *opaque, int event) +{ + QObject *data; + Monitor *mon = opaque; + + switch (event) { + case CHR_EVENT_OPENED: + mon->qmp.in_command_mode = false; + data = get_qmp_greeting(); + monitor_json_emitter(mon, data); + qobject_decref(data); + mon_refcount++; + break; + case CHR_EVENT_CLOSED: + json_message_parser_destroy(&mon->qmp.parser); + json_message_parser_init(&mon->qmp.parser, handle_qmp_command); + mon_refcount--; + monitor_fdsets_cleanup(); + break; + } +} + +static void monitor_event(void *opaque, int event) +{ + Monitor *mon = opaque; + + switch (event) { + case CHR_EVENT_MUX_IN: + qemu_mutex_lock(&mon->out_lock); + mon->mux_out = 0; + qemu_mutex_unlock(&mon->out_lock); + if (mon->reset_seen) { + readline_restart(mon->rs); + monitor_resume(mon); + monitor_flush(mon); + } else { + mon->suspend_cnt = 0; + } + break; + + case CHR_EVENT_MUX_OUT: + if (mon->reset_seen) { + if (mon->suspend_cnt == 0) { + monitor_printf(mon, "\n"); + } + monitor_flush(mon); + monitor_suspend(mon); + } else { + mon->suspend_cnt++; + } + qemu_mutex_lock(&mon->out_lock); + mon->mux_out = 1; + qemu_mutex_unlock(&mon->out_lock); + break; + + case CHR_EVENT_OPENED: + monitor_printf(mon, "QEMU %s monitor - type 'help' for more " + "information\n", QEMU_VERSION); + if (!mon->mux_out) { + readline_restart(mon->rs); + readline_show_prompt(mon->rs); + } + mon->reset_seen = 1; + mon_refcount++; + break; + + case CHR_EVENT_CLOSED: + mon_refcount--; + monitor_fdsets_cleanup(); + break; + } +} + +static int +compare_mon_cmd(const void *a, const void *b) +{ + return strcmp(((const mon_cmd_t *)a)->name, + ((const mon_cmd_t *)b)->name); +} + +static void sortcmdlist(void) +{ + int array_num; + int elem_size = sizeof(mon_cmd_t); + + array_num = sizeof(mon_cmds)/elem_size-1; + qsort((void *)mon_cmds, array_num, elem_size, compare_mon_cmd); + + array_num = sizeof(info_cmds)/elem_size-1; + qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd); +} + + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 8 + * End: + */ + +/* These functions just adapt the readline interface in a typesafe way. We + * could cast function pointers but that discards compiler checks. + */ +static void GCC_FMT_ATTR(2, 3) monitor_readline_printf(void *opaque, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + monitor_vprintf(opaque, fmt, ap); + va_end(ap); +} + +static void monitor_readline_flush(void *opaque) +{ + monitor_flush(opaque); +} + +static void __attribute__((constructor)) monitor_lock_init(void) +{ + qemu_mutex_init(&monitor_lock); +} + +void monitor_init(CharDriverState *chr, int flags) +{ + static int is_first_init = 1; + Monitor *mon; + + if (is_first_init) { + monitor_qapi_event_init(); + sortcmdlist(); + is_first_init = 0; + } + + mon = g_malloc(sizeof(*mon)); + monitor_data_init(mon); + + mon->chr = chr; + mon->flags = flags; + if (flags & MONITOR_USE_READLINE) { + mon->rs = readline_init(monitor_readline_printf, + monitor_readline_flush, + mon, + monitor_find_completion); + monitor_read_command(mon, 0); + } + + if (monitor_is_qmp(mon)) { + qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read, + monitor_qmp_event, mon); + qemu_chr_fe_set_echo(chr, true); + json_message_parser_init(&mon->qmp.parser, handle_qmp_command); + } else { + qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, + monitor_event, mon); + } + + qemu_mutex_lock(&monitor_lock); + QLIST_INSERT_HEAD(&mon_list, mon, entry); + qemu_mutex_unlock(&monitor_lock); +} + +static void bdrv_password_cb(void *opaque, const char *password, + void *readline_opaque) +{ + Monitor *mon = opaque; + BlockDriverState *bs = readline_opaque; + int ret = 0; + Error *local_err = NULL; + + bdrv_add_key(bs, password, &local_err); + if (local_err) { + monitor_printf(mon, "%s\n", error_get_pretty(local_err)); + error_free(local_err); + ret = -EPERM; + } + if (mon->password_completion_cb) + mon->password_completion_cb(mon->password_opaque, ret); + + monitor_read_command(mon, 1); +} + +int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, + BlockCompletionFunc *completion_cb, + void *opaque) +{ + int err; + + monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs), + bdrv_get_encrypted_filename(bs)); + + mon->password_completion_cb = completion_cb; + mon->password_opaque = opaque; + + err = monitor_read_password(mon, bdrv_password_cb, bs); + + if (err && completion_cb) + completion_cb(opaque, err); + + return err; +} + +int monitor_read_block_device_key(Monitor *mon, const char *device, + BlockCompletionFunc *completion_cb, + void *opaque) +{ + Error *err = NULL; + BlockBackend *blk; + + blk = blk_by_name(device); + if (!blk) { + monitor_printf(mon, "Device not found %s\n", device); + return -1; + } + if (!blk_bs(blk)) { + monitor_printf(mon, "Device '%s' has no medium\n", device); + return -1; + } + + bdrv_add_key(blk_bs(blk), NULL, &err); + if (err) { + error_free(err); + return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque); + } + + if (completion_cb) { + completion_cb(opaque, 0); + } + return 0; +} + +QemuOptsList qemu_mon_opts = { + .name = "mon", + .implied_opt_name = "chardev", + .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head), + .desc = { + { + .name = "mode", + .type = QEMU_OPT_STRING, + },{ + .name = "chardev", + .type = QEMU_OPT_STRING, + },{ + .name = "default", + .type = QEMU_OPT_BOOL, + },{ + .name = "pretty", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; + +#ifndef TARGET_I386 +void qmp_rtc_reset_reinjection(Error **errp) +{ + error_setg(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection"); +} +#endif + +#ifndef TARGET_S390X +void qmp_dump_skeys(const char *filename, Error **errp) +{ + error_setg(errp, QERR_FEATURE_DISABLED, "dump-skeys"); +} +#endif diff --git a/pebble.py b/pebble.py new file mode 100755 index 0000000000000..b5760a996d428 --- /dev/null +++ b/pebble.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +import os +import argparse + + +#################################################################################################### +if __name__ == '__main__': + # Collect our command line arguments + parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--machine', choices=['bb2', 'snowy-bb', 's4-bb'], + default='bb2', help="Which machine to emulate ") + parser.add_argument('-S', '--start_in_monitor', action='store_true', + help="Start in the monitor. Enter 'cont' in the monitor to start emulation") + parser.add_argument('--vnc', action='store_true', + help="Use VNC on port 5900 for the display") + parser.add_argument('--vnc_ws', action='store_true', + help="Use VNC over websockets on port 4444 for the display") + parser.add_argument('-d', '--debug', + help=("Turn on extensive debug logging. Available ones are:" + "out_asm,in_asm,op,op_opt,int,exec,cpu,pcall,cpu_reset,ioport,unimp," + "guest_errors. Enter one or more comma separated.")) + args = parser.parse_args() + + + cmd_line = ( + "qemu-system-arm " + "-rtc base=localtime " + "-s " # Start gdb server + "-serial file:uart1.log " + "-serial tcp::12344,server,nowait " # Used for Pebble Protocol + "-serial tcp::12345,server,nowait " # Used for console + "-monitor stdio " + ) + cmd_line += "-machine pebble-%s " % (args.machine) + if args.machine in ('snowy-bb', 's4-bb'): + cmd_line += "-cpu cortex-m4 " + cmd_line += "-pflash ../test_images/qemu_micro_flash.bin " + cmd_line += "-pflash ../test_images/qemu_spi_flash.bin " + else: + cmd_line += "-cpu cortex-m3 " + cmd_line += "-pflash ../test_images/qemu_micro_flash.bin " + cmd_line += "-mtdblock ../test_images/qemu_spi_flash.bin " + + if args.start_in_monitor: + cmd_line += "-S " + if args.debug: + cmd_line += ("-d " + args.debug) + + if (args.vnc and args.vnc_ws): + raise RuntimeError("--vnc and --vnc_ws can not both be specified"); + if args.vnc: + cmd_line += "-vnc :0 " + if args.vnc_ws: + cmd_line += "-vnc :1,websocket=4444 " + + print "Executing command line: \n ", cmd_line + os.system(cmd_line) + + diff --git a/pebble_dbgserial.sh b/pebble_dbgserial.sh new file mode 100755 index 0000000000000..69faefc06fbb2 --- /dev/null +++ b/pebble_dbgserial.sh @@ -0,0 +1 @@ +python -m serial.tools.miniterm socket://:12345 230400 diff --git a/qemu-char.c b/qemu-char.c new file mode 100644 index 0000000000000..b7822865ae8ac --- /dev/null +++ b/qemu-char.c @@ -0,0 +1,4393 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * 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-common.h" +#include "monitor/monitor.h" +#include "sysemu/sysemu.h" +#include "qemu/error-report.h" +#include "qemu/timer.h" +#include "sysemu/char.h" +#include "hw/usb.h" +#include "qmp-commands.h" +#include "qapi/qmp-input-visitor.h" +#include "qapi/qmp-output-visitor.h" +#include "qapi-visit.h" + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BSD +#include +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include +#include +#elif defined(__DragonFly__) +#include +#include +#endif +#else +#ifdef __linux__ +#include +#include +#endif +#ifdef __sun__ +#include +#include +#include +#include +#include +#include +#include +#include // must come after ip.h +#include +#include +#endif +#endif +#endif + +#include "qemu/sockets.h" +#include "ui/qemu-spice.h" + +#define READ_BUF_LEN 4096 +#define READ_RETRIES 10 +#define CHR_MAX_FILENAME_SIZE 256 +#define TCP_MAX_FDS 16 + +/***********************************************************/ +/* Socket address helpers */ + +static int SocketAddress_to_str(char *dest, int max_len, + const char *prefix, SocketAddress *addr, + bool is_listen, bool is_telnet) +{ + switch (addr->type) { + case SOCKET_ADDRESS_KIND_INET: + return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix, + is_telnet ? "telnet" : "tcp", addr->u.inet->host, + addr->u.inet->port, is_listen ? ",server" : ""); + break; + case SOCKET_ADDRESS_KIND_UNIX: + return snprintf(dest, max_len, "%sunix:%s%s", prefix, + addr->u.q_unix->path, is_listen ? ",server" : ""); + break; + case SOCKET_ADDRESS_KIND_FD: + return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->u.fd->str, + is_listen ? ",server" : ""); + break; + default: + abort(); + } +} + +static int sockaddr_to_str(char *dest, int max_len, + struct sockaddr_storage *ss, socklen_t ss_len, + struct sockaddr_storage *ps, socklen_t ps_len, + bool is_listen, bool is_telnet) +{ + char shost[NI_MAXHOST], sserv[NI_MAXSERV]; + char phost[NI_MAXHOST], pserv[NI_MAXSERV]; + const char *left = "", *right = ""; + + switch (ss->ss_family) { +#ifndef _WIN32 + case AF_UNIX: + return snprintf(dest, max_len, "unix:%s%s", + ((struct sockaddr_un *)(ss))->sun_path, + is_listen ? ",server" : ""); +#endif + case AF_INET6: + left = "["; + right = "]"; + /* fall through */ + case AF_INET: + getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost), + sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV); + getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost), + pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV); + return snprintf(dest, max_len, "%s:%s%s%s:%s%s <-> %s%s%s:%s", + is_telnet ? "telnet" : "tcp", + left, shost, right, sserv, + is_listen ? ",server" : "", + left, phost, right, pserv); + + default: + return snprintf(dest, max_len, "unknown"); + } +} + +/***********************************************************/ +/* character device */ + +static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = + QTAILQ_HEAD_INITIALIZER(chardevs); + +CharDriverState *qemu_chr_alloc(void) +{ + CharDriverState *chr = g_malloc0(sizeof(CharDriverState)); + qemu_mutex_init(&chr->chr_write_lock); + return chr; +} + +void qemu_chr_be_event(CharDriverState *s, int event) +{ + /* Keep track if the char device is open */ + switch (event) { + case CHR_EVENT_OPENED: + s->be_open = 1; + break; + case CHR_EVENT_CLOSED: + s->be_open = 0; + break; + } + + if (!s->chr_event) + return; + s->chr_event(s->handler_opaque, event); +} + +void qemu_chr_be_generic_open(CharDriverState *s) +{ + qemu_chr_be_event(s, CHR_EVENT_OPENED); +} + +int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) +{ + int ret; + + qemu_mutex_lock(&s->chr_write_lock); + ret = s->chr_write(s, buf, len); + qemu_mutex_unlock(&s->chr_write_lock); + return ret; +} + +int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) +{ + int offset = 0; + int res = 0; + + qemu_mutex_lock(&s->chr_write_lock); + while (offset < len) { + do { + res = s->chr_write(s, buf + offset, len - offset); + if (res == -1 && errno == EAGAIN) { + g_usleep(100); + } + } while (res == -1 && errno == EAGAIN); + + if (res <= 0) { + break; + } + + offset += res; + } + qemu_mutex_unlock(&s->chr_write_lock); + + if (res < 0) { + return res; + } + return offset; +} + +int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len) +{ + int offset = 0, counter = 10; + int res; + + if (!s->chr_sync_read) { + return 0; + } + + while (offset < len) { + do { + res = s->chr_sync_read(s, buf + offset, len - offset); + if (res == -1 && errno == EAGAIN) { + g_usleep(100); + } + } while (res == -1 && errno == EAGAIN); + + if (res == 0) { + break; + } + + if (res < 0) { + return res; + } + + offset += res; + + if (!counter--) { + break; + } + } + + return offset; +} + +int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg) +{ + if (!s->chr_ioctl) + return -ENOTSUP; + return s->chr_ioctl(s, cmd, arg); +} + +int qemu_chr_be_can_write(CharDriverState *s) +{ + if (!s->chr_can_read) + return 0; + return s->chr_can_read(s->handler_opaque); +} + +void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len) +{ + if (s->chr_read) { + s->chr_read(s->handler_opaque, buf, len); + } +} + +int qemu_chr_fe_get_msgfd(CharDriverState *s) +{ + int fd; + return (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1; +} + +int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len) +{ + return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1; +} + +int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num) +{ + return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1; +} + +int qemu_chr_add_client(CharDriverState *s, int fd) +{ + return s->chr_add_client ? s->chr_add_client(s, fd) : -1; +} + +void qemu_chr_accept_input(CharDriverState *s) +{ + if (s->chr_accept_input) + s->chr_accept_input(s); + qemu_notify_event(); +} + +void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) +{ + char buf[READ_BUF_LEN]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf)); + va_end(ap); +} + +static void remove_fd_in_watch(CharDriverState *chr); + +void qemu_chr_add_handlers(CharDriverState *s, + IOCanReadHandler *fd_can_read, + IOReadHandler *fd_read, + IOEventHandler *fd_event, + void *opaque) +{ + int fe_open; + + if (!opaque && !fd_can_read && !fd_read && !fd_event) { + fe_open = 0; + remove_fd_in_watch(s); + } else { + fe_open = 1; + } + s->chr_can_read = fd_can_read; + s->chr_read = fd_read; + s->chr_event = fd_event; + s->handler_opaque = opaque; + if (fe_open && s->chr_update_read_handler) + s->chr_update_read_handler(s); + + if (!s->explicit_fe_open) { + qemu_chr_fe_set_open(s, fe_open); + } + + /* We're connecting to an already opened device, so let's make sure we + also get the open event */ + if (fe_open && s->be_open) { + qemu_chr_be_generic_open(s); + } +} + +static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + return len; +} + +static CharDriverState *qemu_chr_open_null(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + CharDriverState *chr; + + chr = qemu_chr_alloc(); + chr->chr_write = null_chr_write; + chr->explicit_be_open = true; + return chr; +} + +/* MUX driver for serial I/O splitting */ +#define MAX_MUX 4 +#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */ +#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1) +typedef struct { + IOCanReadHandler *chr_can_read[MAX_MUX]; + IOReadHandler *chr_read[MAX_MUX]; + IOEventHandler *chr_event[MAX_MUX]; + void *ext_opaque[MAX_MUX]; + CharDriverState *drv; + int focus; + int mux_cnt; + int term_got_escape; + int max_size; + /* Intermediate input buffer allows to catch escape sequences even if the + currently active device is not accepting any input - but only until it + is full as well. */ + unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE]; + int prod[MAX_MUX]; + int cons[MAX_MUX]; + int timestamps; + + /* Protected by the CharDriverState chr_write_lock. */ + int linestart; + int64_t timestamps_start; +} MuxDriver; + + +/* Called with chr_write_lock held. */ +static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + MuxDriver *d = chr->opaque; + int ret; + if (!d->timestamps) { + ret = qemu_chr_fe_write(d->drv, buf, len); + } else { + int i; + + ret = 0; + for (i = 0; i < len; i++) { + if (d->linestart) { + char buf1[64]; + int64_t ti; + int secs; + + ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + if (d->timestamps_start == -1) + d->timestamps_start = ti; + ti -= d->timestamps_start; + secs = ti / 1000; + snprintf(buf1, sizeof(buf1), + "[%02d:%02d:%02d.%03d] ", + secs / 3600, + (secs / 60) % 60, + secs % 60, + (int)(ti % 1000)); + qemu_chr_fe_write(d->drv, (uint8_t *)buf1, strlen(buf1)); + d->linestart = 0; + } + ret += qemu_chr_fe_write(d->drv, buf+i, 1); + if (buf[i] == '\n') { + d->linestart = 1; + } + } + } + return ret; +} + +static const char * const mux_help[] = { + "% h print this help\n\r", + "% x exit emulator\n\r", + "% s save disk data back to file (if -snapshot)\n\r", + "% t toggle console timestamps\n\r", + "% b send break (magic sysrq)\n\r", + "% c switch between console and monitor\n\r", + "% % sends %\n\r", + NULL +}; + +int term_escape_char = 0x01; /* ctrl-a is used for escape */ +static void mux_print_help(CharDriverState *chr) +{ + int i, j; + char ebuf[15] = "Escape-Char"; + char cbuf[50] = "\n\r"; + + if (term_escape_char > 0 && term_escape_char < 26) { + snprintf(cbuf, sizeof(cbuf), "\n\r"); + snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a'); + } else { + snprintf(cbuf, sizeof(cbuf), + "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", + term_escape_char); + } + qemu_chr_fe_write(chr, (uint8_t *)cbuf, strlen(cbuf)); + for (i = 0; mux_help[i] != NULL; i++) { + for (j=0; mux_help[i][j] != '\0'; j++) { + if (mux_help[i][j] == '%') + qemu_chr_fe_write(chr, (uint8_t *)ebuf, strlen(ebuf)); + else + qemu_chr_fe_write(chr, (uint8_t *)&mux_help[i][j], 1); + } + } +} + +static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event) +{ + if (d->chr_event[mux_nr]) + d->chr_event[mux_nr](d->ext_opaque[mux_nr], event); +} + +static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) +{ + if (d->term_got_escape) { + d->term_got_escape = 0; + if (ch == term_escape_char) + goto send_char; + switch(ch) { + case '?': + case 'h': + mux_print_help(chr); + break; + case 'x': + { + const char *term = "QEMU: Terminated\n\r"; + qemu_chr_fe_write(chr, (uint8_t *)term, strlen(term)); + exit(0); + break; + } + case 's': + bdrv_commit_all(); + break; + case 'b': + qemu_chr_be_event(chr, CHR_EVENT_BREAK); + break; + case 'c': + /* Switch to the next registered device */ + mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); + d->focus++; + if (d->focus >= d->mux_cnt) + d->focus = 0; + mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); + break; + case 't': + d->timestamps = !d->timestamps; + d->timestamps_start = -1; + d->linestart = 0; + break; + } + } else if (ch == term_escape_char) { + d->term_got_escape = 1; + } else { + send_char: + return 1; + } + return 0; +} + +static void mux_chr_accept_input(CharDriverState *chr) +{ + MuxDriver *d = chr->opaque; + int m = d->focus; + + while (d->prod[m] != d->cons[m] && + d->chr_can_read[m] && + d->chr_can_read[m](d->ext_opaque[m])) { + d->chr_read[m](d->ext_opaque[m], + &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1); + } +} + +static int mux_chr_can_read(void *opaque) +{ + CharDriverState *chr = opaque; + MuxDriver *d = chr->opaque; + int m = d->focus; + + if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) + return 1; + if (d->chr_can_read[m]) + return d->chr_can_read[m](d->ext_opaque[m]); + return 0; +} + +static void mux_chr_read(void *opaque, const uint8_t *buf, int size) +{ + CharDriverState *chr = opaque; + MuxDriver *d = chr->opaque; + int m = d->focus; + int i; + + mux_chr_accept_input (opaque); + + for(i = 0; i < size; i++) + if (mux_proc_byte(chr, d, buf[i])) { + if (d->prod[m] == d->cons[m] && + d->chr_can_read[m] && + d->chr_can_read[m](d->ext_opaque[m])) + d->chr_read[m](d->ext_opaque[m], &buf[i], 1); + else + d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i]; + } +} + +static void mux_chr_event(void *opaque, int event) +{ + CharDriverState *chr = opaque; + MuxDriver *d = chr->opaque; + int i; + + /* Send the event to all registered listeners */ + for (i = 0; i < d->mux_cnt; i++) + mux_chr_send_event(d, i, event); +} + +static void mux_chr_update_read_handler(CharDriverState *chr) +{ + MuxDriver *d = chr->opaque; + + if (d->mux_cnt >= MAX_MUX) { + fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n"); + return; + } + d->ext_opaque[d->mux_cnt] = chr->handler_opaque; + d->chr_can_read[d->mux_cnt] = chr->chr_can_read; + d->chr_read[d->mux_cnt] = chr->chr_read; + d->chr_event[d->mux_cnt] = chr->chr_event; + /* Fix up the real driver with mux routines */ + if (d->mux_cnt == 0) { + qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read, + mux_chr_event, chr); + } + if (d->focus != -1) { + mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); + } + d->focus = d->mux_cnt; + d->mux_cnt++; + mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); +} + +static bool muxes_realized; + +/** + * Called after processing of default and command-line-specified + * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached + * to a mux chardev. This is done here to ensure that + * output/prompts/banners are only displayed for the FE that has + * focus when initial command-line processing/machine init is + * completed. + * + * After this point, any new FE attached to any new or existing + * mux will receive CHR_EVENT_OPENED notifications for the BE + * immediately. + */ +static void muxes_realize_done(Notifier *notifier, void *unused) +{ + CharDriverState *chr; + + QTAILQ_FOREACH(chr, &chardevs, next) { + if (chr->is_mux) { + MuxDriver *d = chr->opaque; + int i; + + /* send OPENED to all already-attached FEs */ + for (i = 0; i < d->mux_cnt; i++) { + mux_chr_send_event(d, i, CHR_EVENT_OPENED); + } + /* mark mux as OPENED so any new FEs will immediately receive + * OPENED event + */ + qemu_chr_be_generic_open(chr); + } + } + muxes_realized = true; +} + +static Notifier muxes_realize_notify = { + .notify = muxes_realize_done, +}; + +static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) +{ + MuxDriver *d = s->opaque; + return d->drv->chr_add_watch(d->drv, cond); +} + +static CharDriverState *qemu_chr_open_mux(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) +{ + ChardevMux *mux = backend->u.mux; + CharDriverState *chr, *drv; + MuxDriver *d; + + drv = qemu_chr_find(mux->chardev); + if (drv == NULL) { + error_setg(errp, "mux: base chardev %s not found", mux->chardev); + return NULL; + } + + chr = qemu_chr_alloc(); + d = g_new0(MuxDriver, 1); + + chr->opaque = d; + d->drv = drv; + d->focus = -1; + chr->chr_write = mux_chr_write; + chr->chr_update_read_handler = mux_chr_update_read_handler; + chr->chr_accept_input = mux_chr_accept_input; + /* Frontend guest-open / -close notification is not support with muxes */ + chr->chr_set_fe_open = NULL; + if (drv->chr_add_watch) { + chr->chr_add_watch = mux_chr_add_watch; + } + /* only default to opened state if we've realized the initial + * set of muxes + */ + chr->explicit_be_open = muxes_realized ? 0 : 1; + chr->is_mux = 1; + + return chr; +} + + +#ifdef _WIN32 +int send_all(int fd, const void *buf, int len1) +{ + int ret, len; + + len = len1; + while (len > 0) { + ret = send(fd, buf, len, 0); + if (ret < 0) { + errno = WSAGetLastError(); + if (errno != WSAEWOULDBLOCK) { + return -1; + } + } else if (ret == 0) { + break; + } else { + buf += ret; + len -= ret; + } + } + return len1 - len; +} + +#else + +int send_all(int fd, const void *_buf, int len1) +{ + int ret, len; + const uint8_t *buf = _buf; + + len = len1; + while (len > 0) { + ret = write(fd, buf, len); + if (ret < 0) { + if (errno != EINTR && errno != EAGAIN) + return -1; + } else if (ret == 0) { + break; + } else { + buf += ret; + len -= ret; + } + } + return len1 - len; +} + +int recv_all(int fd, void *_buf, int len1, bool single_read) +{ + int ret, len; + uint8_t *buf = _buf; + + len = len1; + while ((len > 0) && (ret = read(fd, buf, len)) != 0) { + if (ret < 0) { + if (errno != EINTR && errno != EAGAIN) { + return -1; + } + continue; + } else { + if (single_read) { + return ret; + } + buf += ret; + len -= ret; + } + } + return len1 - len; +} + +#endif /* !_WIN32 */ + +typedef struct IOWatchPoll +{ + GSource parent; + + GIOChannel *channel; + GSource *src; + + IOCanReadHandler *fd_can_read; + GSourceFunc fd_read; + void *opaque; +} IOWatchPoll; + +static IOWatchPoll *io_watch_poll_from_source(GSource *source) +{ + return container_of(source, IOWatchPoll, parent); +} + +static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_) +{ + IOWatchPoll *iwp = io_watch_poll_from_source(source); + bool now_active = iwp->fd_can_read(iwp->opaque) > 0; + bool was_active = iwp->src != NULL; + if (was_active == now_active) { + return FALSE; + } + + if (now_active) { + iwp->src = g_io_create_watch(iwp->channel, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); + g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL); + g_source_attach(iwp->src, NULL); + } else { + g_source_destroy(iwp->src); + g_source_unref(iwp->src); + iwp->src = NULL; + } + return FALSE; +} + +static gboolean io_watch_poll_check(GSource *source) +{ + return FALSE; +} + +static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback, + gpointer user_data) +{ + abort(); +} + +static void io_watch_poll_finalize(GSource *source) +{ + /* Due to a glib bug, removing the last reference to a source + * inside a finalize callback causes recursive locking (and a + * deadlock). This is not a problem inside other callbacks, + * including dispatch callbacks, so we call io_remove_watch_poll + * to remove this source. At this point, iwp->src must + * be NULL, or we would leak it. + * + * This would be solved much more elegantly by child sources, + * but we support older glib versions that do not have them. + */ + IOWatchPoll *iwp = io_watch_poll_from_source(source); + assert(iwp->src == NULL); +} + +static GSourceFuncs io_watch_poll_funcs = { + .prepare = io_watch_poll_prepare, + .check = io_watch_poll_check, + .dispatch = io_watch_poll_dispatch, + .finalize = io_watch_poll_finalize, +}; + +/* Can only be used for read */ +static guint io_add_watch_poll(GIOChannel *channel, + IOCanReadHandler *fd_can_read, + GIOFunc fd_read, + gpointer user_data) +{ + IOWatchPoll *iwp; + int tag; + + iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll)); + iwp->fd_can_read = fd_can_read; + iwp->opaque = user_data; + iwp->channel = channel; + iwp->fd_read = (GSourceFunc) fd_read; + iwp->src = NULL; + + tag = g_source_attach(&iwp->parent, NULL); + g_source_unref(&iwp->parent); + return tag; +} + +static void io_remove_watch_poll(guint tag) +{ + GSource *source; + IOWatchPoll *iwp; + + g_return_if_fail (tag > 0); + + source = g_main_context_find_source_by_id(NULL, tag); + g_return_if_fail (source != NULL); + + iwp = io_watch_poll_from_source(source); + if (iwp->src) { + g_source_destroy(iwp->src); + g_source_unref(iwp->src); + iwp->src = NULL; + } + g_source_destroy(&iwp->parent); +} + +static void remove_fd_in_watch(CharDriverState *chr) +{ + if (chr->fd_in_tag) { + io_remove_watch_poll(chr->fd_in_tag); + chr->fd_in_tag = 0; + } +} + +#ifndef _WIN32 +static GIOChannel *io_channel_from_fd(int fd) +{ + GIOChannel *chan; + + if (fd == -1) { + return NULL; + } + + chan = g_io_channel_unix_new(fd); + + g_io_channel_set_encoding(chan, NULL, NULL); + g_io_channel_set_buffered(chan, FALSE); + + return chan; +} +#endif + +static GIOChannel *io_channel_from_socket(int fd) +{ + GIOChannel *chan; + + if (fd == -1) { + return NULL; + } + +#ifdef _WIN32 + chan = g_io_channel_win32_new_socket(fd); +#else + chan = g_io_channel_unix_new(fd); +#endif + + g_io_channel_set_encoding(chan, NULL, NULL); + g_io_channel_set_buffered(chan, FALSE); + + return chan; +} + +static int io_channel_send(GIOChannel *fd, const void *buf, size_t len) +{ + size_t offset = 0; + GIOStatus status = G_IO_STATUS_NORMAL; + + while (offset < len && status == G_IO_STATUS_NORMAL) { + gsize bytes_written = 0; + + status = g_io_channel_write_chars(fd, buf + offset, len - offset, + &bytes_written, NULL); + offset += bytes_written; + } + + if (offset > 0) { + return offset; + } + switch (status) { + case G_IO_STATUS_NORMAL: + g_assert(len == 0); + return 0; + case G_IO_STATUS_AGAIN: + errno = EAGAIN; + return -1; + default: + break; + } + errno = EINVAL; + return -1; +} + +#ifndef _WIN32 + +typedef struct FDCharDriver { + CharDriverState *chr; + GIOChannel *fd_in, *fd_out; + int max_size; +} FDCharDriver; + +/* Called with chr_write_lock held. */ +static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + FDCharDriver *s = chr->opaque; + + return io_channel_send(s->fd_out, buf, len); +} + +static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) +{ + CharDriverState *chr = opaque; + FDCharDriver *s = chr->opaque; + int len; + uint8_t buf[READ_BUF_LEN]; + GIOStatus status; + gsize bytes_read; + + len = sizeof(buf); + if (len > s->max_size) { + len = s->max_size; + } + if (len == 0) { + return TRUE; + } + + status = g_io_channel_read_chars(chan, (gchar *)buf, + len, &bytes_read, NULL); + if (status == G_IO_STATUS_EOF) { + remove_fd_in_watch(chr); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); + return FALSE; + } + if (status == G_IO_STATUS_NORMAL) { + qemu_chr_be_write(chr, buf, bytes_read); + } + + return TRUE; +} + +static int fd_chr_read_poll(void *opaque) +{ + CharDriverState *chr = opaque; + FDCharDriver *s = chr->opaque; + + s->max_size = qemu_chr_be_can_write(chr); + return s->max_size; +} + +static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond) +{ + FDCharDriver *s = chr->opaque; + return g_io_create_watch(s->fd_out, cond); +} + +static void fd_chr_update_read_handler(CharDriverState *chr) +{ + FDCharDriver *s = chr->opaque; + + remove_fd_in_watch(chr); + if (s->fd_in) { + chr->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll, + fd_chr_read, chr); + } +} + +static void fd_chr_close(struct CharDriverState *chr) +{ + FDCharDriver *s = chr->opaque; + + remove_fd_in_watch(chr); + if (s->fd_in) { + g_io_channel_unref(s->fd_in); + } + if (s->fd_out) { + g_io_channel_unref(s->fd_out); + } + + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + +/* open a character device to a unix fd */ +static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) +{ + CharDriverState *chr; + FDCharDriver *s; + + chr = qemu_chr_alloc(); + s = g_new0(FDCharDriver, 1); + s->fd_in = io_channel_from_fd(fd_in); + s->fd_out = io_channel_from_fd(fd_out); + qemu_set_nonblock(fd_out); + s->chr = chr; + chr->opaque = s; + chr->chr_add_watch = fd_chr_add_watch; + chr->chr_write = fd_chr_write; + chr->chr_update_read_handler = fd_chr_update_read_handler; + chr->chr_close = fd_chr_close; + + return chr; +} + +static CharDriverState *qemu_chr_open_pipe(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevHostdev *opts = backend->u.pipe; + int fd_in, fd_out; + char filename_in[CHR_MAX_FILENAME_SIZE]; + char filename_out[CHR_MAX_FILENAME_SIZE]; + const char *filename = opts->device; + + snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename); + snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename); + TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY)); + TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY)); + if (fd_in < 0 || fd_out < 0) { + if (fd_in >= 0) + close(fd_in); + if (fd_out >= 0) + close(fd_out); + TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY)); + if (fd_in < 0) { + error_setg_file_open(errp, errno, filename); + return NULL; + } + } + return qemu_chr_open_fd(fd_in, fd_out); +} + +/* init terminal so that we can grab keys */ +static struct termios oldtty; +static int old_fd0_flags; +static bool stdio_in_use; +static bool stdio_allow_signal; +static bool stdio_echo_state; + +static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo); + +static void term_exit(void) +{ + tcsetattr (0, TCSANOW, &oldtty); + fcntl(0, F_SETFL, old_fd0_flags); +} + +static void term_stdio_handler(int sig) +{ + /* restore echo after resume from suspend. */ + qemu_chr_set_echo_stdio(NULL, stdio_echo_state); +} + +static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo) +{ + struct termios tty; + + stdio_echo_state = echo; + tty = oldtty; + if (!echo) { + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + tty.c_oflag |= OPOST; + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); + tty.c_cflag &= ~(CSIZE|PARENB); + tty.c_cflag |= CS8; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + } + if (!stdio_allow_signal) + tty.c_lflag &= ~ISIG; + + tcsetattr (0, TCSANOW, &tty); +} + +static void qemu_chr_close_stdio(struct CharDriverState *chr) +{ + term_exit(); + fd_chr_close(chr); +} + +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevStdio *opts = backend->u.stdio; + CharDriverState *chr; + struct sigaction act; + + if (is_daemonized()) { + error_setg(errp, "cannot use stdio with -daemonize"); + return NULL; + } + + if (stdio_in_use) { + error_setg(errp, "cannot use stdio by multiple character devices"); + return NULL; + } + + stdio_in_use = true; + old_fd0_flags = fcntl(0, F_GETFL); + tcgetattr(0, &oldtty); + qemu_set_nonblock(0); + atexit(term_exit); + + memset(&act, 0, sizeof(act)); + act.sa_handler = term_stdio_handler; + sigaction(SIGCONT, &act, NULL); + + /* NOTE: on Mac OS (noticed on 10.9.5), we get buffer overruns if the stdout stream is + * line buffered and the underlying stdout file has O_NONBLOCK set. When the stream reaches + * the end of the buffer allocated to it by setvbuf, instead of wrapping to the beginning of + * the buffer again, it just starts trashing memory after the buffer. We can avoid this issue + * by changing the stream to be non-buffered. + */ + setvbuf(stdout, NULL, _IONBF, 0); + + chr = qemu_chr_open_fd(0, 1); + chr->chr_close = qemu_chr_close_stdio; + chr->chr_set_echo = qemu_chr_set_echo_stdio; + if (opts->has_signal) { + stdio_allow_signal = opts->signal; + } + qemu_chr_fe_set_echo(chr, false); + + return chr; +} + +#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ + || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \ + || defined(__GLIBC__) + +#define HAVE_CHARDEV_SERIAL 1 +#define HAVE_CHARDEV_PTY 1 + +typedef struct { + GIOChannel *fd; + int read_bytes; + + /* Protected by the CharDriverState chr_write_lock. */ + int connected; + guint timer_tag; + guint open_tag; +} PtyCharDriver; + +static void pty_chr_update_read_handler_locked(CharDriverState *chr); +static void pty_chr_state(CharDriverState *chr, int connected); + +static gboolean pty_chr_timer(gpointer opaque) +{ + struct CharDriverState *chr = opaque; + PtyCharDriver *s = chr->opaque; + + qemu_mutex_lock(&chr->chr_write_lock); + s->timer_tag = 0; + s->open_tag = 0; + if (!s->connected) { + /* Next poll ... */ + pty_chr_update_read_handler_locked(chr); + } + qemu_mutex_unlock(&chr->chr_write_lock); + return FALSE; +} + +/* Called with chr_write_lock held. */ +static void pty_chr_rearm_timer(CharDriverState *chr, int ms) +{ + PtyCharDriver *s = chr->opaque; + + if (s->timer_tag) { + g_source_remove(s->timer_tag); + s->timer_tag = 0; + } + + if (ms == 1000) { + s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr); + } else { + s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr); + } +} + +/* Called with chr_write_lock held. */ +static void pty_chr_update_read_handler_locked(CharDriverState *chr) +{ + PtyCharDriver *s = chr->opaque; + GPollFD pfd; + int rc; + + pfd.fd = g_io_channel_unix_get_fd(s->fd); + pfd.events = G_IO_OUT; + pfd.revents = 0; + do { + rc = g_poll(&pfd, 1, 0); + } while (rc == -1 && errno == EINTR); + assert(rc >= 0); + + if (pfd.revents & G_IO_HUP) { + pty_chr_state(chr, 0); + } else { + pty_chr_state(chr, 1); + } +} + +static void pty_chr_update_read_handler(CharDriverState *chr) +{ + qemu_mutex_lock(&chr->chr_write_lock); + pty_chr_update_read_handler_locked(chr); + qemu_mutex_unlock(&chr->chr_write_lock); +} + +/* Called with chr_write_lock held. */ +static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + PtyCharDriver *s = chr->opaque; + + if (!s->connected) { + /* guest sends data, check for (re-)connect */ + pty_chr_update_read_handler_locked(chr); + if (!s->connected) { + return 0; + } + } + return io_channel_send(s->fd, buf, len); +} + +static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond) +{ + PtyCharDriver *s = chr->opaque; + if (!s->connected) { + return NULL; + } + return g_io_create_watch(s->fd, cond); +} + +static int pty_chr_read_poll(void *opaque) +{ + CharDriverState *chr = opaque; + PtyCharDriver *s = chr->opaque; + + s->read_bytes = qemu_chr_be_can_write(chr); + return s->read_bytes; +} + +static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) +{ + CharDriverState *chr = opaque; + PtyCharDriver *s = chr->opaque; + gsize size, len; + uint8_t buf[READ_BUF_LEN]; + GIOStatus status; + + len = sizeof(buf); + if (len > s->read_bytes) + len = s->read_bytes; + if (len == 0) { + return TRUE; + } + status = g_io_channel_read_chars(s->fd, (gchar *)buf, len, &size, NULL); + if (status != G_IO_STATUS_NORMAL) { + pty_chr_state(chr, 0); + return FALSE; + } else { + pty_chr_state(chr, 1); + qemu_chr_be_write(chr, buf, size); + } + return TRUE; +} + +static gboolean qemu_chr_be_generic_open_func(gpointer opaque) +{ + CharDriverState *chr = opaque; + PtyCharDriver *s = chr->opaque; + + s->open_tag = 0; + qemu_chr_be_generic_open(chr); + return FALSE; +} + +/* Called with chr_write_lock held. */ +static void pty_chr_state(CharDriverState *chr, int connected) +{ + PtyCharDriver *s = chr->opaque; + + if (!connected) { + if (s->open_tag) { + g_source_remove(s->open_tag); + s->open_tag = 0; + } + remove_fd_in_watch(chr); + s->connected = 0; + /* (re-)connect poll interval for idle guests: once per second. + * We check more frequently in case the guests sends data to + * the virtual device linked to our pty. */ + pty_chr_rearm_timer(chr, 1000); + } else { + if (s->timer_tag) { + g_source_remove(s->timer_tag); + s->timer_tag = 0; + } + if (!s->connected) { + g_assert(s->open_tag == 0); + s->connected = 1; + s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr); + } + if (!chr->fd_in_tag) { + chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, + pty_chr_read, chr); + } + } +} + +static void pty_chr_close(struct CharDriverState *chr) +{ + PtyCharDriver *s = chr->opaque; + int fd; + + qemu_mutex_lock(&chr->chr_write_lock); + pty_chr_state(chr, 0); + fd = g_io_channel_unix_get_fd(s->fd); + g_io_channel_unref(s->fd); + close(fd); + if (s->timer_tag) { + g_source_remove(s->timer_tag); + s->timer_tag = 0; + } + qemu_mutex_unlock(&chr->chr_write_lock); + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + +static CharDriverState *qemu_chr_open_pty(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + CharDriverState *chr; + PtyCharDriver *s; + int master_fd, slave_fd; + char pty_name[PATH_MAX]; + + master_fd = qemu_openpty_raw(&slave_fd, pty_name); + if (master_fd < 0) { + error_setg_errno(errp, errno, "Failed to create PTY"); + return NULL; + } + + close(slave_fd); + qemu_set_nonblock(master_fd); + + chr = qemu_chr_alloc(); + + chr->filename = g_strdup_printf("pty:%s", pty_name); + ret->pty = g_strdup(pty_name); + ret->has_pty = true; + + fprintf(stderr, "char device redirected to %s (label %s)\n", + pty_name, id); + + s = g_new0(PtyCharDriver, 1); + chr->opaque = s; + chr->chr_write = pty_chr_write; + chr->chr_update_read_handler = pty_chr_update_read_handler; + chr->chr_close = pty_chr_close; + chr->chr_add_watch = pty_chr_add_watch; + chr->explicit_be_open = true; + + s->fd = io_channel_from_fd(master_fd); + s->timer_tag = 0; + + return chr; +} + +static void tty_serial_init(int fd, int speed, + int parity, int data_bits, int stop_bits) +{ + struct termios tty; + speed_t spd; + +#if 0 + printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n", + speed, parity, data_bits, stop_bits); +#endif + tcgetattr (fd, &tty); + +#define check_speed(val) if (speed <= val) { spd = B##val; break; } + speed = speed * 10 / 11; + do { + check_speed(50); + check_speed(75); + check_speed(110); + check_speed(134); + check_speed(150); + check_speed(200); + check_speed(300); + check_speed(600); + check_speed(1200); + check_speed(1800); + check_speed(2400); + check_speed(4800); + check_speed(9600); + check_speed(19200); + check_speed(38400); + /* Non-Posix values follow. They may be unsupported on some systems. */ + check_speed(57600); + check_speed(115200); +#ifdef B230400 + check_speed(230400); +#endif +#ifdef B460800 + check_speed(460800); +#endif +#ifdef B500000 + check_speed(500000); +#endif +#ifdef B576000 + check_speed(576000); +#endif +#ifdef B921600 + check_speed(921600); +#endif +#ifdef B1000000 + check_speed(1000000); +#endif +#ifdef B1152000 + check_speed(1152000); +#endif +#ifdef B1500000 + check_speed(1500000); +#endif +#ifdef B2000000 + check_speed(2000000); +#endif +#ifdef B2500000 + check_speed(2500000); +#endif +#ifdef B3000000 + check_speed(3000000); +#endif +#ifdef B3500000 + check_speed(3500000); +#endif +#ifdef B4000000 + check_speed(4000000); +#endif + spd = B115200; + } while (0); + + cfsetispeed(&tty, spd); + cfsetospeed(&tty, spd); + + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + tty.c_oflag |= OPOST; + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); + tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB); + switch(data_bits) { + default: + case 8: + tty.c_cflag |= CS8; + break; + case 7: + tty.c_cflag |= CS7; + break; + case 6: + tty.c_cflag |= CS6; + break; + case 5: + tty.c_cflag |= CS5; + break; + } + switch(parity) { + default: + case 'N': + break; + case 'E': + tty.c_cflag |= PARENB; + break; + case 'O': + tty.c_cflag |= PARENB | PARODD; + break; + } + if (stop_bits == 2) + tty.c_cflag |= CSTOPB; + + tcsetattr (fd, TCSANOW, &tty); +} + +static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) +{ + FDCharDriver *s = chr->opaque; + + switch(cmd) { + case CHR_IOCTL_SERIAL_SET_PARAMS: + { + QEMUSerialSetParams *ssp = arg; + tty_serial_init(g_io_channel_unix_get_fd(s->fd_in), + ssp->speed, ssp->parity, + ssp->data_bits, ssp->stop_bits); + } + break; + case CHR_IOCTL_SERIAL_SET_BREAK: + { + int enable = *(int *)arg; + if (enable) { + tcsendbreak(g_io_channel_unix_get_fd(s->fd_in), 1); + } + } + break; + case CHR_IOCTL_SERIAL_GET_TIOCM: + { + int sarg = 0; + int *targ = (int *)arg; + ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &sarg); + *targ = 0; + if (sarg & TIOCM_CTS) + *targ |= CHR_TIOCM_CTS; + if (sarg & TIOCM_CAR) + *targ |= CHR_TIOCM_CAR; + if (sarg & TIOCM_DSR) + *targ |= CHR_TIOCM_DSR; + if (sarg & TIOCM_RI) + *targ |= CHR_TIOCM_RI; + if (sarg & TIOCM_DTR) + *targ |= CHR_TIOCM_DTR; + if (sarg & TIOCM_RTS) + *targ |= CHR_TIOCM_RTS; + } + break; + case CHR_IOCTL_SERIAL_SET_TIOCM: + { + int sarg = *(int *)arg; + int targ = 0; + ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &targ); + targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR + | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS); + if (sarg & CHR_TIOCM_CTS) + targ |= TIOCM_CTS; + if (sarg & CHR_TIOCM_CAR) + targ |= TIOCM_CAR; + if (sarg & CHR_TIOCM_DSR) + targ |= TIOCM_DSR; + if (sarg & CHR_TIOCM_RI) + targ |= TIOCM_RI; + if (sarg & CHR_TIOCM_DTR) + targ |= TIOCM_DTR; + if (sarg & CHR_TIOCM_RTS) + targ |= TIOCM_RTS; + ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); + } + break; + default: + return -ENOTSUP; + } + return 0; +} + +static void qemu_chr_close_tty(CharDriverState *chr) +{ + FDCharDriver *s = chr->opaque; + int fd = -1; + + if (s) { + fd = g_io_channel_unix_get_fd(s->fd_in); + } + + fd_chr_close(chr); + + if (fd >= 0) { + close(fd); + } +} + +static CharDriverState *qemu_chr_open_tty_fd(int fd) +{ + CharDriverState *chr; + + tty_serial_init(fd, 115200, 'N', 8, 1); + chr = qemu_chr_open_fd(fd, fd); + chr->chr_ioctl = tty_serial_ioctl; + chr->chr_close = qemu_chr_close_tty; + return chr; +} +#endif /* __linux__ || __sun__ */ + +#if defined(__linux__) + +#define HAVE_CHARDEV_PARPORT 1 + +typedef struct { + int fd; + int mode; +} ParallelCharDriver; + +static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode) +{ + if (s->mode != mode) { + int m = mode; + if (ioctl(s->fd, PPSETMODE, &m) < 0) + return 0; + s->mode = mode; + } + return 1; +} + +static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) +{ + ParallelCharDriver *drv = chr->opaque; + int fd = drv->fd; + uint8_t b; + + switch(cmd) { + case CHR_IOCTL_PP_READ_DATA: + if (ioctl(fd, PPRDATA, &b) < 0) + return -ENOTSUP; + *(uint8_t *)arg = b; + break; + case CHR_IOCTL_PP_WRITE_DATA: + b = *(uint8_t *)arg; + if (ioctl(fd, PPWDATA, &b) < 0) + return -ENOTSUP; + break; + case CHR_IOCTL_PP_READ_CONTROL: + if (ioctl(fd, PPRCONTROL, &b) < 0) + return -ENOTSUP; + /* Linux gives only the lowest bits, and no way to know data + direction! For better compatibility set the fixed upper + bits. */ + *(uint8_t *)arg = b | 0xc0; + break; + case CHR_IOCTL_PP_WRITE_CONTROL: + b = *(uint8_t *)arg; + if (ioctl(fd, PPWCONTROL, &b) < 0) + return -ENOTSUP; + break; + case CHR_IOCTL_PP_READ_STATUS: + if (ioctl(fd, PPRSTATUS, &b) < 0) + return -ENOTSUP; + *(uint8_t *)arg = b; + break; + case CHR_IOCTL_PP_DATA_DIR: + if (ioctl(fd, PPDATADIR, (int *)arg) < 0) + return -ENOTSUP; + break; + case CHR_IOCTL_PP_EPP_READ_ADDR: + if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) { + struct ParallelIOArg *parg = arg; + int n = read(fd, parg->buffer, parg->count); + if (n != parg->count) { + return -EIO; + } + } + break; + case CHR_IOCTL_PP_EPP_READ: + if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) { + struct ParallelIOArg *parg = arg; + int n = read(fd, parg->buffer, parg->count); + if (n != parg->count) { + return -EIO; + } + } + break; + case CHR_IOCTL_PP_EPP_WRITE_ADDR: + if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) { + struct ParallelIOArg *parg = arg; + int n = write(fd, parg->buffer, parg->count); + if (n != parg->count) { + return -EIO; + } + } + break; + case CHR_IOCTL_PP_EPP_WRITE: + if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) { + struct ParallelIOArg *parg = arg; + int n = write(fd, parg->buffer, parg->count); + if (n != parg->count) { + return -EIO; + } + } + break; + default: + return -ENOTSUP; + } + return 0; +} + +static void pp_close(CharDriverState *chr) +{ + ParallelCharDriver *drv = chr->opaque; + int fd = drv->fd; + + pp_hw_mode(drv, IEEE1284_MODE_COMPAT); + ioctl(fd, PPRELEASE); + close(fd); + g_free(drv); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + +static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) +{ + CharDriverState *chr; + ParallelCharDriver *drv; + + if (ioctl(fd, PPCLAIM) < 0) { + error_setg_errno(errp, errno, "not a parallel port"); + close(fd); + return NULL; + } + + drv = g_new0(ParallelCharDriver, 1); + drv->fd = fd; + drv->mode = IEEE1284_MODE_COMPAT; + + chr = qemu_chr_alloc(); + chr->chr_write = null_chr_write; + chr->chr_ioctl = pp_ioctl; + chr->chr_close = pp_close; + chr->opaque = drv; + + return chr; +} +#endif /* __linux__ */ + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + +#define HAVE_CHARDEV_PARPORT 1 + +static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) +{ + int fd = (int)(intptr_t)chr->opaque; + uint8_t b; + + switch(cmd) { + case CHR_IOCTL_PP_READ_DATA: + if (ioctl(fd, PPIGDATA, &b) < 0) + return -ENOTSUP; + *(uint8_t *)arg = b; + break; + case CHR_IOCTL_PP_WRITE_DATA: + b = *(uint8_t *)arg; + if (ioctl(fd, PPISDATA, &b) < 0) + return -ENOTSUP; + break; + case CHR_IOCTL_PP_READ_CONTROL: + if (ioctl(fd, PPIGCTRL, &b) < 0) + return -ENOTSUP; + *(uint8_t *)arg = b; + break; + case CHR_IOCTL_PP_WRITE_CONTROL: + b = *(uint8_t *)arg; + if (ioctl(fd, PPISCTRL, &b) < 0) + return -ENOTSUP; + break; + case CHR_IOCTL_PP_READ_STATUS: + if (ioctl(fd, PPIGSTATUS, &b) < 0) + return -ENOTSUP; + *(uint8_t *)arg = b; + break; + default: + return -ENOTSUP; + } + return 0; +} + +static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) +{ + CharDriverState *chr; + + chr = qemu_chr_alloc(); + chr->opaque = (void *)(intptr_t)fd; + chr->chr_write = null_chr_write; + chr->chr_ioctl = pp_ioctl; + chr->explicit_be_open = true; + return chr; +} +#endif + +#else /* _WIN32 */ + +#define HAVE_CHARDEV_SERIAL 1 + +typedef struct { + int max_size; + HANDLE hcom, hrecv, hsend; + OVERLAPPED orecv; + BOOL fpipe; + DWORD len; + + /* Protected by the CharDriverState chr_write_lock. */ + OVERLAPPED osend; +} WinCharState; + +typedef struct { + HANDLE hStdIn; + HANDLE hInputReadyEvent; + HANDLE hInputDoneEvent; + HANDLE hInputThread; + uint8_t win_stdio_buf; +} WinStdioCharState; + +#define NSENDBUF 2048 +#define NRECVBUF 2048 +#define MAXCONNECT 1 +#define NTIMEOUT 5000 + +static int win_chr_poll(void *opaque); +static int win_chr_pipe_poll(void *opaque); + +static void win_chr_close(CharDriverState *chr) +{ + WinCharState *s = chr->opaque; + + if (s->hsend) { + CloseHandle(s->hsend); + s->hsend = NULL; + } + if (s->hrecv) { + CloseHandle(s->hrecv); + s->hrecv = NULL; + } + if (s->hcom) { + CloseHandle(s->hcom); + s->hcom = NULL; + } + if (s->fpipe) + qemu_del_polling_cb(win_chr_pipe_poll, chr); + else + qemu_del_polling_cb(win_chr_poll, chr); + + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + +static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp) +{ + WinCharState *s = chr->opaque; + COMMCONFIG comcfg; + COMMTIMEOUTS cto = { 0, 0, 0, 0, 0}; + COMSTAT comstat; + DWORD size; + DWORD err; + + s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!s->hsend) { + error_setg(errp, "Failed CreateEvent"); + goto fail; + } + s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!s->hrecv) { + error_setg(errp, "Failed CreateEvent"); + goto fail; + } + + s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + if (s->hcom == INVALID_HANDLE_VALUE) { + error_setg(errp, "Failed CreateFile (%lu)", GetLastError()); + s->hcom = NULL; + goto fail; + } + + if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) { + error_setg(errp, "Failed SetupComm"); + goto fail; + } + + ZeroMemory(&comcfg, sizeof(COMMCONFIG)); + size = sizeof(COMMCONFIG); + GetDefaultCommConfig(filename, &comcfg, &size); + comcfg.dcb.DCBlength = sizeof(DCB); + CommConfigDialog(filename, NULL, &comcfg); + + if (!SetCommState(s->hcom, &comcfg.dcb)) { + error_setg(errp, "Failed SetCommState"); + goto fail; + } + + if (!SetCommMask(s->hcom, EV_ERR)) { + error_setg(errp, "Failed SetCommMask"); + goto fail; + } + + cto.ReadIntervalTimeout = MAXDWORD; + if (!SetCommTimeouts(s->hcom, &cto)) { + error_setg(errp, "Failed SetCommTimeouts"); + goto fail; + } + + if (!ClearCommError(s->hcom, &err, &comstat)) { + error_setg(errp, "Failed ClearCommError"); + goto fail; + } + qemu_add_polling_cb(win_chr_poll, chr); + return 0; + + fail: + win_chr_close(chr); + return -1; +} + +/* Called with chr_write_lock held. */ +static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1) +{ + WinCharState *s = chr->opaque; + DWORD len, ret, size, err; + + len = len1; + ZeroMemory(&s->osend, sizeof(s->osend)); + s->osend.hEvent = s->hsend; + while (len > 0) { + if (s->hsend) + ret = WriteFile(s->hcom, buf, len, &size, &s->osend); + else + ret = WriteFile(s->hcom, buf, len, &size, NULL); + if (!ret) { + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE); + if (ret) { + buf += size; + len -= size; + } else { + break; + } + } else { + break; + } + } else { + buf += size; + len -= size; + } + } + return len1 - len; +} + +static int win_chr_read_poll(CharDriverState *chr) +{ + WinCharState *s = chr->opaque; + + s->max_size = qemu_chr_be_can_write(chr); + return s->max_size; +} + +static void win_chr_readfile(CharDriverState *chr) +{ + WinCharState *s = chr->opaque; + int ret, err; + uint8_t buf[READ_BUF_LEN]; + DWORD size; + + ZeroMemory(&s->orecv, sizeof(s->orecv)); + s->orecv.hEvent = s->hrecv; + ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv); + if (!ret) { + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE); + } + } + + if (size > 0) { + qemu_chr_be_write(chr, buf, size); + } +} + +static void win_chr_read(CharDriverState *chr) +{ + WinCharState *s = chr->opaque; + + if (s->len > s->max_size) + s->len = s->max_size; + if (s->len == 0) + return; + + win_chr_readfile(chr); +} + +static int win_chr_poll(void *opaque) +{ + CharDriverState *chr = opaque; + WinCharState *s = chr->opaque; + COMSTAT status; + DWORD comerr; + + ClearCommError(s->hcom, &comerr, &status); + if (status.cbInQue > 0) { + s->len = status.cbInQue; + win_chr_read_poll(chr); + win_chr_read(chr); + return 1; + } + return 0; +} + +static CharDriverState *qemu_chr_open_win_path(const char *filename, + Error **errp) +{ + CharDriverState *chr; + WinCharState *s; + + chr = qemu_chr_alloc(); + s = g_new0(WinCharState, 1); + chr->opaque = s; + chr->chr_write = win_chr_write; + chr->chr_close = win_chr_close; + + if (win_chr_init(chr, filename, errp) < 0) { + g_free(s); + g_free(chr); + return NULL; + } + return chr; +} + +static int win_chr_pipe_poll(void *opaque) +{ + CharDriverState *chr = opaque; + WinCharState *s = chr->opaque; + DWORD size; + + PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL); + if (size > 0) { + s->len = size; + win_chr_read_poll(chr); + win_chr_read(chr); + return 1; + } + return 0; +} + +static int win_chr_pipe_init(CharDriverState *chr, const char *filename, + Error **errp) +{ + WinCharState *s = chr->opaque; + OVERLAPPED ov; + int ret; + DWORD size; + char openname[CHR_MAX_FILENAME_SIZE]; + + s->fpipe = TRUE; + + s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!s->hsend) { + error_setg(errp, "Failed CreateEvent"); + goto fail; + } + s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!s->hrecv) { + error_setg(errp, "Failed CreateEvent"); + goto fail; + } + + snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename); + s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | + PIPE_WAIT, + MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL); + if (s->hcom == INVALID_HANDLE_VALUE) { + error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError()); + s->hcom = NULL; + goto fail; + } + + ZeroMemory(&ov, sizeof(ov)); + ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + ret = ConnectNamedPipe(s->hcom, &ov); + if (ret) { + error_setg(errp, "Failed ConnectNamedPipe"); + goto fail; + } + + ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE); + if (!ret) { + error_setg(errp, "Failed GetOverlappedResult"); + if (ov.hEvent) { + CloseHandle(ov.hEvent); + ov.hEvent = NULL; + } + goto fail; + } + + if (ov.hEvent) { + CloseHandle(ov.hEvent); + ov.hEvent = NULL; + } + qemu_add_polling_cb(win_chr_pipe_poll, chr); + return 0; + + fail: + win_chr_close(chr); + return -1; +} + + +static CharDriverState *qemu_chr_open_pipe(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevHostdev *opts = backend->u.pipe; + const char *filename = opts->device; + CharDriverState *chr; + WinCharState *s; + + chr = qemu_chr_alloc(); + s = g_new0(WinCharState, 1); + chr->opaque = s; + chr->chr_write = win_chr_write; + chr->chr_close = win_chr_close; + + if (win_chr_pipe_init(chr, filename, errp) < 0) { + g_free(s); + g_free(chr); + return NULL; + } + return chr; +} + +static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) +{ + CharDriverState *chr; + WinCharState *s; + + chr = qemu_chr_alloc(); + s = g_new0(WinCharState, 1); + s->hcom = fd_out; + chr->opaque = s; + chr->chr_write = win_chr_write; + return chr; +} + +static CharDriverState *qemu_chr_open_win_con(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE)); +} + +static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwSize; + int len1; + + len1 = len; + + while (len1 > 0) { + if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) { + break; + } + buf += dwSize; + len1 -= dwSize; + } + + return len - len1; +} + +static void win_stdio_wait_func(void *opaque) +{ + CharDriverState *chr = opaque; + WinStdioCharState *stdio = chr->opaque; + INPUT_RECORD buf[4]; + int ret; + DWORD dwSize; + int i; + + ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize); + + if (!ret) { + /* Avoid error storm */ + qemu_del_wait_object(stdio->hStdIn, NULL, NULL); + return; + } + + for (i = 0; i < dwSize; i++) { + KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent; + + if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) { + int j; + if (kev->uChar.AsciiChar != 0) { + for (j = 0; j < kev->wRepeatCount; j++) { + if (qemu_chr_be_can_write(chr)) { + uint8_t c = kev->uChar.AsciiChar; + qemu_chr_be_write(chr, &c, 1); + } + } + } + } + } +} + +static DWORD WINAPI win_stdio_thread(LPVOID param) +{ + CharDriverState *chr = param; + WinStdioCharState *stdio = chr->opaque; + int ret; + DWORD dwSize; + + while (1) { + + /* Wait for one byte */ + ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL); + + /* Exit in case of error, continue if nothing read */ + if (!ret) { + break; + } + if (!dwSize) { + continue; + } + + /* Some terminal emulator returns \r\n for Enter, just pass \n */ + if (stdio->win_stdio_buf == '\r') { + continue; + } + + /* Signal the main thread and wait until the byte was eaten */ + if (!SetEvent(stdio->hInputReadyEvent)) { + break; + } + if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE) + != WAIT_OBJECT_0) { + break; + } + } + + qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); + return 0; +} + +static void win_stdio_thread_wait_func(void *opaque) +{ + CharDriverState *chr = opaque; + WinStdioCharState *stdio = chr->opaque; + + if (qemu_chr_be_can_write(chr)) { + qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1); + } + + SetEvent(stdio->hInputDoneEvent); +} + +static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo) +{ + WinStdioCharState *stdio = chr->opaque; + DWORD dwMode = 0; + + GetConsoleMode(stdio->hStdIn, &dwMode); + + if (echo) { + SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT); + } else { + SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT); + } +} + +static void win_stdio_close(CharDriverState *chr) +{ + WinStdioCharState *stdio = chr->opaque; + + if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) { + CloseHandle(stdio->hInputReadyEvent); + } + if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) { + CloseHandle(stdio->hInputDoneEvent); + } + if (stdio->hInputThread != INVALID_HANDLE_VALUE) { + TerminateThread(stdio->hInputThread, 0); + } + + g_free(chr->opaque); + g_free(chr); +} + +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + CharDriverState *chr; + WinStdioCharState *stdio; + DWORD dwMode; + int is_console = 0; + + chr = qemu_chr_alloc(); + stdio = g_new0(WinStdioCharState, 1); + + stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); + if (stdio->hStdIn == INVALID_HANDLE_VALUE) { + error_setg(errp, "cannot open stdio: invalid handle"); + return NULL; + } + + is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; + + chr->opaque = stdio; + chr->chr_write = win_stdio_write; + chr->chr_close = win_stdio_close; + + if (is_console) { + if (qemu_add_wait_object(stdio->hStdIn, + win_stdio_wait_func, chr)) { + error_setg(errp, "qemu_add_wait_object: failed"); + goto err1; + } + } else { + DWORD dwId; + + stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE + || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { + error_setg(errp, "cannot create event"); + goto err2; + } + if (qemu_add_wait_object(stdio->hInputReadyEvent, + win_stdio_thread_wait_func, chr)) { + error_setg(errp, "qemu_add_wait_object: failed"); + goto err2; + } + stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, + chr, 0, &dwId); + + if (stdio->hInputThread == INVALID_HANDLE_VALUE) { + error_setg(errp, "cannot create stdio thread"); + goto err3; + } + } + + dwMode |= ENABLE_LINE_INPUT; + + if (is_console) { + /* set the terminal in raw mode */ + /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */ + dwMode |= ENABLE_PROCESSED_INPUT; + } + + SetConsoleMode(stdio->hStdIn, dwMode); + + chr->chr_set_echo = qemu_chr_set_echo_win_stdio; + qemu_chr_fe_set_echo(chr, false); + + return chr; + +err3: + qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); +err2: + CloseHandle(stdio->hInputReadyEvent); + CloseHandle(stdio->hInputDoneEvent); +err1: + qemu_del_wait_object(stdio->hStdIn, NULL, NULL); + return NULL; +} +#endif /* !_WIN32 */ + + +/***********************************************************/ +/* UDP Net console */ + +typedef struct { + int fd; + GIOChannel *chan; + uint8_t buf[READ_BUF_LEN]; + int bufcnt; + int bufptr; + int max_size; +} NetCharDriver; + +/* Called with chr_write_lock held. */ +static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + NetCharDriver *s = chr->opaque; + gsize bytes_written; + GIOStatus status; + + status = g_io_channel_write_chars(s->chan, (const gchar *)buf, len, &bytes_written, NULL); + if (status == G_IO_STATUS_EOF) { + return 0; + } else if (status != G_IO_STATUS_NORMAL) { + return -1; + } + + return bytes_written; +} + +static int udp_chr_read_poll(void *opaque) +{ + CharDriverState *chr = opaque; + NetCharDriver *s = chr->opaque; + + s->max_size = qemu_chr_be_can_write(chr); + + /* If there were any stray characters in the queue process them + * first + */ + while (s->max_size > 0 && s->bufptr < s->bufcnt) { + qemu_chr_be_write(chr, &s->buf[s->bufptr], 1); + s->bufptr++; + s->max_size = qemu_chr_be_can_write(chr); + } + return s->max_size; +} + +static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) +{ + CharDriverState *chr = opaque; + NetCharDriver *s = chr->opaque; + gsize bytes_read = 0; + GIOStatus status; + + if (s->max_size == 0) { + return TRUE; + } + status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf), + &bytes_read, NULL); + s->bufcnt = bytes_read; + s->bufptr = s->bufcnt; + if (status != G_IO_STATUS_NORMAL) { + remove_fd_in_watch(chr); + return FALSE; + } + + s->bufptr = 0; + while (s->max_size > 0 && s->bufptr < s->bufcnt) { + qemu_chr_be_write(chr, &s->buf[s->bufptr], 1); + s->bufptr++; + s->max_size = qemu_chr_be_can_write(chr); + } + + return TRUE; +} + +static void udp_chr_update_read_handler(CharDriverState *chr) +{ + NetCharDriver *s = chr->opaque; + + remove_fd_in_watch(chr); + if (s->chan) { + chr->fd_in_tag = io_add_watch_poll(s->chan, udp_chr_read_poll, + udp_chr_read, chr); + } +} + +static void udp_chr_close(CharDriverState *chr) +{ + NetCharDriver *s = chr->opaque; + + remove_fd_in_watch(chr); + if (s->chan) { + g_io_channel_unref(s->chan); + closesocket(s->fd); + } + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + +static CharDriverState *qemu_chr_open_udp_fd(int fd) +{ + CharDriverState *chr = NULL; + NetCharDriver *s = NULL; + + chr = qemu_chr_alloc(); + s = g_new0(NetCharDriver, 1); + + s->fd = fd; + s->chan = io_channel_from_socket(s->fd); + s->bufcnt = 0; + s->bufptr = 0; + chr->opaque = s; + chr->chr_write = udp_chr_write; + chr->chr_update_read_handler = udp_chr_update_read_handler; + chr->chr_close = udp_chr_close; + /* be isn't opened until we get a connection */ + chr->explicit_be_open = true; + return chr; +} + +/***********************************************************/ +/* TCP Net console */ + +typedef struct { + + GIOChannel *chan, *listen_chan; + guint listen_tag; + int fd, listen_fd; + int connected; + int max_size; + int do_telnetopt; + int do_nodelay; + int is_unix; + int *read_msgfds; + int read_msgfds_num; + int *write_msgfds; + int write_msgfds_num; + + SocketAddress *addr; + bool is_listen; + bool is_telnet; + + guint reconnect_timer; + int64_t reconnect_time; + bool connect_err_reported; +} TCPCharDriver; + +static gboolean socket_reconnect_timeout(gpointer opaque); + +static void qemu_chr_socket_restart_timer(CharDriverState *chr) +{ + TCPCharDriver *s = chr->opaque; + assert(s->connected == 0); + s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time, + socket_reconnect_timeout, chr); +} + +static void check_report_connect_error(CharDriverState *chr, + Error *err) +{ + TCPCharDriver *s = chr->opaque; + + if (!s->connect_err_reported) { + error_report("Unable to connect character device %s: %s", + chr->label, error_get_pretty(err)); + s->connect_err_reported = true; + } + qemu_chr_socket_restart_timer(chr); +} + +static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque); + +#ifndef _WIN32 +static int unix_send_msgfds(CharDriverState *chr, const uint8_t *buf, int len) +{ + TCPCharDriver *s = chr->opaque; + struct msghdr msgh; + struct iovec iov; + int r; + + size_t fd_size = s->write_msgfds_num * sizeof(int); + char control[CMSG_SPACE(fd_size)]; + struct cmsghdr *cmsg; + + memset(&msgh, 0, sizeof(msgh)); + memset(control, 0, sizeof(control)); + + /* set the payload */ + iov.iov_base = (uint8_t *) buf; + iov.iov_len = len; + + msgh.msg_iov = &iov; + msgh.msg_iovlen = 1; + + msgh.msg_control = control; + msgh.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&msgh); + + cmsg->cmsg_len = CMSG_LEN(fd_size); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy(CMSG_DATA(cmsg), s->write_msgfds, fd_size); + + do { + r = sendmsg(s->fd, &msgh, 0); + } while (r < 0 && errno == EINTR); + + /* free the written msgfds, no matter what */ + if (s->write_msgfds_num) { + g_free(s->write_msgfds); + s->write_msgfds = 0; + s->write_msgfds_num = 0; + } + + return r; +} +#endif + +/* Called with chr_write_lock held. */ +static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + TCPCharDriver *s = chr->opaque; + if (s->connected) { +#ifndef _WIN32 + if (s->is_unix && s->write_msgfds_num) { + return unix_send_msgfds(chr, buf, len); + } else +#endif + { + return io_channel_send(s->chan, buf, len); + } + } else { + /* XXX: indicate an error ? */ + return len; + } +} + +static int tcp_chr_read_poll(void *opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + if (!s->connected) + return 0; + s->max_size = qemu_chr_be_can_write(chr); + return s->max_size; +} + +#define IAC 255 +#define IAC_BREAK 243 +static void tcp_chr_process_IAC_bytes(CharDriverState *chr, + TCPCharDriver *s, + uint8_t *buf, int *size) +{ + /* Handle any telnet client's basic IAC options to satisfy char by + * char mode with no echo. All IAC options will be removed from + * the buf and the do_telnetopt variable will be used to track the + * state of the width of the IAC information. + * + * IAC commands come in sets of 3 bytes with the exception of the + * "IAC BREAK" command and the double IAC. + */ + + int i; + int j = 0; + + for (i = 0; i < *size; i++) { + if (s->do_telnetopt > 1) { + if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) { + /* Double IAC means send an IAC */ + if (j != i) + buf[j] = buf[i]; + j++; + s->do_telnetopt = 1; + } else { + if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) { + /* Handle IAC break commands by sending a serial break */ + qemu_chr_be_event(chr, CHR_EVENT_BREAK); + s->do_telnetopt++; + } + s->do_telnetopt++; + } + if (s->do_telnetopt >= 4) { + s->do_telnetopt = 1; + } + } else { + if ((unsigned char)buf[i] == IAC) { + s->do_telnetopt = 2; + } else { + if (j != i) + buf[j] = buf[i]; + j++; + } + } + } + *size = j; +} + +static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num) +{ + TCPCharDriver *s = chr->opaque; + int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; + + assert(num <= TCP_MAX_FDS); + + if (to_copy) { + int i; + + memcpy(fds, s->read_msgfds, to_copy * sizeof(int)); + + /* Close unused fds */ + for (i = to_copy; i < s->read_msgfds_num; i++) { + close(s->read_msgfds[i]); + } + + g_free(s->read_msgfds); + s->read_msgfds = 0; + s->read_msgfds_num = 0; + } + + return to_copy; +} + +static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) +{ + TCPCharDriver *s = chr->opaque; + + /* clear old pending fd array */ + g_free(s->write_msgfds); + + if (num) { + s->write_msgfds = g_new(int, num); + memcpy(s->write_msgfds, fds, num * sizeof(int)); + } + + s->write_msgfds_num = num; + + return 0; +} + +#ifndef _WIN32 +static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg) +{ + TCPCharDriver *s = chr->opaque; + struct cmsghdr *cmsg; + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { + int fd_size, i; + + if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) || + cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) { + continue; + } + + fd_size = cmsg->cmsg_len - CMSG_LEN(0); + + if (!fd_size) { + continue; + } + + /* close and clean read_msgfds */ + for (i = 0; i < s->read_msgfds_num; i++) { + close(s->read_msgfds[i]); + } + + if (s->read_msgfds_num) { + g_free(s->read_msgfds); + } + + s->read_msgfds_num = fd_size / sizeof(int); + s->read_msgfds = g_malloc(fd_size); + memcpy(s->read_msgfds, CMSG_DATA(cmsg), fd_size); + + for (i = 0; i < s->read_msgfds_num; i++) { + int fd = s->read_msgfds[i]; + if (fd < 0) { + continue; + } + + /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ + qemu_set_block(fd); + + #ifndef MSG_CMSG_CLOEXEC + qemu_set_cloexec(fd); + #endif + } + } +} + +static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) +{ + TCPCharDriver *s = chr->opaque; + struct msghdr msg = { NULL, }; + struct iovec iov[1]; + union { + struct cmsghdr cmsg; + char control[CMSG_SPACE(sizeof(int) * TCP_MAX_FDS)]; + } msg_control; + int flags = 0; + ssize_t ret; + + iov[0].iov_base = buf; + iov[0].iov_len = len; + + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + +#ifdef MSG_CMSG_CLOEXEC + flags |= MSG_CMSG_CLOEXEC; +#endif + do { + ret = recvmsg(s->fd, &msg, flags); + } while (ret == -1 && errno == EINTR); + + if (ret > 0 && s->is_unix) { + unix_process_msgfd(chr, &msg); + } + + return ret; +} +#else +static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) +{ + TCPCharDriver *s = chr->opaque; + ssize_t ret; + + do { + ret = qemu_recv(s->fd, buf, len, 0); + } while (ret == -1 && socket_error() == EINTR); + + return ret; +} +#endif + +static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond) +{ + TCPCharDriver *s = chr->opaque; + return g_io_create_watch(s->chan, cond); +} + +static void tcp_chr_disconnect(CharDriverState *chr) +{ + TCPCharDriver *s = chr->opaque; + + s->connected = 0; + if (s->listen_chan) { + s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, + tcp_chr_accept, chr); + } + remove_fd_in_watch(chr); + g_io_channel_unref(s->chan); + s->chan = NULL; + closesocket(s->fd); + s->fd = -1; + SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, + "disconnected:", s->addr, s->is_listen, s->is_telnet); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); + if (s->reconnect_time) { + qemu_chr_socket_restart_timer(chr); + } +} + +static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + uint8_t buf[READ_BUF_LEN]; + int len, size; + + if (!s->connected || s->max_size <= 0) { + return TRUE; + } + len = sizeof(buf); + if (len > s->max_size) + len = s->max_size; + size = tcp_chr_recv(chr, (void *)buf, len); + if (size == 0 || + (size < 0 && + socket_error() != EAGAIN && socket_error() != EWOULDBLOCK)) { + /* connection closed */ + tcp_chr_disconnect(chr); + } else if (size > 0) { + if (s->do_telnetopt) + tcp_chr_process_IAC_bytes(chr, s, buf, &size); + if (size > 0) + qemu_chr_be_write(chr, buf, size); + } + + return TRUE; +} + +static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len) +{ + TCPCharDriver *s = chr->opaque; + int size; + + if (!s->connected) { + return 0; + } + + size = tcp_chr_recv(chr, (void *) buf, len); + if (size == 0) { + /* connection closed */ + tcp_chr_disconnect(chr); + } + + return size; +} + +#ifndef _WIN32 +CharDriverState *qemu_chr_open_eventfd(int eventfd) +{ + CharDriverState *chr = qemu_chr_open_fd(eventfd, eventfd); + + if (chr) { + chr->avail_connections = 1; + } + + return chr; +} +#endif + +static void tcp_chr_connect(void *opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + struct sockaddr_storage ss, ps; + socklen_t ss_len = sizeof(ss), ps_len = sizeof(ps); + + memset(&ss, 0, ss_len); + if (getsockname(s->fd, (struct sockaddr *) &ss, &ss_len) != 0) { + snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, + "Error in getsockname: %s\n", strerror(errno)); + } else if (getpeername(s->fd, (struct sockaddr *) &ps, &ps_len) != 0) { + snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, + "Error in getpeername: %s\n", strerror(errno)); + } else { + sockaddr_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, + &ss, ss_len, &ps, ps_len, + s->is_listen, s->is_telnet); + } + + s->connected = 1; + if (s->chan) { + chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, + tcp_chr_read, chr); + } + qemu_chr_be_generic_open(chr); +} + +static void tcp_chr_update_read_handler(CharDriverState *chr) +{ + TCPCharDriver *s = chr->opaque; + + remove_fd_in_watch(chr); + if (s->chan) { + chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, + tcp_chr_read, chr); + } +} + +#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c; +static void tcp_chr_telnet_init(int fd) +{ + char buf[3]; + /* Send the telnet negotion to put telnet in binary, no echo, single char mode */ + IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */ + send(fd, (char *)buf, 3, 0); + IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */ + send(fd, (char *)buf, 3, 0); + IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */ + send(fd, (char *)buf, 3, 0); + IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */ + send(fd, (char *)buf, 3, 0); +} + +static int tcp_chr_add_client(CharDriverState *chr, int fd) +{ + TCPCharDriver *s = chr->opaque; + if (s->fd != -1) + return -1; + + qemu_set_nonblock(fd); + if (s->do_nodelay) + socket_set_nodelay(fd); + s->fd = fd; + s->chan = io_channel_from_socket(fd); + if (s->listen_tag) { + g_source_remove(s->listen_tag); + s->listen_tag = 0; + } + tcp_chr_connect(chr); + + return 0; +} + +static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + struct sockaddr_in saddr; +#ifndef _WIN32 + struct sockaddr_un uaddr; +#endif + struct sockaddr *addr; + socklen_t len; + int fd; + + for(;;) { +#ifndef _WIN32 + if (s->is_unix) { + len = sizeof(uaddr); + addr = (struct sockaddr *)&uaddr; + } else +#endif + { + len = sizeof(saddr); + addr = (struct sockaddr *)&saddr; + } + fd = qemu_accept(s->listen_fd, addr, &len); + if (fd < 0 && errno != EINTR) { + s->listen_tag = 0; + return FALSE; + } else if (fd >= 0) { + if (s->do_telnetopt) + tcp_chr_telnet_init(fd); + break; + } + } + if (tcp_chr_add_client(chr, fd) < 0) + close(fd); + + return TRUE; +} + +static void tcp_chr_close(CharDriverState *chr) +{ + TCPCharDriver *s = chr->opaque; + int i; + + if (s->reconnect_timer) { + g_source_remove(s->reconnect_timer); + s->reconnect_timer = 0; + } + qapi_free_SocketAddress(s->addr); + if (s->fd >= 0) { + remove_fd_in_watch(chr); + if (s->chan) { + g_io_channel_unref(s->chan); + } + closesocket(s->fd); + } + if (s->listen_fd >= 0) { + if (s->listen_tag) { + g_source_remove(s->listen_tag); + s->listen_tag = 0; + } + if (s->listen_chan) { + g_io_channel_unref(s->listen_chan); + } + closesocket(s->listen_fd); + } + if (s->read_msgfds_num) { + for (i = 0; i < s->read_msgfds_num; i++) { + close(s->read_msgfds[i]); + } + g_free(s->read_msgfds); + } + if (s->write_msgfds_num) { + g_free(s->write_msgfds); + } + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); +} + +static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd) +{ + TCPCharDriver *s = chr->opaque; + + if (s->is_listen) { + s->listen_fd = fd; + s->listen_chan = io_channel_from_socket(s->listen_fd); + s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, + tcp_chr_accept, chr); + } else { + s->connected = 1; + s->fd = fd; + socket_set_nodelay(fd); + s->chan = io_channel_from_socket(s->fd); + tcp_chr_connect(chr); + } +} + +static void qemu_chr_socket_connected(int fd, Error *err, void *opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + + if (fd < 0) { + check_report_connect_error(chr, err); + return; + } + + s->connect_err_reported = false; + qemu_chr_finish_socket_connection(chr, fd); +} + +static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp) +{ + TCPCharDriver *s = chr->opaque; + int fd; + + if (s->is_listen) { + fd = socket_listen(s->addr, errp); + } else if (s->reconnect_time) { + fd = socket_connect(s->addr, errp, qemu_chr_socket_connected, chr); + return fd >= 0; + } else { + fd = socket_connect(s->addr, errp, NULL, NULL); + } + if (fd < 0) { + return false; + } + + qemu_chr_finish_socket_connection(chr, fd); + return true; +} + +/*********************************************************/ +/* Ring buffer chardev */ + +typedef struct { + size_t size; + size_t prod; + size_t cons; + uint8_t *cbuf; +} RingBufCharDriver; + +static size_t ringbuf_count(const CharDriverState *chr) +{ + const RingBufCharDriver *d = chr->opaque; + + return d->prod - d->cons; +} + +/* Called with chr_write_lock held. */ +static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + RingBufCharDriver *d = chr->opaque; + int i; + + if (!buf || (len < 0)) { + return -1; + } + + for (i = 0; i < len; i++ ) { + d->cbuf[d->prod++ & (d->size - 1)] = buf[i]; + if (d->prod - d->cons > d->size) { + d->cons = d->prod - d->size; + } + } + + return 0; +} + +static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len) +{ + RingBufCharDriver *d = chr->opaque; + int i; + + qemu_mutex_lock(&chr->chr_write_lock); + for (i = 0; i < len && d->cons != d->prod; i++) { + buf[i] = d->cbuf[d->cons++ & (d->size - 1)]; + } + qemu_mutex_unlock(&chr->chr_write_lock); + + return i; +} + +static void ringbuf_chr_close(struct CharDriverState *chr) +{ + RingBufCharDriver *d = chr->opaque; + + g_free(d->cbuf); + g_free(d); + chr->opaque = NULL; +} + +static CharDriverState *qemu_chr_open_ringbuf(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevRingbuf *opts = backend->u.ringbuf; + CharDriverState *chr; + RingBufCharDriver *d; + + chr = qemu_chr_alloc(); + d = g_malloc(sizeof(*d)); + + d->size = opts->has_size ? opts->size : 65536; + + /* The size must be power of 2 */ + if (d->size & (d->size - 1)) { + error_setg(errp, "size of ringbuf chardev must be power of two"); + goto fail; + } + + d->prod = 0; + d->cons = 0; + d->cbuf = g_malloc0(d->size); + + chr->opaque = d; + chr->chr_write = ringbuf_chr_write; + chr->chr_close = ringbuf_chr_close; + + return chr; + +fail: + g_free(d); + g_free(chr); + return NULL; +} + +bool chr_is_ringbuf(const CharDriverState *chr) +{ + return chr->chr_write == ringbuf_chr_write; +} + +void qmp_ringbuf_write(const char *device, const char *data, + bool has_format, enum DataFormat format, + Error **errp) +{ + CharDriverState *chr; + const uint8_t *write_data; + int ret; + gsize write_count; + + chr = qemu_chr_find(device); + if (!chr) { + error_setg(errp, "Device '%s' not found", device); + return; + } + + if (!chr_is_ringbuf(chr)) { + error_setg(errp,"%s is not a ringbuf device", device); + return; + } + + if (has_format && (format == DATA_FORMAT_BASE64)) { + write_data = g_base64_decode(data, &write_count); + } else { + write_data = (uint8_t *)data; + write_count = strlen(data); + } + + ret = ringbuf_chr_write(chr, write_data, write_count); + + if (write_data != (uint8_t *)data) { + g_free((void *)write_data); + } + + if (ret < 0) { + error_setg(errp, "Failed to write to device %s", device); + return; + } +} + +char *qmp_ringbuf_read(const char *device, int64_t size, + bool has_format, enum DataFormat format, + Error **errp) +{ + CharDriverState *chr; + uint8_t *read_data; + size_t count; + char *data; + + chr = qemu_chr_find(device); + if (!chr) { + error_setg(errp, "Device '%s' not found", device); + return NULL; + } + + if (!chr_is_ringbuf(chr)) { + error_setg(errp,"%s is not a ringbuf device", device); + return NULL; + } + + if (size <= 0) { + error_setg(errp, "size must be greater than zero"); + return NULL; + } + + count = ringbuf_count(chr); + size = size > count ? count : size; + read_data = g_malloc(size + 1); + + ringbuf_chr_read(chr, read_data, size); + + if (has_format && (format == DATA_FORMAT_BASE64)) { + data = g_base64_encode(read_data, size); + g_free(read_data); + } else { + /* + * FIXME should read only complete, valid UTF-8 characters up + * to @size bytes. Invalid sequences should be replaced by a + * suitable replacement character. Except when (and only + * when) ring buffer lost characters since last read, initial + * continuation characters should be dropped. + */ + read_data[size] = 0; + data = (char *)read_data; + } + + return data; +} + +QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) +{ + char host[65], port[33], width[8], height[8]; + int pos; + const char *p; + QemuOpts *opts; + Error *local_err = NULL; + + opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err); + if (local_err) { + error_report_err(local_err); + return NULL; + } + + if (strstart(filename, "mon:", &p)) { + filename = p; + qemu_opt_set(opts, "mux", "on", &error_abort); + if (strcmp(filename, "stdio") == 0) { + /* Monitor is muxed to stdio: do not exit on Ctrl+C by default + * but pass it to the guest. Handle this only for compat syntax, + * for -chardev syntax we have special option for this. + * This is what -nographic did, redirecting+muxing serial+monitor + * to stdio causing Ctrl+C to be passed to guest. */ + qemu_opt_set(opts, "signal", "off", &error_abort); + } + } + + if (strcmp(filename, "null") == 0 || + strcmp(filename, "pty") == 0 || + strcmp(filename, "msmouse") == 0 || + strcmp(filename, "braille") == 0 || + strcmp(filename, "testdev") == 0 || + strcmp(filename, "stdio") == 0) { + qemu_opt_set(opts, "backend", filename, &error_abort); + return opts; + } + if (strstart(filename, "vc", &p)) { + qemu_opt_set(opts, "backend", "vc", &error_abort); + if (*p == ':') { + if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) { + /* pixels */ + qemu_opt_set(opts, "width", width, &error_abort); + qemu_opt_set(opts, "height", height, &error_abort); + } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) { + /* chars */ + qemu_opt_set(opts, "cols", width, &error_abort); + qemu_opt_set(opts, "rows", height, &error_abort); + } else { + goto fail; + } + } + return opts; + } + if (strcmp(filename, "con:") == 0) { + qemu_opt_set(opts, "backend", "console", &error_abort); + return opts; + } + if (strstart(filename, "COM", NULL)) { + qemu_opt_set(opts, "backend", "serial", &error_abort); + qemu_opt_set(opts, "path", filename, &error_abort); + return opts; + } + if (strstart(filename, "file:", &p)) { + qemu_opt_set(opts, "backend", "file", &error_abort); + qemu_opt_set(opts, "path", p, &error_abort); + return opts; + } + if (strstart(filename, "pipe:", &p)) { + qemu_opt_set(opts, "backend", "pipe", &error_abort); + qemu_opt_set(opts, "path", p, &error_abort); + return opts; + } + if (strstart(filename, "tcp:", &p) || + strstart(filename, "telnet:", &p)) { + if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) { + host[0] = 0; + if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) + goto fail; + } + qemu_opt_set(opts, "backend", "socket", &error_abort); + qemu_opt_set(opts, "host", host, &error_abort); + qemu_opt_set(opts, "port", port, &error_abort); + if (p[pos] == ',') { + qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err); + if (local_err) { + error_report_err(local_err); + goto fail; + } + } + if (strstart(filename, "telnet:", &p)) + qemu_opt_set(opts, "telnet", "on", &error_abort); + return opts; + } + if (strstart(filename, "udp:", &p)) { + qemu_opt_set(opts, "backend", "udp", &error_abort); + if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) { + host[0] = 0; + if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) { + goto fail; + } + } + qemu_opt_set(opts, "host", host, &error_abort); + qemu_opt_set(opts, "port", port, &error_abort); + if (p[pos] == '@') { + p += pos + 1; + if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) { + host[0] = 0; + if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) { + goto fail; + } + } + qemu_opt_set(opts, "localaddr", host, &error_abort); + qemu_opt_set(opts, "localport", port, &error_abort); + } + return opts; + } + if (strstart(filename, "unix:", &p)) { + qemu_opt_set(opts, "backend", "socket", &error_abort); + qemu_opts_do_parse(opts, p, "path", &local_err); + if (local_err) { + error_report_err(local_err); + goto fail; + } + return opts; + } + if (strstart(filename, "/dev/parport", NULL) || + strstart(filename, "/dev/ppi", NULL)) { + qemu_opt_set(opts, "backend", "parport", &error_abort); + qemu_opt_set(opts, "path", filename, &error_abort); + return opts; + } + if (strstart(filename, "/dev/", NULL)) { + qemu_opt_set(opts, "backend", "tty", &error_abort); + qemu_opt_set(opts, "path", filename, &error_abort); + return opts; + } + +fail: + qemu_opts_del(opts); + return NULL; +} + +static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *path = qemu_opt_get(opts, "path"); + + if (path == NULL) { + error_setg(errp, "chardev: file: no filename given"); + return; + } + backend->u.file = g_new0(ChardevFile, 1); + backend->u.file->out = g_strdup(path); +} + +static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + backend->u.stdio = g_new0(ChardevStdio, 1); + backend->u.stdio->has_signal = true; + backend->u.stdio->signal = qemu_opt_get_bool(opts, "signal", true); +} + +#ifdef HAVE_CHARDEV_SERIAL +static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *device = qemu_opt_get(opts, "path"); + + if (device == NULL) { + error_setg(errp, "chardev: serial/tty: no device path given"); + return; + } + backend->u.serial = g_new0(ChardevHostdev, 1); + backend->u.serial->device = g_strdup(device); +} +#endif + +#ifdef HAVE_CHARDEV_PARPORT +static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *device = qemu_opt_get(opts, "path"); + + if (device == NULL) { + error_setg(errp, "chardev: parallel: no device path given"); + return; + } + backend->u.parallel = g_new0(ChardevHostdev, 1); + backend->u.parallel->device = g_strdup(device); +} +#endif + +static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *device = qemu_opt_get(opts, "path"); + + if (device == NULL) { + error_setg(errp, "chardev: pipe: no device path given"); + return; + } + backend->u.pipe = g_new0(ChardevHostdev, 1); + backend->u.pipe->device = g_strdup(device); +} + +static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + int val; + + backend->u.ringbuf = g_new0(ChardevRingbuf, 1); + + val = qemu_opt_get_size(opts, "size", 0); + if (val != 0) { + backend->u.ringbuf->has_size = true; + backend->u.ringbuf->size = val; + } +} + +static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *chardev = qemu_opt_get(opts, "chardev"); + + if (chardev == NULL) { + error_setg(errp, "chardev: mux: no chardev given"); + return; + } + backend->u.mux = g_new0(ChardevMux, 1); + backend->u.mux->chardev = g_strdup(chardev); +} + +static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + bool is_listen = qemu_opt_get_bool(opts, "server", false); + bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); + bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); + bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); + int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0); + const char *path = qemu_opt_get(opts, "path"); + const char *host = qemu_opt_get(opts, "host"); + const char *port = qemu_opt_get(opts, "port"); + SocketAddress *addr; + + if (!path) { + if (!host) { + error_setg(errp, "chardev: socket: no host given"); + return; + } + if (!port) { + error_setg(errp, "chardev: socket: no port given"); + return; + } + } + + backend->u.socket = g_new0(ChardevSocket, 1); + + backend->u.socket->has_nodelay = true; + backend->u.socket->nodelay = do_nodelay; + backend->u.socket->has_server = true; + backend->u.socket->server = is_listen; + backend->u.socket->has_telnet = true; + backend->u.socket->telnet = is_telnet; + backend->u.socket->has_wait = true; + backend->u.socket->wait = is_waitconnect; + backend->u.socket->has_reconnect = true; + backend->u.socket->reconnect = reconnect; + + addr = g_new0(SocketAddress, 1); + if (path) { + addr->type = SOCKET_ADDRESS_KIND_UNIX; + addr->u.q_unix = g_new0(UnixSocketAddress, 1); + addr->u.q_unix->path = g_strdup(path); + } else { + addr->type = SOCKET_ADDRESS_KIND_INET; + addr->u.inet = g_new0(InetSocketAddress, 1); + addr->u.inet->host = g_strdup(host); + addr->u.inet->port = g_strdup(port); + addr->u.inet->has_to = qemu_opt_get(opts, "to"); + addr->u.inet->to = qemu_opt_get_number(opts, "to", 0); + addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4"); + addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0); + addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6"); + addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0); + } + backend->u.socket->addr = addr; +} + +static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *host = qemu_opt_get(opts, "host"); + const char *port = qemu_opt_get(opts, "port"); + const char *localaddr = qemu_opt_get(opts, "localaddr"); + const char *localport = qemu_opt_get(opts, "localport"); + bool has_local = false; + SocketAddress *addr; + + if (host == NULL || strlen(host) == 0) { + host = "localhost"; + } + if (port == NULL || strlen(port) == 0) { + error_setg(errp, "chardev: udp: remote port not specified"); + return; + } + if (localport == NULL || strlen(localport) == 0) { + localport = "0"; + } else { + has_local = true; + } + if (localaddr == NULL || strlen(localaddr) == 0) { + localaddr = ""; + } else { + has_local = true; + } + + backend->u.udp = g_new0(ChardevUdp, 1); + + addr = g_new0(SocketAddress, 1); + addr->type = SOCKET_ADDRESS_KIND_INET; + addr->u.inet = g_new0(InetSocketAddress, 1); + addr->u.inet->host = g_strdup(host); + addr->u.inet->port = g_strdup(port); + addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4"); + addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0); + addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6"); + addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0); + backend->u.udp->remote = addr; + + if (has_local) { + backend->u.udp->has_local = true; + addr = g_new0(SocketAddress, 1); + addr->type = SOCKET_ADDRESS_KIND_INET; + addr->u.inet = g_new0(InetSocketAddress, 1); + addr->u.inet->host = g_strdup(localaddr); + addr->u.inet->port = g_strdup(localport); + backend->u.udp->local = addr; + } +} + +typedef struct CharDriver { + const char *name; + ChardevBackendKind kind; + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp); +} CharDriver; + +static GSList *backends; + +void register_char_driver(const char *name, ChardevBackendKind kind, + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp), + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp)) +{ + CharDriver *s; + + s = g_malloc0(sizeof(*s)); + s->name = g_strdup(name); + s->kind = kind; + s->parse = parse; + s->create = create; + + backends = g_slist_append(backends, s); +} + +CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, + void (*init)(struct CharDriverState *s), + Error **errp) +{ + Error *local_err = NULL; + CharDriver *cd; + CharDriverState *chr; + GSList *i; + ChardevReturn *ret = NULL; + ChardevBackend *backend; + const char *id = qemu_opts_id(opts); + char *bid = NULL; + + if (id == NULL) { + error_setg(errp, "chardev: no id specified"); + goto err; + } + + if (qemu_opt_get(opts, "backend") == NULL) { + error_setg(errp, "chardev: \"%s\" missing backend", + qemu_opts_id(opts)); + goto err; + } + for (i = backends; i; i = i->next) { + cd = i->data; + + if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) { + break; + } + } + if (i == NULL) { + error_setg(errp, "chardev: backend \"%s\" not found", + qemu_opt_get(opts, "backend")); + goto err; + } + + backend = g_new0(ChardevBackend, 1); + + if (qemu_opt_get_bool(opts, "mux", 0)) { + bid = g_strdup_printf("%s-base", id); + } + + chr = NULL; + backend->type = cd->kind; + if (cd->parse) { + cd->parse(opts, backend, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto qapi_out; + } + } + ret = qmp_chardev_add(bid ? bid : id, backend, errp); + if (!ret) { + goto qapi_out; + } + + if (bid) { + qapi_free_ChardevBackend(backend); + qapi_free_ChardevReturn(ret); + backend = g_new0(ChardevBackend, 1); + backend->u.mux = g_new0(ChardevMux, 1); + backend->type = CHARDEV_BACKEND_KIND_MUX; + backend->u.mux->chardev = g_strdup(bid); + ret = qmp_chardev_add(id, backend, errp); + if (!ret) { + chr = qemu_chr_find(bid); + qemu_chr_delete(chr); + chr = NULL; + goto qapi_out; + } + } + + chr = qemu_chr_find(id); + chr->opts = opts; + +qapi_out: + qapi_free_ChardevBackend(backend); + qapi_free_ChardevReturn(ret); + g_free(bid); + return chr; + +err: + qemu_opts_del(opts); + return NULL; +} + +CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) +{ + const char *p; + CharDriverState *chr; + QemuOpts *opts; + Error *err = NULL; + + if (strstart(filename, "chardev:", &p)) { + return qemu_chr_find(p); + } + + opts = qemu_chr_parse_compat(label, filename); + if (!opts) + return NULL; + + chr = qemu_chr_new_from_opts(opts, init, &err); + if (err) { + error_report_err(err); + } + if (chr && qemu_opt_get_bool(opts, "mux", 0)) { + qemu_chr_fe_claim_no_fail(chr); + monitor_init(chr, MONITOR_USE_READLINE); + } + return chr; +} + +void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo) +{ + if (chr->chr_set_echo) { + chr->chr_set_echo(chr, echo); + } +} + +void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open) +{ + if (chr->fe_open == fe_open) { + return; + } + chr->fe_open = fe_open; + if (chr->chr_set_fe_open) { + chr->chr_set_fe_open(chr, fe_open); + } +} + +void qemu_chr_fe_event(struct CharDriverState *chr, int event) +{ + if (chr->chr_fe_event) { + chr->chr_fe_event(chr, event); + } +} + +int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, + GIOFunc func, void *user_data) +{ + GSource *src; + guint tag; + + if (s->chr_add_watch == NULL) { + return -ENOSYS; + } + + src = s->chr_add_watch(s, cond); + if (!src) { + return -EINVAL; + } + + g_source_set_callback(src, (GSourceFunc)func, user_data, NULL); + tag = g_source_attach(src, NULL); + g_source_unref(src); + + return tag; +} + +int qemu_chr_fe_claim(CharDriverState *s) +{ + if (s->avail_connections < 1) { + return -1; + } + s->avail_connections--; + return 0; +} + +void qemu_chr_fe_claim_no_fail(CharDriverState *s) +{ + if (qemu_chr_fe_claim(s) != 0) { + fprintf(stderr, "%s: error chardev \"%s\" already used\n", + __func__, s->label); + exit(1); + } +} + +void qemu_chr_fe_release(CharDriverState *s) +{ + s->avail_connections++; +} + +void qemu_chr_free(CharDriverState *chr) +{ + if (chr->chr_close) { + chr->chr_close(chr); + } + g_free(chr->filename); + g_free(chr->label); + qemu_opts_del(chr->opts); + g_free(chr); +} + +void qemu_chr_delete(CharDriverState *chr) +{ + QTAILQ_REMOVE(&chardevs, chr, next); + qemu_chr_free(chr); +} + +ChardevInfoList *qmp_query_chardev(Error **errp) +{ + ChardevInfoList *chr_list = NULL; + CharDriverState *chr; + + QTAILQ_FOREACH(chr, &chardevs, next) { + ChardevInfoList *info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->label = g_strdup(chr->label); + info->value->filename = g_strdup(chr->filename); + info->value->frontend_open = chr->fe_open; + + info->next = chr_list; + chr_list = info; + } + + return chr_list; +} + +ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp) +{ + ChardevBackendInfoList *backend_list = NULL; + CharDriver *c = NULL; + GSList *i = NULL; + + for (i = backends; i; i = i->next) { + ChardevBackendInfoList *info = g_malloc0(sizeof(*info)); + c = i->data; + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(c->name); + + info->next = backend_list; + backend_list = info; + } + + return backend_list; +} + +CharDriverState *qemu_chr_find(const char *name) +{ + CharDriverState *chr; + + QTAILQ_FOREACH(chr, &chardevs, next) { + if (strcmp(chr->label, name) != 0) + continue; + return chr; + } + return NULL; +} + +/* Get a character (serial) device interface. */ +CharDriverState *qemu_char_get_next_serial(void) +{ + static int next_serial; + CharDriverState *chr; + + /* FIXME: This function needs to go away: use chardev properties! */ + + while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) { + chr = serial_hds[next_serial++]; + qemu_chr_fe_claim_no_fail(chr); + return chr; + } + return NULL; +} + +QemuOptsList qemu_chardev_opts = { + .name = "chardev", + .implied_opt_name = "backend", + .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head), + .desc = { + { + .name = "backend", + .type = QEMU_OPT_STRING, + },{ + .name = "path", + .type = QEMU_OPT_STRING, + },{ + .name = "host", + .type = QEMU_OPT_STRING, + },{ + .name = "port", + .type = QEMU_OPT_STRING, + },{ + .name = "localaddr", + .type = QEMU_OPT_STRING, + },{ + .name = "localport", + .type = QEMU_OPT_STRING, + },{ + .name = "to", + .type = QEMU_OPT_NUMBER, + },{ + .name = "ipv4", + .type = QEMU_OPT_BOOL, + },{ + .name = "ipv6", + .type = QEMU_OPT_BOOL, + },{ + .name = "wait", + .type = QEMU_OPT_BOOL, + },{ + .name = "server", + .type = QEMU_OPT_BOOL, + },{ + .name = "delay", + .type = QEMU_OPT_BOOL, + },{ + .name = "reconnect", + .type = QEMU_OPT_NUMBER, + },{ + .name = "telnet", + .type = QEMU_OPT_BOOL, + },{ + .name = "width", + .type = QEMU_OPT_NUMBER, + },{ + .name = "height", + .type = QEMU_OPT_NUMBER, + },{ + .name = "cols", + .type = QEMU_OPT_NUMBER, + },{ + .name = "rows", + .type = QEMU_OPT_NUMBER, + },{ + .name = "mux", + .type = QEMU_OPT_BOOL, + },{ + .name = "signal", + .type = QEMU_OPT_BOOL, + },{ + .name = "name", + .type = QEMU_OPT_STRING, + },{ + .name = "debug", + .type = QEMU_OPT_NUMBER, + },{ + .name = "size", + .type = QEMU_OPT_SIZE, + },{ + .name = "chardev", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +#ifdef _WIN32 + +static CharDriverState *qmp_chardev_open_file(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevFile *file = backend->u.file; + HANDLE out; + + if (file->has_in) { + error_setg(errp, "input file not supported"); + return NULL; + } + + out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (out == INVALID_HANDLE_VALUE) { + error_setg(errp, "open %s failed", file->out); + return NULL; + } + return qemu_chr_open_win_file(out); +} + +static CharDriverState *qmp_chardev_open_serial(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevHostdev *serial = backend->u.serial; + return qemu_chr_open_win_path(serial->device, errp); +} + +#else /* WIN32 */ + +static int qmp_chardev_open_file_source(char *src, int flags, + Error **errp) +{ + int fd = -1; + + TFR(fd = qemu_open(src, flags, 0666)); + if (fd == -1) { + error_setg_file_open(errp, errno, src); + } + return fd; +} + +static CharDriverState *qmp_chardev_open_file(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevFile *file = backend->u.file; + int flags, in = -1, out; + + flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY; + out = qmp_chardev_open_file_source(file->out, flags, errp); + if (out < 0) { + return NULL; + } + + if (file->has_in) { + flags = O_RDONLY; + in = qmp_chardev_open_file_source(file->in, flags, errp); + if (in < 0) { + qemu_close(out); + return NULL; + } + } + + return qemu_chr_open_fd(in, out); +} + +#ifdef HAVE_CHARDEV_SERIAL +static CharDriverState *qmp_chardev_open_serial(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevHostdev *serial = backend->u.serial; + int fd; + + fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); + if (fd < 0) { + return NULL; + } + qemu_set_nonblock(fd); + return qemu_chr_open_tty_fd(fd); +} +#endif + +#ifdef HAVE_CHARDEV_PARPORT +static CharDriverState *qmp_chardev_open_parallel(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevHostdev *parallel = backend->u.parallel; + int fd; + + fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); + if (fd < 0) { + return NULL; + } + return qemu_chr_open_pp_fd(fd, errp); +} +#endif + +#endif /* WIN32 */ + +static void socket_try_connect(CharDriverState *chr) +{ + Error *err = NULL; + + if (!qemu_chr_open_socket_fd(chr, &err)) { + check_report_connect_error(chr, err); + } +} + +static gboolean socket_reconnect_timeout(gpointer opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + + s->reconnect_timer = 0; + + if (chr->be_open) { + return false; + } + + socket_try_connect(chr); + + return false; +} + +static CharDriverState *qmp_chardev_open_socket(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + CharDriverState *chr; + TCPCharDriver *s; + ChardevSocket *sock = backend->u.socket; + SocketAddress *addr = sock->addr; + bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; + bool is_listen = sock->has_server ? sock->server : true; + bool is_telnet = sock->has_telnet ? sock->telnet : false; + bool is_waitconnect = sock->has_wait ? sock->wait : false; + int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; + + chr = qemu_chr_alloc(); + s = g_new0(TCPCharDriver, 1); + + s->fd = -1; + s->listen_fd = -1; + s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX; + s->is_listen = is_listen; + s->is_telnet = is_telnet; + s->do_nodelay = do_nodelay; + qapi_copy_SocketAddress(&s->addr, sock->addr); + + chr->opaque = s; + chr->chr_write = tcp_chr_write; + chr->chr_sync_read = tcp_chr_sync_read; + chr->chr_close = tcp_chr_close; + chr->get_msgfds = tcp_get_msgfds; + chr->set_msgfds = tcp_set_msgfds; + chr->chr_add_client = tcp_chr_add_client; + chr->chr_add_watch = tcp_chr_add_watch; + chr->chr_update_read_handler = tcp_chr_update_read_handler; + /* be isn't opened until we get a connection */ + chr->explicit_be_open = true; + + chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE); + SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, "disconnected:", + addr, is_listen, is_telnet); + + if (is_listen) { + if (is_telnet) { + s->do_telnetopt = 1; + } + } else if (reconnect > 0) { + s->reconnect_time = reconnect; + } + + if (s->reconnect_time) { + socket_try_connect(chr); + } else if (!qemu_chr_open_socket_fd(chr, errp)) { + g_free(s); + g_free(chr->filename); + g_free(chr); + return NULL; + } + + if (is_listen && is_waitconnect) { + fprintf(stderr, "QEMU waiting for connection on: %s\n", + chr->filename); + tcp_chr_accept(s->listen_chan, G_IO_IN, chr); + qemu_set_nonblock(s->listen_fd); + } + + return chr; +} + +static CharDriverState *qmp_chardev_open_udp(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) +{ + ChardevUdp *udp = backend->u.udp; + int fd; + + fd = socket_dgram(udp->remote, udp->local, errp); + if (fd < 0) { + return NULL; + } + return qemu_chr_open_udp_fd(fd); +} + +ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, + Error **errp) +{ + ChardevReturn *ret = g_new0(ChardevReturn, 1); + CharDriverState *chr = NULL; + Error *local_err = NULL; + GSList *i; + CharDriver *cd; + + chr = qemu_chr_find(id); + if (chr) { + error_setg(errp, "Chardev '%s' already exists", id); + g_free(ret); + return NULL; + } + + for (i = backends; i; i = i->next) { + cd = i->data; + + if (cd->kind == backend->type) { + chr = cd->create(id, backend, ret, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto out_error; + } + break; + } + } + + if (chr == NULL) { + assert(!i); + error_setg(errp, "chardev backend not available"); + goto out_error; + } + + chr->label = g_strdup(id); + chr->avail_connections = + (backend->type == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; + if (!chr->filename) { + chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]); + } + if (!chr->explicit_be_open) { + qemu_chr_be_event(chr, CHR_EVENT_OPENED); + } + QTAILQ_INSERT_TAIL(&chardevs, chr, next); + return ret; + +out_error: + g_free(ret); + return NULL; +} + +void qmp_chardev_remove(const char *id, Error **errp) +{ + CharDriverState *chr; + + chr = qemu_chr_find(id); + if (chr == NULL) { + error_setg(errp, "Chardev '%s' not found", id); + return; + } + if (chr->chr_can_read || chr->chr_read || + chr->chr_event || chr->handler_opaque) { + error_setg(errp, "Chardev '%s' is busy", id); + return; + } + qemu_chr_delete(chr); +} + +static void register_types(void) +{ + register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, + qemu_chr_open_null); + register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, + qemu_chr_parse_socket, qmp_chardev_open_socket); + register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, + qmp_chardev_open_udp); + register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, + qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); + register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, + qemu_chr_parse_file_out, qmp_chardev_open_file); + register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, + qemu_chr_parse_stdio, qemu_chr_open_stdio); +#if defined HAVE_CHARDEV_SERIAL + register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, + qemu_chr_parse_serial, qmp_chardev_open_serial); + register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, + qemu_chr_parse_serial, qmp_chardev_open_serial); +#endif +#ifdef HAVE_CHARDEV_PARPORT + register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, + qemu_chr_parse_parallel, qmp_chardev_open_parallel); + register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, + qemu_chr_parse_parallel, qmp_chardev_open_parallel); +#endif +#ifdef HAVE_CHARDEV_PTY + register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, + qemu_chr_open_pty); +#endif +#ifdef _WIN32 + register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, + qemu_chr_open_win_con); +#endif + register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, + qemu_chr_parse_pipe, qemu_chr_open_pipe); + register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, + qemu_chr_open_mux); + /* Bug-compatibility: */ + register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, + qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); + /* this must be done after machine init, since we register FEs with muxes + * as part of realize functions like serial_isa_realizefn when -nographic + * is specified + */ + qemu_add_machine_init_done_notifier(&muxes_realize_notify); +} + +type_init(register_types); diff --git a/qtest.c b/qtest.c index 5672b75c354b6..483b5a170bee7 100644 --- a/qtest.c +++ b/qtest.c @@ -36,11 +36,10 @@ bool qtest_allowed; -static DeviceState *irq_intercept_dev; +static DeviceState *irq_intercept_dev = NULL; static FILE *qtest_log_fp; static CharBackend qtest_chr; static GString *inbuf; -static int irq_levels[MAX_IRQ]; static qemu_timeval start_time; static bool qtest_opened; static void (*qtest_server_send)(void*, const char*); @@ -150,23 +149,24 @@ static void *qtest_server_send_opaque; * * IRQ management: * - * > irq_intercept_in QOM-PATH + * > irq_intercept_in QOM-PATH ID-NUM * < OK * - * > irq_intercept_out QOM-PATH + * > irq_intercept_out QOM-PATH ID-NUM * < OK * * Attach to the gpio-in (resp. gpio-out) pins exported by the device at * QOM-PATH. When the pin is triggered, one of the following async messages * will be printed to the qtest stream: * - * IRQ raise NUM - * IRQ lower NUM + * IRQ raise GPIO-ID NUM + * IRQ lower GPIO-ID NUM * * where NUM is an IRQ number. For the PC, interrupts can be intercepted * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with * NUM=0 even though it is remapped to GSI 2). * +<<<<<<< HEAD * Setting interrupt level: * * > set_irq_in QOM-PATH NAME NUM LEVEL @@ -176,6 +176,15 @@ static void *qtest_server_send_opaque; * LEVEL is an signed integer IRQ level. * * Forcibly set the given interrupt pin to the given level. +======= + * A gpio-in IRQ mon an arbitrary device may be changed as follows: + * + * > set_irq_in QOM-PATH raise + * < OK + * + * > set_irq_in QOM-PATH lower + * < OK +>>>>>>> 919b29ba7d... Pebble Qemu * */ @@ -261,6 +270,7 @@ static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr, static void qtest_irq_handler(void *opaque, int n, int level) { +<<<<<<< HEAD qemu_irq old_irq = *(qemu_irq *)opaque; qemu_set_irq(old_irq, level); @@ -271,6 +281,15 @@ static void qtest_irq_handler(void *opaque, int n, int level) qtest_sendf(chr, "IRQ %s %d\n", level ? "raise" : "lower", n); } +======= + IRQInterceptData *intercept_data = opaque; + qemu_irq *old_irqs = intercept_data->old_irqs; + qemu_set_irq(old_irqs[n], level); + CharDriverState *chr = qtest_chr; + qtest_send_prefix(chr); + qtest_sendf(chr, "IRQ %s %d %d\n", + level ? "raise" : "lower", intercept_data->id, n); +>>>>>>> 919b29ba7d... Pebble Qemu } static void qtest_process_command(CharBackend *chr, gchar **words) @@ -299,6 +318,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words) || strcmp(words[0], "irq_intercept_in") == 0) { DeviceState *dev; NamedGPIOList *ngl; + int id; g_assert(words[1]); dev = DEVICE(object_resolve_path(words[1], NULL)); @@ -308,19 +328,35 @@ static void qtest_process_command(CharBackend *chr, gchar **words) return; } - if (irq_intercept_dev) { + g_assert(words[2]); + id = strtoul(words[2], NULL, 0); + + if (irq_intercept_dev == dev) { qtest_send_prefix(chr); - if (irq_intercept_dev != dev) { - qtest_send(chr, "FAIL IRQ intercept already enabled\n"); + qtest_send(chr, "OK\n"); + return; + } + QLIST_FOREACH(ngl, &dev->gpios, node) { + /* We don't support intercept of named GPIOs yet */ + if (ngl->name && (strcmp(ngl->name, "sysbus-irq") != 0)) { + continue; + } + if (words[0][14] == 'o') { + qemu_irq_intercept_out(&ngl->out, qtest_irq_handler, + id, ngl->num_out); } else { - qtest_send(chr, "OK\n"); + qemu_irq_intercept_in(ngl->in, qtest_irq_handler, + id, ngl->num_in); } +<<<<<<< HEAD return; +======= +>>>>>>> 919b29ba7d... Pebble Qemu } - +#if 0 QLIST_FOREACH(ngl, &dev->gpios, node) { /* We don't support intercept of named GPIOs yet */ - if (ngl->name) { + if (ngl->name && (strcmp(ngl->name, "sysbus-irq") != 0)) { continue; } if (words[0][14] == 'o') { @@ -335,9 +371,10 @@ static void qtest_process_command(CharBackend *chr, gchar **words) } } else { qemu_irq_intercept_in(ngl->in, qtest_irq_handler, - ngl->num_in); + id, ngl->num_in); } } +#endif irq_intercept_dev = dev; qtest_send_prefix(chr); qtest_send(chr, "OK\n"); @@ -351,6 +388,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words) g_assert(words[1] && words[2] && words[3] && words[4]); +<<<<<<< HEAD +======= + } else if (strcmp(words[0], "set_irq_in") == 0) { + DeviceState *dev; + qemu_irq irq; + unsigned n, level; + + g_assert(words[1]); +>>>>>>> 919b29ba7d... Pebble Qemu dev = DEVICE(object_resolve_path(words[1], NULL)); if (!dev) { qtest_send_prefix(chr); @@ -358,6 +404,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words) return; } +<<<<<<< HEAD if (strcmp(words[2], "unnamed-gpio-in") == 0) { name = NULL; } else { @@ -373,6 +420,20 @@ static void qtest_process_command(CharBackend *chr, gchar **words) qemu_set_irq(irq, level); qtest_send_prefix(chr); +======= + g_assert(words[2]); + n = strtoul(words[2], NULL, 0); + irq = qdev_get_gpio_in(dev, n); + + g_assert(words[3]); + if (strcmp(words[3], "raise") == 0) { + level = 1; + } else { + level = 0; + } + qemu_set_irq(irq, level); + +>>>>>>> 919b29ba7d... Pebble Qemu qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "outb") == 0 || strcmp(words[0], "outw") == 0 || @@ -729,8 +790,6 @@ static int qtest_can_read(void *opaque) static void qtest_event(void *opaque, QEMUChrEvent event) { - int i; - switch (event) { case CHR_EVENT_OPENED: /* @@ -739,9 +798,6 @@ static void qtest_event(void *opaque, QEMUChrEvent event) * used. Injects an extra reset even when it's not used, and * that can mess up tests, e.g. -boot once. */ - for (i = 0; i < ARRAY_SIZE(irq_levels); i++) { - irq_levels[i] = 0; - } qemu_gettimeofday(&start_time); qtest_opened = true; if (qtest_log_fp) { diff --git a/scripts/png_to_cstruct.py b/scripts/png_to_cstruct.py new file mode 100755 index 0000000000000..362ec9fd0655e --- /dev/null +++ b/scripts/png_to_cstruct.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +""" +Convert a PNG image into a C struct +""" + +import itertools +import math +import png + +_NoFill = object() +def unflatten(iterable, n, fill=_NoFill): + count = 0 + accumulator = [] + for item in iterable: + accumulator.append(item) + count += 1 + if count == n: + yield tuple(accumulator) + accumulator = [] + count = 0 + if accumulator and fill is not _NoFill: + accumulator += [fill] * (n-count) + yield tuple(accumulator) + +def rgb_triplets(row): + """Packs a flattened row of RGB pixel data into (r,g,b) tuples.""" + return unflatten(row, 3) + +def to_rgb222(row): + """Converts pixels from RGB888 to RGB222 format. + + The function takes an iterable of (r,g,b) tuples, each representing + a pixel. Each pixel is downsampled to RGB222 and packed into a + single byte. The format of the byte is 0bRrGgBb00. + """ + def downsample(value): + return (value >> 6) & 0x3 + + for r, g, b in row: + yield downsample(r) << 6 | downsample(g) << 4 | downsample(b) << 2 + +def png_to_bytes(png_reader, converter=to_rgb222): + width, height, image, _ = png_reader.asRGB8() + rows = [rgb_triplets(row) for row in image] + scanlines = [converter(row) for row in rows] + return height, width, scanlines + +def png_to_cstruct(png_reader, dst_name, var_name): + height, width, image = png_to_bytes(png_reader) + + print "// C struct format image converted from '%s' using png_to_cstruct.py" % args.src.name + print "static uint8_t *get_%s_image(int *width, int *height) {\n" % (var_name) + print " *width = %d;" % (width) + print " *height = %d;" % (height) + print " static uint8_t %s[%d] = {\n" % (var_name, width*height) + + for line in image: + print " ", + for i, pixel in enumerate(line): + if (i > 0) and (i % 12) == 0: + print "\n ", + print " 0x%02x," % pixel, + print "\n" + + print " };" + print " return %s;" % (var_name) + print "}" + + +if __name__=='__main__': + import argparse + import os.path + import re + + parser = argparse.ArgumentParser() + parser.add_argument('src', metavar='PNGFILE', type=argparse.FileType('rb'), + help='image file to convert') + args = parser.parse_args() + + # Attempt to strip ".png" suffix. Not terribly smart, but good enough. + dst_name = os.path.splitext(args.src.name)[0] + '.c' + + # Attempt to strip ".png" suffix. Not terribly smart, but good enough. + var_name = re.sub(r'[^a-zA-Z0-9_]', '_', + os.path.splitext(os.path.basename(args.src.name))[0]) + + reader = png.Reader(args.src) + png_to_cstruct(reader, dst_name, var_name) + diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c new file mode 100644 index 0000000000000..41f47f309c63e --- /dev/null +++ b/target-arm/arm-semi.c @@ -0,0 +1,660 @@ +/* + * Arm "Angel" semihosting syscalls + * + * Copyright (c) 2005, 2007 CodeSourcery. + * Written by Paul Brook. + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cpu.h" +#include "exec/semihost.h" +#ifdef CONFIG_USER_ONLY +#include "qemu.h" + +#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) +#else +#include "qemu-common.h" +#include "exec/gdbstub.h" +#include "hw/arm/arm.h" +#endif + +#define TARGET_SYS_OPEN 0x01 +#define TARGET_SYS_CLOSE 0x02 +#define TARGET_SYS_WRITEC 0x03 +#define TARGET_SYS_WRITE0 0x04 +#define TARGET_SYS_WRITE 0x05 +#define TARGET_SYS_READ 0x06 +#define TARGET_SYS_READC 0x07 +#define TARGET_SYS_ISTTY 0x09 +#define TARGET_SYS_SEEK 0x0a +#define TARGET_SYS_FLEN 0x0c +#define TARGET_SYS_TMPNAM 0x0d +#define TARGET_SYS_REMOVE 0x0e +#define TARGET_SYS_RENAME 0x0f +#define TARGET_SYS_CLOCK 0x10 +#define TARGET_SYS_TIME 0x11 +#define TARGET_SYS_SYSTEM 0x12 +#define TARGET_SYS_ERRNO 0x13 +#define TARGET_SYS_GET_CMDLINE 0x15 +#define TARGET_SYS_HEAPINFO 0x16 +#define TARGET_SYS_EXIT 0x18 +#define TARGET_SYS_SYNCCACHE 0x19 + +/* ADP_Stopped_ApplicationExit is used for exit(0), + * anything else is implemented as exit(1) */ +#define ADP_Stopped_ApplicationExit (0x20026) + +/* ADP_Stopped_ApplicationExit is used for exit(0), + * anything else is implemented as exit(1) */ +#define ADP_Stopped_ApplicationExit (0x20026) + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define GDB_O_RDONLY 0x000 +#define GDB_O_WRONLY 0x001 +#define GDB_O_RDWR 0x002 +#define GDB_O_APPEND 0x008 +#define GDB_O_CREAT 0x200 +#define GDB_O_TRUNC 0x400 +#define GDB_O_BINARY 0 + +static int gdb_open_modeflags[12] = { + GDB_O_RDONLY, + GDB_O_RDONLY | GDB_O_BINARY, + GDB_O_RDWR, + GDB_O_RDWR | GDB_O_BINARY, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY +}; + +static int open_modeflags[12] = { + O_RDONLY, + O_RDONLY | O_BINARY, + O_RDWR, + O_RDWR | O_BINARY, + O_WRONLY | O_CREAT | O_TRUNC, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + O_RDWR | O_CREAT | O_TRUNC, + O_RDWR | O_CREAT | O_TRUNC | O_BINARY, + O_WRONLY | O_CREAT | O_APPEND, + O_WRONLY | O_CREAT | O_APPEND | O_BINARY, + O_RDWR | O_CREAT | O_APPEND, + O_RDWR | O_CREAT | O_APPEND | O_BINARY +}; + +#ifdef CONFIG_USER_ONLY +static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) +{ + if (code == (uint32_t)-1) + ts->swi_errno = errno; + return code; +} +#else +static inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code) +{ + return code; +} + +#include "exec/softmmu-semi.h" +#endif + +static target_ulong arm_semi_syscall_len; + +#if !defined(CONFIG_USER_ONLY) +static target_ulong syscall_err; +#endif + +static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; +#ifdef CONFIG_USER_ONLY + TaskState *ts = cs->opaque; +#endif + target_ulong reg0 = is_a64(env) ? env->xregs[0] : env->regs[0]; + + if (ret == (target_ulong)-1) { +#ifdef CONFIG_USER_ONLY + ts->swi_errno = err; +#else + syscall_err = err; +#endif + reg0 = ret; + } else { + /* Fixup syscalls that use nonstardard return conventions. */ + switch (reg0) { + case TARGET_SYS_WRITE: + case TARGET_SYS_READ: + reg0 = arm_semi_syscall_len - ret; + break; + case TARGET_SYS_SEEK: + reg0 = 0; + break; + default: + reg0 = ret; + break; + } + } + if (is_a64(env)) { + env->xregs[0] = reg0; + } else { + env->regs[0] = reg0; + } +} + +static target_ulong arm_flen_buf(ARMCPU *cpu) +{ + /* Return an address in target memory of 64 bytes where the remote + * gdb should write its stat struct. (The format of this structure + * is defined by GDB's remote protocol and is not target-specific.) + * We put this on the guest's stack just below SP. + */ + CPUARMState *env = &cpu->env; + target_ulong sp; + + if (is_a64(env)) { + sp = env->xregs[31]; + } else { + sp = env->regs[13]; + } + + return sp - 64; +} + +static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + /* The size is always stored in big-endian order, extract + the value. We assume the size always fit in 32 bits. */ + uint32_t size; + cpu_memory_rw_debug(cs, arm_flen_buf(cpu) + 32, (uint8_t *)&size, 4, 0); + size = be32_to_cpu(size); + if (is_a64(env)) { + env->xregs[0] = size; + } else { + env->regs[0] = size; + } +#ifdef CONFIG_USER_ONLY + ((TaskState *)cs->opaque)->swi_errno = err; +#else + syscall_err = err; +#endif +} + +static target_ulong arm_gdb_syscall(ARMCPU *cpu, gdb_syscall_complete_cb cb, + const char *fmt, ...) +{ + va_list va; + CPUARMState *env = &cpu->env; + + va_start(va, fmt); + gdb_do_syscallv(cb, fmt, va); + va_end(va); + + /* FIXME: we are implicitly relying on the syscall completing + * before this point, which is not guaranteed. We should + * put in an explicit synchronization between this and + * the callback function. + */ + + return is_a64(env) ? env->xregs[0] : env->regs[0]; +} + +/* Read the input value from the argument block; fail the semihosting + * call if the memory read fails. + */ +#define GET_ARG(n) do { \ + if (is_a64(env)) { \ + if (get_user_u64(arg ## n, args + (n) * 8)) { \ + return -1; \ + } \ + } else { \ + if (get_user_u32(arg ## n, args + (n) * 4)) { \ + return -1; \ + } \ + } \ +} while (0) + +#define SET_ARG(n, val) \ + (is_a64(env) ? \ + put_user_u64(val, args + (n) * 8) : \ + put_user_u32(val, args + (n) * 4)) + +target_ulong do_arm_semihosting(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + target_ulong args; + target_ulong arg0, arg1, arg2, arg3; + char * s; + int nr; + uint32_t ret; + uint32_t len; +#ifdef CONFIG_USER_ONLY + TaskState *ts = cs->opaque; +#else + CPUARMState *ts = env; +#endif + + if (is_a64(env)) { + /* Note that the syscall number is in W0, not X0 */ + nr = env->xregs[0] & 0xffffffffU; + args = env->xregs[1]; + } else { + nr = env->regs[0]; + args = env->regs[1]; + } + + switch (nr) { + case TARGET_SYS_OPEN: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + s = lock_user_string(arg0); + if (!s) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + if (arg1 >= 12) { + unlock_user(s, arg0, 0); + return (uint32_t)-1; + } + if (strcmp(s, ":tt") == 0) { + int result_fileno = arg1 < 4 ? STDIN_FILENO : STDOUT_FILENO; + unlock_user(s, arg0, 0); + return result_fileno; + } + if (use_gdb_syscalls()) { + ret = arm_gdb_syscall(cpu, arm_semi_cb, "open,%s,%x,1a4", arg0, + (int)arg2+1, gdb_open_modeflags[arg1]); + } else { + ret = set_swi_errno(ts, open(s, open_modeflags[arg1], 0644)); + } + unlock_user(s, arg0, 0); + return ret; + case TARGET_SYS_CLOSE: + GET_ARG(0); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "close,%x", arg0); + } else { + return set_swi_errno(ts, close(arg0)); + } + case TARGET_SYS_WRITEC: + { + char c; + + if (get_user_u8(c, args)) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + /* Write to debug console. stderr is near enough. */ + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "write,2,%x,1", args); + } else { + return write(STDERR_FILENO, &c, 1); + } + } + case TARGET_SYS_WRITE0: + if (!(s = lock_user_string(args))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + len = strlen(s); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "write,2,%x,%x", + args, len); + } else { + ret = write(STDERR_FILENO, s, len); + } + unlock_user(s, args, 0); + return ret; + case TARGET_SYS_WRITE: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + len = arg2; + if (use_gdb_syscalls()) { + arm_semi_syscall_len = len; + return arm_gdb_syscall(cpu, arm_semi_cb, "write,%x,%x,%x", + arg0, arg1, len); + } else { + s = lock_user(VERIFY_READ, arg1, len, 1); + if (!s) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + ret = set_swi_errno(ts, write(arg0, s, len)); + unlock_user(s, arg1, 0); + if (ret == (uint32_t)-1) + return -1; + return len - ret; + } + case TARGET_SYS_READ: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + len = arg2; + if (use_gdb_syscalls()) { + arm_semi_syscall_len = len; + return arm_gdb_syscall(cpu, arm_semi_cb, "read,%x,%x,%x", + arg0, arg1, len); + } else { + s = lock_user(VERIFY_WRITE, arg1, len, 0); + if (!s) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + do { + ret = set_swi_errno(ts, read(arg0, s, len)); + } while (ret == -1 && errno == EINTR); + unlock_user(s, arg1, len); + if (ret == (uint32_t)-1) + return -1; + return len - ret; + } + case TARGET_SYS_READC: + /* XXX: Read from debug console. Not implemented. */ + return 0; + case TARGET_SYS_ISTTY: + GET_ARG(0); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "isatty,%x", arg0); + } else { + return isatty(arg0); + } + case TARGET_SYS_SEEK: + GET_ARG(0); + GET_ARG(1); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "lseek,%x,%x,0", + arg0, arg1); + } else { + ret = set_swi_errno(ts, lseek(arg0, arg1, SEEK_SET)); + if (ret == (uint32_t)-1) + return -1; + return 0; + } + case TARGET_SYS_FLEN: + GET_ARG(0); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_flen_cb, "fstat,%x,%x", + arg0, arm_flen_buf(cpu)); + } else { + struct stat buf; + ret = set_swi_errno(ts, fstat(arg0, &buf)); + if (ret == (uint32_t)-1) + return -1; + return buf.st_size; + } + case TARGET_SYS_TMPNAM: + /* XXX: Not implemented. */ + return -1; + case TARGET_SYS_REMOVE: + GET_ARG(0); + GET_ARG(1); + if (use_gdb_syscalls()) { + ret = arm_gdb_syscall(cpu, arm_semi_cb, "unlink,%s", + arg0, (int)arg1+1); + } else { + s = lock_user_string(arg0); + if (!s) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + ret = set_swi_errno(ts, remove(s)); + unlock_user(s, arg0, 0); + } + return ret; + case TARGET_SYS_RENAME: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + GET_ARG(3); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "rename,%s,%s", + arg0, (int)arg1+1, arg2, (int)arg3+1); + } else { + char *s2; + s = lock_user_string(arg0); + s2 = lock_user_string(arg2); + if (!s || !s2) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + ret = (uint32_t)-1; + else + ret = set_swi_errno(ts, rename(s, s2)); + if (s2) + unlock_user(s2, arg2, 0); + if (s) + unlock_user(s, arg0, 0); + return ret; + } + case TARGET_SYS_CLOCK: + return clock() / (CLOCKS_PER_SEC / 100); + case TARGET_SYS_TIME: + return set_swi_errno(ts, time(NULL)); + case TARGET_SYS_SYSTEM: + GET_ARG(0); + GET_ARG(1); + if (use_gdb_syscalls()) { + return arm_gdb_syscall(cpu, arm_semi_cb, "system,%s", + arg0, (int)arg1+1); + } else { + s = lock_user_string(arg0); + if (!s) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + ret = set_swi_errno(ts, system(s)); + unlock_user(s, arg0, 0); + return ret; + } + case TARGET_SYS_ERRNO: +#ifdef CONFIG_USER_ONLY + return ts->swi_errno; +#else + return syscall_err; +#endif + case TARGET_SYS_GET_CMDLINE: + { + /* Build a command-line from the original argv. + * + * The inputs are: + * * arg0, pointer to a buffer of at least the size + * specified in arg1. + * * arg1, size of the buffer pointed to by arg0 in + * bytes. + * + * The outputs are: + * * arg0, pointer to null-terminated string of the + * command line. + * * arg1, length of the string pointed to by arg0. + */ + + char *output_buffer; + size_t input_size; + size_t output_size; + int status = 0; +#if !defined(CONFIG_USER_ONLY) + const char *cmdline; +#endif + GET_ARG(0); + GET_ARG(1); + input_size = arg1; + /* Compute the size of the output string. */ +#if !defined(CONFIG_USER_ONLY) + cmdline = semihosting_get_cmdline(); + if (cmdline == NULL) { + cmdline = ""; /* Default to an empty line. */ + } + output_size = strlen(cmdline) + 1; /* Count terminating 0. */ +#else + unsigned int i; + + output_size = ts->info->arg_end - ts->info->arg_start; + if (!output_size) { + /* We special-case the "empty command line" case (argc==0). + Just provide the terminating 0. */ + output_size = 1; + } +#endif + + if (output_size > input_size) { + /* Not enough space to store command-line arguments. */ + return -1; + } + + /* Adjust the command-line length. */ + if (SET_ARG(1, output_size - 1)) { + /* Couldn't write back to argument block */ + return -1; + } + + /* Lock the buffer on the ARM side. */ + output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0); + if (!output_buffer) { + return -1; + } + + /* Copy the command-line arguments. */ +#if !defined(CONFIG_USER_ONLY) + pstrcpy(output_buffer, output_size, cmdline); +#else + if (output_size == 1) { + /* Empty command-line. */ + output_buffer[0] = '\0'; + goto out; + } + + if (copy_from_user(output_buffer, ts->info->arg_start, + output_size)) { + status = -1; + goto out; + } + + /* Separate arguments by white spaces. */ + for (i = 0; i < output_size - 1; i++) { + if (output_buffer[i] == 0) { + output_buffer[i] = ' '; + } + } + out: +#endif + /* Unlock the buffer on the ARM side. */ + unlock_user(output_buffer, arg0, output_size); + + return status; + } + case TARGET_SYS_HEAPINFO: + { + uint32_t *ptr; + uint32_t limit; + GET_ARG(0); + +#ifdef CONFIG_USER_ONLY + /* Some C libraries assume the heap immediately follows .bss, so + allocate it using sbrk. */ + if (!ts->heap_limit) { + abi_ulong ret; + + ts->heap_base = do_brk(0); + limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; + /* Try a big heap, and reduce the size if that fails. */ + for (;;) { + ret = do_brk(limit); + if (ret >= limit) { + break; + } + limit = (ts->heap_base >> 1) + (limit >> 1); + } + ts->heap_limit = limit; + } + + ptr = lock_user(VERIFY_WRITE, arg0, 16, 0); + if (!ptr) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + ptr[0] = tswap32(ts->heap_base); + ptr[1] = tswap32(ts->heap_limit); + ptr[2] = tswap32(ts->stack_base); + ptr[3] = tswap32(0); /* Stack limit. */ + unlock_user(ptr, arg0, 16); +#else + limit = ram_size; + ptr = lock_user(VERIFY_WRITE, arg0, 16, 0); + if (!ptr) { + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + } + /* TODO: Make this use the limit of the loaded application. */ + ptr[0] = tswap32(limit / 2); + ptr[1] = tswap32(limit); + ptr[2] = tswap32(limit); /* Stack base */ + ptr[3] = tswap32(0); /* Stack limit. */ + unlock_user(ptr, arg0, 16); +#endif + return 0; + } + case TARGET_SYS_EXIT: + if (is_a64(env)) { + /* The A64 version of this call takes a parameter block, + * so the application-exit type can return a subcode which + * is the exit status code from the application. + */ + GET_ARG(0); + GET_ARG(1); + + if (arg0 == ADP_Stopped_ApplicationExit) { + ret = arg1; + } else { + ret = 1; + } + } else { + /* ARM specifies only Stopped_ApplicationExit as normal + * exit, everything else is considered an error */ + ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1; + } + gdb_exit(env, ret); + exit(ret); + case TARGET_SYS_SYNCCACHE: + /* Clean the D-cache and invalidate the I-cache for the specified + * virtual address range. This is a nop for us since we don't + * implement caches. This is only present on A64. + */ + if (is_a64(env)) { + return 0; + } + /* fall through -- invalid for A32/T32 */ + default: + fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr); + cpu_dump_state(cs, stderr, fprintf, 0); + abort(); + } +} diff --git a/target-arm/cpu.c b/target-arm/cpu.c new file mode 100644 index 0000000000000..35932c656d422 --- /dev/null +++ b/target-arm/cpu.c @@ -0,0 +1,1509 @@ +/* + * QEMU ARM CPU + * + * Copyright (c) 2012 SUSE LINUX Products GmbH + * + * 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 + * + */ + +#include "cpu.h" +#include "internals.h" +#include "qemu-common.h" +#include "hw/qdev-properties.h" +#if !defined(CONFIG_USER_ONLY) +#include "hw/loader.h" +#endif +#include "hw/arm/arm.h" +#include "sysemu/sysemu.h" +#include "sysemu/kvm.h" +#include "kvm_arm.h" + +static void arm_cpu_set_pc(CPUState *cs, vaddr value) +{ + ARMCPU *cpu = ARM_CPU(cs); + + cpu->env.regs[15] = value; +} + +static bool arm_cpu_has_work(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + + return !cpu->powered_off + && cs->interrupt_request & + (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD + | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ + | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_WKUP); +} + +static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) +{ + /* Reset a single ARMCPRegInfo register */ + ARMCPRegInfo *ri = value; + ARMCPU *cpu = opaque; + + if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) { + return; + } + + if (ri->resetfn) { + ri->resetfn(&cpu->env, ri); + return; + } + + /* A zero offset is never possible as it would be regs[0] + * so we use it to indicate that reset is being handled elsewhere. + * This is basically only used for fields in non-core coprocessors + * (like the pxa2xx ones). + */ + if (!ri->fieldoffset) { + return; + } + + if (cpreg_field_is_64bit(ri)) { + CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue; + } else { + CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue; + } +} + +static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque) +{ + /* Purely an assertion check: we've already done reset once, + * so now check that running the reset for the cpreg doesn't + * change its value. This traps bugs where two different cpregs + * both try to reset the same state field but to different values. + */ + ARMCPRegInfo *ri = value; + ARMCPU *cpu = opaque; + uint64_t oldvalue, newvalue; + + if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) { + return; + } + + oldvalue = read_raw_cp_reg(&cpu->env, ri); + cp_reg_reset(key, value, opaque); + newvalue = read_raw_cp_reg(&cpu->env, ri); + assert(oldvalue == newvalue); +} + +/* CPUClass::reset() */ +static void arm_cpu_reset(CPUState *s) +{ + ARMCPU *cpu = ARM_CPU(s); + ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); + CPUARMState *env = &cpu->env; + + acc->parent_reset(s); + + memset(env, 0, offsetof(CPUARMState, features)); + g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); + g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu); + + env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; + env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; + env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; + env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2; + + cpu->powered_off = cpu->start_powered_off; + s->halted = cpu->start_powered_off; + + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; + } + + if (arm_feature(env, ARM_FEATURE_AARCH64)) { + /* 64 bit CPUs always start in 64 bit mode */ + env->aarch64 = 1; +#if defined(CONFIG_USER_ONLY) + env->pstate = PSTATE_MODE_EL0t; + /* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */ + env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE; + /* and to the FP/Neon instructions */ + env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3); +#else + /* Reset into the highest available EL */ + if (arm_feature(env, ARM_FEATURE_EL3)) { + env->pstate = PSTATE_MODE_EL3h; + } else if (arm_feature(env, ARM_FEATURE_EL2)) { + env->pstate = PSTATE_MODE_EL2h; + } else { + env->pstate = PSTATE_MODE_EL1h; + } + env->pc = cpu->rvbar; +#endif + } else { +#if defined(CONFIG_USER_ONLY) + /* Userspace expects access to cp10 and cp11 for FP/Neon */ + env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 4, 0xf); +#endif + } + +#if defined(CONFIG_USER_ONLY) + env->uncached_cpsr = ARM_CPU_MODE_USR; + /* For user mode we must enable access to coprocessors */ + env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->cp15.c15_cpar = 3; + } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { + env->cp15.c15_cpar = 1; + } +#else + /* SVC mode with interrupts disabled. */ + env->uncached_cpsr = ARM_CPU_MODE_SVC; + env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; + /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is + * clear at reset. Initial SP and PC are loaded from ROM. + */ + if (IS_M(env)) { + uint32_t initial_msp; /* Loaded from 0x0 */ + uint32_t initial_pc; /* Loaded from 0x4 */ + uint8_t *rom; + + env->daif &= ~PSTATE_I; + rom = rom_ptr(0); + if (rom) { + /* Address zero is covered by ROM which hasn't yet been + * copied into physical memory. + */ + initial_msp = ldl_p(rom); + initial_pc = ldl_p(rom + 4); + } else { + /* Address zero not covered by a ROM blob, or the ROM blob + * is in non-modifiable memory and this is a second reset after + * it got copied into memory. In the latter case, rom_ptr + * will return a NULL pointer and we should use ldl_phys instead. + */ + initial_msp = ldl_phys(s->as, 0); + initial_pc = ldl_phys(s->as, 4); + } + + env->regs[13] = initial_msp & 0xFFFFFFFC; + env->regs[15] = initial_pc & ~1; + env->thumb = initial_pc & 1; + } + + /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently + * executing as AArch32 then check if highvecs are enabled and + * adjust the PC accordingly. + */ + if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) { + env->regs[15] = 0xFFFF0000; + } + + env->vfp.xregs[ARM_VFP_FPEXC] = 0; +#endif + set_flush_to_zero(1, &env->vfp.standard_fp_status); + set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); + set_default_nan_mode(1, &env->vfp.standard_fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.standard_fp_status); + tlb_flush(s, 1); + /* Reset is a state change for some CPUARMState fields which we + * bake assumptions about into translated code, so we need to + * tb_flush(). + */ + tb_flush(&(cpu->parent_obj)); + +#ifndef CONFIG_USER_ONLY + if (kvm_enabled()) { + kvm_arm_reset_vcpu(cpu); + } +#endif + + hw_breakpoint_update_all(cpu); + hw_watchpoint_update_all(cpu); +} + +bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + CPUClass *cc = CPU_GET_CLASS(cs); + CPUARMState *env = cs->env_ptr; + uint32_t cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + uint32_t target_el; + uint32_t excp_idx; + bool ret = false; + + if (interrupt_request & CPU_INTERRUPT_FIQ) { + excp_idx = EXCP_FIQ; + target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); + if (arm_excp_unmasked(cs, excp_idx, target_el)) { + cs->exception_index = excp_idx; + env->exception.target_el = target_el; + cc->do_interrupt(cs); + ret = true; + } + } + if (interrupt_request & CPU_INTERRUPT_HARD) { + excp_idx = EXCP_IRQ; + target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); + if (arm_excp_unmasked(cs, excp_idx, target_el)) { + cs->exception_index = excp_idx; + env->exception.target_el = target_el; + cc->do_interrupt(cs); + ret = true; + } + } + if (interrupt_request & CPU_INTERRUPT_VIRQ) { + excp_idx = EXCP_VIRQ; + target_el = 1; + if (arm_excp_unmasked(cs, excp_idx, target_el)) { + cs->exception_index = excp_idx; + env->exception.target_el = target_el; + cc->do_interrupt(cs); + ret = true; + } + } + if (interrupt_request & CPU_INTERRUPT_VFIQ) { + excp_idx = EXCP_VFIQ; + target_el = 1; + if (arm_excp_unmasked(cs, excp_idx, target_el)) { + cs->exception_index = excp_idx; + env->exception.target_el = target_el; + cc->do_interrupt(cs); + ret = true; + } + } + if (interrupt_request & CPU_INTERRUPT_WKUP) { + excp_idx = EXCP_WKUP; + target_el = 1; + if (arm_excp_unmasked(cs, excp_idx, target_el)) { + cs->exception_index = excp_idx; + env->exception.target_el = target_el; + cc->do_interrupt(cs); + ret = true; + } + } + return ret; +} + +#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) +static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + CPUClass *cc = CPU_GET_CLASS(cs); + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + bool ret = false; + + + if (interrupt_request & CPU_INTERRUPT_FIQ + && !(env->daif & PSTATE_F)) { + cs->exception_index = EXCP_FIQ; + cc->do_interrupt(cs); + ret = true; + } + /* ARMv7-M interrupt return works by loading a magic value + * into the PC. On real hardware the load causes the + * return to occur. The qemu implementation performs the + * jump normally, then does the exception return when the + * CPU tries to execute code at the magic address. + * This will cause the magic PC value to be pushed to + * the stack if an interrupt occurred at the wrong time. + * We avoid this by disabling interrupts when + * pc contains a magic address. + */ + if (interrupt_request & CPU_INTERRUPT_HARD + && !(env->daif & PSTATE_I) + && (env->regs[15] < 0xfffffff0)) { + cs->exception_index = EXCP_IRQ; + cc->do_interrupt(cs); + ret = true; + } + + /* This gets sent if the WKUP pin got asserted while we were in + * standby. Simply wake up without taking an interrupt */ + if (interrupt_request & CPU_INTERRUPT_WKUP) { + cs->interrupt_request &= ~CPU_INTERRUPT_WKUP; + cs->exception_index = EXCP_WKUP; + cc->do_interrupt(cs); + } + + return ret; +} +#endif + +#ifndef CONFIG_USER_ONLY +static void arm_cpu_set_irq(void *opaque, int irq, int level) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + CPUState *cs = CPU(cpu); + static const int mask[] = { + [ARM_CPU_IRQ] = CPU_INTERRUPT_HARD, + [ARM_CPU_FIQ] = CPU_INTERRUPT_FIQ, + [ARM_CPU_VIRQ] = CPU_INTERRUPT_VIRQ, + [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ, + [ARM_CPU_WKUP] = CPU_INTERRUPT_WKUP + }; + + switch (irq) { + case ARM_CPU_VIRQ: + case ARM_CPU_VFIQ: + assert(arm_feature(env, ARM_FEATURE_EL2)); + /* fall through */ + case ARM_CPU_IRQ: + case ARM_CPU_FIQ: + case ARM_CPU_WKUP: + if (level) { + cpu_interrupt(cs, mask[irq]); + } else { + cpu_reset_interrupt(cs, mask[irq]); + } + break; + default: + g_assert_not_reached(); + } +} + +static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level) +{ +#ifdef CONFIG_KVM + ARMCPU *cpu = opaque; + CPUState *cs = CPU(cpu); + int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT; + + switch (irq) { + case ARM_CPU_IRQ: + kvm_irq |= KVM_ARM_IRQ_CPU_IRQ; + break; + case ARM_CPU_FIQ: + kvm_irq |= KVM_ARM_IRQ_CPU_FIQ; + break; + default: + g_assert_not_reached(); + } + kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT; + kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0); +#endif +} + +static bool arm_cpu_is_big_endian(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + int cur_el; + + cpu_synchronize_state(cs); + + /* In 32bit guest endianness is determined by looking at CPSR's E bit */ + if (!is_a64(env)) { + return (env->uncached_cpsr & CPSR_E) ? 1 : 0; + } + + cur_el = arm_current_el(env); + + if (cur_el == 0) { + return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0; + } + + return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0; +} + +#endif + +static inline void set_feature(CPUARMState *env, int feature) +{ + env->features |= 1ULL << feature; +} + +static inline void unset_feature(CPUARMState *env, int feature) +{ + env->features &= ~(1ULL << feature); +} + +static int +print_insn_thumb1(bfd_vma pc, disassemble_info *info) +{ + return print_insn_arm(pc | 1, info); +} + +static void arm_disas_set_info(CPUState *cpu, disassemble_info *info) +{ + ARMCPU *ac = ARM_CPU(cpu); + CPUARMState *env = &ac->env; + + if (is_a64(env)) { + /* We might not be compiled with the A64 disassembler + * because it needs a C++ compiler. Leave print_insn + * unset in this case to use the caller default behaviour. + */ +#if defined(CONFIG_ARM_A64_DIS) + info->print_insn = print_insn_arm_a64; +#endif + } else if (env->thumb) { + info->print_insn = print_insn_thumb1; + } else { + info->print_insn = print_insn_arm; + } + if (env->bswap_code) { +#ifdef TARGET_WORDS_BIGENDIAN + info->endian = BFD_ENDIAN_LITTLE; +#else + info->endian = BFD_ENDIAN_BIG; +#endif + } +} + +#define ARM_CPUS_PER_CLUSTER 8 + +static void arm_cpu_initfn(Object *obj) +{ + CPUState *cs = CPU(obj); + ARMCPU *cpu = ARM_CPU(obj); + static bool inited; + uint32_t Aff1, Aff0; + + cs->env_ptr = &cpu->env; + cpu_exec_init(cs, &error_abort); + cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, + g_free, g_free); + + /* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it. + * We don't support setting cluster ID ([16..23]) (known as Aff2 + * in later ARM ARM versions), or any of the higher affinity level fields, + * so these bits always RAZ. + */ + Aff1 = cs->cpu_index / ARM_CPUS_PER_CLUSTER; + Aff0 = cs->cpu_index % ARM_CPUS_PER_CLUSTER; + cpu->mp_affinity = (Aff1 << ARM_AFF1_SHIFT) | Aff0; + +#ifndef CONFIG_USER_ONLY + /* Our inbound IRQ and FIQ lines */ + if (kvm_enabled()) { + /* VIRQ and VFIQ are unused with KVM but we add them to maintain + * the same interface as non-KVM CPUs. + */ + qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 5); + } else { + qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 5); + } + + cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, + arm_gt_ptimer_cb, cpu); + cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, + arm_gt_vtimer_cb, cpu); + cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, + arm_gt_htimer_cb, cpu); + cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, + arm_gt_stimer_cb, cpu); + qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs, + ARRAY_SIZE(cpu->gt_timer_outputs)); +#endif + + /* DTB consumers generally don't in fact care what the 'compatible' + * string is, so always provide some string and trust that a hypothetical + * picky DTB consumer will also provide a helpful error message. + */ + cpu->dtb_compatible = "qemu,unknown"; + cpu->psci_version = 1; /* By default assume PSCI v0.1 */ + cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; + + if (tcg_enabled()) { + cpu->psci_version = 2; /* TCG implements PSCI 0.2 */ + if (!inited) { + inited = true; + arm_translate_init(); + } + } +} + +static Property arm_cpu_reset_cbar_property = + DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0); + +static Property arm_cpu_reset_hivecs_property = + DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false); + +static Property arm_cpu_rvbar_property = + DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0); + +static Property arm_cpu_has_el3_property = + DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true); + +static Property arm_cpu_has_mpu_property = + DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); + +static Property arm_cpu_pmsav7_dregion_property = + DEFINE_PROP_UINT32("pmsav7-dregion", ARMCPU, pmsav7_dregion, 16); + +static void arm_cpu_post_init(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) || + arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property, + &error_abort); + } + + if (!arm_feature(&cpu->env, ARM_FEATURE_M)) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property, + &error_abort); + } + + if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property, + &error_abort); + } + + if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { + /* Add the has_el3 state CPU property only if EL3 is allowed. This will + * prevent "has_el3" from existing on CPUs which cannot support EL3. + */ + qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el3_property, + &error_abort); + } + + if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, + &error_abort); + if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { + qdev_property_add_static(DEVICE(obj), + &arm_cpu_pmsav7_dregion_property, + &error_abort); + } + } + +} + +static void arm_cpu_finalizefn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + g_hash_table_destroy(cpu->cp_regs); +} + +static void arm_cpu_realizefn(DeviceState *dev, Error **errp) +{ + CPUState *cs = CPU(dev); + ARMCPU *cpu = ARM_CPU(dev); + ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev); + CPUARMState *env = &cpu->env; + + /* Some features automatically imply others: */ + if (arm_feature(env, ARM_FEATURE_V8)) { + set_feature(env, ARM_FEATURE_V7); + set_feature(env, ARM_FEATURE_ARM_DIV); + set_feature(env, ARM_FEATURE_LPAE); + } + if (arm_feature(env, ARM_FEATURE_V7)) { + set_feature(env, ARM_FEATURE_VAPA); + set_feature(env, ARM_FEATURE_THUMB2); + set_feature(env, ARM_FEATURE_MPIDR); + if (!arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_V6K); + } else { + set_feature(env, ARM_FEATURE_V6); + } + } + if (arm_feature(env, ARM_FEATURE_V6K)) { + set_feature(env, ARM_FEATURE_V6); + set_feature(env, ARM_FEATURE_MVFR); + } + if (arm_feature(env, ARM_FEATURE_V6)) { + set_feature(env, ARM_FEATURE_V5); + if (!arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_AUXCR); + } + } + if (arm_feature(env, ARM_FEATURE_V5)) { + set_feature(env, ARM_FEATURE_V4T); + } + if (arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_THUMB_DIV); + } + if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { + set_feature(env, ARM_FEATURE_THUMB_DIV); + } + if (arm_feature(env, ARM_FEATURE_VFP4)) { + set_feature(env, ARM_FEATURE_VFP3); + set_feature(env, ARM_FEATURE_VFP_FP16); + } + if (arm_feature(env, ARM_FEATURE_VFP3)) { + set_feature(env, ARM_FEATURE_VFP); + } + if (arm_feature(env, ARM_FEATURE_LPAE)) { + set_feature(env, ARM_FEATURE_V7MP); + set_feature(env, ARM_FEATURE_PXN); + } + if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { + set_feature(env, ARM_FEATURE_CBAR); + } + if (arm_feature(env, ARM_FEATURE_THUMB2) && + !arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_THUMB_DSP); + } + + if (cpu->reset_hivecs) { + cpu->reset_sctlr |= (1 << 13); + } + + if (!cpu->has_el3) { + /* If the has_el3 CPU property is disabled then we need to disable the + * feature. + */ + unset_feature(env, ARM_FEATURE_EL3); + + /* Disable the security extension feature bits in the processor feature + * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12]. + */ + cpu->id_pfr1 &= ~0xf0; + cpu->id_aa64pfr0 &= ~0xf000; + } + + if (!cpu->has_mpu) { + unset_feature(env, ARM_FEATURE_MPU); + } + + if (arm_feature(env, ARM_FEATURE_MPU) && + arm_feature(env, ARM_FEATURE_V7)) { + uint32_t nr = cpu->pmsav7_dregion; + + if (nr > 0xff) { + error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32 "\n", nr); + return; + } + + if (nr) { + env->pmsav7.drbar = g_new0(uint32_t, nr); + env->pmsav7.drsr = g_new0(uint32_t, nr); + env->pmsav7.dracr = g_new0(uint32_t, nr); + } + } + + register_cp_regs_for_features(cpu); + arm_cpu_register_gdb_regs_for_features(cpu); + + init_cpreg_list(cpu); + + qemu_init_vcpu(cs); + cpu_reset(cs); + + acc->parent_realize(dev, errp); +} + +static ObjectClass *arm_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + char *typename; + char **cpuname; + + if (!cpu_model) { + return NULL; + } + + cpuname = g_strsplit(cpu_model, ",", 1); + typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpuname[0]); + oc = object_class_by_name(typename); + g_strfreev(cpuname); + g_free(typename); + if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) || + object_class_is_abstract(oc)) { + return NULL; + } + return oc; +} + +/* CPU models. These are not needed for the AArch64 linux-user build. */ +#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) + +static void arm926_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,arm926"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); + cpu->midr = 0x41069265; + cpu->reset_fpsid = 0x41011090; + cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00090078; +} + +static void arm946_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,arm946"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_MPU); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + cpu->midr = 0x41059461; + cpu->ctr = 0x0f004006; + cpu->reset_sctlr = 0x00000078; +} + +static void arm1026_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,arm1026"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_AUXCR); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); + cpu->midr = 0x4106a262; + cpu->reset_fpsid = 0x410110a0; + cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00090078; + cpu->reset_auxcr = 1; + { + /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */ + ARMCPRegInfo ifar = { + .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns), + .resetvalue = 0 + }; + define_one_arm_cp_reg(cpu, &ifar); + } +} + +static void arm1136_r2_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an + * older core than plain "arm1136". In particular this does not + * have the v6K features. + * These ID register values are correct for 1136 but may be wrong + * for 1136_r2 (in particular r0p2 does not actually implement most + * of the ID registers). + */ + + cpu->dtb_compatible = "arm,arm1136"; + set_feature(&cpu->env, ARM_FEATURE_V6); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); + set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); + cpu->midr = 0x4107b362; + cpu->reset_fpsid = 0x410120b4; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00050078; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x1; + cpu->id_dfr0 = 0x2; + cpu->id_afr0 = 0x3; + cpu->id_mmfr0 = 0x01130003; + cpu->id_mmfr1 = 0x10030302; + cpu->id_mmfr2 = 0x01222110; + cpu->id_isar0 = 0x00140011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11231111; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x141; + cpu->reset_auxcr = 7; +} + +static void arm1136_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,arm1136"; + set_feature(&cpu->env, ARM_FEATURE_V6K); + set_feature(&cpu->env, ARM_FEATURE_V6); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); + set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); + cpu->midr = 0x4117b363; + cpu->reset_fpsid = 0x410120b4; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00050078; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x1; + cpu->id_dfr0 = 0x2; + cpu->id_afr0 = 0x3; + cpu->id_mmfr0 = 0x01130003; + cpu->id_mmfr1 = 0x10030302; + cpu->id_mmfr2 = 0x01222110; + cpu->id_isar0 = 0x00140011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11231111; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x141; + cpu->reset_auxcr = 7; +} + +static void arm1176_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,arm1176"; + set_feature(&cpu->env, ARM_FEATURE_V6K); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_VAPA); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); + set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); + set_feature(&cpu->env, ARM_FEATURE_EL3); + cpu->midr = 0x410fb767; + cpu->reset_fpsid = 0x410120b5; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00050078; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x11; + cpu->id_dfr0 = 0x33; + cpu->id_afr0 = 0; + cpu->id_mmfr0 = 0x01130003; + cpu->id_mmfr1 = 0x10030302; + cpu->id_mmfr2 = 0x01222100; + cpu->id_isar0 = 0x0140011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11231121; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x01141; + cpu->reset_auxcr = 7; +} + +static void arm11mpcore_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,arm11mpcore"; + set_feature(&cpu->env, ARM_FEATURE_V6K); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_VAPA); + set_feature(&cpu->env, ARM_FEATURE_MPIDR); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + cpu->midr = 0x410fb022; + cpu->reset_fpsid = 0x410120b4; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x1; + cpu->id_dfr0 = 0; + cpu->id_afr0 = 0x2; + cpu->id_mmfr0 = 0x01100103; + cpu->id_mmfr1 = 0x10020302; + cpu->id_mmfr2 = 0x01222000; + cpu->id_isar0 = 0x00100011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11221011; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x141; + cpu->reset_auxcr = 1; +} + +static void cortex_m3_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_M); + set_feature(&cpu->env, ARM_FEATURE_MPU); + cpu->midr = 0x410fc231; +} + +static void cortex_m4_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_M); + set_feature(&cpu->env, ARM_FEATURE_MPU); + set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); + cpu->midr = 0x410fc240; /* r0p0 */ +} +static void arm_v7m_class_init(ObjectClass *oc, void *data) +{ + CPUClass *cc = CPU_CLASS(oc); + +#ifndef CONFIG_USER_ONLY + cc->do_interrupt = arm_v7m_cpu_do_interrupt; +#endif + + cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; +} + +static const ARMCPRegInfo cortexr5_cp_reginfo[] = { + /* Dummy the TCM region regs for the moment */ + { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST }, + { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST }, + REGINFO_SENTINEL +}; + +static void cortex_r5_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV); + set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); + set_feature(&cpu->env, ARM_FEATURE_V7MP); + set_feature(&cpu->env, ARM_FEATURE_MPU); + cpu->midr = 0x411fc153; /* r1p3 */ + cpu->id_pfr0 = 0x0131; + cpu->id_pfr1 = 0x001; + cpu->id_dfr0 = 0x010400; + cpu->id_afr0 = 0x0; + cpu->id_mmfr0 = 0x0210030; + cpu->id_mmfr1 = 0x00000000; + cpu->id_mmfr2 = 0x01200000; + cpu->id_mmfr3 = 0x0211; + cpu->id_isar0 = 0x2101111; + cpu->id_isar1 = 0x13112111; + cpu->id_isar2 = 0x21232141; + cpu->id_isar3 = 0x01112131; + cpu->id_isar4 = 0x0010142; + cpu->id_isar5 = 0x0; + cpu->mp_is_up = true; + define_arm_cp_regs(cpu, cortexr5_cp_reginfo); +} + +static const ARMCPRegInfo cortexa8_cp_reginfo[] = { + { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static void cortex_a8_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,cortex-a8"; + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP3); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_EL3); + cpu->midr = 0x410fc080; + cpu->reset_fpsid = 0x410330c0; + cpu->mvfr0 = 0x11110222; + cpu->mvfr1 = 0x00011100; + cpu->ctr = 0x82048004; + cpu->reset_sctlr = 0x00c50078; + cpu->id_pfr0 = 0x1031; + cpu->id_pfr1 = 0x11; + cpu->id_dfr0 = 0x400; + cpu->id_afr0 = 0; + cpu->id_mmfr0 = 0x31100003; + cpu->id_mmfr1 = 0x20000000; + cpu->id_mmfr2 = 0x01202000; + cpu->id_mmfr3 = 0x11; + cpu->id_isar0 = 0x00101111; + cpu->id_isar1 = 0x12112111; + cpu->id_isar2 = 0x21232031; + cpu->id_isar3 = 0x11112131; + cpu->id_isar4 = 0x00111142; + cpu->dbgdidr = 0x15141000; + cpu->clidr = (1 << 27) | (2 << 24) | 3; + cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ + cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ + cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ + cpu->reset_auxcr = 2; + define_arm_cp_regs(cpu, cortexa8_cp_reginfo); +} + +static const ARMCPRegInfo cortexa9_cp_reginfo[] = { + /* power_control should be set to maximum latency. Again, + * default to 0 and set by private hook + */ + { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) }, + { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) }, + { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) }, + { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, + /* TLB lockdown control */ + { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2, + .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4, + .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, + { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2, + .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, + { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2, + .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, + { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2, + .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, + REGINFO_SENTINEL +}; + +static void cortex_a9_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,cortex-a9"; + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP3); + set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_EL3); + /* Note that A9 supports the MP extensions even for + * A9UP and single-core A9MP (which are both different + * and valid configurations; we don't model A9UP). + */ + set_feature(&cpu->env, ARM_FEATURE_V7MP); + set_feature(&cpu->env, ARM_FEATURE_CBAR); + cpu->midr = 0x410fc090; + cpu->reset_fpsid = 0x41033090; + cpu->mvfr0 = 0x11110222; + cpu->mvfr1 = 0x01111111; + cpu->ctr = 0x80038003; + cpu->reset_sctlr = 0x00c50078; + cpu->id_pfr0 = 0x1031; + cpu->id_pfr1 = 0x11; + cpu->id_dfr0 = 0x000; + cpu->id_afr0 = 0; + cpu->id_mmfr0 = 0x00100103; + cpu->id_mmfr1 = 0x20000000; + cpu->id_mmfr2 = 0x01230000; + cpu->id_mmfr3 = 0x00002111; + cpu->id_isar0 = 0x00101111; + cpu->id_isar1 = 0x13112111; + cpu->id_isar2 = 0x21232041; + cpu->id_isar3 = 0x11112131; + cpu->id_isar4 = 0x00111142; + cpu->dbgdidr = 0x35141000; + cpu->clidr = (1 << 27) | (1 << 24) | 3; + cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ + cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ + define_arm_cp_regs(cpu, cortexa9_cp_reginfo); +} + +#ifndef CONFIG_USER_ONLY +static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Linux wants the number of processors from here. + * Might as well set the interrupt-controller bit too. + */ + return ((smp_cpus - 1) << 24) | (1 << 23); +} +#endif + +static const ARMCPRegInfo cortexa15_cp_reginfo[] = { +#ifndef CONFIG_USER_ONLY + { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, + .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read, + .writefn = arm_cp_write_ignore, }, +#endif + { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static void cortex_a15_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "arm,cortex-a15"; + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP4); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); + set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); + set_feature(&cpu->env, ARM_FEATURE_LPAE); + set_feature(&cpu->env, ARM_FEATURE_EL3); + cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15; + cpu->midr = 0x412fc0f1; + cpu->reset_fpsid = 0x410430f0; + cpu->mvfr0 = 0x10110222; + cpu->mvfr1 = 0x11111111; + cpu->ctr = 0x8444c004; + cpu->reset_sctlr = 0x00c50078; + cpu->id_pfr0 = 0x00001131; + cpu->id_pfr1 = 0x00011011; + cpu->id_dfr0 = 0x02010555; + cpu->id_afr0 = 0x00000000; + cpu->id_mmfr0 = 0x10201105; + cpu->id_mmfr1 = 0x20000000; + cpu->id_mmfr2 = 0x01240000; + cpu->id_mmfr3 = 0x02102211; + cpu->id_isar0 = 0x02101110; + cpu->id_isar1 = 0x13112111; + cpu->id_isar2 = 0x21232041; + cpu->id_isar3 = 0x11112131; + cpu->id_isar4 = 0x10011142; + cpu->dbgdidr = 0x3515f021; + cpu->clidr = 0x0a200023; + cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ + cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ + cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ + define_arm_cp_regs(cpu, cortexa15_cp_reginfo); +} + +static void ti925t_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V4T); + set_feature(&cpu->env, ARM_FEATURE_OMAPCP); + cpu->midr = ARM_CPUID_TI925T; + cpu->ctr = 0x5109149; + cpu->reset_sctlr = 0x00000070; +} + +static void sa1100_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "intel,sa1100"; + set_feature(&cpu->env, ARM_FEATURE_STRONGARM); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + cpu->midr = 0x4401A11B; + cpu->reset_sctlr = 0x00000070; +} + +static void sa1110_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_STRONGARM); + set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + cpu->midr = 0x6901B119; + cpu->reset_sctlr = 0x00000070; +} + +static void pxa250_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + cpu->midr = 0x69052100; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa255_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + cpu->midr = 0x69052d00; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa260_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + cpu->midr = 0x69052903; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa261_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + cpu->midr = 0x69052d05; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa262_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + cpu->midr = 0x69052d06; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa270a0_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); + cpu->midr = 0x69054110; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa270a1_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); + cpu->midr = 0x69054111; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa270b0_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); + cpu->midr = 0x69054112; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa270b1_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); + cpu->midr = 0x69054113; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa270c0_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); + cpu->midr = 0x69054114; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +static void pxa270c5_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu->dtb_compatible = "marvell,xscale"; + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); + cpu->midr = 0x69054117; + cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; +} + +#ifdef CONFIG_USER_ONLY +static void arm_any_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_VFP4); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_V8_AES); + set_feature(&cpu->env, ARM_FEATURE_V8_SHA1); + set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); + set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); + set_feature(&cpu->env, ARM_FEATURE_CRC); + cpu->midr = 0xffffffff; +} +#endif + +#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */ + +typedef struct ARMCPUInfo { + const char *name; + void (*initfn)(Object *obj); + void (*class_init)(ObjectClass *oc, void *data); +} ARMCPUInfo; + +static const ARMCPUInfo arm_cpus[] = { +#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) + { .name = "arm926", .initfn = arm926_initfn }, + { .name = "arm946", .initfn = arm946_initfn }, + { .name = "arm1026", .initfn = arm1026_initfn }, + /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an + * older core than plain "arm1136". In particular this does not + * have the v6K features. + */ + { .name = "arm1136-r2", .initfn = arm1136_r2_initfn }, + { .name = "arm1136", .initfn = arm1136_initfn }, + { .name = "arm1176", .initfn = arm1176_initfn }, + { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, + { .name = "cortex-m3", .initfn = cortex_m3_initfn, + .class_init = arm_v7m_class_init }, + { .name = "cortex-m4", .initfn = cortex_m4_initfn, + .class_init = arm_v7m_class_init }, + { .name = "cortex-r5", .initfn = cortex_r5_initfn }, + { .name = "cortex-a8", .initfn = cortex_a8_initfn }, + { .name = "cortex-a9", .initfn = cortex_a9_initfn }, + { .name = "cortex-a15", .initfn = cortex_a15_initfn }, + { .name = "ti925t", .initfn = ti925t_initfn }, + { .name = "sa1100", .initfn = sa1100_initfn }, + { .name = "sa1110", .initfn = sa1110_initfn }, + { .name = "pxa250", .initfn = pxa250_initfn }, + { .name = "pxa255", .initfn = pxa255_initfn }, + { .name = "pxa260", .initfn = pxa260_initfn }, + { .name = "pxa261", .initfn = pxa261_initfn }, + { .name = "pxa262", .initfn = pxa262_initfn }, + /* "pxa270" is an alias for "pxa270-a0" */ + { .name = "pxa270", .initfn = pxa270a0_initfn }, + { .name = "pxa270-a0", .initfn = pxa270a0_initfn }, + { .name = "pxa270-a1", .initfn = pxa270a1_initfn }, + { .name = "pxa270-b0", .initfn = pxa270b0_initfn }, + { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, + { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, + { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, +#ifdef CONFIG_USER_ONLY + { .name = "any", .initfn = arm_any_initfn }, +#endif +#endif + { .name = NULL } +}; + +static Property arm_cpu_properties[] = { + DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false), + DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0), + DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0), + DEFINE_PROP_END_OF_LIST() +}; + +#ifdef CONFIG_USER_ONLY +static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + env->exception.vaddress = address; + if (rw == 2) { + cs->exception_index = EXCP_PREFETCH_ABORT; + } else { + cs->exception_index = EXCP_DATA_ABORT; + } + return 1; +} +#endif + +static void arm_cpu_class_init(ObjectClass *oc, void *data) +{ + ARMCPUClass *acc = ARM_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(acc); + DeviceClass *dc = DEVICE_CLASS(oc); + + acc->parent_realize = dc->realize; + dc->realize = arm_cpu_realizefn; + dc->props = arm_cpu_properties; + + acc->parent_reset = cc->reset; + cc->reset = arm_cpu_reset; + + cc->class_by_name = arm_cpu_class_by_name; + cc->has_work = arm_cpu_has_work; + cc->cpu_exec_interrupt = arm_cpu_exec_interrupt; + cc->dump_state = arm_cpu_dump_state; + cc->set_pc = arm_cpu_set_pc; + cc->gdb_read_register = arm_cpu_gdb_read_register; + cc->gdb_write_register = arm_cpu_gdb_write_register; +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = arm_cpu_handle_mmu_fault; +#else + cc->do_interrupt = arm_cpu_do_interrupt; + cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_arm_cpu; + cc->virtio_is_big_endian = arm_cpu_is_big_endian; +#endif + cc->gdb_num_core_regs = 26; + cc->gdb_core_xml_file = "arm-core.xml"; + cc->gdb_stop_before_watchpoint = true; + cc->debug_excp_handler = arm_debug_excp_handler; + + cc->disas_set_info = arm_disas_set_info; + + /* + * Reason: arm_cpu_initfn() calls cpu_exec_init(), which saves + * the object in cpus -> dangling pointer after final + * object_unref(). + * + * Once this is fixed, the devices that create ARM CPUs should be + * updated not to set cannot_destroy_with_object_finalize_yet, + * unless they still screw up something else. + */ + dc->cannot_destroy_with_object_finalize_yet = true; +} + +static void cpu_register(const ARMCPUInfo *info) +{ + TypeInfo type_info = { + .parent = TYPE_ARM_CPU, + .instance_size = sizeof(ARMCPU), + .instance_init = info->initfn, + .class_size = sizeof(ARMCPUClass), + .class_init = info->class_init, + }; + + type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name); + type_register(&type_info); + g_free((void *)type_info.name); +} + +static const TypeInfo arm_cpu_type_info = { + .name = TYPE_ARM_CPU, + .parent = TYPE_CPU, + .instance_size = sizeof(ARMCPU), + .instance_init = arm_cpu_initfn, + .instance_post_init = arm_cpu_post_init, + .instance_finalize = arm_cpu_finalizefn, + .abstract = true, + .class_size = sizeof(ARMCPUClass), + .class_init = arm_cpu_class_init, +}; + +static void arm_cpu_register_types(void) +{ + const ARMCPUInfo *info = arm_cpus; + + type_register_static(&arm_cpu_type_info); + + while (info->name) { + cpu_register(info); + info++; + } +} + +type_init(arm_cpu_register_types) diff --git a/target-arm/cpu.h b/target-arm/cpu.h new file mode 100644 index 0000000000000..ff9b81c5328df --- /dev/null +++ b/target-arm/cpu.h @@ -0,0 +1,2060 @@ +/* + * ARM virtual CPU header + * + * Copyright (c) 2003 Fabrice Bellard + * + * 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 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 . + */ +#ifndef CPU_ARM_H +#define CPU_ARM_H + +#include "config.h" + +#include "kvm-consts.h" + +#if defined(TARGET_AARCH64) + /* AArch64 definitions */ +# define TARGET_LONG_BITS 64 +#else +# define TARGET_LONG_BITS 32 +#endif + +#define TARGET_IS_BIENDIAN 1 + +#define CPUArchState struct CPUARMState + +#include "qemu-common.h" +#include "exec/cpu-defs.h" + +#include "fpu/softfloat.h" + +#define EXCP_UDEF 1 /* undefined instruction */ +#define EXCP_SWI 2 /* software interrupt */ +#define EXCP_PREFETCH_ABORT 3 +#define EXCP_DATA_ABORT 4 +#define EXCP_IRQ 5 +#define EXCP_FIQ 6 +#define EXCP_BKPT 7 +#define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */ +#define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */ +#define EXCP_STREX 10 +#define EXCP_HVC 11 /* HyperVisor Call */ +#define EXCP_HYP_TRAP 12 +#define EXCP_SMC 13 /* Secure Monitor Call */ +#define EXCP_VIRQ 14 +#define EXCP_VFIQ 15 +#define EXCP_WKUP 16 /* Wakeup from standby mode */ +#define EXCP_SEMIHOST 17 /* semihosting call (A64 only) */ + +#define ARMV7M_EXCP_RESET 1 +#define ARMV7M_EXCP_NMI 2 +#define ARMV7M_EXCP_HARD 3 +#define ARMV7M_EXCP_MEM 4 +#define ARMV7M_EXCP_BUS 5 +#define ARMV7M_EXCP_USAGE 6 +#define ARMV7M_EXCP_SVC 11 +#define ARMV7M_EXCP_DEBUG 12 +#define ARMV7M_EXCP_PENDSV 14 +#define ARMV7M_EXCP_SYSTICK 15 + +/* ARM-specific interrupt pending bits. */ +#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1 +#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2 +#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3 +#define CPU_INTERRUPT_WKUP CPU_INTERRUPT_TGT_EXT_4 /* Wake up without any interrupt */ + + +/* The usual mapping for an AArch64 system register to its AArch32 + * counterpart is for the 32 bit world to have access to the lower + * half only (with writes leaving the upper half untouched). It's + * therefore useful to be able to pass TCG the offset of the least + * significant half of a uint64_t struct member. + */ +#ifdef HOST_WORDS_BIGENDIAN +#define offsetoflow32(S, M) (offsetof(S, M) + sizeof(uint32_t)) +#define offsetofhigh32(S, M) offsetof(S, M) +#else +#define offsetoflow32(S, M) offsetof(S, M) +#define offsetofhigh32(S, M) (offsetof(S, M) + sizeof(uint32_t)) +#endif + +/* Meanings of the ARMCPU object's five inbound GPIO lines */ +#define ARM_CPU_IRQ 0 +#define ARM_CPU_FIQ 1 +#define ARM_CPU_VIRQ 2 +#define ARM_CPU_VFIQ 3 +#define ARM_CPU_WKUP 4 + +struct arm_boot_info; + +#define NB_MMU_MODES 7 +#define TARGET_INSN_START_EXTRA_WORDS 1 + +/* We currently assume float and double are IEEE single and double + precision respectively. + Doing runtime conversions is tricky because VFP registers may contain + integer values (eg. as the result of a FTOSI instruction). + s<2n> maps to the least significant half of d + s<2n+1> maps to the most significant half of d + */ + +/* CPU state for each instance of a generic timer (in cp15 c14) */ +typedef struct ARMGenericTimer { + uint64_t cval; /* Timer CompareValue register */ + uint64_t ctl; /* Timer Control register */ +} ARMGenericTimer; + +#define GTIMER_PHYS 0 +#define GTIMER_VIRT 1 +#define GTIMER_HYP 2 +#define GTIMER_SEC 3 +#define NUM_GTIMERS 4 + +typedef struct { + uint64_t raw_tcr; + uint32_t mask; + uint32_t base_mask; +} TCR; + +typedef struct CPUARMState { + /* Regs for current mode. */ + uint32_t regs[16]; + + /* 32/64 switch only happens when taking and returning from + * exceptions so the overlap semantics are taken care of then + * instead of having a complicated union. + */ + /* Regs for A64 mode. */ + uint64_t xregs[32]; + uint64_t pc; + /* PSTATE isn't an architectural register for ARMv8. However, it is + * convenient for us to assemble the underlying state into a 32 bit format + * identical to the architectural format used for the SPSR. (This is also + * what the Linux kernel's 'pstate' field in signal handlers and KVM's + * 'pstate' register are.) Of the PSTATE bits: + * NZCV are kept in the split out env->CF/VF/NF/ZF, (which have the same + * semantics as for AArch32, as described in the comments on each field) + * nRW (also known as M[4]) is kept, inverted, in env->aarch64 + * DAIF (exception masks) are kept in env->daif + * all other bits are stored in their correct places in env->pstate + */ + uint32_t pstate; + uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */ + + /* Frequently accessed CPSR bits are stored separately for efficiency. + This contains all the other bits. Use cpsr_{read,write} to access + the whole CPSR. */ + uint32_t uncached_cpsr; + uint32_t spsr; + + /* Banked registers. */ + uint64_t banked_spsr[8]; + uint32_t banked_r13[8]; + uint32_t banked_r14[8]; + + /* These hold r8-r12. */ + uint32_t usr_regs[5]; + uint32_t fiq_regs[5]; + + /* cpsr flag cache for faster execution */ + uint32_t CF; /* 0 or 1 */ + uint32_t VF; /* V is the bit 31. All other bits are undefined */ + uint32_t NF; /* N is bit 31. All other bits are undefined. */ + uint32_t ZF; /* Z set if zero. */ + uint32_t QF; /* 0 or 1 */ + uint32_t GE; /* cpsr[19:16] */ + uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */ + uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */ + uint64_t daif; /* exception masks, in the bits they are in PSTATE */ + + uint64_t elr_el[4]; /* AArch64 exception link regs */ + uint64_t sp_el[4]; /* AArch64 banked stack pointers */ + + /* System control coprocessor (cp15) */ + struct { + uint32_t c0_cpuid; + union { /* Cache size selection */ + struct { + uint64_t _unused_csselr0; + uint64_t csselr_ns; + uint64_t _unused_csselr1; + uint64_t csselr_s; + }; + uint64_t csselr_el[4]; + }; + union { /* System control register. */ + struct { + uint64_t _unused_sctlr; + uint64_t sctlr_ns; + uint64_t hsctlr; + uint64_t sctlr_s; + }; + uint64_t sctlr_el[4]; + }; + uint64_t cpacr_el1; /* Architectural feature access control register */ + uint64_t cptr_el[4]; /* ARMv8 feature trap registers */ + uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */ + uint64_t sder; /* Secure debug enable register. */ + uint32_t nsacr; /* Non-secure access control register. */ + union { /* MMU translation table base 0. */ + struct { + uint64_t _unused_ttbr0_0; + uint64_t ttbr0_ns; + uint64_t _unused_ttbr0_1; + uint64_t ttbr0_s; + }; + uint64_t ttbr0_el[4]; + }; + union { /* MMU translation table base 1. */ + struct { + uint64_t _unused_ttbr1_0; + uint64_t ttbr1_ns; + uint64_t _unused_ttbr1_1; + uint64_t ttbr1_s; + }; + uint64_t ttbr1_el[4]; + }; + uint64_t vttbr_el2; /* Virtualization Translation Table Base. */ + /* MMU translation table base control. */ + TCR tcr_el[4]; + TCR vtcr_el2; /* Virtualization Translation Control. */ + uint32_t c2_data; /* MPU data cacheable bits. */ + uint32_t c2_insn; /* MPU instruction cacheable bits. */ + union { /* MMU domain access control register + * MPU write buffer control. + */ + struct { + uint64_t dacr_ns; + uint64_t dacr_s; + }; + struct { + uint64_t dacr32_el2; + }; + }; + uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */ + uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */ + uint64_t hcr_el2; /* Hypervisor configuration register */ + uint64_t scr_el3; /* Secure configuration register. */ + union { /* Fault status registers. */ + struct { + uint64_t ifsr_ns; + uint64_t ifsr_s; + }; + struct { + uint64_t ifsr32_el2; + }; + }; + union { + struct { + uint64_t _unused_dfsr; + uint64_t dfsr_ns; + uint64_t hsr; + uint64_t dfsr_s; + }; + uint64_t esr_el[4]; + }; + uint32_t c6_region[8]; /* MPU base/size registers. */ + union { /* Fault address registers. */ + struct { + uint64_t _unused_far0; +#ifdef HOST_WORDS_BIGENDIAN + uint32_t ifar_ns; + uint32_t dfar_ns; + uint32_t ifar_s; + uint32_t dfar_s; +#else + uint32_t dfar_ns; + uint32_t ifar_ns; + uint32_t dfar_s; + uint32_t ifar_s; +#endif + uint64_t _unused_far3; + }; + uint64_t far_el[4]; + }; + uint64_t hpfar_el2; + union { /* Translation result. */ + struct { + uint64_t _unused_par_0; + uint64_t par_ns; + uint64_t _unused_par_1; + uint64_t par_s; + }; + uint64_t par_el[4]; + }; + + uint32_t c6_rgnr; + + uint32_t c9_insn; /* Cache lockdown registers. */ + uint32_t c9_data; + uint64_t c9_pmcr; /* performance monitor control register */ + uint64_t c9_pmcnten; /* perf monitor counter enables */ + uint32_t c9_pmovsr; /* perf monitor overflow status */ + uint32_t c9_pmxevtyper; /* perf monitor event type */ + uint32_t c9_pmuserenr; /* perf monitor user enable */ + uint32_t c9_pminten; /* perf monitor interrupt enables */ + union { /* Memory attribute redirection */ + struct { +#ifdef HOST_WORDS_BIGENDIAN + uint64_t _unused_mair_0; + uint32_t mair1_ns; + uint32_t mair0_ns; + uint64_t _unused_mair_1; + uint32_t mair1_s; + uint32_t mair0_s; +#else + uint64_t _unused_mair_0; + uint32_t mair0_ns; + uint32_t mair1_ns; + uint64_t _unused_mair_1; + uint32_t mair0_s; + uint32_t mair1_s; +#endif + }; + uint64_t mair_el[4]; + }; + union { /* vector base address register */ + struct { + uint64_t _unused_vbar; + uint64_t vbar_ns; + uint64_t hvbar; + uint64_t vbar_s; + }; + uint64_t vbar_el[4]; + }; + uint32_t mvbar; /* (monitor) vector base address register */ + struct { /* FCSE PID. */ + uint32_t fcseidr_ns; + uint32_t fcseidr_s; + }; + union { /* Context ID. */ + struct { + uint64_t _unused_contextidr_0; + uint64_t contextidr_ns; + uint64_t _unused_contextidr_1; + uint64_t contextidr_s; + }; + uint64_t contextidr_el[4]; + }; + union { /* User RW Thread register. */ + struct { + uint64_t tpidrurw_ns; + uint64_t tpidrprw_ns; + uint64_t htpidr; + uint64_t _tpidr_el3; + }; + uint64_t tpidr_el[4]; + }; + /* The secure banks of these registers don't map anywhere */ + uint64_t tpidrurw_s; + uint64_t tpidrprw_s; + uint64_t tpidruro_s; + + union { /* User RO Thread register. */ + uint64_t tpidruro_ns; + uint64_t tpidrro_el[1]; + }; + uint64_t c14_cntfrq; /* Counter Frequency register */ + uint64_t c14_cntkctl; /* Timer Control register */ + uint32_t cnthctl_el2; /* Counter/Timer Hyp Control register */ + uint64_t cntvoff_el2; /* Counter Virtual Offset register */ + ARMGenericTimer c14_timer[NUM_GTIMERS]; + uint32_t c15_cpar; /* XScale Coprocessor Access Register */ + uint32_t c15_ticonfig; /* TI925T configuration byte. */ + uint32_t c15_i_max; /* Maximum D-cache dirty line index. */ + uint32_t c15_i_min; /* Minimum D-cache dirty line index. */ + uint32_t c15_threadid; /* TI debugger thread-ID. */ + uint32_t c15_config_base_address; /* SCU base address. */ + uint32_t c15_diagnostic; /* diagnostic register */ + uint32_t c15_power_diagnostic; + uint32_t c15_power_control; /* power control */ + uint64_t dbgbvr[16]; /* breakpoint value registers */ + uint64_t dbgbcr[16]; /* breakpoint control registers */ + uint64_t dbgwvr[16]; /* watchpoint value registers */ + uint64_t dbgwcr[16]; /* watchpoint control registers */ + uint64_t mdscr_el1; + uint64_t oslsr_el1; /* OS Lock Status */ + uint64_t mdcr_el2; + /* If the counter is enabled, this stores the last time the counter + * was reset. Otherwise it stores the counter value + */ + uint64_t c15_ccnt; + uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ + uint64_t vpidr_el2; /* Virtualization Processor ID Register */ + uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ + } cp15; + + struct { + uint32_t other_sp; + uint32_t vecbase; + uint32_t basepri; + uint32_t control; + int current_sp; + int exception; + uint32_t ccr; + uint32_t cfsr; + uint32_t hfsr; + uint32_t dfsr; + uint32_t mmfar; + uint32_t bfar; + uint32_t mpu_ctrl; + } v7m; + + /* Information associated with an exception about to be taken: + * code which raises an exception must set cs->exception_index and + * the relevant parts of this structure; the cpu_do_interrupt function + * will then set the guest-visible registers as part of the exception + * entry process. + */ + struct { + uint32_t syndrome; /* AArch64 format syndrome register */ + uint32_t fsr; /* AArch32 format fault status register info */ + uint64_t vaddress; /* virtual addr associated with exception, if any */ + uint32_t target_el; /* EL the exception should be targeted for */ + /* If we implement EL2 we will also need to store information + * about the intermediate physical address for stage 2 faults. + */ + } exception; + + /* Thumb-2 EE state. */ + uint32_t teecr; + uint32_t teehbr; + + /* VFP coprocessor state. */ + struct { + /* VFP/Neon register state. Note that the mapping between S, D and Q + * views of the register bank differs between AArch64 and AArch32: + * In AArch32: + * Qn = regs[2n+1]:regs[2n] + * Dn = regs[n] + * Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n + * (and regs[32] to regs[63] are inaccessible) + * In AArch64: + * Qn = regs[2n+1]:regs[2n] + * Dn = regs[2n] + * Sn = regs[2n] bits 31..0 + * This corresponds to the architecturally defined mapping between + * the two execution states, and means we do not need to explicitly + * map these registers when changing states. + */ + float64 regs[64]; + + uint32_t xregs[16]; + /* We store these fpcsr fields separately for convenience. */ + int vec_len; + int vec_stride; + + /* scratch space when Tn are not sufficient. */ + uint32_t scratch[8]; + + /* fp_status is the "normal" fp status. standard_fp_status retains + * values corresponding to the ARM "Standard FPSCR Value", ie + * default-NaN, flush-to-zero, round-to-nearest and is used by + * any operations (generally Neon) which the architecture defines + * as controlled by the standard FPSCR value rather than the FPSCR. + * + * To avoid having to transfer exception bits around, we simply + * say that the FPSCR cumulative exception flags are the logical + * OR of the flags in the two fp statuses. This relies on the + * only thing which needs to read the exception flags being + * an explicit FPSCR read. + */ + float_status fp_status; + float_status standard_fp_status; + } vfp; + uint64_t exclusive_addr; + uint64_t exclusive_val; + uint64_t exclusive_high; +#if defined(CONFIG_USER_ONLY) + uint64_t exclusive_test; + uint32_t exclusive_info; +#endif + + /* iwMMXt coprocessor state. */ + struct { + uint64_t regs[16]; + uint64_t val; + + uint32_t cregs[16]; + } iwmmxt; + + /* For mixed endian mode. */ + bool bswap_code; + +#if defined(CONFIG_USER_ONLY) + /* For usermode syscall translation. */ + int eabi; +#endif + + struct CPUBreakpoint *cpu_breakpoint[16]; + struct CPUWatchpoint *cpu_watchpoint[16]; + + CPU_COMMON + + /* These fields after the common ones so they are preserved on reset. */ + + /* Internal CPU feature flags. */ + uint64_t features; + + /* PMSAv7 MPU */ + struct { + uint32_t *drbar; + uint32_t *drsr; + uint32_t *dracr; + } pmsav7; + + void *nvic; + const struct arm_boot_info *boot_info; +} CPUARMState; + +#include "cpu-qom.h" + +ARMCPU *cpu_arm_init(const char *cpu_model); +int cpu_arm_exec(CPUState *cpu); +target_ulong do_arm_semihosting(CPUARMState *env); +void aarch64_sync_32_to_64(CPUARMState *env); +void aarch64_sync_64_to_32(CPUARMState *env); + +static inline bool is_a64(CPUARMState *env) +{ + return env->aarch64; +} + +/* you can call this signal handler from your SIGBUS and SIGSEGV + signal handlers to inform the virtual CPU of exceptions. non zero + is returned if the signal was handled by the virtual CPU. */ +int cpu_arm_signal_handler(int host_signum, void *pinfo, + void *puc); + +/** + * pmccntr_sync + * @env: CPUARMState + * + * Synchronises the counter in the PMCCNTR. This must always be called twice, + * once before any action that might affect the timer and again afterwards. + * The function is used to swap the state of the register if required. + * This only happens when not in user mode (!CONFIG_USER_ONLY) + */ +void pmccntr_sync(CPUARMState *env); + +/* SCTLR bit meanings. Several bits have been reused in newer + * versions of the architecture; in that case we define constants + * for both old and new bit meanings. Code which tests against those + * bits should probably check or otherwise arrange that the CPU + * is the architectural version it expects. + */ +#define SCTLR_M (1U << 0) +#define SCTLR_A (1U << 1) +#define SCTLR_C (1U << 2) +#define SCTLR_W (1U << 3) /* up to v6; RAO in v7 */ +#define SCTLR_SA (1U << 3) +#define SCTLR_P (1U << 4) /* up to v5; RAO in v6 and v7 */ +#define SCTLR_SA0 (1U << 4) /* v8 onward, AArch64 only */ +#define SCTLR_D (1U << 5) /* up to v5; RAO in v6 */ +#define SCTLR_CP15BEN (1U << 5) /* v7 onward */ +#define SCTLR_L (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */ +#define SCTLR_B (1U << 7) /* up to v6; RAZ in v7 */ +#define SCTLR_ITD (1U << 7) /* v8 onward */ +#define SCTLR_S (1U << 8) /* up to v6; RAZ in v7 */ +#define SCTLR_SED (1U << 8) /* v8 onward */ +#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */ +#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */ +#define SCTLR_F (1U << 10) /* up to v6 */ +#define SCTLR_SW (1U << 10) /* v7 onward */ +#define SCTLR_Z (1U << 11) +#define SCTLR_I (1U << 12) +#define SCTLR_V (1U << 13) +#define SCTLR_RR (1U << 14) /* up to v7 */ +#define SCTLR_DZE (1U << 14) /* v8 onward, AArch64 only */ +#define SCTLR_L4 (1U << 15) /* up to v6; RAZ in v7 */ +#define SCTLR_UCT (1U << 15) /* v8 onward, AArch64 only */ +#define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */ +#define SCTLR_nTWI (1U << 16) /* v8 onward */ +#define SCTLR_HA (1U << 17) +#define SCTLR_BR (1U << 17) /* PMSA only */ +#define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */ +#define SCTLR_nTWE (1U << 18) /* v8 onward */ +#define SCTLR_WXN (1U << 19) +#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */ +#define SCTLR_UWXN (1U << 20) /* v7 onward */ +#define SCTLR_FI (1U << 21) +#define SCTLR_U (1U << 22) +#define SCTLR_XP (1U << 23) /* up to v6; v7 onward RAO */ +#define SCTLR_VE (1U << 24) /* up to v7 */ +#define SCTLR_E0E (1U << 24) /* v8 onward, AArch64 only */ +#define SCTLR_EE (1U << 25) +#define SCTLR_L2 (1U << 26) /* up to v6, RAZ in v7 */ +#define SCTLR_UCI (1U << 26) /* v8 onward, AArch64 only */ +#define SCTLR_NMFI (1U << 27) +#define SCTLR_TRE (1U << 28) +#define SCTLR_AFE (1U << 29) +#define SCTLR_TE (1U << 30) + +#define CPTR_TCPAC (1U << 31) +#define CPTR_TTA (1U << 20) +#define CPTR_TFP (1U << 10) + +#define CPSR_M (0x1fU) +#define CPSR_T (1U << 5) +#define CPSR_F (1U << 6) +#define CPSR_I (1U << 7) +#define CPSR_A (1U << 8) +#define CPSR_E (1U << 9) +#define CPSR_IT_2_7 (0xfc00U) +#define CPSR_GE (0xfU << 16) +#define CPSR_IL (1U << 20) +/* Note that the RESERVED bits include bit 21, which is PSTATE_SS in + * an AArch64 SPSR but RES0 in AArch32 SPSR and CPSR. In QEMU we use + * env->uncached_cpsr bit 21 to store PSTATE.SS when executing in AArch32, + * where it is live state but not accessible to the AArch32 code. + */ +#define CPSR_RESERVED (0x7U << 21) +#define CPSR_J (1U << 24) +#define CPSR_IT_0_1 (3U << 25) +#define CPSR_Q (1U << 27) +#define CPSR_V (1U << 28) +#define CPSR_C (1U << 29) +#define CPSR_Z (1U << 30) +#define CPSR_N (1U << 31) +#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) +#define CPSR_AIF (CPSR_A | CPSR_I | CPSR_F) + +#define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7) +#define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | CPSR_Q \ + | CPSR_NZCV) +/* Bits writable in user mode. */ +#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE) +/* Execution state bits. MRS read as zero, MSR writes ignored. */ +#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL) +/* Mask of bits which may be set by exception return copying them from SPSR */ +#define CPSR_ERET_MASK (~CPSR_RESERVED) + +#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */ +#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */ +#define TTBCR_PD0 (1U << 4) +#define TTBCR_PD1 (1U << 5) +#define TTBCR_EPD0 (1U << 7) +#define TTBCR_IRGN0 (3U << 8) +#define TTBCR_ORGN0 (3U << 10) +#define TTBCR_SH0 (3U << 12) +#define TTBCR_T1SZ (3U << 16) +#define TTBCR_A1 (1U << 22) +#define TTBCR_EPD1 (1U << 23) +#define TTBCR_IRGN1 (3U << 24) +#define TTBCR_ORGN1 (3U << 26) +#define TTBCR_SH1 (1U << 28) +#define TTBCR_EAE (1U << 31) + +/* Bit definitions for ARMv8 SPSR (PSTATE) format. + * Only these are valid when in AArch64 mode; in + * AArch32 mode SPSRs are basically CPSR-format. + */ +#define PSTATE_SP (1U) +#define PSTATE_M (0xFU) +#define PSTATE_nRW (1U << 4) +#define PSTATE_F (1U << 6) +#define PSTATE_I (1U << 7) +#define PSTATE_A (1U << 8) +#define PSTATE_D (1U << 9) +#define PSTATE_IL (1U << 20) +#define PSTATE_SS (1U << 21) +#define PSTATE_V (1U << 28) +#define PSTATE_C (1U << 29) +#define PSTATE_Z (1U << 30) +#define PSTATE_N (1U << 31) +#define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V) +#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F) +#define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF) +/* Mode values for AArch64 */ +#define PSTATE_MODE_EL3h 13 +#define PSTATE_MODE_EL3t 12 +#define PSTATE_MODE_EL2h 9 +#define PSTATE_MODE_EL2t 8 +#define PSTATE_MODE_EL1h 5 +#define PSTATE_MODE_EL1t 4 +#define PSTATE_MODE_EL0t 0 + +/* Map EL and handler into a PSTATE_MODE. */ +static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handler) +{ + return (el << 2) | handler; +} + +/* Return the current PSTATE value. For the moment we don't support 32<->64 bit + * interprocessing, so we don't attempt to sync with the cpsr state used by + * the 32 bit decoder. + */ +static inline uint32_t pstate_read(CPUARMState *env) +{ + int ZF; + + ZF = (env->ZF == 0); + return (env->NF & 0x80000000) | (ZF << 30) + | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) + | env->pstate | env->daif; +} + +static inline void pstate_write(CPUARMState *env, uint32_t val) +{ + env->ZF = (~val) & PSTATE_Z; + env->NF = val; + env->CF = (val >> 29) & 1; + env->VF = (val << 3) & 0x80000000; + env->daif = val & PSTATE_DAIF; + env->pstate = val & ~CACHED_PSTATE_BITS; +} + +/* Return the current CPSR value. */ +uint32_t cpsr_read(CPUARMState *env); +/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */ +void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask); + +/* Return the current xPSR value. */ +static inline uint32_t xpsr_read(CPUARMState *env) +{ + int ZF; + ZF = (env->ZF == 0); + return (env->NF & 0x80000000) | (ZF << 30) + | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) + | (env->thumb << 24) | ((env->condexec_bits & 3) << 25) + | ((env->condexec_bits & 0xfc) << 8) + | env->v7m.exception; +} + +/* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */ +static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) +{ + if (mask & CPSR_NZCV) { + env->ZF = (~val) & CPSR_Z; + env->NF = val; + env->CF = (val >> 29) & 1; + env->VF = (val << 3) & 0x80000000; + } + if (mask & CPSR_Q) + env->QF = ((val & CPSR_Q) != 0); + if (mask & (1 << 24)) + env->thumb = ((val & (1 << 24)) != 0); + if (mask & CPSR_IT_0_1) { + env->condexec_bits &= ~3; + env->condexec_bits |= (val >> 25) & 3; + } + if (mask & CPSR_IT_2_7) { + env->condexec_bits &= 3; + env->condexec_bits |= (val >> 8) & 0xfc; + } + if (mask & 0x1ff) { + env->v7m.exception = val & 0x1ff; + } +} + +#define HCR_VM (1ULL << 0) +#define HCR_SWIO (1ULL << 1) +#define HCR_PTW (1ULL << 2) +#define HCR_FMO (1ULL << 3) +#define HCR_IMO (1ULL << 4) +#define HCR_AMO (1ULL << 5) +#define HCR_VF (1ULL << 6) +#define HCR_VI (1ULL << 7) +#define HCR_VSE (1ULL << 8) +#define HCR_FB (1ULL << 9) +#define HCR_BSU_MASK (3ULL << 10) +#define HCR_DC (1ULL << 12) +#define HCR_TWI (1ULL << 13) +#define HCR_TWE (1ULL << 14) +#define HCR_TID0 (1ULL << 15) +#define HCR_TID1 (1ULL << 16) +#define HCR_TID2 (1ULL << 17) +#define HCR_TID3 (1ULL << 18) +#define HCR_TSC (1ULL << 19) +#define HCR_TIDCP (1ULL << 20) +#define HCR_TACR (1ULL << 21) +#define HCR_TSW (1ULL << 22) +#define HCR_TPC (1ULL << 23) +#define HCR_TPU (1ULL << 24) +#define HCR_TTLB (1ULL << 25) +#define HCR_TVM (1ULL << 26) +#define HCR_TGE (1ULL << 27) +#define HCR_TDZ (1ULL << 28) +#define HCR_HCD (1ULL << 29) +#define HCR_TRVM (1ULL << 30) +#define HCR_RW (1ULL << 31) +#define HCR_CD (1ULL << 32) +#define HCR_ID (1ULL << 33) +#define HCR_MASK ((1ULL << 34) - 1) + +#define SCR_NS (1U << 0) +#define SCR_IRQ (1U << 1) +#define SCR_FIQ (1U << 2) +#define SCR_EA (1U << 3) +#define SCR_FW (1U << 4) +#define SCR_AW (1U << 5) +#define SCR_NET (1U << 6) +#define SCR_SMD (1U << 7) +#define SCR_HCE (1U << 8) +#define SCR_SIF (1U << 9) +#define SCR_RW (1U << 10) +#define SCR_ST (1U << 11) +#define SCR_TWI (1U << 12) +#define SCR_TWE (1U << 13) +#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST)) +#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET) + +/* Return the current FPSCR value. */ +uint32_t vfp_get_fpscr(CPUARMState *env); +void vfp_set_fpscr(CPUARMState *env, uint32_t val); + +/* For A64 the FPSCR is split into two logically distinct registers, + * FPCR and FPSR. However since they still use non-overlapping bits + * we store the underlying state in fpscr and just mask on read/write. + */ +#define FPSR_MASK 0xf800009f +#define FPCR_MASK 0x07f79f00 +static inline uint32_t vfp_get_fpsr(CPUARMState *env) +{ + return vfp_get_fpscr(env) & FPSR_MASK; +} + +static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val) +{ + uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val & FPSR_MASK); + vfp_set_fpscr(env, new_fpscr); +} + +static inline uint32_t vfp_get_fpcr(CPUARMState *env) +{ + return vfp_get_fpscr(env) & FPCR_MASK; +} + +static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val) +{ + uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val & FPCR_MASK); + vfp_set_fpscr(env, new_fpscr); +} + +enum arm_cpu_mode { + ARM_CPU_MODE_USR = 0x10, + ARM_CPU_MODE_FIQ = 0x11, + ARM_CPU_MODE_IRQ = 0x12, + ARM_CPU_MODE_SVC = 0x13, + ARM_CPU_MODE_MON = 0x16, + ARM_CPU_MODE_ABT = 0x17, + ARM_CPU_MODE_HYP = 0x1a, + ARM_CPU_MODE_UND = 0x1b, + ARM_CPU_MODE_SYS = 0x1f +}; + +/* VFP system registers. */ +#define ARM_VFP_FPSID 0 +#define ARM_VFP_FPSCR 1 +#define ARM_VFP_MVFR2 5 +#define ARM_VFP_MVFR1 6 +#define ARM_VFP_MVFR0 7 +#define ARM_VFP_FPEXC 8 +#define ARM_VFP_FPINST 9 +#define ARM_VFP_FPINST2 10 + +/* iwMMXt coprocessor control registers. */ +#define ARM_IWMMXT_wCID 0 +#define ARM_IWMMXT_wCon 1 +#define ARM_IWMMXT_wCSSF 2 +#define ARM_IWMMXT_wCASF 3 +#define ARM_IWMMXT_wCGR0 8 +#define ARM_IWMMXT_wCGR1 9 +#define ARM_IWMMXT_wCGR2 10 +#define ARM_IWMMXT_wCGR3 11 + +/* V7M CCSR bits */ +#define CCR_STKALIGN 0x00000200 +#define CCR_BFHFNMIGN 0x00000100 +#define CCR_DIV_0_TRP 0x00000010 +#define CCR_UNALIGN_TRP 0x00000008 +#define CCR_USERSETMPEND 0x00000002 +#define CCR_NONBASETHRDENA 0x00000001 + +/* V7M CFSR bits for UFSR */ +#define CFSR_DIVBYZERO 0x02000000 +#define CFSR_UNALIGNED 0x01000000 +#define CFSR_NOCP 0x00080000 +#define CFSR_INVPC 0x00040000 +#define CFSR_INVSTATE 0x00020000 +#define CFSR_UNDEFINSTR 0x00010000 + +/* V7M CFSR bits for BFSR */ +#define CFSR_BFARVALID 0x00008000 +#define CFSR_LSPERR 0x00002000 +#define CFSR_STKERR 0x00001000 +#define CFSR_UNSTKERR 0x00000800 +#define CFSR_IMPRECISERR 0x00000400 +#define CFSR_PRECISERR 0x00000200 +#define CFSR_IBUSERR 0x00000100 + +/* V7M CFSR bits for MMFSR */ +#define CFSR_MMARVALID 0x00000080 +#define CFSR_MLSPERR 0x00000020 +#define CFSR_MSTKERR 0x00000010 +#define CFSR_MUNSTKERR 0x00000008 +#define CFSR_DACCVIOL 0x00000002 +#define CFSR_IACCVIOL 0x00000001 + +/* V7M HFSR bits */ +#define HFSR_DEBUG_VT 0x80000000 +#define HFSR_FORCED 0x40000000 +#define HFSR_VECTTBL 0x00000002 + +/* V7M DFSR bits */ +#define DFSR_EXTERNAL 0x00000010 +#define DFSR_VCATCH 0x00000008 +#define DFSR_DWTTRAP 0x00000004 +#define DFSR_BKPT 0x00000002 +#define DFSR_HALTED 0x00000001 + +/* V7M MPU_CTRL bits */ +#define MPU_CTRL_PRIVDEFENA 0x00000004 +#define MPU_CTRL_HFNMIENA 0x00000002 +#define MPU_CTRL_ENABLE 0x00000001 + +/* If adding a feature bit which corresponds to a Linux ELF + * HWCAP bit, remember to update the feature-bit-to-hwcap + * mapping in linux-user/elfload.c:get_elf_hwcap(). + */ +enum arm_features { + ARM_FEATURE_VFP, + ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */ + ARM_FEATURE_XSCALE, /* Intel XScale extensions. */ + ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */ + ARM_FEATURE_V6, + ARM_FEATURE_V6K, + ARM_FEATURE_V7, + ARM_FEATURE_THUMB2, + ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */ + ARM_FEATURE_VFP3, + ARM_FEATURE_VFP_FP16, + ARM_FEATURE_NEON, + ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */ + ARM_FEATURE_M, /* Microcontroller profile. */ + ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */ + ARM_FEATURE_THUMB2EE, + ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */ + ARM_FEATURE_V4T, + ARM_FEATURE_V5, + ARM_FEATURE_STRONGARM, + ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */ + ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */ + ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */ + ARM_FEATURE_GENERIC_TIMER, + ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */ + ARM_FEATURE_DUMMY_C15_REGS, /* RAZ/WI all of cp15 crn=15 */ + ARM_FEATURE_CACHE_TEST_CLEAN, /* 926/1026 style test-and-clean ops */ + ARM_FEATURE_CACHE_DIRTY_REG, /* 1136/1176 cache dirty status register */ + ARM_FEATURE_CACHE_BLOCK_OPS, /* v6 optional cache block operations */ + ARM_FEATURE_MPIDR, /* has cp15 MPIDR */ + ARM_FEATURE_PXN, /* has Privileged Execute Never bit */ + ARM_FEATURE_LPAE, /* has Large Physical Address Extension */ + ARM_FEATURE_V8, + ARM_FEATURE_AARCH64, /* supports 64 bit mode */ + ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */ + ARM_FEATURE_CBAR, /* has cp15 CBAR */ + ARM_FEATURE_CRC, /* ARMv8 CRC instructions */ + ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */ + ARM_FEATURE_EL2, /* has EL2 Virtualization support */ + ARM_FEATURE_EL3, /* has EL3 Secure monitor support */ + ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */ + ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */ + ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */ + ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */ +}; + +static inline int arm_feature(CPUARMState *env, int feature) +{ + return (env->features & (1ULL << feature)) != 0; +} + +#if !defined(CONFIG_USER_ONLY) +/* Return true if exception levels below EL3 are in secure state, + * or would be following an exception return to that level. + * Unlike arm_is_secure() (which is always a question about the + * _current_ state of the CPU) this doesn't care about the current + * EL or mode. + */ +static inline bool arm_is_secure_below_el3(CPUARMState *env) +{ + if (arm_feature(env, ARM_FEATURE_EL3)) { + return !(env->cp15.scr_el3 & SCR_NS); + } else { + /* If EL2 is not supported then the secure state is implementation + * defined, in which case QEMU defaults to non-secure. + */ + return false; + } +} + +/* Return true if the processor is in secure state */ +static inline bool arm_is_secure(CPUARMState *env) +{ + if (arm_feature(env, ARM_FEATURE_EL3)) { + if (is_a64(env) && extract32(env->pstate, 2, 2) == 3) { + /* CPU currently in AArch64 state and EL3 */ + return true; + } else if (!is_a64(env) && + (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) { + /* CPU currently in AArch32 state and monitor mode */ + return true; + } + } + return arm_is_secure_below_el3(env); +} + +#else +static inline bool arm_is_secure_below_el3(CPUARMState *env) +{ + return false; +} + +static inline bool arm_is_secure(CPUARMState *env) +{ + return false; +} +#endif + +/* Return true if the specified exception level is running in AArch64 state. */ +static inline bool arm_el_is_aa64(CPUARMState *env, int el) +{ + /* We don't currently support EL2, and this isn't valid for EL0 + * (if we're in EL0, is_a64() is what you want, and if we're not in EL0 + * then the state of EL0 isn't well defined.) + */ + assert(el == 1 || el == 3); + + /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This + * is a QEMU-imposed simplification which we may wish to change later. + * If we in future support EL2 and/or EL3, then the state of lower + * exception levels is controlled by the HCR.RW and SCR.RW bits. + */ + return arm_feature(env, ARM_FEATURE_AARCH64); +} + +/* Function for determing whether guest cp register reads and writes should + * access the secure or non-secure bank of a cp register. When EL3 is + * operating in AArch32 state, the NS-bit determines whether the secure + * instance of a cp register should be used. When EL3 is AArch64 (or if + * it doesn't exist at all) then there is no register banking, and all + * accesses are to the non-secure version. + */ +static inline bool access_secure_reg(CPUARMState *env) +{ + bool ret = (arm_feature(env, ARM_FEATURE_EL3) && + !arm_el_is_aa64(env, 3) && + !(env->cp15.scr_el3 & SCR_NS)); + + return ret; +} + +/* Macros for accessing a specified CP register bank */ +#define A32_BANKED_REG_GET(_env, _regname, _secure) \ + ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns) + +#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \ + do { \ + if (_secure) { \ + (_env)->cp15._regname##_s = (_val); \ + } else { \ + (_env)->cp15._regname##_ns = (_val); \ + } \ + } while (0) + +/* Macros for automatically accessing a specific CP register bank depending on + * the current secure state of the system. These macros are not intended for + * supporting instruction translation reads/writes as these are dependent + * solely on the SCR.NS bit and not the mode. + */ +#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \ + A32_BANKED_REG_GET((_env), _regname, \ + (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3))) + +#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \ + A32_BANKED_REG_SET((_env), _regname, \ + (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \ + (_val)) + +void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf); +uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, + uint32_t cur_el, bool secure); + +/* Interface between CPU and Interrupt controller. */ +void armv7m_nvic_set_pending(void *opaque, int irq); +int armv7m_nvic_acknowledge_irq(void *opaque); +void armv7m_nvic_complete_irq(void *opaque, int irq); +void armv7m_nvic_set_base_priority(void *opaque, unsigned int priority); +void armv7m_nvic_cpu_executed_wfi(void *opaque); + +/* Interface between interrupt controller and power controller */ +bool f2xx_pwr_powerdown_deepsleep(void *opaqe); + +/* Interface for defining coprocessor registers. + * Registers are defined in tables of arm_cp_reginfo structs + * which are passed to define_arm_cp_regs(). + */ + +/* When looking up a coprocessor register we look for it + * via an integer which encodes all of: + * coprocessor number + * Crn, Crm, opc1, opc2 fields + * 32 or 64 bit register (ie is it accessed via MRC/MCR + * or via MRRC/MCRR?) + * non-secure/secure bank (AArch32 only) + * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field. + * (In this case crn and opc2 should be zero.) + * For AArch64, there is no 32/64 bit size distinction; + * instead all registers have a 2 bit op0, 3 bit op1 and op2, + * and 4 bit CRn and CRm. The encoding patterns are chosen + * to be easy to convert to and from the KVM encodings, and also + * so that the hashtable can contain both AArch32 and AArch64 + * registers (to allow for interprocessing where we might run + * 32 bit code on a 64 bit core). + */ +/* This bit is private to our hashtable cpreg; in KVM register + * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64 + * in the upper bits of the 64 bit ID. + */ +#define CP_REG_AA64_SHIFT 28 +#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT) + +/* To enable banking of coprocessor registers depending on ns-bit we + * add a bit to distinguish between secure and non-secure cpregs in the + * hashtable. + */ +#define CP_REG_NS_SHIFT 29 +#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT) + +#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \ + ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \ + ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2)) + +#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \ + (CP_REG_AA64_MASK | \ + ((cp) << CP_REG_ARM_COPROC_SHIFT) | \ + ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \ + ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \ + ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \ + ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \ + ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT)) + +/* Convert a full 64 bit KVM register ID to the truncated 32 bit + * version used as a key for the coprocessor register hashtable + */ +static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid) +{ + uint32_t cpregid = kvmid; + if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) { + cpregid |= CP_REG_AA64_MASK; + } else { + if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) { + cpregid |= (1 << 15); + } + + /* KVM is always non-secure so add the NS flag on AArch32 register + * entries. + */ + cpregid |= 1 << CP_REG_NS_SHIFT; + } + return cpregid; +} + +/* Convert a truncated 32 bit hashtable key into the full + * 64 bit KVM register ID. + */ +static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) +{ + uint64_t kvmid; + + if (cpregid & CP_REG_AA64_MASK) { + kvmid = cpregid & ~CP_REG_AA64_MASK; + kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64; + } else { + kvmid = cpregid & ~(1 << 15); + if (cpregid & (1 << 15)) { + kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM; + } else { + kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM; + } + } + return kvmid; +} + +/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a + * special-behaviour cp reg and bits [15..8] indicate what behaviour + * it has. Otherwise it is a simple cp reg, where CONST indicates that + * TCG can assume the value to be constant (ie load at translate time) + * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END + * indicates that the TB should not be ended after a write to this register + * (the default is that the TB ends after cp writes). OVERRIDE permits + * a register definition to override a previous definition for the + * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the + * old must have the OVERRIDE bit set. + * ALIAS indicates that this register is an alias view of some underlying + * state which is also visible via another register, and that the other + * register is handling migration and reset; registers marked ALIAS will not be + * migrated but may have their state set by syncing of register state from KVM. + * NO_RAW indicates that this register has no underlying state and does not + * support raw access for state saving/loading; it will not be used for either + * migration or KVM state synchronization. (Typically this is for "registers" + * which are actually used as instructions for cache maintenance and so on.) + * IO indicates that this register does I/O and therefore its accesses + * need to be surrounded by gen_io_start()/gen_io_end(). In particular, + * registers which implement clocks or timers require this. + */ +#define ARM_CP_SPECIAL 1 +#define ARM_CP_CONST 2 +#define ARM_CP_64BIT 4 +#define ARM_CP_SUPPRESS_TB_END 8 +#define ARM_CP_OVERRIDE 16 +#define ARM_CP_ALIAS 32 +#define ARM_CP_IO 64 +#define ARM_CP_NO_RAW 128 +#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8)) +#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8)) +#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8)) +#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8)) +#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8)) +#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA +/* Used only as a terminator for ARMCPRegInfo lists */ +#define ARM_CP_SENTINEL 0xffff +/* Mask of only the flag bits in a type field */ +#define ARM_CP_FLAG_MASK 0xff + +/* Valid values for ARMCPRegInfo state field, indicating which of + * the AArch32 and AArch64 execution states this register is visible in. + * If the reginfo doesn't explicitly specify then it is AArch32 only. + * If the reginfo is declared to be visible in both states then a second + * reginfo is synthesised for the AArch32 view of the AArch64 register, + * such that the AArch32 view is the lower 32 bits of the AArch64 one. + * Note that we rely on the values of these enums as we iterate through + * the various states in some places. + */ +enum { + ARM_CP_STATE_AA32 = 0, + ARM_CP_STATE_AA64 = 1, + ARM_CP_STATE_BOTH = 2, +}; + +/* ARM CP register secure state flags. These flags identify security state + * attributes for a given CP register entry. + * The existence of both or neither secure and non-secure flags indicates that + * the register has both a secure and non-secure hash entry. A single one of + * these flags causes the register to only be hashed for the specified + * security state. + * Although definitions may have any combination of the S/NS bits, each + * registered entry will only have one to identify whether the entry is secure + * or non-secure. + */ +enum { + ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */ + ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */ +}; + +/* Return true if cptype is a valid type field. This is used to try to + * catch errors where the sentinel has been accidentally left off the end + * of a list of registers. + */ +static inline bool cptype_valid(int cptype) +{ + return ((cptype & ~ARM_CP_FLAG_MASK) == 0) + || ((cptype & ARM_CP_SPECIAL) && + ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL)); +} + +/* Access rights: + * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM + * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and + * PL2 (hyp). The other level which has Read and Write bits is Secure PL1 + * (ie any of the privileged modes in Secure state, or Monitor mode). + * If a register is accessible in one privilege level it's always accessible + * in higher privilege levels too. Since "Secure PL1" also follows this rule + * (ie anything visible in PL2 is visible in S-PL1, some things are only + * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the + * terminology a little and call this PL3. + * In AArch64 things are somewhat simpler as the PLx bits line up exactly + * with the ELx exception levels. + * + * If access permissions for a register are more complex than can be + * described with these bits, then use a laxer set of restrictions, and + * do the more restrictive/complex check inside a helper function. + */ +#define PL3_R 0x80 +#define PL3_W 0x40 +#define PL2_R (0x20 | PL3_R) +#define PL2_W (0x10 | PL3_W) +#define PL1_R (0x08 | PL2_R) +#define PL1_W (0x04 | PL2_W) +#define PL0_R (0x02 | PL1_R) +#define PL0_W (0x01 | PL1_W) + +#define PL3_RW (PL3_R | PL3_W) +#define PL2_RW (PL2_R | PL2_W) +#define PL1_RW (PL1_R | PL1_W) +#define PL0_RW (PL0_R | PL0_W) + +/* Return the current Exception Level (as per ARMv8; note that this differs + * from the ARMv7 Privilege Level). + */ +static inline int arm_current_el(CPUARMState *env) +{ + if (arm_feature(env, ARM_FEATURE_M)) { + return !((env->v7m.exception == 0) && (env->v7m.control & 1)); + } + + if (is_a64(env)) { + return extract32(env->pstate, 2, 2); + } + + switch (env->uncached_cpsr & 0x1f) { + case ARM_CPU_MODE_USR: + return 0; + case ARM_CPU_MODE_HYP: + return 2; + case ARM_CPU_MODE_MON: + return 3; + default: + if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) { + /* If EL3 is 32-bit then all secure privileged modes run in + * EL3 + */ + return 3; + } + + return 1; + } +} + +typedef struct ARMCPRegInfo ARMCPRegInfo; + +typedef enum CPAccessResult { + /* Access is permitted */ + CP_ACCESS_OK = 0, + /* Access fails due to a configurable trap or enable which would + * result in a categorized exception syndrome giving information about + * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6, + * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or + * PL1 if in EL0, otherwise to the current EL). + */ + CP_ACCESS_TRAP = 1, + /* Access fails and results in an exception syndrome 0x0 ("uncategorized"). + * Note that this is not a catch-all case -- the set of cases which may + * result in this failure is specifically defined by the architecture. + */ + CP_ACCESS_TRAP_UNCATEGORIZED = 2, + /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */ + CP_ACCESS_TRAP_EL2 = 3, + CP_ACCESS_TRAP_EL3 = 4, + /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */ + CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5, + CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6, +} CPAccessResult; + +/* Access functions for coprocessor registers. These cannot fail and + * may not raise exceptions. + */ +typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque); +typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque, + uint64_t value); +/* Access permission check functions for coprocessor registers. */ +typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque); +/* Hook function for register reset */ +typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque); + +#define CP_ANY 0xff + +/* Definition of an ARM coprocessor register */ +struct ARMCPRegInfo { + /* Name of register (useful mainly for debugging, need not be unique) */ + const char *name; + /* Location of register: coprocessor number and (crn,crm,opc1,opc2) + * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a + * 'wildcard' field -- any value of that field in the MRC/MCR insn + * will be decoded to this register. The register read and write + * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2 + * used by the program, so it is possible to register a wildcard and + * then behave differently on read/write if necessary. + * For 64 bit registers, only crm and opc1 are relevant; crn and opc2 + * must both be zero. + * For AArch64-visible registers, opc0 is also used. + * Since there are no "coprocessors" in AArch64, cp is purely used as a + * way to distinguish (for KVM's benefit) guest-visible system registers + * from demuxed ones provided to preserve the "no side effects on + * KVM register read/write from QEMU" semantics. cp==0x13 is guest + * visible (to match KVM's encoding); cp==0 will be converted to + * cp==0x13 when the ARMCPRegInfo is registered, for convenience. + */ + uint8_t cp; + uint8_t crn; + uint8_t crm; + uint8_t opc0; + uint8_t opc1; + uint8_t opc2; + /* Execution state in which this register is visible: ARM_CP_STATE_* */ + int state; + /* Register type: ARM_CP_* bits/values */ + int type; + /* Access rights: PL*_[RW] */ + int access; + /* Security state: ARM_CP_SECSTATE_* bits/values */ + int secure; + /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when + * this register was defined: can be used to hand data through to the + * register read/write functions, since they are passed the ARMCPRegInfo*. + */ + void *opaque; + /* Value of this register, if it is ARM_CP_CONST. Otherwise, if + * fieldoffset is non-zero, the reset value of the register. + */ + uint64_t resetvalue; + /* Offset of the field in CPUARMState for this register. + * + * This is not needed if either: + * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs + * 2. both readfn and writefn are specified + */ + ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */ + + /* Offsets of the secure and non-secure fields in CPUARMState for the + * register if it is banked. These fields are only used during the static + * registration of a register. During hashing the bank associated + * with a given security state is copied to fieldoffset which is used from + * there on out. + * + * It is expected that register definitions use either fieldoffset or + * bank_fieldoffsets in the definition but not both. It is also expected + * that both bank offsets are set when defining a banked register. This + * use indicates that a register is banked. + */ + ptrdiff_t bank_fieldoffsets[2]; + + /* Function for making any access checks for this register in addition to + * those specified by the 'access' permissions bits. If NULL, no extra + * checks required. The access check is performed at runtime, not at + * translate time. + */ + CPAccessFn *accessfn; + /* Function for handling reads of this register. If NULL, then reads + * will be done by loading from the offset into CPUARMState specified + * by fieldoffset. + */ + CPReadFn *readfn; + /* Function for handling writes of this register. If NULL, then writes + * will be done by writing to the offset into CPUARMState specified + * by fieldoffset. + */ + CPWriteFn *writefn; + /* Function for doing a "raw" read; used when we need to copy + * coprocessor state to the kernel for KVM or out for + * migration. This only needs to be provided if there is also a + * readfn and it has side effects (for instance clear-on-read bits). + */ + CPReadFn *raw_readfn; + /* Function for doing a "raw" write; used when we need to copy KVM + * kernel coprocessor state into userspace, or for inbound + * migration. This only needs to be provided if there is also a + * writefn and it masks out "unwritable" bits or has write-one-to-clear + * or similar behaviour. + */ + CPWriteFn *raw_writefn; + /* Function for resetting the register. If NULL, then reset will be done + * by writing resetvalue to the field specified in fieldoffset. If + * fieldoffset is 0 then no reset will be done. + */ + CPResetFn *resetfn; +}; + +/* Macros which are lvalues for the field in CPUARMState for the + * ARMCPRegInfo *ri. + */ +#define CPREG_FIELD32(env, ri) \ + (*(uint32_t *)((char *)(env) + (ri)->fieldoffset)) +#define CPREG_FIELD64(env, ri) \ + (*(uint64_t *)((char *)(env) + (ri)->fieldoffset)) + +#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL } + +void define_arm_cp_regs_with_opaque(ARMCPU *cpu, + const ARMCPRegInfo *regs, void *opaque); +void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, + const ARMCPRegInfo *regs, void *opaque); +static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs) +{ + define_arm_cp_regs_with_opaque(cpu, regs, 0); +} +static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs) +{ + define_one_arm_cp_reg_with_opaque(cpu, regs, 0); +} +const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp); + +/* CPWriteFn that can be used to implement writes-ignored behaviour */ +void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value); +/* CPReadFn that can be used for read-as-zero behaviour */ +uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri); + +/* CPResetFn that does nothing, for use if no reset is required even + * if fieldoffset is non zero. + */ +void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque); + +/* Return true if this reginfo struct's field in the cpu state struct + * is 64 bits wide. + */ +static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri) +{ + return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT); +} + +static inline bool cp_access_ok(int current_el, + const ARMCPRegInfo *ri, int isread) +{ + return (ri->access >> ((current_el * 2) + isread)) & 1; +} + +/* Raw read of a coprocessor register (as needed for migration, etc) */ +uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri); + +/** + * write_list_to_cpustate + * @cpu: ARMCPU + * + * For each register listed in the ARMCPU cpreg_indexes list, write + * its value from the cpreg_values list into the ARMCPUState structure. + * This updates TCG's working data structures from KVM data or + * from incoming migration state. + * + * Returns: true if all register values were updated correctly, + * false if some register was unknown or could not be written. + * Note that we do not stop early on failure -- we will attempt + * writing all registers in the list. + */ +bool write_list_to_cpustate(ARMCPU *cpu); + +/** + * write_cpustate_to_list: + * @cpu: ARMCPU + * + * For each register listed in the ARMCPU cpreg_indexes list, write + * its value from the ARMCPUState structure into the cpreg_values list. + * This is used to copy info from TCG's working data structures into + * KVM or for outbound migration. + * + * Returns: true if all register values were read correctly, + * false if some register was unknown or could not be read. + * Note that we do not stop early on failure -- we will attempt + * reading all registers in the list. + */ +bool write_cpustate_to_list(ARMCPU *cpu); + +/* Does the core conform to the "MicroController" profile. e.g. Cortex-M3. + Note the M in older cores (eg. ARM7TDMI) stands for Multiply. These are + conventional cores (ie. Application or Realtime profile). */ + +#define IS_M(env) arm_feature(env, ARM_FEATURE_M) + +#define ARM_CPUID_TI915T 0x54029152 +#define ARM_CPUID_TI925T 0x54029252 + +#if defined(CONFIG_USER_ONLY) +#define TARGET_PAGE_BITS 12 +#else +/* The ARM MMU allows 1k pages. */ +/* ??? Linux doesn't actually use these, and they're deprecated in recent + architecture revisions. Maybe a configure option to disable them. */ +#define TARGET_PAGE_BITS 10 +#endif + +#if defined(TARGET_AARCH64) +# define TARGET_PHYS_ADDR_SPACE_BITS 48 +# define TARGET_VIRT_ADDR_SPACE_BITS 64 +#else +# define TARGET_PHYS_ADDR_SPACE_BITS 40 +# define TARGET_VIRT_ADDR_SPACE_BITS 32 +#endif + +static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, + unsigned int target_el) +{ + CPUARMState *env = cs->env_ptr; + unsigned int cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + bool pstate_unmasked; + int8_t unmasked = 0; + + /* Don't take exceptions if they target a lower EL. + * This check should catch any exceptions that would not be taken but left + * pending. + */ + if (cur_el > target_el) { + return false; + } + + switch (excp_idx) { + case EXCP_FIQ: + pstate_unmasked = !(env->daif & PSTATE_F); + break; + + case EXCP_IRQ: + pstate_unmasked = !(env->daif & PSTATE_I); + break; + + case EXCP_VFIQ: + if (secure || !(env->cp15.hcr_el2 & HCR_FMO)) { + /* VFIQs are only taken when hypervized and non-secure. */ + return false; + } + return !(env->daif & PSTATE_F); + case EXCP_VIRQ: + if (secure || !(env->cp15.hcr_el2 & HCR_IMO)) { + /* VIRQs are only taken when hypervized and non-secure. */ + return false; + } + return !(env->daif & PSTATE_I); + default: + g_assert_not_reached(); + } + + /* Use the target EL, current execution state and SCR/HCR settings to + * determine whether the corresponding CPSR bit is used to mask the + * interrupt. + */ + if ((target_el > cur_el) && (target_el != 1)) { + /* Exceptions targeting a higher EL may not be maskable */ + if (arm_feature(env, ARM_FEATURE_AARCH64)) { + /* 64-bit masking rules are simple: exceptions to EL3 + * can't be masked, and exceptions to EL2 can only be + * masked from Secure state. The HCR and SCR settings + * don't affect the masking logic, only the interrupt routing. + */ + if (target_el == 3 || !secure) { + unmasked = 1; + } + } else { + /* The old 32-bit-only environment has a more complicated + * masking setup. HCR and SCR bits not only affect interrupt + * routing but also change the behaviour of masking. + */ + bool hcr, scr; + + switch (excp_idx) { + case EXCP_FIQ: + /* If FIQs are routed to EL3 or EL2 then there are cases where + * we override the CPSR.F in determining if the exception is + * masked or not. If neither of these are set then we fall back + * to the CPSR.F setting otherwise we further assess the state + * below. + */ + hcr = (env->cp15.hcr_el2 & HCR_FMO); + scr = (env->cp15.scr_el3 & SCR_FIQ); + + /* When EL3 is 32-bit, the SCR.FW bit controls whether the + * CPSR.F bit masks FIQ interrupts when taken in non-secure + * state. If SCR.FW is set then FIQs can be masked by CPSR.F + * when non-secure but only when FIQs are only routed to EL3. + */ + scr = scr && !((env->cp15.scr_el3 & SCR_FW) && !hcr); + break; + case EXCP_IRQ: + /* When EL3 execution state is 32-bit, if HCR.IMO is set then + * we may override the CPSR.I masking when in non-secure state. + * The SCR.IRQ setting has already been taken into consideration + * when setting the target EL, so it does not have a further + * affect here. + */ + hcr = (env->cp15.hcr_el2 & HCR_IMO); + scr = false; + break; + default: + g_assert_not_reached(); + } + + if ((scr || hcr) && !secure) { + unmasked = 1; + } + } + } + + /* The PSTATE bits only mask the interrupt if we have not overriden the + * ability above. + */ + return unmasked || pstate_unmasked; +} + +#define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model)) + +#define cpu_exec cpu_arm_exec +#define cpu_signal_handler cpu_arm_signal_handler +#define cpu_list arm_cpu_list + +/* ARM has the following "translation regimes" (as the ARM ARM calls them): + * + * If EL3 is 64-bit: + * + NonSecure EL1 & 0 stage 1 + * + NonSecure EL1 & 0 stage 2 + * + NonSecure EL2 + * + Secure EL1 & EL0 + * + Secure EL3 + * If EL3 is 32-bit: + * + NonSecure PL1 & 0 stage 1 + * + NonSecure PL1 & 0 stage 2 + * + NonSecure PL2 + * + Secure PL0 & PL1 + * (reminder: for 32 bit EL3, Secure PL1 is *EL3*, not EL1.) + * + * For QEMU, an mmu_idx is not quite the same as a translation regime because: + * 1. we need to split the "EL1 & 0" regimes into two mmu_idxes, because they + * may differ in access permissions even if the VA->PA map is the same + * 2. we want to cache in our TLB the full VA->IPA->PA lookup for a stage 1+2 + * translation, which means that we have one mmu_idx that deals with two + * concatenated translation regimes [this sort of combined s1+2 TLB is + * architecturally permitted] + * 3. we don't need to allocate an mmu_idx to translations that we won't be + * handling via the TLB. The only way to do a stage 1 translation without + * the immediate stage 2 translation is via the ATS or AT system insns, + * which can be slow-pathed and always do a page table walk. + * 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3" + * translation regimes, because they map reasonably well to each other + * and they can't both be active at the same time. + * This gives us the following list of mmu_idx values: + * + * NS EL0 (aka NS PL0) stage 1+2 + * NS EL1 (aka NS PL1) stage 1+2 + * NS EL2 (aka NS PL2) + * S EL3 (aka S PL1) + * S EL0 (aka S PL0) + * S EL1 (not used if EL3 is 32 bit) + * NS EL0+1 stage 2 + * + * (The last of these is an mmu_idx because we want to be able to use the TLB + * for the accesses done as part of a stage 1 page table walk, rather than + * having to walk the stage 2 page table over and over.) + * + * Our enumeration includes at the end some entries which are not "true" + * mmu_idx values in that they don't have corresponding TLBs and are only + * valid for doing slow path page table walks. + * + * The constant names here are patterned after the general style of the names + * of the AT/ATS operations. + * The values used are carefully arranged to make mmu_idx => EL lookup easy. + */ +typedef enum ARMMMUIdx { + ARMMMUIdx_S12NSE0 = 0, + ARMMMUIdx_S12NSE1 = 1, + ARMMMUIdx_S1E2 = 2, + ARMMMUIdx_S1E3 = 3, + ARMMMUIdx_S1SE0 = 4, + ARMMMUIdx_S1SE1 = 5, + ARMMMUIdx_S2NS = 6, + /* Indexes below here don't have TLBs and are used only for AT system + * instructions or for the first stage of an S12 page table walk. + */ + ARMMMUIdx_S1NSE0 = 7, + ARMMMUIdx_S1NSE1 = 8, +} ARMMMUIdx; + +#define MMU_USER_IDX 0 + +/* Return the exception level we're running at if this is our mmu_idx */ +static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx) +{ + assert(mmu_idx < ARMMMUIdx_S2NS); + return mmu_idx & 3; +} + +/* Determine the current mmu_idx to use for normal loads/stores */ +static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) +{ + int el = arm_current_el(env); + + if (el < 2 && arm_is_secure_below_el3(env)) { + return ARMMMUIdx_S1SE0 + el; + } + return el; +} + +/* Return the Exception Level targeted by debug exceptions; + * currently always EL1 since we don't implement EL2 or EL3. + */ +static inline int arm_debug_target_el(CPUARMState *env) +{ + bool secure = arm_is_secure(env); + bool route_to_el2 = false; + + if (arm_feature(env, ARM_FEATURE_EL2) && !secure) { + route_to_el2 = env->cp15.hcr_el2 & HCR_TGE || + env->cp15.mdcr_el2 & (1 << 8); + } + + if (route_to_el2) { + return 2; + } else if (arm_feature(env, ARM_FEATURE_EL3) && + !arm_el_is_aa64(env, 3) && secure) { + return 3; + } else { + return 1; + } +} + +static inline bool aa64_generate_debug_exceptions(CPUARMState *env) +{ + if (arm_current_el(env) == arm_debug_target_el(env)) { + if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0) + || (env->daif & PSTATE_D)) { + return false; + } + } + return true; +} + +static inline bool aa32_generate_debug_exceptions(CPUARMState *env) +{ + if (arm_current_el(env) == 0 && arm_el_is_aa64(env, 1)) { + return aa64_generate_debug_exceptions(env); + } + return arm_current_el(env) != 2; +} + +/* Return true if debugging exceptions are currently enabled. + * This corresponds to what in ARM ARM pseudocode would be + * if UsingAArch32() then + * return AArch32.GenerateDebugExceptions() + * else + * return AArch64.GenerateDebugExceptions() + * We choose to push the if() down into this function for clarity, + * since the pseudocode has it at all callsites except for the one in + * CheckSoftwareStep(), where it is elided because both branches would + * always return the same value. + * + * Parts of the pseudocode relating to EL2 and EL3 are omitted because we + * don't yet implement those exception levels or their associated trap bits. + */ +static inline bool arm_generate_debug_exceptions(CPUARMState *env) +{ + if (env->aarch64) { + return aa64_generate_debug_exceptions(env); + } else { + return aa32_generate_debug_exceptions(env); + } +} + +/* Is single-stepping active? (Note that the "is EL_D AArch64?" check + * implicitly means this always returns false in pre-v8 CPUs.) + */ +static inline bool arm_singlestep_active(CPUARMState *env) +{ + return extract32(env->cp15.mdscr_el1, 0, 1) + && arm_el_is_aa64(env, arm_debug_target_el(env)) + && arm_generate_debug_exceptions(env); +} + +#include "exec/cpu-all.h" + +/* Bit usage in the TB flags field: bit 31 indicates whether we are + * in 32 or 64 bit mode. The meaning of the other bits depends on that. + * We put flags which are shared between 32 and 64 bit mode at the top + * of the word, and flags which apply to only one mode at the bottom. + */ +#define ARM_TBFLAG_AARCH64_STATE_SHIFT 31 +#define ARM_TBFLAG_AARCH64_STATE_MASK (1U << ARM_TBFLAG_AARCH64_STATE_SHIFT) +#define ARM_TBFLAG_MMUIDX_SHIFT 28 +#define ARM_TBFLAG_MMUIDX_MASK (0x7 << ARM_TBFLAG_MMUIDX_SHIFT) +#define ARM_TBFLAG_SS_ACTIVE_SHIFT 27 +#define ARM_TBFLAG_SS_ACTIVE_MASK (1 << ARM_TBFLAG_SS_ACTIVE_SHIFT) +#define ARM_TBFLAG_PSTATE_SS_SHIFT 26 +#define ARM_TBFLAG_PSTATE_SS_MASK (1 << ARM_TBFLAG_PSTATE_SS_SHIFT) +/* Target EL if we take a floating-point-disabled exception */ +#define ARM_TBFLAG_FPEXC_EL_SHIFT 24 +#define ARM_TBFLAG_FPEXC_EL_MASK (0x3 << ARM_TBFLAG_FPEXC_EL_SHIFT) + +/* Bit usage when in AArch32 state: */ +#define ARM_TBFLAG_THUMB_SHIFT 0 +#define ARM_TBFLAG_THUMB_MASK (1 << ARM_TBFLAG_THUMB_SHIFT) +#define ARM_TBFLAG_VECLEN_SHIFT 1 +#define ARM_TBFLAG_VECLEN_MASK (0x7 << ARM_TBFLAG_VECLEN_SHIFT) +#define ARM_TBFLAG_VECSTRIDE_SHIFT 4 +#define ARM_TBFLAG_VECSTRIDE_MASK (0x3 << ARM_TBFLAG_VECSTRIDE_SHIFT) +#define ARM_TBFLAG_VFPEN_SHIFT 7 +#define ARM_TBFLAG_VFPEN_MASK (1 << ARM_TBFLAG_VFPEN_SHIFT) +#define ARM_TBFLAG_CONDEXEC_SHIFT 8 +#define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT) +#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16 +#define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT) +/* We store the bottom two bits of the CPAR as TB flags and handle + * checks on the other bits at runtime + */ +#define ARM_TBFLAG_XSCALE_CPAR_SHIFT 17 +#define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT) +/* Indicates whether cp register reads and writes by guest code should access + * the secure or nonsecure bank of banked registers; note that this is not + * the same thing as the current security state of the processor! + */ +#define ARM_TBFLAG_NS_SHIFT 19 +#define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT) + +/* Bit usage when in AArch64 state: currently we have no A64 specific bits */ + +/* some convenience accessor macros */ +#define ARM_TBFLAG_AARCH64_STATE(F) \ + (((F) & ARM_TBFLAG_AARCH64_STATE_MASK) >> ARM_TBFLAG_AARCH64_STATE_SHIFT) +#define ARM_TBFLAG_MMUIDX(F) \ + (((F) & ARM_TBFLAG_MMUIDX_MASK) >> ARM_TBFLAG_MMUIDX_SHIFT) +#define ARM_TBFLAG_SS_ACTIVE(F) \ + (((F) & ARM_TBFLAG_SS_ACTIVE_MASK) >> ARM_TBFLAG_SS_ACTIVE_SHIFT) +#define ARM_TBFLAG_PSTATE_SS(F) \ + (((F) & ARM_TBFLAG_PSTATE_SS_MASK) >> ARM_TBFLAG_PSTATE_SS_SHIFT) +#define ARM_TBFLAG_FPEXC_EL(F) \ + (((F) & ARM_TBFLAG_FPEXC_EL_MASK) >> ARM_TBFLAG_FPEXC_EL_SHIFT) +#define ARM_TBFLAG_THUMB(F) \ + (((F) & ARM_TBFLAG_THUMB_MASK) >> ARM_TBFLAG_THUMB_SHIFT) +#define ARM_TBFLAG_VECLEN(F) \ + (((F) & ARM_TBFLAG_VECLEN_MASK) >> ARM_TBFLAG_VECLEN_SHIFT) +#define ARM_TBFLAG_VECSTRIDE(F) \ + (((F) & ARM_TBFLAG_VECSTRIDE_MASK) >> ARM_TBFLAG_VECSTRIDE_SHIFT) +#define ARM_TBFLAG_VFPEN(F) \ + (((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT) +#define ARM_TBFLAG_CONDEXEC(F) \ + (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT) +#define ARM_TBFLAG_BSWAP_CODE(F) \ + (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT) +#define ARM_TBFLAG_XSCALE_CPAR(F) \ + (((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT) +#define ARM_TBFLAG_NS(F) \ + (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT) + +/* Return the exception level to which FP-disabled exceptions should + * be taken, or 0 if FP is enabled. + */ +static inline int fp_exception_el(CPUARMState *env) +{ + int fpen; + int cur_el = arm_current_el(env); + + /* CPACR and the CPTR registers don't exist before v6, so FP is + * always accessible + */ + if (!arm_feature(env, ARM_FEATURE_V6)) { + return 0; + } + + /* The CPACR controls traps to EL1, or PL1 if we're 32 bit: + * 0, 2 : trap EL0 and EL1/PL1 accesses + * 1 : trap only EL0 accesses + * 3 : trap no accesses + */ + fpen = extract32(env->cp15.cpacr_el1, 20, 2); + switch (fpen) { + case 0: + case 2: + if (cur_el == 0 || cur_el == 1) { + /* Trap to PL1, which might be EL1 or EL3 */ + if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) { + return 3; + } + return 1; + } + if (cur_el == 3 && !is_a64(env)) { + /* Secure PL1 running at EL3 */ + return 3; + } + break; + case 1: + if (cur_el == 0) { + return 1; + } + break; + case 3: + break; + } + + /* For the CPTR registers we don't need to guard with an ARM_FEATURE + * check because zero bits in the registers mean "don't trap". + */ + + /* CPTR_EL2 : present in v7VE or v8 */ + if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1) + && !arm_is_secure_below_el3(env)) { + /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */ + return 2; + } + + /* CPTR_EL3 : present in v8 */ + if (extract32(env->cp15.cptr_el[3], 10, 1)) { + /* Trap all FP ops to EL3 */ + return 3; + } + + return 0; +} + +static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, + target_ulong *cs_base, int *flags) +{ + if (is_a64(env)) { + *pc = env->pc; + *flags = ARM_TBFLAG_AARCH64_STATE_MASK; + } else { + *pc = env->regs[15]; + *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT) + | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT) + | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT) + | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT) + | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT); + if (!(access_secure_reg(env))) { + *flags |= ARM_TBFLAG_NS_MASK; + } + if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30) + || arm_el_is_aa64(env, 1)) { + *flags |= ARM_TBFLAG_VFPEN_MASK; + } + *flags |= (extract32(env->cp15.c15_cpar, 0, 2) + << ARM_TBFLAG_XSCALE_CPAR_SHIFT); + } + + *flags |= (cpu_mmu_index(env, false) << ARM_TBFLAG_MMUIDX_SHIFT); + /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine + * states defined in the ARM ARM for software singlestep: + * SS_ACTIVE PSTATE.SS State + * 0 x Inactive (the TB flag for SS is always 0) + * 1 0 Active-pending + * 1 1 Active-not-pending + */ + if (arm_singlestep_active(env)) { + *flags |= ARM_TBFLAG_SS_ACTIVE_MASK; + if (is_a64(env)) { + if (env->pstate & PSTATE_SS) { + *flags |= ARM_TBFLAG_PSTATE_SS_MASK; + } + } else { + if (env->uncached_cpsr & PSTATE_SS) { + *flags |= ARM_TBFLAG_PSTATE_SS_MASK; + } + } + } + *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT; + + *cs_base = 0; +} + +#include "exec/exec-all.h" + +enum { + QEMU_PSCI_CONDUIT_DISABLED = 0, + QEMU_PSCI_CONDUIT_SMC = 1, + QEMU_PSCI_CONDUIT_HVC = 2, +}; + +#endif diff --git a/target-arm/helper.c b/target-arm/helper.c new file mode 100644 index 0000000000000..c615bd3f9874b --- /dev/null +++ b/target-arm/helper.c @@ -0,0 +1,8971 @@ +#include "cpu.h" +#include "internals.h" +#include "exec/gdbstub.h" +#include "exec/helper-proto.h" +#include "qemu/host-utils.h" +#include "sysemu/arch_init.h" +#include "sysemu/sysemu.h" +#include "qemu/bitops.h" +#include "qemu/crc32c.h" +#include "exec/cpu_ldst.h" +#include "arm_ldst.h" +#include /* For crc32 */ +#include "exec/semihost.h" + +#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ + +//#define DEBUG_ARM_HELPER +#ifdef DEBUG_ARM_HELPER + +// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out +#define DPRINTF(fmt, ...) \ + do { printf("ARM_HELPER: " fmt , ## __VA_ARGS__); \ + /* usleep(100); */ /* the usleep causes watchdogs :( */ \ + fflush(stdout); \ + } while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +static CompatGMutex helper_mmu_lock; + +#ifndef CONFIG_USER_ONLY +static bool get_phys_addr(CPUARMState *env, target_ulong address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, + target_ulong *page_size, uint32_t *fsr, + ARMMMUFaultInfo *fi); + +static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot, + target_ulong *page_size_ptr, uint32_t *fsr, + ARMMMUFaultInfo *fi); + +/* Definitions for the PMCCNTR and PMCR registers */ +#define PMCRD 0x8 +#define PMCRC 0x4 +#define PMCRE 0x1 +#endif + +static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) +{ + int nregs; + + /* VFP data registers are always little-endian. */ + nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; + if (reg < nregs) { + stfq_le_p(buf, env->vfp.regs[reg]); + return 8; + } + if (arm_feature(env, ARM_FEATURE_NEON)) { + /* Aliases for Q regs. */ + nregs += 16; + if (reg < nregs) { + stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]); + stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]); + return 16; + } + } + switch (reg - nregs) { + case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4; + case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4; + case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4; + } + return 0; +} + +static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) +{ + int nregs; + + nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; + if (reg < nregs) { + env->vfp.regs[reg] = ldfq_le_p(buf); + return 8; + } + if (arm_feature(env, ARM_FEATURE_NEON)) { + nregs += 16; + if (reg < nregs) { + env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf); + env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8); + return 16; + } + } + switch (reg - nregs) { + case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4; + case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4; + case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4; + } + return 0; +} + +static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) +{ + switch (reg) { + case 0 ... 31: + /* 128 bit FP register */ + stfq_le_p(buf, env->vfp.regs[reg * 2]); + stfq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]); + return 16; + case 32: + /* FPSR */ + stl_p(buf, vfp_get_fpsr(env)); + return 4; + case 33: + /* FPCR */ + stl_p(buf, vfp_get_fpcr(env)); + return 4; + default: + return 0; + } +} + +static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) +{ + switch (reg) { + case 0 ... 31: + /* 128 bit FP register */ + env->vfp.regs[reg * 2] = ldfq_le_p(buf); + env->vfp.regs[reg * 2 + 1] = ldfq_le_p(buf + 8); + return 16; + case 32: + /* FPSR */ + vfp_set_fpsr(env, ldl_p(buf)); + return 4; + case 33: + /* FPCR */ + vfp_set_fpcr(env, ldl_p(buf)); + return 4; + default: + return 0; + } +} + +static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + assert(ri->fieldoffset); + if (cpreg_field_is_64bit(ri)) { + return CPREG_FIELD64(env, ri); + } else { + return CPREG_FIELD32(env, ri); + } +} + +static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + assert(ri->fieldoffset); + if (cpreg_field_is_64bit(ri)) { + CPREG_FIELD64(env, ri) = value; + } else { + CPREG_FIELD32(env, ri) = value; + } +} + +static void *raw_ptr(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return (char *)env + ri->fieldoffset; +} + +uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Raw read of a coprocessor register (as needed for migration, etc). */ + if (ri->type & ARM_CP_CONST) { + return ri->resetvalue; + } else if (ri->raw_readfn) { + return ri->raw_readfn(env, ri); + } else if (ri->readfn) { + return ri->readfn(env, ri); + } else { + return raw_read(env, ri); + } +} + +static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t v) +{ + /* Raw write of a coprocessor register (as needed for migration, etc). + * Note that constant registers are treated as write-ignored; the + * caller should check for success by whether a readback gives the + * value written. + */ + if (ri->type & ARM_CP_CONST) { + return; + } else if (ri->raw_writefn) { + ri->raw_writefn(env, ri, v); + } else if (ri->writefn) { + ri->writefn(env, ri, v); + } else { + raw_write(env, ri, v); + } +} + +static bool raw_accessors_invalid(const ARMCPRegInfo *ri) +{ + /* Return true if the regdef would cause an assertion if you called + * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a + * program bug for it not to have the NO_RAW flag). + * NB that returning false here doesn't necessarily mean that calling + * read/write_raw_cp_reg() is safe, because we can't distinguish "has + * read/write access functions which are safe for raw use" from "has + * read/write access functions which have side effects but has forgotten + * to provide raw access functions". + * The tests here line up with the conditions in read/write_raw_cp_reg() + * and assertions in raw_read()/raw_write(). + */ + if ((ri->type & ARM_CP_CONST) || + ri->fieldoffset || + ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) { + return false; + } + return true; +} + +bool write_cpustate_to_list(ARMCPU *cpu) +{ + /* Write the coprocessor state from cpu->env to the (index,value) list. */ + int i; + bool ok = true; + + for (i = 0; i < cpu->cpreg_array_len; i++) { + uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]); + const ARMCPRegInfo *ri; + + ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); + if (!ri) { + ok = false; + continue; + } + if (ri->type & ARM_CP_NO_RAW) { + continue; + } + cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri); + } + return ok; +} + +bool write_list_to_cpustate(ARMCPU *cpu) +{ + int i; + bool ok = true; + + for (i = 0; i < cpu->cpreg_array_len; i++) { + uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]); + uint64_t v = cpu->cpreg_values[i]; + const ARMCPRegInfo *ri; + + ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); + if (!ri) { + ok = false; + continue; + } + if (ri->type & ARM_CP_NO_RAW) { + continue; + } + /* Write value and confirm it reads back as written + * (to catch read-only registers and partially read-only + * registers where the incoming migration value doesn't match) + */ + write_raw_cp_reg(&cpu->env, ri, v); + if (read_raw_cp_reg(&cpu->env, ri) != v) { + ok = false; + } + } + return ok; +} + +static void add_cpreg_to_list(gpointer key, gpointer opaque) +{ + ARMCPU *cpu = opaque; + uint64_t regidx; + const ARMCPRegInfo *ri; + + regidx = *(uint32_t *)key; + ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); + + if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { + cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx); + /* The value array need not be initialized at this point */ + cpu->cpreg_array_len++; + } +} + +static void count_cpreg(gpointer key, gpointer opaque) +{ + ARMCPU *cpu = opaque; + uint64_t regidx; + const ARMCPRegInfo *ri; + + regidx = *(uint32_t *)key; + ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); + + if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { + cpu->cpreg_array_len++; + } +} + +static gint cpreg_key_compare(gconstpointer a, gconstpointer b) +{ + uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a); + uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b); + + if (aidx > bidx) { + return 1; + } + if (aidx < bidx) { + return -1; + } + return 0; +} + +void init_cpreg_list(ARMCPU *cpu) +{ + /* Initialise the cpreg_tuples[] array based on the cp_regs hash. + * Note that we require cpreg_tuples[] to be sorted by key ID. + */ + GList *keys; + int arraylen; + + keys = g_hash_table_get_keys(cpu->cp_regs); + keys = g_list_sort(keys, cpreg_key_compare); + + cpu->cpreg_array_len = 0; + + g_list_foreach(keys, count_cpreg, cpu); + + arraylen = cpu->cpreg_array_len; + cpu->cpreg_indexes = g_new(uint64_t, arraylen); + cpu->cpreg_values = g_new(uint64_t, arraylen); + cpu->cpreg_vmstate_indexes = g_new(uint64_t, arraylen); + cpu->cpreg_vmstate_values = g_new(uint64_t, arraylen); + cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; + cpu->cpreg_array_len = 0; + + g_list_foreach(keys, add_cpreg_to_list, cpu); + + assert(cpu->cpreg_array_len == arraylen); + + g_list_free(keys); +} + +/* + * Some registers are not accessible if EL3.NS=0 and EL3 is using AArch32 but + * they are accessible when EL3 is using AArch64 regardless of EL3.NS. + * + * access_el3_aa32ns: Used to check AArch32 register views. + * access_el3_aa32ns_aa64any: Used to check both AArch32/64 register views. + */ +static CPAccessResult access_el3_aa32ns(CPUARMState *env, + const ARMCPRegInfo *ri) +{ + bool secure = arm_is_secure_below_el3(env); + + assert(!arm_el_is_aa64(env, 3)); + if (secure) { + return CP_ACCESS_TRAP_UNCATEGORIZED; + } + return CP_ACCESS_OK; +} + +static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env, + const ARMCPRegInfo *ri) +{ + if (!arm_el_is_aa64(env, 3)) { + return access_el3_aa32ns(env, ri); + } + return CP_ACCESS_OK; +} + +static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + raw_write(env, ri, value); + tlb_flush(CPU(cpu), 1); /* Flush TLB as domain not tracked in TLB */ +} + +static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + if (raw_read(env, ri) != value) { + /* Unlike real hardware the qemu TLB uses virtual addresses, + * not modified virtual addresses, so this causes a TLB flush. + */ + tlb_flush(CPU(cpu), 1); + raw_write(env, ri, value); + } +} + +static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_MPU) + && !extended_addresses_enabled(env)) { + /* For VMSA (when not using the LPAE long descriptor page table + * format) this register includes the ASID, so do a TLB flush. + * For PMSA it is purely a process ID and no action is needed. + */ + tlb_flush(CPU(cpu), 1); + } + raw_write(env, ri, value); +} + +static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate all (TLBIALL) */ + ARMCPU *cpu = arm_env_get_cpu(env); + + tlb_flush(CPU(cpu), 1); +} + +static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */ + ARMCPU *cpu = arm_env_get_cpu(env); + + tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK); +} + +static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by ASID (TLBIASID) */ + ARMCPU *cpu = arm_env_get_cpu(env); + + tlb_flush(CPU(cpu), value == 0); +} + +static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */ + ARMCPU *cpu = arm_env_get_cpu(env); + + tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK); +} + +/* IS variants of TLB operations must affect all cores */ +static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush(other_cs, 1); + } +} + +static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush(other_cs, value == 0); + } +} + +static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush_page(other_cs, value & TARGET_PAGE_MASK); + } +} + +static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush_page(other_cs, value & TARGET_PAGE_MASK); + } +} + +static const ARMCPRegInfo cp_reginfo[] = { + /* Define the secure and non-secure FCSE identifier CP registers + * separately because there is no secure bank in V8 (no _EL3). This allows + * the secure register to be properly reset and migrated. There is also no + * v8 EL1 version of the register so the non-secure instance stands alone. + */ + { .name = "FCSEIDR(NS)", + .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS, + .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_ns), + .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, + { .name = "FCSEIDR(S)", + .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_S, + .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s), + .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, + /* Define the secure and non-secure context identifier CP registers + * separately because there is no secure bank in V8 (no _EL3). This allows + * the secure register to be properly reset and migrated. In the + * non-secure case, the 32-bit register will have reset and migration + * disabled during registration as it is handled by the 64-bit instance. + */ + { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS, + .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]), + .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, + { .name = "CONTEXTIDR(S)", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, + .access = PL1_RW, .secure = ARM_CP_SECSTATE_S, + .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s), + .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo not_v8_cp_reginfo[] = { + /* NB: Some of these registers exist in v8 but with more precise + * definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]). + */ + /* MMU Domain access control / MPU write buffer control */ + { .name = "DACR", + .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY, + .access = PL1_RW, .resetvalue = 0, + .writefn = dacr_write, .raw_writefn = raw_write, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), + offsetoflow32(CPUARMState, cp15.dacr_ns) } }, + /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs. + * For v6 and v5, these mappings are overly broad. + */ + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 1, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 4, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 8, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, + /* Cache maintenance ops; some of this space may be overridden later. */ + { .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, + .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, + .type = ARM_CP_NOP | ARM_CP_OVERRIDE }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo not_v6_cp_reginfo[] = { + /* Not all pre-v6 cores implemented this WFI, so this is slightly + * over-broad. + */ + { .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_WFI }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo not_v7_cp_reginfo[] = { + /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which + * is UNPREDICTABLE; we choose to NOP as most implementations do). + */ + { .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_WFI }, + /* L1 cache lockdown. Not architectural in v6 and earlier but in practice + * implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and + * OMAPCP will override this space. + */ + { .name = "DLOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_data), + .resetvalue = 0 }, + { .name = "ILOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_insn), + .resetvalue = 0 }, + /* v6 doesn't have the cache ID registers but Linux reads them anyway */ + { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = 0 }, + /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR; + * implementing it as RAZ means the "debug architecture version" bits + * will read as a reserved value, which should cause Linux to not try + * to use the debug hardware. + */ + { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + /* MMU TLB control. Note that the wildcarding means we cover not just + * the unified TLB ops but also the dside/iside/inner-shareable variants. + */ + { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, + .type = ARM_CP_NO_RAW }, + { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, + .type = ARM_CP_NO_RAW }, + { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, + .type = ARM_CP_NO_RAW }, + { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, + .type = ARM_CP_NO_RAW }, + { .name = "PRRR", .cp = 15, .crn = 10, .crm = 2, + .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "NMRR", .cp = 15, .crn = 10, .crm = 2, + .opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP }, + REGINFO_SENTINEL +}; + +static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint32_t mask = 0; + + /* In ARMv8 most bits of CPACR_EL1 are RES0. */ + if (!arm_feature(env, ARM_FEATURE_V8)) { + /* ARMv7 defines bits for unimplemented coprocessors as RAZ/WI. + * ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP. + * TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell. + */ + if (arm_feature(env, ARM_FEATURE_VFP)) { + /* VFP coprocessor: cp10 & cp11 [23:20] */ + mask |= (1 << 31) | (1 << 30) | (0xf << 20); + + if (!arm_feature(env, ARM_FEATURE_NEON)) { + /* ASEDIS [31] bit is RAO/WI */ + value |= (1 << 31); + } + + /* VFPv3 and upwards with NEON implement 32 double precision + * registers (D0-D31). + */ + if (!arm_feature(env, ARM_FEATURE_NEON) || + !arm_feature(env, ARM_FEATURE_VFP3)) { + /* D32DIS [30] is RAO/WI if D16-31 are not implemented. */ + value |= (1 << 30); + } + } + value &= mask; + } + env->cp15.cpacr_el1 = value; +} + +static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + if (arm_feature(env, ARM_FEATURE_V8)) { + /* Check if CPACR accesses are to be trapped to EL2 */ + if (arm_current_el(env) == 1 && + (env->cp15.cptr_el[2] & CPTR_TCPAC) && !arm_is_secure(env)) { + return CP_ACCESS_TRAP_EL2; + /* Check if CPACR accesses are to be trapped to EL3 */ + } else if (arm_current_el(env) < 3 && + (env->cp15.cptr_el[3] & CPTR_TCPAC)) { + return CP_ACCESS_TRAP_EL3; + } + } + + return CP_ACCESS_OK; +} + +static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Check if CPTR accesses are set to trap to EL3 */ + if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) { + return CP_ACCESS_TRAP_EL3; + } + + return CP_ACCESS_OK; +} + +static const ARMCPRegInfo v6_cp_reginfo[] = { + /* prefetch by MVA in v6, NOP in v7 */ + { .name = "MVA_prefetch", + .cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + /* We need to break the TB after ISB to execute self-modifying code + * correctly and also to take any pending interrupts immediately. + * So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag. + */ + { .name = "ISB", .cp = 15, .crn = 7, .crm = 5, .opc1 = 0, .opc2 = 4, + .access = PL0_W, .type = ARM_CP_NO_RAW, .writefn = arm_cp_write_ignore }, + { .name = "DSB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 4, + .access = PL0_W, .type = ARM_CP_NOP }, + { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5, + .access = PL0_W, .type = ARM_CP_NOP }, + { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s), + offsetof(CPUARMState, cp15.ifar_ns) }, + .resetvalue = 0, }, + /* Watchpoint Fault Address Register : should actually only be present + * for 1136, 1176, 11MPCore. + */ + { .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, }, + { .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, + .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1), + .resetvalue = 0, .writefn = cpacr_write }, + REGINFO_SENTINEL +}; + +static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Performance monitor registers user accessibility is controlled + * by PMUSERENR. + */ + if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +#ifndef CONFIG_USER_ONLY + +static inline bool arm_ccnt_enabled(CPUARMState *env) +{ + /* This does not support checking PMCCFILTR_EL0 register */ + + if (!(env->cp15.c9_pmcr & PMCRE)) { + return false; + } + + return true; +} + +void pmccntr_sync(CPUARMState *env) +{ + uint64_t temp_ticks; + + temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); + + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + temp_ticks /= 64; + } + + if (arm_ccnt_enabled(env)) { + env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt; + } +} + +static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + pmccntr_sync(env); + + if (value & PMCRC) { + /* The counter has been reset */ + env->cp15.c15_ccnt = 0; + } + + /* only the DP, X, D and E bits are writable */ + env->cp15.c9_pmcr &= ~0x39; + env->cp15.c9_pmcr |= (value & 0x39); + + pmccntr_sync(env); +} + +static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint64_t total_ticks; + + if (!arm_ccnt_enabled(env)) { + /* Counter is disabled, do not change value */ + return env->cp15.c15_ccnt; + } + + total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); + + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + total_ticks /= 64; + } + return total_ticks - env->cp15.c15_ccnt; +} + +static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint64_t total_ticks; + + if (!arm_ccnt_enabled(env)) { + /* Counter is disabled, set the absolute value */ + env->cp15.c15_ccnt = value; + return; + } + + total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); + + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + total_ticks /= 64; + } + env->cp15.c15_ccnt = total_ticks - value; +} + +static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint64_t cur_val = pmccntr_read(env, NULL); + + pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value)); +} + +#else /* CONFIG_USER_ONLY */ + +void pmccntr_sync(CPUARMState *env) +{ +} + +#endif + +static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + pmccntr_sync(env); + env->cp15.pmccfiltr_el0 = value & 0x7E000000; + pmccntr_sync(env); +} + +static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + value &= (1 << 31); + env->cp15.c9_pmcnten |= value; +} + +static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + value &= (1 << 31); + env->cp15.c9_pmcnten &= ~value; +} + +static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c9_pmovsr &= ~value; +} + +static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c9_pmxevtyper = value & 0xff; +} + +static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c9_pmuserenr = value & 1; +} + +static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* We have no event counters so only the C bit can be changed */ + value &= (1 << 31); + env->cp15.c9_pminten |= value; +} + +static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + value &= (1 << 31); + env->cp15.c9_pminten &= ~value; +} + +static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Note that even though the AArch64 view of this register has bits + * [10:0] all RES0 we can only mask the bottom 5, to comply with the + * architectural requirements for bits which are RES0 only in some + * contexts. (ARMv8 would permit us to do no masking at all, but ARMv7 + * requires the bottom five bits to be RAZ/WI because they're UNK/SBZP.) + */ + raw_write(env, ri, value & ~0x1FULL); +} + +static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + /* We only mask off bits that are RES0 both for AArch64 and AArch32. + * For bits that vary between AArch32/64, code needs to check the + * current execution mode before directly using the feature bit. + */ + uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK; + + if (!arm_feature(env, ARM_FEATURE_EL2)) { + valid_mask &= ~SCR_HCE; + + /* On ARMv7, SMD (or SCD as it is called in v7) is only + * supported if EL2 exists. The bit is UNK/SBZP when + * EL2 is unavailable. In QEMU ARMv7, we force it to always zero + * when EL2 is unavailable. + * On ARMv8, this bit is always available. + */ + if (arm_feature(env, ARM_FEATURE_V7) && + !arm_feature(env, ARM_FEATURE_V8)) { + valid_mask &= ~SCR_SMD; + } + } + + /* Clear all-context RES0 bits. */ + value &= valid_mask; + raw_write(env, ri, value); +} + +static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + /* Acquire the CSSELR index from the bank corresponding to the CCSIDR + * bank + */ + uint32_t index = A32_BANKED_REG_GET(env, csselr, + ri->secure & ARM_CP_SECSTATE_S); + + return cpu->ccsidr[index]; +} + +static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + raw_write(env, ri, value & 0xf); +} + +static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + CPUState *cs = ENV_GET_CPU(env); + uint64_t ret = 0; + + if (cs->interrupt_request & CPU_INTERRUPT_HARD) { + ret |= CPSR_I; + } + if (cs->interrupt_request & CPU_INTERRUPT_FIQ) { + ret |= CPSR_F; + } + /* External aborts are not possible in QEMU so A bit is always clear */ + return ret; +} + +static const ARMCPRegInfo v7_cp_reginfo[] = { + /* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */ + { .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_NOP }, + /* Performance monitors are implementation defined in v7, + * but with an ARM recommended set of registers, which we + * follow (although we don't actually implement any counters) + * + * Performance registers fall into three categories: + * (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR) + * (b) RO in PL0 (ie UNDEF on write), RW in PL1 (PMUSERENR) + * (c) UNDEF in PL0 if PMUSERENR.EN==0, otherwise accessible (all others) + * For the cases controlled by PMUSERENR we must set .access to PL0_RW + * or PL0_RO as appropriate and then check PMUSERENR in the helper fn. + */ + { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), + .writefn = pmcntenset_write, + .accessfn = pmreg_access, + .raw_writefn = raw_write }, + { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1, + .access = PL0_RW, .accessfn = pmreg_access, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0, + .writefn = pmcntenset_write, .raw_writefn = raw_write }, + { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), + .accessfn = pmreg_access, + .writefn = pmcntenclr_write, + .type = ARM_CP_ALIAS }, + { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), + .writefn = pmcntenclr_write }, + { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3, + .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), + .accessfn = pmreg_access, + .writefn = pmovsr_write, + .raw_writefn = raw_write }, + /* Unimplemented so WI. */ + { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, + .access = PL0_W, .accessfn = pmreg_access, .type = ARM_CP_NOP }, + /* Since we don't implement any events, writing to PMSELR is UNPREDICTABLE. + * We choose to RAZ/WI. + */ + { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, + .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, + .accessfn = pmreg_access }, +#ifndef CONFIG_USER_ONLY + { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0, + .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO, + .readfn = pmccntr_read, .writefn = pmccntr_write32, + .accessfn = pmreg_access }, + { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .readfn = pmccntr_read, .writefn = pmccntr_write, }, +#endif + { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7, + .writefn = pmccfiltr_write, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), + .resetvalue = 0, }, + { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, + .access = PL0_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper), + .accessfn = pmreg_access, .writefn = pmxevtyper_write, + .raw_writefn = raw_write }, + /* Unimplemented, RAZ/WI. */ + { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, + .accessfn = pmreg_access }, + { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0, + .access = PL0_R | PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr), + .resetvalue = 0, + .writefn = pmuserenr_write, .raw_writefn = raw_write }, + { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .resetvalue = 0, + .writefn = pmintenset_write, .raw_writefn = raw_write }, + { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenclr_write, }, + { .name = "VBAR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .writefn = vbar_write, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s), + offsetof(CPUARMState, cp15.vbar_ns) }, + .resetvalue = 0 }, + { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, + .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW }, + { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0, + .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s), + offsetof(CPUARMState, cp15.csselr_ns) } }, + /* Auxiliary ID register: this actually has an IMPDEF value but for now + * just RAZ for all cores: + */ + { .name = "AIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + /* Auxiliary fault status registers: these also are IMPDEF, and we + * choose to RAZ/WI for all cores. + */ + { .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + /* MAIR can just read-as-written because we don't implement caches + * and so don't need to care about memory attributes. + */ + { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]), + .resetvalue = 0 }, + { .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]), + .resetvalue = 0 }, + /* For non-long-descriptor page tables these are PRRR and NMRR; + * regardless they still act as reads-as-written for QEMU. + */ + /* MAIR0/1 are defined separately from their 64-bit counterpart which + * allows them to assign the correct fieldoffset based on the endianness + * handled in the field definitions. + */ + { .name = "MAIR0", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s), + offsetof(CPUARMState, cp15.mair0_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "MAIR1", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s), + offsetof(CPUARMState, cp15.mair1_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read }, + /* 32 bit ITLB invalidates */ + { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, + { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, + /* 32 bit DTLB invalidates */ + { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, + { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, + /* 32 bit TLB invalidates */ + { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, + { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, + { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo v7mp_cp_reginfo[] = { + /* 32 bit TLB invalidates, Inner Shareable */ + { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write }, + { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write }, + { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, + .type = ARM_CP_NO_RAW, .access = PL1_W, + .writefn = tlbiasid_is_write }, + { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, + .type = ARM_CP_NO_RAW, .access = PL1_W, + .writefn = tlbimvaa_is_write }, + REGINFO_SENTINEL +}; + +static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + value &= 1; + env->teecr = value; +} + +static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + if (arm_current_el(env) == 0 && (env->teecr & 1)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +static const ARMCPRegInfo t2ee_cp_reginfo[] = { + { .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr), + .resetvalue = 0, + .writefn = teecr_write }, + { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0, + .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr), + .accessfn = teehbr_access, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo v6k_cp_reginfo[] = { + { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0, + .access = PL0_RW, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 }, + { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s), + offsetoflow32(CPUARMState, cp15.tpidrurw_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0, + .access = PL0_R|PL1_W, + .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]), + .resetvalue = 0}, + { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL0_R|PL1_W, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s), + offsetoflow32(CPUARMState, cp15.tpidruro_ns) }, + .resetfn = arm_cp_reset_ignore }, + { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 }, + { .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4, + .access = PL1_RW, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s), + offsetoflow32(CPUARMState, cp15.tpidrprw_ns) }, + .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +#ifndef CONFIG_USER_ONLY + +static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */ + if (arm_current_el(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx) +{ + unsigned int cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + + /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */ + if (cur_el == 0 && + !extract32(env->cp15.c14_cntkctl, timeridx, 1)) { + return CP_ACCESS_TRAP; + } + + if (arm_feature(env, ARM_FEATURE_EL2) && + timeridx == GTIMER_PHYS && !secure && cur_el < 2 && + !extract32(env->cp15.cnthctl_el2, 0, 1)) { + return CP_ACCESS_TRAP_EL2; + } + return CP_ACCESS_OK; +} + +static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx) +{ + unsigned int cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + + /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if + * EL0[PV]TEN is zero. + */ + if (cur_el == 0 && + !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) { + return CP_ACCESS_TRAP; + } + + if (arm_feature(env, ARM_FEATURE_EL2) && + timeridx == GTIMER_PHYS && !secure && cur_el < 2 && + !extract32(env->cp15.cnthctl_el2, 1, 1)) { + return CP_ACCESS_TRAP_EL2; + } + return CP_ACCESS_OK; +} + +static CPAccessResult gt_pct_access(CPUARMState *env, + const ARMCPRegInfo *ri) +{ + return gt_counter_access(env, GTIMER_PHYS); +} + +static CPAccessResult gt_vct_access(CPUARMState *env, + const ARMCPRegInfo *ri) +{ + return gt_counter_access(env, GTIMER_VIRT); +} + +static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_timer_access(env, GTIMER_PHYS); +} + +static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_timer_access(env, GTIMER_VIRT); +} + +static CPAccessResult gt_stimer_access(CPUARMState *env, + const ARMCPRegInfo *ri) +{ + /* The AArch64 register view of the secure physical timer is + * always accessible from EL3, and configurably accessible from + * Secure EL1. + */ + switch (arm_current_el(env)) { + case 1: + if (!arm_is_secure(env)) { + return CP_ACCESS_TRAP; + } + if (!(env->cp15.scr_el3 & SCR_ST)) { + return CP_ACCESS_TRAP_EL3; + } + return CP_ACCESS_OK; + case 0: + case 2: + return CP_ACCESS_TRAP; + case 3: + return CP_ACCESS_OK; + default: + g_assert_not_reached(); + } +} + +static uint64_t gt_get_countervalue(CPUARMState *env) +{ + return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE; +} + +static void gt_recalc_timer(ARMCPU *cpu, int timeridx) +{ + ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx]; + + if (gt->ctl & 1) { + /* Timer enabled: calculate and set current ISTATUS, irq, and + * reset timer to when ISTATUS next has to change + */ + uint64_t offset = timeridx == GTIMER_VIRT ? + cpu->env.cp15.cntvoff_el2 : 0; + uint64_t count = gt_get_countervalue(&cpu->env); + /* Note that this must be unsigned 64 bit arithmetic: */ + int istatus = count - offset >= gt->cval; + uint64_t nexttick; + + gt->ctl = deposit32(gt->ctl, 2, 1, istatus); + qemu_set_irq(cpu->gt_timer_outputs[timeridx], + (istatus && !(gt->ctl & 2))); + if (istatus) { + /* Next transition is when count rolls back over to zero */ + nexttick = UINT64_MAX; + } else { + /* Next transition is when we hit cval */ + nexttick = gt->cval + offset; + } + /* Note that the desired next expiry time might be beyond the + * signed-64-bit range of a QEMUTimer -- in this case we just + * set the timer for as far in the future as possible. When the + * timer expires we will reset the timer for any remaining period. + */ + if (nexttick > INT64_MAX / GTIMER_SCALE) { + nexttick = INT64_MAX / GTIMER_SCALE; + } + timer_mod(cpu->gt_timer[timeridx], nexttick); + } else { + /* Timer disabled: ISTATUS and timer output always clear */ + gt->ctl &= ~4; + qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0); + timer_del(cpu->gt_timer[timeridx]); + } +} + +static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri, + int timeridx) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + timer_del(cpu->gt_timer[timeridx]); +} + +static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_get_countervalue(env); +} + +static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_get_countervalue(env) - env->cp15.cntvoff_el2; +} + +static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, + int timeridx, + uint64_t value) +{ + env->cp15.c14_timer[timeridx].cval = value; + gt_recalc_timer(arm_env_get_cpu(env), timeridx); +} + +static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri, + int timeridx) +{ + uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0; + + return (uint32_t)(env->cp15.c14_timer[timeridx].cval - + (gt_get_countervalue(env) - offset)); +} + +static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, + int timeridx, + uint64_t value) +{ + uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0; + + env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset + + sextract64(value, 0, 32); + gt_recalc_timer(arm_env_get_cpu(env), timeridx); +} + +static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, + int timeridx, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint32_t oldval = env->cp15.c14_timer[timeridx].ctl; + + env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value); + if ((oldval ^ value) & 1) { + /* Enable toggled */ + gt_recalc_timer(cpu, timeridx); + } else if ((oldval ^ value) & 2) { + /* IMASK toggled: don't need to recalculate, + * just set the interrupt line based on ISTATUS + */ + qemu_set_irq(cpu->gt_timer_outputs[timeridx], + (oldval & 4) && !(value & 2)); + } +} + +static void gt_phys_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + gt_timer_reset(env, ri, GTIMER_PHYS); +} + +static void gt_phys_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_cval_write(env, ri, GTIMER_PHYS, value); +} + +static uint64_t gt_phys_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_tval_read(env, ri, GTIMER_PHYS); +} + +static void gt_phys_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_tval_write(env, ri, GTIMER_PHYS, value); +} + +static void gt_phys_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_ctl_write(env, ri, GTIMER_PHYS, value); +} + +static void gt_virt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + gt_timer_reset(env, ri, GTIMER_VIRT); +} + +static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_cval_write(env, ri, GTIMER_VIRT, value); +} + +static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_tval_read(env, ri, GTIMER_VIRT); +} + +static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_tval_write(env, ri, GTIMER_VIRT, value); +} + +static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_ctl_write(env, ri, GTIMER_VIRT, value); +} + +static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + raw_write(env, ri, value); + gt_recalc_timer(cpu, GTIMER_VIRT); +} + +static void gt_hyp_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + gt_timer_reset(env, ri, GTIMER_HYP); +} + +static void gt_hyp_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_cval_write(env, ri, GTIMER_HYP, value); +} + +static uint64_t gt_hyp_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_tval_read(env, ri, GTIMER_HYP); +} + +static void gt_hyp_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_tval_write(env, ri, GTIMER_HYP, value); +} + +static void gt_hyp_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_ctl_write(env, ri, GTIMER_HYP, value); +} + +static void gt_sec_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + gt_timer_reset(env, ri, GTIMER_SEC); +} + +static void gt_sec_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_cval_write(env, ri, GTIMER_SEC, value); +} + +static uint64_t gt_sec_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return gt_tval_read(env, ri, GTIMER_SEC); +} + +static void gt_sec_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_tval_write(env, ri, GTIMER_SEC, value); +} + +static void gt_sec_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + gt_ctl_write(env, ri, GTIMER_SEC, value); +} + +void arm_gt_ptimer_cb(void *opaque) +{ + ARMCPU *cpu = opaque; + + gt_recalc_timer(cpu, GTIMER_PHYS); +} + +void arm_gt_vtimer_cb(void *opaque) +{ + ARMCPU *cpu = opaque; + + gt_recalc_timer(cpu, GTIMER_VIRT); +} + +void arm_gt_htimer_cb(void *opaque) +{ + ARMCPU *cpu = opaque; + + gt_recalc_timer(cpu, GTIMER_HYP); +} + +void arm_gt_stimer_cb(void *opaque) +{ + ARMCPU *cpu = opaque; + + gt_recalc_timer(cpu, GTIMER_SEC); +} + +static const ARMCPRegInfo generic_timer_cp_reginfo[] = { + /* Note that CNTFRQ is purely reads-as-written for the benefit + * of software; writing it doesn't actually change the timer frequency. + * Our reset value matches the fixed frequency we implement the timer at. + */ + { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_ALIAS, + .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq), + }, + { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0, + .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq), + .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE, + }, + /* overall control: mostly access permissions */ + { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl), + .resetvalue = 0, + }, + /* per-timer control */ + { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1, + .secure = ARM_CP_SECSTATE_NS, + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .fieldoffset = offsetoflow32(CPUARMState, + cp15.c14_timer[GTIMER_PHYS].ctl), + .writefn = gt_phys_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CTL(S)", + .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1, + .secure = ARM_CP_SECSTATE_S, + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .fieldoffset = offsetoflow32(CPUARMState, + cp15.c14_timer[GTIMER_SEC].ctl), + .writefn = gt_sec_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1, + .type = ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl), + .resetvalue = 0, + .writefn = gt_phys_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1, + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, + .fieldoffset = offsetoflow32(CPUARMState, + cp15.c14_timer[GTIMER_VIRT].ctl), + .writefn = gt_virt_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1, + .type = ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl), + .resetvalue = 0, + .writefn = gt_virt_ctl_write, .raw_writefn = raw_write, + }, + /* TimerValue views: a 32 bit downcounting view of the underlying state */ + { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0, + .secure = ARM_CP_SECSTATE_NS, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write, + }, + { .name = "CNTP_TVAL(S)", + .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0, + .secure = ARM_CP_SECSTATE_S, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, + .readfn = gt_sec_tval_read, .writefn = gt_sec_tval_write, + }, + { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_ptimer_access, .resetfn = gt_phys_timer_reset, + .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write, + }, + { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, + .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write, + }, + { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, + .accessfn = gt_vtimer_access, .resetfn = gt_virt_timer_reset, + .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write, + }, + /* The counter itself */ + { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_pct_access, + .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore, + }, + { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1, + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_pct_access, .readfn = gt_cnt_read, + }, + { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1, + .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_vct_access, + .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore, + }, + { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2, + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read, + }, + /* Comparison value, indicating when the timer goes off */ + { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2, + .secure = ARM_CP_SECSTATE_NS, + .access = PL1_RW | PL0_R, + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), + .accessfn = gt_ptimer_access, + .writefn = gt_phys_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CVAL(S)", .cp = 15, .crm = 14, .opc1 = 2, + .secure = ARM_CP_SECSTATE_S, + .access = PL1_RW | PL0_R, + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), + .accessfn = gt_ptimer_access, + .writefn = gt_sec_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2, + .access = PL1_RW | PL0_R, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), + .resetvalue = 0, .accessfn = gt_ptimer_access, + .writefn = gt_phys_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3, + .access = PL1_RW | PL0_R, + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), + .accessfn = gt_vtimer_access, + .writefn = gt_virt_cval_write, .raw_writefn = raw_write, + }, + { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2, + .access = PL1_RW | PL0_R, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), + .resetvalue = 0, .accessfn = gt_vtimer_access, + .writefn = gt_virt_cval_write, .raw_writefn = raw_write, + }, + /* Secure timer -- this is actually restricted to only EL3 + * and configurably Secure-EL1 via the accessfn. + */ + { .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW, + .accessfn = gt_stimer_access, + .readfn = gt_sec_tval_read, + .writefn = gt_sec_tval_write, + .resetfn = gt_sec_timer_reset, + }, + { .name = "CNTPS_CTL_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 1, + .type = ARM_CP_IO, .access = PL1_RW, + .accessfn = gt_stimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl), + .resetvalue = 0, + .writefn = gt_sec_ctl_write, .raw_writefn = raw_write, + }, + { .name = "CNTPS_CVAL_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 2, + .type = ARM_CP_IO, .access = PL1_RW, + .accessfn = gt_stimer_access, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), + .writefn = gt_sec_cval_write, .raw_writefn = raw_write, + }, + REGINFO_SENTINEL +}; + +#else +/* In user-mode none of the generic timer registers are accessible, + * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs, + * so instead just don't register any of them. + */ +static const ARMCPRegInfo generic_timer_cp_reginfo[] = { + REGINFO_SENTINEL +}; + +#endif + +static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + if (arm_feature(env, ARM_FEATURE_LPAE)) { + raw_write(env, ri, value); + } else if (arm_feature(env, ARM_FEATURE_V7)) { + raw_write(env, ri, value & 0xfffff6ff); + } else { + raw_write(env, ri, value & 0xfffff1ff); + } +} + +#ifndef CONFIG_USER_ONLY +/* get_phys_addr() isn't present for user-mode-only targets */ + +static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + if (ri->opc2 & 4) { + /* The ATS12NSO* operations must trap to EL3 if executed in + * Secure EL1 (which can only happen if EL3 is AArch64). + * They are simply UNDEF if executed from NS EL1. + * They function normally from EL2 or EL3. + */ + if (arm_current_el(env) == 1) { + if (arm_is_secure_below_el3(env)) { + return CP_ACCESS_TRAP_UNCATEGORIZED_EL3; + } + return CP_ACCESS_TRAP_UNCATEGORIZED; + } + } + return CP_ACCESS_OK; +} + +static uint64_t do_ats_write(CPUARMState *env, uint64_t value, + int access_type, ARMMMUIdx mmu_idx) +{ + hwaddr phys_addr; + target_ulong page_size; + int prot; + uint32_t fsr; + bool ret; + uint64_t par64; + MemTxAttrs attrs = {}; + ARMMMUFaultInfo fi = {}; + + ret = get_phys_addr(env, value, access_type, mmu_idx, + &phys_addr, &attrs, &prot, &page_size, &fsr, &fi); + if (extended_addresses_enabled(env)) { + /* fsr is a DFSR/IFSR value for the long descriptor + * translation table format, but with WnR always clear. + * Convert it to a 64-bit PAR. + */ + par64 = (1 << 11); /* LPAE bit always set */ + if (!ret) { + par64 |= phys_addr & ~0xfffULL; + if (!attrs.secure) { + par64 |= (1 << 9); /* NS */ + } + /* We don't set the ATTR or SH fields in the PAR. */ + } else { + par64 |= 1; /* F */ + par64 |= (fsr & 0x3f) << 1; /* FS */ + /* Note that S2WLK and FSTAGE are always zero, because we don't + * implement virtualization and therefore there can't be a stage 2 + * fault. + */ + } + } else { + /* fsr is a DFSR/IFSR value for the short descriptor + * translation table format (with WnR always clear). + * Convert it to a 32-bit PAR. + */ + if (!ret) { + /* We do not set any attribute bits in the PAR */ + if (page_size == (1 << 24) + && arm_feature(env, ARM_FEATURE_V7)) { + par64 = (phys_addr & 0xff000000) | (1 << 1); + } else { + par64 = phys_addr & 0xfffff000; + } + if (!attrs.secure) { + par64 |= (1 << 9); /* NS */ + } + } else { + par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) | + ((fsr & 0xf) << 1) | 1; + } + } + return par64; +} + +static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + int access_type = ri->opc2 & 1; + uint64_t par64; + ARMMMUIdx mmu_idx; + int el = arm_current_el(env); + bool secure = arm_is_secure_below_el3(env); + + switch (ri->opc2 & 6) { + case 0: + /* stage 1 current state PL1: ATS1CPR, ATS1CPW */ + switch (el) { + case 3: + mmu_idx = ARMMMUIdx_S1E3; + break; + case 2: + mmu_idx = ARMMMUIdx_S1NSE1; + break; + case 1: + mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S1NSE1; + break; + default: + g_assert_not_reached(); + } + break; + case 2: + /* stage 1 current state PL0: ATS1CUR, ATS1CUW */ + switch (el) { + case 3: + mmu_idx = ARMMMUIdx_S1SE0; + break; + case 2: + mmu_idx = ARMMMUIdx_S1NSE0; + break; + case 1: + mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S1NSE0; + break; + default: + g_assert_not_reached(); + } + break; + case 4: + /* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */ + mmu_idx = ARMMMUIdx_S12NSE1; + break; + case 6: + /* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */ + mmu_idx = ARMMMUIdx_S12NSE0; + break; + default: + g_assert_not_reached(); + } + + par64 = do_ats_write(env, value, access_type, mmu_idx); + + A32_BANKED_CURRENT_REG_SET(env, par, par64); +} + +static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + int access_type = ri->opc2 & 1; + uint64_t par64; + + par64 = do_ats_write(env, value, access_type, ARMMMUIdx_S2NS); + + A32_BANKED_CURRENT_REG_SET(env, par, par64); +} + +static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + int access_type = ri->opc2 & 1; + ARMMMUIdx mmu_idx; + int secure = arm_is_secure_below_el3(env); + + switch (ri->opc2 & 6) { + case 0: + switch (ri->opc1) { + case 0: /* AT S1E1R, AT S1E1W */ + mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S1NSE1; + break; + case 4: /* AT S1E2R, AT S1E2W */ + mmu_idx = ARMMMUIdx_S1E2; + break; + case 6: /* AT S1E3R, AT S1E3W */ + mmu_idx = ARMMMUIdx_S1E3; + break; + default: + g_assert_not_reached(); + } + break; + case 2: /* AT S1E0R, AT S1E0W */ + mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S1NSE0; + break; + case 4: /* AT S12E1R, AT S12E1W */ + mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S12NSE1; + break; + case 6: /* AT S12E0R, AT S12E0W */ + mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S12NSE0; + break; + default: + g_assert_not_reached(); + } + + env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx); +} +#endif + +static const ARMCPRegInfo vapa_cp_reginfo[] = { + { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s), + offsetoflow32(CPUARMState, cp15.par_ns) }, + .writefn = par_write }, +#ifndef CONFIG_USER_ONLY + /* This underdecoding is safe because the reginfo is NO_RAW. */ + { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_W, .accessfn = ats_access, + .writefn = ats_write, .type = ARM_CP_NO_RAW }, +#endif + REGINFO_SENTINEL +}; + +/* Return basic MPU access permission bits. */ +static uint32_t simple_mpu_ap_bits(uint32_t val) +{ + uint32_t ret; + uint32_t mask; + int i; + ret = 0; + mask = 3; + for (i = 0; i < 16; i += 2) { + ret |= (val >> i) & mask; + mask <<= 2; + } + return ret; +} + +/* Pad basic MPU access permission bits to extended format. */ +static uint32_t extended_mpu_ap_bits(uint32_t val) +{ + uint32_t ret; + uint32_t mask; + int i; + ret = 0; + mask = 3; + for (i = 0; i < 16; i += 2) { + ret |= (val & mask) << i; + mask <<= 2; + } + return ret; +} + +static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.pmsav5_data_ap = extended_mpu_ap_bits(value); +} + +static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return simple_mpu_ap_bits(env->cp15.pmsav5_data_ap); +} + +static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.pmsav5_insn_ap = extended_mpu_ap_bits(value); +} + +static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return simple_mpu_ap_bits(env->cp15.pmsav5_insn_ap); +} + +static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); + + if (!u32p) { + return 0; + } + + u32p += env->cp15.c6_rgnr; + return *u32p; +} + +static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); + + if (!u32p) { + return; + } + + u32p += env->cp15.c6_rgnr; + tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ + *u32p = value; +} + +static void pmsav7_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); + + if (!u32p) { + return; + } + + memset(u32p, 0, sizeof(*u32p) * cpu->pmsav7_dregion); +} + +static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint32_t nrgs = cpu->pmsav7_dregion; + + if (value >= nrgs) { + qemu_log_mask(LOG_GUEST_ERROR, + "PMSAv7 RGNR write >= # supported regions, %" PRIu32 + " > %" PRIu32 "\n", (uint32_t)value, nrgs); + return; + } + + raw_write(env, ri, value); +} + +static const ARMCPRegInfo pmsav7_cp_reginfo[] = { + { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), + .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, + { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.drsr), + .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, + { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4, + .access = PL1_RW, .type = ARM_CP_NO_RAW, + .fieldoffset = offsetof(CPUARMState, pmsav7.dracr), + .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, + { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c6_rgnr), + .writefn = pmsav7_rgnr_write }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo pmsav5_cp_reginfo[] = { + { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), + .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, }, + { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), + .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, }, + { .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), + .resetvalue = 0, }, + { .name = "INSN_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), + .resetvalue = 0, }, + { .name = "DCACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c2_data), .resetvalue = 0, }, + { .name = "ICACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, }, + /* Protection region base and size registers */ + { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) }, + { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) }, + { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) }, + { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) }, + { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) }, + { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) }, + { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) }, + { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0, + .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) }, + REGINFO_SENTINEL +}; + +static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + TCR *tcr = raw_ptr(env, ri); + int maskshift = extract32(value, 0, 3); + + if (!arm_feature(env, ARM_FEATURE_V8)) { + if (arm_feature(env, ARM_FEATURE_LPAE) && (value & TTBCR_EAE)) { + /* Pre ARMv8 bits [21:19], [15:14] and [6:3] are UNK/SBZP when + * using Long-desciptor translation table format */ + value &= ~((7 << 19) | (3 << 14) | (0xf << 3)); + } else if (arm_feature(env, ARM_FEATURE_EL3)) { + /* In an implementation that includes the Security Extensions + * TTBCR has additional fields PD0 [4] and PD1 [5] for + * Short-descriptor translation table format. + */ + value &= TTBCR_PD1 | TTBCR_PD0 | TTBCR_N; + } else { + value &= TTBCR_N; + } + } + + /* Update the masks corresponding to the TCR bank being written + * Note that we always calculate mask and base_mask, but + * they are only used for short-descriptor tables (ie if EAE is 0); + * for long-descriptor tables the TCR fields are used differently + * and the mask and base_mask values are meaningless. + */ + tcr->raw_tcr = value; + tcr->mask = ~(((uint32_t)0xffffffffu) >> maskshift); + tcr->base_mask = ~((uint32_t)0x3fffu >> maskshift); +} + +static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + if (arm_feature(env, ARM_FEATURE_LPAE)) { + /* With LPAE the TTBCR could result in a change of ASID + * via the TTBCR.A1 bit, so do a TLB flush. + */ + tlb_flush(CPU(cpu), 1); + } + vmsa_ttbcr_raw_write(env, ri, value); +} + +static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + TCR *tcr = raw_ptr(env, ri); + + /* Reset both the TCR as well as the masks corresponding to the bank of + * the TCR being reset. + */ + tcr->raw_tcr = 0; + tcr->mask = 0; + tcr->base_mask = 0xffffc000u; +} + +static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + TCR *tcr = raw_ptr(env, ri); + + /* For AArch64 the A1 bit could result in a change of ASID, so TLB flush. */ + tlb_flush(CPU(cpu), 1); + tcr->raw_tcr = value; +} + +static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* 64 bit accesses to the TTBRs can change the ASID and so we + * must flush the TLB. + */ + if (cpreg_field_is_64bit(ri)) { + ARMCPU *cpu = arm_env_get_cpu(env); + + tlb_flush(CPU(cpu), 1); + } + raw_write(env, ri, value); +} + +static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + /* Accesses to VTTBR may change the VMID so we must flush the TLB. */ + if (raw_read(env, ri) != value) { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, + ARMMMUIdx_S2NS, -1); + raw_write(env, ri, value); + } +} + +static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = { + { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s), + offsetoflow32(CPUARMState, cp15.dfsr_ns) }, }, + { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .resetvalue = 0, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s), + offsetoflow32(CPUARMState, cp15.ifsr_ns) } }, + { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s), + offsetof(CPUARMState, cp15.dfar_ns) } }, + { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]), + .resetvalue = 0, }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo vmsa_cp_reginfo[] = { + { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, }, + { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), + offsetof(CPUARMState, cp15.ttbr0_ns) } }, + { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1, + .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), + offsetof(CPUARMState, cp15.ttbr1_ns) } }, + { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .writefn = vmsa_tcr_el1_write, + .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) }, + { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write, + .raw_writefn = vmsa_ttbcr_raw_write, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]), + offsetoflow32(CPUARMState, cp15.tcr_el[1])} }, + REGINFO_SENTINEL +}; + +static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c15_ticonfig = value & 0xe7; + /* The OS_TYPE bit in this register changes the reported CPUID! */ + env->cp15.c0_cpuid = (value & (1 << 5)) ? + ARM_CPUID_TI915T : ARM_CPUID_TI925T; +} + +static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c15_threadid = value & 0xffff; +} + +static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Wait-for-interrupt (deprecated) */ + cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT); +} + +static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* On OMAP there are registers indicating the max/min index of dcache lines + * containing a dirty line; cache flush operations have to reset these. + */ + env->cp15.c15_i_max = 0x000; + env->cp15.c15_i_min = 0xff0; +} + +static const ARMCPRegInfo omap_cp_reginfo[] = { + { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE, + .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]), + .resetvalue = 0, }, + { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0, + .writefn = omap_ticonfig_write }, + { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, }, + { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0xff0, + .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) }, + { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0, + .writefn = omap_threadid_write }, + { .name = "TI925T_STATUS", .cp = 15, .crn = 15, + .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW, + .type = ARM_CP_NO_RAW, + .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, }, + /* TODO: Peripheral port remap register: + * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller + * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff), + * when MMU is off. + */ + { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, + .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, + .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW, + .writefn = omap_cachemaint_write }, + { .name = "C9", .cp = 15, .crn = 9, + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, + .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->cp15.c15_cpar = value & 0x3fff; +} + +static const ARMCPRegInfo xscale_cp_reginfo[] = { + { .name = "XSCALE_CPAR", + .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0, + .writefn = xscale_cpar_write, }, + { .name = "XSCALE_AUXCR", + .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr), + .resetvalue = 0, }, + /* XScale specific cache-lockdown: since we have no cache we NOP these + * and hope the guest does not really rely on cache behaviour. + */ + { .name = "XSCALE_LOCK_ICACHE_LINE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "XSCALE_UNLOCK_ICACHE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "XSCALE_DCACHE_LOCK", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NOP }, + { .name = "XSCALE_UNLOCK_DCACHE", + .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo dummy_c15_cp_reginfo[] = { + /* RAZ/WI the whole crn=15 space, when we don't have a more specific + * implementation of this implementation-defined space. + * Ideally this should eventually disappear in favour of actually + * implementing the correct behaviour for all cores. + */ + { .name = "C15_IMPDEF", .cp = 15, .crn = 15, + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, + .access = PL1_RW, + .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE, + .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = { + /* Cache status: RAZ because we have no cache so it's always clean */ + { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = { + /* We never have a a block transfer operation in progress */ + { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = 0 }, + /* The cache ops themselves: these all NOP for QEMU */ + { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0, + .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0, + .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0, + .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1, + .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2, + .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + { .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0, + .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = { + /* The cache test-and-clean instructions always return (1 << 30) + * to indicate that there are no dirty cache lines. + */ + { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = (1 << 30) }, + { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3, + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, + .resetvalue = (1 << 30) }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo strongarm_cp_reginfo[] = { + /* Ignore ReadBuffer accesses */ + { .name = "C9_READBUFFER", .cp = 15, .crn = 9, + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, + .access = PL1_RW, .resetvalue = 0, + .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW }, + REGINFO_SENTINEL +}; + +static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + unsigned int cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + + if (arm_feature(&cpu->env, ARM_FEATURE_EL2) && !secure && cur_el == 1) { + return env->cp15.vpidr_el2; + } + return raw_read(env, ri); +} + +static uint64_t mpidr_read_val(CPUARMState *env) +{ + ARMCPU *cpu = ARM_CPU(arm_env_get_cpu(env)); + uint64_t mpidr = cpu->mp_affinity; + + if (arm_feature(env, ARM_FEATURE_V7MP)) { + mpidr |= (1U << 31); + /* Cores which are uniprocessor (non-coherent) + * but still implement the MP extensions set + * bit 30. (For instance, Cortex-R5). + */ + if (cpu->mp_is_up) { + mpidr |= (1u << 30); + } + } + return mpidr; +} + +static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + unsigned int cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + + if (arm_feature(env, ARM_FEATURE_EL2) && !secure && cur_el == 1) { + return env->cp15.vmpidr_el2; + } + return mpidr_read_val(env); +} + +static const ARMCPRegInfo mpidr_cp_reginfo[] = { + { .name = "MPIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5, + .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo lpae_cp_reginfo[] = { + /* NOP AMAIR0/1 */ + { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + /* AMAIR1 is mapped to AMAIR_EL1[63:32] */ + { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0, + .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s), + offsetof(CPUARMState, cp15.par_ns)} }, + { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0, + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), + offsetof(CPUARMState, cp15.ttbr0_ns) }, + .writefn = vmsa_ttbr_write, }, + { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1, + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), + offsetof(CPUARMState, cp15.ttbr1_ns) }, + .writefn = vmsa_ttbr_write, }, + REGINFO_SENTINEL +}; + +static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return vfp_get_fpcr(env); +} + +static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + vfp_set_fpcr(env, value); +} + +static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return vfp_get_fpsr(env); +} + +static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + vfp_set_fpsr(env, value); +} + +static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->daif = value & PSTATE_DAIF; +} + +static CPAccessResult aa64_cacheop_access(CPUARMState *env, + const ARMCPRegInfo *ri) +{ + /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless + * SCTLR_EL1.UCI is set. + */ + if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCI)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions + * Page D4-1736 (DDI0487A.b) + */ + +static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + if (arm_is_secure_below_el3(env)) { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + } else { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); + } +} + +static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + bool sec = arm_is_secure_below_el3(env); + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + if (sec) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + } else { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, -1); + } + } +} + +static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Note that the 'ALL' scope must invalidate both stage 1 and + * stage 2 translations, whereas most other scopes only invalidate + * stage 1 translations. + */ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + if (arm_is_secure_below_el3(env)) { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + } else { + if (arm_feature(env, ARM_FEATURE_EL2)) { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, + ARMMMUIdx_S2NS, -1); + } else { + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); + } + } +} + +static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1); +} + +static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E3, -1); +} + +static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Note that the 'ALL' scope must invalidate both stage 1 and + * stage 2 translations, whereas most other scopes only invalidate + * stage 1 translations. + */ + bool sec = arm_is_secure_below_el3(env); + bool has_el2 = arm_feature(env, ARM_FEATURE_EL2); + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + if (sec) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); + } else if (has_el2) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1); + } else { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, -1); + } + } +} + +static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1); + } +} + +static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + + CPU_FOREACH(other_cs) { + tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E3, -1); + } +} + +static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by VA, EL1&0 (AArch64 version). + * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1, + * since we don't support flush-for-specific-ASID-only or + * flush-last-level-only. + */ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + if (arm_is_secure_below_el3(env)) { + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1SE1, + ARMMMUIdx_S1SE0, -1); + } else { + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, -1); + } +} + +static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by VA, EL2 + * Currently handles both VAE2 and VALE2, since we don't support + * flush-last-level-only. + */ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1E2, -1); +} + +static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by VA, EL3 + * Currently handles both VAE3 and VALE3, since we don't support + * flush-last-level-only. + */ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1E3, -1); +} + +static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + bool sec = arm_is_secure_below_el3(env); + CPUState *other_cs; + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + CPU_FOREACH(other_cs) { + if (sec) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1SE1, + ARMMMUIdx_S1SE0, -1); + } else { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S12NSE1, + ARMMMUIdx_S12NSE0, -1); + } + } +} + +static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + CPU_FOREACH(other_cs) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); + } +} + +static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + CPU_FOREACH(other_cs) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E3, -1); + } +} + +static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Invalidate by IPA. This has to invalidate any structures that + * contain only stage 2 translation information, but does not need + * to apply to structures that contain combined stage 1 and stage 2 + * translation information. + * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero. + */ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + uint64_t pageaddr; + + if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { + return; + } + + pageaddr = sextract64(value << 12, 0, 48); + + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1); +} + +static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *other_cs; + uint64_t pageaddr; + + if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { + return; + } + + pageaddr = sextract64(value << 12, 0, 48); + + CPU_FOREACH(other_cs) { + tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1); + } +} + +static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* We don't implement EL2, so the only control on DC ZVA is the + * bit in the SCTLR which can prohibit access for EL0. + */ + if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_DZE)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int dzp_bit = 1 << 4; + + /* DZP indicates whether DC ZVA access is allowed */ + if (aa64_zva_access(env, NULL) == CP_ACCESS_OK) { + dzp_bit = 0; + } + return cpu->dcz_blocksize | dzp_bit; +} + +static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + if (!(env->pstate & PSTATE_SP)) { + /* Access to SP_EL0 is undefined if it's being used as + * the stack pointer. + */ + return CP_ACCESS_TRAP_UNCATEGORIZED; + } + return CP_ACCESS_OK; +} + +static uint64_t spsel_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pstate & PSTATE_SP; +} + +static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val) +{ + update_spsel(env, val); +} + +static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + if (raw_read(env, ri) == value) { + /* Skip the TLB flush if nothing actually changed; Linux likes + * to do a lot of pointless SCTLR writes. + */ + return; + } + + raw_write(env, ri, value); + /* ??? Lots of these bits are not implemented. */ + /* This may enable/disable the MMU, so do a TLB flush. */ + tlb_flush(CPU(cpu), 1); +} + +static const ARMCPRegInfo v8_cp_reginfo[] = { + /* Minimal set of EL0-visible registers. This will need to be expanded + * significantly for system emulation of AArch64 CPUs. + */ + { .name = "NZCV", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2, + .access = PL0_RW, .type = ARM_CP_NZCV }, + { .name = "DAIF", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2, + .type = ARM_CP_NO_RAW, + .access = PL0_RW, .accessfn = aa64_daif_access, + .fieldoffset = offsetof(CPUARMState, daif), + .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore }, + { .name = "FPCR", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4, + .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write }, + { .name = "FPSR", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4, + .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write }, + { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0, + .access = PL0_R, .type = ARM_CP_NO_RAW, + .readfn = aa64_dczid_read }, + { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_DC_ZVA, +#ifndef CONFIG_USER_ONLY + /* Avoid overhead of an access check that always passes in user-mode */ + .accessfn = aa64_zva_access, +#endif + }, + { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2, + .access = PL1_R, .type = ARM_CP_CURRENTEL }, + /* Cache ops: all NOPs since we don't emulate caches */ + { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "DC_ISW", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_CSW", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NOP }, + { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1, + .access = PL0_W, .type = ARM_CP_NOP, + .accessfn = aa64_cacheop_access }, + { .name = "DC_CISW", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NOP }, + /* TLBI operations */ + { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1is_write }, + { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1is_write }, + { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1is_write }, + { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1_write }, + { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vmalle1_write }, + { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae1_write }, + { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1is_write }, + { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1is_write }, + { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1is_write }, + { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1is_write }, + { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1_write }, + { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1_write }, + { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1_write }, + { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle1is_write }, +#ifndef CONFIG_USER_ONLY + /* 64 bit address translation operations */ + { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7, + .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + /* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */ + { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.par_el[1]), + .writefn = par_write }, +#endif + /* TLB invalidate last level of translation table walk */ + { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write }, + { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, + .type = ARM_CP_NO_RAW, .access = PL1_W, + .writefn = tlbimvaa_is_write }, + { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, + { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, + /* 32 bit cache operations */ + { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1, + .type = ARM_CP_NOP, .access = PL1_W }, + { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, + .type = ARM_CP_NOP, .access = PL1_W }, + /* MMU Domain access control / MPU write buffer control */ + { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0, + .access = PL1_RW, .resetvalue = 0, + .writefn = dacr_write, .raw_writefn = raw_write, + .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), + offsetoflow32(CPUARMState, cp15.dacr_ns) } }, + { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, elr_el[1]) }, + { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) }, + /* We rely on the access checks not allowing the guest to write to the + * state field when SPSel indicates that it's being used as the stack + * pointer. + */ + { .name = "SP_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0, + .access = PL1_RW, .accessfn = sp_el0_access, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, sp_el[0]) }, + { .name = "SP_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, sp_el[1]) }, + { .name = "SPSel", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0, + .type = ARM_CP_NO_RAW, + .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write }, + REGINFO_SENTINEL +}; + +/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */ +static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = { + { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, + .access = PL2_RW, + .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, + { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_NO_RAW, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL2_RW, + .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, + { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, + .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, + .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "VTTBR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 6, .crm = 2, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + uint64_t valid_mask = HCR_MASK; + + if (arm_feature(env, ARM_FEATURE_EL3)) { + valid_mask &= ~HCR_HCD; + } else { + valid_mask &= ~HCR_TSC; + } + + /* Clear RES0 bits. */ + value &= valid_mask; + + /* These bits change the MMU setup: + * HCR_VM enables stage 2 translation + * HCR_PTW forbids certain page-table setups + * HCR_DC Disables stage1 and enables stage2 translation + */ + if ((raw_read(env, ri) ^ value) & (HCR_VM | HCR_PTW | HCR_DC)) { + tlb_flush(CPU(cpu), 1); + } + raw_write(env, ri, value); +} + +static const ARMCPRegInfo el2_cp_reginfo[] = { + { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2), + .writefn = hcr_write }, + { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0, + .access = PL2_RW, .resetvalue = 0, + .writefn = dacr_write, .raw_writefn = raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) }, + { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, elr_el[2]) }, + { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) }, + { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) }, + { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) }, + { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) }, + { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) }, + { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) }, + { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) }, + { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) }, + { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, + .access = PL2_RW, .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]), + .resetvalue = 0 }, + { .name = "SP_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 1, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, sp_el[2]) }, + { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]) }, + { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]), + .resetvalue = 0 }, + { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, + .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) }, + { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + /* HAMAIR1 is mapped to AMAIR_EL2[63:32] */ + { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, + .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2, + .access = PL2_RW, .writefn = vmsa_tcr_el1_write, + .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) }, + { .name = "VTCR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, + { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, + .access = PL2_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, + { .name = "VTTBR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 6, .crm = 2, + .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2), + .writefn = vttbr_write }, + { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, + .access = PL2_RW, .writefn = vttbr_write, + .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) }, + { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write, + .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) }, + { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) }, + { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, + { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, + { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbi_aa64_alle2_write }, + { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbi_aa64_vae2_write }, + { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae2_write }, + { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle2is_write }, + { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbi_aa64_vae2is_write }, + { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae2is_write }, +#ifndef CONFIG_USER_ONLY + /* Unlike the other EL2-related AT operations, these must + * UNDEF from EL3 if EL2 is not implemented, which is why we + * define them here rather than with the rest of the AT ops. + */ + { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL2_W, .accessfn = at_s1e2_access, + .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL2_W, .accessfn = at_s1e2_access, + .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, + /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE + * if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3 + * with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose + * to behave as if SCR.NS was 1. + */ + { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, + .access = PL2_W, + .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, + { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, + .access = PL2_W, + .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, + { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, + /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the + * reset values as IMPDEF. We choose to reset to 3 to comply with + * both ARMv7 and ARMv8. + */ + .access = PL2_RW, .resetvalue = 3, + .fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) }, + { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3, + .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0, + .writefn = gt_cntvoff_write, + .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) }, + { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14, + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO, + .writefn = gt_cntvoff_write, + .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) }, + { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), + .type = ARM_CP_IO, .access = PL2_RW, + .writefn = gt_hyp_cval_write, .raw_writefn = raw_write }, + { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), + .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_IO, + .writefn = gt_hyp_cval_write, .raw_writefn = raw_write }, + { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0, + .type = ARM_CP_IO, .access = PL2_RW, + .resetfn = gt_hyp_timer_reset, + .readfn = gt_hyp_tval_read, .writefn = gt_hyp_tval_write }, + { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH, + .type = ARM_CP_IO, + .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl), + .resetvalue = 0, + .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write }, +#endif + /* The only field of MDCR_EL2 that has a defined architectural reset value + * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we + * don't impelment any PMU event counters, so using zero as a reset + * value for MDCR_EL2 is okay + */ + { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL2_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), }, + { .name = "HPFAR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) }, + { .name = "HPFAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, + .access = PL2_RW, + .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo el3_cp_reginfo[] = { + { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3), + .resetvalue = 0, .writefn = scr_write }, + { .name = "SCR", .type = ARM_CP_ALIAS, + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3), + .writefn = scr_write }, + { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.sder) }, + { .name = "SDER", + .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) }, + /* TODO: Implement NSACR trapping of secure EL1 accesses to EL3 */ + { .name = "NSACR", .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL3_W | PL1_R, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.nsacr) }, + { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, + .access = PL3_RW, .writefn = vbar_write, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.mvbar) }, + { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, /* reset handled by AArch32 view */ + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write, + .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]) }, + { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0, + .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) }, + { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2, + .access = PL3_RW, .writefn = vmsa_tcr_el1_write, + .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, + .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) }, + { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1, + .access = PL3_RW, + .fieldoffset = offsetof(CPUARMState, elr_el[3]) }, + { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) }, + { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) }, + { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, + .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0, + .access = PL3_RW, + .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) }, + { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0, + .access = PL3_RW, .writefn = vbar_write, + .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]), + .resetvalue = 0 }, + { .name = "CPTR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 2, + .access = PL3_RW, .accessfn = cptr_access, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[3]) }, + { .name = "TPIDR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 2, + .access = PL3_RW, .resetvalue = 0, + .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[3]) }, + { .name = "AMAIR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 3, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR0_EL3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 0, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "AFSR1_EL3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 1, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle3is_write }, + { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3is_write }, + { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3is_write }, + { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_alle3_write }, + { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3_write }, + { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5, + .access = PL3_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_vae3_write }, + REGINFO_SENTINEL +}; + +static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64, + * but the AArch32 CTR has its own reginfo struct) + */ + if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) { + return CP_ACCESS_TRAP; + } + return CP_ACCESS_OK; +} + +static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Writes to OSLAR_EL1 may update the OS lock status, which can be + * read via a bit in OSLSR_EL1. + */ + int oslock; + + if (ri->state == ARM_CP_STATE_AA32) { + oslock = (value == 0xC5ACCE55); + } else { + oslock = value & 1; + } + + env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock); +} + +static const ARMCPRegInfo debug_cp_reginfo[] = { + /* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped + * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1; + * unlike DBGDRAR it is never accessible from EL0. + * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64 + * accessor. + */ + { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */ + { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), + .resetvalue = 0 }, + /* MDCCSR_EL0, aka DBGDSCRint. This is a read-only mirror of MDSCR_EL1. + * We don't implement the configurable EL0 access. + */ + { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, + .type = ARM_CP_ALIAS, + .access = PL1_R, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), }, + { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_NO_RAW, + .writefn = oslar_write }, + { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4, + .access = PL1_R, .resetvalue = 10, + .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) }, + /* Dummy OSDLR_EL1: 32-bit Linux will read this */ + { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, + .access = PL1_RW, .type = ARM_CP_NOP }, + /* Dummy DBGVCR: Linux wants to clear this on startup, but we don't + * implement vector catch debug events yet. + */ + { .name = "DBGVCR", + .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL1_RW, .type = ARM_CP_NOP }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { + /* 64 bit access versions of the (dummy) debug registers */ + { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, + { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, + .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + +void hw_watchpoint_update(ARMCPU *cpu, int n) +{ + CPUARMState *env = &cpu->env; + vaddr len = 0; + vaddr wvr = env->cp15.dbgwvr[n]; + uint64_t wcr = env->cp15.dbgwcr[n]; + int mask; + int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; + + if (env->cpu_watchpoint[n]) { + cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]); + env->cpu_watchpoint[n] = NULL; + } + + if (!extract64(wcr, 0, 1)) { + /* E bit clear : watchpoint disabled */ + return; + } + + switch (extract64(wcr, 3, 2)) { + case 0: + /* LSC 00 is reserved and must behave as if the wp is disabled */ + return; + case 1: + flags |= BP_MEM_READ; + break; + case 2: + flags |= BP_MEM_WRITE; + break; + case 3: + flags |= BP_MEM_ACCESS; + break; + } + + /* Attempts to use both MASK and BAS fields simultaneously are + * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, + * thus generating a watchpoint for every byte in the masked region. + */ + mask = extract64(wcr, 24, 4); + if (mask == 1 || mask == 2) { + /* Reserved values of MASK; we must act as if the mask value was + * some non-reserved value, or as if the watchpoint were disabled. + * We choose the latter. + */ + return; + } else if (mask) { + /* Watchpoint covers an aligned area up to 2GB in size */ + len = 1ULL << mask; + /* If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE + * whether the watchpoint fires when the unmasked bits match; we opt + * to generate the exceptions. + */ + wvr &= ~(len - 1); + } else { + /* Watchpoint covers bytes defined by the byte address select bits */ + int bas = extract64(wcr, 5, 8); + int basstart; + + if (bas == 0) { + /* This must act as if the watchpoint is disabled */ + return; + } + + if (extract64(wvr, 2, 1)) { + /* Deprecated case of an only 4-aligned address. BAS[7:4] are + * ignored, and BAS[3:0] define which bytes to watch. + */ + bas &= 0xf; + } + /* The BAS bits are supposed to be programmed to indicate a contiguous + * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether + * we fire for each byte in the word/doubleword addressed by the WVR. + * We choose to ignore any non-zero bits after the first range of 1s. + */ + basstart = ctz32(bas); + len = cto32(bas >> basstart); + wvr += basstart; + } + + cpu_watchpoint_insert(CPU(cpu), wvr, len, flags, + &env->cpu_watchpoint[n]); +} + +void hw_watchpoint_update_all(ARMCPU *cpu) +{ + int i; + CPUARMState *env = &cpu->env; + + /* Completely clear out existing QEMU watchpoints and our array, to + * avoid possible stale entries following migration load. + */ + cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); + memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint)); + + for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) { + hw_watchpoint_update(cpu, i); + } +} + +static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int i = ri->crm; + + /* Bits [63:49] are hardwired to the value of bit [48]; that is, the + * register reads and behaves as if values written are sign extended. + * Bits [1:0] are RES0. + */ + value = sextract64(value, 0, 49) & ~3ULL; + + raw_write(env, ri, value); + hw_watchpoint_update(cpu, i); +} + +static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int i = ri->crm; + + raw_write(env, ri, value); + hw_watchpoint_update(cpu, i); +} + +void hw_breakpoint_update(ARMCPU *cpu, int n) +{ + CPUARMState *env = &cpu->env; + uint64_t bvr = env->cp15.dbgbvr[n]; + uint64_t bcr = env->cp15.dbgbcr[n]; + vaddr addr; + int bt; + int flags = BP_CPU; + + if (env->cpu_breakpoint[n]) { + cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]); + env->cpu_breakpoint[n] = NULL; + } + + if (!extract64(bcr, 0, 1)) { + /* E bit clear : watchpoint disabled */ + return; + } + + bt = extract64(bcr, 20, 4); + + switch (bt) { + case 4: /* unlinked address mismatch (reserved if AArch64) */ + case 5: /* linked address mismatch (reserved if AArch64) */ + qemu_log_mask(LOG_UNIMP, + "arm: address mismatch breakpoint types not implemented"); + return; + case 0: /* unlinked address match */ + case 1: /* linked address match */ + { + /* Bits [63:49] are hardwired to the value of bit [48]; that is, + * we behave as if the register was sign extended. Bits [1:0] are + * RES0. The BAS field is used to allow setting breakpoints on 16 + * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether + * a bp will fire if the addresses covered by the bp and the addresses + * covered by the insn overlap but the insn doesn't start at the + * start of the bp address range. We choose to require the insn and + * the bp to have the same address. The constraints on writing to + * BAS enforced in dbgbcr_write mean we have only four cases: + * 0b0000 => no breakpoint + * 0b0011 => breakpoint on addr + * 0b1100 => breakpoint on addr + 2 + * 0b1111 => breakpoint on addr + * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). + */ + int bas = extract64(bcr, 5, 4); + addr = sextract64(bvr, 0, 49) & ~3ULL; + if (bas == 0) { + return; + } + if (bas == 0xc) { + addr += 2; + } + break; + } + case 2: /* unlinked context ID match */ + case 8: /* unlinked VMID match (reserved if no EL2) */ + case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ + qemu_log_mask(LOG_UNIMP, + "arm: unlinked context breakpoint types not implemented"); + return; + case 9: /* linked VMID match (reserved if no EL2) */ + case 11: /* linked context ID and VMID match (reserved if no EL2) */ + case 3: /* linked context ID match */ + default: + /* We must generate no events for Linked context matches (unless + * they are linked to by some other bp/wp, which is handled in + * updates for the linking bp/wp). We choose to also generate no events + * for reserved values. + */ + return; + } + + cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]); +} + +void hw_breakpoint_update_all(ARMCPU *cpu) +{ + int i; + CPUARMState *env = &cpu->env; + + /* Completely clear out existing QEMU breakpoints and our array, to + * avoid possible stale entries following migration load. + */ + cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); + memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint)); + + for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) { + hw_breakpoint_update(cpu, i); + } +} + +static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int i = ri->crm; + + raw_write(env, ri, value); + hw_breakpoint_update(cpu, i); +} + +static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int i = ri->crm; + + /* BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only + * copy of BAS[0]. + */ + value = deposit64(value, 6, 1, extract64(value, 5, 1)); + value = deposit64(value, 8, 1, extract64(value, 7, 1)); + + raw_write(env, ri, value); + hw_breakpoint_update(cpu, i); +} + +static void define_debug_regs(ARMCPU *cpu) +{ + /* Define v7 and v8 architectural debug registers. + * These are just dummy implementations for now. + */ + int i; + int wrps, brps, ctx_cmps; + ARMCPRegInfo dbgdidr = { + .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr, + }; + + /* Note that all these register fields hold "number of Xs minus 1". */ + brps = extract32(cpu->dbgdidr, 24, 4); + wrps = extract32(cpu->dbgdidr, 28, 4); + ctx_cmps = extract32(cpu->dbgdidr, 20, 4); + + assert(ctx_cmps <= brps); + + /* The DBGDIDR and ID_AA64DFR0_EL1 define various properties + * of the debug registers such as number of breakpoints; + * check that if they both exist then they agree. + */ + if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps); + assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps); + assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps); + } + + define_one_arm_cp_reg(cpu, &dbgdidr); + define_arm_cp_regs(cpu, debug_cp_reginfo); + + if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) { + define_arm_cp_regs(cpu, debug_lpae_cp_reginfo); + } + + for (i = 0; i < brps + 1; i++) { + ARMCPRegInfo dbgregs[] = { + { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]), + .writefn = dbgbvr_write, .raw_writefn = raw_write + }, + { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]), + .writefn = dbgbcr_write, .raw_writefn = raw_write + }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, dbgregs); + } + + for (i = 0; i < wrps + 1; i++) { + ARMCPRegInfo dbgregs[] = { + { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]), + .writefn = dbgwvr_write, .raw_writefn = raw_write + }, + { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH, + .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]), + .writefn = dbgwcr_write, .raw_writefn = raw_write + }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, dbgregs); + } +} + +void register_cp_regs_for_features(ARMCPU *cpu) +{ + /* Register all the coprocessor registers based on feature bits */ + CPUARMState *env = &cpu->env; + if (arm_feature(env, ARM_FEATURE_M)) { + /* M profile has no coprocessor registers */ + return; + } + + define_arm_cp_regs(cpu, cp_reginfo); + if (!arm_feature(env, ARM_FEATURE_V8)) { + /* Must go early as it is full of wildcards that may be + * overridden by later definitions. + */ + define_arm_cp_regs(cpu, not_v8_cp_reginfo); + } + + if (arm_feature(env, ARM_FEATURE_V6)) { + /* The ID registers all have impdef reset values */ + ARMCPRegInfo v6_idregs[] = { + { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_pfr0 }, + { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_pfr1 }, + { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_dfr0 }, + { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_afr0 }, + { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr0 }, + { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr1 }, + { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr2 }, + { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_mmfr3 }, + { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_isar0 }, + { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_isar1 }, + { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_isar2 }, + { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_isar3 }, + { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_isar4 }, + { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_isar5 }, + /* 6..7 are as yet unallocated and must RAZ */ + { .name = "ID_ISAR6", .cp = 15, .crn = 0, .crm = 2, + .opc1 = 0, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ID_ISAR7", .cp = 15, .crn = 0, .crm = 2, + .opc1 = 0, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = 0 }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, v6_idregs); + define_arm_cp_regs(cpu, v6_cp_reginfo); + } else { + define_arm_cp_regs(cpu, not_v6_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_V6K)) { + define_arm_cp_regs(cpu, v6k_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_V7MP) && + !arm_feature(env, ARM_FEATURE_MPU)) { + define_arm_cp_regs(cpu, v7mp_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_V7)) { + /* v7 performance monitor control register: same implementor + * field as main ID register, and we implement only the cycle + * count register. + */ +#ifndef CONFIG_USER_ONLY + ARMCPRegInfo pmcr = { + .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, + .access = PL0_RW, + .type = ARM_CP_IO | ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr), + .accessfn = pmreg_access, .writefn = pmcr_write, + .raw_writefn = raw_write, + }; + ARMCPRegInfo pmcr64 = { + .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr), + .resetvalue = cpu->midr & 0xff000000, + .writefn = pmcr_write, .raw_writefn = raw_write, + }; + define_one_arm_cp_reg(cpu, &pmcr); + define_one_arm_cp_reg(cpu, &pmcr64); +#endif + ARMCPRegInfo clidr = { + .name = "CLIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr + }; + define_one_arm_cp_reg(cpu, &clidr); + define_arm_cp_regs(cpu, v7_cp_reginfo); + define_debug_regs(cpu); + } else { + define_arm_cp_regs(cpu, not_v7_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_V8)) { + /* AArch64 ID registers, which all have impdef reset values */ + ARMCPRegInfo v8_idregs[] = { + { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64pfr0 }, + { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64pfr1}, + { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + /* We mask out the PMUVer field, because we don't currently + * implement the PMU. Not advertising it prevents the guest + * from trying to use it and getting UNDEFs on registers we + * don't implement. + */ + .resetvalue = cpu->id_aa64dfr0 & ~0xf00 }, + { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64dfr1 }, + { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64afr0 }, + { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64afr1 }, + { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64isar0 }, + { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64isar1 }, + { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64mmfr0 }, + { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64mmfr1 }, + { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->mvfr0 }, + { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->mvfr1 }, + { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->mvfr2 }, + REGINFO_SENTINEL + }; + /* RVBAR_EL1 is only implemented if EL1 is the highest EL */ + if (!arm_feature(env, ARM_FEATURE_EL3) && + !arm_feature(env, ARM_FEATURE_EL2)) { + ARMCPRegInfo rvbar = { + .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, + .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar + }; + define_one_arm_cp_reg(cpu, &rvbar); + } + define_arm_cp_regs(cpu, v8_idregs); + define_arm_cp_regs(cpu, v8_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_EL2)) { + uint64_t vmpidr_def = mpidr_read_val(env); + ARMCPRegInfo vpidr_regs[] = { + { .name = "VPIDR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, + { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL2_RW, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, + { .name = "VMPIDR", .state = ARM_CP_STATE_AA32, + .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, + .access = PL2_RW, .accessfn = access_el3_aa32ns, + .resetvalue = vmpidr_def, + .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) }, + { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, + .access = PL2_RW, + .resetvalue = vmpidr_def, + .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, vpidr_regs); + define_arm_cp_regs(cpu, el2_cp_reginfo); + /* RVBAR_EL2 is only implemented if EL2 is the highest EL */ + if (!arm_feature(env, ARM_FEATURE_EL3)) { + ARMCPRegInfo rvbar = { + .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1, + .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar + }; + define_one_arm_cp_reg(cpu, &rvbar); + } + } else { + /* If EL2 is missing but higher ELs are enabled, we need to + * register the no_el2 reginfos. + */ + if (arm_feature(env, ARM_FEATURE_EL3)) { + /* When EL3 exists but not EL2, VPIDR and VMPIDR take the value + * of MIDR_EL1 and MPIDR_EL1. + */ + ARMCPRegInfo vpidr_regs[] = { + { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_CONST, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, + { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, + .type = ARM_CP_NO_RAW, + .writefn = arm_cp_write_ignore, .readfn = mpidr_read }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, vpidr_regs); + define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo); + } + } + if (arm_feature(env, ARM_FEATURE_EL3)) { + define_arm_cp_regs(cpu, el3_cp_reginfo); + ARMCPRegInfo rvbar = { + .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1, + .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar + }; + define_one_arm_cp_reg(cpu, &rvbar); + } + if (arm_feature(env, ARM_FEATURE_MPU)) { + if (arm_feature(env, ARM_FEATURE_V6)) { + /* PMSAv6 not implemented */ + assert(arm_feature(env, ARM_FEATURE_V7)); + define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); + define_arm_cp_regs(cpu, pmsav7_cp_reginfo); + } else { + define_arm_cp_regs(cpu, pmsav5_cp_reginfo); + } + } else { + define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); + define_arm_cp_regs(cpu, vmsa_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { + define_arm_cp_regs(cpu, t2ee_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) { + define_arm_cp_regs(cpu, generic_timer_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_VAPA)) { + define_arm_cp_regs(cpu, vapa_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_CACHE_TEST_CLEAN)) { + define_arm_cp_regs(cpu, cache_test_clean_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_CACHE_DIRTY_REG)) { + define_arm_cp_regs(cpu, cache_dirty_status_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_CACHE_BLOCK_OPS)) { + define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_OMAPCP)) { + define_arm_cp_regs(cpu, omap_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_STRONGARM)) { + define_arm_cp_regs(cpu, strongarm_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_XSCALE)) { + define_arm_cp_regs(cpu, xscale_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) { + define_arm_cp_regs(cpu, dummy_c15_cp_reginfo); + } + if (arm_feature(env, ARM_FEATURE_LPAE)) { + define_arm_cp_regs(cpu, lpae_cp_reginfo); + } + /* Slightly awkwardly, the OMAP and StrongARM cores need all of + * cp15 crn=0 to be writes-ignored, whereas for other cores they should + * be read-only (ie write causes UNDEF exception). + */ + { + ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = { + /* Pre-v8 MIDR space. + * Note that the MIDR isn't a simple constant register because + * of the TI925 behaviour where writes to another register can + * cause the MIDR value to change. + * + * Unimplemented registers in the c15 0 0 0 space default to + * MIDR. Define MIDR first as this entire space, then CTR, TCMTR + * and friends override accordingly. + */ + { .name = "MIDR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .resetvalue = cpu->midr, + .writefn = arm_cp_write_ignore, .raw_writefn = raw_write, + .readfn = midr_read, + .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), + .type = ARM_CP_OVERRIDE }, + /* crn = 0 op1 = 0 crm = 3..7 : currently unassigned; we RAZ. */ + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "DUMMY", + .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL + }; + ARMCPRegInfo id_v8_midr_cp_reginfo[] = { + { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0, + .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), + .readfn = midr_read }, + /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */ + { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST, + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_R, .resetvalue = cpu->midr }, + { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST, + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7, + .access = PL1_R, .resetvalue = cpu->midr }, + { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr }, + REGINFO_SENTINEL + }; + ARMCPRegInfo id_cp_reginfo[] = { + /* These are common to v8 and pre-v8 */ + { .name = "CTR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr }, + { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0, + .access = PL0_R, .accessfn = ctr_el0_access, + .type = ARM_CP_CONST, .resetvalue = cpu->ctr }, + /* TCMTR and TLBTR exist in v8 but have no 64-bit versions */ + { .name = "TCMTR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL + }; + /* TLBTR is specific to VMSA */ + ARMCPRegInfo id_tlbtr_reginfo = { + .name = "TLBTR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, + .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0, + }; + /* MPUIR is specific to PMSA V6+ */ + ARMCPRegInfo id_mpuir_reginfo = { + .name = "MPUIR", + .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmsav7_dregion << 8 + }; + ARMCPRegInfo crn0_wi_reginfo = { + .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, + .type = ARM_CP_NOP | ARM_CP_OVERRIDE + }; + if (arm_feature(env, ARM_FEATURE_OMAPCP) || + arm_feature(env, ARM_FEATURE_STRONGARM)) { + ARMCPRegInfo *r; + /* Register the blanket "writes ignored" value first to cover the + * whole space. Then update the specific ID registers to allow write + * access, so that they ignore writes rather than causing them to + * UNDEF. + */ + define_one_arm_cp_reg(cpu, &crn0_wi_reginfo); + for (r = id_pre_v8_midr_cp_reginfo; + r->type != ARM_CP_SENTINEL; r++) { + r->access = PL1_RW; + } + for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) { + r->access = PL1_RW; + } + id_tlbtr_reginfo.access = PL1_RW; + id_tlbtr_reginfo.access = PL1_RW; + } + if (arm_feature(env, ARM_FEATURE_V8)) { + define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo); + } else { + define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo); + } + define_arm_cp_regs(cpu, id_cp_reginfo); + if (!arm_feature(env, ARM_FEATURE_MPU)) { + define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); + } else if (arm_feature(env, ARM_FEATURE_V7)) { + define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); + } + } + + if (arm_feature(env, ARM_FEATURE_MPIDR)) { + define_arm_cp_regs(cpu, mpidr_cp_reginfo); + } + + if (arm_feature(env, ARM_FEATURE_AUXCR)) { + ARMCPRegInfo auxcr_reginfo[] = { + { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1, + .access = PL1_RW, .type = ARM_CP_CONST, + .resetvalue = cpu->reset_auxcr }, + { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1, + .access = PL2_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1, + .access = PL3_RW, .type = ARM_CP_CONST, + .resetvalue = 0 }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, auxcr_reginfo); + } + + if (arm_feature(env, ARM_FEATURE_CBAR)) { + if (arm_feature(env, ARM_FEATURE_AARCH64)) { + /* 32 bit view is [31:18] 0...0 [43:32]. */ + uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18) + | extract64(cpu->reset_cbar, 32, 12); + ARMCPRegInfo cbar_reginfo[] = { + { .name = "CBAR", + .type = ARM_CP_CONST, + .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0, + .access = PL1_R, .resetvalue = cpu->reset_cbar }, + { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_CONST, + .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0, + .access = PL1_R, .resetvalue = cbar32 }, + REGINFO_SENTINEL + }; + /* We don't implement a r/w 64 bit CBAR currently */ + assert(arm_feature(env, ARM_FEATURE_CBAR_RO)); + define_arm_cp_regs(cpu, cbar_reginfo); + } else { + ARMCPRegInfo cbar = { + .name = "CBAR", + .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0, + .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar, + .fieldoffset = offsetof(CPUARMState, + cp15.c15_config_base_address) + }; + if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { + cbar.access = PL1_R; + cbar.fieldoffset = 0; + cbar.type = ARM_CP_CONST; + } + define_one_arm_cp_reg(cpu, &cbar); + } + } + + /* Generic registers whose values depend on the implementation */ + { + ARMCPRegInfo sctlr = { + .name = "SCTLR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, + .access = PL1_RW, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s), + offsetof(CPUARMState, cp15.sctlr_ns) }, + .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr, + .raw_writefn = raw_write, + }; + if (arm_feature(env, ARM_FEATURE_XSCALE)) { + /* Normally we would always end the TB on an SCTLR write, but Linux + * arch/arm/mach-pxa/sleep.S expects two instructions following + * an MMU enable to execute from cache. Imitate this behaviour. + */ + sctlr.type |= ARM_CP_SUPPRESS_TB_END; + } + define_one_arm_cp_reg(cpu, &sctlr); + } +} + +ARMCPU *cpu_arm_init(const char *cpu_model) +{ + return ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model)); +} + +void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) +{ + CPUState *cs = CPU(cpu); + CPUARMState *env = &cpu->env; + + if (arm_feature(env, ARM_FEATURE_AARCH64)) { + gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg, + aarch64_fpu_gdb_set_reg, + 34, "aarch64-fpu.xml", 0); + } else if (arm_feature(env, ARM_FEATURE_NEON)) { + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, + 51, "arm-neon.xml", 0); + } else if (arm_feature(env, ARM_FEATURE_VFP3)) { + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, + 35, "arm-vfp3.xml", 0); + } else if (arm_feature(env, ARM_FEATURE_VFP)) { + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, + 19, "arm-vfp.xml", 0); + } +} + +/* Sort alphabetically by type name, except for "any". */ +static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + const char *name_a, *name_b; + + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) { + return 1; + } else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) { + return -1; + } else { + return strcmp(name_a, name_b); + } +} + +static void arm_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + CPUListState *s = user_data; + const char *typename; + char *name; + + typename = object_class_get_name(oc); + name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU)); + (*s->cpu_fprintf)(s->file, " %s\n", + name); + g_free(name); +} + +void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf) +{ + CPUListState s = { + .file = f, + .cpu_fprintf = cpu_fprintf, + }; + GSList *list; + + list = object_class_get_list(TYPE_ARM_CPU, false); + list = g_slist_sort(list, arm_cpu_list_compare); + (*cpu_fprintf)(f, "Available CPUs:\n"); + g_slist_foreach(list, arm_cpu_list_entry, &s); + g_slist_free(list); +#ifdef CONFIG_KVM + /* The 'host' CPU type is dynamically registered only if KVM is + * enabled, so we have to special-case it here: + */ + (*cpu_fprintf)(f, " host (only available in KVM mode)\n"); +#endif +} + +static void arm_cpu_add_definition(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + CpuDefinitionInfoList **cpu_list = user_data; + CpuDefinitionInfoList *entry; + CpuDefinitionInfo *info; + const char *typename; + + typename = object_class_get_name(oc); + info = g_malloc0(sizeof(*info)); + info->name = g_strndup(typename, + strlen(typename) - strlen("-" TYPE_ARM_CPU)); + + entry = g_malloc0(sizeof(*entry)); + entry->value = info; + entry->next = *cpu_list; + *cpu_list = entry; +} + +CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) +{ + CpuDefinitionInfoList *cpu_list = NULL; + GSList *list; + + list = object_class_get_list(TYPE_ARM_CPU, false); + g_slist_foreach(list, arm_cpu_add_definition, &cpu_list); + g_slist_free(list); + + return cpu_list; +} + +static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, + void *opaque, int state, int secstate, + int crm, int opc1, int opc2) +{ + /* Private utility function for define_one_arm_cp_reg_with_opaque(): + * add a single reginfo struct to the hash table. + */ + uint32_t *key = g_new(uint32_t, 1); + ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); + int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0; + int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0; + + /* Reset the secure state to the specific incoming state. This is + * necessary as the register may have been defined with both states. + */ + r2->secure = secstate; + + if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) { + /* Register is banked (using both entries in array). + * Overwriting fieldoffset as the array is only used to define + * banked registers but later only fieldoffset is used. + */ + r2->fieldoffset = r->bank_fieldoffsets[ns]; + } + + if (state == ARM_CP_STATE_AA32) { + if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) { + /* If the register is banked then we don't need to migrate or + * reset the 32-bit instance in certain cases: + * + * 1) If the register has both 32-bit and 64-bit instances then we + * can count on the 64-bit instance taking care of the + * non-secure bank. + * 2) If ARMv8 is enabled then we can count on a 64-bit version + * taking care of the secure bank. This requires that separate + * 32 and 64-bit definitions are provided. + */ + if ((r->state == ARM_CP_STATE_BOTH && ns) || + (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) { + r2->type |= ARM_CP_ALIAS; + } + } else if ((secstate != r->secure) && !ns) { + /* The register is not banked so we only want to allow migration of + * the non-secure instance. + */ + r2->type |= ARM_CP_ALIAS; + } + + if (r->state == ARM_CP_STATE_BOTH) { + /* We assume it is a cp15 register if the .cp field is left unset. + */ + if (r2->cp == 0) { + r2->cp = 15; + } + +#ifdef HOST_WORDS_BIGENDIAN + if (r2->fieldoffset) { + r2->fieldoffset += sizeof(uint32_t); + } +#endif + } + } + if (state == ARM_CP_STATE_AA64) { + /* To allow abbreviation of ARMCPRegInfo + * definitions, we treat cp == 0 as equivalent to + * the value for "standard guest-visible sysreg". + * STATE_BOTH definitions are also always "standard + * sysreg" in their AArch64 view (the .cp value may + * be non-zero for the benefit of the AArch32 view). + */ + if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) { + r2->cp = CP_REG_ARM64_SYSREG_CP; + } + *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm, + r2->opc0, opc1, opc2); + } else { + *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2); + } + if (opaque) { + r2->opaque = opaque; + } + /* reginfo passed to helpers is correct for the actual access, + * and is never ARM_CP_STATE_BOTH: + */ + r2->state = state; + /* Make sure reginfo passed to helpers for wildcarded regs + * has the correct crm/opc1/opc2 for this reg, not CP_ANY: + */ + r2->crm = crm; + r2->opc1 = opc1; + r2->opc2 = opc2; + /* By convention, for wildcarded registers only the first + * entry is used for migration; the others are marked as + * ALIAS so we don't try to transfer the register + * multiple times. Special registers (ie NOP/WFI) are + * never migratable and not even raw-accessible. + */ + if ((r->type & ARM_CP_SPECIAL)) { + r2->type |= ARM_CP_NO_RAW; + } + if (((r->crm == CP_ANY) && crm != 0) || + ((r->opc1 == CP_ANY) && opc1 != 0) || + ((r->opc2 == CP_ANY) && opc2 != 0)) { + r2->type |= ARM_CP_ALIAS; + } + + /* Check that raw accesses are either forbidden or handled. Note that + * we can't assert this earlier because the setup of fieldoffset for + * banked registers has to be done first. + */ + if (!(r2->type & ARM_CP_NO_RAW)) { + assert(!raw_accessors_invalid(r2)); + } + + /* Overriding of an existing definition must be explicitly + * requested. + */ + if (!(r->type & ARM_CP_OVERRIDE)) { + ARMCPRegInfo *oldreg; + oldreg = g_hash_table_lookup(cpu->cp_regs, key); + if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) { + fprintf(stderr, "Register redefined: cp=%d %d bit " + "crn=%d crm=%d opc1=%d opc2=%d, " + "was %s, now %s\n", r2->cp, 32 + 32 * is64, + r2->crn, r2->crm, r2->opc1, r2->opc2, + oldreg->name, r2->name); + g_assert_not_reached(); + } + } + g_hash_table_insert(cpu->cp_regs, key, r2); +} + + +void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, + const ARMCPRegInfo *r, void *opaque) +{ + /* Define implementations of coprocessor registers. + * We store these in a hashtable because typically + * there are less than 150 registers in a space which + * is 16*16*16*8*8 = 262144 in size. + * Wildcarding is supported for the crm, opc1 and opc2 fields. + * If a register is defined twice then the second definition is + * used, so this can be used to define some generic registers and + * then override them with implementation specific variations. + * At least one of the original and the second definition should + * include ARM_CP_OVERRIDE in its type bits -- this is just a guard + * against accidental use. + * + * The state field defines whether the register is to be + * visible in the AArch32 or AArch64 execution state. If the + * state is set to ARM_CP_STATE_BOTH then we synthesise a + * reginfo structure for the AArch32 view, which sees the lower + * 32 bits of the 64 bit register. + * + * Only registers visible in AArch64 may set r->opc0; opc0 cannot + * be wildcarded. AArch64 registers are always considered to be 64 + * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of + * the register, if any. + */ + int crm, opc1, opc2, state; + int crmmin = (r->crm == CP_ANY) ? 0 : r->crm; + int crmmax = (r->crm == CP_ANY) ? 15 : r->crm; + int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1; + int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1; + int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2; + int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2; + /* 64 bit registers have only CRm and Opc1 fields */ + assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn))); + /* op0 only exists in the AArch64 encodings */ + assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0)); + /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */ + assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT)); + /* The AArch64 pseudocode CheckSystemAccess() specifies that op1 + * encodes a minimum access level for the register. We roll this + * runtime check into our general permission check code, so check + * here that the reginfo's specified permissions are strict enough + * to encompass the generic architectural permission check. + */ + if (r->state != ARM_CP_STATE_AA32) { + int mask = 0; + switch (r->opc1) { + case 0: case 1: case 2: + /* min_EL EL1 */ + mask = PL1_RW; + break; + case 3: + /* min_EL EL0 */ + mask = PL0_RW; + break; + case 4: + /* min_EL EL2 */ + mask = PL2_RW; + break; + case 5: + /* unallocated encoding, so not possible */ + assert(false); + break; + case 6: + /* min_EL EL3 */ + mask = PL3_RW; + break; + case 7: + /* min_EL EL1, secure mode only (we don't check the latter) */ + mask = PL1_RW; + break; + default: + /* broken reginfo with out-of-range opc1 */ + assert(false); + break; + } + /* assert our permissions are not too lax (stricter is fine) */ + assert((r->access & ~mask) == 0); + } + + /* Check that the register definition has enough info to handle + * reads and writes if they are permitted. + */ + if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) { + if (r->access & PL3_R) { + assert((r->fieldoffset || + (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) || + r->readfn); + } + if (r->access & PL3_W) { + assert((r->fieldoffset || + (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) || + r->writefn); + } + } + /* Bad type field probably means missing sentinel at end of reg list */ + assert(cptype_valid(r->type)); + for (crm = crmmin; crm <= crmmax; crm++) { + for (opc1 = opc1min; opc1 <= opc1max; opc1++) { + for (opc2 = opc2min; opc2 <= opc2max; opc2++) { + for (state = ARM_CP_STATE_AA32; + state <= ARM_CP_STATE_AA64; state++) { + if (r->state != state && r->state != ARM_CP_STATE_BOTH) { + continue; + } + if (state == ARM_CP_STATE_AA32) { + /* Under AArch32 CP registers can be common + * (same for secure and non-secure world) or banked. + */ + switch (r->secure) { + case ARM_CP_SECSTATE_S: + case ARM_CP_SECSTATE_NS: + add_cpreg_to_hashtable(cpu, r, opaque, state, + r->secure, crm, opc1, opc2); + break; + default: + add_cpreg_to_hashtable(cpu, r, opaque, state, + ARM_CP_SECSTATE_S, + crm, opc1, opc2); + add_cpreg_to_hashtable(cpu, r, opaque, state, + ARM_CP_SECSTATE_NS, + crm, opc1, opc2); + break; + } + } else { + /* AArch64 registers get mapped to non-secure instance + * of AArch32 */ + add_cpreg_to_hashtable(cpu, r, opaque, state, + ARM_CP_SECSTATE_NS, + crm, opc1, opc2); + } + } + } + } + } +} + +void define_arm_cp_regs_with_opaque(ARMCPU *cpu, + const ARMCPRegInfo *regs, void *opaque) +{ + /* Define a whole list of registers */ + const ARMCPRegInfo *r; + for (r = regs; r->type != ARM_CP_SENTINEL; r++) { + define_one_arm_cp_reg_with_opaque(cpu, r, opaque); + } +} + +const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp) +{ + return g_hash_table_lookup(cpregs, &encoded_cp); +} + +void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* Helper coprocessor write function for write-ignore registers */ +} + +uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* Helper coprocessor write function for read-as-zero registers */ + return 0; +} + +void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque) +{ + /* Helper coprocessor reset function for do-nothing-on-reset registers */ +} + +static int bad_mode_switch(CPUARMState *env, int mode) +{ + /* Return true if it is not valid for us to switch to + * this CPU mode (ie all the UNPREDICTABLE cases in + * the ARM ARM CPSRWriteByInstr pseudocode). + */ + switch (mode) { + case ARM_CPU_MODE_USR: + case ARM_CPU_MODE_SYS: + case ARM_CPU_MODE_SVC: + case ARM_CPU_MODE_ABT: + case ARM_CPU_MODE_UND: + case ARM_CPU_MODE_IRQ: + case ARM_CPU_MODE_FIQ: + return 0; + case ARM_CPU_MODE_MON: + return !arm_is_secure(env); + default: + return 1; + } +} + +uint32_t cpsr_read(CPUARMState *env) +{ + int ZF; + ZF = (env->ZF == 0); + return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) | + (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) + | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) + | ((env->condexec_bits & 0xfc) << 8) + | (env->GE << 16) | (env->daif & CPSR_AIF); +} + +void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) +{ + uint32_t changed_daif; + + if (mask & CPSR_NZCV) { + env->ZF = (~val) & CPSR_Z; + env->NF = val; + env->CF = (val >> 29) & 1; + env->VF = (val << 3) & 0x80000000; + } + if (mask & CPSR_Q) + env->QF = ((val & CPSR_Q) != 0); + if (mask & CPSR_T) + env->thumb = ((val & CPSR_T) != 0); + if (mask & CPSR_IT_0_1) { + env->condexec_bits &= ~3; + env->condexec_bits |= (val >> 25) & 3; + } + if (mask & CPSR_IT_2_7) { + env->condexec_bits &= 3; + env->condexec_bits |= (val >> 8) & 0xfc; + } + if (mask & CPSR_GE) { + env->GE = (val >> 16) & 0xf; + } + + /* In a V7 implementation that includes the security extensions but does + * not include Virtualization Extensions the SCR.FW and SCR.AW bits control + * whether non-secure software is allowed to change the CPSR_F and CPSR_A + * bits respectively. + * + * In a V8 implementation, it is permitted for privileged software to + * change the CPSR A/F bits regardless of the SCR.AW/FW bits. + */ + if (!arm_feature(env, ARM_FEATURE_V8) && + arm_feature(env, ARM_FEATURE_EL3) && + !arm_feature(env, ARM_FEATURE_EL2) && + !arm_is_secure(env)) { + + changed_daif = (env->daif ^ val) & mask; + + if (changed_daif & CPSR_A) { + /* Check to see if we are allowed to change the masking of async + * abort exceptions from a non-secure state. + */ + if (!(env->cp15.scr_el3 & SCR_AW)) { + qemu_log_mask(LOG_GUEST_ERROR, + "Ignoring attempt to switch CPSR_A flag from " + "non-secure world with SCR.AW bit clear\n"); + mask &= ~CPSR_A; + } + } + + if (changed_daif & CPSR_F) { + /* Check to see if we are allowed to change the masking of FIQ + * exceptions from a non-secure state. + */ + if (!(env->cp15.scr_el3 & SCR_FW)) { + qemu_log_mask(LOG_GUEST_ERROR, + "Ignoring attempt to switch CPSR_F flag from " + "non-secure world with SCR.FW bit clear\n"); + mask &= ~CPSR_F; + } + + /* Check whether non-maskable FIQ (NMFI) support is enabled. + * If this bit is set software is not allowed to mask + * FIQs, but is allowed to set CPSR_F to 0. + */ + if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) && + (val & CPSR_F)) { + qemu_log_mask(LOG_GUEST_ERROR, + "Ignoring attempt to enable CPSR_F flag " + "(non-maskable FIQ [NMFI] support enabled)\n"); + mask &= ~CPSR_F; + } + } + } + + env->daif &= ~(CPSR_AIF & mask); + env->daif |= val & CPSR_AIF & mask; + + if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { + if (bad_mode_switch(env, val & CPSR_M)) { + /* Attempt to switch to an invalid mode: this is UNPREDICTABLE. + * We choose to ignore the attempt and leave the CPSR M field + * untouched. + */ + mask &= ~CPSR_M; + } else { + switch_mode(env, val & CPSR_M); + } + } + mask &= ~CACHED_CPSR_BITS; + env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); +} + +/* Sign/zero extend */ +uint32_t HELPER(sxtb16)(uint32_t x) +{ + uint32_t res; + res = (uint16_t)(int8_t)x; + res |= (uint32_t)(int8_t)(x >> 16) << 16; + return res; +} + +uint32_t HELPER(uxtb16)(uint32_t x) +{ + uint32_t res; + res = (uint16_t)(uint8_t)x; + res |= (uint32_t)(uint8_t)(x >> 16) << 16; + return res; +} + +uint32_t HELPER(clz)(uint32_t x) +{ + return clz32(x); +} + +int32_t HELPER(sdiv)(int32_t num, int32_t den) +{ + if (den == 0) + return 0; + if (num == INT_MIN && den == -1) + return INT_MIN; + return num / den; +} + +uint32_t HELPER(udiv)(uint32_t num, uint32_t den) +{ + if (den == 0) + return 0; + return num / den; +} + +uint32_t HELPER(rbit)(uint32_t x) +{ + return revbit32(x); +} + +#if defined(CONFIG_USER_ONLY) + +/* These should probably raise undefined insn exceptions. */ +void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + cpu_abort(CPU(cpu), "v7m_msr %d\n", reg); +} + +uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + cpu_abort(CPU(cpu), "v7m_mrs %d\n", reg); + return 0; +} + +void switch_mode(CPUARMState *env, int mode) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + if (mode != ARM_CPU_MODE_USR) { + cpu_abort(CPU(cpu), "Tried to switch out of user mode\n"); + } +} + +void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + cpu_abort(CPU(cpu), "banked r13 write\n"); +} + +uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + cpu_abort(CPU(cpu), "banked r13 read\n"); + return 0; +} + +uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, + uint32_t cur_el, bool secure) +{ + return 1; +} + +void aarch64_sync_64_to_32(CPUARMState *env) +{ + g_assert_not_reached(); +} + +#else + +/* Map CPU modes onto saved register banks. */ +int bank_number(int mode) +{ + switch (mode) { + case ARM_CPU_MODE_USR: + case ARM_CPU_MODE_SYS: + return BANK_USRSYS; + case ARM_CPU_MODE_SVC: + return BANK_SVC; + case ARM_CPU_MODE_ABT: + return BANK_ABT; + case ARM_CPU_MODE_UND: + return BANK_UND; + case ARM_CPU_MODE_IRQ: + return BANK_IRQ; + case ARM_CPU_MODE_FIQ: + return BANK_FIQ; + case ARM_CPU_MODE_HYP: + return BANK_HYP; + case ARM_CPU_MODE_MON: + return BANK_MON; + } + g_assert_not_reached(); +} + +void switch_mode(CPUARMState *env, int mode) +{ + int old_mode; + int i; + + old_mode = env->uncached_cpsr & CPSR_M; + if (mode == old_mode) + return; + + if (old_mode == ARM_CPU_MODE_FIQ) { + memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t)); + memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t)); + } else if (mode == ARM_CPU_MODE_FIQ) { + memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t)); + memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t)); + } + + i = bank_number(old_mode); + env->banked_r13[i] = env->regs[13]; + env->banked_r14[i] = env->regs[14]; + env->banked_spsr[i] = env->spsr; + + i = bank_number(mode); + env->regs[13] = env->banked_r13[i]; + env->regs[14] = env->banked_r14[i]; + env->spsr = env->banked_spsr[i]; +} + +/* Physical Interrupt Target EL Lookup Table + * + * [ From ARM ARM section G1.13.4 (Table G1-15) ] + * + * The below multi-dimensional table is used for looking up the target + * exception level given numerous condition criteria. Specifically, the + * target EL is based on SCR and HCR routing controls as well as the + * currently executing EL and secure state. + * + * Dimensions: + * target_el_table[2][2][2][2][2][4] + * | | | | | +--- Current EL + * | | | | +------ Non-secure(0)/Secure(1) + * | | | +--------- HCR mask override + * | | +------------ SCR exec state control + * | +--------------- SCR mask override + * +------------------ 32-bit(0)/64-bit(1) EL3 + * + * The table values are as such: + * 0-3 = EL0-EL3 + * -1 = Cannot occur + * + * The ARM ARM target EL table includes entries indicating that an "exception + * is not taken". The two cases where this is applicable are: + * 1) An exception is taken from EL3 but the SCR does not have the exception + * routed to EL3. + * 2) An exception is taken from EL2 but the HCR does not have the exception + * routed to EL2. + * In these two cases, the below table contain a target of EL1. This value is + * returned as it is expected that the consumer of the table data will check + * for "target EL >= current EL" to ensure the exception is not taken. + * + * SCR HCR + * 64 EA AMO From + * BIT IRQ IMO Non-secure Secure + * EL3 FIQ RW FMO EL0 EL1 EL2 EL3 EL0 EL1 EL2 EL3 + */ +static const int8_t target_el_table[2][2][2][2][2][4] = { + {{{{/* 0 0 0 0 */{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },}, + {/* 0 0 0 1 */{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},}, + {{/* 0 0 1 0 */{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },}, + {/* 0 0 1 1 */{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},}, + {{{/* 0 1 0 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },}, + {/* 0 1 0 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},}, + {{/* 0 1 1 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },}, + {/* 0 1 1 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},}, + {{{{/* 1 0 0 0 */{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },}, + {/* 1 0 0 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},}, + {{/* 1 0 1 0 */{ 1, 1, 1, -1 },{ 1, 1, -1, 1 },}, + {/* 1 0 1 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},}, + {{{/* 1 1 0 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },}, + {/* 1 1 0 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},}, + {{/* 1 1 1 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },}, + {/* 1 1 1 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},},}, +}; + +/* + * Determine the target EL for physical exceptions + */ +uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, + uint32_t cur_el, bool secure) +{ + CPUARMState *env = cs->env_ptr; + int rw; + int scr; + int hcr; + int target_el; + /* Is the highest EL AArch64? */ + int is64 = arm_feature(env, ARM_FEATURE_AARCH64); + + if (arm_feature(env, ARM_FEATURE_EL3)) { + rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW); + } else { + /* Either EL2 is the highest EL (and so the EL2 register width + * is given by is64); or there is no EL2 or EL3, in which case + * the value of 'rw' does not affect the table lookup anyway. + */ + rw = is64; + } + + switch (excp_idx) { + case EXCP_IRQ: + scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ); + hcr = ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO); + break; + case EXCP_FIQ: + scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ); + hcr = ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO); + break; + default: + scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA); + hcr = ((env->cp15.hcr_el2 & HCR_AMO) == HCR_AMO); + break; + }; + + /* If HCR.TGE is set then HCR is treated as being 1 */ + hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE); + + /* Perform a table-lookup for the target EL given the current state */ + target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el]; + + assert(target_el > 0); + + return target_el; +} + +static void v7m_push(CPUARMState *env, uint32_t val) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + + env->regs[13] -= 4; + stl_phys(cs->as, env->regs[13], val); +} + +static uint32_t v7m_pop(CPUARMState *env) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + uint32_t val; + + val = ldl_phys(cs->as, env->regs[13]); + env->regs[13] += 4; + return val; +} + +/* Switch to V7M main or process stack pointer. */ +static void switch_v7m_sp(CPUARMState *env, int process) +{ + uint32_t tmp; + if (env->v7m.current_sp != process) { + tmp = env->v7m.other_sp; + env->v7m.other_sp = env->regs[13]; + env->regs[13] = tmp; + env->v7m.current_sp = process; + } +} + +static void do_v7m_exception_exit(CPUARMState *env) +{ + uint32_t type; + uint32_t xpsr; + + type = env->regs[15]; + if (env->v7m.exception != 0) + armv7m_nvic_complete_irq(env->nvic, env->v7m.exception); + + /* Switch to the target stack. */ + switch_v7m_sp(env, (type & 4) != 0); + /* Pop registers. */ + env->regs[0] = v7m_pop(env); + env->regs[1] = v7m_pop(env); + env->regs[2] = v7m_pop(env); + env->regs[3] = v7m_pop(env); + env->regs[12] = v7m_pop(env); + env->regs[14] = v7m_pop(env); + env->regs[15] = v7m_pop(env); + if (env->regs[15] & 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "M profile return from interrupt with misaligned " + "PC is UNPREDICTABLE\n"); + /* Actual hardware seems to ignore the lsbit, and there are several + * RTOSes out there which incorrectly assume the r15 in the stack + * frame should be a Thumb-style "lsbit indicates ARM/Thumb" value. + */ + env->regs[15] &= ~1U; + } + xpsr = v7m_pop(env); + xpsr_write(env, xpsr, 0xfffffdff); + /* Undo stack alignment. */ + if (xpsr & 0x200) + env->regs[13] |= 4; + /* ??? The exception return type specifies Thread/Handler mode. However + this is also implied by the xPSR value. Not sure what to do + if there is a mismatch. */ + /* ??? Likewise for mismatches between the CONTROL register and the stack + pointer. */ +} + +void arm_v7m_cpu_do_interrupt(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + uint32_t xpsr = xpsr_read(env); + uint32_t lr; + uint32_t addr; + + arm_log_exception(cs->exception_index); + + lr = 0xfffffff1; + if (env->v7m.current_sp) + lr |= 4; + if (env->v7m.exception == 0) + lr |= 8; + + /* For exceptions we just mark as pending on the NVIC, and let that + handle it. */ + /* TODO: Need to escalate if the current priority is higher than the + one we're raising. */ + switch (cs->exception_index) { + case EXCP_UDEF: + env->v7m.cfsr |= CFSR_UNDEFINSTR; + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + return; + case EXCP_SWI: + /* The PC already points to the next instruction. */ + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC); + return; + case EXCP_PREFETCH_ABORT: + case EXCP_DATA_ABORT: + env->v7m.mmfar = env->exception.vaddress; + env->v7m.cfsr |= CFSR_MMARVALID; + if (cs->exception_index == EXCP_PREFETCH_ABORT) + env->v7m.cfsr |= CFSR_IACCVIOL; + else + env->v7m.cfsr |= CFSR_DACCVIOL; + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); + return; + case EXCP_BKPT: + if (semihosting_enabled()) { + int nr; + nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff; + if (nr == 0xab) { + env->regs[15] += 2; + qemu_log_mask(CPU_LOG_INT, + "...handling as semihosting call 0x%x\n", + env->regs[0]); + env->regs[0] = do_arm_semihosting(env); + return; + } + } + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG); + return; + case EXCP_IRQ: + env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic); + break; + case EXCP_WKUP: + // Take a reset + qemu_devices_reset(); + return; + case EXCP_EXCEPTION_EXIT: + do_v7m_exception_exit(env); + return; + default: + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); + return; /* Never happens. Keep compiler happy. */ + } + + /* Align stack pointer. */ + if ((env->v7m.ccr & CCR_STKALIGN) && (env->regs[13] & 4)) { + env->regs[13] -= 4; + xpsr |= 0x200; + } + /* Switch to the handler mode. */ + v7m_push(env, xpsr); + v7m_push(env, env->regs[15]); + v7m_push(env, env->regs[14]); + v7m_push(env, env->regs[12]); + v7m_push(env, env->regs[3]); + v7m_push(env, env->regs[2]); + v7m_push(env, env->regs[1]); + v7m_push(env, env->regs[0]); + switch_v7m_sp(env, 0); + /* Clear IT bits */ + env->condexec_bits = 0; + env->regs[14] = lr; + addr = ldl_phys(cs->as, env->v7m.vecbase + env->v7m.exception * 4); + env->regs[15] = addr & 0xfffffffe; + env->thumb = addr & 1; + if (env->v7m.exception == 1) { // reset? + env->v7m.exception = 0; + } +} + +/* Function used to synchronize QEMU's AArch64 register set with AArch32 + * register set. This is necessary when switching between AArch32 and AArch64 + * execution state. + */ +void aarch64_sync_32_to_64(CPUARMState *env) +{ + int i; + uint32_t mode = env->uncached_cpsr & CPSR_M; + + /* We can blanket copy R[0:7] to X[0:7] */ + for (i = 0; i < 8; i++) { + env->xregs[i] = env->regs[i]; + } + + /* Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12. + * Otherwise, they come from the banked user regs. + */ + if (mode == ARM_CPU_MODE_FIQ) { + for (i = 8; i < 13; i++) { + env->xregs[i] = env->usr_regs[i - 8]; + } + } else { + for (i = 8; i < 13; i++) { + env->xregs[i] = env->regs[i]; + } + } + + /* Registers x13-x23 are the various mode SP and FP registers. Registers + * r13 and r14 are only copied if we are in that mode, otherwise we copy + * from the mode banked register. + */ + if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) { + env->xregs[13] = env->regs[13]; + env->xregs[14] = env->regs[14]; + } else { + env->xregs[13] = env->banked_r13[bank_number(ARM_CPU_MODE_USR)]; + /* HYP is an exception in that it is copied from r14 */ + if (mode == ARM_CPU_MODE_HYP) { + env->xregs[14] = env->regs[14]; + } else { + env->xregs[14] = env->banked_r14[bank_number(ARM_CPU_MODE_USR)]; + } + } + + if (mode == ARM_CPU_MODE_HYP) { + env->xregs[15] = env->regs[13]; + } else { + env->xregs[15] = env->banked_r13[bank_number(ARM_CPU_MODE_HYP)]; + } + + if (mode == ARM_CPU_MODE_IRQ) { + env->xregs[16] = env->regs[14]; + env->xregs[17] = env->regs[13]; + } else { + env->xregs[16] = env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)]; + env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)]; + } + + if (mode == ARM_CPU_MODE_SVC) { + env->xregs[18] = env->regs[14]; + env->xregs[19] = env->regs[13]; + } else { + env->xregs[18] = env->banked_r14[bank_number(ARM_CPU_MODE_SVC)]; + env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)]; + } + + if (mode == ARM_CPU_MODE_ABT) { + env->xregs[20] = env->regs[14]; + env->xregs[21] = env->regs[13]; + } else { + env->xregs[20] = env->banked_r14[bank_number(ARM_CPU_MODE_ABT)]; + env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)]; + } + + if (mode == ARM_CPU_MODE_UND) { + env->xregs[22] = env->regs[14]; + env->xregs[23] = env->regs[13]; + } else { + env->xregs[22] = env->banked_r14[bank_number(ARM_CPU_MODE_UND)]; + env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)]; + } + + /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ + * mode, then we can copy from r8-r14. Otherwise, we copy from the + * FIQ bank for r8-r14. + */ + if (mode == ARM_CPU_MODE_FIQ) { + for (i = 24; i < 31; i++) { + env->xregs[i] = env->regs[i - 16]; /* X[24:30] <- R[8:14] */ + } + } else { + for (i = 24; i < 29; i++) { + env->xregs[i] = env->fiq_regs[i - 24]; + } + env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)]; + env->xregs[30] = env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)]; + } + + env->pc = env->regs[15]; +} + +/* Function used to synchronize QEMU's AArch32 register set with AArch64 + * register set. This is necessary when switching between AArch32 and AArch64 + * execution state. + */ +void aarch64_sync_64_to_32(CPUARMState *env) +{ + int i; + uint32_t mode = env->uncached_cpsr & CPSR_M; + + /* We can blanket copy X[0:7] to R[0:7] */ + for (i = 0; i < 8; i++) { + env->regs[i] = env->xregs[i]; + } + + /* Unless we are in FIQ mode, r8-r12 come from the user registers x8-x12. + * Otherwise, we copy x8-x12 into the banked user regs. + */ + if (mode == ARM_CPU_MODE_FIQ) { + for (i = 8; i < 13; i++) { + env->usr_regs[i - 8] = env->xregs[i]; + } + } else { + for (i = 8; i < 13; i++) { + env->regs[i] = env->xregs[i]; + } + } + + /* Registers r13 & r14 depend on the current mode. + * If we are in a given mode, we copy the corresponding x registers to r13 + * and r14. Otherwise, we copy the x register to the banked r13 and r14 + * for the mode. + */ + if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) { + env->regs[13] = env->xregs[13]; + env->regs[14] = env->xregs[14]; + } else { + env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13]; + + /* HYP is an exception in that it does not have its own banked r14 but + * shares the USR r14 + */ + if (mode == ARM_CPU_MODE_HYP) { + env->regs[14] = env->xregs[14]; + } else { + env->banked_r14[bank_number(ARM_CPU_MODE_USR)] = env->xregs[14]; + } + } + + if (mode == ARM_CPU_MODE_HYP) { + env->regs[13] = env->xregs[15]; + } else { + env->banked_r13[bank_number(ARM_CPU_MODE_HYP)] = env->xregs[15]; + } + + if (mode == ARM_CPU_MODE_IRQ) { + env->regs[14] = env->xregs[16]; + env->regs[13] = env->xregs[17]; + } else { + env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16]; + env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17]; + } + + if (mode == ARM_CPU_MODE_SVC) { + env->regs[14] = env->xregs[18]; + env->regs[13] = env->xregs[19]; + } else { + env->banked_r14[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18]; + env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19]; + } + + if (mode == ARM_CPU_MODE_ABT) { + env->regs[14] = env->xregs[20]; + env->regs[13] = env->xregs[21]; + } else { + env->banked_r14[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20]; + env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21]; + } + + if (mode == ARM_CPU_MODE_UND) { + env->regs[14] = env->xregs[22]; + env->regs[13] = env->xregs[23]; + } else { + env->banked_r14[bank_number(ARM_CPU_MODE_UND)] = env->xregs[22]; + env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23]; + } + + /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ + * mode, then we can copy to r8-r14. Otherwise, we copy to the + * FIQ bank for r8-r14. + */ + if (mode == ARM_CPU_MODE_FIQ) { + for (i = 24; i < 31; i++) { + env->regs[i - 16] = env->xregs[i]; /* X[24:30] -> R[8:14] */ + } + } else { + for (i = 24; i < 29; i++) { + env->fiq_regs[i - 24] = env->xregs[i]; + } + env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29]; + env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30]; + } + + env->regs[15] = env->pc; +} + +/* Handle a CPU exception. */ +void arm_cpu_do_interrupt(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + uint32_t addr; + uint32_t mask; + int new_mode; + uint32_t offset; + uint32_t moe; + + assert(!IS_M(env)); + + arm_log_exception(cs->exception_index); + + if (arm_is_psci_call(cpu, cs->exception_index)) { + arm_handle_psci_call(cpu); + qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n"); + return; + } + + /* If this is a debug exception we must update the DBGDSCR.MOE bits */ + switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) { + case EC_BREAKPOINT: + case EC_BREAKPOINT_SAME_EL: + moe = 1; + break; + case EC_WATCHPOINT: + case EC_WATCHPOINT_SAME_EL: + moe = 10; + break; + case EC_AA32_BKPT: + moe = 3; + break; + case EC_VECTORCATCH: + moe = 5; + break; + default: + moe = 0; + break; + } + + if (moe) { + env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe); + } + + /* TODO: Vectored interrupt controller. */ + switch (cs->exception_index) { + case EXCP_UDEF: + new_mode = ARM_CPU_MODE_UND; + addr = 0x04; + mask = CPSR_I; + if (env->thumb) + offset = 2; + else + offset = 4; + break; + case EXCP_SWI: + if (semihosting_enabled()) { + /* Check for semihosting interrupt. */ + if (env->thumb) { + mask = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code) + & 0xff; + } else { + mask = arm_ldl_code(env, env->regs[15] - 4, env->bswap_code) + & 0xffffff; + } + /* Only intercept calls from privileged modes, to provide some + semblance of security. */ + if (((mask == 0x123456 && !env->thumb) + || (mask == 0xab && env->thumb)) + && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { + qemu_log_mask(CPU_LOG_INT, + "...handling as semihosting call 0x%x\n", + env->regs[0]); + env->regs[0] = do_arm_semihosting(env); + return; + } + } + new_mode = ARM_CPU_MODE_SVC; + addr = 0x08; + mask = CPSR_I; + /* The PC already points to the next instruction. */ + offset = 0; + break; + case EXCP_BKPT: + /* See if this is a semihosting syscall. */ + if (env->thumb && semihosting_enabled()) { + mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff; + if (mask == 0xab + && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { + env->regs[15] += 2; + qemu_log_mask(CPU_LOG_INT, + "...handling as semihosting call 0x%x\n", + env->regs[0]); + env->regs[0] = do_arm_semihosting(env); + return; + } + } + env->exception.fsr = 2; + /* Fall through to prefetch abort. */ + case EXCP_PREFETCH_ABORT: + A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr); + A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress); + qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", + env->exception.fsr, (uint32_t)env->exception.vaddress); + new_mode = ARM_CPU_MODE_ABT; + addr = 0x0c; + mask = CPSR_A | CPSR_I; + offset = 4; + break; + case EXCP_DATA_ABORT: + A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr); + A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress); + qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", + env->exception.fsr, + (uint32_t)env->exception.vaddress); + new_mode = ARM_CPU_MODE_ABT; + addr = 0x10; + mask = CPSR_A | CPSR_I; + offset = 8; + break; + case EXCP_IRQ: + new_mode = ARM_CPU_MODE_IRQ; + addr = 0x18; + /* Disable IRQ and imprecise data aborts. */ + mask = CPSR_A | CPSR_I; + offset = 4; + if (env->cp15.scr_el3 & SCR_IRQ) { + /* IRQ routed to monitor mode */ + new_mode = ARM_CPU_MODE_MON; + mask |= CPSR_F; + } + break; + case EXCP_FIQ: + new_mode = ARM_CPU_MODE_FIQ; + addr = 0x1c; + /* Disable FIQ, IRQ and imprecise data aborts. */ + mask = CPSR_A | CPSR_I | CPSR_F; + if (env->cp15.scr_el3 & SCR_FIQ) { + /* FIQ routed to monitor mode */ + new_mode = ARM_CPU_MODE_MON; + } + offset = 4; + break; + case EXCP_SMC: + new_mode = ARM_CPU_MODE_MON; + addr = 0x08; + mask = CPSR_A | CPSR_I | CPSR_F; + offset = 0; + break; + default: + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); + return; /* Never happens. Keep compiler happy. */ + } + + if (new_mode == ARM_CPU_MODE_MON) { + addr += env->cp15.mvbar; + } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) { + /* High vectors. When enabled, base address cannot be remapped. */ + addr += 0xffff0000; + } else { + /* ARM v7 architectures provide a vector base address register to remap + * the interrupt vector table. + * This register is only followed in non-monitor mode, and is banked. + * Note: only bits 31:5 are valid. + */ + addr += A32_BANKED_CURRENT_REG_GET(env, vbar); + } + + if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) { + env->cp15.scr_el3 &= ~SCR_NS; + } + + switch_mode (env, new_mode); + /* For exceptions taken to AArch32 we must clear the SS bit in both + * PSTATE and in the old-state value we save to SPSR_, so zero it now. + */ + env->uncached_cpsr &= ~PSTATE_SS; + env->spsr = cpsr_read(env); + /* Clear IT bits. */ + env->condexec_bits = 0; + /* Switch to the new mode, and to the correct instruction set. */ + env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; + env->daif |= mask; + /* this is a lie, as the was no c1_sys on V4T/V5, but who cares + * and we should just guard the thumb mode on V4 */ + if (arm_feature(env, ARM_FEATURE_V4T)) { + env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0; + } + env->regs[14] = env->regs[15] + offset; + env->regs[15] = addr; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; +} + + +/* Return the exception level which controls this address translation regime */ +static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_S2NS: + case ARMMMUIdx_S1E2: + return 2; + case ARMMMUIdx_S1E3: + return 3; + case ARMMMUIdx_S1SE0: + return arm_el_is_aa64(env, 3) ? 1 : 3; + case ARMMMUIdx_S1SE1: + case ARMMMUIdx_S1NSE0: + case ARMMMUIdx_S1NSE1: + return 1; + default: + g_assert_not_reached(); + } +} + +/* Return true if this address translation regime is secure */ +static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_S12NSE0: + case ARMMMUIdx_S12NSE1: + case ARMMMUIdx_S1NSE0: + case ARMMMUIdx_S1NSE1: + case ARMMMUIdx_S1E2: + case ARMMMUIdx_S2NS: + return false; + case ARMMMUIdx_S1E3: + case ARMMMUIdx_S1SE0: + case ARMMMUIdx_S1SE1: + return true; + default: + g_assert_not_reached(); + } +} + +/* Return the SCTLR value which controls this address translation regime */ +static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + return env->cp15.sctlr_el[regime_el(env, mmu_idx)]; +} + +/* Return true if the specified stage of address translation is disabled */ +static inline bool regime_translation_disabled(CPUARMState *env, + ARMMMUIdx mmu_idx) +{ + if (mmu_idx == ARMMMUIdx_S2NS) { + return (env->cp15.hcr_el2 & HCR_VM) == 0; + } + return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0; +} + +/* Return the TCR controlling this translation regime */ +static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + if (mmu_idx == ARMMMUIdx_S2NS) { + return &env->cp15.vtcr_el2; + } + return &env->cp15.tcr_el[regime_el(env, mmu_idx)]; +} + +/* Return the TTBR associated with this translation regime */ +static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, + int ttbrn) +{ + if (mmu_idx == ARMMMUIdx_S2NS) { + return env->cp15.vttbr_el2; + } + if (ttbrn == 0) { + return env->cp15.ttbr0_el[regime_el(env, mmu_idx)]; + } else { + return env->cp15.ttbr1_el[regime_el(env, mmu_idx)]; + } +} + +/* Return true if the translation regime is using LPAE format page tables */ +static inline bool regime_using_lpae_format(CPUARMState *env, + ARMMMUIdx mmu_idx) +{ + int el = regime_el(env, mmu_idx); + if (el == 2 || arm_el_is_aa64(env, el)) { + return true; + } + if (arm_feature(env, ARM_FEATURE_LPAE) + && (regime_tcr(env, mmu_idx)->raw_tcr & TTBCR_EAE)) { + return true; + } + return false; +} + +static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_S1SE0: + case ARMMMUIdx_S1NSE0: + return true; + default: + return false; + case ARMMMUIdx_S12NSE0: + case ARMMMUIdx_S12NSE1: + g_assert_not_reached(); + } +} + +/* Translate section/page access permissions to page + * R/W protection flags + * + * @env: CPUARMState + * @mmu_idx: MMU index indicating required translation regime + * @ap: The 3-bit access permissions (AP[2:0]) + * @domain_prot: The 2-bit domain access permissions + */ +static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, + int ap, int domain_prot) +{ + bool is_user = regime_is_user(env, mmu_idx); + + if (domain_prot == 3) { + return PAGE_READ | PAGE_WRITE; + } + + switch (ap) { + case 0: + if (arm_feature(env, ARM_FEATURE_V7)) { + return 0; + } + switch (regime_sctlr(env, mmu_idx) & (SCTLR_S | SCTLR_R)) { + case SCTLR_S: + return is_user ? 0 : PAGE_READ; + case SCTLR_R: + return PAGE_READ; + default: + return 0; + } + case 1: + return is_user ? 0 : PAGE_READ | PAGE_WRITE; + case 2: + if (is_user) { + return PAGE_READ; + } else { + return PAGE_READ | PAGE_WRITE; + } + case 3: + return PAGE_READ | PAGE_WRITE; + case 4: /* Reserved. */ + return 0; + case 5: + return is_user ? 0 : PAGE_READ; + case 6: + return PAGE_READ; + case 7: + if (!arm_feature(env, ARM_FEATURE_V6K)) { + return 0; + } + return PAGE_READ; + default: + g_assert_not_reached(); + } +} + +/* Translate section/page access permissions to page + * R/W protection flags. + * + * @ap: The 2-bit simple AP (AP[2:1]) + * @is_user: TRUE if accessing from PL0 + */ +static inline int simple_ap_to_rw_prot_is_user(int ap, bool is_user) +{ + switch (ap) { + case 0: + return is_user ? 0 : PAGE_READ | PAGE_WRITE; + case 1: + return PAGE_READ | PAGE_WRITE; + case 2: + return is_user ? 0 : PAGE_READ; + case 3: + return PAGE_READ; + default: + g_assert_not_reached(); + } +} + +static inline int +simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap) +{ + return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx)); +} + +/* Translate S2 section/page access permissions to protection flags + * + * @env: CPUARMState + * @s2ap: The 2-bit stage2 access permissions (S2AP) + * @xn: XN (execute-never) bit + */ +static int get_S2prot(CPUARMState *env, int s2ap, int xn) +{ + int prot = 0; + + if (s2ap & 1) { + prot |= PAGE_READ; + } + if (s2ap & 2) { + prot |= PAGE_WRITE; + } + if (!xn) { + prot |= PAGE_EXEC; + } + return prot; +} + +/* Translate section/page access permissions to protection flags + * + * @env: CPUARMState + * @mmu_idx: MMU index indicating required translation regime + * @is_aa64: TRUE if AArch64 + * @ap: The 2-bit simple AP (AP[2:1]) + * @ns: NS (non-secure) bit + * @xn: XN (execute-never) bit + * @pxn: PXN (privileged execute-never) bit + */ +static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, + int ap, int ns, int xn, int pxn) +{ + bool is_user = regime_is_user(env, mmu_idx); + int prot_rw, user_rw; + bool have_wxn; + int wxn = 0; + + assert(mmu_idx != ARMMMUIdx_S2NS); + + user_rw = simple_ap_to_rw_prot_is_user(ap, true); + if (is_user) { + prot_rw = user_rw; + } else { + prot_rw = simple_ap_to_rw_prot_is_user(ap, false); + } + + if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) { + return prot_rw; + } + + /* TODO have_wxn should be replaced with + * ARM_FEATURE_V8 || (ARM_FEATURE_V7 && ARM_FEATURE_EL2) + * when ARM_FEATURE_EL2 starts getting set. For now we assume all LPAE + * compatible processors have EL2, which is required for [U]WXN. + */ + have_wxn = arm_feature(env, ARM_FEATURE_LPAE); + + if (have_wxn) { + wxn = regime_sctlr(env, mmu_idx) & SCTLR_WXN; + } + + if (is_aa64) { + switch (regime_el(env, mmu_idx)) { + case 1: + if (!is_user) { + xn = pxn || (user_rw & PAGE_WRITE); + } + break; + case 2: + case 3: + break; + } + } else if (arm_feature(env, ARM_FEATURE_V7)) { + switch (regime_el(env, mmu_idx)) { + case 1: + case 3: + if (is_user) { + xn = xn || !(user_rw & PAGE_READ); + } else { + int uwxn = 0; + if (have_wxn) { + uwxn = regime_sctlr(env, mmu_idx) & SCTLR_UWXN; + } + xn = xn || !(prot_rw & PAGE_READ) || pxn || + (uwxn && (user_rw & PAGE_WRITE)); + } + break; + case 2: + break; + } + } else { + xn = wxn = 0; + } + + if (xn || (wxn && (prot_rw & PAGE_WRITE))) { + return prot_rw; + } + return prot_rw | PAGE_EXEC; +} + +static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, + uint32_t *table, uint32_t address) +{ + /* Note that we can only get here for an AArch32 PL0/PL1 lookup */ + TCR *tcr = regime_tcr(env, mmu_idx); + + if (address & tcr->mask) { + if (tcr->raw_tcr & TTBCR_PD1) { + /* Translation table walk disabled for TTBR1 */ + return false; + } + *table = regime_ttbr(env, mmu_idx, 1) & 0xffffc000; + } else { + if (tcr->raw_tcr & TTBCR_PD0) { + /* Translation table walk disabled for TTBR0 */ + return false; + } + *table = regime_ttbr(env, mmu_idx, 0) & tcr->base_mask; + } + *table |= (address >> 18) & 0x3ffc; + return true; +} + +/* Translate a S1 pagetable walk through S2 if needed. */ +static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, + hwaddr addr, MemTxAttrs txattrs, + uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + if ((mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1) && + !regime_translation_disabled(env, ARMMMUIdx_S2NS)) { + target_ulong s2size; + hwaddr s2pa; + int s2prot; + int ret; + + ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa, + &txattrs, &s2prot, &s2size, fsr, fi); + if (ret) { + fi->s2addr = addr; + fi->stage2 = true; + fi->s1ptw = true; + return ~0; + } + addr = s2pa; + } + return addr; +} + +/* All loads done in the course of a page table walk go through here. + * TODO: rather than ignoring errors from physical memory reads (which + * are external aborts in ARM terminology) we should propagate this + * error out so that we can turn it into a Data Abort if this walk + * was being done for a CPU load/store or an address translation instruction + * (but not if it was for a debug access). + */ +static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure, + ARMMMUIdx mmu_idx, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + MemTxAttrs attrs = {}; + + attrs.secure = is_secure; + addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi); + if (fi->s1ptw) { + return 0; + } + return address_space_ldl(cs->as, addr, attrs, NULL); +} + +static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure, + ARMMMUIdx mmu_idx, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + MemTxAttrs attrs = {}; + + attrs.secure = is_secure; + addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi); + if (fi->s1ptw) { + return 0; + } + return address_space_ldq(cs->as, addr, attrs, NULL); +} + +static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, + target_ulong *page_size, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + int code; + uint32_t table; + uint32_t desc; + int type; + int ap; + int domain = 0; + int domain_prot; + hwaddr phys_addr; + uint32_t dacr; + + /* Pagetable walk. */ + /* Lookup l1 descriptor. */ + if (!get_level1_table_address(env, mmu_idx, &table, address)) { + /* Section translation fault if page walk is disabled by PD0 or PD1 */ + code = 5; + goto do_fault; + } + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), + mmu_idx, fsr, fi); + type = (desc & 3); + domain = (desc >> 5) & 0x0f; + if (regime_el(env, mmu_idx) == 1) { + dacr = env->cp15.dacr_ns; + } else { + dacr = env->cp15.dacr_s; + } + domain_prot = (dacr >> (domain * 2)) & 3; + if (type == 0) { + /* Section translation fault. */ + code = 5; + goto do_fault; + } + if (domain_prot == 0 || domain_prot == 2) { + if (type == 2) + code = 9; /* Section domain fault. */ + else + code = 11; /* Page domain fault. */ + goto do_fault; + } + if (type == 2) { + /* 1Mb section. */ + phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); + ap = (desc >> 10) & 3; + code = 13; + *page_size = 1024 * 1024; + } else { + /* Lookup l2 entry. */ + if (type == 1) { + /* Coarse pagetable. */ + table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); + } else { + /* Fine pagetable. */ + table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); + } + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), + mmu_idx, fsr, fi); + switch (desc & 3) { + case 0: /* Page translation fault. */ + code = 7; + goto do_fault; + case 1: /* 64k page. */ + phys_addr = (desc & 0xffff0000) | (address & 0xffff); + ap = (desc >> (4 + ((address >> 13) & 6))) & 3; + *page_size = 0x10000; + break; + case 2: /* 4k page. */ + phys_addr = (desc & 0xfffff000) | (address & 0xfff); + ap = (desc >> (4 + ((address >> 9) & 6))) & 3; + *page_size = 0x1000; + break; + case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */ + if (type == 1) { + /* ARMv6/XScale extended small page format */ + if (arm_feature(env, ARM_FEATURE_XSCALE) + || arm_feature(env, ARM_FEATURE_V6)) { + phys_addr = (desc & 0xfffff000) | (address & 0xfff); + *page_size = 0x1000; + } else { + /* UNPREDICTABLE in ARMv5; we choose to take a + * page translation fault. + */ + code = 7; + goto do_fault; + } + } else { + phys_addr = (desc & 0xfffffc00) | (address & 0x3ff); + *page_size = 0x400; + } + ap = (desc >> 4) & 3; + break; + default: + /* Never happens, but compiler isn't smart enough to tell. */ + abort(); + } + code = 15; + } + *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot); + *prot |= *prot ? PAGE_EXEC : 0; + if (!(*prot & (1 << access_type))) { + /* Access permission fault. */ + goto do_fault; + } + *phys_ptr = phys_addr; + return false; +do_fault: + *fsr = code | (domain << 4); + return true; +} + +static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, + target_ulong *page_size, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + int code; + uint32_t table; + uint32_t desc; + uint32_t xn; + uint32_t pxn = 0; + int type; + int ap; + int domain = 0; + int domain_prot; + hwaddr phys_addr; + uint32_t dacr; + bool ns; + + /* Pagetable walk. */ + /* Lookup l1 descriptor. */ + if (!get_level1_table_address(env, mmu_idx, &table, address)) { + /* Section translation fault if page walk is disabled by PD0 or PD1 */ + code = 5; + goto do_fault; + } + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), + mmu_idx, fsr, fi); + type = (desc & 3); + if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) { + /* Section translation fault, or attempt to use the encoding + * which is Reserved on implementations without PXN. + */ + code = 5; + goto do_fault; + } + if ((type == 1) || !(desc & (1 << 18))) { + /* Page or Section. */ + domain = (desc >> 5) & 0x0f; + } + if (regime_el(env, mmu_idx) == 1) { + dacr = env->cp15.dacr_ns; + } else { + dacr = env->cp15.dacr_s; + } + domain_prot = (dacr >> (domain * 2)) & 3; + if (domain_prot == 0 || domain_prot == 2) { + if (type != 1) { + code = 9; /* Section domain fault. */ + } else { + code = 11; /* Page domain fault. */ + } + goto do_fault; + } + if (type != 1) { + if (desc & (1 << 18)) { + /* Supersection. */ + phys_addr = (desc & 0xff000000) | (address & 0x00ffffff); + phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32; + phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36; + *page_size = 0x1000000; + } else { + /* Section. */ + phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); + *page_size = 0x100000; + } + ap = ((desc >> 10) & 3) | ((desc >> 13) & 4); + xn = desc & (1 << 4); + pxn = desc & 1; + code = 13; + ns = extract32(desc, 19, 1); + } else { + if (arm_feature(env, ARM_FEATURE_PXN)) { + pxn = (desc >> 2) & 1; + } + ns = extract32(desc, 3, 1); + /* Lookup l2 entry. */ + table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), + mmu_idx, fsr, fi); + ap = ((desc >> 4) & 3) | ((desc >> 7) & 4); + switch (desc & 3) { + case 0: /* Page translation fault. */ + code = 7; + goto do_fault; + case 1: /* 64k page. */ + phys_addr = (desc & 0xffff0000) | (address & 0xffff); + xn = desc & (1 << 15); + *page_size = 0x10000; + break; + case 2: case 3: /* 4k page. */ + phys_addr = (desc & 0xfffff000) | (address & 0xfff); + xn = desc & 1; + *page_size = 0x1000; + break; + default: + /* Never happens, but compiler isn't smart enough to tell. */ + abort(); + } + code = 15; + } + if (domain_prot == 3) { + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + } else { + if (pxn && !regime_is_user(env, mmu_idx)) { + xn = 1; + } + if (xn && access_type == 2) + goto do_fault; + + if (arm_feature(env, ARM_FEATURE_V6K) && + (regime_sctlr(env, mmu_idx) & SCTLR_AFE)) { + /* The simplified model uses AP[0] as an access control bit. */ + if ((ap & 1) == 0) { + /* Access flag fault. */ + code = (code == 15) ? 6 : 3; + goto do_fault; + } + *prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1); + } else { + *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot); + } + if (*prot && !xn) { + *prot |= PAGE_EXEC; + } + if (!(*prot & (1 << access_type))) { + /* Access permission fault. */ + goto do_fault; + } + } + if (ns) { + /* The NS bit will (as required by the architecture) have no effect if + * the CPU doesn't support TZ or this is a non-secure translation + * regime, because the attribute will already be non-secure. + */ + attrs->secure = false; + } + *phys_ptr = phys_addr; + return false; +do_fault: + *fsr = code | (domain << 4); + return true; +} + +/* Fault type for long-descriptor MMU fault reporting; this corresponds + * to bits [5..2] in the STATUS field in long-format DFSR/IFSR. + */ +typedef enum { + translation_fault = 1, + access_fault = 2, + permission_fault = 3, +} MMUFaultType; + +/* + * check_s2_startlevel + * @cpu: ARMCPU + * @is_aa64: True if the translation regime is in AArch64 state + * @startlevel: Suggested starting level + * @inputsize: Bitsize of IPAs + * @stride: Page-table stride (See the ARM ARM) + * + * Returns true if the suggested starting level is OK and false otherwise. + */ +static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level, + int inputsize, int stride) +{ + /* Negative levels are never allowed. */ + if (level < 0) { + return false; + } + + if (is_aa64) { + unsigned int pamax = arm_pamax(cpu); + + switch (stride) { + case 13: /* 64KB Pages. */ + if (level == 0 || (level == 1 && pamax <= 42)) { + return false; + } + break; + case 11: /* 16KB Pages. */ + if (level == 0 || (level == 1 && pamax <= 40)) { + return false; + } + break; + case 9: /* 4KB Pages. */ + if (level == 0 && pamax <= 42) { + return false; + } + break; + default: + g_assert_not_reached(); + } + } else { + const int grainsize = stride + 3; + int startsizecheck; + + /* AArch32 only supports 4KB pages. Assert on that. */ + assert(stride == 9); + + if (level == 0) { + return false; + } + + startsizecheck = inputsize - ((3 - level) * stride + grainsize); + if (startsizecheck < 1 || startsizecheck > stride + 4) { + return false; + } + } + return true; +} + +static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot, + target_ulong *page_size_ptr, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + /* Read an LPAE long-descriptor translation table. */ + MMUFaultType fault_type = translation_fault; + uint32_t level = 1; + uint32_t epd = 0; + int32_t t0sz, t1sz; + uint32_t tg; + uint64_t ttbr; + int ttbr_select; + hwaddr descaddr, descmask; + uint32_t tableattrs; + target_ulong page_size; + uint32_t attrs; + int32_t stride = 9; + int32_t va_size = 32; + int inputsize; + int32_t tbi = 0; + TCR *tcr = regime_tcr(env, mmu_idx); + int ap, ns, xn, pxn; + uint32_t el = regime_el(env, mmu_idx); + bool ttbr1_valid = true; + uint64_t descaddrmask; + + /* TODO: + * This code does not handle the different format TCR for VTCR_EL2. + * This code also does not support shareability levels. + * Attribute and permission bit handling should also be checked when adding + * support for those page table walks. + */ + if (arm_el_is_aa64(env, el)) { + va_size = 64; + if (el > 1) { + if (mmu_idx != ARMMMUIdx_S2NS) { + tbi = extract64(tcr->raw_tcr, 20, 1); + } + } else { + if (extract64(address, 55, 1)) { + tbi = extract64(tcr->raw_tcr, 38, 1); + } else { + tbi = extract64(tcr->raw_tcr, 37, 1); + } + } + tbi *= 8; + + /* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it + * invalid. + */ + if (el > 1) { + ttbr1_valid = false; + } + } else { + /* There is no TTBR1 for EL2 */ + if (el == 2) { + ttbr1_valid = false; + } + } + + /* Determine whether this address is in the region controlled by + * TTBR0 or TTBR1 (or if it is in neither region and should fault). + * This is a Non-secure PL0/1 stage 1 translation, so controlled by + * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32: + */ + if (va_size == 64) { + /* AArch64 translation. */ + t0sz = extract32(tcr->raw_tcr, 0, 6); + t0sz = MIN(t0sz, 39); + t0sz = MAX(t0sz, 16); + } else if (mmu_idx != ARMMMUIdx_S2NS) { + /* AArch32 stage 1 translation. */ + t0sz = extract32(tcr->raw_tcr, 0, 3); + } else { + /* AArch32 stage 2 translation. */ + bool sext = extract32(tcr->raw_tcr, 4, 1); + bool sign = extract32(tcr->raw_tcr, 3, 1); + t0sz = sextract32(tcr->raw_tcr, 0, 4); + + /* If the sign-extend bit is not the same as t0sz[3], the result + * is unpredictable. Flag this as a guest error. */ + if (sign != sext) { + qemu_log_mask(LOG_GUEST_ERROR, + "AArch32: VTCR.S / VTCR.T0SZ[3] missmatch\n"); + } + } + t1sz = extract32(tcr->raw_tcr, 16, 6); + if (va_size == 64) { + t1sz = MIN(t1sz, 39); + t1sz = MAX(t1sz, 16); + } + if (t0sz && !extract64(address, va_size - t0sz, t0sz - tbi)) { + /* there is a ttbr0 region and we are in it (high bits all zero) */ + ttbr_select = 0; + } else if (ttbr1_valid && t1sz && + !extract64(~address, va_size - t1sz, t1sz - tbi)) { + /* there is a ttbr1 region and we are in it (high bits all one) */ + ttbr_select = 1; + } else if (!t0sz) { + /* ttbr0 region is "everything not in the ttbr1 region" */ + ttbr_select = 0; + } else if (!t1sz && ttbr1_valid) { + /* ttbr1 region is "everything not in the ttbr0 region" */ + ttbr_select = 1; + } else { + /* in the gap between the two regions, this is a Translation fault */ + fault_type = translation_fault; + goto do_fault; + } + + /* Note that QEMU ignores shareability and cacheability attributes, + * so we don't need to do anything with the SH, ORGN, IRGN fields + * in the TTBCR. Similarly, TTBCR:A1 selects whether we get the + * ASID from TTBR0 or TTBR1, but QEMU's TLB doesn't currently + * implement any ASID-like capability so we can ignore it (instead + * we will always flush the TLB any time the ASID is changed). + */ + if (ttbr_select == 0) { + ttbr = regime_ttbr(env, mmu_idx, 0); + if (el < 2) { + epd = extract32(tcr->raw_tcr, 7, 1); + } + inputsize = va_size - t0sz; + + tg = extract32(tcr->raw_tcr, 14, 2); + if (tg == 1) { /* 64KB pages */ + stride = 13; + } + if (tg == 2) { /* 16KB pages */ + stride = 11; + } + } else { + /* We should only be here if TTBR1 is valid */ + assert(ttbr1_valid); + + ttbr = regime_ttbr(env, mmu_idx, 1); + epd = extract32(tcr->raw_tcr, 23, 1); + inputsize = va_size - t1sz; + + tg = extract32(tcr->raw_tcr, 30, 2); + if (tg == 3) { /* 64KB pages */ + stride = 13; + } + if (tg == 1) { /* 16KB pages */ + stride = 11; + } + } + + /* Here we should have set up all the parameters for the translation: + * va_size, inputsize, ttbr, epd, stride, tbi + */ + + if (epd) { + /* Translation table walk disabled => Translation fault on TLB miss + * Note: This is always 0 on 64-bit EL2 and EL3. + */ + goto do_fault; + } + + if (mmu_idx != ARMMMUIdx_S2NS) { + /* The starting level depends on the virtual address size (which can + * be up to 48 bits) and the translation granule size. It indicates + * the number of strides (stride bits at a time) needed to + * consume the bits of the input address. In the pseudocode this is: + * level = 4 - RoundUp((inputsize - grainsize) / stride) + * where their 'inputsize' is our 'inputsize', 'grainsize' is + * our 'stride + 3' and 'stride' is our 'stride'. + * Applying the usual "rounded up m/n is (m+n-1)/n" and simplifying: + * = 4 - (inputsize - stride - 3 + stride - 1) / stride + * = 4 - (inputsize - 4) / stride; + */ + level = 4 - (inputsize - 4) / stride; + } else { + /* For stage 2 translations the starting level is specified by the + * VTCR_EL2.SL0 field (whose interpretation depends on the page size) + */ + int startlevel = extract32(tcr->raw_tcr, 6, 2); + bool ok; + + if (va_size == 32 || stride == 9) { + /* AArch32 or 4KB pages */ + level = 2 - startlevel; + } else { + /* 16KB or 64KB pages */ + level = 3 - startlevel; + } + + /* Check that the starting level is valid. */ + ok = check_s2_startlevel(cpu, va_size == 64, level, + inputsize, stride); + if (!ok) { + /* AArch64 reports these as level 0 faults. + * AArch32 reports these as level 1 faults. + */ + level = va_size == 64 ? 0 : 1; + fault_type = translation_fault; + goto do_fault; + } + } + + /* Clear the vaddr bits which aren't part of the within-region address, + * so that we don't have to special case things when calculating the + * first descriptor address. + */ + if (va_size != inputsize) { + address &= (1ULL << inputsize) - 1; + } + + descmask = (1ULL << (stride + 3)) - 1; + + /* Now we can extract the actual base address from the TTBR */ + descaddr = extract64(ttbr, 0, 48); + descaddr &= ~((1ULL << (inputsize - (stride * (4 - level)))) - 1); + + /* The address field in the descriptor goes up to bit 39 for ARMv7 + * but up to bit 47 for ARMv8. + */ + if (arm_feature(env, ARM_FEATURE_V8)) { + descaddrmask = 0xfffffffff000ULL; + } else { + descaddrmask = 0xfffffff000ULL; + } + + /* Secure accesses start with the page table in secure memory and + * can be downgraded to non-secure at any step. Non-secure accesses + * remain non-secure. We implement this by just ORing in the NSTable/NS + * bits at each step. + */ + tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4); + for (;;) { + uint64_t descriptor; + bool nstable; + + descaddr |= (address >> (stride * (4 - level))) & descmask; + descaddr &= ~7ULL; + nstable = extract32(tableattrs, 4, 1); + descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi); + if (fi->s1ptw) { + goto do_fault; + } + + if (!(descriptor & 1) || + (!(descriptor & 2) && (level == 3))) { + /* Invalid, or the Reserved level 3 encoding */ + goto do_fault; + } + descaddr = descriptor & descaddrmask; + + if ((descriptor & 2) && (level < 3)) { + /* Table entry. The top five bits are attributes which may + * propagate down through lower levels of the table (and + * which are all arranged so that 0 means "no effect", so + * we can gather them up by ORing in the bits at each level). + */ + tableattrs |= extract64(descriptor, 59, 5); + level++; + continue; + } + /* Block entry at level 1 or 2, or page entry at level 3. + * These are basically the same thing, although the number + * of bits we pull in from the vaddr varies. + */ + page_size = (1ULL << ((stride * (4 - level)) + 3)); + descaddr |= (address & (page_size - 1)); + /* Extract attributes from the descriptor */ + attrs = extract64(descriptor, 2, 10) + | (extract64(descriptor, 52, 12) << 10); + + if (mmu_idx == ARMMMUIdx_S2NS) { + /* Stage 2 table descriptors do not include any attribute fields */ + break; + } + /* Merge in attributes from table descriptors */ + attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ + attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */ + /* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 + * means "force PL1 access only", which means forcing AP[1] to 0. + */ + if (extract32(tableattrs, 2, 1)) { + attrs &= ~(1 << 4); + } + attrs |= nstable << 3; /* NS */ + break; + } + /* Here descaddr is the final physical address, and attributes + * are all in attrs. + */ + fault_type = access_fault; + if ((attrs & (1 << 8)) == 0) { + /* Access flag */ + goto do_fault; + } + + ap = extract32(attrs, 4, 2); + xn = extract32(attrs, 12, 1); + + if (mmu_idx == ARMMMUIdx_S2NS) { + ns = true; + *prot = get_S2prot(env, ap, xn); + } else { + ns = extract32(attrs, 3, 1); + pxn = extract32(attrs, 11, 1); + *prot = get_S1prot(env, mmu_idx, va_size == 64, ap, ns, xn, pxn); + } + + fault_type = permission_fault; + if (!(*prot & (1 << access_type))) { + goto do_fault; + } + + if (ns) { + /* The NS bit will (as required by the architecture) have no effect if + * the CPU doesn't support TZ or this is a non-secure translation + * regime, because the attribute will already be non-secure. + */ + txattrs->secure = false; + } + *phys_ptr = descaddr; + *page_size_ptr = page_size; + return false; + +do_fault: + /* Long-descriptor format IFSR/DFSR value */ + *fsr = (1 << 9) | (fault_type << 2) | level; + /* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */ + fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS); + return true; +} + +static inline void get_phys_addr_pmsav7_default(CPUARMState *env, + ARMMMUIdx mmu_idx, + int32_t address, int *prot) +{ + *prot = PAGE_READ | PAGE_WRITE; + switch (address) { + case 0xF0000000 ... 0xFFFFFFFF: + if (regime_sctlr(env, mmu_idx) & SCTLR_V) { /* hivecs execing is ok */ + *prot |= PAGE_EXEC; + } + break; + case 0x00000000 ... 0x7FFFFFFF: + *prot |= PAGE_EXEC; + break; + } + +} + +static inline void get_phys_addr_v7m_default(CPUARMState *env, + ARMMMUIdx mmu_idx, + int32_t address, int *prot) +{ + *prot = PAGE_READ | PAGE_WRITE; + switch (address) { + case 0xFFFFF000 ... 0xFFFFFFFF: + /* the special exception return address memory region is EXEC only */ + *prot = PAGE_EXEC; + break; + + case 0x00000000 ... 0x1FFFFFFF: + case 0x20000000 ... 0x3FFFFFFF: + case 0x60000000 ... 0x7FFFFFFF: + case 0x80000000 ... 0x9FFFFFFF: + *prot |= PAGE_EXEC; + break; + } +} + +#if 1 +static bool get_phys_addr_pmsav7_regions(CPUARMState *env, uint32_t address, + ARMMMUIdx mmu_idx, int *prot) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + bool is_user = regime_is_user(env, mmu_idx); + int match = -1; + for (int n = 0; n < cpu->pmsav7_dregion; ++n) { + /* region search */ + uint32_t base = env->pmsav7.drbar[n]; + uint32_t rsizebits = extract32(env->pmsav7.drsr[n], 1, 5); + uint32_t rsize = 1 << (rsizebits + 1); + bool enabled = (env->pmsav7.drsr[n] & 0x1); + bool outside_range = (address < base) || (address >= (base + rsize)); + if (!enabled) { + continue; + } + if (outside_range) { + continue; + } + if (rsize >= 256) { /* subregions only if region is big enough */ + uint32_t region_size = rsize / 8; + uint32_t region = (address - base) / region_size; + uint8_t srdis = extract32(env->pmsav7.drsr[n], 8, 8); + if (srdis & (1 << region)) { /* disabled - not really a match */ + continue; + } else { + } + } + match = n; + } + if (match == -1) { + return false; /* we didn't match a region or subregion... */ + } + /* set the permissions while we're here... */ + uint32_t ap = extract32(env->pmsav7.dracr[match], 8, 3); + if ((ap == 7) && arm_feature(env, ARM_FEATURE_M)) + ap = 6; + + if (is_user) { /* User mode AP bit decoding */ + switch (ap) { + case 0: + case 1: + case 5: + break; /* no access */ + case 3: + *prot |= PAGE_WRITE; + /* fall through */ + case 2: + case 6: + *prot |= PAGE_READ | PAGE_EXEC; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "Bad value for AP bits in DRACR %" + PRIx32 "\n", ap); + } + } else { /* Priv. mode AP bits decoding */ + switch (ap) { + case 0: + break; /* no access */ + case 1: + case 2: + case 3: + *prot |= PAGE_WRITE; + /* fall through */ + case 5: + case 6: + *prot |= PAGE_READ | PAGE_EXEC; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "Bad value for AP bits in DRACR %" + PRIx32 "\n", ap); + } + } + /* execute never */ + if (env->pmsav7.dracr[match] & (1 << 12)) { + *prot &= ~PAGE_EXEC; + } + return true; +} + +static bool get_phys_addr_pmsav7_sub(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, uint32_t *fsr) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + bool is_user = regime_is_user(env, mmu_idx); + + *phys_ptr = address; + *prot = 0; + + if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ + if (arm_feature(env, ARM_FEATURE_M)) { + get_phys_addr_v7m_default(env, mmu_idx, address, prot); + } else { + get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); + } + } else { /* MPU enabled */ + if (!get_phys_addr_pmsav7_regions(env, address, mmu_idx, prot)) { + if (cpu->pmsav7_dregion && (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR))) { + /* background fault */ + *fsr = 0; + return true; + } + if (arm_feature(env, ARM_FEATURE_M)) { + get_phys_addr_v7m_default(env, mmu_idx, address, prot); + } else { + get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); + } + } + } + + *fsr = 0x00d; /* Permission fault */ + return !(*prot & (1 << access_type)); +} + +#else + +static bool get_phys_addr_pmsav7_sub(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, uint32_t *fsr) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int n; + bool is_user = regime_is_user(env, mmu_idx); + + *phys_ptr = address; + *prot = 0; + + if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ + if (arm_feature(env, ARM_FEATURE_M)) { + get_phys_addr_v7m_default(env, mmu_idx, address, prot); + } else { + get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); + } + } else { /* MPU enabled */ + for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { + /* region search */ + uint32_t base = env->pmsav7.drbar[n]; + uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5); + uint32_t rmask; + bool srdis = false; + + if (!(env->pmsav7.drsr[n] & 0x1)) { + continue; + } + + if (!rsize) { + qemu_log_mask(LOG_GUEST_ERROR, "DRSR.Rsize field can not be 0"); + continue; + } + rsize++; + rmask = (1ull << rsize) - 1; + + if (base & rmask) { + qemu_log_mask(LOG_GUEST_ERROR, "DRBAR %" PRIx32 " misaligned " + "to DRSR region size, mask = %" PRIx32, + base, rmask); + continue; + } + + if (address < base || address > base + rmask) { + continue; + } + + /* Region matched */ + + if (rsize >= 8) { /* no subregions for regions < 256 bytes */ + int i, snd; + uint32_t srdis_mask; + + rsize -= 3; /* sub region size (power of 2) */ + snd = ((address - base) >> rsize) & 0x7; + srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1); + + srdis_mask = srdis ? 0x3 : 0x0; + for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) { + /* This will check in groups of 2, 4 and then 8, whether + * the subregion bits are consistent. rsize is incremented + * back up to give the region size, considering consistent + * adjacent subregions as one region. Stop testing if rsize + * is already big enough for an entire QEMU page. + */ + int snd_rounded = snd & ~(i - 1); + uint32_t srdis_multi = extract32(env->pmsav7.drsr[n], + snd_rounded + 8, i); + if (srdis_mask ^ srdis_multi) { + break; + } + srdis_mask = (srdis_mask << i) | srdis_mask; + rsize++; + } + if (rsize < TARGET_PAGE_BITS) { + qemu_log_mask(LOG_UNIMP, "No support for MPU (sub)region" + "alignment of %" PRIu32 " bits. Minimum is %d\n", + rsize, TARGET_PAGE_BITS); + continue; + } + if (srdis) { + continue; + } + } + break; + } + + if (n == -1) { /* no hits */ + if (cpu->pmsav7_dregion && + (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR))) { + /* background fault */ + *fsr = 0; + return true; + } + if (arm_feature(env, ARM_FEATURE_M)) { + get_phys_addr_v7m_default(env, mmu_idx, address, prot); + } else { + get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); + } + } else { /* a MPU hit! */ + uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3); + if ((ap == 7) && arm_feature(env, ARM_FEATURE_M)) + ap = 6; + + if (is_user) { /* User mode AP bit decoding */ + switch (ap) { + case 0: + case 1: + case 5: + break; /* no access */ + case 3: + *prot |= PAGE_WRITE; + /* fall through */ + case 2: + case 6: + *prot |= PAGE_READ | PAGE_EXEC; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "Bad value for AP bits in DRACR %" + PRIx32 "\n", ap); + } + } else { /* Priv. mode AP bits decoding */ + switch (ap) { + case 0: + break; /* no access */ + case 1: + case 2: + case 3: + *prot |= PAGE_WRITE; + /* fall through */ + case 5: + case 6: + *prot |= PAGE_READ | PAGE_EXEC; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "Bad value for AP bits in DRACR %" + PRIx32 "\n", ap); + } + } + /* execute never */ + if (env->pmsav7.dracr[n] & (1 << 12)) { + *prot &= ~PAGE_EXEC; + } + + } + } + + *fsr = 0x00d; /* Permission fault */ + return !(*prot & (1 << access_type)); +} +#endif + +static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, uint32_t *fsr) +{ + g_mutex_lock(&helper_mmu_lock); + bool ret = get_phys_addr_pmsav7_sub(env, address, access_type, mmu_idx, phys_ptr, prot, fsr); + g_mutex_unlock(&helper_mmu_lock); + return ret; +} +static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, uint32_t *fsr) +{ + int n; + uint32_t mask; + uint32_t base; + bool is_user = regime_is_user(env, mmu_idx); + + *phys_ptr = address; + for (n = 7; n >= 0; n--) { + base = env->cp15.c6_region[n]; + if ((base & 1) == 0) { + continue; + } + mask = 1 << ((base >> 1) & 0x1f); + /* Keep this shift separate from the above to avoid an + (undefined) << 32. */ + mask = (mask << 1) - 1; + if (((base ^ address) & ~mask) == 0) { + break; + } + } + if (n < 0) { + *fsr = 2; + return true; + } + + if (access_type == 2) { + mask = env->cp15.pmsav5_insn_ap; + } else { + mask = env->cp15.pmsav5_data_ap; + } + mask = (mask >> (n * 4)) & 0xf; + switch (mask) { + case 0: + *fsr = 1; + return true; + case 1: + if (is_user) { + *fsr = 1; + return true; + } + *prot = PAGE_READ | PAGE_WRITE; + break; + case 2: + *prot = PAGE_READ; + if (!is_user) { + *prot |= PAGE_WRITE; + } + break; + case 3: + *prot = PAGE_READ | PAGE_WRITE; + break; + case 5: + if (is_user) { + *fsr = 1; + return true; + } + *prot = PAGE_READ; + break; + case 6: + *prot = PAGE_READ; + break; + default: + /* Bad permission. */ + *fsr = 1; + return true; + } + *prot |= PAGE_EXEC; + return false; +} + +/* get_phys_addr - get the physical address for this virtual address + * + * Find the physical address corresponding to the given virtual address, + * by doing a translation table walk on MMU based systems or using the + * MPU state on MPU based systems. + * + * Returns false if the translation was successful. Otherwise, phys_ptr, attrs, + * prot and page_size may not be filled in, and the populated fsr value provides + * information on why the translation aborted, in the format of a + * DFSR/IFSR fault register, with the following caveats: + * * we honour the short vs long DFSR format differences. + * * the WnR bit is never set (the caller must do this). + * * for PSMAv5 based systems we don't bother to return a full FSR format + * value. + * + * @env: CPUARMState + * @address: virtual address to get physical address for + * @access_type: 0 for read, 1 for write, 2 for execute + * @mmu_idx: MMU index indicating required translation regime + * @phys_ptr: set to the physical address corresponding to the virtual address + * @attrs: set to the memory transaction attributes to use + * @prot: set to the permissions for the page containing phys_ptr + * @page_size: set to the size of the page containing phys_ptr + * @fsr: set to the DFSR/IFSR value on failure + */ +static bool get_phys_addr(CPUARMState *env, target_ulong address, + int access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, + target_ulong *page_size, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + + if ((address >= 0x20017F00) && (address < 0x20018020)) { + DPRINTF("get_phys_addr(%08X)\n", address); + } + + if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { + /* Call ourselves recursively to do the stage 1 and then stage 2 + * translations. + */ + if (arm_feature(env, ARM_FEATURE_EL2)) { + hwaddr ipa; + int s2_prot; + int ret; + + ret = get_phys_addr(env, address, access_type, + mmu_idx + ARMMMUIdx_S1NSE0, &ipa, attrs, + prot, page_size, fsr, fi); + + /* If S1 fails or S2 is disabled, return early. */ + if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) { + *phys_ptr = ipa; + return ret; + } + + /* S1 is done. Now do S2 translation. */ + ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS, + phys_ptr, attrs, &s2_prot, + page_size, fsr, fi); + fi->s2addr = ipa; + /* Combine the S1 and S2 perms. */ + *prot &= s2_prot; + return ret; + } else { + /* + * For non-EL2 CPUs a stage1+stage2 translation is just stage 1. + */ + mmu_idx += ARMMMUIdx_S1NSE0; + } + } + + /* The page table entries may downgrade secure to non-secure, but + * cannot upgrade an non-secure translation regime's attributes + * to secure. + */ + attrs->secure = regime_is_secure(env, mmu_idx); + attrs->user = regime_is_user(env, mmu_idx); + + /* Fast Context Switch Extension. This doesn't exist at all in v8. + * In v7 and earlier it affects all stage 1 translations. + */ + if (address < 0x02000000 && mmu_idx != ARMMMUIdx_S2NS + && !arm_feature(env, ARM_FEATURE_V8)) { + if (regime_el(env, mmu_idx) == 3) { + address += env->cp15.fcseidr_s; + } else { + address += env->cp15.fcseidr_ns; + } + } + + /* pmsav7 has special handling for when MPU is disabled so call it before + * the common MMU/MPU disabled check below. + */ + if (arm_feature(env, ARM_FEATURE_MPU) && + arm_feature(env, ARM_FEATURE_V7)) { + *page_size = TARGET_PAGE_SIZE; + return get_phys_addr_pmsav7(env, address, access_type, mmu_idx, + phys_ptr, prot, fsr); + } + + if (regime_translation_disabled(env, mmu_idx)) { + /* MMU/MPU disabled. */ + *phys_ptr = address; + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + *page_size = TARGET_PAGE_SIZE; + return 0; + } + + if (arm_feature(env, ARM_FEATURE_MPU)) { + /* Pre-v7 MPU */ + *page_size = TARGET_PAGE_SIZE; + return get_phys_addr_pmsav5(env, address, access_type, mmu_idx, + phys_ptr, prot, fsr); + } + + if (regime_using_lpae_format(env, mmu_idx)) { + return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr, + attrs, prot, page_size, fsr, fi); + } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { + return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr, + attrs, prot, page_size, fsr, fi); + } else { + return get_phys_addr_v5(env, address, access_type, mmu_idx, phys_ptr, + prot, page_size, fsr, fi); + } +} + +/* Walk the page table and (if the mapping exists) add the page + * to the TLB. Return false on success, or true on failure. Populate + * fsr with ARM DFSR/IFSR fault register format value on failure. + */ +bool arm_tlb_fill(CPUState *cs, vaddr address, + int access_type, int mmu_idx, uint32_t *fsr, + ARMMMUFaultInfo *fi) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + hwaddr phys_addr; + target_ulong page_size; + int prot; + int ret; + MemTxAttrs attrs = {}; + + ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr, + &attrs, &prot, &page_size, fsr, fi); + if (!ret) { + /* Map a single [sub]page. */ + phys_addr &= TARGET_PAGE_MASK; + address &= TARGET_PAGE_MASK; + tlb_set_page_with_attrs(cs, address, phys_addr, attrs, + prot, mmu_idx, page_size); + return 0; + } + + return ret; +} + +hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + hwaddr phys_addr; + target_ulong page_size; + int prot; + bool ret; + uint32_t fsr; + MemTxAttrs attrs = {}; + ARMMMUFaultInfo fi = {}; + + ret = get_phys_addr(env, addr, 0, cpu_mmu_index(env, false), &phys_addr, + &attrs, &prot, &page_size, &fsr, &fi); + + if (ret) { + return -1; + } + + return phys_addr; +} + +void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val) +{ + if ((env->uncached_cpsr & CPSR_M) == mode) { + env->regs[13] = val; + } else { + env->banked_r13[bank_number(mode)] = val; + } +} + +uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode) +{ + if ((env->uncached_cpsr & CPSR_M) == mode) { + return env->regs[13]; + } else { + return env->banked_r13[bank_number(mode)]; + } +} + +uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + switch (reg) { + case 0: /* APSR */ + return xpsr_read(env) & 0xf8000000; + case 1: /* IAPSR */ + return xpsr_read(env) & 0xf80001ff; + case 2: /* EAPSR */ + return xpsr_read(env) & 0xff00fc00; + case 3: /* xPSR */ + return xpsr_read(env) & 0xff00fdff; + case 5: /* IPSR */ + return xpsr_read(env) & 0x000001ff; + case 6: /* EPSR */ + return xpsr_read(env) & 0x0700fc00; + case 7: /* IEPSR */ + return xpsr_read(env) & 0x0700edff; + case 8: /* MSP */ + return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]; + case 9: /* PSP */ + return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp; + case 16: /* PRIMASK */ + return (env->daif & PSTATE_I) != 0; + case 17: /* BASEPRI */ + case 18: /* BASEPRI_MAX */ + return env->v7m.basepri; + case 19: /* FAULTMASK */ + return (env->daif & PSTATE_F) != 0; + case 20: /* CONTROL */ + return env->v7m.control; + default: + /* ??? For debugging only. */ + cpu_abort(CPU(cpu), "Unimplemented system register read (%d)\n", reg); + return 0; + } +} + +void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + switch (reg) { + case 0: /* APSR */ + xpsr_write(env, val, 0xf8000000); + break; + case 1: /* IAPSR */ + xpsr_write(env, val, 0xf8000000); + break; + case 2: /* EAPSR */ + xpsr_write(env, val, 0xfe00fc00); + break; + case 3: /* xPSR */ + xpsr_write(env, val, 0xfe00fc00); + break; + case 5: /* IPSR */ + /* IPSR bits are readonly. */ + break; + case 6: /* EPSR */ + xpsr_write(env, val, 0x0600fc00); + break; + case 7: /* IEPSR */ + xpsr_write(env, val, 0x0600fc00); + break; + case 8: /* MSP */ + if (env->v7m.current_sp) + env->v7m.other_sp = val; + else + env->regs[13] = val; + break; + case 9: /* PSP */ + if (env->v7m.current_sp) + env->regs[13] = val; + else + env->v7m.other_sp = val; + break; + case 16: /* PRIMASK */ + if (val & 1) { + env->daif |= PSTATE_I; + } else { + env->daif &= ~PSTATE_I; + } + break; + case 17: /* BASEPRI */ + env->v7m.basepri = val & 0xff; + armv7m_nvic_set_base_priority(env->nvic, env->v7m.basepri); + break; + case 18: /* BASEPRI_MAX */ + val &= 0xff; + if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) { + env->v7m.basepri = val; + armv7m_nvic_set_base_priority(env->nvic, env->v7m.basepri); + } + break; + case 19: /* FAULTMASK */ + if (val & 1) { + env->daif |= PSTATE_F; + } else { + env->daif &= ~PSTATE_F; + } + break; + case 20: /* CONTROL */ + env->v7m.control = val & 3; + switch_v7m_sp(env, (env->v7m.exception == 0) && ((val & 2) != 0)); + break; + default: + /* ??? For debugging only. */ + cpu_abort(CPU(cpu), "Unimplemented system register write (%d)\n", reg); + return; + } +} + +#endif + +void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) +{ + /* Implement DC ZVA, which zeroes a fixed-length block of memory. + * Note that we do not implement the (architecturally mandated) + * alignment fault for attempts to use this on Device memory + * (which matches the usual QEMU behaviour of not implementing either + * alignment faults or any memory attribute handling). + */ + + ARMCPU *cpu = arm_env_get_cpu(env); + uint64_t blocklen = 4 << cpu->dcz_blocksize; + uint64_t vaddr = vaddr_in & ~(blocklen - 1); + +#ifndef CONFIG_USER_ONLY + { + /* Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than + * the block size so we might have to do more than one TLB lookup. + * We know that in fact for any v8 CPU the page size is at least 4K + * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only + * 1K as an artefact of legacy v5 subpage support being present in the + * same QEMU executable. + */ + int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE); + void *hostaddr[maxidx]; + int try, i; + unsigned mmu_idx = cpu_mmu_index(env, false); + TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx); + + for (try = 0; try < 2; try++) { + + for (i = 0; i < maxidx; i++) { + hostaddr[i] = tlb_vaddr_to_host(env, + vaddr + TARGET_PAGE_SIZE * i, + 1, mmu_idx); + if (!hostaddr[i]) { + break; + } + } + if (i == maxidx) { + /* If it's all in the TLB it's fair game for just writing to; + * we know we don't need to update dirty status, etc. + */ + for (i = 0; i < maxidx - 1; i++) { + memset(hostaddr[i], 0, TARGET_PAGE_SIZE); + } + memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE)); + return; + } + /* OK, try a store and see if we can populate the tlb. This + * might cause an exception if the memory isn't writable, + * in which case we will longjmp out of here. We must for + * this purpose use the actual register value passed to us + * so that we get the fault address right. + */ + helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETRA()); + /* Now we can populate the other TLB entries, if any */ + for (i = 0; i < maxidx; i++) { + uint64_t va = vaddr + TARGET_PAGE_SIZE * i; + if (va != (vaddr_in & TARGET_PAGE_MASK)) { + helper_ret_stb_mmu(env, va, 0, oi, GETRA()); + } + } + } + + /* Slow path (probably attempt to do this to an I/O device or + * similar, or clearing of a block of code we have translations + * cached for). Just do a series of byte writes as the architecture + * demands. It's not worth trying to use a cpu_physical_memory_map(), + * memset(), unmap() sequence here because: + * + we'd need to account for the blocksize being larger than a page + * + the direct-RAM access case is almost always going to be dealt + * with in the fastpath code above, so there's no speed benefit + * + we would have to deal with the map returning NULL because the + * bounce buffer was in use + */ + for (i = 0; i < blocklen; i++) { + helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETRA()); + } + } +#else + memset(g2h(vaddr), 0, blocklen); +#endif +} + +/* Note that signed overflow is undefined in C. The following routines are + careful to use unsigned types where modulo arithmetic is required. + Failure to do so _will_ break on newer gcc. */ + +/* Signed saturating arithmetic. */ + +/* Perform 16-bit signed saturating addition. */ +static inline uint16_t add16_sat(uint16_t a, uint16_t b) +{ + uint16_t res; + + res = a + b; + if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) { + if (a & 0x8000) + res = 0x8000; + else + res = 0x7fff; + } + return res; +} + +/* Perform 8-bit signed saturating addition. */ +static inline uint8_t add8_sat(uint8_t a, uint8_t b) +{ + uint8_t res; + + res = a + b; + if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) { + if (a & 0x80) + res = 0x80; + else + res = 0x7f; + } + return res; +} + +/* Perform 16-bit signed saturating subtraction. */ +static inline uint16_t sub16_sat(uint16_t a, uint16_t b) +{ + uint16_t res; + + res = a - b; + if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) { + if (a & 0x8000) + res = 0x8000; + else + res = 0x7fff; + } + return res; +} + +/* Perform 8-bit signed saturating subtraction. */ +static inline uint8_t sub8_sat(uint8_t a, uint8_t b) +{ + uint8_t res; + + res = a - b; + if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) { + if (a & 0x80) + res = 0x80; + else + res = 0x7f; + } + return res; +} + +#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16); +#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16); +#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8); +#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8); +#define PFX q + +#include "op_addsub.h" + +/* Unsigned saturating arithmetic. */ +static inline uint16_t add16_usat(uint16_t a, uint16_t b) +{ + uint16_t res; + res = a + b; + if (res < a) + res = 0xffff; + return res; +} + +static inline uint16_t sub16_usat(uint16_t a, uint16_t b) +{ + if (a > b) + return a - b; + else + return 0; +} + +static inline uint8_t add8_usat(uint8_t a, uint8_t b) +{ + uint8_t res; + res = a + b; + if (res < a) + res = 0xff; + return res; +} + +static inline uint8_t sub8_usat(uint8_t a, uint8_t b) +{ + if (a > b) + return a - b; + else + return 0; +} + +#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16); +#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16); +#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8); +#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8); +#define PFX uq + +#include "op_addsub.h" + +/* Signed modulo arithmetic. */ +#define SARITH16(a, b, n, op) do { \ + int32_t sum; \ + sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \ + RESULT(sum, n, 16); \ + if (sum >= 0) \ + ge |= 3 << (n * 2); \ + } while(0) + +#define SARITH8(a, b, n, op) do { \ + int32_t sum; \ + sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \ + RESULT(sum, n, 8); \ + if (sum >= 0) \ + ge |= 1 << n; \ + } while(0) + + +#define ADD16(a, b, n) SARITH16(a, b, n, +) +#define SUB16(a, b, n) SARITH16(a, b, n, -) +#define ADD8(a, b, n) SARITH8(a, b, n, +) +#define SUB8(a, b, n) SARITH8(a, b, n, -) +#define PFX s +#define ARITH_GE + +#include "op_addsub.h" + +/* Unsigned modulo arithmetic. */ +#define ADD16(a, b, n) do { \ + uint32_t sum; \ + sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \ + RESULT(sum, n, 16); \ + if ((sum >> 16) == 1) \ + ge |= 3 << (n * 2); \ + } while(0) + +#define ADD8(a, b, n) do { \ + uint32_t sum; \ + sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \ + RESULT(sum, n, 8); \ + if ((sum >> 8) == 1) \ + ge |= 1 << n; \ + } while(0) + +#define SUB16(a, b, n) do { \ + uint32_t sum; \ + sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \ + RESULT(sum, n, 16); \ + if ((sum >> 16) == 0) \ + ge |= 3 << (n * 2); \ + } while(0) + +#define SUB8(a, b, n) do { \ + uint32_t sum; \ + sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \ + RESULT(sum, n, 8); \ + if ((sum >> 8) == 0) \ + ge |= 1 << n; \ + } while(0) + +#define PFX u +#define ARITH_GE + +#include "op_addsub.h" + +/* Halved signed arithmetic. */ +#define ADD16(a, b, n) \ + RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16) +#define SUB16(a, b, n) \ + RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16) +#define ADD8(a, b, n) \ + RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8) +#define SUB8(a, b, n) \ + RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8) +#define PFX sh + +#include "op_addsub.h" + +/* Halved unsigned arithmetic. */ +#define ADD16(a, b, n) \ + RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16) +#define SUB16(a, b, n) \ + RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16) +#define ADD8(a, b, n) \ + RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8) +#define SUB8(a, b, n) \ + RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8) +#define PFX uh + +#include "op_addsub.h" + +static inline uint8_t do_usad(uint8_t a, uint8_t b) +{ + if (a > b) + return a - b; + else + return b - a; +} + +/* Unsigned sum of absolute byte differences. */ +uint32_t HELPER(usad8)(uint32_t a, uint32_t b) +{ + uint32_t sum; + sum = do_usad(a, b); + sum += do_usad(a >> 8, b >> 8); + sum += do_usad(a >> 16, b >>16); + sum += do_usad(a >> 24, b >> 24); + return sum; +} + +/* For ARMv6 SEL instruction. */ +uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) +{ + uint32_t mask; + + mask = 0; + if (flags & 1) + mask |= 0xff; + if (flags & 2) + mask |= 0xff00; + if (flags & 4) + mask |= 0xff0000; + if (flags & 8) + mask |= 0xff000000; + return (a & mask) | (b & ~mask); +} + +/* VFP support. We follow the convention used for VFP instructions: + Single precision routines have a "s" suffix, double precision a + "d" suffix. */ + +/* Convert host exception flags to vfp form. */ +static inline int vfp_exceptbits_from_host(int host_bits) +{ + int target_bits = 0; + + if (host_bits & float_flag_invalid) + target_bits |= 1; + if (host_bits & float_flag_divbyzero) + target_bits |= 2; + if (host_bits & float_flag_overflow) + target_bits |= 4; + if (host_bits & (float_flag_underflow | float_flag_output_denormal)) + target_bits |= 8; + if (host_bits & float_flag_inexact) + target_bits |= 0x10; + if (host_bits & float_flag_input_denormal) + target_bits |= 0x80; + return target_bits; +} + +uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env) +{ + int i; + uint32_t fpscr; + + fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff) + | (env->vfp.vec_len << 16) + | (env->vfp.vec_stride << 20); + i = get_float_exception_flags(&env->vfp.fp_status); + i |= get_float_exception_flags(&env->vfp.standard_fp_status); + fpscr |= vfp_exceptbits_from_host(i); + return fpscr; +} + +uint32_t vfp_get_fpscr(CPUARMState *env) +{ + return HELPER(vfp_get_fpscr)(env); +} + +/* Convert vfp exception flags to target form. */ +static inline int vfp_exceptbits_to_host(int target_bits) +{ + int host_bits = 0; + + if (target_bits & 1) + host_bits |= float_flag_invalid; + if (target_bits & 2) + host_bits |= float_flag_divbyzero; + if (target_bits & 4) + host_bits |= float_flag_overflow; + if (target_bits & 8) + host_bits |= float_flag_underflow; + if (target_bits & 0x10) + host_bits |= float_flag_inexact; + if (target_bits & 0x80) + host_bits |= float_flag_input_denormal; + return host_bits; +} + +void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) +{ + int i; + uint32_t changed; + + changed = env->vfp.xregs[ARM_VFP_FPSCR]; + env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff); + env->vfp.vec_len = (val >> 16) & 7; + env->vfp.vec_stride = (val >> 20) & 3; + + changed ^= val; + if (changed & (3 << 22)) { + i = (val >> 22) & 3; + switch (i) { + case FPROUNDING_TIEEVEN: + i = float_round_nearest_even; + break; + case FPROUNDING_POSINF: + i = float_round_up; + break; + case FPROUNDING_NEGINF: + i = float_round_down; + break; + case FPROUNDING_ZERO: + i = float_round_to_zero; + break; + } + set_float_rounding_mode(i, &env->vfp.fp_status); + } + if (changed & (1 << 24)) { + set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status); + set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status); + } + if (changed & (1 << 25)) + set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status); + + i = vfp_exceptbits_to_host(val); + set_float_exception_flags(i, &env->vfp.fp_status); + set_float_exception_flags(0, &env->vfp.standard_fp_status); +} + +void vfp_set_fpscr(CPUARMState *env, uint32_t val) +{ + HELPER(vfp_set_fpscr)(env, val); +} + +#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p)) + +#define VFP_BINOP(name) \ +float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + return float32_ ## name(a, b, fpst); \ +} \ +float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + return float64_ ## name(a, b, fpst); \ +} +VFP_BINOP(add) +VFP_BINOP(sub) +VFP_BINOP(mul) +VFP_BINOP(div) +VFP_BINOP(min) +VFP_BINOP(max) +VFP_BINOP(minnum) +VFP_BINOP(maxnum) +#undef VFP_BINOP + +float32 VFP_HELPER(neg, s)(float32 a) +{ + return float32_chs(a); +} + +float64 VFP_HELPER(neg, d)(float64 a) +{ + return float64_chs(a); +} + +float32 VFP_HELPER(abs, s)(float32 a) +{ + return float32_abs(a); +} + +float64 VFP_HELPER(abs, d)(float64 a) +{ + return float64_abs(a); +} + +float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env) +{ + return float32_sqrt(a, &env->vfp.fp_status); +} + +float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env) +{ + return float64_sqrt(a, &env->vfp.fp_status); +} + +/* XXX: check quiet/signaling case */ +#define DO_VFP_cmp(p, type) \ +void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ +{ \ + uint32_t flags; \ + switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \ + case 0: flags = 0x6; break; \ + case -1: flags = 0x8; break; \ + case 1: flags = 0x2; break; \ + default: case 2: flags = 0x3; break; \ + } \ + env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ + | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ +} \ +void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ +{ \ + uint32_t flags; \ + switch(type ## _compare(a, b, &env->vfp.fp_status)) { \ + case 0: flags = 0x6; break; \ + case -1: flags = 0x8; break; \ + case 1: flags = 0x2; break; \ + default: case 2: flags = 0x3; break; \ + } \ + env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ + | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ +} +DO_VFP_cmp(s, float32) +DO_VFP_cmp(d, float64) +#undef DO_VFP_cmp + +/* Integer to float and float to integer conversions */ + +#define CONV_ITOF(name, fsz, sign) \ + float##fsz HELPER(name)(uint32_t x, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \ +} + +#define CONV_FTOI(name, fsz, sign, round) \ +uint32_t HELPER(name)(float##fsz x, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + if (float##fsz##_is_any_nan(x)) { \ + float_raise(float_flag_invalid, fpst); \ + return 0; \ + } \ + return float##fsz##_to_##sign##int32##round(x, fpst); \ +} + +#define FLOAT_CONVS(name, p, fsz, sign) \ +CONV_ITOF(vfp_##name##to##p, fsz, sign) \ +CONV_FTOI(vfp_to##name##p, fsz, sign, ) \ +CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero) + +FLOAT_CONVS(si, s, 32, ) +FLOAT_CONVS(si, d, 64, ) +FLOAT_CONVS(ui, s, 32, u) +FLOAT_CONVS(ui, d, 64, u) + +#undef CONV_ITOF +#undef CONV_FTOI +#undef FLOAT_CONVS + +/* floating point conversion */ +float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env) +{ + float64 r = float32_to_float64(x, &env->vfp.fp_status); + /* ARM requires that S<->D conversion of any kind of NaN generates + * a quiet NaN by forcing the most significant frac bit to 1. + */ + return float64_maybe_silence_nan(r); +} + +float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env) +{ + float32 r = float64_to_float32(x, &env->vfp.fp_status); + /* ARM requires that S<->D conversion of any kind of NaN generates + * a quiet NaN by forcing the most significant frac bit to 1. + */ + return float32_maybe_silence_nan(r); +} + +/* VFP3 fixed point conversion. */ +#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ +float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ + void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + float##fsz tmp; \ + tmp = itype##_to_##float##fsz(x, fpst); \ + return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ +} + +/* Notice that we want only input-denormal exception flags from the + * scalbn operation: the other possible flags (overflow+inexact if + * we overflow to infinity, output-denormal) aren't correct for the + * complete scale-and-convert operation. + */ +#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \ +uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \ + uint32_t shift, \ + void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + int old_exc_flags = get_float_exception_flags(fpst); \ + float##fsz tmp; \ + if (float##fsz##_is_any_nan(x)) { \ + float_raise(float_flag_invalid, fpst); \ + return 0; \ + } \ + tmp = float##fsz##_scalbn(x, shift, fpst); \ + old_exc_flags |= get_float_exception_flags(fpst) \ + & float_flag_input_denormal; \ + set_float_exception_flags(old_exc_flags, fpst); \ + return float##fsz##_to_##itype##round(tmp, fpst); \ +} + +#define VFP_CONV_FIX(name, p, fsz, isz, itype) \ +VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) + +#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \ +VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) + +VFP_CONV_FIX(sh, d, 64, 64, int16) +VFP_CONV_FIX(sl, d, 64, 64, int32) +VFP_CONV_FIX_A64(sq, d, 64, 64, int64) +VFP_CONV_FIX(uh, d, 64, 64, uint16) +VFP_CONV_FIX(ul, d, 64, 64, uint32) +VFP_CONV_FIX_A64(uq, d, 64, 64, uint64) +VFP_CONV_FIX(sh, s, 32, 32, int16) +VFP_CONV_FIX(sl, s, 32, 32, int32) +VFP_CONV_FIX_A64(sq, s, 32, 64, int64) +VFP_CONV_FIX(uh, s, 32, 32, uint16) +VFP_CONV_FIX(ul, s, 32, 32, uint32) +VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) +#undef VFP_CONV_FIX +#undef VFP_CONV_FIX_FLOAT +#undef VFP_CONV_FLOAT_FIX_ROUND + +/* Set the current fp rounding mode and return the old one. + * The argument is a softfloat float_round_ value. + */ +uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env) +{ + float_status *fp_status = &env->vfp.fp_status; + + uint32_t prev_rmode = get_float_rounding_mode(fp_status); + set_float_rounding_mode(rmode, fp_status); + + return prev_rmode; +} + +/* Set the current fp rounding mode in the standard fp status and return + * the old one. This is for NEON instructions that need to change the + * rounding mode but wish to use the standard FPSCR values for everything + * else. Always set the rounding mode back to the correct value after + * modifying it. + * The argument is a softfloat float_round_ value. + */ +uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env) +{ + float_status *fp_status = &env->vfp.standard_fp_status; + + uint32_t prev_rmode = get_float_rounding_mode(fp_status); + set_float_rounding_mode(rmode, fp_status); + + return prev_rmode; +} + +/* Half precision conversions. */ +static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s) +{ + int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; + float32 r = float16_to_float32(make_float16(a), ieee, s); + if (ieee) { + return float32_maybe_silence_nan(r); + } + return r; +} + +static uint32_t do_fcvt_f32_to_f16(float32 a, CPUARMState *env, float_status *s) +{ + int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; + float16 r = float32_to_float16(a, ieee, s); + if (ieee) { + r = float16_maybe_silence_nan(r); + } + return float16_val(r); +} + +float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env) +{ + return do_fcvt_f16_to_f32(a, env, &env->vfp.standard_fp_status); +} + +uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUARMState *env) +{ + return do_fcvt_f32_to_f16(a, env, &env->vfp.standard_fp_status); +} + +float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env) +{ + return do_fcvt_f16_to_f32(a, env, &env->vfp.fp_status); +} + +uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env) +{ + return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status); +} + +float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env) +{ + int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; + float64 r = float16_to_float64(make_float16(a), ieee, &env->vfp.fp_status); + if (ieee) { + return float64_maybe_silence_nan(r); + } + return r; +} + +uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env) +{ + int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; + float16 r = float64_to_float16(a, ieee, &env->vfp.fp_status); + if (ieee) { + r = float16_maybe_silence_nan(r); + } + return float16_val(r); +} + +#define float32_two make_float32(0x40000000) +#define float32_three make_float32(0x40400000) +#define float32_one_point_five make_float32(0x3fc00000) + +float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env) +{ + float_status *s = &env->vfp.standard_fp_status; + if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) || + (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) { + if (!(float32_is_zero(a) || float32_is_zero(b))) { + float_raise(float_flag_input_denormal, s); + } + return float32_two; + } + return float32_sub(float32_two, float32_mul(a, b, s), s); +} + +float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env) +{ + float_status *s = &env->vfp.standard_fp_status; + float32 product; + if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) || + (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) { + if (!(float32_is_zero(a) || float32_is_zero(b))) { + float_raise(float_flag_input_denormal, s); + } + return float32_one_point_five; + } + product = float32_mul(a, b, s); + return float32_div(float32_sub(float32_three, product, s), float32_two, s); +} + +/* NEON helpers. */ + +/* Constants 256 and 512 are used in some helpers; we avoid relying on + * int->float conversions at run-time. */ +#define float64_256 make_float64(0x4070000000000000LL) +#define float64_512 make_float64(0x4080000000000000LL) +#define float32_maxnorm make_float32(0x7f7fffff) +#define float64_maxnorm make_float64(0x7fefffffffffffffLL) + +/* Reciprocal functions + * + * The algorithm that must be used to calculate the estimate + * is specified by the ARM ARM, see FPRecipEstimate() + */ + +static float64 recip_estimate(float64 a, float_status *real_fp_status) +{ + /* These calculations mustn't set any fp exception flags, + * so we use a local copy of the fp_status. + */ + float_status dummy_status = *real_fp_status; + float_status *s = &dummy_status; + /* q = (int)(a * 512.0) */ + float64 q = float64_mul(float64_512, a, s); + int64_t q_int = float64_to_int64_round_to_zero(q, s); + + /* r = 1.0 / (((double)q + 0.5) / 512.0) */ + q = int64_to_float64(q_int, s); + q = float64_add(q, float64_half, s); + q = float64_div(q, float64_512, s); + q = float64_div(float64_one, q, s); + + /* s = (int)(256.0 * r + 0.5) */ + q = float64_mul(q, float64_256, s); + q = float64_add(q, float64_half, s); + q_int = float64_to_int64_round_to_zero(q, s); + + /* return (double)s / 256.0 */ + return float64_div(int64_to_float64(q_int, s), float64_256, s); +} + +/* Common wrapper to call recip_estimate */ +static float64 call_recip_estimate(float64 num, int off, float_status *fpst) +{ + uint64_t val64 = float64_val(num); + uint64_t frac = extract64(val64, 0, 52); + int64_t exp = extract64(val64, 52, 11); + uint64_t sbit; + float64 scaled, estimate; + + /* Generate the scaled number for the estimate function */ + if (exp == 0) { + if (extract64(frac, 51, 1) == 0) { + exp = -1; + frac = extract64(frac, 0, 50) << 2; + } else { + frac = extract64(frac, 0, 51) << 1; + } + } + + /* scaled = '0' : '01111111110' : fraction<51:44> : Zeros(44); */ + scaled = make_float64((0x3feULL << 52) + | extract64(frac, 44, 8) << 44); + + estimate = recip_estimate(scaled, fpst); + + /* Build new result */ + val64 = float64_val(estimate); + sbit = 0x8000000000000000ULL & val64; + exp = off - exp; + frac = extract64(val64, 0, 52); + + if (exp == 0) { + frac = 1ULL << 51 | extract64(frac, 1, 51); + } else if (exp == -1) { + frac = 1ULL << 50 | extract64(frac, 2, 50); + exp = 0; + } + + return make_float64(sbit | (exp << 52) | frac); +} + +static bool round_to_inf(float_status *fpst, bool sign_bit) +{ + switch (fpst->float_rounding_mode) { + case float_round_nearest_even: /* Round to Nearest */ + return true; + case float_round_up: /* Round to +Inf */ + return !sign_bit; + case float_round_down: /* Round to -Inf */ + return sign_bit; + case float_round_to_zero: /* Round to Zero */ + return false; + } + + g_assert_not_reached(); +} + +float32 HELPER(recpe_f32)(float32 input, void *fpstp) +{ + float_status *fpst = fpstp; + float32 f32 = float32_squash_input_denormal(input, fpst); + uint32_t f32_val = float32_val(f32); + uint32_t f32_sbit = 0x80000000ULL & f32_val; + int32_t f32_exp = extract32(f32_val, 23, 8); + uint32_t f32_frac = extract32(f32_val, 0, 23); + float64 f64, r64; + uint64_t r64_val; + int64_t r64_exp; + uint64_t r64_frac; + + if (float32_is_any_nan(f32)) { + float32 nan = f32; + if (float32_is_signaling_nan(f32)) { + float_raise(float_flag_invalid, fpst); + nan = float32_maybe_silence_nan(f32); + } + if (fpst->default_nan_mode) { + nan = float32_default_nan; + } + return nan; + } else if (float32_is_infinity(f32)) { + return float32_set_sign(float32_zero, float32_is_neg(f32)); + } else if (float32_is_zero(f32)) { + float_raise(float_flag_divbyzero, fpst); + return float32_set_sign(float32_infinity, float32_is_neg(f32)); + } else if ((f32_val & ~(1ULL << 31)) < (1ULL << 21)) { + /* Abs(value) < 2.0^-128 */ + float_raise(float_flag_overflow | float_flag_inexact, fpst); + if (round_to_inf(fpst, f32_sbit)) { + return float32_set_sign(float32_infinity, float32_is_neg(f32)); + } else { + return float32_set_sign(float32_maxnorm, float32_is_neg(f32)); + } + } else if (f32_exp >= 253 && fpst->flush_to_zero) { + float_raise(float_flag_underflow, fpst); + return float32_set_sign(float32_zero, float32_is_neg(f32)); + } + + + f64 = make_float64(((int64_t)(f32_exp) << 52) | (int64_t)(f32_frac) << 29); + r64 = call_recip_estimate(f64, 253, fpst); + r64_val = float64_val(r64); + r64_exp = extract64(r64_val, 52, 11); + r64_frac = extract64(r64_val, 0, 52); + + /* result = sign : result_exp<7:0> : fraction<51:29>; */ + return make_float32(f32_sbit | + (r64_exp & 0xff) << 23 | + extract64(r64_frac, 29, 24)); +} + +float64 HELPER(recpe_f64)(float64 input, void *fpstp) +{ + float_status *fpst = fpstp; + float64 f64 = float64_squash_input_denormal(input, fpst); + uint64_t f64_val = float64_val(f64); + uint64_t f64_sbit = 0x8000000000000000ULL & f64_val; + int64_t f64_exp = extract64(f64_val, 52, 11); + float64 r64; + uint64_t r64_val; + int64_t r64_exp; + uint64_t r64_frac; + + /* Deal with any special cases */ + if (float64_is_any_nan(f64)) { + float64 nan = f64; + if (float64_is_signaling_nan(f64)) { + float_raise(float_flag_invalid, fpst); + nan = float64_maybe_silence_nan(f64); + } + if (fpst->default_nan_mode) { + nan = float64_default_nan; + } + return nan; + } else if (float64_is_infinity(f64)) { + return float64_set_sign(float64_zero, float64_is_neg(f64)); + } else if (float64_is_zero(f64)) { + float_raise(float_flag_divbyzero, fpst); + return float64_set_sign(float64_infinity, float64_is_neg(f64)); + } else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) { + /* Abs(value) < 2.0^-1024 */ + float_raise(float_flag_overflow | float_flag_inexact, fpst); + if (round_to_inf(fpst, f64_sbit)) { + return float64_set_sign(float64_infinity, float64_is_neg(f64)); + } else { + return float64_set_sign(float64_maxnorm, float64_is_neg(f64)); + } + } else if (f64_exp >= 2045 && fpst->flush_to_zero) { + float_raise(float_flag_underflow, fpst); + return float64_set_sign(float64_zero, float64_is_neg(f64)); + } + + r64 = call_recip_estimate(f64, 2045, fpst); + r64_val = float64_val(r64); + r64_exp = extract64(r64_val, 52, 11); + r64_frac = extract64(r64_val, 0, 52); + + /* result = sign : result_exp<10:0> : fraction<51:0> */ + return make_float64(f64_sbit | + ((r64_exp & 0x7ff) << 52) | + r64_frac); +} + +/* The algorithm that must be used to calculate the estimate + * is specified by the ARM ARM. + */ +static float64 recip_sqrt_estimate(float64 a, float_status *real_fp_status) +{ + /* These calculations mustn't set any fp exception flags, + * so we use a local copy of the fp_status. + */ + float_status dummy_status = *real_fp_status; + float_status *s = &dummy_status; + float64 q; + int64_t q_int; + + if (float64_lt(a, float64_half, s)) { + /* range 0.25 <= a < 0.5 */ + + /* a in units of 1/512 rounded down */ + /* q0 = (int)(a * 512.0); */ + q = float64_mul(float64_512, a, s); + q_int = float64_to_int64_round_to_zero(q, s); + + /* reciprocal root r */ + /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */ + q = int64_to_float64(q_int, s); + q = float64_add(q, float64_half, s); + q = float64_div(q, float64_512, s); + q = float64_sqrt(q, s); + q = float64_div(float64_one, q, s); + } else { + /* range 0.5 <= a < 1.0 */ + + /* a in units of 1/256 rounded down */ + /* q1 = (int)(a * 256.0); */ + q = float64_mul(float64_256, a, s); + int64_t q_int = float64_to_int64_round_to_zero(q, s); + + /* reciprocal root r */ + /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */ + q = int64_to_float64(q_int, s); + q = float64_add(q, float64_half, s); + q = float64_div(q, float64_256, s); + q = float64_sqrt(q, s); + q = float64_div(float64_one, q, s); + } + /* r in units of 1/256 rounded to nearest */ + /* s = (int)(256.0 * r + 0.5); */ + + q = float64_mul(q, float64_256,s ); + q = float64_add(q, float64_half, s); + q_int = float64_to_int64_round_to_zero(q, s); + + /* return (double)s / 256.0;*/ + return float64_div(int64_to_float64(q_int, s), float64_256, s); +} + +float32 HELPER(rsqrte_f32)(float32 input, void *fpstp) +{ + float_status *s = fpstp; + float32 f32 = float32_squash_input_denormal(input, s); + uint32_t val = float32_val(f32); + uint32_t f32_sbit = 0x80000000 & val; + int32_t f32_exp = extract32(val, 23, 8); + uint32_t f32_frac = extract32(val, 0, 23); + uint64_t f64_frac; + uint64_t val64; + int result_exp; + float64 f64; + + if (float32_is_any_nan(f32)) { + float32 nan = f32; + if (float32_is_signaling_nan(f32)) { + float_raise(float_flag_invalid, s); + nan = float32_maybe_silence_nan(f32); + } + if (s->default_nan_mode) { + nan = float32_default_nan; + } + return nan; + } else if (float32_is_zero(f32)) { + float_raise(float_flag_divbyzero, s); + return float32_set_sign(float32_infinity, float32_is_neg(f32)); + } else if (float32_is_neg(f32)) { + float_raise(float_flag_invalid, s); + return float32_default_nan; + } else if (float32_is_infinity(f32)) { + return float32_zero; + } + + /* Scale and normalize to a double-precision value between 0.25 and 1.0, + * preserving the parity of the exponent. */ + + f64_frac = ((uint64_t) f32_frac) << 29; + if (f32_exp == 0) { + while (extract64(f64_frac, 51, 1) == 0) { + f64_frac = f64_frac << 1; + f32_exp = f32_exp-1; + } + f64_frac = extract64(f64_frac, 0, 51) << 1; + } + + if (extract64(f32_exp, 0, 1) == 0) { + f64 = make_float64(((uint64_t) f32_sbit) << 32 + | (0x3feULL << 52) + | f64_frac); + } else { + f64 = make_float64(((uint64_t) f32_sbit) << 32 + | (0x3fdULL << 52) + | f64_frac); + } + + result_exp = (380 - f32_exp) / 2; + + f64 = recip_sqrt_estimate(f64, s); + + val64 = float64_val(f64); + + val = ((result_exp & 0xff) << 23) + | ((val64 >> 29) & 0x7fffff); + return make_float32(val); +} + +float64 HELPER(rsqrte_f64)(float64 input, void *fpstp) +{ + float_status *s = fpstp; + float64 f64 = float64_squash_input_denormal(input, s); + uint64_t val = float64_val(f64); + uint64_t f64_sbit = 0x8000000000000000ULL & val; + int64_t f64_exp = extract64(val, 52, 11); + uint64_t f64_frac = extract64(val, 0, 52); + int64_t result_exp; + uint64_t result_frac; + + if (float64_is_any_nan(f64)) { + float64 nan = f64; + if (float64_is_signaling_nan(f64)) { + float_raise(float_flag_invalid, s); + nan = float64_maybe_silence_nan(f64); + } + if (s->default_nan_mode) { + nan = float64_default_nan; + } + return nan; + } else if (float64_is_zero(f64)) { + float_raise(float_flag_divbyzero, s); + return float64_set_sign(float64_infinity, float64_is_neg(f64)); + } else if (float64_is_neg(f64)) { + float_raise(float_flag_invalid, s); + return float64_default_nan; + } else if (float64_is_infinity(f64)) { + return float64_zero; + } + + /* Scale and normalize to a double-precision value between 0.25 and 1.0, + * preserving the parity of the exponent. */ + + if (f64_exp == 0) { + while (extract64(f64_frac, 51, 1) == 0) { + f64_frac = f64_frac << 1; + f64_exp = f64_exp - 1; + } + f64_frac = extract64(f64_frac, 0, 51) << 1; + } + + if (extract64(f64_exp, 0, 1) == 0) { + f64 = make_float64(f64_sbit + | (0x3feULL << 52) + | f64_frac); + } else { + f64 = make_float64(f64_sbit + | (0x3fdULL << 52) + | f64_frac); + } + + result_exp = (3068 - f64_exp) / 2; + + f64 = recip_sqrt_estimate(f64, s); + + result_frac = extract64(float64_val(f64), 0, 52); + + return make_float64(f64_sbit | + ((result_exp & 0x7ff) << 52) | + result_frac); +} + +uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp) +{ + float_status *s = fpstp; + float64 f64; + + if ((a & 0x80000000) == 0) { + return 0xffffffff; + } + + f64 = make_float64((0x3feULL << 52) + | ((int64_t)(a & 0x7fffffff) << 21)); + + f64 = recip_estimate(f64, s); + + return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff); +} + +uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp) +{ + float_status *fpst = fpstp; + float64 f64; + + if ((a & 0xc0000000) == 0) { + return 0xffffffff; + } + + if (a & 0x80000000) { + f64 = make_float64((0x3feULL << 52) + | ((uint64_t)(a & 0x7fffffff) << 21)); + } else { /* bits 31-30 == '01' */ + f64 = make_float64((0x3fdULL << 52) + | ((uint64_t)(a & 0x3fffffff) << 22)); + } + + f64 = recip_sqrt_estimate(f64, fpst); + + return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff); +} + +/* VFPv4 fused multiply-accumulate */ +float32 VFP_HELPER(muladd, s)(float32 a, float32 b, float32 c, void *fpstp) +{ + float_status *fpst = fpstp; + return float32_muladd(a, b, c, 0, fpst); +} + +float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp) +{ + float_status *fpst = fpstp; + return float64_muladd(a, b, c, 0, fpst); +} + +/* ARMv8 round to integral */ +float32 HELPER(rints_exact)(float32 x, void *fp_status) +{ + return float32_round_to_int(x, fp_status); +} + +float64 HELPER(rintd_exact)(float64 x, void *fp_status) +{ + return float64_round_to_int(x, fp_status); +} + +float32 HELPER(rints)(float32 x, void *fp_status) +{ + int old_flags = get_float_exception_flags(fp_status), new_flags; + float32 ret; + + ret = float32_round_to_int(x, fp_status); + + /* Suppress any inexact exceptions the conversion produced */ + if (!(old_flags & float_flag_inexact)) { + new_flags = get_float_exception_flags(fp_status); + set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status); + } + + return ret; +} + +float64 HELPER(rintd)(float64 x, void *fp_status) +{ + int old_flags = get_float_exception_flags(fp_status), new_flags; + float64 ret; + + ret = float64_round_to_int(x, fp_status); + + new_flags = get_float_exception_flags(fp_status); + + /* Suppress any inexact exceptions the conversion produced */ + if (!(old_flags & float_flag_inexact)) { + new_flags = get_float_exception_flags(fp_status); + set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status); + } + + return ret; +} + +/* Convert ARM rounding mode to softfloat */ +int arm_rmode_to_sf(int rmode) +{ + switch (rmode) { + case FPROUNDING_TIEAWAY: + rmode = float_round_ties_away; + break; + case FPROUNDING_ODD: + /* FIXME: add support for TIEAWAY and ODD */ + qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n", + rmode); + case FPROUNDING_TIEEVEN: + default: + rmode = float_round_nearest_even; + break; + case FPROUNDING_POSINF: + rmode = float_round_up; + break; + case FPROUNDING_NEGINF: + rmode = float_round_down; + break; + case FPROUNDING_ZERO: + rmode = float_round_to_zero; + break; + } + return rmode; +} + +/* CRC helpers. + * The upper bytes of val (above the number specified by 'bytes') must have + * been zeroed out by the caller. + */ +uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes) +{ + uint8_t buf[4]; + + stl_le_p(buf, val); + + /* zlib crc32 converts the accumulator and output to one's complement. */ + return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff; +} + +uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes) +{ + uint8_t buf[4]; + + stl_le_p(buf, val); + + /* Linux crc32c converts the output to one's complement. */ + return crc32c(acc, buf, bytes) ^ 0xffffffff; +} diff --git a/target-arm/internals.h b/target-arm/internals.h new file mode 100644 index 0000000000000..325c7ea6e6682 --- /dev/null +++ b/target-arm/internals.h @@ -0,0 +1,445 @@ +/* + * QEMU ARM CPU -- internal functions and types + * + * Copyright (c) 2014 Linaro Ltd + * + * 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 + * + * + * This header defines functions, types, etc which need to be shared + * between different source files within target-arm/ but which are + * private to it and not required by the rest of QEMU. + */ + +#ifndef TARGET_ARM_INTERNALS_H +#define TARGET_ARM_INTERNALS_H + +/* register banks for CPU modes */ +#define BANK_USRSYS 0 +#define BANK_SVC 1 +#define BANK_ABT 2 +#define BANK_UND 3 +#define BANK_IRQ 4 +#define BANK_FIQ 5 +#define BANK_HYP 6 +#define BANK_MON 7 + +static inline bool excp_is_internal(int excp) +{ + /* Return true if this exception number represents a QEMU-internal + * exception that will not be passed to the guest. + */ + return excp == EXCP_INTERRUPT + || excp == EXCP_HLT + || excp == EXCP_DEBUG + || excp == EXCP_HALTED + || excp == EXCP_EXCEPTION_EXIT + || excp == EXCP_KERNEL_TRAP + || excp == EXCP_SEMIHOST + || excp == EXCP_STREX; +} + +/* Exception names for debug logging; note that not all of these + * precisely correspond to architectural exceptions. + */ +static const char * const excnames[] = { + [EXCP_UDEF] = "Undefined Instruction", + [EXCP_SWI] = "SVC", + [EXCP_PREFETCH_ABORT] = "Prefetch Abort", + [EXCP_DATA_ABORT] = "Data Abort", + [EXCP_IRQ] = "IRQ", + [EXCP_FIQ] = "FIQ", + [EXCP_BKPT] = "Breakpoint", + [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit", + [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage", + [EXCP_STREX] = "QEMU intercept of STREX", + [EXCP_HVC] = "Hypervisor Call", + [EXCP_HYP_TRAP] = "Hypervisor Trap", + [EXCP_SMC] = "Secure Monitor Call", + [EXCP_VIRQ] = "Virtual IRQ", + [EXCP_VFIQ] = "Virtual FIQ", + [EXCP_WKUP] = "Wakeup", + [EXCP_SEMIHOST] = "Semihosting call", +}; + +static inline void arm_log_exception(int idx) +{ + if (qemu_loglevel_mask(CPU_LOG_INT)) { + const char *exc = NULL; + + if (idx >= 0 && idx < ARRAY_SIZE(excnames)) { + exc = excnames[idx]; + } + if (!exc) { + exc = "unknown"; + } + qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc); + } +} + +/* Scale factor for generic timers, ie number of ns per tick. + * This gives a 62.5MHz timer. + */ +#define GTIMER_SCALE 16 + +/* + * For AArch64, map a given EL to an index in the banked_spsr array. + * Note that this mapping and the AArch32 mapping defined in bank_number() + * must agree such that the AArch64<->AArch32 SPSRs have the architecturally + * mandated mapping between each other. + */ +static inline unsigned int aarch64_banked_spsr_index(unsigned int el) +{ + static const unsigned int map[4] = { + [1] = BANK_SVC, /* EL1. */ + [2] = BANK_HYP, /* EL2. */ + [3] = BANK_MON, /* EL3. */ + }; + assert(el >= 1 && el <= 3); + return map[el]; +} + +int bank_number(int mode); +void switch_mode(CPUARMState *, int); +void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu); +void arm_translate_init(void); + +enum arm_fprounding { + FPROUNDING_TIEEVEN, + FPROUNDING_POSINF, + FPROUNDING_NEGINF, + FPROUNDING_ZERO, + FPROUNDING_TIEAWAY, + FPROUNDING_ODD +}; + +int arm_rmode_to_sf(int rmode); + +static inline void aarch64_save_sp(CPUARMState *env, int el) +{ + if (env->pstate & PSTATE_SP) { + env->sp_el[el] = env->xregs[31]; + } else { + env->sp_el[0] = env->xregs[31]; + } +} + +static inline void aarch64_restore_sp(CPUARMState *env, int el) +{ + if (env->pstate & PSTATE_SP) { + env->xregs[31] = env->sp_el[el]; + } else { + env->xregs[31] = env->sp_el[0]; + } +} + +static inline void update_spsel(CPUARMState *env, uint32_t imm) +{ + unsigned int cur_el = arm_current_el(env); + /* Update PSTATE SPSel bit; this requires us to update the + * working stack pointer in xregs[31]. + */ + if (!((imm ^ env->pstate) & PSTATE_SP)) { + return; + } + aarch64_save_sp(env, cur_el); + env->pstate = deposit32(env->pstate, 0, 1, imm); + + /* We rely on illegal updates to SPsel from EL0 to get trapped + * at translation time. + */ + assert(cur_el >= 1 && cur_el <= 3); + aarch64_restore_sp(env, cur_el); +} + +/* + * arm_pamax + * @cpu: ARMCPU + * + * Returns the implementation defined bit-width of physical addresses. + * The ARMv8 reference manuals refer to this as PAMax(). + */ +static inline unsigned int arm_pamax(ARMCPU *cpu) +{ + static const unsigned int pamax_map[] = { + [0] = 32, + [1] = 36, + [2] = 40, + [3] = 42, + [4] = 44, + [5] = 48, + }; + unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4); + + /* id_aa64mmfr0 is a read-only register so values outside of the + * supported mappings can be considered an implementation error. */ + assert(parange < ARRAY_SIZE(pamax_map)); + return pamax_map[parange]; +} + +/* Return true if extended addresses are enabled. + * This is always the case if our translation regime is 64 bit, + * but depends on TTBCR.EAE for 32 bit. + */ +static inline bool extended_addresses_enabled(CPUARMState *env) +{ + TCR *tcr = &env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1]; + return arm_el_is_aa64(env, 1) || + (arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE)); +} + +/* Valid Syndrome Register EC field values */ +enum arm_exception_class { + EC_UNCATEGORIZED = 0x00, + EC_WFX_TRAP = 0x01, + EC_CP15RTTRAP = 0x03, + EC_CP15RRTTRAP = 0x04, + EC_CP14RTTRAP = 0x05, + EC_CP14DTTRAP = 0x06, + EC_ADVSIMDFPACCESSTRAP = 0x07, + EC_FPIDTRAP = 0x08, + EC_CP14RRTTRAP = 0x0c, + EC_ILLEGALSTATE = 0x0e, + EC_AA32_SVC = 0x11, + EC_AA32_HVC = 0x12, + EC_AA32_SMC = 0x13, + EC_AA64_SVC = 0x15, + EC_AA64_HVC = 0x16, + EC_AA64_SMC = 0x17, + EC_SYSTEMREGISTERTRAP = 0x18, + EC_INSNABORT = 0x20, + EC_INSNABORT_SAME_EL = 0x21, + EC_PCALIGNMENT = 0x22, + EC_DATAABORT = 0x24, + EC_DATAABORT_SAME_EL = 0x25, + EC_SPALIGNMENT = 0x26, + EC_AA32_FPTRAP = 0x28, + EC_AA64_FPTRAP = 0x2c, + EC_SERROR = 0x2f, + EC_BREAKPOINT = 0x30, + EC_BREAKPOINT_SAME_EL = 0x31, + EC_SOFTWARESTEP = 0x32, + EC_SOFTWARESTEP_SAME_EL = 0x33, + EC_WATCHPOINT = 0x34, + EC_WATCHPOINT_SAME_EL = 0x35, + EC_AA32_BKPT = 0x38, + EC_VECTORCATCH = 0x3a, + EC_AA64_BKPT = 0x3c, +}; + +#define ARM_EL_EC_SHIFT 26 +#define ARM_EL_IL_SHIFT 25 +#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT) + +/* Utility functions for constructing various kinds of syndrome value. + * Note that in general we follow the AArch64 syndrome values; in a + * few cases the value in HSR for exceptions taken to AArch32 Hyp + * mode differs slightly, so if we ever implemented Hyp mode then the + * syndrome value would need some massaging on exception entry. + * (One example of this is that AArch64 defaults to IL bit set for + * exceptions which don't specifically indicate information about the + * trapping instruction, whereas AArch32 defaults to IL bit clear.) + */ +static inline uint32_t syn_uncategorized(void) +{ + return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL; +} + +static inline uint32_t syn_aa64_svc(uint32_t imm16) +{ + return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa64_hvc(uint32_t imm16) +{ + return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa64_smc(uint32_t imm16) +{ + return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb) +{ + return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff) + | (is_thumb ? 0 : ARM_EL_IL); +} + +static inline uint32_t syn_aa32_hvc(uint32_t imm16) +{ + return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa32_smc(void) +{ + return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL; +} + +static inline uint32_t syn_aa64_bkpt(uint32_t imm16) +{ + return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_thumb) +{ + return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff) + | (is_thumb ? 0 : ARM_EL_IL); +} + +static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2, + int crn, int crm, int rt, + int isread) +{ + return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL + | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5) + | (crm << 1) | isread; +} + +static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2, + int crn, int crm, int rt, int isread, + bool is_thumb) +{ + return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT) + | (is_thumb ? 0 : ARM_EL_IL) + | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14) + | (crn << 10) | (rt << 5) | (crm << 1) | isread; +} + +static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2, + int crn, int crm, int rt, int isread, + bool is_thumb) +{ + return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT) + | (is_thumb ? 0 : ARM_EL_IL) + | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14) + | (crn << 10) | (rt << 5) | (crm << 1) | isread; +} + +static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm, + int rt, int rt2, int isread, + bool is_thumb) +{ + return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT) + | (is_thumb ? 0 : ARM_EL_IL) + | (cv << 24) | (cond << 20) | (opc1 << 16) + | (rt2 << 10) | (rt << 5) | (crm << 1) | isread; +} + +static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm, + int rt, int rt2, int isread, + bool is_thumb) +{ + return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT) + | (is_thumb ? 0 : ARM_EL_IL) + | (cv << 24) | (cond << 20) | (opc1 << 16) + | (rt2 << 10) | (rt << 5) | (crm << 1) | isread; +} + +static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_thumb) +{ + return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT) + | (is_thumb ? 0 : ARM_EL_IL) + | (cv << 24) | (cond << 20); +} + +static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc) +{ + return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) + | (ea << 9) | (s1ptw << 7) | fsc; +} + +static inline uint32_t syn_data_abort(int same_el, int ea, int cm, int s1ptw, + int wnr, int fsc) +{ + return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) + | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc; +} + +static inline uint32_t syn_swstep(int same_el, int isv, int ex) +{ + return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) + | (isv << 24) | (ex << 6) | 0x22; +} + +static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr) +{ + return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) + | (cm << 8) | (wnr << 6) | 0x22; +} + +static inline uint32_t syn_breakpoint(int same_el) +{ + return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) + | ARM_EL_IL | 0x22; +} + +static inline uint32_t syn_wfx(int cv, int cond, int ti) +{ + return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) | + (cv << 24) | (cond << 20) | ti; +} + +/* Update a QEMU watchpoint based on the information the guest has set in the + * DBGWCR_EL1 and DBGWVR_EL1 registers. + */ +void hw_watchpoint_update(ARMCPU *cpu, int n); +/* Update the QEMU watchpoints for every guest watchpoint. This does a + * complete delete-and-reinstate of the QEMU watchpoint list and so is + * suitable for use after migration or on reset. + */ +void hw_watchpoint_update_all(ARMCPU *cpu); +/* Update a QEMU breakpoint based on the information the guest has set in the + * DBGBCR_EL1 and DBGBVR_EL1 registers. + */ +void hw_breakpoint_update(ARMCPU *cpu, int n); +/* Update the QEMU breakpoints for every guest breakpoint. This does a + * complete delete-and-reinstate of the QEMU breakpoint list and so is + * suitable for use after migration or on reset. + */ +void hw_breakpoint_update_all(ARMCPU *cpu); + +/* Callback function for when a watchpoint or breakpoint triggers. */ +void arm_debug_excp_handler(CPUState *cs); + +#ifdef CONFIG_USER_ONLY +static inline bool arm_is_psci_call(ARMCPU *cpu, int excp_type) +{ + return false; +} +#else +/* Return true if the r0/x0 value indicates that this SMC/HVC is a PSCI call. */ +bool arm_is_psci_call(ARMCPU *cpu, int excp_type); +/* Actually handle a PSCI call */ +void arm_handle_psci_call(ARMCPU *cpu); +#endif + +/** + * ARMMMUFaultInfo: Information describing an ARM MMU Fault + * @s2addr: Address that caused a fault at stage 2 + * @stage2: True if we faulted at stage 2 + * @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk + */ +typedef struct ARMMMUFaultInfo ARMMMUFaultInfo; +struct ARMMMUFaultInfo { + target_ulong s2addr; + bool stage2; + bool s1ptw; +}; + +/* Do a page table walk and add page to TLB if possible */ +bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx, + uint32_t *fsr, ARMMMUFaultInfo *fi); + +#endif diff --git a/target-arm/machine.c b/target-arm/machine.c new file mode 100644 index 0000000000000..c2c5bb4db24f7 --- /dev/null +++ b/target-arm/machine.c @@ -0,0 +1,355 @@ +#include "hw/hw.h" +#include "hw/boards.h" +#include "qemu/error-report.h" +#include "sysemu/kvm.h" +#include "kvm_arm.h" +#include "internals.h" + +static bool vfp_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_VFP); +} + +static int get_fpscr(QEMUFile *f, void *opaque, size_t size) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + uint32_t val = qemu_get_be32(f); + + vfp_set_fpscr(env, val); + return 0; +} + +static void put_fpscr(QEMUFile *f, void *opaque, size_t size) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + qemu_put_be32(f, vfp_get_fpscr(env)); +} + +static const VMStateInfo vmstate_fpscr = { + .name = "fpscr", + .get = get_fpscr, + .put = put_fpscr, +}; + +static const VMStateDescription vmstate_vfp = { + .name = "cpu/vfp", + .version_id = 3, + .minimum_version_id = 3, + .needed = vfp_needed, + .fields = (VMStateField[]) { + VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 64), + /* The xregs array is a little awkward because element 1 (FPSCR) + * requires a specific accessor, so we have to split it up in + * the vmstate: + */ + VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU), + VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14), + { + .name = "fpscr", + .version_id = 0, + .size = sizeof(uint32_t), + .info = &vmstate_fpscr, + .flags = VMS_SINGLE, + .offset = 0, + }, + VMSTATE_END_OF_LIST() + } +}; + +static bool iwmmxt_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_IWMMXT); +} + +static const VMStateDescription vmstate_iwmmxt = { + .name = "cpu/iwmmxt", + .version_id = 1, + .minimum_version_id = 1, + .needed = iwmmxt_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16), + VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16), + VMSTATE_END_OF_LIST() + } +}; + +static bool m_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_M); +} + +static const VMStateDescription vmstate_m = { + .name = "cpu/m", + .version_id = 2, + .minimum_version_id = 2, + .needed = m_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), + VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), + VMSTATE_UINT32(env.v7m.basepri, ARMCPU), + VMSTATE_UINT32(env.v7m.control, ARMCPU), + VMSTATE_INT32(env.v7m.current_sp, ARMCPU), + VMSTATE_INT32(env.v7m.exception, ARMCPU), + VMSTATE_UINT32(env.v7m.ccr, ARMCPU), + VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), + VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), + VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), + VMSTATE_UINT32(env.v7m.mmfar, ARMCPU), + VMSTATE_UINT32(env.v7m.bfar, ARMCPU), + VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + +static bool thumb2ee_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_THUMB2EE); +} + +static const VMStateDescription vmstate_thumb2ee = { + .name = "cpu/thumb2ee", + .version_id = 1, + .minimum_version_id = 1, + .needed = thumb2ee_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32(env.teecr, ARMCPU), + VMSTATE_UINT32(env.teehbr, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + +static bool pmsav7_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_MPU) && + arm_feature(env, ARM_FEATURE_V7); +} + +static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) +{ + ARMCPU *cpu = opaque; + + return cpu->env.cp15.c6_rgnr < cpu->pmsav7_dregion; +} + +static const VMStateDescription vmstate_pmsav7 = { + .name = "cpu/pmsav7", + .version_id = 1, + .minimum_version_id = 1, + .needed = pmsav7_needed, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(env.pmsav7.drbar, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav7.drsr, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav7.dracr, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VALIDATE("rgnr is valid", pmsav7_rgnr_vmstate_validate), + VMSTATE_END_OF_LIST() + } +}; + +static int get_cpsr(QEMUFile *f, void *opaque, size_t size) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + uint32_t val = qemu_get_be32(f); + + env->aarch64 = ((val & PSTATE_nRW) == 0); + + if (is_a64(env)) { + pstate_write(env, val); + return 0; + } + + /* Avoid mode switch when restoring CPSR */ + env->uncached_cpsr = val & CPSR_M; + cpsr_write(env, val, 0xffffffff); + return 0; +} + +static void put_cpsr(QEMUFile *f, void *opaque, size_t size) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + uint32_t val; + + if (is_a64(env)) { + val = pstate_read(env); + } else { + val = cpsr_read(env); + } + + qemu_put_be32(f, val); +} + +static const VMStateInfo vmstate_cpsr = { + .name = "cpsr", + .get = get_cpsr, + .put = put_cpsr, +}; + +static void cpu_pre_save(void *opaque) +{ + ARMCPU *cpu = opaque; + + if (kvm_enabled()) { + if (!write_kvmstate_to_list(cpu)) { + /* This should never fail */ + abort(); + } + } else { + if (!write_cpustate_to_list(cpu)) { + /* This should never fail. */ + abort(); + } + } + + cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; + memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes, + cpu->cpreg_array_len * sizeof(uint64_t)); + memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values, + cpu->cpreg_array_len * sizeof(uint64_t)); +} + +static int cpu_post_load(void *opaque, int version_id) +{ + ARMCPU *cpu = opaque; + int i, v; + + /* Update the values list from the incoming migration data. + * Anything in the incoming data which we don't know about is + * a migration failure; anything we know about but the incoming + * data doesn't specify retains its current (reset) value. + * The indexes list remains untouched -- we only inspect the + * incoming migration index list so we can match the values array + * entries with the right slots in our own values array. + */ + + for (i = 0, v = 0; i < cpu->cpreg_array_len + && v < cpu->cpreg_vmstate_array_len; i++) { + if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) { + /* register in our list but not incoming : skip it */ + continue; + } + if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) { + /* register in their list but not ours: fail migration */ + return -1; + } + /* matching register, copy the value over */ + cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v]; + v++; + } + + if (kvm_enabled()) { + if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) { + return -1; + } + /* Note that it's OK for the TCG side not to know about + * every register in the list; KVM is authoritative if + * we're using it. + */ + write_list_to_cpustate(cpu); + } else { + if (!write_list_to_cpustate(cpu)) { + return -1; + } + } + + hw_breakpoint_update_all(cpu); + hw_watchpoint_update_all(cpu); + + return 0; +} + +const VMStateDescription vmstate_arm_cpu = { + .name = "cpu", + .version_id = 22, + .minimum_version_id = 22, + .pre_save = cpu_pre_save, + .post_load = cpu_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), + VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32), + VMSTATE_UINT64(env.pc, ARMCPU), + { + .name = "cpsr", + .version_id = 0, + .size = sizeof(uint32_t), + .info = &vmstate_cpsr, + .flags = VMS_SINGLE, + .offset = 0, + }, + VMSTATE_UINT32(env.spsr, ARMCPU), + VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8), + VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8), + VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8), + VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5), + VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5), + VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4), + VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 4), + /* The length-check must come before the arrays to avoid + * incoming data possibly overflowing the array. + */ + VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU), + VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU, + cpreg_vmstate_array_len, + 0, vmstate_info_uint64, uint64_t), + VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU, + cpreg_vmstate_array_len, + 0, vmstate_info_uint64, uint64_t), + VMSTATE_UINT64(env.exclusive_addr, ARMCPU), + VMSTATE_UINT64(env.exclusive_val, ARMCPU), + VMSTATE_UINT64(env.exclusive_high, ARMCPU), + VMSTATE_UINT64(env.features, ARMCPU), + VMSTATE_UINT32(env.exception.syndrome, ARMCPU), + VMSTATE_UINT32(env.exception.fsr, ARMCPU), + VMSTATE_UINT64(env.exception.vaddress, ARMCPU), + VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU), + VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU), + VMSTATE_BOOL(powered_off, ARMCPU), + VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription*[]) { + &vmstate_vfp, + &vmstate_iwmmxt, + &vmstate_m, + &vmstate_thumb2ee, + &vmstate_pmsav7, + NULL + } +}; + +const char *gicv3_class_name(void) +{ + if (kvm_irqchip_in_kernel()) { +#ifdef TARGET_AARCH64 + return "kvm-arm-gicv3"; +#else + error_report("KVM GICv3 acceleration is not supported on this " + "platform\n"); +#endif + } else { + /* TODO: Software emulation is not implemented yet */ + error_report("KVM is currently required for GICv3 emulation\n"); + } + + exit(1); +} diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c new file mode 100644 index 0000000000000..d3fccf17fbc05 --- /dev/null +++ b/target-arm/op_helper.c @@ -0,0 +1,1009 @@ +/* + * ARM helper routines + * + * Copyright (c) 2005-2007 CodeSourcery, LLC + * + * 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 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 . + */ +#include "cpu.h" +#include "exec/helper-proto.h" +#include "internals.h" +#include "exec/cpu_ldst.h" + +#define SIGNBIT (uint32_t)0x80000000 +#define SIGNBIT64 ((uint64_t)1 << 63) + +static void raise_exception(CPUARMState *env, uint32_t excp, + uint32_t syndrome, uint32_t target_el) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + + assert(!excp_is_internal(excp)); + cs->exception_index = excp; + env->exception.syndrome = syndrome; + env->exception.target_el = target_el; + cpu_loop_exit(cs); +} + +static int exception_target_el(CPUARMState *env) +{ + int target_el = MAX(1, arm_current_el(env)); + + /* No such thing as secure EL1 if EL3 is aarch32, so update the target EL + * to EL3 in this case. + */ + if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) { + target_el = 3; + } + + return target_el; +} + +uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def, + uint32_t rn, uint32_t maxindex) +{ + uint32_t val; + uint32_t tmp; + int index; + int shift; + uint64_t *table; + table = (uint64_t *)&env->vfp.regs[rn]; + val = 0; + for (shift = 0; shift < 32; shift += 8) { + index = (ireg >> shift) & 0xff; + if (index < maxindex) { + tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff; + val |= tmp << shift; + } else { + val |= def & (0xff << shift); + } + } + return val; +} + +#if !defined(CONFIG_USER_ONLY) + +/* try to fill the TLB and return an exception if error. If retaddr is + * NULL, it means that the function was called in C code (i.e. not + * from generated code or from helper.c) + */ +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, + uintptr_t retaddr) +{ + bool ret; + uint32_t fsr = 0; + ARMMMUFaultInfo fi = {}; + + ret = arm_tlb_fill(cs, addr, is_write, mmu_idx, &fsr, &fi); + if (unlikely(ret)) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + uint32_t syn, exc; + unsigned int target_el; + bool same_el; + + if (retaddr) { + /* now we have a real cpu fault */ + cpu_restore_state(cs, retaddr); + } + + target_el = exception_target_el(env); + if (fi.stage2) { + target_el = 2; + env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4; + } + same_el = arm_current_el(env) == target_el; + /* AArch64 syndrome does not have an LPAE bit */ + syn = fsr & ~(1 << 9); + + /* For insn and data aborts we assume there is no instruction syndrome + * information; this is always true for exceptions reported to EL1. + */ + if (is_write == 2) { + syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn); + exc = EXCP_PREFETCH_ABORT; + } else { + syn = syn_data_abort(same_el, 0, 0, fi.s1ptw, is_write == 1, syn); + if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) { + fsr |= (1 << 11); + } + exc = EXCP_DATA_ABORT; + } + + env->exception.vaddress = addr; + env->exception.fsr = fsr; + raise_exception(env, exc, syn, target_el); + } +} +#endif + +uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b) +{ + uint32_t res = a + b; + if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) + env->QF = 1; + return res; +} + +uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b) +{ + uint32_t res = a + b; + if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) { + env->QF = 1; + res = ~(((int32_t)a >> 31) ^ SIGNBIT); + } + return res; +} + +uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b) +{ + uint32_t res = a - b; + if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) { + env->QF = 1; + res = ~(((int32_t)a >> 31) ^ SIGNBIT); + } + return res; +} + +uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val) +{ + uint32_t res; + if (val >= 0x40000000) { + res = ~SIGNBIT; + env->QF = 1; + } else if (val <= (int32_t)0xc0000000) { + res = SIGNBIT; + env->QF = 1; + } else { + res = val << 1; + } + return res; +} + +uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b) +{ + uint32_t res = a + b; + if (res < a) { + env->QF = 1; + res = ~0; + } + return res; +} + +uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b) +{ + uint32_t res = a - b; + if (res > a) { + env->QF = 1; + res = 0; + } + return res; +} + +/* Signed saturation. */ +static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift) +{ + int32_t top; + uint32_t mask; + + top = val >> shift; + mask = (1u << shift) - 1; + if (top > 0) { + env->QF = 1; + return mask; + } else if (top < -1) { + env->QF = 1; + return ~mask; + } + return val; +} + +/* Unsigned saturation. */ +static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift) +{ + uint32_t max; + + max = (1u << shift) - 1; + if (val < 0) { + env->QF = 1; + return 0; + } else if (val > max) { + env->QF = 1; + return max; + } + return val; +} + +/* Signed saturate. */ +uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift) +{ + return do_ssat(env, x, shift); +} + +/* Dual halfword signed saturate. */ +uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift) +{ + uint32_t res; + + res = (uint16_t)do_ssat(env, (int16_t)x, shift); + res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16; + return res; +} + +/* Unsigned saturate. */ +uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift) +{ + return do_usat(env, x, shift); +} + +/* Dual halfword unsigned saturate. */ +uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift) +{ + uint32_t res; + + res = (uint16_t)do_usat(env, (int16_t)x, shift); + res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16; + return res; +} + +/* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped. + * The function returns the target EL (1-3) if the instruction is to be trapped; + * otherwise it returns 0 indicating it is not trapped. + */ +static inline int check_wfx_trap(CPUARMState *env, bool is_wfe) +{ + int cur_el = arm_current_el(env); + uint64_t mask; + + /* If we are currently in EL0 then we need to check if SCTLR is set up for + * WFx instructions being trapped to EL1. These trap bits don't exist in v7. + */ + if (cur_el < 1 && arm_feature(env, ARM_FEATURE_V8)) { + int target_el; + + mask = is_wfe ? SCTLR_nTWE : SCTLR_nTWI; + if (arm_is_secure_below_el3(env) && !arm_el_is_aa64(env, 3)) { + /* Secure EL0 and Secure PL1 is at EL3 */ + target_el = 3; + } else { + target_el = 1; + } + + if (!(env->cp15.sctlr_el[target_el] & mask)) { + return target_el; + } + } + + /* We are not trapping to EL1; trap to EL2 if HCR_EL2 requires it + * No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the + * bits will be zero indicating no trap. + */ + if (cur_el < 2 && !arm_is_secure(env)) { + mask = (is_wfe) ? HCR_TWE : HCR_TWI; + if (env->cp15.hcr_el2 & mask) { + return 2; + } + } + + /* We are not trapping to EL1 or EL2; trap to EL3 if SCR_EL3 requires it */ + if (cur_el < 3) { + mask = (is_wfe) ? SCR_TWE : SCR_TWI; + if (env->cp15.scr_el3 & mask) { + return 3; + } + } + + return 0; +} + +void HELPER(wfi)(CPUARMState *env) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + int target_el = check_wfx_trap(env, false); + + if (cpu_has_work(cs)) { + /* Don't bother to go into our "low power state" if + * we would just wake up immediately. + */ + return; + } + + if (target_el) { + env->pc -= 4; + raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0), target_el); + } + + /* Tell the NVIC we are executing a WFI instruction so that it can determine if we should + * go into deep sleep mode */ + armv7m_nvic_cpu_executed_wfi(env->nvic); + cs->exception_index = EXCP_HLT; + cs->halted = 1; + cpu_loop_exit(cs); +} + +void HELPER(wfe)(CPUARMState *env) +{ + /* This is a hint instruction that is semantically different + * from YIELD even though we currently implement it identically. + * Don't actually halt the CPU, just yield back to top + * level loop. This is not going into a "low power state" + * (ie halting until some event occurs), so we never take + * a configurable trap to a different exception level. + */ + HELPER(yield)(env); +} + +void HELPER(yield)(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + /* This is a non-trappable hint instruction that generally indicates + * that the guest is currently busy-looping. Yield control back to the + * top level loop so that a more deserving VCPU has a chance to run. + */ + cs->exception_index = EXCP_YIELD; + cpu_loop_exit(cs); +} + +/* Raise an internal-to-QEMU exception. This is limited to only + * those EXCP values which are special cases for QEMU to interrupt + * execution and not to be used for exceptions which are passed to + * the guest (those must all have syndrome information and thus should + * use exception_with_syndrome). + */ +void HELPER(exception_internal)(CPUARMState *env, uint32_t excp) +{ + CPUState *cs = CPU(arm_env_get_cpu(env)); + + assert(excp_is_internal(excp)); + cs->exception_index = excp; + cpu_loop_exit(cs); +} + +/* Raise an exception with the specified syndrome register value */ +void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp, + uint32_t syndrome, uint32_t target_el) +{ + raise_exception(env, excp, syndrome, target_el); +} + +uint32_t HELPER(cpsr_read)(CPUARMState *env) +{ + return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED); +} + +void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) +{ + cpsr_write(env, val, mask); +} + +/* Access to user mode registers from privileged modes. */ +uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno) +{ + uint32_t val; + + if (regno == 13) { + val = env->banked_r13[BANK_USRSYS]; + } else if (regno == 14) { + val = env->banked_r14[BANK_USRSYS]; + } else if (regno >= 8 + && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) { + val = env->usr_regs[regno - 8]; + } else { + val = env->regs[regno]; + } + return val; +} + +void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val) +{ + if (regno == 13) { + env->banked_r13[BANK_USRSYS] = val; + } else if (regno == 14) { + env->banked_r14[BANK_USRSYS] = val; + } else if (regno >= 8 + && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) { + env->usr_regs[regno - 8] = val; + } else { + env->regs[regno] = val; + } +} + +void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome) +{ + const ARMCPRegInfo *ri = rip; + int target_el; + + if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14 + && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) { + raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env)); + } + + if (!ri->accessfn) { + return; + } + + switch (ri->accessfn(env, ri)) { + case CP_ACCESS_OK: + return; + case CP_ACCESS_TRAP: + target_el = exception_target_el(env); + break; + case CP_ACCESS_TRAP_EL2: + /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is + * a bug in the access function. + */ + assert(!arm_is_secure(env) && arm_current_el(env) != 3); + target_el = 2; + break; + case CP_ACCESS_TRAP_EL3: + target_el = 3; + break; + case CP_ACCESS_TRAP_UNCATEGORIZED: + target_el = exception_target_el(env); + syndrome = syn_uncategorized(); + break; + case CP_ACCESS_TRAP_UNCATEGORIZED_EL2: + target_el = 2; + syndrome = syn_uncategorized(); + break; + case CP_ACCESS_TRAP_UNCATEGORIZED_EL3: + target_el = 3; + syndrome = syn_uncategorized(); + break; + default: + g_assert_not_reached(); + } + + raise_exception(env, EXCP_UDEF, syndrome, target_el); +} + +void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value) +{ + const ARMCPRegInfo *ri = rip; + + ri->writefn(env, ri, value); +} + +uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip) +{ + const ARMCPRegInfo *ri = rip; + + return ri->readfn(env, ri); +} + +void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value) +{ + const ARMCPRegInfo *ri = rip; + + ri->writefn(env, ri, value); +} + +uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip) +{ + const ARMCPRegInfo *ri = rip; + + return ri->readfn(env, ri); +} + +void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm) +{ + /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set. + * Note that SPSel is never OK from EL0; we rely on handle_msr_i() + * to catch that case at translate time. + */ + if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) { + uint32_t syndrome = syn_aa64_sysregtrap(0, extract32(op, 0, 3), + extract32(op, 3, 3), 4, + imm, 0x1f, 0); + raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env)); + } + + switch (op) { + case 0x05: /* SPSel */ + update_spsel(env, imm); + break; + case 0x1e: /* DAIFSet */ + env->daif |= (imm << 6) & PSTATE_DAIF; + break; + case 0x1f: /* DAIFClear */ + env->daif &= ~((imm << 6) & PSTATE_DAIF); + break; + default: + g_assert_not_reached(); + } +} + +void HELPER(clear_pstate_ss)(CPUARMState *env) +{ + env->pstate &= ~PSTATE_SS; +} + +void HELPER(pre_hvc)(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int cur_el = arm_current_el(env); + /* FIXME: Use actual secure state. */ + bool secure = false; + bool undef; + + if (arm_is_psci_call(cpu, EXCP_HVC)) { + /* If PSCI is enabled and this looks like a valid PSCI call then + * that overrides the architecturally mandated HVC behaviour. + */ + return; + } + + if (!arm_feature(env, ARM_FEATURE_EL2)) { + /* If EL2 doesn't exist, HVC always UNDEFs */ + undef = true; + } else if (arm_feature(env, ARM_FEATURE_EL3)) { + /* EL3.HCE has priority over EL2.HCD. */ + undef = !(env->cp15.scr_el3 & SCR_HCE); + } else { + undef = env->cp15.hcr_el2 & HCR_HCD; + } + + /* In ARMv7 and ARMv8/AArch32, HVC is undef in secure state. + * For ARMv8/AArch64, HVC is allowed in EL3. + * Note that we've already trapped HVC from EL0 at translation + * time. + */ + if (secure && (!is_a64(env) || cur_el == 1)) { + undef = true; + } + + if (undef) { + raise_exception(env, EXCP_UDEF, syn_uncategorized(), + exception_target_el(env)); + } +} + +void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + int cur_el = arm_current_el(env); + bool secure = arm_is_secure(env); + bool smd = env->cp15.scr_el3 & SCR_SMD; + /* On ARMv8 AArch32, SMD only applies to NS state. + * On ARMv7 SMD only applies to NS state and only if EL2 is available. + * For ARMv7 non EL2, we force SMD to zero so we don't need to re-check + * the EL2 condition here. + */ + bool undef = is_a64(env) ? smd : (!secure && smd); + + if (arm_is_psci_call(cpu, EXCP_SMC)) { + /* If PSCI is enabled and this looks like a valid PSCI call then + * that overrides the architecturally mandated SMC behaviour. + */ + return; + } + + if (!arm_feature(env, ARM_FEATURE_EL3)) { + /* If we have no EL3 then SMC always UNDEFs */ + undef = true; + } else if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) { + /* In NS EL1, HCR controlled routing to EL2 has priority over SMD. */ + raise_exception(env, EXCP_HYP_TRAP, syndrome, 2); + } + + if (undef) { + raise_exception(env, EXCP_UDEF, syn_uncategorized(), + exception_target_el(env)); + } +} + +void HELPER(exception_return)(CPUARMState *env) +{ + int cur_el = arm_current_el(env); + unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el); + uint32_t spsr = env->banked_spsr[spsr_idx]; + int new_el; + + aarch64_save_sp(env, cur_el); + + env->exclusive_addr = -1; + + /* We must squash the PSTATE.SS bit to zero unless both of the + * following hold: + * 1. debug exceptions are currently disabled + * 2. singlestep will be active in the EL we return to + * We check 1 here and 2 after we've done the pstate/cpsr write() to + * transition to the EL we're going to. + */ + if (arm_generate_debug_exceptions(env)) { + spsr &= ~PSTATE_SS; + } + + if (spsr & PSTATE_nRW) { + /* TODO: We currently assume EL1/2/3 are running in AArch64. */ + env->aarch64 = 0; + new_el = 0; + env->uncached_cpsr = 0x10; + cpsr_write(env, spsr, ~0); + if (!arm_singlestep_active(env)) { + env->uncached_cpsr &= ~PSTATE_SS; + } + aarch64_sync_64_to_32(env); + + env->regs[15] = env->elr_el[1] & ~0x1; + } else { + new_el = extract32(spsr, 2, 2); + if (new_el > cur_el + || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) { + /* Disallow return to an EL which is unimplemented or higher + * than the current one. + */ + goto illegal_return; + } + if (extract32(spsr, 1, 1)) { + /* Return with reserved M[1] bit set */ + goto illegal_return; + } + if (new_el == 0 && (spsr & PSTATE_SP)) { + /* Return to EL0 with M[0] bit set */ + goto illegal_return; + } + env->aarch64 = 1; + pstate_write(env, spsr); + if (!arm_singlestep_active(env)) { + env->pstate &= ~PSTATE_SS; + } + aarch64_restore_sp(env, new_el); + env->pc = env->elr_el[cur_el]; + } + + return; + +illegal_return: + /* Illegal return events of various kinds have architecturally + * mandated behaviour: + * restore NZCV and DAIF from SPSR_ELx + * set PSTATE.IL + * restore PC from ELR_ELx + * no change to exception level, execution state or stack pointer + */ + env->pstate |= PSTATE_IL; + env->pc = env->elr_el[cur_el]; + spsr &= PSTATE_NZCV | PSTATE_DAIF; + spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF); + pstate_write(env, spsr); + if (!arm_singlestep_active(env)) { + env->pstate &= ~PSTATE_SS; + } +} + +/* Return true if the linked breakpoint entry lbn passes its checks */ +static bool linked_bp_matches(ARMCPU *cpu, int lbn) +{ + CPUARMState *env = &cpu->env; + uint64_t bcr = env->cp15.dbgbcr[lbn]; + int brps = extract32(cpu->dbgdidr, 24, 4); + int ctx_cmps = extract32(cpu->dbgdidr, 20, 4); + int bt; + uint32_t contextidr; + + /* Links to unimplemented or non-context aware breakpoints are + * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or + * as if linked to an UNKNOWN context-aware breakpoint (in which + * case DBGWCR_EL1.LBN must indicate that breakpoint). + * We choose the former. + */ + if (lbn > brps || lbn < (brps - ctx_cmps)) { + return false; + } + + bcr = env->cp15.dbgbcr[lbn]; + + if (extract64(bcr, 0, 1) == 0) { + /* Linked breakpoint disabled : generate no events */ + return false; + } + + bt = extract64(bcr, 20, 4); + + /* We match the whole register even if this is AArch32 using the + * short descriptor format (in which case it holds both PROCID and ASID), + * since we don't implement the optional v7 context ID masking. + */ + contextidr = extract64(env->cp15.contextidr_el[1], 0, 32); + + switch (bt) { + case 3: /* linked context ID match */ + if (arm_current_el(env) > 1) { + /* Context matches never fire in EL2 or (AArch64) EL3 */ + return false; + } + return (contextidr == extract64(env->cp15.dbgbvr[lbn], 0, 32)); + case 5: /* linked address mismatch (reserved in AArch64) */ + case 9: /* linked VMID match (reserved if no EL2) */ + case 11: /* linked context ID and VMID match (reserved if no EL2) */ + default: + /* Links to Unlinked context breakpoints must generate no + * events; we choose to do the same for reserved values too. + */ + return false; + } + + return false; +} + +static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp) +{ + CPUARMState *env = &cpu->env; + uint64_t cr; + int pac, hmc, ssc, wt, lbn; + /* Note that for watchpoints the check is against the CPU security + * state, not the S/NS attribute on the offending data access. + */ + bool is_secure = arm_is_secure(env); + int access_el = arm_current_el(env); + + if (is_wp) { + CPUWatchpoint *wp = env->cpu_watchpoint[n]; + + if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) { + return false; + } + cr = env->cp15.dbgwcr[n]; + if (wp->hitattrs.user) { + /* The LDRT/STRT/LDT/STT "unprivileged access" instructions should + * match watchpoints as if they were accesses done at EL0, even if + * the CPU is at EL1 or higher. + */ + access_el = 0; + } + } else { + uint64_t pc = is_a64(env) ? env->pc : env->regs[15]; + + if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) { + return false; + } + cr = env->cp15.dbgbcr[n]; + } + /* The WATCHPOINT_HIT flag guarantees us that the watchpoint is + * enabled and that the address and access type match; for breakpoints + * we know the address matched; check the remaining fields, including + * linked breakpoints. We rely on WCR and BCR having the same layout + * for the LBN, SSC, HMC, PAC/PMC and is-linked fields. + * Note that some combinations of {PAC, HMC, SSC} are reserved and + * must act either like some valid combination or as if the watchpoint + * were disabled. We choose the former, and use this together with + * the fact that EL3 must always be Secure and EL2 must always be + * Non-Secure to simplify the code slightly compared to the full + * table in the ARM ARM. + */ + pac = extract64(cr, 1, 2); + hmc = extract64(cr, 13, 1); + ssc = extract64(cr, 14, 2); + + switch (ssc) { + case 0: + break; + case 1: + case 3: + if (is_secure) { + return false; + } + break; + case 2: + if (!is_secure) { + return false; + } + break; + } + + switch (access_el) { + case 3: + case 2: + if (!hmc) { + return false; + } + break; + case 1: + if (extract32(pac, 0, 1) == 0) { + return false; + } + break; + case 0: + if (extract32(pac, 1, 1) == 0) { + return false; + } + break; + default: + g_assert_not_reached(); + } + + wt = extract64(cr, 20, 1); + lbn = extract64(cr, 16, 4); + + if (wt && !linked_bp_matches(cpu, lbn)) { + return false; + } + + return true; +} + +static bool check_watchpoints(ARMCPU *cpu) +{ + CPUARMState *env = &cpu->env; + int n; + + /* If watchpoints are disabled globally or we can't take debug + * exceptions here then watchpoint firings are ignored. + */ + if (extract32(env->cp15.mdscr_el1, 15, 1) == 0 + || !arm_generate_debug_exceptions(env)) { + return false; + } + + for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) { + if (bp_wp_matches(cpu, n, true)) { + return true; + } + } + return false; +} + +static bool check_breakpoints(ARMCPU *cpu) +{ + CPUARMState *env = &cpu->env; + int n; + + /* If breakpoints are disabled globally or we can't take debug + * exceptions here then breakpoint firings are ignored. + */ + if (extract32(env->cp15.mdscr_el1, 15, 1) == 0 + || !arm_generate_debug_exceptions(env)) { + return false; + } + + for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) { + if (bp_wp_matches(cpu, n, false)) { + return true; + } + } + return false; +} + +void HELPER(check_breakpoints)(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + + if (check_breakpoints(cpu)) { + HELPER(exception_internal(env, EXCP_DEBUG)); + } +} + +void arm_debug_excp_handler(CPUState *cs) +{ + /* Called by core code when a watchpoint or breakpoint fires; + * need to check which one and raise the appropriate exception. + */ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + CPUWatchpoint *wp_hit = cs->watchpoint_hit; + + if (wp_hit) { + if (wp_hit->flags & BP_CPU) { + cs->watchpoint_hit = NULL; + if (check_watchpoints(cpu)) { + bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0; + bool same_el = arm_debug_target_el(env) == arm_current_el(env); + + if (extended_addresses_enabled(env)) { + env->exception.fsr = (1 << 9) | 0x22; + } else { + env->exception.fsr = 0x2; + } + env->exception.vaddress = wp_hit->hitaddr; + raise_exception(env, EXCP_DATA_ABORT, + syn_watchpoint(same_el, 0, wnr), + arm_debug_target_el(env)); + } else { + cpu_resume_from_signal(cs, NULL); + } + } + } else { + uint64_t pc = is_a64(env) ? env->pc : env->regs[15]; + bool same_el = (arm_debug_target_el(env) == arm_current_el(env)); + + /* (1) GDB breakpoints should be handled first. + * (2) Do not raise a CPU exception if no CPU breakpoint has fired, + * since singlestep is also done by generating a debug internal + * exception. + */ + if (cpu_breakpoint_test(cs, pc, BP_GDB) + || !cpu_breakpoint_test(cs, pc, BP_CPU)) { + return; + } + + if (extended_addresses_enabled(env)) { + env->exception.fsr = (1 << 9) | 0x22; + } else { + env->exception.fsr = 0x2; + } + /* FAR is UNKNOWN, so doesn't need setting */ + raise_exception(env, EXCP_PREFETCH_ABORT, + syn_breakpoint(same_el), + arm_debug_target_el(env)); + } +} + +/* ??? Flag setting arithmetic is awkward because we need to do comparisons. + The only way to do that in TCG is a conditional branch, which clobbers + all our temporaries. For now implement these as helper functions. */ + +/* Similarly for variable shift instructions. */ + +uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i) +{ + int shift = i & 0xff; + if (shift >= 32) { + if (shift == 32) + env->CF = x & 1; + else + env->CF = 0; + return 0; + } else if (shift != 0) { + env->CF = (x >> (32 - shift)) & 1; + return x << shift; + } + return x; +} + +uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i) +{ + int shift = i & 0xff; + if (shift >= 32) { + if (shift == 32) + env->CF = (x >> 31) & 1; + else + env->CF = 0; + return 0; + } else if (shift != 0) { + env->CF = (x >> (shift - 1)) & 1; + return x >> shift; + } + return x; +} + +uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i) +{ + int shift = i & 0xff; + if (shift >= 32) { + env->CF = (x >> 31) & 1; + return (int32_t)x >> 31; + } else if (shift != 0) { + env->CF = (x >> (shift - 1)) & 1; + return (int32_t)x >> shift; + } + return x; +} + +uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i) +{ + int shift1, shift; + shift1 = i & 0xff; + shift = shift1 & 0x1f; + if (shift == 0) { + if (shift1 != 0) + env->CF = (x >> 31) & 1; + return x; + } else { + env->CF = (x >> (shift - 1)) & 1; + return ((uint32_t)x >> shift) | (x << (32 - shift)); + } +} diff --git a/target-arm/translate.c b/target-arm/translate.c new file mode 100644 index 0000000000000..029f33783ea28 --- /dev/null +++ b/target-arm/translate.c @@ -0,0 +1,11688 @@ +/* + * ARM translation + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2005-2007 CodeSourcery + * Copyright (c) 2007 OpenedHand, Ltd. + * + * 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 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 . + */ +#include +#include +#include +#include +#include + +#include "cpu.h" +#include "internals.h" +#include "disas/disas.h" +#include "tcg-op.h" +#include "qemu/log.h" +#include "qemu/bitops.h" +#include "arm_ldst.h" + +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" + +#include "trace-tcg.h" + + +#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T) +#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5) +/* currently all emulated v5 cores are also v5TE, so don't bother */ +#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5) +#define ENABLE_ARCH_5J 0 +#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6) +#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K) +#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2) +#define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7) +#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8) + +#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0) + +#include "translate.h" + +#if defined(CONFIG_USER_ONLY) +#define IS_USER(s) 1 +#else +#define IS_USER(s) (s->user) +#endif + +TCGv_ptr cpu_env; +/* We reuse the same 64-bit temporaries for efficiency. */ +static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; +static TCGv_i32 cpu_R[16]; +TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF; +TCGv_i64 cpu_exclusive_addr; +TCGv_i64 cpu_exclusive_val; +#ifdef CONFIG_USER_ONLY +TCGv_i64 cpu_exclusive_test; +TCGv_i32 cpu_exclusive_info; +#endif + +/* FIXME: These should be removed. */ +static TCGv_i32 cpu_F0s, cpu_F1s; +static TCGv_i64 cpu_F0d, cpu_F1d; + +#include "exec/gen-icount.h" + +static const char *regnames[] = + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" }; + +/* initialize TCG globals. */ +void arm_translate_init(void) +{ + int i; + + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); + + for (i = 0; i < 16; i++) { + cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUARMState, regs[i]), + regnames[i]); + } + cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF"); + cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF"); + cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF"); + cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF"); + + cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUARMState, exclusive_addr), "exclusive_addr"); + cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUARMState, exclusive_val), "exclusive_val"); +#ifdef CONFIG_USER_ONLY + cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUARMState, exclusive_test), "exclusive_test"); + cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUARMState, exclusive_info), "exclusive_info"); +#endif + + a64_translate_init(); +} + +static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s) +{ + /* Return the mmu_idx to use for A32/T32 "unprivileged load/store" + * insns: + * if PL2, UNPREDICTABLE (we choose to implement as if PL0) + * otherwise, access as if at PL0. + */ + switch (s->mmu_idx) { + case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */ + case ARMMMUIdx_S12NSE0: + case ARMMMUIdx_S12NSE1: + return ARMMMUIdx_S12NSE0; + case ARMMMUIdx_S1E3: + case ARMMMUIdx_S1SE0: + case ARMMMUIdx_S1SE1: + return ARMMMUIdx_S1SE0; + case ARMMMUIdx_S2NS: + default: + g_assert_not_reached(); + } +} + +static inline TCGv_i32 load_cpu_offset(int offset) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp, cpu_env, offset); + return tmp; +} + +#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name)) + +static inline void store_cpu_offset(TCGv_i32 var, int offset) +{ + tcg_gen_st_i32(var, cpu_env, offset); + tcg_temp_free_i32(var); +} + +#define store_cpu_field(var, name) \ + store_cpu_offset(var, offsetof(CPUARMState, name)) + +/* Set a variable to the value of a CPU register. */ +static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg) +{ + if (reg == 15) { + uint32_t addr; + /* normally, since we updated PC, we need only to add one insn */ + if (s->thumb) + addr = (long)s->pc + 2; + else + addr = (long)s->pc + 4; + tcg_gen_movi_i32(var, addr); + } else { + tcg_gen_mov_i32(var, cpu_R[reg]); + } +} + +/* Create a new temporary and set it to the value of a CPU register. */ +static inline TCGv_i32 load_reg(DisasContext *s, int reg) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + load_reg_var(s, tmp, reg); + return tmp; +} + +/* Set a CPU register. The source must be a temporary and will be + marked as dead. */ +static void store_reg(DisasContext *s, int reg, TCGv_i32 var) +{ + if (reg == 15) { + tcg_gen_andi_i32(var, var, ~1); + s->is_jmp = DISAS_JUMP; + } + tcg_gen_mov_i32(cpu_R[reg], var); + tcg_temp_free_i32(var); +} + +/* Value extensions. */ +#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var) +#define gen_uxth(var) tcg_gen_ext16u_i32(var, var) +#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) +#define gen_sxth(var) tcg_gen_ext16s_i32(var, var) + +#define gen_sxtb16(var) gen_helper_sxtb16(var, var) +#define gen_uxtb16(var) gen_helper_uxtb16(var, var) + + +static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask) +{ + TCGv_i32 tmp_mask = tcg_const_i32(mask); + gen_helper_cpsr_write(cpu_env, var, tmp_mask); + tcg_temp_free_i32(tmp_mask); +} +/* Set NZCV flags from the high 4 bits of var. */ +#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV) + +static void gen_exception_internal(int excp) +{ + TCGv_i32 tcg_excp = tcg_const_i32(excp); + + assert(excp_is_internal(excp)); + gen_helper_exception_internal(cpu_env, tcg_excp); + tcg_temp_free_i32(tcg_excp); +} + +static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el) +{ + TCGv_i32 tcg_excp = tcg_const_i32(excp); + TCGv_i32 tcg_syn = tcg_const_i32(syndrome); + TCGv_i32 tcg_el = tcg_const_i32(target_el); + + gen_helper_exception_with_syndrome(cpu_env, tcg_excp, + tcg_syn, tcg_el); + + tcg_temp_free_i32(tcg_el); + tcg_temp_free_i32(tcg_syn); + tcg_temp_free_i32(tcg_excp); +} + +static void gen_ss_advance(DisasContext *s) +{ + /* If the singlestep state is Active-not-pending, advance to + * Active-pending. + */ + if (s->ss_active) { + s->pstate_ss = 0; + gen_helper_clear_pstate_ss(cpu_env); + } +} + +static void gen_step_complete_exception(DisasContext *s) +{ + /* We just completed step of an insn. Move from Active-not-pending + * to Active-pending, and then also take the swstep exception. + * This corresponds to making the (IMPDEF) choice to prioritize + * swstep exceptions over asynchronous exceptions taken to an exception + * level where debug is disabled. This choice has the advantage that + * we do not need to maintain internal state corresponding to the + * ISV/EX syndrome bits between completion of the step and generation + * of the exception, and our syndrome information is always correct. + */ + gen_ss_advance(s); + gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex), + default_exception_el(s)); + s->is_jmp = DISAS_EXC; +} + +static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b) +{ + TCGv_i32 tmp1 = tcg_temp_new_i32(); + TCGv_i32 tmp2 = tcg_temp_new_i32(); + tcg_gen_ext16s_i32(tmp1, a); + tcg_gen_ext16s_i32(tmp2, b); + tcg_gen_mul_i32(tmp1, tmp1, tmp2); + tcg_temp_free_i32(tmp2); + tcg_gen_sari_i32(a, a, 16); + tcg_gen_sari_i32(b, b, 16); + tcg_gen_mul_i32(b, b, a); + tcg_gen_mov_i32(a, tmp1); + tcg_temp_free_i32(tmp1); +} + +/* Byteswap each halfword. */ +static void gen_rev16(TCGv_i32 var) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_shri_i32(tmp, var, 8); + tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff); + tcg_gen_shli_i32(var, var, 8); + tcg_gen_andi_i32(var, var, 0xff00ff00); + tcg_gen_or_i32(var, var, tmp); + tcg_temp_free_i32(tmp); +} + +/* Byteswap low halfword and sign extend. */ +static void gen_revsh(TCGv_i32 var) +{ + tcg_gen_ext16u_i32(var, var); + tcg_gen_bswap16_i32(var, var); + tcg_gen_ext16s_i32(var, var); +} + +/* Unsigned bitfield extract. */ +static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask) +{ + if (shift) + tcg_gen_shri_i32(var, var, shift); + tcg_gen_andi_i32(var, var, mask); +} + +/* Signed bitfield extract. */ +static void gen_sbfx(TCGv_i32 var, int shift, int width) +{ + uint32_t signbit; + + if (shift) + tcg_gen_sari_i32(var, var, shift); + if (shift + width < 32) { + signbit = 1u << (width - 1); + tcg_gen_andi_i32(var, var, (1u << width) - 1); + tcg_gen_xori_i32(var, var, signbit); + tcg_gen_subi_i32(var, var, signbit); + } +} + +/* Return (b << 32) + a. Mark inputs as dead */ +static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b) +{ + TCGv_i64 tmp64 = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(tmp64, b); + tcg_temp_free_i32(b); + tcg_gen_shli_i64(tmp64, tmp64, 32); + tcg_gen_add_i64(a, tmp64, a); + + tcg_temp_free_i64(tmp64); + return a; +} + +/* Return (b << 32) - a. Mark inputs as dead. */ +static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b) +{ + TCGv_i64 tmp64 = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(tmp64, b); + tcg_temp_free_i32(b); + tcg_gen_shli_i64(tmp64, tmp64, 32); + tcg_gen_sub_i64(a, tmp64, a); + + tcg_temp_free_i64(tmp64); + return a; +} + +/* 32x32->64 multiply. Marks inputs as dead. */ +static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b) +{ + TCGv_i32 lo = tcg_temp_new_i32(); + TCGv_i32 hi = tcg_temp_new_i32(); + TCGv_i64 ret; + + tcg_gen_mulu2_i32(lo, hi, a, b); + tcg_temp_free_i32(a); + tcg_temp_free_i32(b); + + ret = tcg_temp_new_i64(); + tcg_gen_concat_i32_i64(ret, lo, hi); + tcg_temp_free_i32(lo); + tcg_temp_free_i32(hi); + + return ret; +} + +static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b) +{ + TCGv_i32 lo = tcg_temp_new_i32(); + TCGv_i32 hi = tcg_temp_new_i32(); + TCGv_i64 ret; + + tcg_gen_muls2_i32(lo, hi, a, b); + tcg_temp_free_i32(a); + tcg_temp_free_i32(b); + + ret = tcg_temp_new_i64(); + tcg_gen_concat_i32_i64(ret, lo, hi); + tcg_temp_free_i32(lo); + tcg_temp_free_i32(hi); + + return ret; +} + +/* Swap low and high halfwords. */ +static void gen_swap_half(TCGv_i32 var) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_shri_i32(tmp, var, 16); + tcg_gen_shli_i32(var, var, 16); + tcg_gen_or_i32(var, var, tmp); + tcg_temp_free_i32(tmp); +} + +/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. + tmp = (t0 ^ t1) & 0x8000; + t0 &= ~0x8000; + t1 &= ~0x8000; + t0 = (t0 + t1) ^ tmp; + */ + +static void gen_add16(TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, t0, t1); + tcg_gen_andi_i32(tmp, tmp, 0x8000); + tcg_gen_andi_i32(t0, t0, ~0x8000); + tcg_gen_andi_i32(t1, t1, ~0x8000); + tcg_gen_add_i32(t0, t0, t1); + tcg_gen_xor_i32(t0, t0, tmp); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(t1); +} + +/* Set CF to the top bit of var. */ +static void gen_set_CF_bit31(TCGv_i32 var) +{ + tcg_gen_shri_i32(cpu_CF, var, 31); +} + +/* Set N and Z flags from var. */ +static inline void gen_logic_CC(TCGv_i32 var) +{ + tcg_gen_mov_i32(cpu_NF, var); + tcg_gen_mov_i32(cpu_ZF, var); +} + +/* T0 += T1 + CF. */ +static void gen_adc(TCGv_i32 t0, TCGv_i32 t1) +{ + tcg_gen_add_i32(t0, t0, t1); + tcg_gen_add_i32(t0, t0, cpu_CF); +} + +/* dest = T0 + T1 + CF. */ +static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + tcg_gen_add_i32(dest, t0, t1); + tcg_gen_add_i32(dest, dest, cpu_CF); +} + +/* dest = T0 - T1 + CF - 1. */ +static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + tcg_gen_sub_i32(dest, t0, t1); + tcg_gen_add_i32(dest, dest, cpu_CF); + tcg_gen_subi_i32(dest, dest, 1); +} + +/* dest = T0 + T1. Compute C, N, V and Z flags */ +static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp); + tcg_gen_mov_i32(cpu_ZF, cpu_NF); + tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); + tcg_gen_xor_i32(tmp, t0, t1); + tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp); + tcg_temp_free_i32(tmp); + tcg_gen_mov_i32(dest, cpu_NF); +} + +/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */ +static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + if (TCG_TARGET_HAS_add2_i32) { + tcg_gen_movi_i32(tmp, 0); + tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp); + tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp); + } else { + TCGv_i64 q0 = tcg_temp_new_i64(); + TCGv_i64 q1 = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(q0, t0); + tcg_gen_extu_i32_i64(q1, t1); + tcg_gen_add_i64(q0, q0, q1); + tcg_gen_extu_i32_i64(q1, cpu_CF); + tcg_gen_add_i64(q0, q0, q1); + tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0); + tcg_temp_free_i64(q0); + tcg_temp_free_i64(q1); + } + tcg_gen_mov_i32(cpu_ZF, cpu_NF); + tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); + tcg_gen_xor_i32(tmp, t0, t1); + tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp); + tcg_temp_free_i32(tmp); + tcg_gen_mov_i32(dest, cpu_NF); +} + +/* dest = T0 - T1. Compute C, N, V and Z flags */ +static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 tmp; + tcg_gen_sub_i32(cpu_NF, t0, t1); + tcg_gen_mov_i32(cpu_ZF, cpu_NF); + tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1); + tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, t0, t1); + tcg_gen_and_i32(cpu_VF, cpu_VF, tmp); + tcg_temp_free_i32(tmp); + tcg_gen_mov_i32(dest, cpu_NF); +} + +/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */ +static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_not_i32(tmp, t1); + gen_adc_CC(dest, t0, tmp); + tcg_temp_free_i32(tmp); +} + +#define GEN_SHIFT(name) \ +static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \ +{ \ + TCGv_i32 tmp1, tmp2, tmp3; \ + tmp1 = tcg_temp_new_i32(); \ + tcg_gen_andi_i32(tmp1, t1, 0xff); \ + tmp2 = tcg_const_i32(0); \ + tmp3 = tcg_const_i32(0x1f); \ + tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \ + tcg_temp_free_i32(tmp3); \ + tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \ + tcg_gen_##name##_i32(dest, tmp2, tmp1); \ + tcg_temp_free_i32(tmp2); \ + tcg_temp_free_i32(tmp1); \ +} +GEN_SHIFT(shl) +GEN_SHIFT(shr) +#undef GEN_SHIFT + +static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 tmp1, tmp2; + tmp1 = tcg_temp_new_i32(); + tcg_gen_andi_i32(tmp1, t1, 0xff); + tmp2 = tcg_const_i32(0x1f); + tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1); + tcg_temp_free_i32(tmp2); + tcg_gen_sar_i32(dest, t0, tmp1); + tcg_temp_free_i32(tmp1); +} + +static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src) +{ + TCGv_i32 c0 = tcg_const_i32(0); + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_neg_i32(tmp, src); + tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp); + tcg_temp_free_i32(c0); + tcg_temp_free_i32(tmp); +} + +static void shifter_out_im(TCGv_i32 var, int shift) +{ + if (shift == 0) { + tcg_gen_andi_i32(cpu_CF, var, 1); + } else { + tcg_gen_shri_i32(cpu_CF, var, shift); + if (shift != 31) { + tcg_gen_andi_i32(cpu_CF, cpu_CF, 1); + } + } +} + +/* Shift by immediate. Includes special handling for shift == 0. */ +static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop, + int shift, int flags) +{ + switch (shiftop) { + case 0: /* LSL */ + if (shift != 0) { + if (flags) + shifter_out_im(var, 32 - shift); + tcg_gen_shli_i32(var, var, shift); + } + break; + case 1: /* LSR */ + if (shift == 0) { + if (flags) { + tcg_gen_shri_i32(cpu_CF, var, 31); + } + tcg_gen_movi_i32(var, 0); + } else { + if (flags) + shifter_out_im(var, shift - 1); + tcg_gen_shri_i32(var, var, shift); + } + break; + case 2: /* ASR */ + if (shift == 0) + shift = 32; + if (flags) + shifter_out_im(var, shift - 1); + if (shift == 32) + shift = 31; + tcg_gen_sari_i32(var, var, shift); + break; + case 3: /* ROR/RRX */ + if (shift != 0) { + if (flags) + shifter_out_im(var, shift - 1); + tcg_gen_rotri_i32(var, var, shift); break; + } else { + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_shli_i32(tmp, cpu_CF, 31); + if (flags) + shifter_out_im(var, 0); + tcg_gen_shri_i32(var, var, 1); + tcg_gen_or_i32(var, var, tmp); + tcg_temp_free_i32(tmp); + } + } +}; + +static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop, + TCGv_i32 shift, int flags) +{ + if (flags) { + switch (shiftop) { + case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break; + case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break; + case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break; + case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break; + } + } else { + switch (shiftop) { + case 0: + gen_shl(var, var, shift); + break; + case 1: + gen_shr(var, var, shift); + break; + case 2: + gen_sar(var, var, shift); + break; + case 3: tcg_gen_andi_i32(shift, shift, 0x1f); + tcg_gen_rotr_i32(var, var, shift); break; + } + } + tcg_temp_free_i32(shift); +} + +#define PAS_OP(pfx) \ + switch (op2) { \ + case 0: gen_pas_helper(glue(pfx,add16)); break; \ + case 1: gen_pas_helper(glue(pfx,addsubx)); break; \ + case 2: gen_pas_helper(glue(pfx,subaddx)); break; \ + case 3: gen_pas_helper(glue(pfx,sub16)); break; \ + case 4: gen_pas_helper(glue(pfx,add8)); break; \ + case 7: gen_pas_helper(glue(pfx,sub8)); break; \ + } +static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b) +{ + TCGv_ptr tmp; + + switch (op1) { +#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) + case 1: + tmp = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); + PAS_OP(s) + tcg_temp_free_ptr(tmp); + break; + case 5: + tmp = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); + PAS_OP(u) + tcg_temp_free_ptr(tmp); + break; +#undef gen_pas_helper +#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) + case 2: + PAS_OP(q); + break; + case 3: + PAS_OP(sh); + break; + case 6: + PAS_OP(uq); + break; + case 7: + PAS_OP(uh); + break; +#undef gen_pas_helper + } +} +#undef PAS_OP + +/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */ +#define PAS_OP(pfx) \ + switch (op1) { \ + case 0: gen_pas_helper(glue(pfx,add8)); break; \ + case 1: gen_pas_helper(glue(pfx,add16)); break; \ + case 2: gen_pas_helper(glue(pfx,addsubx)); break; \ + case 4: gen_pas_helper(glue(pfx,sub8)); break; \ + case 5: gen_pas_helper(glue(pfx,sub16)); break; \ + case 6: gen_pas_helper(glue(pfx,subaddx)); break; \ + } +static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b) +{ + TCGv_ptr tmp; + + switch (op2) { +#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) + case 0: + tmp = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); + PAS_OP(s) + tcg_temp_free_ptr(tmp); + break; + case 4: + tmp = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); + PAS_OP(u) + tcg_temp_free_ptr(tmp); + break; +#undef gen_pas_helper +#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) + case 1: + PAS_OP(q); + break; + case 2: + PAS_OP(sh); + break; + case 5: + PAS_OP(uq); + break; + case 6: + PAS_OP(uh); + break; +#undef gen_pas_helper + } +} +#undef PAS_OP + +/* + * Generate a conditional based on ARM condition code cc. + * This is common between ARM and Aarch64 targets. + */ +void arm_test_cc(DisasCompare *cmp, int cc) +{ + TCGv_i32 value; + TCGCond cond; + bool global = true; + + switch (cc) { + case 0: /* eq: Z */ + case 1: /* ne: !Z */ + cond = TCG_COND_EQ; + value = cpu_ZF; + break; + + case 2: /* cs: C */ + case 3: /* cc: !C */ + cond = TCG_COND_NE; + value = cpu_CF; + break; + + case 4: /* mi: N */ + case 5: /* pl: !N */ + cond = TCG_COND_LT; + value = cpu_NF; + break; + + case 6: /* vs: V */ + case 7: /* vc: !V */ + cond = TCG_COND_LT; + value = cpu_VF; + break; + + case 8: /* hi: C && !Z */ + case 9: /* ls: !C || Z -> !(C && !Z) */ + cond = TCG_COND_NE; + value = tcg_temp_new_i32(); + global = false; + /* CF is 1 for C, so -CF is an all-bits-set mask for C; + ZF is non-zero for !Z; so AND the two subexpressions. */ + tcg_gen_neg_i32(value, cpu_CF); + tcg_gen_and_i32(value, value, cpu_ZF); + break; + + case 10: /* ge: N == V -> N ^ V == 0 */ + case 11: /* lt: N != V -> N ^ V != 0 */ + /* Since we're only interested in the sign bit, == 0 is >= 0. */ + cond = TCG_COND_GE; + value = tcg_temp_new_i32(); + global = false; + tcg_gen_xor_i32(value, cpu_VF, cpu_NF); + break; + + case 12: /* gt: !Z && N == V */ + case 13: /* le: Z || N != V */ + cond = TCG_COND_NE; + value = tcg_temp_new_i32(); + global = false; + /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate + * the sign bit then AND with ZF to yield the result. */ + tcg_gen_xor_i32(value, cpu_VF, cpu_NF); + tcg_gen_sari_i32(value, value, 31); + tcg_gen_andc_i32(value, cpu_ZF, value); + break; + + case 14: /* always */ + case 15: /* always */ + /* Use the ALWAYS condition, which will fold early. + * It doesn't matter what we use for the value. */ + cond = TCG_COND_ALWAYS; + value = cpu_ZF; + goto no_invert; + + default: + fprintf(stderr, "Bad condition code 0x%x\n", cc); + abort(); + } + + if (cc & 1) { + cond = tcg_invert_cond(cond); + } + + no_invert: + cmp->cond = cond; + cmp->value = value; + cmp->value_global = global; +} + +void arm_free_cc(DisasCompare *cmp) +{ + if (!cmp->value_global) { + tcg_temp_free_i32(cmp->value); + } +} + +void arm_jump_cc(DisasCompare *cmp, TCGLabel *label) +{ + tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label); +} + +void arm_gen_test_cc(int cc, TCGLabel *label) +{ + DisasCompare cmp; + arm_test_cc(&cmp, cc); + arm_jump_cc(&cmp, label); + arm_free_cc(&cmp); +} + +static const uint8_t table_logic_cc[16] = { + 1, /* and */ + 1, /* xor */ + 0, /* sub */ + 0, /* rsb */ + 0, /* add */ + 0, /* adc */ + 0, /* sbc */ + 0, /* rsc */ + 1, /* andl */ + 1, /* xorl */ + 0, /* cmp */ + 0, /* cmn */ + 1, /* orr */ + 1, /* mov */ + 1, /* bic */ + 1, /* mvn */ +}; + +/* Set PC and Thumb state from an immediate address. */ +static inline void gen_bx_im(DisasContext *s, uint32_t addr) +{ + TCGv_i32 tmp; + + s->is_jmp = DISAS_JUMP; + if (s->thumb != (addr & 1)) { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, addr & 1); + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb)); + tcg_temp_free_i32(tmp); + } + tcg_gen_movi_i32(cpu_R[15], addr & ~1); +} + +/* Set PC and Thumb state from var. var is marked as dead. */ +static inline void gen_bx(DisasContext *s, TCGv_i32 var) +{ + s->is_jmp = DISAS_JUMP; + tcg_gen_andi_i32(cpu_R[15], var, ~1); + tcg_gen_andi_i32(var, var, 1); + store_cpu_field(var, thumb); +} + +/* Variant of store_reg which uses branch&exchange logic when storing + to r15 in ARM architecture v7 and above. The source must be a temporary + and will be marked as dead. */ +static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var) +{ + if (reg == 15 && ENABLE_ARCH_7) { + gen_bx(s, var); + } else { + store_reg(s, reg, var); + } +} + +/* Variant of store_reg which uses branch&exchange logic when storing + * to r15 in ARM architecture v5T and above. This is used for storing + * the results of a LDR/LDM/POP into r15, and corresponds to the cases + * in the ARM ARM which use the LoadWritePC() pseudocode function. */ +static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var) +{ + if (reg == 15 && ENABLE_ARCH_5) { + gen_bx(s, var); + } else { + store_reg(s, reg, var); + } +} + +/* Abstractions of "generate code to do a guest load/store for + * AArch32", where a vaddr is always 32 bits (and is zero + * extended if we're a 64 bit core) and data is also + * 32 bits unless specifically doing a 64 bit access. + * These functions work like tcg_gen_qemu_{ld,st}* except + * that the address argument is TCGv_i32 rather than TCGv. + */ +#if TARGET_LONG_BITS == 32 + +#define DO_GEN_LD(SUFF, OPC) \ +static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ +{ \ + tcg_gen_qemu_ld_i32(val, addr, index, OPC); \ +} + +#define DO_GEN_ST(SUFF, OPC) \ +static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ +{ \ + tcg_gen_qemu_st_i32(val, addr, index, OPC); \ +} + +static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index) +{ + tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ); +} + +static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index) +{ + tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ); +} + +#else + +#define DO_GEN_LD(SUFF, OPC) \ +static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ +{ \ + TCGv addr64 = tcg_temp_new(); \ + tcg_gen_extu_i32_i64(addr64, addr); \ + tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \ + tcg_temp_free(addr64); \ +} + +#define DO_GEN_ST(SUFF, OPC) \ +static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ +{ \ + TCGv addr64 = tcg_temp_new(); \ + tcg_gen_extu_i32_i64(addr64, addr); \ + tcg_gen_qemu_st_i32(val, addr64, index, OPC); \ + tcg_temp_free(addr64); \ +} + +static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index) +{ + TCGv addr64 = tcg_temp_new(); + tcg_gen_extu_i32_i64(addr64, addr); + tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ); + tcg_temp_free(addr64); +} + +static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index) +{ + TCGv addr64 = tcg_temp_new(); + tcg_gen_extu_i32_i64(addr64, addr); + tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ); + tcg_temp_free(addr64); +} + +#endif + +DO_GEN_LD(8s, MO_SB) +DO_GEN_LD(8u, MO_UB) +DO_GEN_LD(16s, MO_TESW) +DO_GEN_LD(16u, MO_TEUW) +DO_GEN_LD(32u, MO_TEUL) +DO_GEN_ST(8, MO_UB) +DO_GEN_ST(16, MO_TEUW) +DO_GEN_ST(32, MO_TEUL) + +static inline void gen_set_pc_im(DisasContext *s, target_ulong val) +{ + tcg_gen_movi_i32(cpu_R[15], val); +} + +static inline void gen_hvc(DisasContext *s, int imm16) +{ + /* The pre HVC helper handles cases when HVC gets trapped + * as an undefined insn by runtime configuration (ie before + * the insn really executes). + */ + gen_set_pc_im(s, s->pc - 4); + gen_helper_pre_hvc(cpu_env); + /* Otherwise we will treat this as a real exception which + * happens after execution of the insn. (The distinction matters + * for the PC value reported to the exception handler and also + * for single stepping.) + */ + s->svc_imm = imm16; + gen_set_pc_im(s, s->pc); + s->is_jmp = DISAS_HVC; +} + +static inline void gen_smc(DisasContext *s) +{ + /* As with HVC, we may take an exception either before or after + * the insn executes. + */ + TCGv_i32 tmp; + + gen_set_pc_im(s, s->pc - 4); + tmp = tcg_const_i32(syn_aa32_smc()); + gen_helper_pre_smc(cpu_env, tmp); + tcg_temp_free_i32(tmp); + gen_set_pc_im(s, s->pc); + s->is_jmp = DISAS_SMC; +} + +static inline void +gen_set_condexec (DisasContext *s) +{ + if (s->condexec_mask) { + uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + store_cpu_field(tmp, condexec_bits); + } +} + +static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) +{ + gen_set_condexec(s); + gen_set_pc_im(s, s->pc - offset); + gen_exception_internal(excp); + s->is_jmp = DISAS_JUMP; +} + +static void gen_exception_insn(DisasContext *s, int offset, int excp, + int syn, uint32_t target_el) +{ + gen_set_condexec(s); + gen_set_pc_im(s, s->pc - offset); + gen_exception(excp, syn, target_el); + s->is_jmp = DISAS_JUMP; +} + +/* Force a TB lookup after an instruction that changes the CPU state. */ +static inline void gen_lookup_tb(DisasContext *s) +{ + tcg_gen_movi_i32(cpu_R[15], s->pc & ~1); + s->is_jmp = DISAS_JUMP; +} + +static inline void gen_add_data_offset(DisasContext *s, unsigned int insn, + TCGv_i32 var) +{ + int val, rm, shift, shiftop; + TCGv_i32 offset; + + if (!(insn & (1 << 25))) { + /* immediate */ + val = insn & 0xfff; + if (!(insn & (1 << 23))) + val = -val; + if (val != 0) + tcg_gen_addi_i32(var, var, val); + } else { + /* shift/register */ + rm = (insn) & 0xf; + shift = (insn >> 7) & 0x1f; + shiftop = (insn >> 5) & 3; + offset = load_reg(s, rm); + gen_arm_shift_im(offset, shiftop, shift, 0); + if (!(insn & (1 << 23))) + tcg_gen_sub_i32(var, var, offset); + else + tcg_gen_add_i32(var, var, offset); + tcg_temp_free_i32(offset); + } +} + +static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, + int extra, TCGv_i32 var) +{ + int val, rm; + TCGv_i32 offset; + + if (insn & (1 << 22)) { + /* immediate */ + val = (insn & 0xf) | ((insn >> 4) & 0xf0); + if (!(insn & (1 << 23))) + val = -val; + val += extra; + if (val != 0) + tcg_gen_addi_i32(var, var, val); + } else { + /* register */ + if (extra) + tcg_gen_addi_i32(var, var, extra); + rm = (insn) & 0xf; + offset = load_reg(s, rm); + if (!(insn & (1 << 23))) + tcg_gen_sub_i32(var, var, offset); + else + tcg_gen_add_i32(var, var, offset); + tcg_temp_free_i32(offset); + } +} + +static TCGv_ptr get_fpstatus_ptr(int neon) +{ + TCGv_ptr statusptr = tcg_temp_new_ptr(); + int offset; + if (neon) { + offset = offsetof(CPUARMState, vfp.standard_fp_status); + } else { + offset = offsetof(CPUARMState, vfp.fp_status); + } + tcg_gen_addi_ptr(statusptr, cpu_env, offset); + return statusptr; +} + +#define VFP_OP2(name) \ +static inline void gen_vfp_##name(int dp) \ +{ \ + TCGv_ptr fpst = get_fpstatus_ptr(0); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \ + } \ + tcg_temp_free_ptr(fpst); \ +} + +VFP_OP2(add) +VFP_OP2(sub) +VFP_OP2(mul) +VFP_OP2(div) + +#undef VFP_OP2 + +static inline void gen_vfp_F1_mul(int dp) +{ + /* Like gen_vfp_mul() but put result in F1 */ + TCGv_ptr fpst = get_fpstatus_ptr(0); + if (dp) { + gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst); + } else { + gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst); + } + tcg_temp_free_ptr(fpst); +} + +static inline void gen_vfp_F1_neg(int dp) +{ + /* Like gen_vfp_neg() but put result in F1 */ + if (dp) { + gen_helper_vfp_negd(cpu_F1d, cpu_F0d); + } else { + gen_helper_vfp_negs(cpu_F1s, cpu_F0s); + } +} + +static inline void gen_vfp_abs(int dp) +{ + if (dp) + gen_helper_vfp_absd(cpu_F0d, cpu_F0d); + else + gen_helper_vfp_abss(cpu_F0s, cpu_F0s); +} + +static inline void gen_vfp_neg(int dp) +{ + if (dp) + gen_helper_vfp_negd(cpu_F0d, cpu_F0d); + else + gen_helper_vfp_negs(cpu_F0s, cpu_F0s); +} + +static inline void gen_vfp_sqrt(int dp) +{ + if (dp) + gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env); + else + gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env); +} + +static inline void gen_vfp_cmp(int dp) +{ + if (dp) + gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env); + else + gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env); +} + +static inline void gen_vfp_cmpe(int dp) +{ + if (dp) + gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env); + else + gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env); +} + +static inline void gen_vfp_F1_ld0(int dp) +{ + if (dp) + tcg_gen_movi_i64(cpu_F1d, 0); + else + tcg_gen_movi_i32(cpu_F1s, 0); +} + +#define VFP_GEN_ITOF(name) \ +static inline void gen_vfp_##name(int dp, int neon) \ +{ \ + TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ + } \ + tcg_temp_free_ptr(statusptr); \ +} + +VFP_GEN_ITOF(uito) +VFP_GEN_ITOF(sito) +#undef VFP_GEN_ITOF + +#define VFP_GEN_FTOI(name) \ +static inline void gen_vfp_##name(int dp, int neon) \ +{ \ + TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ + } \ + tcg_temp_free_ptr(statusptr); \ +} + +VFP_GEN_FTOI(toui) +VFP_GEN_FTOI(touiz) +VFP_GEN_FTOI(tosi) +VFP_GEN_FTOI(tosiz) +#undef VFP_GEN_FTOI + +#define VFP_GEN_FIX(name, round) \ +static inline void gen_vfp_##name(int dp, int shift, int neon) \ +{ \ + TCGv_i32 tmp_shift = tcg_const_i32(shift); \ + TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ + if (dp) { \ + gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \ + statusptr); \ + } else { \ + gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \ + statusptr); \ + } \ + tcg_temp_free_i32(tmp_shift); \ + tcg_temp_free_ptr(statusptr); \ +} +VFP_GEN_FIX(tosh, _round_to_zero) +VFP_GEN_FIX(tosl, _round_to_zero) +VFP_GEN_FIX(touh, _round_to_zero) +VFP_GEN_FIX(toul, _round_to_zero) +VFP_GEN_FIX(shto, ) +VFP_GEN_FIX(slto, ) +VFP_GEN_FIX(uhto, ) +VFP_GEN_FIX(ulto, ) +#undef VFP_GEN_FIX + +static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr) +{ + if (dp) { + gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s)); + } else { + gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s)); + } +} + +static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr) +{ + if (dp) { + gen_aa32_st64(cpu_F0d, addr, get_mem_index(s)); + } else { + gen_aa32_st32(cpu_F0s, addr, get_mem_index(s)); + } +} + +static inline long +vfp_reg_offset (int dp, int reg) +{ + if (dp) + return offsetof(CPUARMState, vfp.regs[reg]); + else if (reg & 1) { + return offsetof(CPUARMState, vfp.regs[reg >> 1]) + + offsetof(CPU_DoubleU, l.upper); + } else { + return offsetof(CPUARMState, vfp.regs[reg >> 1]) + + offsetof(CPU_DoubleU, l.lower); + } +} + +/* Return the offset of a 32-bit piece of a NEON register. + zero is the least significant end of the register. */ +static inline long +neon_reg_offset (int reg, int n) +{ + int sreg; + sreg = reg * 2 + n; + return vfp_reg_offset(0, sreg); +} + +static TCGv_i32 neon_load_reg(int reg, int pass) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass)); + return tmp; +} + +static void neon_store_reg(int reg, int pass, TCGv_i32 var) +{ + tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass)); + tcg_temp_free_i32(var); +} + +static inline void neon_load_reg64(TCGv_i64 var, int reg) +{ + tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg)); +} + +static inline void neon_store_reg64(TCGv_i64 var, int reg) +{ + tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg)); +} + +#define tcg_gen_ld_f32 tcg_gen_ld_i32 +#define tcg_gen_ld_f64 tcg_gen_ld_i64 +#define tcg_gen_st_f32 tcg_gen_st_i32 +#define tcg_gen_st_f64 tcg_gen_st_i64 + +static inline void gen_mov_F0_vreg(int dp, int reg) +{ + if (dp) + tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg)); + else + tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg)); +} + +static inline void gen_mov_F1_vreg(int dp, int reg) +{ + if (dp) + tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg)); + else + tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg)); +} + +static inline void gen_mov_vreg_F0(int dp, int reg) +{ + if (dp) + tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg)); + else + tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg)); +} + +#define ARM_CP_RW_BIT (1 << 20) + +static inline void iwmmxt_load_reg(TCGv_i64 var, int reg) +{ + tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg])); +} + +static inline void iwmmxt_store_reg(TCGv_i64 var, int reg) +{ + tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg])); +} + +static inline TCGv_i32 iwmmxt_load_creg(int reg) +{ + TCGv_i32 var = tcg_temp_new_i32(); + tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg])); + return var; +} + +static inline void iwmmxt_store_creg(int reg, TCGv_i32 var) +{ + tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg])); + tcg_temp_free_i32(var); +} + +static inline void gen_op_iwmmxt_movq_wRn_M0(int rn) +{ + iwmmxt_store_reg(cpu_M0, rn); +} + +static inline void gen_op_iwmmxt_movq_M0_wRn(int rn) +{ + iwmmxt_load_reg(cpu_M0, rn); +} + +static inline void gen_op_iwmmxt_orq_M0_wRn(int rn) +{ + iwmmxt_load_reg(cpu_V1, rn); + tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1); +} + +static inline void gen_op_iwmmxt_andq_M0_wRn(int rn) +{ + iwmmxt_load_reg(cpu_V1, rn); + tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1); +} + +static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn) +{ + iwmmxt_load_reg(cpu_V1, rn); + tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1); +} + +#define IWMMXT_OP(name) \ +static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \ +{ \ + iwmmxt_load_reg(cpu_V1, rn); \ + gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \ +} + +#define IWMMXT_OP_ENV(name) \ +static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \ +{ \ + iwmmxt_load_reg(cpu_V1, rn); \ + gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \ +} + +#define IWMMXT_OP_ENV_SIZE(name) \ +IWMMXT_OP_ENV(name##b) \ +IWMMXT_OP_ENV(name##w) \ +IWMMXT_OP_ENV(name##l) + +#define IWMMXT_OP_ENV1(name) \ +static inline void gen_op_iwmmxt_##name##_M0(void) \ +{ \ + gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \ +} + +IWMMXT_OP(maddsq) +IWMMXT_OP(madduq) +IWMMXT_OP(sadb) +IWMMXT_OP(sadw) +IWMMXT_OP(mulslw) +IWMMXT_OP(mulshw) +IWMMXT_OP(mululw) +IWMMXT_OP(muluhw) +IWMMXT_OP(macsw) +IWMMXT_OP(macuw) + +IWMMXT_OP_ENV_SIZE(unpackl) +IWMMXT_OP_ENV_SIZE(unpackh) + +IWMMXT_OP_ENV1(unpacklub) +IWMMXT_OP_ENV1(unpackluw) +IWMMXT_OP_ENV1(unpacklul) +IWMMXT_OP_ENV1(unpackhub) +IWMMXT_OP_ENV1(unpackhuw) +IWMMXT_OP_ENV1(unpackhul) +IWMMXT_OP_ENV1(unpacklsb) +IWMMXT_OP_ENV1(unpacklsw) +IWMMXT_OP_ENV1(unpacklsl) +IWMMXT_OP_ENV1(unpackhsb) +IWMMXT_OP_ENV1(unpackhsw) +IWMMXT_OP_ENV1(unpackhsl) + +IWMMXT_OP_ENV_SIZE(cmpeq) +IWMMXT_OP_ENV_SIZE(cmpgtu) +IWMMXT_OP_ENV_SIZE(cmpgts) + +IWMMXT_OP_ENV_SIZE(mins) +IWMMXT_OP_ENV_SIZE(minu) +IWMMXT_OP_ENV_SIZE(maxs) +IWMMXT_OP_ENV_SIZE(maxu) + +IWMMXT_OP_ENV_SIZE(subn) +IWMMXT_OP_ENV_SIZE(addn) +IWMMXT_OP_ENV_SIZE(subu) +IWMMXT_OP_ENV_SIZE(addu) +IWMMXT_OP_ENV_SIZE(subs) +IWMMXT_OP_ENV_SIZE(adds) + +IWMMXT_OP_ENV(avgb0) +IWMMXT_OP_ENV(avgb1) +IWMMXT_OP_ENV(avgw0) +IWMMXT_OP_ENV(avgw1) + +IWMMXT_OP_ENV(packuw) +IWMMXT_OP_ENV(packul) +IWMMXT_OP_ENV(packuq) +IWMMXT_OP_ENV(packsw) +IWMMXT_OP_ENV(packsl) +IWMMXT_OP_ENV(packsq) + +static void gen_op_iwmmxt_set_mup(void) +{ + TCGv_i32 tmp; + tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]); + tcg_gen_ori_i32(tmp, tmp, 2); + store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]); +} + +static void gen_op_iwmmxt_set_cup(void) +{ + TCGv_i32 tmp; + tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]); + tcg_gen_ori_i32(tmp, tmp, 1); + store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]); +} + +static void gen_op_iwmmxt_setpsr_nz(void) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0); + store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]); +} + +static inline void gen_op_iwmmxt_addl_M0_wRn(int rn) +{ + iwmmxt_load_reg(cpu_V1, rn); + tcg_gen_ext32u_i64(cpu_V1, cpu_V1); + tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); +} + +static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, + TCGv_i32 dest) +{ + int rd; + uint32_t offset; + TCGv_i32 tmp; + + rd = (insn >> 16) & 0xf; + tmp = load_reg(s, rd); + + offset = (insn & 0xff) << ((insn >> 7) & 2); + if (insn & (1 << 24)) { + /* Pre indexed */ + if (insn & (1 << 23)) + tcg_gen_addi_i32(tmp, tmp, offset); + else + tcg_gen_addi_i32(tmp, tmp, -offset); + tcg_gen_mov_i32(dest, tmp); + if (insn & (1 << 21)) + store_reg(s, rd, tmp); + else + tcg_temp_free_i32(tmp); + } else if (insn & (1 << 21)) { + /* Post indexed */ + tcg_gen_mov_i32(dest, tmp); + if (insn & (1 << 23)) + tcg_gen_addi_i32(tmp, tmp, offset); + else + tcg_gen_addi_i32(tmp, tmp, -offset); + store_reg(s, rd, tmp); + } else if (!(insn & (1 << 23))) + return 1; + return 0; +} + +static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest) +{ + int rd = (insn >> 0) & 0xf; + TCGv_i32 tmp; + + if (insn & (1 << 8)) { + if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) { + return 1; + } else { + tmp = iwmmxt_load_creg(rd); + } + } else { + tmp = tcg_temp_new_i32(); + iwmmxt_load_reg(cpu_V0, rd); + tcg_gen_extrl_i64_i32(tmp, cpu_V0); + } + tcg_gen_andi_i32(tmp, tmp, mask); + tcg_gen_mov_i32(dest, tmp); + tcg_temp_free_i32(tmp); + return 0; +} + +/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred + (ie. an undefined instruction). */ +static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn) +{ + int rd, wrd; + int rdhi, rdlo, rd0, rd1, i; + TCGv_i32 addr; + TCGv_i32 tmp, tmp2, tmp3; + + if ((insn & 0x0e000e00) == 0x0c000000) { + if ((insn & 0x0fe00ff0) == 0x0c400000) { + wrd = insn & 0xf; + rdlo = (insn >> 12) & 0xf; + rdhi = (insn >> 16) & 0xf; + if (insn & ARM_CP_RW_BIT) { /* TMRRC */ + iwmmxt_load_reg(cpu_V0, wrd); + tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0); + tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); + tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0); + } else { /* TMCRR */ + tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); + iwmmxt_store_reg(cpu_V0, wrd); + gen_op_iwmmxt_set_mup(); + } + return 0; + } + + wrd = (insn >> 12) & 0xf; + addr = tcg_temp_new_i32(); + if (gen_iwmmxt_address(s, insn, addr)) { + tcg_temp_free_i32(addr); + return 1; + } + if (insn & ARM_CP_RW_BIT) { + if ((insn >> 28) == 0xf) { /* WLDRW wCx */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + iwmmxt_store_creg(wrd, tmp); + } else { + i = 1; + if (insn & (1 << 8)) { + if (insn & (1 << 22)) { /* WLDRD */ + gen_aa32_ld64(cpu_M0, addr, get_mem_index(s)); + i = 0; + } else { /* WLDRW wRd */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + } + } else { + tmp = tcg_temp_new_i32(); + if (insn & (1 << 22)) { /* WLDRH */ + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + } else { /* WLDRB */ + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + } + } + if (i) { + tcg_gen_extu_i32_i64(cpu_M0, tmp); + tcg_temp_free_i32(tmp); + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + } + } else { + if ((insn >> 28) == 0xf) { /* WSTRW wCx */ + tmp = iwmmxt_load_creg(wrd); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + } else { + gen_op_iwmmxt_movq_M0_wRn(wrd); + tmp = tcg_temp_new_i32(); + if (insn & (1 << 8)) { + if (insn & (1 << 22)) { /* WSTRD */ + gen_aa32_st64(cpu_M0, addr, get_mem_index(s)); + } else { /* WSTRW wRd */ + tcg_gen_extrl_i64_i32(tmp, cpu_M0); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + } + } else { + if (insn & (1 << 22)) { /* WSTRH */ + tcg_gen_extrl_i64_i32(tmp, cpu_M0); + gen_aa32_st16(tmp, addr, get_mem_index(s)); + } else { /* WSTRB */ + tcg_gen_extrl_i64_i32(tmp, cpu_M0); + gen_aa32_st8(tmp, addr, get_mem_index(s)); + } + } + } + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); + return 0; + } + + if ((insn & 0x0f000000) != 0x0e000000) + return 1; + + switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) { + case 0x000: /* WOR */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 0) & 0xf; + rd1 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + gen_op_iwmmxt_orq_M0_wRn(rd1); + gen_op_iwmmxt_setpsr_nz(); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x011: /* TMCR */ + if (insn & 0xf) + return 1; + rd = (insn >> 12) & 0xf; + wrd = (insn >> 16) & 0xf; + switch (wrd) { + case ARM_IWMMXT_wCID: + case ARM_IWMMXT_wCASF: + break; + case ARM_IWMMXT_wCon: + gen_op_iwmmxt_set_cup(); + /* Fall through. */ + case ARM_IWMMXT_wCSSF: + tmp = iwmmxt_load_creg(wrd); + tmp2 = load_reg(s, rd); + tcg_gen_andc_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + iwmmxt_store_creg(wrd, tmp); + break; + case ARM_IWMMXT_wCGR0: + case ARM_IWMMXT_wCGR1: + case ARM_IWMMXT_wCGR2: + case ARM_IWMMXT_wCGR3: + gen_op_iwmmxt_set_cup(); + tmp = load_reg(s, rd); + iwmmxt_store_creg(wrd, tmp); + break; + default: + return 1; + } + break; + case 0x100: /* WXOR */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 0) & 0xf; + rd1 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + gen_op_iwmmxt_xorq_M0_wRn(rd1); + gen_op_iwmmxt_setpsr_nz(); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x111: /* TMRC */ + if (insn & 0xf) + return 1; + rd = (insn >> 12) & 0xf; + wrd = (insn >> 16) & 0xf; + tmp = iwmmxt_load_creg(wrd); + store_reg(s, rd, tmp); + break; + case 0x300: /* WANDN */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 0) & 0xf; + rd1 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tcg_gen_neg_i64(cpu_M0, cpu_M0); + gen_op_iwmmxt_andq_M0_wRn(rd1); + gen_op_iwmmxt_setpsr_nz(); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x200: /* WAND */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 0) & 0xf; + rd1 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + gen_op_iwmmxt_andq_M0_wRn(rd1); + gen_op_iwmmxt_setpsr_nz(); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x810: case 0xa10: /* WMADD */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 0) & 0xf; + rd1 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + if (insn & (1 << 21)) + gen_op_iwmmxt_maddsq_M0_wRn(rd1); + else + gen_op_iwmmxt_madduq_M0_wRn(rd1); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + gen_op_iwmmxt_unpacklb_M0_wRn(rd1); + break; + case 1: + gen_op_iwmmxt_unpacklw_M0_wRn(rd1); + break; + case 2: + gen_op_iwmmxt_unpackll_M0_wRn(rd1); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + gen_op_iwmmxt_unpackhb_M0_wRn(rd1); + break; + case 1: + gen_op_iwmmxt_unpackhw_M0_wRn(rd1); + break; + case 2: + gen_op_iwmmxt_unpackhl_M0_wRn(rd1); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + if (insn & (1 << 22)) + gen_op_iwmmxt_sadw_M0_wRn(rd1); + else + gen_op_iwmmxt_sadb_M0_wRn(rd1); + if (!(insn & (1 << 20))) + gen_op_iwmmxt_addl_M0_wRn(wrd); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + if (insn & (1 << 21)) { + if (insn & (1 << 20)) + gen_op_iwmmxt_mulshw_M0_wRn(rd1); + else + gen_op_iwmmxt_mulslw_M0_wRn(rd1); + } else { + if (insn & (1 << 20)) + gen_op_iwmmxt_muluhw_M0_wRn(rd1); + else + gen_op_iwmmxt_mululw_M0_wRn(rd1); + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + if (insn & (1 << 21)) + gen_op_iwmmxt_macsw_M0_wRn(rd1); + else + gen_op_iwmmxt_macuw_M0_wRn(rd1); + if (!(insn & (1 << 20))) { + iwmmxt_load_reg(cpu_V1, wrd); + tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + gen_op_iwmmxt_cmpeqb_M0_wRn(rd1); + break; + case 1: + gen_op_iwmmxt_cmpeqw_M0_wRn(rd1); + break; + case 2: + gen_op_iwmmxt_cmpeql_M0_wRn(rd1); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + if (insn & (1 << 22)) { + if (insn & (1 << 20)) + gen_op_iwmmxt_avgw1_M0_wRn(rd1); + else + gen_op_iwmmxt_avgw0_M0_wRn(rd1); + } else { + if (insn & (1 << 20)) + gen_op_iwmmxt_avgb1_M0_wRn(rd1); + else + gen_op_iwmmxt_avgb0_M0_wRn(rd1); + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3)); + tcg_gen_andi_i32(tmp, tmp, 7); + iwmmxt_load_reg(cpu_V1, rd1); + gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */ + if (((insn >> 6) & 3) == 3) + return 1; + rd = (insn >> 12) & 0xf; + wrd = (insn >> 16) & 0xf; + tmp = load_reg(s, rd); + gen_op_iwmmxt_movq_M0_wRn(wrd); + switch ((insn >> 6) & 3) { + case 0: + tmp2 = tcg_const_i32(0xff); + tmp3 = tcg_const_i32((insn & 7) << 3); + break; + case 1: + tmp2 = tcg_const_i32(0xffff); + tmp3 = tcg_const_i32((insn & 3) << 4); + break; + case 2: + tmp2 = tcg_const_i32(0xffffffff); + tmp3 = tcg_const_i32((insn & 1) << 5); + break; + default: + TCGV_UNUSED_I32(tmp2); + TCGV_UNUSED_I32(tmp3); + } + gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3); + tcg_temp_free_i32(tmp3); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */ + rd = (insn >> 12) & 0xf; + wrd = (insn >> 16) & 0xf; + if (rd == 15 || ((insn >> 22) & 3) == 3) + return 1; + gen_op_iwmmxt_movq_M0_wRn(wrd); + tmp = tcg_temp_new_i32(); + switch ((insn >> 22) & 3) { + case 0: + tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3); + tcg_gen_extrl_i64_i32(tmp, cpu_M0); + if (insn & 8) { + tcg_gen_ext8s_i32(tmp, tmp); + } else { + tcg_gen_andi_i32(tmp, tmp, 0xff); + } + break; + case 1: + tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4); + tcg_gen_extrl_i64_i32(tmp, cpu_M0); + if (insn & 8) { + tcg_gen_ext16s_i32(tmp, tmp); + } else { + tcg_gen_andi_i32(tmp, tmp, 0xffff); + } + break; + case 2: + tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5); + tcg_gen_extrl_i64_i32(tmp, cpu_M0); + break; + } + store_reg(s, rd, tmp); + break; + case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */ + if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3) + return 1; + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); + switch ((insn >> 22) & 3) { + case 0: + tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0); + break; + case 1: + tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4); + break; + case 2: + tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12); + break; + } + tcg_gen_shli_i32(tmp, tmp, 28); + gen_set_nzcv(tmp); + tcg_temp_free_i32(tmp); + break; + case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */ + if (((insn >> 6) & 3) == 3) + return 1; + rd = (insn >> 12) & 0xf; + wrd = (insn >> 16) & 0xf; + tmp = load_reg(s, rd); + switch ((insn >> 6) & 3) { + case 0: + gen_helper_iwmmxt_bcstb(cpu_M0, tmp); + break; + case 1: + gen_helper_iwmmxt_bcstw(cpu_M0, tmp); + break; + case 2: + gen_helper_iwmmxt_bcstl(cpu_M0, tmp); + break; + } + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */ + if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) + return 1; + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); + tmp2 = tcg_temp_new_i32(); + tcg_gen_mov_i32(tmp2, tmp); + switch ((insn >> 22) & 3) { + case 0: + for (i = 0; i < 7; i ++) { + tcg_gen_shli_i32(tmp2, tmp2, 4); + tcg_gen_and_i32(tmp, tmp, tmp2); + } + break; + case 1: + for (i = 0; i < 3; i ++) { + tcg_gen_shli_i32(tmp2, tmp2, 8); + tcg_gen_and_i32(tmp, tmp, tmp2); + } + break; + case 2: + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_and_i32(tmp, tmp, tmp2); + break; + } + gen_set_nzcv(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; + case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */ + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0); + break; + case 1: + gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0); + break; + case 2: + gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */ + if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) + return 1; + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); + tmp2 = tcg_temp_new_i32(); + tcg_gen_mov_i32(tmp2, tmp); + switch ((insn >> 22) & 3) { + case 0: + for (i = 0; i < 7; i ++) { + tcg_gen_shli_i32(tmp2, tmp2, 4); + tcg_gen_or_i32(tmp, tmp, tmp2); + } + break; + case 1: + for (i = 0; i < 3; i ++) { + tcg_gen_shli_i32(tmp2, tmp2, 8); + tcg_gen_or_i32(tmp, tmp, tmp2); + } + break; + case 2: + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_or_i32(tmp, tmp, tmp2); + break; + } + gen_set_nzcv(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; + case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */ + rd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3) + return 1; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_temp_new_i32(); + switch ((insn >> 22) & 3) { + case 0: + gen_helper_iwmmxt_msbb(tmp, cpu_M0); + break; + case 1: + gen_helper_iwmmxt_msbw(tmp, cpu_M0); + break; + case 2: + gen_helper_iwmmxt_msbl(tmp, cpu_M0); + break; + } + store_reg(s, rd, tmp); + break; + case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */ + case 0x906: case 0xb06: case 0xd06: case 0xf06: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + if (insn & (1 << 21)) + gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1); + else + gen_op_iwmmxt_cmpgtub_M0_wRn(rd1); + break; + case 1: + if (insn & (1 << 21)) + gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1); + else + gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1); + break; + case 2: + if (insn & (1 << 21)) + gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1); + else + gen_op_iwmmxt_cmpgtul_M0_wRn(rd1); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */ + case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + if (insn & (1 << 21)) + gen_op_iwmmxt_unpacklsb_M0(); + else + gen_op_iwmmxt_unpacklub_M0(); + break; + case 1: + if (insn & (1 << 21)) + gen_op_iwmmxt_unpacklsw_M0(); + else + gen_op_iwmmxt_unpackluw_M0(); + break; + case 2: + if (insn & (1 << 21)) + gen_op_iwmmxt_unpacklsl_M0(); + else + gen_op_iwmmxt_unpacklul_M0(); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */ + case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + if (insn & (1 << 21)) + gen_op_iwmmxt_unpackhsb_M0(); + else + gen_op_iwmmxt_unpackhub_M0(); + break; + case 1: + if (insn & (1 << 21)) + gen_op_iwmmxt_unpackhsw_M0(); + else + gen_op_iwmmxt_unpackhuw_M0(); + break; + case 2: + if (insn & (1 << 21)) + gen_op_iwmmxt_unpackhsl_M0(); + else + gen_op_iwmmxt_unpackhul_M0(); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */ + case 0x214: case 0x614: case 0xa14: case 0xe14: + if (((insn >> 22) & 3) == 0) + return 1; + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_temp_new_i32(); + if (gen_iwmmxt_shift(insn, 0xff, tmp)) { + tcg_temp_free_i32(tmp); + return 1; + } + switch ((insn >> 22) & 3) { + case 1: + gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 2: + gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 3: + gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp); + break; + } + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */ + case 0x014: case 0x414: case 0x814: case 0xc14: + if (((insn >> 22) & 3) == 0) + return 1; + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_temp_new_i32(); + if (gen_iwmmxt_shift(insn, 0xff, tmp)) { + tcg_temp_free_i32(tmp); + return 1; + } + switch ((insn >> 22) & 3) { + case 1: + gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 2: + gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 3: + gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp); + break; + } + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */ + case 0x114: case 0x514: case 0x914: case 0xd14: + if (((insn >> 22) & 3) == 0) + return 1; + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_temp_new_i32(); + if (gen_iwmmxt_shift(insn, 0xff, tmp)) { + tcg_temp_free_i32(tmp); + return 1; + } + switch ((insn >> 22) & 3) { + case 1: + gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 2: + gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 3: + gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp); + break; + } + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */ + case 0x314: case 0x714: case 0xb14: case 0xf14: + if (((insn >> 22) & 3) == 0) + return 1; + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_temp_new_i32(); + switch ((insn >> 22) & 3) { + case 1: + if (gen_iwmmxt_shift(insn, 0xf, tmp)) { + tcg_temp_free_i32(tmp); + return 1; + } + gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 2: + if (gen_iwmmxt_shift(insn, 0x1f, tmp)) { + tcg_temp_free_i32(tmp); + return 1; + } + gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp); + break; + case 3: + if (gen_iwmmxt_shift(insn, 0x3f, tmp)) { + tcg_temp_free_i32(tmp); + return 1; + } + gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp); + break; + } + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */ + case 0x916: case 0xb16: case 0xd16: case 0xf16: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + if (insn & (1 << 21)) + gen_op_iwmmxt_minsb_M0_wRn(rd1); + else + gen_op_iwmmxt_minub_M0_wRn(rd1); + break; + case 1: + if (insn & (1 << 21)) + gen_op_iwmmxt_minsw_M0_wRn(rd1); + else + gen_op_iwmmxt_minuw_M0_wRn(rd1); + break; + case 2: + if (insn & (1 << 21)) + gen_op_iwmmxt_minsl_M0_wRn(rd1); + else + gen_op_iwmmxt_minul_M0_wRn(rd1); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */ + case 0x816: case 0xa16: case 0xc16: case 0xe16: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 0: + if (insn & (1 << 21)) + gen_op_iwmmxt_maxsb_M0_wRn(rd1); + else + gen_op_iwmmxt_maxub_M0_wRn(rd1); + break; + case 1: + if (insn & (1 << 21)) + gen_op_iwmmxt_maxsw_M0_wRn(rd1); + else + gen_op_iwmmxt_maxuw_M0_wRn(rd1); + break; + case 2: + if (insn & (1 << 21)) + gen_op_iwmmxt_maxsl_M0_wRn(rd1); + else + gen_op_iwmmxt_maxul_M0_wRn(rd1); + break; + case 3: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */ + case 0x402: case 0x502: case 0x602: case 0x702: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_const_i32((insn >> 20) & 3); + iwmmxt_load_reg(cpu_V1, rd1); + gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */ + case 0x41a: case 0x51a: case 0x61a: case 0x71a: + case 0x81a: case 0x91a: case 0xa1a: case 0xb1a: + case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 20) & 0xf) { + case 0x0: + gen_op_iwmmxt_subnb_M0_wRn(rd1); + break; + case 0x1: + gen_op_iwmmxt_subub_M0_wRn(rd1); + break; + case 0x3: + gen_op_iwmmxt_subsb_M0_wRn(rd1); + break; + case 0x4: + gen_op_iwmmxt_subnw_M0_wRn(rd1); + break; + case 0x5: + gen_op_iwmmxt_subuw_M0_wRn(rd1); + break; + case 0x7: + gen_op_iwmmxt_subsw_M0_wRn(rd1); + break; + case 0x8: + gen_op_iwmmxt_subnl_M0_wRn(rd1); + break; + case 0x9: + gen_op_iwmmxt_subul_M0_wRn(rd1); + break; + case 0xb: + gen_op_iwmmxt_subsl_M0_wRn(rd1); + break; + default: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */ + case 0x41e: case 0x51e: case 0x61e: case 0x71e: + case 0x81e: case 0x91e: case 0xa1e: case 0xb1e: + case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f)); + gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp); + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */ + case 0x418: case 0x518: case 0x618: case 0x718: + case 0x818: case 0x918: case 0xa18: case 0xb18: + case 0xc18: case 0xd18: case 0xe18: case 0xf18: + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 20) & 0xf) { + case 0x0: + gen_op_iwmmxt_addnb_M0_wRn(rd1); + break; + case 0x1: + gen_op_iwmmxt_addub_M0_wRn(rd1); + break; + case 0x3: + gen_op_iwmmxt_addsb_M0_wRn(rd1); + break; + case 0x4: + gen_op_iwmmxt_addnw_M0_wRn(rd1); + break; + case 0x5: + gen_op_iwmmxt_adduw_M0_wRn(rd1); + break; + case 0x7: + gen_op_iwmmxt_addsw_M0_wRn(rd1); + break; + case 0x8: + gen_op_iwmmxt_addnl_M0_wRn(rd1); + break; + case 0x9: + gen_op_iwmmxt_addul_M0_wRn(rd1); + break; + case 0xb: + gen_op_iwmmxt_addsl_M0_wRn(rd1); + break; + default: + return 1; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */ + case 0x408: case 0x508: case 0x608: case 0x708: + case 0x808: case 0x908: case 0xa08: case 0xb08: + case 0xc08: case 0xd08: case 0xe08: case 0xf08: + if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0) + return 1; + wrd = (insn >> 12) & 0xf; + rd0 = (insn >> 16) & 0xf; + rd1 = (insn >> 0) & 0xf; + gen_op_iwmmxt_movq_M0_wRn(rd0); + switch ((insn >> 22) & 3) { + case 1: + if (insn & (1 << 21)) + gen_op_iwmmxt_packsw_M0_wRn(rd1); + else + gen_op_iwmmxt_packuw_M0_wRn(rd1); + break; + case 2: + if (insn & (1 << 21)) + gen_op_iwmmxt_packsl_M0_wRn(rd1); + else + gen_op_iwmmxt_packul_M0_wRn(rd1); + break; + case 3: + if (insn & (1 << 21)) + gen_op_iwmmxt_packsq_M0_wRn(rd1); + else + gen_op_iwmmxt_packuq_M0_wRn(rd1); + break; + } + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + gen_op_iwmmxt_set_cup(); + break; + case 0x201: case 0x203: case 0x205: case 0x207: + case 0x209: case 0x20b: case 0x20d: case 0x20f: + case 0x211: case 0x213: case 0x215: case 0x217: + case 0x219: case 0x21b: case 0x21d: case 0x21f: + wrd = (insn >> 5) & 0xf; + rd0 = (insn >> 12) & 0xf; + rd1 = (insn >> 0) & 0xf; + if (rd0 == 0xf || rd1 == 0xf) + return 1; + gen_op_iwmmxt_movq_M0_wRn(wrd); + tmp = load_reg(s, rd0); + tmp2 = load_reg(s, rd1); + switch ((insn >> 16) & 0xf) { + case 0x0: /* TMIA */ + gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); + break; + case 0x8: /* TMIAPH */ + gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); + break; + case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */ + if (insn & (1 << 16)) + tcg_gen_shri_i32(tmp, tmp, 16); + if (insn & (1 << 17)) + tcg_gen_shri_i32(tmp2, tmp2, 16); + gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); + break; + default: + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + return 1; + } + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + gen_op_iwmmxt_movq_wRn_M0(wrd); + gen_op_iwmmxt_set_mup(); + break; + default: + return 1; + } + + return 0; +} + +/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred + (ie. an undefined instruction). */ +static int disas_dsp_insn(DisasContext *s, uint32_t insn) +{ + int acc, rd0, rd1, rdhi, rdlo; + TCGv_i32 tmp, tmp2; + + if ((insn & 0x0ff00f10) == 0x0e200010) { + /* Multiply with Internal Accumulate Format */ + rd0 = (insn >> 12) & 0xf; + rd1 = insn & 0xf; + acc = (insn >> 5) & 7; + + if (acc != 0) + return 1; + + tmp = load_reg(s, rd0); + tmp2 = load_reg(s, rd1); + switch ((insn >> 16) & 0xf) { + case 0x0: /* MIA */ + gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); + break; + case 0x8: /* MIAPH */ + gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); + break; + case 0xc: /* MIABB */ + case 0xd: /* MIABT */ + case 0xe: /* MIATB */ + case 0xf: /* MIATT */ + if (insn & (1 << 16)) + tcg_gen_shri_i32(tmp, tmp, 16); + if (insn & (1 << 17)) + tcg_gen_shri_i32(tmp2, tmp2, 16); + gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); + break; + default: + return 1; + } + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + + gen_op_iwmmxt_movq_wRn_M0(acc); + return 0; + } + + if ((insn & 0x0fe00ff8) == 0x0c400000) { + /* Internal Accumulator Access Format */ + rdhi = (insn >> 16) & 0xf; + rdlo = (insn >> 12) & 0xf; + acc = insn & 7; + + if (acc != 0) + return 1; + + if (insn & ARM_CP_RW_BIT) { /* MRA */ + iwmmxt_load_reg(cpu_V0, acc); + tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0); + tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); + tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0); + tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1); + } else { /* MAR */ + tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); + iwmmxt_store_reg(cpu_V0, acc); + } + return 0; + } + + return 1; +} + +#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n)) +#define VFP_SREG(insn, bigbit, smallbit) \ + ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1)) +#define VFP_DREG(reg, insn, bigbit, smallbit) do { \ + if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \ + reg = (((insn) >> (bigbit)) & 0x0f) \ + | (((insn) >> ((smallbit) - 4)) & 0x10); \ + } else { \ + if (insn & (1 << (smallbit))) \ + return 1; \ + reg = ((insn) >> (bigbit)) & 0x0f; \ + }} while (0) + +#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22) +#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22) +#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7) +#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7) +#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5) +#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5) + +/* Move between integer and VFP cores. */ +static TCGv_i32 gen_vfp_mrs(void) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_mov_i32(tmp, cpu_F0s); + return tmp; +} + +static void gen_vfp_msr(TCGv_i32 tmp) +{ + tcg_gen_mov_i32(cpu_F0s, tmp); + tcg_temp_free_i32(tmp); +} + +static void gen_neon_dup_u8(TCGv_i32 var, int shift) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + if (shift) + tcg_gen_shri_i32(var, var, shift); + tcg_gen_ext8u_i32(var, var); + tcg_gen_shli_i32(tmp, var, 8); + tcg_gen_or_i32(var, var, tmp); + tcg_gen_shli_i32(tmp, var, 16); + tcg_gen_or_i32(var, var, tmp); + tcg_temp_free_i32(tmp); +} + +static void gen_neon_dup_low16(TCGv_i32 var) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_ext16u_i32(var, var); + tcg_gen_shli_i32(tmp, var, 16); + tcg_gen_or_i32(var, var, tmp); + tcg_temp_free_i32(tmp); +} + +static void gen_neon_dup_high16(TCGv_i32 var) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_andi_i32(var, var, 0xffff0000); + tcg_gen_shri_i32(tmp, var, 16); + tcg_gen_or_i32(var, var, tmp); + tcg_temp_free_i32(tmp); +} + +static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size) +{ + /* Load a single Neon element and replicate into a 32 bit TCG reg */ + TCGv_i32 tmp = tcg_temp_new_i32(); + switch (size) { + case 0: + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + gen_neon_dup_u8(tmp, 0); + break; + case 1: + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + gen_neon_dup_low16(tmp); + break; + case 2: + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + default: /* Avoid compiler warnings. */ + abort(); + } + return tmp; +} + +static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm, + uint32_t dp) +{ + uint32_t cc = extract32(insn, 20, 2); + + if (dp) { + TCGv_i64 frn, frm, dest; + TCGv_i64 tmp, zero, zf, nf, vf; + + zero = tcg_const_i64(0); + + frn = tcg_temp_new_i64(); + frm = tcg_temp_new_i64(); + dest = tcg_temp_new_i64(); + + zf = tcg_temp_new_i64(); + nf = tcg_temp_new_i64(); + vf = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(zf, cpu_ZF); + tcg_gen_ext_i32_i64(nf, cpu_NF); + tcg_gen_ext_i32_i64(vf, cpu_VF); + + tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn)); + tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm)); + switch (cc) { + case 0: /* eq: Z */ + tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero, + frn, frm); + break; + case 1: /* vs: V */ + tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero, + frn, frm); + break; + case 2: /* ge: N == V -> N ^ V == 0 */ + tmp = tcg_temp_new_i64(); + tcg_gen_xor_i64(tmp, vf, nf); + tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero, + frn, frm); + tcg_temp_free_i64(tmp); + break; + case 3: /* gt: !Z && N == V */ + tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero, + frn, frm); + tmp = tcg_temp_new_i64(); + tcg_gen_xor_i64(tmp, vf, nf); + tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero, + dest, frm); + tcg_temp_free_i64(tmp); + break; + } + tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i64(frn); + tcg_temp_free_i64(frm); + tcg_temp_free_i64(dest); + + tcg_temp_free_i64(zf); + tcg_temp_free_i64(nf); + tcg_temp_free_i64(vf); + + tcg_temp_free_i64(zero); + } else { + TCGv_i32 frn, frm, dest; + TCGv_i32 tmp, zero; + + zero = tcg_const_i32(0); + + frn = tcg_temp_new_i32(); + frm = tcg_temp_new_i32(); + dest = tcg_temp_new_i32(); + tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn)); + tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm)); + switch (cc) { + case 0: /* eq: Z */ + tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero, + frn, frm); + break; + case 1: /* vs: V */ + tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero, + frn, frm); + break; + case 2: /* ge: N == V -> N ^ V == 0 */ + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); + tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero, + frn, frm); + tcg_temp_free_i32(tmp); + break; + case 3: /* gt: !Z && N == V */ + tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero, + frn, frm); + tmp = tcg_temp_new_i32(); + tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); + tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero, + dest, frm); + tcg_temp_free_i32(tmp); + break; + } + tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i32(frn); + tcg_temp_free_i32(frm); + tcg_temp_free_i32(dest); + + tcg_temp_free_i32(zero); + } + + return 0; +} + +static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn, + uint32_t rm, uint32_t dp) +{ + uint32_t vmin = extract32(insn, 6, 1); + TCGv_ptr fpst = get_fpstatus_ptr(0); + + if (dp) { + TCGv_i64 frn, frm, dest; + + frn = tcg_temp_new_i64(); + frm = tcg_temp_new_i64(); + dest = tcg_temp_new_i64(); + + tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn)); + tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm)); + if (vmin) { + gen_helper_vfp_minnumd(dest, frn, frm, fpst); + } else { + gen_helper_vfp_maxnumd(dest, frn, frm, fpst); + } + tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i64(frn); + tcg_temp_free_i64(frm); + tcg_temp_free_i64(dest); + } else { + TCGv_i32 frn, frm, dest; + + frn = tcg_temp_new_i32(); + frm = tcg_temp_new_i32(); + dest = tcg_temp_new_i32(); + + tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn)); + tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm)); + if (vmin) { + gen_helper_vfp_minnums(dest, frn, frm, fpst); + } else { + gen_helper_vfp_maxnums(dest, frn, frm, fpst); + } + tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i32(frn); + tcg_temp_free_i32(frm); + tcg_temp_free_i32(dest); + } + + tcg_temp_free_ptr(fpst); + return 0; +} + +static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, + int rounding) +{ + TCGv_ptr fpst = get_fpstatus_ptr(0); + TCGv_i32 tcg_rmode; + + tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding)); + gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + + if (dp) { + TCGv_i64 tcg_op; + TCGv_i64 tcg_res; + tcg_op = tcg_temp_new_i64(); + tcg_res = tcg_temp_new_i64(); + tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm)); + gen_helper_rintd(tcg_res, tcg_op, fpst); + tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i64(tcg_op); + tcg_temp_free_i64(tcg_res); + } else { + TCGv_i32 tcg_op; + TCGv_i32 tcg_res; + tcg_op = tcg_temp_new_i32(); + tcg_res = tcg_temp_new_i32(); + tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm)); + gen_helper_rints(tcg_res, tcg_op, fpst); + tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i32(tcg_op); + tcg_temp_free_i32(tcg_res); + } + + gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + tcg_temp_free_i32(tcg_rmode); + + tcg_temp_free_ptr(fpst); + return 0; +} + +static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, + int rounding) +{ + bool is_signed = extract32(insn, 7, 1); + TCGv_ptr fpst = get_fpstatus_ptr(0); + TCGv_i32 tcg_rmode, tcg_shift; + + tcg_shift = tcg_const_i32(0); + + tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding)); + gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + + if (dp) { + TCGv_i64 tcg_double, tcg_res; + TCGv_i32 tcg_tmp; + /* Rd is encoded as a single precision register even when the source + * is double precision. + */ + rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1); + tcg_double = tcg_temp_new_i64(); + tcg_res = tcg_temp_new_i64(); + tcg_tmp = tcg_temp_new_i32(); + tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm)); + if (is_signed) { + gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst); + } else { + gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst); + } + tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res); + tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd)); + tcg_temp_free_i32(tcg_tmp); + tcg_temp_free_i64(tcg_res); + tcg_temp_free_i64(tcg_double); + } else { + TCGv_i32 tcg_single, tcg_res; + tcg_single = tcg_temp_new_i32(); + tcg_res = tcg_temp_new_i32(); + tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm)); + if (is_signed) { + gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst); + } else { + gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst); + } + tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd)); + tcg_temp_free_i32(tcg_res); + tcg_temp_free_i32(tcg_single); + } + + gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + tcg_temp_free_i32(tcg_rmode); + + tcg_temp_free_i32(tcg_shift); + + tcg_temp_free_ptr(fpst); + + return 0; +} + +/* Table for converting the most common AArch32 encoding of + * rounding mode to arm_fprounding order (which matches the + * common AArch64 order); see ARM ARM pseudocode FPDecodeRM(). + */ +static const uint8_t fp_decode_rm[] = { + FPROUNDING_TIEAWAY, + FPROUNDING_TIEEVEN, + FPROUNDING_POSINF, + FPROUNDING_NEGINF, +}; + +static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn) +{ + uint32_t rd, rn, rm, dp = extract32(insn, 8, 1); + + if (!arm_dc_feature(s, ARM_FEATURE_V8)) { + return 1; + } + + if (dp) { + VFP_DREG_D(rd, insn); + VFP_DREG_N(rn, insn); + VFP_DREG_M(rm, insn); + } else { + rd = VFP_SREG_D(insn); + rn = VFP_SREG_N(insn); + rm = VFP_SREG_M(insn); + } + + if ((insn & 0x0f800e50) == 0x0e000a00) { + return handle_vsel(insn, rd, rn, rm, dp); + } else if ((insn & 0x0fb00e10) == 0x0e800a00) { + return handle_vminmaxnm(insn, rd, rn, rm, dp); + } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) { + /* VRINTA, VRINTN, VRINTP, VRINTM */ + int rounding = fp_decode_rm[extract32(insn, 16, 2)]; + return handle_vrint(insn, rd, rm, dp, rounding); + } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) { + /* VCVTA, VCVTN, VCVTP, VCVTM */ + int rounding = fp_decode_rm[extract32(insn, 16, 2)]; + return handle_vcvt(insn, rd, rm, dp, rounding); + } + return 1; +} + +/* Disassemble a VFP instruction. Returns nonzero if an error occurred + (ie. an undefined instruction). */ +static int disas_vfp_insn(DisasContext *s, uint32_t insn) +{ + uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; + int dp, veclen; + TCGv_i32 addr; + TCGv_i32 tmp; + TCGv_i32 tmp2; + + if (!arm_dc_feature(s, ARM_FEATURE_VFP)) { + return 1; + } + + /* FIXME: this access check should not take precedence over UNDEF + * for invalid encodings; we will generate incorrect syndrome information + * for attempts to execute invalid vfp/neon encodings with FP disabled. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el); + return 0; + } + + if (!s->vfp_enabled) { + /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ + if ((insn & 0x0fe00fff) != 0x0ee00a10) + return 1; + rn = (insn >> 16) & 0xf; + if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2 + && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) { + return 1; + } + } + + if (extract32(insn, 28, 4) == 0xf) { + /* Encodings with T=1 (Thumb) or unconditional (ARM): + * only used in v8 and above. + */ + return disas_vfp_v8_insn(s, insn); + } + + dp = ((insn & 0xf00) == 0xb00); + switch ((insn >> 24) & 0xf) { + case 0xe: + if (insn & (1 << 4)) { + /* single register transfer */ + rd = (insn >> 12) & 0xf; + if (dp) { + int size; + int pass; + + VFP_DREG_N(rn, insn); + if (insn & 0xf) + return 1; + if (insn & 0x00c00060 + && !arm_dc_feature(s, ARM_FEATURE_NEON)) { + return 1; + } + + pass = (insn >> 21) & 1; + if (insn & (1 << 22)) { + size = 0; + offset = ((insn >> 5) & 3) * 8; + } else if (insn & (1 << 5)) { + size = 1; + offset = (insn & (1 << 6)) ? 16 : 0; + } else { + size = 2; + offset = 0; + } + if (insn & ARM_CP_RW_BIT) { + /* vfp->arm */ + tmp = neon_load_reg(rn, pass); + switch (size) { + case 0: + if (offset) + tcg_gen_shri_i32(tmp, tmp, offset); + if (insn & (1 << 23)) + gen_uxtb(tmp); + else + gen_sxtb(tmp); + break; + case 1: + if (insn & (1 << 23)) { + if (offset) { + tcg_gen_shri_i32(tmp, tmp, 16); + } else { + gen_uxth(tmp); + } + } else { + if (offset) { + tcg_gen_sari_i32(tmp, tmp, 16); + } else { + gen_sxth(tmp); + } + } + break; + case 2: + break; + } + store_reg(s, rd, tmp); + } else { + /* arm->vfp */ + tmp = load_reg(s, rd); + if (insn & (1 << 23)) { + /* VDUP */ + if (size == 0) { + gen_neon_dup_u8(tmp, 0); + } else if (size == 1) { + gen_neon_dup_low16(tmp); + } + for (n = 0; n <= pass * 2; n++) { + tmp2 = tcg_temp_new_i32(); + tcg_gen_mov_i32(tmp2, tmp); + neon_store_reg(rn, n, tmp2); + } + neon_store_reg(rn, n, tmp); + } else { + /* VMOV */ + switch (size) { + case 0: + tmp2 = neon_load_reg(rn, pass); + tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8); + tcg_temp_free_i32(tmp2); + break; + case 1: + tmp2 = neon_load_reg(rn, pass); + tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16); + tcg_temp_free_i32(tmp2); + break; + case 2: + break; + } + neon_store_reg(rn, pass, tmp); + } + } + } else { /* !dp */ + if ((insn & 0x6f) != 0x00) + return 1; + rn = VFP_SREG_N(insn); + if (insn & ARM_CP_RW_BIT) { + /* vfp->arm */ + if (insn & (1 << 21)) { + /* system register */ + rn >>= 1; + + switch (rn) { + case ARM_VFP_FPSID: + /* VFP2 allows access to FSID from userspace. + VFP3 restricts all id registers to privileged + accesses. */ + if (IS_USER(s) + && arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + tmp = load_cpu_field(vfp.xregs[rn]); + break; + case ARM_VFP_FPEXC: + if (IS_USER(s)) + return 1; + tmp = load_cpu_field(vfp.xregs[rn]); + break; + case ARM_VFP_FPINST: + case ARM_VFP_FPINST2: + /* Not present in VFP3. */ + if (IS_USER(s) + || arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + tmp = load_cpu_field(vfp.xregs[rn]); + break; + case ARM_VFP_FPSCR: + if (rd == 15) { + tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); + tcg_gen_andi_i32(tmp, tmp, 0xf0000000); + } else { + tmp = tcg_temp_new_i32(); + gen_helper_vfp_get_fpscr(tmp, cpu_env); + } + break; + case ARM_VFP_MVFR2: + if (!arm_dc_feature(s, ARM_FEATURE_V8)) { + return 1; + } + /* fall through */ + case ARM_VFP_MVFR0: + case ARM_VFP_MVFR1: + if (IS_USER(s) + || !arm_dc_feature(s, ARM_FEATURE_MVFR)) { + return 1; + } + tmp = load_cpu_field(vfp.xregs[rn]); + break; + default: + return 1; + } + } else { + gen_mov_F0_vreg(0, rn); + tmp = gen_vfp_mrs(); + } + if (rd == 15) { + /* Set the 4 flag bits in the CPSR. */ + gen_set_nzcv(tmp); + tcg_temp_free_i32(tmp); + } else { + store_reg(s, rd, tmp); + } + } else { + /* arm->vfp */ + if (insn & (1 << 21)) { + rn >>= 1; + /* system register */ + switch (rn) { + case ARM_VFP_FPSID: + case ARM_VFP_MVFR0: + case ARM_VFP_MVFR1: + /* Writes are ignored. */ + break; + case ARM_VFP_FPSCR: + tmp = load_reg(s, rd); + gen_helper_vfp_set_fpscr(cpu_env, tmp); + tcg_temp_free_i32(tmp); + gen_lookup_tb(s); + break; + case ARM_VFP_FPEXC: + if (IS_USER(s)) + return 1; + /* TODO: VFP subarchitecture support. + * For now, keep the EN bit only */ + tmp = load_reg(s, rd); + tcg_gen_andi_i32(tmp, tmp, 1 << 30); + store_cpu_field(tmp, vfp.xregs[rn]); + gen_lookup_tb(s); + break; + case ARM_VFP_FPINST: + case ARM_VFP_FPINST2: + if (IS_USER(s)) { + return 1; + } + tmp = load_reg(s, rd); + store_cpu_field(tmp, vfp.xregs[rn]); + break; + default: + return 1; + } + } else { + tmp = load_reg(s, rd); + gen_vfp_msr(tmp); + gen_mov_vreg_F0(0, rn); + } + } + } + } else { + /* data processing */ + /* The opcode is in bits 23, 21, 20 and 6. */ + op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1); + if (dp) { + if (op == 15) { + /* rn is opcode */ + rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1); + } else { + /* rn is register number */ + VFP_DREG_N(rn, insn); + } + + if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) || + ((rn & 0x1e) == 0x6))) { + /* Integer or single/half precision destination. */ + rd = VFP_SREG_D(insn); + } else { + VFP_DREG_D(rd, insn); + } + if (op == 15 && + (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) || + ((rn & 0x1e) == 0x4))) { + /* VCVT from int or half precision is always from S reg + * regardless of dp bit. VCVT with immediate frac_bits + * has same format as SREG_M. + */ + rm = VFP_SREG_M(insn); + } else { + VFP_DREG_M(rm, insn); + } + } else { + rn = VFP_SREG_N(insn); + if (op == 15 && rn == 15) { + /* Double precision destination. */ + VFP_DREG_D(rd, insn); + } else { + rd = VFP_SREG_D(insn); + } + /* NB that we implicitly rely on the encoding for the frac_bits + * in VCVT of fixed to float being the same as that of an SREG_M + */ + rm = VFP_SREG_M(insn); + } + + veclen = s->vec_len; + if (op == 15 && rn > 3) + veclen = 0; + + /* Shut up compiler warnings. */ + delta_m = 0; + delta_d = 0; + bank_mask = 0; + + if (veclen > 0) { + if (dp) + bank_mask = 0xc; + else + bank_mask = 0x18; + + /* Figure out what type of vector operation this is. */ + if ((rd & bank_mask) == 0) { + /* scalar */ + veclen = 0; + } else { + if (dp) + delta_d = (s->vec_stride >> 1) + 1; + else + delta_d = s->vec_stride + 1; + + if ((rm & bank_mask) == 0) { + /* mixed scalar/vector */ + delta_m = 0; + } else { + /* vector */ + delta_m = delta_d; + } + } + } + + /* Load the initial operands. */ + if (op == 15) { + switch (rn) { + case 16: + case 17: + /* Integer source */ + gen_mov_F0_vreg(0, rm); + break; + case 8: + case 9: + /* Compare */ + gen_mov_F0_vreg(dp, rd); + gen_mov_F1_vreg(dp, rm); + break; + case 10: + case 11: + /* Compare with zero */ + gen_mov_F0_vreg(dp, rd); + gen_vfp_F1_ld0(dp); + break; + case 20: + case 21: + case 22: + case 23: + case 28: + case 29: + case 30: + case 31: + /* Source and destination the same. */ + gen_mov_F0_vreg(dp, rd); + break; + case 4: + case 5: + case 6: + case 7: + /* VCVTB, VCVTT: only present with the halfprec extension + * UNPREDICTABLE if bit 8 is set prior to ARMv8 + * (we choose to UNDEF) + */ + if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) || + !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) { + return 1; + } + if (!extract32(rn, 1, 1)) { + /* Half precision source. */ + gen_mov_F0_vreg(0, rm); + break; + } + /* Otherwise fall through */ + default: + /* One source operand. */ + gen_mov_F0_vreg(dp, rm); + break; + } + } else { + /* Two source operands. */ + gen_mov_F0_vreg(dp, rn); + gen_mov_F1_vreg(dp, rm); + } + + for (;;) { + /* Perform the calculation. */ + switch (op) { + case 0: /* VMLA: fd + (fn * fm) */ + /* Note that order of inputs to the add matters for NaNs */ + gen_vfp_F1_mul(dp); + gen_mov_F0_vreg(dp, rd); + gen_vfp_add(dp); + break; + case 1: /* VMLS: fd + -(fn * fm) */ + gen_vfp_mul(dp); + gen_vfp_F1_neg(dp); + gen_mov_F0_vreg(dp, rd); + gen_vfp_add(dp); + break; + case 2: /* VNMLS: -fd + (fn * fm) */ + /* Note that it isn't valid to replace (-A + B) with (B - A) + * or similar plausible looking simplifications + * because this will give wrong results for NaNs. + */ + gen_vfp_F1_mul(dp); + gen_mov_F0_vreg(dp, rd); + gen_vfp_neg(dp); + gen_vfp_add(dp); + break; + case 3: /* VNMLA: -fd + -(fn * fm) */ + gen_vfp_mul(dp); + gen_vfp_F1_neg(dp); + gen_mov_F0_vreg(dp, rd); + gen_vfp_neg(dp); + gen_vfp_add(dp); + break; + case 4: /* mul: fn * fm */ + gen_vfp_mul(dp); + break; + case 5: /* nmul: -(fn * fm) */ + gen_vfp_mul(dp); + gen_vfp_neg(dp); + break; + case 6: /* add: fn + fm */ + gen_vfp_add(dp); + break; + case 7: /* sub: fn - fm */ + gen_vfp_sub(dp); + break; + case 8: /* div: fn / fm */ + gen_vfp_div(dp); + break; + case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */ + case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */ + case 12: /* VFMA : fd = muladd( fd, fn, fm) */ + case 13: /* VFMS : fd = muladd( fd, -fn, fm) */ + /* These are fused multiply-add, and must be done as one + * floating point operation with no rounding between the + * multiplication and addition steps. + * NB that doing the negations here as separate steps is + * correct : an input NaN should come out with its sign bit + * flipped if it is a negated-input. + */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) { + return 1; + } + if (dp) { + TCGv_ptr fpst; + TCGv_i64 frd; + if (op & 1) { + /* VFNMS, VFMS */ + gen_helper_vfp_negd(cpu_F0d, cpu_F0d); + } + frd = tcg_temp_new_i64(); + tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd)); + if (op & 2) { + /* VFNMA, VFNMS */ + gen_helper_vfp_negd(frd, frd); + } + fpst = get_fpstatus_ptr(0); + gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d, + cpu_F1d, frd, fpst); + tcg_temp_free_ptr(fpst); + tcg_temp_free_i64(frd); + } else { + TCGv_ptr fpst; + TCGv_i32 frd; + if (op & 1) { + /* VFNMS, VFMS */ + gen_helper_vfp_negs(cpu_F0s, cpu_F0s); + } + frd = tcg_temp_new_i32(); + tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd)); + if (op & 2) { + gen_helper_vfp_negs(frd, frd); + } + fpst = get_fpstatus_ptr(0); + gen_helper_vfp_muladds(cpu_F0s, cpu_F0s, + cpu_F1s, frd, fpst); + tcg_temp_free_ptr(fpst); + tcg_temp_free_i32(frd); + } + break; + case 14: /* fconst */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + + n = (insn << 12) & 0x80000000; + i = ((insn >> 12) & 0x70) | (insn & 0xf); + if (dp) { + if (i & 0x40) + i |= 0x3f80; + else + i |= 0x4000; + n |= i << 16; + tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32); + } else { + if (i & 0x40) + i |= 0x780; + else + i |= 0x800; + n |= i << 19; + tcg_gen_movi_i32(cpu_F0s, n); + } + break; + case 15: /* extension space */ + switch (rn) { + case 0: /* cpy */ + /* no-op */ + break; + case 1: /* abs */ + gen_vfp_abs(dp); + break; + case 2: /* neg */ + gen_vfp_neg(dp); + break; + case 3: /* sqrt */ + gen_vfp_sqrt(dp); + break; + case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */ + tmp = gen_vfp_mrs(); + tcg_gen_ext16u_i32(tmp, tmp); + if (dp) { + gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp, + cpu_env); + } else { + gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, + cpu_env); + } + tcg_temp_free_i32(tmp); + break; + case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */ + tmp = gen_vfp_mrs(); + tcg_gen_shri_i32(tmp, tmp, 16); + if (dp) { + gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp, + cpu_env); + } else { + gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, + cpu_env); + } + tcg_temp_free_i32(tmp); + break; + case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */ + tmp = tcg_temp_new_i32(); + if (dp) { + gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d, + cpu_env); + } else { + gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, + cpu_env); + } + gen_mov_F0_vreg(0, rd); + tmp2 = gen_vfp_mrs(); + tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); + tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + gen_vfp_msr(tmp); + break; + case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */ + tmp = tcg_temp_new_i32(); + if (dp) { + gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d, + cpu_env); + } else { + gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, + cpu_env); + } + tcg_gen_shli_i32(tmp, tmp, 16); + gen_mov_F0_vreg(0, rd); + tmp2 = gen_vfp_mrs(); + tcg_gen_ext16u_i32(tmp2, tmp2); + tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + gen_vfp_msr(tmp); + break; + case 8: /* cmp */ + gen_vfp_cmp(dp); + break; + case 9: /* cmpe */ + gen_vfp_cmpe(dp); + break; + case 10: /* cmpz */ + gen_vfp_cmp(dp); + break; + case 11: /* cmpez */ + gen_vfp_F1_ld0(dp); + gen_vfp_cmpe(dp); + break; + case 12: /* vrintr */ + { + TCGv_ptr fpst = get_fpstatus_ptr(0); + if (dp) { + gen_helper_rintd(cpu_F0d, cpu_F0d, fpst); + } else { + gen_helper_rints(cpu_F0s, cpu_F0s, fpst); + } + tcg_temp_free_ptr(fpst); + break; + } + case 13: /* vrintz */ + { + TCGv_ptr fpst = get_fpstatus_ptr(0); + TCGv_i32 tcg_rmode; + tcg_rmode = tcg_const_i32(float_round_to_zero); + gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + if (dp) { + gen_helper_rintd(cpu_F0d, cpu_F0d, fpst); + } else { + gen_helper_rints(cpu_F0s, cpu_F0s, fpst); + } + gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + tcg_temp_free_i32(tcg_rmode); + tcg_temp_free_ptr(fpst); + break; + } + case 14: /* vrintx */ + { + TCGv_ptr fpst = get_fpstatus_ptr(0); + if (dp) { + gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst); + } else { + gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst); + } + tcg_temp_free_ptr(fpst); + break; + } + case 15: /* single<->double conversion */ + if (dp) + gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); + else + gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); + break; + case 16: /* fuito */ + gen_vfp_uito(dp, 0); + break; + case 17: /* fsito */ + gen_vfp_sito(dp, 0); + break; + case 20: /* fshto */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_shto(dp, 16 - rm, 0); + break; + case 21: /* fslto */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_slto(dp, 32 - rm, 0); + break; + case 22: /* fuhto */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_uhto(dp, 16 - rm, 0); + break; + case 23: /* fulto */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_ulto(dp, 32 - rm, 0); + break; + case 24: /* ftoui */ + gen_vfp_toui(dp, 0); + break; + case 25: /* ftouiz */ + gen_vfp_touiz(dp, 0); + break; + case 26: /* ftosi */ + gen_vfp_tosi(dp, 0); + break; + case 27: /* ftosiz */ + gen_vfp_tosiz(dp, 0); + break; + case 28: /* ftosh */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_tosh(dp, 16 - rm, 0); + break; + case 29: /* ftosl */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_tosl(dp, 32 - rm, 0); + break; + case 30: /* ftouh */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_touh(dp, 16 - rm, 0); + break; + case 31: /* ftoul */ + if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { + return 1; + } + gen_vfp_toul(dp, 32 - rm, 0); + break; + default: /* undefined */ + return 1; + } + break; + default: /* undefined */ + return 1; + } + + /* Write back the result. */ + if (op == 15 && (rn >= 8 && rn <= 11)) { + /* Comparison, do nothing. */ + } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 || + (rn & 0x1e) == 0x6)) { + /* VCVT double to int: always integer result. + * VCVT double to half precision is always a single + * precision result. + */ + gen_mov_vreg_F0(0, rd); + } else if (op == 15 && rn == 15) { + /* conversion */ + gen_mov_vreg_F0(!dp, rd); + } else { + gen_mov_vreg_F0(dp, rd); + } + + /* break out of the loop if we have finished */ + if (veclen == 0) + break; + + if (op == 15 && delta_m == 0) { + /* single source one-many */ + while (veclen--) { + rd = ((rd + delta_d) & (bank_mask - 1)) + | (rd & bank_mask); + gen_mov_vreg_F0(dp, rd); + } + break; + } + /* Setup the next operands. */ + veclen--; + rd = ((rd + delta_d) & (bank_mask - 1)) + | (rd & bank_mask); + + if (op == 15) { + /* One source operand. */ + rm = ((rm + delta_m) & (bank_mask - 1)) + | (rm & bank_mask); + gen_mov_F0_vreg(dp, rm); + } else { + /* Two source operands. */ + rn = ((rn + delta_d) & (bank_mask - 1)) + | (rn & bank_mask); + gen_mov_F0_vreg(dp, rn); + if (delta_m) { + rm = ((rm + delta_m) & (bank_mask - 1)) + | (rm & bank_mask); + gen_mov_F1_vreg(dp, rm); + } + } + } + } + break; + case 0xc: + case 0xd: + if ((insn & 0x03e00000) == 0x00400000) { + /* two-register transfer */ + rn = (insn >> 16) & 0xf; + rd = (insn >> 12) & 0xf; + if (dp) { + VFP_DREG_M(rm, insn); + } else { + rm = VFP_SREG_M(insn); + } + + if (insn & ARM_CP_RW_BIT) { + /* vfp->arm */ + if (dp) { + gen_mov_F0_vreg(0, rm * 2); + tmp = gen_vfp_mrs(); + store_reg(s, rd, tmp); + gen_mov_F0_vreg(0, rm * 2 + 1); + tmp = gen_vfp_mrs(); + store_reg(s, rn, tmp); + } else { + gen_mov_F0_vreg(0, rm); + tmp = gen_vfp_mrs(); + store_reg(s, rd, tmp); + gen_mov_F0_vreg(0, rm + 1); + tmp = gen_vfp_mrs(); + store_reg(s, rn, tmp); + } + } else { + /* arm->vfp */ + if (dp) { + tmp = load_reg(s, rd); + gen_vfp_msr(tmp); + gen_mov_vreg_F0(0, rm * 2); + tmp = load_reg(s, rn); + gen_vfp_msr(tmp); + gen_mov_vreg_F0(0, rm * 2 + 1); + } else { + tmp = load_reg(s, rd); + gen_vfp_msr(tmp); + gen_mov_vreg_F0(0, rm); + tmp = load_reg(s, rn); + gen_vfp_msr(tmp); + gen_mov_vreg_F0(0, rm + 1); + } + } + } else { + /* Load/store */ + rn = (insn >> 16) & 0xf; + if (dp) + VFP_DREG_D(rd, insn); + else + rd = VFP_SREG_D(insn); + if ((insn & 0x01200000) == 0x01000000) { + /* Single load/store */ + offset = (insn & 0xff) << 2; + if ((insn & (1 << 23)) == 0) + offset = -offset; + if (s->thumb && rn == 15) { + /* This is actually UNPREDICTABLE */ + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~2); + } else { + addr = load_reg(s, rn); + } + tcg_gen_addi_i32(addr, addr, offset); + if (insn & (1 << 20)) { + gen_vfp_ld(s, dp, addr); + gen_mov_vreg_F0(dp, rd); + } else { + gen_mov_F0_vreg(dp, rd); + gen_vfp_st(s, dp, addr); + } + tcg_temp_free_i32(addr); + } else { + /* load/store multiple */ + int w = insn & (1 << 21); + if (dp) + n = (insn >> 1) & 0x7f; + else + n = insn & 0xff; + + if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) { + /* P == U , W == 1 => UNDEF */ + return 1; + } + if (n == 0 || (rd + n) > 32 || (dp && n > 16)) { + /* UNPREDICTABLE cases for bad immediates: we choose to + * UNDEF to avoid generating huge numbers of TCG ops + */ + return 1; + } + if (rn == 15 && w) { + /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */ + return 1; + } + + if (s->thumb && rn == 15) { + /* This is actually UNPREDICTABLE */ + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~2); + } else { + addr = load_reg(s, rn); + } + if (insn & (1 << 24)) /* pre-decrement */ + tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); + + if (dp) + offset = 8; + else + offset = 4; + for (i = 0; i < n; i++) { + if (insn & ARM_CP_RW_BIT) { + /* load */ + gen_vfp_ld(s, dp, addr); + gen_mov_vreg_F0(dp, rd + i); + } else { + /* store */ + gen_mov_F0_vreg(dp, rd + i); + gen_vfp_st(s, dp, addr); + } + tcg_gen_addi_i32(addr, addr, offset); + } + if (w) { + /* writeback */ + if (insn & (1 << 24)) + offset = -offset * n; + else if (dp && (insn & 1)) + offset = 4; + else + offset = 0; + + if (offset != 0) + tcg_gen_addi_i32(addr, addr, offset); + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + } + } + break; + default: + /* Should never happen. */ + return 1; + } + return 0; +} + +static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) +{ + TranslationBlock *tb; + + tb = s->tb; + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { + tcg_gen_goto_tb(n); + gen_set_pc_im(s, dest); + tcg_gen_exit_tb((uintptr_t)tb + n); + } else { + gen_set_pc_im(s, dest); + tcg_gen_exit_tb(0); + } +} + +static inline void gen_jmp (DisasContext *s, uint32_t dest) +{ + if (unlikely(s->singlestep_enabled || s->ss_active)) { + /* An indirect jump so that we still trigger the debug exception. */ + if (s->thumb) + dest |= 1; + gen_bx_im(s, dest); + } else { + gen_goto_tb(s, 0, dest); + s->is_jmp = DISAS_TB_JUMP; + } +} + +static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y) +{ + if (x) + tcg_gen_sari_i32(t0, t0, 16); + else + gen_sxth(t0); + if (y) + tcg_gen_sari_i32(t1, t1, 16); + else + gen_sxth(t1); + tcg_gen_mul_i32(t0, t0, t1); +} + +/* Return the mask of PSR bits set by a MSR instruction. */ +static uint32_t msr_mask(DisasContext *s, int flags, int spsr) +{ + uint32_t mask; + + mask = 0; + if (flags & (1 << 0)) + mask |= 0xff; + if (flags & (1 << 1)) + mask |= 0xff00; + if (flags & (1 << 2)) + mask |= 0xff0000; + if (flags & (1 << 3)) + mask |= 0xff000000; + + /* Mask out undefined bits. */ + mask &= ~CPSR_RESERVED; + if (!arm_dc_feature(s, ARM_FEATURE_V4T)) { + mask &= ~CPSR_T; + } + if (!arm_dc_feature(s, ARM_FEATURE_V5)) { + mask &= ~CPSR_Q; /* V5TE in reality*/ + } + if (!arm_dc_feature(s, ARM_FEATURE_V6)) { + mask &= ~(CPSR_E | CPSR_GE); + } + if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) { + mask &= ~CPSR_IT; + } + /* Mask out execution state and reserved bits. */ + if (!spsr) { + mask &= ~(CPSR_EXEC | CPSR_RESERVED); + } + /* Mask out privileged bits. */ + if (IS_USER(s)) + mask &= CPSR_USER; + return mask; +} + +/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */ +static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0) +{ + TCGv_i32 tmp; + if (spsr) { + /* ??? This is also undefined in system mode. */ + if (IS_USER(s)) + return 1; + + tmp = load_cpu_field(spsr); + tcg_gen_andi_i32(tmp, tmp, ~mask); + tcg_gen_andi_i32(t0, t0, mask); + tcg_gen_or_i32(tmp, tmp, t0); + store_cpu_field(tmp, spsr); + } else { + gen_set_cpsr(t0, mask); + } + tcg_temp_free_i32(t0); + gen_lookup_tb(s); + return 0; +} + +/* Returns nonzero if access to the PSR is not permitted. */ +static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val) +{ + TCGv_i32 tmp; + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + return gen_set_psr(s, mask, spsr, tmp); +} + +/* Generate an old-style exception return. Marks pc as dead. */ +static void gen_exception_return(DisasContext *s, TCGv_i32 pc) +{ + TCGv_i32 tmp; + store_reg(s, 15, pc); + tmp = load_cpu_field(spsr); + gen_set_cpsr(tmp, CPSR_ERET_MASK); + tcg_temp_free_i32(tmp); + s->is_jmp = DISAS_JUMP; +} + +/* Generate a v6 exception return. Marks both values as dead. */ +static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr) +{ + gen_set_cpsr(cpsr, CPSR_ERET_MASK); + tcg_temp_free_i32(cpsr); + store_reg(s, 15, pc); + s->is_jmp = DISAS_JUMP; +} + +static void gen_nop_hint(DisasContext *s, int val) +{ + switch (val) { + case 1: /* yield */ + gen_set_pc_im(s, s->pc); + s->is_jmp = DISAS_YIELD; + break; + case 3: /* wfi */ + gen_set_pc_im(s, s->pc); + s->is_jmp = DISAS_WFI; + break; + case 2: /* wfe */ + gen_set_pc_im(s, s->pc); + s->is_jmp = DISAS_WFE; + break; + case 4: /* sev */ + case 5: /* sevl */ + /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */ + default: /* nop */ + break; + } +} + +#define CPU_V001 cpu_V0, cpu_V0, cpu_V1 + +static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1) +{ + switch (size) { + case 0: gen_helper_neon_add_u8(t0, t0, t1); break; + case 1: gen_helper_neon_add_u16(t0, t0, t1); break; + case 2: tcg_gen_add_i32(t0, t0, t1); break; + default: abort(); + } +} + +static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1) +{ + switch (size) { + case 0: gen_helper_neon_sub_u8(t0, t1, t0); break; + case 1: gen_helper_neon_sub_u16(t0, t1, t0); break; + case 2: tcg_gen_sub_i32(t0, t1, t0); break; + default: return; + } +} + +/* 32-bit pairwise ops end up the same as the elementwise versions. */ +#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32 +#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32 +#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32 +#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32 + +#define GEN_NEON_INTEGER_OP_ENV(name) do { \ + switch ((size << 1) | u) { \ + case 0: \ + gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \ + break; \ + case 1: \ + gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \ + break; \ + case 2: \ + gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \ + break; \ + case 3: \ + gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \ + break; \ + case 4: \ + gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \ + break; \ + case 5: \ + gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \ + break; \ + default: return 1; \ + }} while (0) + +#define GEN_NEON_INTEGER_OP(name) do { \ + switch ((size << 1) | u) { \ + case 0: \ + gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \ + break; \ + case 1: \ + gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \ + break; \ + case 2: \ + gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \ + break; \ + case 3: \ + gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \ + break; \ + case 4: \ + gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \ + break; \ + case 5: \ + gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \ + break; \ + default: return 1; \ + }} while (0) + +static TCGv_i32 neon_load_scratch(int scratch) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); + return tmp; +} + +static void neon_store_scratch(int scratch, TCGv_i32 var) +{ + tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); + tcg_temp_free_i32(var); +} + +static inline TCGv_i32 neon_get_scalar(int size, int reg) +{ + TCGv_i32 tmp; + if (size == 1) { + tmp = neon_load_reg(reg & 7, reg >> 4); + if (reg & 8) { + gen_neon_dup_high16(tmp); + } else { + gen_neon_dup_low16(tmp); + } + } else { + tmp = neon_load_reg(reg & 15, reg >> 4); + } + return tmp; +} + +static int gen_neon_unzip(int rd, int rm, int size, int q) +{ + TCGv_i32 tmp, tmp2; + if (!q && size == 2) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + if (q) { + switch (size) { + case 0: + gen_helper_neon_qunzip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_qunzip16(cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qunzip32(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } else { + switch (size) { + case 0: + gen_helper_neon_unzip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_unzip16(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + return 0; +} + +static int gen_neon_zip(int rd, int rm, int size, int q) +{ + TCGv_i32 tmp, tmp2; + if (!q && size == 2) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + if (q) { + switch (size) { + case 0: + gen_helper_neon_qzip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_qzip16(cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qzip32(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } else { + switch (size) { + case 0: + gen_helper_neon_zip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_zip16(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + return 0; +} + +static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 rd, tmp; + + rd = tcg_temp_new_i32(); + tmp = tcg_temp_new_i32(); + + tcg_gen_shli_i32(rd, t0, 8); + tcg_gen_andi_i32(rd, rd, 0xff00ff00); + tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); + tcg_gen_or_i32(rd, rd, tmp); + + tcg_gen_shri_i32(t1, t1, 8); + tcg_gen_andi_i32(t1, t1, 0x00ff00ff); + tcg_gen_andi_i32(tmp, t0, 0xff00ff00); + tcg_gen_or_i32(t1, t1, tmp); + tcg_gen_mov_i32(t0, rd); + + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(rd); +} + +static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1) +{ + TCGv_i32 rd, tmp; + + rd = tcg_temp_new_i32(); + tmp = tcg_temp_new_i32(); + + tcg_gen_shli_i32(rd, t0, 16); + tcg_gen_andi_i32(tmp, t1, 0xffff); + tcg_gen_or_i32(rd, rd, tmp); + tcg_gen_shri_i32(t1, t1, 16); + tcg_gen_andi_i32(tmp, t0, 0xffff0000); + tcg_gen_or_i32(t1, t1, tmp); + tcg_gen_mov_i32(t0, rd); + + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(rd); +} + + +static struct { + int nregs; + int interleave; + int spacing; +} neon_ls_element_type[11] = { + {4, 4, 1}, + {4, 4, 2}, + {4, 1, 1}, + {4, 2, 1}, + {3, 3, 1}, + {3, 3, 2}, + {3, 1, 1}, + {1, 1, 1}, + {2, 2, 1}, + {2, 2, 2}, + {2, 1, 1} +}; + +/* Translate a NEON load/store element instruction. Return nonzero if the + instruction is invalid. */ +static int disas_neon_ls_insn(DisasContext *s, uint32_t insn) +{ + int rd, rn, rm; + int op; + int nregs; + int interleave; + int spacing; + int stride; + int size; + int reg; + int pass; + int load; + int shift; + int n; + TCGv_i32 addr; + TCGv_i32 tmp; + TCGv_i32 tmp2; + TCGv_i64 tmp64; + + /* FIXME: this access check should not take precedence over UNDEF + * for invalid encodings; we will generate incorrect syndrome information + * for attempts to execute invalid vfp/neon encodings with FP disabled. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el); + return 0; + } + + if (!s->vfp_enabled) + return 1; + VFP_DREG_D(rd, insn); + rn = (insn >> 16) & 0xf; + rm = insn & 0xf; + load = (insn & (1 << 21)) != 0; + if ((insn & (1 << 23)) == 0) { + /* Load store all elements. */ + op = (insn >> 8) & 0xf; + size = (insn >> 6) & 3; + if (op > 10) + return 1; + /* Catch UNDEF cases for bad values of align field */ + switch (op & 0xc) { + case 4: + if (((insn >> 5) & 1) == 1) { + return 1; + } + break; + case 8: + if (((insn >> 4) & 3) == 3) { + return 1; + } + break; + default: + break; + } + nregs = neon_ls_element_type[op].nregs; + interleave = neon_ls_element_type[op].interleave; + spacing = neon_ls_element_type[op].spacing; + if (size == 3 && (interleave | spacing) != 1) + return 1; + addr = tcg_temp_new_i32(); + load_reg_var(s, addr, rn); + stride = (1 << size) * interleave; + for (reg = 0; reg < nregs; reg++) { + if (interleave > 2 || (interleave == 2 && nregs == 2)) { + load_reg_var(s, addr, rn); + tcg_gen_addi_i32(addr, addr, (1 << size) * reg); + } else if (interleave == 2 && nregs == 4 && reg == 2) { + load_reg_var(s, addr, rn); + tcg_gen_addi_i32(addr, addr, 1 << size); + } + if (size == 3) { + tmp64 = tcg_temp_new_i64(); + if (load) { + gen_aa32_ld64(tmp64, addr, get_mem_index(s)); + neon_store_reg64(tmp64, rd); + } else { + neon_load_reg64(tmp64, rd); + gen_aa32_st64(tmp64, addr, get_mem_index(s)); + } + tcg_temp_free_i64(tmp64); + tcg_gen_addi_i32(addr, addr, stride); + } else { + for (pass = 0; pass < 2; pass++) { + if (size == 2) { + if (load) { + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + neon_store_reg(rd, pass, tmp); + } else { + tmp = neon_load_reg(rd, pass); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_gen_addi_i32(addr, addr, stride); + } else if (size == 1) { + if (load) { + tmp = tcg_temp_new_i32(); + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + tcg_gen_addi_i32(addr, addr, stride); + tmp2 = tcg_temp_new_i32(); + gen_aa32_ld16u(tmp2, addr, get_mem_index(s)); + tcg_gen_addi_i32(addr, addr, stride); + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + neon_store_reg(rd, pass, tmp); + } else { + tmp = neon_load_reg(rd, pass); + tmp2 = tcg_temp_new_i32(); + tcg_gen_shri_i32(tmp2, tmp, 16); + gen_aa32_st16(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + tcg_gen_addi_i32(addr, addr, stride); + gen_aa32_st16(tmp2, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp2); + tcg_gen_addi_i32(addr, addr, stride); + } + } else /* size == 0 */ { + if (load) { + TCGV_UNUSED_I32(tmp2); + for (n = 0; n < 4; n++) { + tmp = tcg_temp_new_i32(); + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + tcg_gen_addi_i32(addr, addr, stride); + if (n == 0) { + tmp2 = tmp; + } else { + tcg_gen_shli_i32(tmp, tmp, n * 8); + tcg_gen_or_i32(tmp2, tmp2, tmp); + tcg_temp_free_i32(tmp); + } + } + neon_store_reg(rd, pass, tmp2); + } else { + tmp2 = neon_load_reg(rd, pass); + for (n = 0; n < 4; n++) { + tmp = tcg_temp_new_i32(); + if (n == 0) { + tcg_gen_mov_i32(tmp, tmp2); + } else { + tcg_gen_shri_i32(tmp, tmp2, n * 8); + } + gen_aa32_st8(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + tcg_gen_addi_i32(addr, addr, stride); + } + tcg_temp_free_i32(tmp2); + } + } + } + } + rd += spacing; + } + tcg_temp_free_i32(addr); + stride = nregs * 8; + } else { + size = (insn >> 10) & 3; + if (size == 3) { + /* Load single element to all lanes. */ + int a = (insn >> 4) & 1; + if (!load) { + return 1; + } + size = (insn >> 6) & 3; + nregs = ((insn >> 8) & 3) + 1; + + if (size == 3) { + if (nregs != 4 || a == 0) { + return 1; + } + /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */ + size = 2; + } + if (nregs == 1 && a == 1 && size == 0) { + return 1; + } + if (nregs == 3 && a == 1) { + return 1; + } + addr = tcg_temp_new_i32(); + load_reg_var(s, addr, rn); + if (nregs == 1) { + /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */ + tmp = gen_load_and_replicate(s, addr, size); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); + if (insn & (1 << 5)) { + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0)); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1)); + } + tcg_temp_free_i32(tmp); + } else { + /* VLD2/3/4 to all lanes: bit 5 indicates register stride */ + stride = (insn & (1 << 5)) ? 2 : 1; + for (reg = 0; reg < nregs; reg++) { + tmp = gen_load_and_replicate(s, addr, size); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); + tcg_temp_free_i32(tmp); + tcg_gen_addi_i32(addr, addr, 1 << size); + rd += stride; + } + } + tcg_temp_free_i32(addr); + stride = (1 << size) * nregs; + } else { + /* Single element. */ + int idx = (insn >> 4) & 0xf; + pass = (insn >> 7) & 1; + switch (size) { + case 0: + shift = ((insn >> 5) & 3) * 8; + stride = 1; + break; + case 1: + shift = ((insn >> 6) & 1) * 16; + stride = (insn & (1 << 5)) ? 2 : 1; + break; + case 2: + shift = 0; + stride = (insn & (1 << 6)) ? 2 : 1; + break; + default: + abort(); + } + nregs = ((insn >> 8) & 3) + 1; + /* Catch the UNDEF cases. This is unavoidably a bit messy. */ + switch (nregs) { + case 1: + if (((idx & (1 << size)) != 0) || + (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) { + return 1; + } + break; + case 3: + if ((idx & 1) != 0) { + return 1; + } + /* fall through */ + case 2: + if (size == 2 && (idx & 2) != 0) { + return 1; + } + break; + case 4: + if ((size == 2) && ((idx & 3) == 3)) { + return 1; + } + break; + default: + abort(); + } + if ((rd + stride * (nregs - 1)) > 31) { + /* Attempts to write off the end of the register file + * are UNPREDICTABLE; we choose to UNDEF because otherwise + * the neon_load_reg() would write off the end of the array. + */ + return 1; + } + addr = tcg_temp_new_i32(); + load_reg_var(s, addr, rn); + for (reg = 0; reg < nregs; reg++) { + if (load) { + tmp = tcg_temp_new_i32(); + switch (size) { + case 0: + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + break; + case 1: + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + case 2: + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + default: /* Avoid compiler warnings. */ + abort(); + } + if (size != 2) { + tmp2 = neon_load_reg(rd, pass); + tcg_gen_deposit_i32(tmp, tmp2, tmp, + shift, size ? 16 : 8); + tcg_temp_free_i32(tmp2); + } + neon_store_reg(rd, pass, tmp); + } else { /* Store */ + tmp = neon_load_reg(rd, pass); + if (shift) + tcg_gen_shri_i32(tmp, tmp, shift); + switch (size) { + case 0: + gen_aa32_st8(tmp, addr, get_mem_index(s)); + break; + case 1: + gen_aa32_st16(tmp, addr, get_mem_index(s)); + break; + case 2: + gen_aa32_st32(tmp, addr, get_mem_index(s)); + break; + } + tcg_temp_free_i32(tmp); + } + rd += stride; + tcg_gen_addi_i32(addr, addr, 1 << size); + } + tcg_temp_free_i32(addr); + stride = nregs * (1 << size); + } + } + if (rm != 15) { + TCGv_i32 base; + + base = load_reg(s, rn); + if (rm == 13) { + tcg_gen_addi_i32(base, base, stride); + } else { + TCGv_i32 index; + index = load_reg(s, rm); + tcg_gen_add_i32(base, base, index); + tcg_temp_free_i32(index); + } + store_reg(s, rn, base); + } + return 0; +} + +/* Bitwise select. dest = c ? t : f. Clobbers T and F. */ +static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c) +{ + tcg_gen_and_i32(t, t, c); + tcg_gen_andc_i32(f, f, c); + tcg_gen_or_i32(dest, t, f); +} + +static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src) +{ + switch (size) { + case 0: gen_helper_neon_narrow_u8(dest, src); break; + case 1: gen_helper_neon_narrow_u16(dest, src); break; + case 2: tcg_gen_extrl_i64_i32(dest, src); break; + default: abort(); + } +} + +static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src) +{ + switch (size) { + case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break; + case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break; + case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break; + default: abort(); + } +} + +static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src) +{ + switch (size) { + case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break; + case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break; + case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break; + default: abort(); + } +} + +static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src) +{ + switch (size) { + case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break; + case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break; + case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break; + default: abort(); + } +} + +static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift, + int q, int u) +{ + if (q) { + if (u) { + switch (size) { + case 1: gen_helper_neon_rshl_u16(var, var, shift); break; + case 2: gen_helper_neon_rshl_u32(var, var, shift); break; + default: abort(); + } + } else { + switch (size) { + case 1: gen_helper_neon_rshl_s16(var, var, shift); break; + case 2: gen_helper_neon_rshl_s32(var, var, shift); break; + default: abort(); + } + } + } else { + if (u) { + switch (size) { + case 1: gen_helper_neon_shl_u16(var, var, shift); break; + case 2: gen_helper_neon_shl_u32(var, var, shift); break; + default: abort(); + } + } else { + switch (size) { + case 1: gen_helper_neon_shl_s16(var, var, shift); break; + case 2: gen_helper_neon_shl_s32(var, var, shift); break; + default: abort(); + } + } + } +} + +static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u) +{ + if (u) { + switch (size) { + case 0: gen_helper_neon_widen_u8(dest, src); break; + case 1: gen_helper_neon_widen_u16(dest, src); break; + case 2: tcg_gen_extu_i32_i64(dest, src); break; + default: abort(); + } + } else { + switch (size) { + case 0: gen_helper_neon_widen_s8(dest, src); break; + case 1: gen_helper_neon_widen_s16(dest, src); break; + case 2: tcg_gen_ext_i32_i64(dest, src); break; + default: abort(); + } + } + tcg_temp_free_i32(src); +} + +static inline void gen_neon_addl(int size) +{ + switch (size) { + case 0: gen_helper_neon_addl_u16(CPU_V001); break; + case 1: gen_helper_neon_addl_u32(CPU_V001); break; + case 2: tcg_gen_add_i64(CPU_V001); break; + default: abort(); + } +} + +static inline void gen_neon_subl(int size) +{ + switch (size) { + case 0: gen_helper_neon_subl_u16(CPU_V001); break; + case 1: gen_helper_neon_subl_u32(CPU_V001); break; + case 2: tcg_gen_sub_i64(CPU_V001); break; + default: abort(); + } +} + +static inline void gen_neon_negl(TCGv_i64 var, int size) +{ + switch (size) { + case 0: gen_helper_neon_negl_u16(var, var); break; + case 1: gen_helper_neon_negl_u32(var, var); break; + case 2: + tcg_gen_neg_i64(var, var); + break; + default: abort(); + } +} + +static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size) +{ + switch (size) { + case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break; + case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break; + default: abort(); + } +} + +static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b, + int size, int u) +{ + TCGv_i64 tmp; + + switch ((size << 1) | u) { + case 0: gen_helper_neon_mull_s8(dest, a, b); break; + case 1: gen_helper_neon_mull_u8(dest, a, b); break; + case 2: gen_helper_neon_mull_s16(dest, a, b); break; + case 3: gen_helper_neon_mull_u16(dest, a, b); break; + case 4: + tmp = gen_muls_i64_i32(a, b); + tcg_gen_mov_i64(dest, tmp); + tcg_temp_free_i64(tmp); + break; + case 5: + tmp = gen_mulu_i64_i32(a, b); + tcg_gen_mov_i64(dest, tmp); + tcg_temp_free_i64(tmp); + break; + default: abort(); + } + + /* gen_helper_neon_mull_[su]{8|16} do not free their parameters. + Don't forget to clean them now. */ + if (size < 2) { + tcg_temp_free_i32(a); + tcg_temp_free_i32(b); + } +} + +static void gen_neon_narrow_op(int op, int u, int size, + TCGv_i32 dest, TCGv_i64 src) +{ + if (op) { + if (u) { + gen_neon_unarrow_sats(size, dest, src); + } else { + gen_neon_narrow(size, dest, src); + } + } else { + if (u) { + gen_neon_narrow_satu(size, dest, src); + } else { + gen_neon_narrow_sats(size, dest, src); + } + } +} + +/* Symbolic constants for op fields for Neon 3-register same-length. + * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B + * table A7-9. + */ +#define NEON_3R_VHADD 0 +#define NEON_3R_VQADD 1 +#define NEON_3R_VRHADD 2 +#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */ +#define NEON_3R_VHSUB 4 +#define NEON_3R_VQSUB 5 +#define NEON_3R_VCGT 6 +#define NEON_3R_VCGE 7 +#define NEON_3R_VSHL 8 +#define NEON_3R_VQSHL 9 +#define NEON_3R_VRSHL 10 +#define NEON_3R_VQRSHL 11 +#define NEON_3R_VMAX 12 +#define NEON_3R_VMIN 13 +#define NEON_3R_VABD 14 +#define NEON_3R_VABA 15 +#define NEON_3R_VADD_VSUB 16 +#define NEON_3R_VTST_VCEQ 17 +#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */ +#define NEON_3R_VMUL 19 +#define NEON_3R_VPMAX 20 +#define NEON_3R_VPMIN 21 +#define NEON_3R_VQDMULH_VQRDMULH 22 +#define NEON_3R_VPADD 23 +#define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */ +#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */ +#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */ +#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */ +#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */ +#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */ +#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */ +#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */ + +static const uint8_t neon_3r_sizes[] = { + [NEON_3R_VHADD] = 0x7, + [NEON_3R_VQADD] = 0xf, + [NEON_3R_VRHADD] = 0x7, + [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */ + [NEON_3R_VHSUB] = 0x7, + [NEON_3R_VQSUB] = 0xf, + [NEON_3R_VCGT] = 0x7, + [NEON_3R_VCGE] = 0x7, + [NEON_3R_VSHL] = 0xf, + [NEON_3R_VQSHL] = 0xf, + [NEON_3R_VRSHL] = 0xf, + [NEON_3R_VQRSHL] = 0xf, + [NEON_3R_VMAX] = 0x7, + [NEON_3R_VMIN] = 0x7, + [NEON_3R_VABD] = 0x7, + [NEON_3R_VABA] = 0x7, + [NEON_3R_VADD_VSUB] = 0xf, + [NEON_3R_VTST_VCEQ] = 0x7, + [NEON_3R_VML] = 0x7, + [NEON_3R_VMUL] = 0x7, + [NEON_3R_VPMAX] = 0x7, + [NEON_3R_VPMIN] = 0x7, + [NEON_3R_VQDMULH_VQRDMULH] = 0x6, + [NEON_3R_VPADD] = 0x7, + [NEON_3R_SHA] = 0xf, /* size field encodes op type */ + [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */ +}; + +/* Symbolic constants for op fields for Neon 2-register miscellaneous. + * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B + * table A7-13. + */ +#define NEON_2RM_VREV64 0 +#define NEON_2RM_VREV32 1 +#define NEON_2RM_VREV16 2 +#define NEON_2RM_VPADDL 4 +#define NEON_2RM_VPADDL_U 5 +#define NEON_2RM_AESE 6 /* Includes AESD */ +#define NEON_2RM_AESMC 7 /* Includes AESIMC */ +#define NEON_2RM_VCLS 8 +#define NEON_2RM_VCLZ 9 +#define NEON_2RM_VCNT 10 +#define NEON_2RM_VMVN 11 +#define NEON_2RM_VPADAL 12 +#define NEON_2RM_VPADAL_U 13 +#define NEON_2RM_VQABS 14 +#define NEON_2RM_VQNEG 15 +#define NEON_2RM_VCGT0 16 +#define NEON_2RM_VCGE0 17 +#define NEON_2RM_VCEQ0 18 +#define NEON_2RM_VCLE0 19 +#define NEON_2RM_VCLT0 20 +#define NEON_2RM_SHA1H 21 +#define NEON_2RM_VABS 22 +#define NEON_2RM_VNEG 23 +#define NEON_2RM_VCGT0_F 24 +#define NEON_2RM_VCGE0_F 25 +#define NEON_2RM_VCEQ0_F 26 +#define NEON_2RM_VCLE0_F 27 +#define NEON_2RM_VCLT0_F 28 +#define NEON_2RM_VABS_F 30 +#define NEON_2RM_VNEG_F 31 +#define NEON_2RM_VSWP 32 +#define NEON_2RM_VTRN 33 +#define NEON_2RM_VUZP 34 +#define NEON_2RM_VZIP 35 +#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ +#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ +#define NEON_2RM_VSHLL 38 +#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */ +#define NEON_2RM_VRINTN 40 +#define NEON_2RM_VRINTX 41 +#define NEON_2RM_VRINTA 42 +#define NEON_2RM_VRINTZ 43 +#define NEON_2RM_VCVT_F16_F32 44 +#define NEON_2RM_VRINTM 45 +#define NEON_2RM_VCVT_F32_F16 46 +#define NEON_2RM_VRINTP 47 +#define NEON_2RM_VCVTAU 48 +#define NEON_2RM_VCVTAS 49 +#define NEON_2RM_VCVTNU 50 +#define NEON_2RM_VCVTNS 51 +#define NEON_2RM_VCVTPU 52 +#define NEON_2RM_VCVTPS 53 +#define NEON_2RM_VCVTMU 54 +#define NEON_2RM_VCVTMS 55 +#define NEON_2RM_VRECPE 56 +#define NEON_2RM_VRSQRTE 57 +#define NEON_2RM_VRECPE_F 58 +#define NEON_2RM_VRSQRTE_F 59 +#define NEON_2RM_VCVT_FS 60 +#define NEON_2RM_VCVT_FU 61 +#define NEON_2RM_VCVT_SF 62 +#define NEON_2RM_VCVT_UF 63 + +static int neon_2rm_is_float_op(int op) +{ + /* Return true if this neon 2reg-misc op is float-to-float */ + return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || + (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) || + op == NEON_2RM_VRINTM || + (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) || + op >= NEON_2RM_VRECPE_F); +} + +/* Each entry in this array has bit n set if the insn allows + * size value n (otherwise it will UNDEF). Since unallocated + * op values will have no bits set they always UNDEF. + */ +static const uint8_t neon_2rm_sizes[] = { + [NEON_2RM_VREV64] = 0x7, + [NEON_2RM_VREV32] = 0x3, + [NEON_2RM_VREV16] = 0x1, + [NEON_2RM_VPADDL] = 0x7, + [NEON_2RM_VPADDL_U] = 0x7, + [NEON_2RM_AESE] = 0x1, + [NEON_2RM_AESMC] = 0x1, + [NEON_2RM_VCLS] = 0x7, + [NEON_2RM_VCLZ] = 0x7, + [NEON_2RM_VCNT] = 0x1, + [NEON_2RM_VMVN] = 0x1, + [NEON_2RM_VPADAL] = 0x7, + [NEON_2RM_VPADAL_U] = 0x7, + [NEON_2RM_VQABS] = 0x7, + [NEON_2RM_VQNEG] = 0x7, + [NEON_2RM_VCGT0] = 0x7, + [NEON_2RM_VCGE0] = 0x7, + [NEON_2RM_VCEQ0] = 0x7, + [NEON_2RM_VCLE0] = 0x7, + [NEON_2RM_VCLT0] = 0x7, + [NEON_2RM_SHA1H] = 0x4, + [NEON_2RM_VABS] = 0x7, + [NEON_2RM_VNEG] = 0x7, + [NEON_2RM_VCGT0_F] = 0x4, + [NEON_2RM_VCGE0_F] = 0x4, + [NEON_2RM_VCEQ0_F] = 0x4, + [NEON_2RM_VCLE0_F] = 0x4, + [NEON_2RM_VCLT0_F] = 0x4, + [NEON_2RM_VABS_F] = 0x4, + [NEON_2RM_VNEG_F] = 0x4, + [NEON_2RM_VSWP] = 0x1, + [NEON_2RM_VTRN] = 0x7, + [NEON_2RM_VUZP] = 0x7, + [NEON_2RM_VZIP] = 0x7, + [NEON_2RM_VMOVN] = 0x7, + [NEON_2RM_VQMOVN] = 0x7, + [NEON_2RM_VSHLL] = 0x7, + [NEON_2RM_SHA1SU1] = 0x4, + [NEON_2RM_VRINTN] = 0x4, + [NEON_2RM_VRINTX] = 0x4, + [NEON_2RM_VRINTA] = 0x4, + [NEON_2RM_VRINTZ] = 0x4, + [NEON_2RM_VCVT_F16_F32] = 0x2, + [NEON_2RM_VRINTM] = 0x4, + [NEON_2RM_VCVT_F32_F16] = 0x2, + [NEON_2RM_VRINTP] = 0x4, + [NEON_2RM_VCVTAU] = 0x4, + [NEON_2RM_VCVTAS] = 0x4, + [NEON_2RM_VCVTNU] = 0x4, + [NEON_2RM_VCVTNS] = 0x4, + [NEON_2RM_VCVTPU] = 0x4, + [NEON_2RM_VCVTPS] = 0x4, + [NEON_2RM_VCVTMU] = 0x4, + [NEON_2RM_VCVTMS] = 0x4, + [NEON_2RM_VRECPE] = 0x4, + [NEON_2RM_VRSQRTE] = 0x4, + [NEON_2RM_VRECPE_F] = 0x4, + [NEON_2RM_VRSQRTE_F] = 0x4, + [NEON_2RM_VCVT_FS] = 0x4, + [NEON_2RM_VCVT_FU] = 0x4, + [NEON_2RM_VCVT_SF] = 0x4, + [NEON_2RM_VCVT_UF] = 0x4, +}; + +/* Translate a NEON data processing instruction. Return nonzero if the + instruction is invalid. + We process data in a mixture of 32-bit and 64-bit chunks. + Mostly we use 32-bit chunks so we can use normal scalar instructions. */ + +static int disas_neon_data_insn(DisasContext *s, uint32_t insn) +{ + int op; + int q; + int rd, rn, rm; + int size; + int shift; + int pass; + int count; + int pairwise; + int u; + uint32_t imm, mask; + TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5; + TCGv_i64 tmp64; + + /* FIXME: this access check should not take precedence over UNDEF + * for invalid encodings; we will generate incorrect syndrome information + * for attempts to execute invalid vfp/neon encodings with FP disabled. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el); + return 0; + } + + if (!s->vfp_enabled) + return 1; + q = (insn & (1 << 6)) != 0; + u = (insn >> 24) & 1; + VFP_DREG_D(rd, insn); + VFP_DREG_N(rn, insn); + VFP_DREG_M(rm, insn); + size = (insn >> 20) & 3; + if ((insn & (1 << 23)) == 0) { + /* Three register same length. */ + op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1); + /* Catch invalid op and bad size combinations: UNDEF */ + if ((neon_3r_sizes[op] & (1 << size)) == 0) { + return 1; + } + /* All insns of this form UNDEF for either this condition or the + * superset of cases "Q==1"; we catch the latter later. + */ + if (q && ((rd | rn | rm) & 1)) { + return 1; + } + /* + * The SHA-1/SHA-256 3-register instructions require special treatment + * here, as their size field is overloaded as an op type selector, and + * they all consume their input in a single pass. + */ + if (op == NEON_3R_SHA) { + if (!q) { + return 1; + } + if (!u) { /* SHA-1 */ + if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rn); + tmp3 = tcg_const_i32(rm); + tmp4 = tcg_const_i32(size); + gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4); + tcg_temp_free_i32(tmp4); + } else { /* SHA-256 */ + if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rn); + tmp3 = tcg_const_i32(rm); + switch (size) { + case 0: + gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3); + break; + case 1: + gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3); + break; + case 2: + gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3); + break; + } + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp3); + return 0; + } + if (size == 3 && op != NEON_3R_LOGIC) { + /* 64-bit element instructions. */ + for (pass = 0; pass < (q ? 2 : 1); pass++) { + neon_load_reg64(cpu_V0, rn + pass); + neon_load_reg64(cpu_V1, rm + pass); + switch (op) { + case NEON_3R_VQADD: + if (u) { + gen_helper_neon_qadd_u64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + } else { + gen_helper_neon_qadd_s64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + } + break; + case NEON_3R_VQSUB: + if (u) { + gen_helper_neon_qsub_u64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + } else { + gen_helper_neon_qsub_s64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + } + break; + case NEON_3R_VSHL: + if (u) { + gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0); + } else { + gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0); + } + break; + case NEON_3R_VQSHL: + if (u) { + gen_helper_neon_qshl_u64(cpu_V0, cpu_env, + cpu_V1, cpu_V0); + } else { + gen_helper_neon_qshl_s64(cpu_V0, cpu_env, + cpu_V1, cpu_V0); + } + break; + case NEON_3R_VRSHL: + if (u) { + gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0); + } else { + gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0); + } + break; + case NEON_3R_VQRSHL: + if (u) { + gen_helper_neon_qrshl_u64(cpu_V0, cpu_env, + cpu_V1, cpu_V0); + } else { + gen_helper_neon_qrshl_s64(cpu_V0, cpu_env, + cpu_V1, cpu_V0); + } + break; + case NEON_3R_VADD_VSUB: + if (u) { + tcg_gen_sub_i64(CPU_V001); + } else { + tcg_gen_add_i64(CPU_V001); + } + break; + default: + abort(); + } + neon_store_reg64(cpu_V0, rd + pass); + } + return 0; + } + pairwise = 0; + switch (op) { + case NEON_3R_VSHL: + case NEON_3R_VQSHL: + case NEON_3R_VRSHL: + case NEON_3R_VQRSHL: + { + int rtmp; + /* Shift instruction operands are reversed. */ + rtmp = rn; + rn = rm; + rm = rtmp; + } + break; + case NEON_3R_VPADD: + if (u) { + return 1; + } + /* Fall through */ + case NEON_3R_VPMAX: + case NEON_3R_VPMIN: + pairwise = 1; + break; + case NEON_3R_FLOAT_ARITH: + pairwise = (u && size < 2); /* if VPADD (float) */ + break; + case NEON_3R_FLOAT_MINMAX: + pairwise = u; /* if VPMIN/VPMAX (float) */ + break; + case NEON_3R_FLOAT_CMP: + if (!u && size) { + /* no encoding for U=0 C=1x */ + return 1; + } + break; + case NEON_3R_FLOAT_ACMP: + if (!u) { + return 1; + } + break; + case NEON_3R_FLOAT_MISC: + /* VMAXNM/VMINNM in ARMv8 */ + if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) { + return 1; + } + break; + case NEON_3R_VMUL: + if (u && (size != 0)) { + /* UNDEF on invalid size for polynomial subcase */ + return 1; + } + break; + case NEON_3R_VFM: + if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) { + return 1; + } + break; + default: + break; + } + + if (pairwise && q) { + /* All the pairwise insns UNDEF if Q is set */ + return 1; + } + + for (pass = 0; pass < (q ? 4 : 2); pass++) { + + if (pairwise) { + /* Pairwise. */ + if (pass < 1) { + tmp = neon_load_reg(rn, 0); + tmp2 = neon_load_reg(rn, 1); + } else { + tmp = neon_load_reg(rm, 0); + tmp2 = neon_load_reg(rm, 1); + } + } else { + /* Elementwise. */ + tmp = neon_load_reg(rn, pass); + tmp2 = neon_load_reg(rm, pass); + } + switch (op) { + case NEON_3R_VHADD: + GEN_NEON_INTEGER_OP(hadd); + break; + case NEON_3R_VQADD: + GEN_NEON_INTEGER_OP_ENV(qadd); + break; + case NEON_3R_VRHADD: + GEN_NEON_INTEGER_OP(rhadd); + break; + case NEON_3R_LOGIC: /* Logic ops. */ + switch ((u << 2) | size) { + case 0: /* VAND */ + tcg_gen_and_i32(tmp, tmp, tmp2); + break; + case 1: /* BIC */ + tcg_gen_andc_i32(tmp, tmp, tmp2); + break; + case 2: /* VORR */ + tcg_gen_or_i32(tmp, tmp, tmp2); + break; + case 3: /* VORN */ + tcg_gen_orc_i32(tmp, tmp, tmp2); + break; + case 4: /* VEOR */ + tcg_gen_xor_i32(tmp, tmp, tmp2); + break; + case 5: /* VBSL */ + tmp3 = neon_load_reg(rd, pass); + gen_neon_bsl(tmp, tmp, tmp2, tmp3); + tcg_temp_free_i32(tmp3); + break; + case 6: /* VBIT */ + tmp3 = neon_load_reg(rd, pass); + gen_neon_bsl(tmp, tmp, tmp3, tmp2); + tcg_temp_free_i32(tmp3); + break; + case 7: /* VBIF */ + tmp3 = neon_load_reg(rd, pass); + gen_neon_bsl(tmp, tmp3, tmp, tmp2); + tcg_temp_free_i32(tmp3); + break; + } + break; + case NEON_3R_VHSUB: + GEN_NEON_INTEGER_OP(hsub); + break; + case NEON_3R_VQSUB: + GEN_NEON_INTEGER_OP_ENV(qsub); + break; + case NEON_3R_VCGT: + GEN_NEON_INTEGER_OP(cgt); + break; + case NEON_3R_VCGE: + GEN_NEON_INTEGER_OP(cge); + break; + case NEON_3R_VSHL: + GEN_NEON_INTEGER_OP(shl); + break; + case NEON_3R_VQSHL: + GEN_NEON_INTEGER_OP_ENV(qshl); + break; + case NEON_3R_VRSHL: + GEN_NEON_INTEGER_OP(rshl); + break; + case NEON_3R_VQRSHL: + GEN_NEON_INTEGER_OP_ENV(qrshl); + break; + case NEON_3R_VMAX: + GEN_NEON_INTEGER_OP(max); + break; + case NEON_3R_VMIN: + GEN_NEON_INTEGER_OP(min); + break; + case NEON_3R_VABD: + GEN_NEON_INTEGER_OP(abd); + break; + case NEON_3R_VABA: + GEN_NEON_INTEGER_OP(abd); + tcg_temp_free_i32(tmp2); + tmp2 = neon_load_reg(rd, pass); + gen_neon_add(size, tmp, tmp2); + break; + case NEON_3R_VADD_VSUB: + if (!u) { /* VADD */ + gen_neon_add(size, tmp, tmp2); + } else { /* VSUB */ + switch (size) { + case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break; + case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break; + default: abort(); + } + } + break; + case NEON_3R_VTST_VCEQ: + if (!u) { /* VTST */ + switch (size) { + case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break; + case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break; + default: abort(); + } + } else { /* VCEQ */ + switch (size) { + case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; + case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; + default: abort(); + } + } + break; + case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */ + switch (size) { + case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; + case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; + default: abort(); + } + tcg_temp_free_i32(tmp2); + tmp2 = neon_load_reg(rd, pass); + if (u) { /* VMLS */ + gen_neon_rsb(size, tmp, tmp2); + } else { /* VMLA */ + gen_neon_add(size, tmp, tmp2); + } + break; + case NEON_3R_VMUL: + if (u) { /* polynomial */ + gen_helper_neon_mul_p8(tmp, tmp, tmp2); + } else { /* Integer */ + switch (size) { + case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; + case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; + default: abort(); + } + } + break; + case NEON_3R_VPMAX: + GEN_NEON_INTEGER_OP(pmax); + break; + case NEON_3R_VPMIN: + GEN_NEON_INTEGER_OP(pmin); + break; + case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */ + if (!u) { /* VQDMULH */ + switch (size) { + case 1: + gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); + break; + default: abort(); + } + } else { /* VQRDMULH */ + switch (size) { + case 1: + gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); + break; + default: abort(); + } + } + break; + case NEON_3R_VPADD: + switch (size) { + case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; + case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break; + default: abort(); + } + break; + case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */ + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + switch ((u << 2) | size) { + case 0: /* VADD */ + case 4: /* VPADD */ + gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); + break; + case 2: /* VSUB */ + gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus); + break; + case 6: /* VABD */ + gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus); + break; + default: + abort(); + } + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_3R_FLOAT_MULTIPLY: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus); + if (!u) { + tcg_temp_free_i32(tmp2); + tmp2 = neon_load_reg(rd, pass); + if (size == 0) { + gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus); + } + } + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_3R_FLOAT_CMP: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + if (!u) { + gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus); + } else { + if (size == 0) { + gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus); + } + } + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_3R_FLOAT_ACMP: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + if (size == 0) { + gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus); + } + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_3R_FLOAT_MINMAX: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + if (size == 0) { + gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus); + } + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_3R_FLOAT_MISC: + if (u) { + /* VMAXNM/VMINNM */ + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + if (size == 0) { + gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus); + } + tcg_temp_free_ptr(fpstatus); + } else { + if (size == 0) { + gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env); + } else { + gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env); + } + } + break; + case NEON_3R_VFM: + { + /* VFMA, VFMS: fused multiply-add */ + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + TCGv_i32 tmp3 = neon_load_reg(rd, pass); + if (size) { + /* VFMS */ + gen_helper_vfp_negs(tmp, tmp); + } + gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus); + tcg_temp_free_i32(tmp3); + tcg_temp_free_ptr(fpstatus); + break; + } + default: + abort(); + } + tcg_temp_free_i32(tmp2); + + /* Save the result. For elementwise operations we can put it + straight into the destination register. For pairwise operations + we have to be careful to avoid clobbering the source operands. */ + if (pairwise && rd == rm) { + neon_store_scratch(pass, tmp); + } else { + neon_store_reg(rd, pass, tmp); + } + + } /* for pass */ + if (pairwise && rd == rm) { + for (pass = 0; pass < (q ? 4 : 2); pass++) { + tmp = neon_load_scratch(pass); + neon_store_reg(rd, pass, tmp); + } + } + /* End of 3 register same size operations. */ + } else if (insn & (1 << 4)) { + if ((insn & 0x00380080) != 0) { + /* Two registers and shift. */ + op = (insn >> 8) & 0xf; + if (insn & (1 << 7)) { + /* 64-bit shift. */ + if (op > 7) { + return 1; + } + size = 3; + } else { + size = 2; + while ((insn & (1 << (size + 19))) == 0) + size--; + } + shift = (insn >> 16) & ((1 << (3 + size)) - 1); + /* To avoid excessive duplication of ops we implement shift + by immediate using the variable shift operations. */ + if (op < 8) { + /* Shift by immediate: + VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ + if (q && ((rd | rm) & 1)) { + return 1; + } + if (!u && (op == 4 || op == 6)) { + return 1; + } + /* Right shifts are encoded as N - shift, where N is the + element size in bits. */ + if (op <= 4) + shift = shift - (1 << (size + 3)); + if (size == 3) { + count = q + 1; + } else { + count = q ? 4: 2; + } + switch (size) { + case 0: + imm = (uint8_t) shift; + imm |= imm << 8; + imm |= imm << 16; + break; + case 1: + imm = (uint16_t) shift; + imm |= imm << 16; + break; + case 2: + case 3: + imm = shift; + break; + default: + abort(); + } + + for (pass = 0; pass < count; pass++) { + if (size == 3) { + neon_load_reg64(cpu_V0, rm + pass); + tcg_gen_movi_i64(cpu_V1, imm); + switch (op) { + case 0: /* VSHR */ + case 1: /* VSRA */ + if (u) + gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); + else + gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1); + break; + case 2: /* VRSHR */ + case 3: /* VRSRA */ + if (u) + gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1); + else + gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1); + break; + case 4: /* VSRI */ + case 5: /* VSHL, VSLI */ + gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); + break; + case 6: /* VQSHLU */ + gen_helper_neon_qshlu_s64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + break; + case 7: /* VQSHL */ + if (u) { + gen_helper_neon_qshl_u64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + } else { + gen_helper_neon_qshl_s64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); + } + break; + } + if (op == 1 || op == 3) { + /* Accumulate. */ + neon_load_reg64(cpu_V1, rd + pass); + tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1); + } else if (op == 4 || (op == 5 && u)) { + /* Insert */ + neon_load_reg64(cpu_V1, rd + pass); + uint64_t mask; + if (shift < -63 || shift > 63) { + mask = 0; + } else { + if (op == 4) { + mask = 0xffffffffffffffffull >> -shift; + } else { + mask = 0xffffffffffffffffull << shift; + } + } + tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask); + tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); + } + neon_store_reg64(cpu_V0, rd + pass); + } else { /* size < 3 */ + /* Operands in T0 and T1. */ + tmp = neon_load_reg(rm, pass); + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, imm); + switch (op) { + case 0: /* VSHR */ + case 1: /* VSRA */ + GEN_NEON_INTEGER_OP(shl); + break; + case 2: /* VRSHR */ + case 3: /* VRSRA */ + GEN_NEON_INTEGER_OP(rshl); + break; + case 4: /* VSRI */ + case 5: /* VSHL, VSLI */ + switch (size) { + case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break; + case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break; + default: abort(); + } + break; + case 6: /* VQSHLU */ + switch (size) { + case 0: + gen_helper_neon_qshlu_s8(tmp, cpu_env, + tmp, tmp2); + break; + case 1: + gen_helper_neon_qshlu_s16(tmp, cpu_env, + tmp, tmp2); + break; + case 2: + gen_helper_neon_qshlu_s32(tmp, cpu_env, + tmp, tmp2); + break; + default: + abort(); + } + break; + case 7: /* VQSHL */ + GEN_NEON_INTEGER_OP_ENV(qshl); + break; + } + tcg_temp_free_i32(tmp2); + + if (op == 1 || op == 3) { + /* Accumulate. */ + tmp2 = neon_load_reg(rd, pass); + gen_neon_add(size, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } else if (op == 4 || (op == 5 && u)) { + /* Insert */ + switch (size) { + case 0: + if (op == 4) + mask = 0xff >> -shift; + else + mask = (uint8_t)(0xff << shift); + mask |= mask << 8; + mask |= mask << 16; + break; + case 1: + if (op == 4) + mask = 0xffff >> -shift; + else + mask = (uint16_t)(0xffff << shift); + mask |= mask << 16; + break; + case 2: + if (shift < -31 || shift > 31) { + mask = 0; + } else { + if (op == 4) + mask = 0xffffffffu >> -shift; + else + mask = 0xffffffffu << shift; + } + break; + default: + abort(); + } + tmp2 = neon_load_reg(rd, pass); + tcg_gen_andi_i32(tmp, tmp, mask); + tcg_gen_andi_i32(tmp2, tmp2, ~mask); + tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + neon_store_reg(rd, pass, tmp); + } + } /* for pass */ + } else if (op < 10) { + /* Shift by immediate and narrow: + VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ + int input_unsigned = (op == 8) ? !u : u; + if (rm & 1) { + return 1; + } + shift = shift - (1 << (size + 3)); + size++; + if (size == 3) { + tmp64 = tcg_const_i64(shift); + neon_load_reg64(cpu_V0, rm); + neon_load_reg64(cpu_V1, rm + 1); + for (pass = 0; pass < 2; pass++) { + TCGv_i64 in; + if (pass == 0) { + in = cpu_V0; + } else { + in = cpu_V1; + } + if (q) { + if (input_unsigned) { + gen_helper_neon_rshl_u64(cpu_V0, in, tmp64); + } else { + gen_helper_neon_rshl_s64(cpu_V0, in, tmp64); + } + } else { + if (input_unsigned) { + gen_helper_neon_shl_u64(cpu_V0, in, tmp64); + } else { + gen_helper_neon_shl_s64(cpu_V0, in, tmp64); + } + } + tmp = tcg_temp_new_i32(); + gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); + neon_store_reg(rd, pass, tmp); + } /* for pass */ + tcg_temp_free_i64(tmp64); + } else { + if (size == 1) { + imm = (uint16_t)shift; + imm |= imm << 16; + } else { + /* size == 2 */ + imm = (uint32_t)shift; + } + tmp2 = tcg_const_i32(imm); + tmp4 = neon_load_reg(rm + 1, 0); + tmp5 = neon_load_reg(rm + 1, 1); + for (pass = 0; pass < 2; pass++) { + if (pass == 0) { + tmp = neon_load_reg(rm, 0); + } else { + tmp = tmp4; + } + gen_neon_shift_narrow(size, tmp, tmp2, q, + input_unsigned); + if (pass == 0) { + tmp3 = neon_load_reg(rm, 1); + } else { + tmp3 = tmp5; + } + gen_neon_shift_narrow(size, tmp3, tmp2, q, + input_unsigned); + tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp3); + tmp = tcg_temp_new_i32(); + gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); + neon_store_reg(rd, pass, tmp); + } /* for pass */ + tcg_temp_free_i32(tmp2); + } + } else if (op == 10) { + /* VSHLL, VMOVL */ + if (q || (rd & 1)) { + return 1; + } + tmp = neon_load_reg(rm, 0); + tmp2 = neon_load_reg(rm, 1); + for (pass = 0; pass < 2; pass++) { + if (pass == 1) + tmp = tmp2; + + gen_neon_widen(cpu_V0, tmp, size, u); + + if (shift != 0) { + /* The shift is less than the width of the source + type, so we can just shift the whole register. */ + tcg_gen_shli_i64(cpu_V0, cpu_V0, shift); + /* Widen the result of shift: we need to clear + * the potential overflow bits resulting from + * left bits of the narrow input appearing as + * right bits of left the neighbour narrow + * input. */ + if (size < 2 || !u) { + uint64_t imm64; + if (size == 0) { + imm = (0xffu >> (8 - shift)); + imm |= imm << 16; + } else if (size == 1) { + imm = 0xffff >> (16 - shift); + } else { + /* size == 2 */ + imm = 0xffffffff >> (32 - shift); + } + if (size < 2) { + imm64 = imm | (((uint64_t)imm) << 32); + } else { + imm64 = imm; + } + tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64); + } + } + neon_store_reg64(cpu_V0, rd + pass); + } + } else if (op >= 14) { + /* VCVT fixed-point. */ + if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { + return 1; + } + /* We have already masked out the must-be-1 top bit of imm6, + * hence this 32-shift where the ARM ARM has 64-imm6. + */ + shift = 32 - shift; + for (pass = 0; pass < (q ? 4 : 2); pass++) { + tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); + if (!(op & 1)) { + if (u) + gen_vfp_ulto(0, shift, 1); + else + gen_vfp_slto(0, shift, 1); + } else { + if (u) + gen_vfp_toul(0, shift, 1); + else + gen_vfp_tosl(0, shift, 1); + } + tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); + } + } else { + return 1; + } + } else { /* (insn & 0x00380080) == 0 */ + int invert; + if (q && (rd & 1)) { + return 1; + } + + op = (insn >> 8) & 0xf; + /* One register and immediate. */ + imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf); + invert = (insn & (1 << 5)) != 0; + /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. + * We choose to not special-case this and will behave as if a + * valid constant encoding of 0 had been given. + */ + switch (op) { + case 0: case 1: + /* no-op */ + break; + case 2: case 3: + imm <<= 8; + break; + case 4: case 5: + imm <<= 16; + break; + case 6: case 7: + imm <<= 24; + break; + case 8: case 9: + imm |= imm << 16; + break; + case 10: case 11: + imm = (imm << 8) | (imm << 24); + break; + case 12: + imm = (imm << 8) | 0xff; + break; + case 13: + imm = (imm << 16) | 0xffff; + break; + case 14: + imm |= (imm << 8) | (imm << 16) | (imm << 24); + if (invert) + imm = ~imm; + break; + case 15: + if (invert) { + return 1; + } + imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) + | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); + break; + } + if (invert) + imm = ~imm; + + for (pass = 0; pass < (q ? 4 : 2); pass++) { + if (op & 1 && op < 12) { + tmp = neon_load_reg(rd, pass); + if (invert) { + /* The immediate value has already been inverted, so + BIC becomes AND. */ + tcg_gen_andi_i32(tmp, tmp, imm); + } else { + tcg_gen_ori_i32(tmp, tmp, imm); + } + } else { + /* VMOV, VMVN. */ + tmp = tcg_temp_new_i32(); + if (op == 14 && invert) { + int n; + uint32_t val; + val = 0; + for (n = 0; n < 4; n++) { + if (imm & (1 << (n + (pass & 1) * 4))) + val |= 0xff << (n * 8); + } + tcg_gen_movi_i32(tmp, val); + } else { + tcg_gen_movi_i32(tmp, imm); + } + } + neon_store_reg(rd, pass, tmp); + } + } + } else { /* (insn & 0x00800010 == 0x00800000) */ + if (size != 3) { + op = (insn >> 8) & 0xf; + if ((insn & (1 << 6)) == 0) { + /* Three registers of different lengths. */ + int src1_wide; + int src2_wide; + int prewiden; + /* undefreq: bit 0 : UNDEF if size == 0 + * bit 1 : UNDEF if size == 1 + * bit 2 : UNDEF if size == 2 + * bit 3 : UNDEF if U == 1 + * Note that [2:0] set implies 'always UNDEF' + */ + int undefreq; + /* prewiden, src1_wide, src2_wide, undefreq */ + static const int neon_3reg_wide[16][4] = { + {1, 0, 0, 0}, /* VADDL */ + {1, 1, 0, 0}, /* VADDW */ + {1, 0, 0, 0}, /* VSUBL */ + {1, 1, 0, 0}, /* VSUBW */ + {0, 1, 1, 0}, /* VADDHN */ + {0, 0, 0, 0}, /* VABAL */ + {0, 1, 1, 0}, /* VSUBHN */ + {0, 0, 0, 0}, /* VABDL */ + {0, 0, 0, 0}, /* VMLAL */ + {0, 0, 0, 9}, /* VQDMLAL */ + {0, 0, 0, 0}, /* VMLSL */ + {0, 0, 0, 9}, /* VQDMLSL */ + {0, 0, 0, 0}, /* Integer VMULL */ + {0, 0, 0, 1}, /* VQDMULL */ + {0, 0, 0, 0xa}, /* Polynomial VMULL */ + {0, 0, 0, 7}, /* Reserved: always UNDEF */ + }; + + prewiden = neon_3reg_wide[op][0]; + src1_wide = neon_3reg_wide[op][1]; + src2_wide = neon_3reg_wide[op][2]; + undefreq = neon_3reg_wide[op][3]; + + if ((undefreq & (1 << size)) || + ((undefreq & 8) && u)) { + return 1; + } + if ((src1_wide && (rn & 1)) || + (src2_wide && (rm & 1)) || + (!src2_wide && (rd & 1))) { + return 1; + } + + /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply) + * outside the loop below as it only performs a single pass. + */ + if (op == 14 && size == 2) { + TCGv_i64 tcg_rn, tcg_rm, tcg_rd; + + if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) { + return 1; + } + tcg_rn = tcg_temp_new_i64(); + tcg_rm = tcg_temp_new_i64(); + tcg_rd = tcg_temp_new_i64(); + neon_load_reg64(tcg_rn, rn); + neon_load_reg64(tcg_rm, rm); + gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm); + neon_store_reg64(tcg_rd, rd); + gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm); + neon_store_reg64(tcg_rd, rd + 1); + tcg_temp_free_i64(tcg_rn); + tcg_temp_free_i64(tcg_rm); + tcg_temp_free_i64(tcg_rd); + return 0; + } + + /* Avoid overlapping operands. Wide source operands are + always aligned so will never overlap with wide + destinations in problematic ways. */ + if (rd == rm && !src2_wide) { + tmp = neon_load_reg(rm, 1); + neon_store_scratch(2, tmp); + } else if (rd == rn && !src1_wide) { + tmp = neon_load_reg(rn, 1); + neon_store_scratch(2, tmp); + } + TCGV_UNUSED_I32(tmp3); + for (pass = 0; pass < 2; pass++) { + if (src1_wide) { + neon_load_reg64(cpu_V0, rn + pass); + TCGV_UNUSED_I32(tmp); + } else { + if (pass == 1 && rd == rn) { + tmp = neon_load_scratch(2); + } else { + tmp = neon_load_reg(rn, pass); + } + if (prewiden) { + gen_neon_widen(cpu_V0, tmp, size, u); + } + } + if (src2_wide) { + neon_load_reg64(cpu_V1, rm + pass); + TCGV_UNUSED_I32(tmp2); + } else { + if (pass == 1 && rd == rm) { + tmp2 = neon_load_scratch(2); + } else { + tmp2 = neon_load_reg(rm, pass); + } + if (prewiden) { + gen_neon_widen(cpu_V1, tmp2, size, u); + } + } + switch (op) { + case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */ + gen_neon_addl(size); + break; + case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */ + gen_neon_subl(size); + break; + case 5: case 7: /* VABAL, VABDL */ + switch ((size << 1) | u) { + case 0: + gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2); + break; + case 1: + gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2); + break; + case 2: + gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2); + break; + case 3: + gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2); + break; + case 4: + gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2); + break; + case 5: + gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2); + break; + default: abort(); + } + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; + case 8: case 9: case 10: case 11: case 12: case 13: + /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */ + gen_neon_mull(cpu_V0, tmp, tmp2, size, u); + break; + case 14: /* Polynomial VMULL */ + gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; + default: /* 15 is RESERVED: caught earlier */ + abort(); + } + if (op == 13) { + /* VQDMULL */ + gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + neon_store_reg64(cpu_V0, rd + pass); + } else if (op == 5 || (op >= 8 && op <= 11)) { + /* Accumulate. */ + neon_load_reg64(cpu_V1, rd + pass); + switch (op) { + case 10: /* VMLSL */ + gen_neon_negl(cpu_V0, size); + /* Fall through */ + case 5: case 8: /* VABAL, VMLAL */ + gen_neon_addl(size); + break; + case 9: case 11: /* VQDMLAL, VQDMLSL */ + gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + if (op == 11) { + gen_neon_negl(cpu_V0, size); + } + gen_neon_addl_saturate(cpu_V0, cpu_V1, size); + break; + default: + abort(); + } + neon_store_reg64(cpu_V0, rd + pass); + } else if (op == 4 || op == 6) { + /* Narrowing operation. */ + tmp = tcg_temp_new_i32(); + if (!u) { + switch (size) { + case 0: + gen_helper_neon_narrow_high_u8(tmp, cpu_V0); + break; + case 1: + gen_helper_neon_narrow_high_u16(tmp, cpu_V0); + break; + case 2: + tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); + tcg_gen_extrl_i64_i32(tmp, cpu_V0); + break; + default: abort(); + } + } else { + switch (size) { + case 0: + gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0); + break; + case 1: + gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0); + break; + case 2: + tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31); + tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); + tcg_gen_extrl_i64_i32(tmp, cpu_V0); + break; + default: abort(); + } + } + if (pass == 0) { + tmp3 = tmp; + } else { + neon_store_reg(rd, 0, tmp3); + neon_store_reg(rd, 1, tmp); + } + } else { + /* Write back the result. */ + neon_store_reg64(cpu_V0, rd + pass); + } + } + } else { + /* Two registers and a scalar. NB that for ops of this form + * the ARM ARM labels bit 24 as Q, but it is in our variable + * 'u', not 'q'. + */ + if (size == 0) { + return 1; + } + switch (op) { + case 1: /* Float VMLA scalar */ + case 5: /* Floating point VMLS scalar */ + case 9: /* Floating point VMUL scalar */ + if (size == 1) { + return 1; + } + /* fall through */ + case 0: /* Integer VMLA scalar */ + case 4: /* Integer VMLS scalar */ + case 8: /* Integer VMUL scalar */ + case 12: /* VQDMULH scalar */ + case 13: /* VQRDMULH scalar */ + if (u && ((rd | rn) & 1)) { + return 1; + } + tmp = neon_get_scalar(size, rm); + neon_store_scratch(0, tmp); + for (pass = 0; pass < (u ? 4 : 2); pass++) { + tmp = neon_load_scratch(0); + tmp2 = neon_load_reg(rn, pass); + if (op == 12) { + if (size == 1) { + gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); + } else { + gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); + } + } else if (op == 13) { + if (size == 1) { + gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); + } else { + gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); + } + } else if (op & 1) { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_ptr(fpstatus); + } else { + switch (size) { + case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; + case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; + default: abort(); + } + } + tcg_temp_free_i32(tmp2); + if (op < 8) { + /* Accumulate. */ + tmp2 = neon_load_reg(rd, pass); + switch (op) { + case 0: + gen_neon_add(size, tmp, tmp2); + break; + case 1: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + case 4: + gen_neon_rsb(size, tmp, tmp2); + break; + case 5: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + default: + abort(); + } + tcg_temp_free_i32(tmp2); + } + neon_store_reg(rd, pass, tmp); + } + break; + case 3: /* VQDMLAL scalar */ + case 7: /* VQDMLSL scalar */ + case 11: /* VQDMULL scalar */ + if (u == 1) { + return 1; + } + /* fall through */ + case 2: /* VMLAL sclar */ + case 6: /* VMLSL scalar */ + case 10: /* VMULL scalar */ + if (rd & 1) { + return 1; + } + tmp2 = neon_get_scalar(size, rm); + /* We need a copy of tmp2 because gen_neon_mull + * deletes it during pass 0. */ + tmp4 = tcg_temp_new_i32(); + tcg_gen_mov_i32(tmp4, tmp2); + tmp3 = neon_load_reg(rn, 1); + + for (pass = 0; pass < 2; pass++) { + if (pass == 0) { + tmp = neon_load_reg(rn, 0); + } else { + tmp = tmp3; + tmp2 = tmp4; + } + gen_neon_mull(cpu_V0, tmp, tmp2, size, u); + if (op != 11) { + neon_load_reg64(cpu_V1, rd + pass); + } + switch (op) { + case 6: + gen_neon_negl(cpu_V0, size); + /* Fall through */ + case 2: + gen_neon_addl(size); + break; + case 3: case 7: + gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + if (op == 7) { + gen_neon_negl(cpu_V0, size); + } + gen_neon_addl_saturate(cpu_V0, cpu_V1, size); + break; + case 10: + /* no-op */ + break; + case 11: + gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + break; + default: + abort(); + } + neon_store_reg64(cpu_V0, rd + pass); + } + + + break; + default: /* 14 and 15 are RESERVED */ + return 1; + } + } + } else { /* size == 3 */ + if (!u) { + /* Extract. */ + imm = (insn >> 8) & 0xf; + + if (imm > 7 && !q) + return 1; + + if (q && ((rd | rn | rm) & 1)) { + return 1; + } + + if (imm == 0) { + neon_load_reg64(cpu_V0, rn); + if (q) { + neon_load_reg64(cpu_V1, rn + 1); + } + } else if (imm == 8) { + neon_load_reg64(cpu_V0, rn + 1); + if (q) { + neon_load_reg64(cpu_V1, rm); + } + } else if (q) { + tmp64 = tcg_temp_new_i64(); + if (imm < 8) { + neon_load_reg64(cpu_V0, rn); + neon_load_reg64(tmp64, rn + 1); + } else { + neon_load_reg64(cpu_V0, rn + 1); + neon_load_reg64(tmp64, rm); + } + tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8); + tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8)); + tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); + if (imm < 8) { + neon_load_reg64(cpu_V1, rm); + } else { + neon_load_reg64(cpu_V1, rm + 1); + imm -= 8; + } + tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); + tcg_gen_shri_i64(tmp64, tmp64, imm * 8); + tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64); + tcg_temp_free_i64(tmp64); + } else { + /* BUGFIX */ + neon_load_reg64(cpu_V0, rn); + tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8); + neon_load_reg64(cpu_V1, rm); + tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); + tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); + } + neon_store_reg64(cpu_V0, rd); + if (q) { + neon_store_reg64(cpu_V1, rd + 1); + } + } else if ((insn & (1 << 11)) == 0) { + /* Two register misc. */ + op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf); + size = (insn >> 18) & 3; + /* UNDEF for unknown op values and bad op-size combinations */ + if ((neon_2rm_sizes[op] & (1 << size)) == 0) { + return 1; + } + if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) && + q && ((rm | rd) & 1)) { + return 1; + } + switch (op) { + case NEON_2RM_VREV64: + for (pass = 0; pass < (q ? 2 : 1); pass++) { + tmp = neon_load_reg(rm, pass * 2); + tmp2 = neon_load_reg(rm, pass * 2 + 1); + switch (size) { + case 0: tcg_gen_bswap32_i32(tmp, tmp); break; + case 1: gen_swap_half(tmp); break; + case 2: /* no-op */ break; + default: abort(); + } + neon_store_reg(rd, pass * 2 + 1, tmp); + if (size == 2) { + neon_store_reg(rd, pass * 2, tmp2); + } else { + switch (size) { + case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break; + case 1: gen_swap_half(tmp2); break; + default: abort(); + } + neon_store_reg(rd, pass * 2, tmp2); + } + } + break; + case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U: + case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U: + for (pass = 0; pass < q + 1; pass++) { + tmp = neon_load_reg(rm, pass * 2); + gen_neon_widen(cpu_V0, tmp, size, op & 1); + tmp = neon_load_reg(rm, pass * 2 + 1); + gen_neon_widen(cpu_V1, tmp, size, op & 1); + switch (size) { + case 0: gen_helper_neon_paddl_u16(CPU_V001); break; + case 1: gen_helper_neon_paddl_u32(CPU_V001); break; + case 2: tcg_gen_add_i64(CPU_V001); break; + default: abort(); + } + if (op >= NEON_2RM_VPADAL) { + /* Accumulate. */ + neon_load_reg64(cpu_V1, rd + pass); + gen_neon_addl(size); + } + neon_store_reg64(cpu_V0, rd + pass); + } + break; + case NEON_2RM_VTRN: + if (size == 2) { + int n; + for (n = 0; n < (q ? 4 : 2); n += 2) { + tmp = neon_load_reg(rm, n); + tmp2 = neon_load_reg(rd, n + 1); + neon_store_reg(rm, n, tmp2); + neon_store_reg(rd, n + 1, tmp); + } + } else { + goto elementwise; + } + break; + case NEON_2RM_VUZP: + if (gen_neon_unzip(rd, rm, size, q)) { + return 1; + } + break; + case NEON_2RM_VZIP: + if (gen_neon_zip(rd, rm, size, q)) { + return 1; + } + break; + case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN: + /* also VQMOVUN; op field and mnemonics don't line up */ + if (rm & 1) { + return 1; + } + TCGV_UNUSED_I32(tmp2); + for (pass = 0; pass < 2; pass++) { + neon_load_reg64(cpu_V0, rm + pass); + tmp = tcg_temp_new_i32(); + gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size, + tmp, cpu_V0); + if (pass == 0) { + tmp2 = tmp; + } else { + neon_store_reg(rd, 0, tmp2); + neon_store_reg(rd, 1, tmp); + } + } + break; + case NEON_2RM_VSHLL: + if (q || (rd & 1)) { + return 1; + } + tmp = neon_load_reg(rm, 0); + tmp2 = neon_load_reg(rm, 1); + for (pass = 0; pass < 2; pass++) { + if (pass == 1) + tmp = tmp2; + gen_neon_widen(cpu_V0, tmp, size, 1); + tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size); + neon_store_reg64(cpu_V0, rd + pass); + } + break; + case NEON_2RM_VCVT_F16_F32: + if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) || + q || (rm & 1)) { + return 1; + } + tmp = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i32(); + tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0)); + gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); + tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1)); + gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_or_i32(tmp2, tmp2, tmp); + tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2)); + gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); + tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3)); + neon_store_reg(rd, 0, tmp2); + tmp2 = tcg_temp_new_i32(); + gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_or_i32(tmp2, tmp2, tmp); + neon_store_reg(rd, 1, tmp2); + tcg_temp_free_i32(tmp); + break; + case NEON_2RM_VCVT_F32_F16: + if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) || + q || (rd & 1)) { + return 1; + } + tmp3 = tcg_temp_new_i32(); + tmp = neon_load_reg(rm, 0); + tmp2 = neon_load_reg(rm, 1); + tcg_gen_ext16u_i32(tmp3, tmp); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0)); + tcg_gen_shri_i32(tmp3, tmp, 16); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1)); + tcg_temp_free_i32(tmp); + tcg_gen_ext16u_i32(tmp3, tmp2); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2)); + tcg_gen_shri_i32(tmp3, tmp2, 16); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3)); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp3); + break; + case NEON_2RM_AESE: case NEON_2RM_AESMC: + if (!arm_dc_feature(s, ARM_FEATURE_V8_AES) + || ((rm | rd) & 1)) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + + /* Bit 6 is the lowest opcode bit; it distinguishes between + * encryption (AESE/AESMC) and decryption (AESD/AESIMC) + */ + tmp3 = tcg_const_i32(extract32(insn, 6, 1)); + + if (op == NEON_2RM_AESE) { + gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3); + } else { + gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3); + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp3); + break; + case NEON_2RM_SHA1H: + if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1) + || ((rm | rd) & 1)) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + + gen_helper_crypto_sha1h(cpu_env, tmp, tmp2); + + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + break; + case NEON_2RM_SHA1SU1: + if ((rm | rd) & 1) { + return 1; + } + /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */ + if (q) { + if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) { + return 1; + } + } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + if (q) { + gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2); + } else { + gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2); + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + break; + default: + elementwise: + for (pass = 0; pass < (q ? 4 : 2); pass++) { + if (neon_2rm_is_float_op(op)) { + tcg_gen_ld_f32(cpu_F0s, cpu_env, + neon_reg_offset(rm, pass)); + TCGV_UNUSED_I32(tmp); + } else { + tmp = neon_load_reg(rm, pass); + } + switch (op) { + case NEON_2RM_VREV32: + switch (size) { + case 0: tcg_gen_bswap32_i32(tmp, tmp); break; + case 1: gen_swap_half(tmp); break; + default: abort(); + } + break; + case NEON_2RM_VREV16: + gen_rev16(tmp); + break; + case NEON_2RM_VCLS: + switch (size) { + case 0: gen_helper_neon_cls_s8(tmp, tmp); break; + case 1: gen_helper_neon_cls_s16(tmp, tmp); break; + case 2: gen_helper_neon_cls_s32(tmp, tmp); break; + default: abort(); + } + break; + case NEON_2RM_VCLZ: + switch (size) { + case 0: gen_helper_neon_clz_u8(tmp, tmp); break; + case 1: gen_helper_neon_clz_u16(tmp, tmp); break; + case 2: gen_helper_clz(tmp, tmp); break; + default: abort(); + } + break; + case NEON_2RM_VCNT: + gen_helper_neon_cnt_u8(tmp, tmp); + break; + case NEON_2RM_VMVN: + tcg_gen_not_i32(tmp, tmp); + break; + case NEON_2RM_VQABS: + switch (size) { + case 0: + gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); + break; + case 1: + gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); + break; + case 2: + gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); + break; + default: abort(); + } + break; + case NEON_2RM_VQNEG: + switch (size) { + case 0: + gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); + break; + case 1: + gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); + break; + case 2: + gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); + break; + default: abort(); + } + break; + case NEON_2RM_VCGT0: case NEON_2RM_VCLE0: + tmp2 = tcg_const_i32(0); + switch(size) { + case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break; + case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break; + default: abort(); + } + tcg_temp_free_i32(tmp2); + if (op == NEON_2RM_VCLE0) { + tcg_gen_not_i32(tmp, tmp); + } + break; + case NEON_2RM_VCGE0: case NEON_2RM_VCLT0: + tmp2 = tcg_const_i32(0); + switch(size) { + case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break; + case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break; + default: abort(); + } + tcg_temp_free_i32(tmp2); + if (op == NEON_2RM_VCLT0) { + tcg_gen_not_i32(tmp, tmp); + } + break; + case NEON_2RM_VCEQ0: + tmp2 = tcg_const_i32(0); + switch(size) { + case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; + case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; + case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; + default: abort(); + } + tcg_temp_free_i32(tmp2); + break; + case NEON_2RM_VABS: + switch(size) { + case 0: gen_helper_neon_abs_s8(tmp, tmp); break; + case 1: gen_helper_neon_abs_s16(tmp, tmp); break; + case 2: tcg_gen_abs_i32(tmp, tmp); break; + default: abort(); + } + break; + case NEON_2RM_VNEG: + tmp2 = tcg_const_i32(0); + gen_neon_rsb(size, tmp, tmp2); + tcg_temp_free_i32(tmp2); + break; + case NEON_2RM_VCGT0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_i32(tmp2); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCGE0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_i32(tmp2); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCEQ0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_i32(tmp2); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCLE0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus); + tcg_temp_free_i32(tmp2); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCLT0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus); + tcg_temp_free_i32(tmp2); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VABS_F: + gen_vfp_abs(0); + break; + case NEON_2RM_VNEG_F: + gen_vfp_neg(0); + break; + case NEON_2RM_VSWP: + tmp2 = neon_load_reg(rd, pass); + neon_store_reg(rm, pass, tmp2); + break; + case NEON_2RM_VTRN: + tmp2 = neon_load_reg(rd, pass); + switch (size) { + case 0: gen_neon_trn_u8(tmp, tmp2); break; + case 1: gen_neon_trn_u16(tmp, tmp2); break; + default: abort(); + } + neon_store_reg(rm, pass, tmp2); + break; + case NEON_2RM_VRINTN: + case NEON_2RM_VRINTA: + case NEON_2RM_VRINTM: + case NEON_2RM_VRINTP: + case NEON_2RM_VRINTZ: + { + TCGv_i32 tcg_rmode; + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + int rmode; + + if (op == NEON_2RM_VRINTZ) { + rmode = FPROUNDING_ZERO; + } else { + rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1]; + } + + tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); + gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); + gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus); + gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); + tcg_temp_free_ptr(fpstatus); + tcg_temp_free_i32(tcg_rmode); + break; + } + case NEON_2RM_VRINTX: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCVTAU: + case NEON_2RM_VCVTAS: + case NEON_2RM_VCVTNU: + case NEON_2RM_VCVTNS: + case NEON_2RM_VCVTPU: + case NEON_2RM_VCVTPS: + case NEON_2RM_VCVTMU: + case NEON_2RM_VCVTMS: + { + bool is_signed = !extract32(insn, 7, 1); + TCGv_ptr fpst = get_fpstatus_ptr(1); + TCGv_i32 tcg_rmode, tcg_shift; + int rmode = fp_decode_rm[extract32(insn, 8, 2)]; + + tcg_shift = tcg_const_i32(0); + tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); + gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); + + if (is_signed) { + gen_helper_vfp_tosls(cpu_F0s, cpu_F0s, + tcg_shift, fpst); + } else { + gen_helper_vfp_touls(cpu_F0s, cpu_F0s, + tcg_shift, fpst); + } + + gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); + tcg_temp_free_i32(tcg_rmode); + tcg_temp_free_i32(tcg_shift); + tcg_temp_free_ptr(fpst); + break; + } + case NEON_2RM_VRECPE: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_recpe_u32(tmp, tmp, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VRSQRTE: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_rsqrte_u32(tmp, tmp, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VRECPE_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VRSQRTE_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */ + gen_vfp_sito(0, 1); + break; + case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */ + gen_vfp_uito(0, 1); + break; + case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */ + gen_vfp_tosiz(0, 1); + break; + case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */ + gen_vfp_touiz(0, 1); + break; + default: + /* Reserved op values were caught by the + * neon_2rm_sizes[] check earlier. + */ + abort(); + } + if (neon_2rm_is_float_op(op)) { + tcg_gen_st_f32(cpu_F0s, cpu_env, + neon_reg_offset(rd, pass)); + } else { + neon_store_reg(rd, pass, tmp); + } + } + break; + } + } else if ((insn & (1 << 10)) == 0) { + /* VTBL, VTBX. */ + int n = ((insn >> 8) & 3) + 1; + if ((rn + n) > 32) { + /* This is UNPREDICTABLE; we choose to UNDEF to avoid the + * helper function running off the end of the register file. + */ + return 1; + } + n <<= 3; + if (insn & (1 << 6)) { + tmp = neon_load_reg(rd, 0); + } else { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } + tmp2 = neon_load_reg(rm, 0); + tmp4 = tcg_const_i32(rn); + tmp5 = tcg_const_i32(n); + gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5); + tcg_temp_free_i32(tmp); + if (insn & (1 << 6)) { + tmp = neon_load_reg(rd, 1); + } else { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } + tmp3 = neon_load_reg(rm, 1); + gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5); + tcg_temp_free_i32(tmp5); + tcg_temp_free_i32(tmp4); + neon_store_reg(rd, 0, tmp2); + neon_store_reg(rd, 1, tmp3); + tcg_temp_free_i32(tmp); + } else if ((insn & 0x380) == 0) { + /* VDUP */ + if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) { + return 1; + } + if (insn & (1 << 19)) { + tmp = neon_load_reg(rm, 1); + } else { + tmp = neon_load_reg(rm, 0); + } + if (insn & (1 << 16)) { + gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8); + } else if (insn & (1 << 17)) { + if ((insn >> 18) & 1) + gen_neon_dup_high16(tmp); + else + gen_neon_dup_low16(tmp); + } + for (pass = 0; pass < (q ? 4 : 2); pass++) { + tmp2 = tcg_temp_new_i32(); + tcg_gen_mov_i32(tmp2, tmp); + neon_store_reg(rd, pass, tmp2); + } + tcg_temp_free_i32(tmp); + } else { + return 1; + } + } + } + return 0; +} + +static int disas_coproc_insn(DisasContext *s, uint32_t insn) +{ + int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2; + const ARMCPRegInfo *ri; + + cpnum = (insn >> 8) & 0xf; + + /* First check for coprocessor space used for XScale/iwMMXt insns */ + if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) { + if (extract32(s->c15_cpar, cpnum, 1) == 0) { + return 1; + } + if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { + return disas_iwmmxt_insn(s, insn); + } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) { + return disas_dsp_insn(s, insn); + } + return 1; + } + + /* Otherwise treat as a generic register access */ + is64 = (insn & (1 << 25)) == 0; + if (!is64 && ((insn & (1 << 4)) == 0)) { + /* cdp */ + return 1; + } + + crm = insn & 0xf; + if (is64) { + crn = 0; + opc1 = (insn >> 4) & 0xf; + opc2 = 0; + rt2 = (insn >> 16) & 0xf; + } else { + crn = (insn >> 16) & 0xf; + opc1 = (insn >> 21) & 7; + opc2 = (insn >> 5) & 7; + rt2 = 0; + } + isread = (insn >> 20) & 1; + rt = (insn >> 12) & 0xf; + + ri = get_arm_cp_reginfo(s->cp_regs, + ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2)); + if (ri) { + /* Check access permissions */ + if (!cp_access_ok(s->current_el, ri, isread)) { + return 1; + } + + if (ri->accessfn || + (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) { + /* Emit code to perform further access permissions checks at + * runtime; this may result in an exception. + * Note that on XScale all cp0..c13 registers do an access check + * call in order to handle c15_cpar. + */ + TCGv_ptr tmpptr; + TCGv_i32 tcg_syn; + uint32_t syndrome; + + /* Note that since we are an implementation which takes an + * exception on a trapped conditional instruction only if the + * instruction passes its condition code check, we can take + * advantage of the clause in the ARM ARM that allows us to set + * the COND field in the instruction to 0xE in all cases. + * We could fish the actual condition out of the insn (ARM) + * or the condexec bits (Thumb) but it isn't necessary. + */ + switch (cpnum) { + case 14: + if (is64) { + syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2, + isread, s->thumb); + } else { + syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm, + rt, isread, s->thumb); + } + break; + case 15: + if (is64) { + syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2, + isread, s->thumb); + } else { + syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm, + rt, isread, s->thumb); + } + break; + default: + /* ARMv8 defines that only coprocessors 14 and 15 exist, + * so this can only happen if this is an ARMv7 or earlier CPU, + * in which case the syndrome information won't actually be + * guest visible. + */ + assert(!arm_dc_feature(s, ARM_FEATURE_V8)); + syndrome = syn_uncategorized(); + break; + } + + gen_set_condexec(s); + gen_set_pc_im(s, s->pc - 4); + tmpptr = tcg_const_ptr(ri); + tcg_syn = tcg_const_i32(syndrome); + gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn); + tcg_temp_free_ptr(tmpptr); + tcg_temp_free_i32(tcg_syn); + } + + /* Handle special cases first */ + switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) { + case ARM_CP_NOP: + return 0; + case ARM_CP_WFI: + if (isread) { + return 1; + } + gen_set_pc_im(s, s->pc); + s->is_jmp = DISAS_WFI; + return 0; + default: + break; + } + + if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) { + gen_io_start(); + } + + if (isread) { + /* Read */ + if (is64) { + TCGv_i64 tmp64; + TCGv_i32 tmp; + if (ri->type & ARM_CP_CONST) { + tmp64 = tcg_const_i64(ri->resetvalue); + } else if (ri->readfn) { + TCGv_ptr tmpptr; + tmp64 = tcg_temp_new_i64(); + tmpptr = tcg_const_ptr(ri); + gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr); + tcg_temp_free_ptr(tmpptr); + } else { + tmp64 = tcg_temp_new_i64(); + tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset); + } + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, tmp64); + store_reg(s, rt, tmp); + tcg_gen_shri_i64(tmp64, tmp64, 32); + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, tmp64); + tcg_temp_free_i64(tmp64); + store_reg(s, rt2, tmp); + } else { + TCGv_i32 tmp; + if (ri->type & ARM_CP_CONST) { + tmp = tcg_const_i32(ri->resetvalue); + } else if (ri->readfn) { + TCGv_ptr tmpptr; + tmp = tcg_temp_new_i32(); + tmpptr = tcg_const_ptr(ri); + gen_helper_get_cp_reg(tmp, cpu_env, tmpptr); + tcg_temp_free_ptr(tmpptr); + } else { + tmp = load_cpu_offset(ri->fieldoffset); + } + if (rt == 15) { + /* Destination register of r15 for 32 bit loads sets + * the condition codes from the high 4 bits of the value + */ + gen_set_nzcv(tmp); + tcg_temp_free_i32(tmp); + } else { + store_reg(s, rt, tmp); + } + } + } else { + /* Write */ + if (ri->type & ARM_CP_CONST) { + /* If not forbidden by access permissions, treat as WI */ + return 0; + } + + if (is64) { + TCGv_i32 tmplo, tmphi; + TCGv_i64 tmp64 = tcg_temp_new_i64(); + tmplo = load_reg(s, rt); + tmphi = load_reg(s, rt2); + tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi); + tcg_temp_free_i32(tmplo); + tcg_temp_free_i32(tmphi); + if (ri->writefn) { + TCGv_ptr tmpptr = tcg_const_ptr(ri); + gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64); + tcg_temp_free_ptr(tmpptr); + } else { + tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset); + } + tcg_temp_free_i64(tmp64); + } else { + if (ri->writefn) { + TCGv_i32 tmp; + TCGv_ptr tmpptr; + tmp = load_reg(s, rt); + tmpptr = tcg_const_ptr(ri); + gen_helper_set_cp_reg(cpu_env, tmpptr, tmp); + tcg_temp_free_ptr(tmpptr); + tcg_temp_free_i32(tmp); + } else { + TCGv_i32 tmp = load_reg(s, rt); + store_cpu_offset(tmp, ri->fieldoffset); + } + } + } + + if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) { + /* I/O operations must end the TB here (whether read or write) */ + gen_io_end(); + gen_lookup_tb(s); + } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) { + /* We default to ending the TB on a coprocessor register write, + * but allow this to be suppressed by the register definition + * (usually only necessary to work around guest bugs). + */ + gen_lookup_tb(s); + } + + return 0; + } + + /* Unknown register; this might be a guest error or a QEMU + * unimplemented feature. + */ + if (is64) { + qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 " + "64 bit system register cp:%d opc1: %d crm:%d " + "(%s)\n", + isread ? "read" : "write", cpnum, opc1, crm, + s->ns ? "non-secure" : "secure"); + } else { + qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 " + "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d " + "(%s)\n", + isread ? "read" : "write", cpnum, opc1, crn, crm, opc2, + s->ns ? "non-secure" : "secure"); + } + + return 1; +} + + +/* Store a 64-bit value to a register pair. Clobbers val. */ +static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val) +{ + TCGv_i32 tmp; + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, val); + store_reg(s, rlow, tmp); + tmp = tcg_temp_new_i32(); + tcg_gen_shri_i64(val, val, 32); + tcg_gen_extrl_i64_i32(tmp, val); + store_reg(s, rhigh, tmp); +} + +/* load a 32-bit value from a register and perform a 64-bit accumulate. */ +static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow) +{ + TCGv_i64 tmp; + TCGv_i32 tmp2; + + /* Load value and extend to 64 bits. */ + tmp = tcg_temp_new_i64(); + tmp2 = load_reg(s, rlow); + tcg_gen_extu_i32_i64(tmp, tmp2); + tcg_temp_free_i32(tmp2); + tcg_gen_add_i64(val, val, tmp); + tcg_temp_free_i64(tmp); +} + +/* load and add a 64-bit value from a register pair. */ +static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh) +{ + TCGv_i64 tmp; + TCGv_i32 tmpl; + TCGv_i32 tmph; + + /* Load 64-bit value rd:rn. */ + tmpl = load_reg(s, rlow); + tmph = load_reg(s, rhigh); + tmp = tcg_temp_new_i64(); + tcg_gen_concat_i32_i64(tmp, tmpl, tmph); + tcg_temp_free_i32(tmpl); + tcg_temp_free_i32(tmph); + tcg_gen_add_i64(val, val, tmp); + tcg_temp_free_i64(tmp); +} + +/* Set N and Z flags from hi|lo. */ +static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi) +{ + tcg_gen_mov_i32(cpu_NF, hi); + tcg_gen_or_i32(cpu_ZF, lo, hi); +} + +/* Load/Store exclusive instructions are implemented by remembering + the value/address loaded, and seeing if these are the same + when the store is performed. This should be sufficient to implement + the architecturally mandated semantics, and avoids having to monitor + regular stores. + + In system emulation mode only one CPU will be running at once, so + this sequence is effectively atomic. In user emulation mode we + throw an exception and handle the atomic operation elsewhere. */ +static void gen_load_exclusive(DisasContext *s, int rt, int rt2, + TCGv_i32 addr, int size) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + + s->is_ldex = true; + + switch (size) { + case 0: + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + break; + case 1: + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + case 2: + case 3: + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + + if (size == 3) { + TCGv_i32 tmp2 = tcg_temp_new_i32(); + TCGv_i32 tmp3 = tcg_temp_new_i32(); + + tcg_gen_addi_i32(tmp2, addr, 4); + gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s)); + tcg_temp_free_i32(tmp2); + tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3); + store_reg(s, rt2, tmp3); + } else { + tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp); + } + + store_reg(s, rt, tmp); + tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr); +} + +static void gen_clrex(DisasContext *s) +{ + tcg_gen_movi_i64(cpu_exclusive_addr, -1); +} + +#ifdef CONFIG_USER_ONLY +static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, + TCGv_i32 addr, int size) +{ + tcg_gen_extu_i32_i64(cpu_exclusive_test, addr); + tcg_gen_movi_i32(cpu_exclusive_info, + size | (rd << 4) | (rt << 8) | (rt2 << 12)); + gen_exception_internal_insn(s, 4, EXCP_STREX); +} +#else +static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, + TCGv_i32 addr, int size) +{ + TCGv_i32 tmp; + TCGv_i64 val64, extaddr; + TCGLabel *done_label; + TCGLabel *fail_label; + + /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) { + [addr] = {Rt}; + {Rd} = 0; + } else { + {Rd} = 1; + } */ + fail_label = gen_new_label(); + done_label = gen_new_label(); + extaddr = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(extaddr, addr); + tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label); + tcg_temp_free_i64(extaddr); + + tmp = tcg_temp_new_i32(); + switch (size) { + case 0: + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + break; + case 1: + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + case 2: + case 3: + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + + val64 = tcg_temp_new_i64(); + if (size == 3) { + TCGv_i32 tmp2 = tcg_temp_new_i32(); + TCGv_i32 tmp3 = tcg_temp_new_i32(); + tcg_gen_addi_i32(tmp2, addr, 4); + gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s)); + tcg_temp_free_i32(tmp2); + tcg_gen_concat_i32_i64(val64, tmp, tmp3); + tcg_temp_free_i32(tmp3); + } else { + tcg_gen_extu_i32_i64(val64, tmp); + } + tcg_temp_free_i32(tmp); + + tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label); + tcg_temp_free_i64(val64); + + tmp = load_reg(s, rt); + switch (size) { + case 0: + gen_aa32_st8(tmp, addr, get_mem_index(s)); + break; + case 1: + gen_aa32_st16(tmp, addr, get_mem_index(s)); + break; + case 2: + case 3: + gen_aa32_st32(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + tcg_temp_free_i32(tmp); + if (size == 3) { + tcg_gen_addi_i32(addr, addr, 4); + tmp = load_reg(s, rt2); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_gen_movi_i32(cpu_R[rd], 0); + tcg_gen_br(done_label); + gen_set_label(fail_label); + tcg_gen_movi_i32(cpu_R[rd], 1); + gen_set_label(done_label); + tcg_gen_movi_i64(cpu_exclusive_addr, -1); +} +#endif + +/* gen_srs: + * @env: CPUARMState + * @s: DisasContext + * @mode: mode field from insn (which stack to store to) + * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn + * @writeback: true if writeback bit set + * + * Generate code for the SRS (Store Return State) insn. + */ +static void gen_srs(DisasContext *s, + uint32_t mode, uint32_t amode, bool writeback) +{ + int32_t offset; + TCGv_i32 addr = tcg_temp_new_i32(); + TCGv_i32 tmp = tcg_const_i32(mode); + gen_helper_get_r13_banked(addr, cpu_env, tmp); + tcg_temp_free_i32(tmp); + switch (amode) { + case 0: /* DA */ + offset = -4; + break; + case 1: /* IA */ + offset = 0; + break; + case 2: /* DB */ + offset = -8; + break; + case 3: /* IB */ + offset = 4; + break; + default: + abort(); + } + tcg_gen_addi_i32(addr, addr, offset); + tmp = load_reg(s, 14); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + tmp = load_cpu_field(spsr); + tcg_gen_addi_i32(addr, addr, 4); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + if (writeback) { + switch (amode) { + case 0: + offset = -8; + break; + case 1: + offset = 4; + break; + case 2: + offset = -4; + break; + case 3: + offset = 0; + break; + default: + abort(); + } + tcg_gen_addi_i32(addr, addr, offset); + tmp = tcg_const_i32(mode); + gen_helper_set_r13_banked(cpu_env, tmp, addr); + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); +} + +static void disas_arm_insn(DisasContext *s, unsigned int insn) +{ + unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh; + TCGv_i32 tmp; + TCGv_i32 tmp2; + TCGv_i32 tmp3; + TCGv_i32 addr; + TCGv_i64 tmp64; + + /* M variants do not implement ARM mode. */ + if (arm_dc_feature(s, ARM_FEATURE_M)) { + goto illegal_op; + } + cond = insn >> 28; + if (cond == 0xf){ + /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we + * choose to UNDEF. In ARMv5 and above the space is used + * for miscellaneous unconditional instructions. + */ + ARCH(5); + + /* Unconditional instructions. */ + if (((insn >> 25) & 7) == 1) { + /* NEON Data processing. */ + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { + goto illegal_op; + } + + if (disas_neon_data_insn(s, insn)) { + goto illegal_op; + } + return; + } + if ((insn & 0x0f100000) == 0x04000000) { + /* NEON load/store. */ + if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { + goto illegal_op; + } + + if (disas_neon_ls_insn(s, insn)) { + goto illegal_op; + } + return; + } + if ((insn & 0x0f000e10) == 0x0e000a00) { + /* VFP. */ + if (disas_vfp_insn(s, insn)) { + goto illegal_op; + } + return; + } + if (((insn & 0x0f30f000) == 0x0510f000) || + ((insn & 0x0f30f010) == 0x0710f000)) { + if ((insn & (1 << 22)) == 0) { + /* PLDW; v7MP */ + if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) { + goto illegal_op; + } + } + /* Otherwise PLD; v5TE+ */ + ARCH(5TE); + return; + } + if (((insn & 0x0f70f000) == 0x0450f000) || + ((insn & 0x0f70f010) == 0x0650f000)) { + ARCH(7); + return; /* PLI; V7 */ + } + if (((insn & 0x0f700000) == 0x04100000) || + ((insn & 0x0f700010) == 0x06100000)) { + if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) { + goto illegal_op; + } + return; /* v7MP: Unallocated memory hint: must NOP */ + } + + if ((insn & 0x0ffffdff) == 0x01010000) { + ARCH(6); + /* setend */ + if (((insn >> 9) & 1) != s->bswap_code) { + /* Dynamic endianness switching not implemented. */ + qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n"); + goto illegal_op; + } + return; + } else if ((insn & 0x0fffff00) == 0x057ff000) { + switch ((insn >> 4) & 0xf) { + case 1: /* clrex */ + ARCH(6K); + gen_clrex(s); + return; + case 4: /* dsb */ + case 5: /* dmb */ + ARCH(7); + /* We don't emulate caches so these are a no-op. */ + return; + case 6: /* isb */ + /* We need to break the TB after this insn to execute + * self-modifying code correctly and also to take + * any pending interrupts immediately. + */ + gen_lookup_tb(s); + return; + default: + goto illegal_op; + } + } else if ((insn & 0x0e5fffe0) == 0x084d0500) { + /* srs */ + if (IS_USER(s)) { + goto illegal_op; + } + ARCH(6); + gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21)); + return; + } else if ((insn & 0x0e50ffe0) == 0x08100a00) { + /* rfe */ + int32_t offset; + if (IS_USER(s)) + goto illegal_op; + ARCH(6); + rn = (insn >> 16) & 0xf; + addr = load_reg(s, rn); + i = (insn >> 23) & 3; + switch (i) { + case 0: offset = -4; break; /* DA */ + case 1: offset = 0; break; /* IA */ + case 2: offset = -8; break; /* DB */ + case 3: offset = 4; break; /* IB */ + default: abort(); + } + if (offset) + tcg_gen_addi_i32(addr, addr, offset); + /* Load PC into tmp and CPSR into tmp2. */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + tcg_gen_addi_i32(addr, addr, 4); + tmp2 = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); + if (insn & (1 << 21)) { + /* Base writeback. */ + switch (i) { + case 0: offset = -8; break; + case 1: offset = 4; break; + case 2: offset = -4; break; + case 3: offset = 0; break; + default: abort(); + } + if (offset) + tcg_gen_addi_i32(addr, addr, offset); + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + gen_rfe(s, tmp, tmp2); + return; + } else if ((insn & 0x0e000000) == 0x0a000000) { + /* branch link and change to thumb (blx ) */ + int32_t offset; + + val = (uint32_t)s->pc; + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + store_reg(s, 14, tmp); + /* Sign-extend the 24-bit offset */ + offset = (((int32_t)insn) << 8) >> 8; + /* offset * 4 + bit24 * 2 + (thumb bit) */ + val += (offset << 2) | ((insn >> 23) & 2) | 1; + /* pipeline offset */ + val += 4; + /* protected by ARCH(5); above, near the start of uncond block */ + gen_bx_im(s, val); + return; + } else if ((insn & 0x0e000f00) == 0x0c000100) { + if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { + /* iWMMXt register transfer. */ + if (extract32(s->c15_cpar, 1, 1)) { + if (!disas_iwmmxt_insn(s, insn)) { + return; + } + } + } + } else if ((insn & 0x0fe00000) == 0x0c400000) { + /* Coprocessor double register transfer. */ + ARCH(5TE); + } else if ((insn & 0x0f000010) == 0x0e000010) { + /* Additional coprocessor register transfer. */ + } else if ((insn & 0x0ff10020) == 0x01000000) { + uint32_t mask; + uint32_t val; + /* cps (privileged) */ + if (IS_USER(s)) + return; + mask = val = 0; + if (insn & (1 << 19)) { + if (insn & (1 << 8)) + mask |= CPSR_A; + if (insn & (1 << 7)) + mask |= CPSR_I; + if (insn & (1 << 6)) + mask |= CPSR_F; + if (insn & (1 << 18)) + val |= mask; + } + if (insn & (1 << 17)) { + mask |= CPSR_M; + val |= (insn & 0x1f); + } + if (mask) { + gen_set_psr_im(s, mask, 0, val); + } + return; + } + goto illegal_op; + } + if (cond != 0xe) { + /* if not always execute, we generate a conditional jump to + next instruction */ + s->condlabel = gen_new_label(); + arm_gen_test_cc(cond ^ 1, s->condlabel); + s->condjmp = 1; + } + if ((insn & 0x0f900000) == 0x03000000) { + if ((insn & (1 << 21)) == 0) { + ARCH(6T2); + rd = (insn >> 12) & 0xf; + val = ((insn >> 4) & 0xf000) | (insn & 0xfff); + if ((insn & (1 << 22)) == 0) { + /* MOVW */ + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + } else { + /* MOVT */ + tmp = load_reg(s, rd); + tcg_gen_ext16u_i32(tmp, tmp); + tcg_gen_ori_i32(tmp, tmp, val << 16); + } + store_reg(s, rd, tmp); + } else { + if (((insn >> 12) & 0xf) != 0xf) + goto illegal_op; + if (((insn >> 16) & 0xf) == 0) { + gen_nop_hint(s, insn & 0xff); + } else { + /* CPSR = immediate */ + val = insn & 0xff; + shift = ((insn >> 8) & 0xf) * 2; + if (shift) + val = (val >> shift) | (val << (32 - shift)); + i = ((insn & (1 << 22)) != 0); + if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i), + i, val)) { + goto illegal_op; + } + } + } + } else if ((insn & 0x0f900000) == 0x01000000 + && (insn & 0x00000090) != 0x00000090) { + /* miscellaneous instructions */ + op1 = (insn >> 21) & 3; + sh = (insn >> 4) & 0xf; + rm = insn & 0xf; + switch (sh) { + case 0x0: /* move program status register */ + if (op1 & 1) { + /* PSR = reg */ + tmp = load_reg(s, rm); + i = ((op1 & 2) != 0); + if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp)) + goto illegal_op; + } else { + /* reg = PSR */ + rd = (insn >> 12) & 0xf; + if (op1 & 2) { + if (IS_USER(s)) + goto illegal_op; + tmp = load_cpu_field(spsr); + } else { + tmp = tcg_temp_new_i32(); + gen_helper_cpsr_read(tmp, cpu_env); + } + store_reg(s, rd, tmp); + } + break; + case 0x1: + if (op1 == 1) { + /* branch/exchange thumb (bx). */ + ARCH(4T); + tmp = load_reg(s, rm); + gen_bx(s, tmp); + } else if (op1 == 3) { + /* clz */ + ARCH(5); + rd = (insn >> 12) & 0xf; + tmp = load_reg(s, rm); + gen_helper_clz(tmp, tmp); + store_reg(s, rd, tmp); + } else { + goto illegal_op; + } + break; + case 0x2: + if (op1 == 1) { + ARCH(5J); /* bxj */ + /* Trivial implementation equivalent to bx. */ + tmp = load_reg(s, rm); + gen_bx(s, tmp); + } else { + goto illegal_op; + } + break; + case 0x3: + if (op1 != 1) + goto illegal_op; + + ARCH(5); + /* branch link/exchange thumb (blx) */ + tmp = load_reg(s, rm); + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, s->pc); + store_reg(s, 14, tmp2); + gen_bx(s, tmp); + break; + case 0x4: + { + /* crc32/crc32c */ + uint32_t c = extract32(insn, 8, 4); + + /* Check this CPU supports ARMv8 CRC instructions. + * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED. + * Bits 8, 10 and 11 should be zero. + */ + if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 || + (c & 0xd) != 0) { + goto illegal_op; + } + + rn = extract32(insn, 16, 4); + rd = extract32(insn, 12, 4); + + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + if (op1 == 0) { + tcg_gen_andi_i32(tmp2, tmp2, 0xff); + } else if (op1 == 1) { + tcg_gen_andi_i32(tmp2, tmp2, 0xffff); + } + tmp3 = tcg_const_i32(1 << op1); + if (c & 0x2) { + gen_helper_crc32c(tmp, tmp, tmp2, tmp3); + } else { + gen_helper_crc32(tmp, tmp, tmp2, tmp3); + } + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp3); + store_reg(s, rd, tmp); + break; + } + case 0x5: /* saturating add/subtract */ + ARCH(5TE); + rd = (insn >> 12) & 0xf; + rn = (insn >> 16) & 0xf; + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rn); + if (op1 & 2) + gen_helper_double_saturate(tmp2, cpu_env, tmp2); + if (op1 & 1) + gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2); + else + gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; + case 7: + { + int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4); + switch (op1) { + case 1: + /* bkpt */ + ARCH(5); + gen_exception_insn(s, 4, EXCP_BKPT, + syn_aa32_bkpt(imm16, false), + default_exception_el(s)); + break; + case 2: + /* Hypervisor call (v7) */ + ARCH(7); + if (IS_USER(s)) { + goto illegal_op; + } + gen_hvc(s, imm16); + break; + case 3: + /* Secure monitor call (v6+) */ + ARCH(6K); + if (IS_USER(s)) { + goto illegal_op; + } + gen_smc(s); + break; + default: + goto illegal_op; + } + break; + } + case 0x8: /* signed multiply */ + case 0xa: + case 0xc: + case 0xe: + ARCH(5TE); + rs = (insn >> 8) & 0xf; + rn = (insn >> 12) & 0xf; + rd = (insn >> 16) & 0xf; + if (op1 == 1) { + /* (32 * 16) >> 16 */ + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + if (sh & 4) + tcg_gen_sari_i32(tmp2, tmp2, 16); + else + gen_sxth(tmp2); + tmp64 = gen_muls_i64_i32(tmp, tmp2); + tcg_gen_shri_i64(tmp64, tmp64, 16); + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, tmp64); + tcg_temp_free_i64(tmp64); + if ((sh & 2) == 0) { + tmp2 = load_reg(s, rn); + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + store_reg(s, rd, tmp); + } else { + /* 16 * 16 */ + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + gen_mulxy(tmp, tmp2, sh & 2, sh & 4); + tcg_temp_free_i32(tmp2); + if (op1 == 2) { + tmp64 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp64, tmp); + tcg_temp_free_i32(tmp); + gen_addq(s, tmp64, rn, rd); + gen_storeq_reg(s, rn, rd, tmp64); + tcg_temp_free_i64(tmp64); + } else { + if (op1 == 0) { + tmp2 = load_reg(s, rn); + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + store_reg(s, rd, tmp); + } + } + break; + default: + goto illegal_op; + } + } else if (((insn & 0x0e000000) == 0 && + (insn & 0x00000090) != 0x90) || + ((insn & 0x0e000000) == (1 << 25))) { + int set_cc, logic_cc, shiftop; + + op1 = (insn >> 21) & 0xf; + set_cc = (insn >> 20) & 1; + logic_cc = table_logic_cc[op1] & set_cc; + + /* data processing instruction */ + if (insn & (1 << 25)) { + /* immediate operand */ + val = insn & 0xff; + shift = ((insn >> 8) & 0xf) * 2; + if (shift) { + val = (val >> shift) | (val << (32 - shift)); + } + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, val); + if (logic_cc && shift) { + gen_set_CF_bit31(tmp2); + } + } else { + /* register */ + rm = (insn) & 0xf; + tmp2 = load_reg(s, rm); + shiftop = (insn >> 5) & 3; + if (!(insn & (1 << 4))) { + shift = (insn >> 7) & 0x1f; + gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); + } else { + rs = (insn >> 8) & 0xf; + tmp = load_reg(s, rs); + gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); + } + } + if (op1 != 0x0f && op1 != 0x0d) { + rn = (insn >> 16) & 0xf; + tmp = load_reg(s, rn); + } else { + TCGV_UNUSED_I32(tmp); + } + rd = (insn >> 12) & 0xf; + switch(op1) { + case 0x00: + tcg_gen_and_i32(tmp, tmp, tmp2); + if (logic_cc) { + gen_logic_CC(tmp); + } + store_reg_bx(s, rd, tmp); + break; + case 0x01: + tcg_gen_xor_i32(tmp, tmp, tmp2); + if (logic_cc) { + gen_logic_CC(tmp); + } + store_reg_bx(s, rd, tmp); + break; + case 0x02: + if (set_cc && rd == 15) { + /* SUBS r15, ... is used for exception return. */ + if (IS_USER(s)) { + goto illegal_op; + } + gen_sub_CC(tmp, tmp, tmp2); + gen_exception_return(s, tmp); + } else { + if (set_cc) { + gen_sub_CC(tmp, tmp, tmp2); + } else { + tcg_gen_sub_i32(tmp, tmp, tmp2); + } + store_reg_bx(s, rd, tmp); + } + break; + case 0x03: + if (set_cc) { + gen_sub_CC(tmp, tmp2, tmp); + } else { + tcg_gen_sub_i32(tmp, tmp2, tmp); + } + store_reg_bx(s, rd, tmp); + break; + case 0x04: + if (set_cc) { + gen_add_CC(tmp, tmp, tmp2); + } else { + tcg_gen_add_i32(tmp, tmp, tmp2); + } + store_reg_bx(s, rd, tmp); + break; + case 0x05: + if (set_cc) { + gen_adc_CC(tmp, tmp, tmp2); + } else { + gen_add_carry(tmp, tmp, tmp2); + } + store_reg_bx(s, rd, tmp); + break; + case 0x06: + if (set_cc) { + gen_sbc_CC(tmp, tmp, tmp2); + } else { + gen_sub_carry(tmp, tmp, tmp2); + } + store_reg_bx(s, rd, tmp); + break; + case 0x07: + if (set_cc) { + gen_sbc_CC(tmp, tmp2, tmp); + } else { + gen_sub_carry(tmp, tmp2, tmp); + } + store_reg_bx(s, rd, tmp); + break; + case 0x08: + if (set_cc) { + tcg_gen_and_i32(tmp, tmp, tmp2); + gen_logic_CC(tmp); + } + tcg_temp_free_i32(tmp); + break; + case 0x09: + if (set_cc) { + tcg_gen_xor_i32(tmp, tmp, tmp2); + gen_logic_CC(tmp); + } + tcg_temp_free_i32(tmp); + break; + case 0x0a: + if (set_cc) { + gen_sub_CC(tmp, tmp, tmp2); + } + tcg_temp_free_i32(tmp); + break; + case 0x0b: + if (set_cc) { + gen_add_CC(tmp, tmp, tmp2); + } + tcg_temp_free_i32(tmp); + break; + case 0x0c: + tcg_gen_or_i32(tmp, tmp, tmp2); + if (logic_cc) { + gen_logic_CC(tmp); + } + store_reg_bx(s, rd, tmp); + break; + case 0x0d: + if (logic_cc && rd == 15) { + /* MOVS r15, ... is used for exception return. */ + if (IS_USER(s)) { + goto illegal_op; + } + gen_exception_return(s, tmp2); + } else { + if (logic_cc) { + gen_logic_CC(tmp2); + } + store_reg_bx(s, rd, tmp2); + } + break; + case 0x0e: + tcg_gen_andc_i32(tmp, tmp, tmp2); + if (logic_cc) { + gen_logic_CC(tmp); + } + store_reg_bx(s, rd, tmp); + break; + default: + case 0x0f: + tcg_gen_not_i32(tmp2, tmp2); + if (logic_cc) { + gen_logic_CC(tmp2); + } + store_reg_bx(s, rd, tmp2); + break; + } + if (op1 != 0x0f && op1 != 0x0d) { + tcg_temp_free_i32(tmp2); + } + } else { + /* other instructions */ + op1 = (insn >> 24) & 0xf; + switch(op1) { + case 0x0: + case 0x1: + /* multiplies, extra load/stores */ + sh = (insn >> 5) & 3; + if (sh == 0) { + if (op1 == 0x0) { + rd = (insn >> 16) & 0xf; + rn = (insn >> 12) & 0xf; + rs = (insn >> 8) & 0xf; + rm = (insn) & 0xf; + op1 = (insn >> 20) & 0xf; + switch (op1) { + case 0: case 1: case 2: case 3: case 6: + /* 32 bit mul */ + tmp = load_reg(s, rs); + tmp2 = load_reg(s, rm); + tcg_gen_mul_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + if (insn & (1 << 22)) { + /* Subtract (mls) */ + ARCH(6T2); + tmp2 = load_reg(s, rn); + tcg_gen_sub_i32(tmp, tmp2, tmp); + tcg_temp_free_i32(tmp2); + } else if (insn & (1 << 21)) { + /* Add */ + tmp2 = load_reg(s, rn); + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + if (insn & (1 << 20)) + gen_logic_CC(tmp); + store_reg(s, rd, tmp); + break; + case 4: + /* 64 bit mul double accumulate (UMAAL) */ + ARCH(6); + tmp = load_reg(s, rs); + tmp2 = load_reg(s, rm); + tmp64 = gen_mulu_i64_i32(tmp, tmp2); + gen_addq_lo(s, tmp64, rn); + gen_addq_lo(s, tmp64, rd); + gen_storeq_reg(s, rn, rd, tmp64); + tcg_temp_free_i64(tmp64); + break; + case 8: case 9: case 10: case 11: + case 12: case 13: case 14: case 15: + /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */ + tmp = load_reg(s, rs); + tmp2 = load_reg(s, rm); + if (insn & (1 << 22)) { + tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2); + } else { + tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2); + } + if (insn & (1 << 21)) { /* mult accumulate */ + TCGv_i32 al = load_reg(s, rn); + TCGv_i32 ah = load_reg(s, rd); + tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah); + tcg_temp_free_i32(al); + tcg_temp_free_i32(ah); + } + if (insn & (1 << 20)) { + gen_logicq_cc(tmp, tmp2); + } + store_reg(s, rn, tmp); + store_reg(s, rd, tmp2); + break; + default: + goto illegal_op; + } + } else { + rn = (insn >> 16) & 0xf; + rd = (insn >> 12) & 0xf; + if (insn & (1 << 23)) { + /* load/store exclusive */ + int op2 = (insn >> 8) & 3; + op1 = (insn >> 21) & 0x3; + + switch (op2) { + case 0: /* lda/stl */ + if (op1 == 1) { + goto illegal_op; + } + ARCH(8); + break; + case 1: /* reserved */ + goto illegal_op; + case 2: /* ldaex/stlex */ + ARCH(8); + break; + case 3: /* ldrex/strex */ + if (op1) { + ARCH(6K); + } else { + ARCH(6); + } + break; + } + + addr = tcg_temp_local_new_i32(); + load_reg_var(s, addr, rn); + + /* Since the emulation does not have barriers, + the acquire/release semantics need no special + handling */ + if (op2 == 0) { + if (insn & (1 << 20)) { + tmp = tcg_temp_new_i32(); + switch (op1) { + case 0: /* lda */ + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + case 2: /* ldab */ + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + break; + case 3: /* ldah */ + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + store_reg(s, rd, tmp); + } else { + rm = insn & 0xf; + tmp = load_reg(s, rm); + switch (op1) { + case 0: /* stl */ + gen_aa32_st32(tmp, addr, get_mem_index(s)); + break; + case 2: /* stlb */ + gen_aa32_st8(tmp, addr, get_mem_index(s)); + break; + case 3: /* stlh */ + gen_aa32_st16(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + tcg_temp_free_i32(tmp); + } + } else if (insn & (1 << 20)) { + switch (op1) { + case 0: /* ldrex */ + gen_load_exclusive(s, rd, 15, addr, 2); + break; + case 1: /* ldrexd */ + gen_load_exclusive(s, rd, rd + 1, addr, 3); + break; + case 2: /* ldrexb */ + gen_load_exclusive(s, rd, 15, addr, 0); + break; + case 3: /* ldrexh */ + gen_load_exclusive(s, rd, 15, addr, 1); + break; + default: + abort(); + } + } else { + rm = insn & 0xf; + switch (op1) { + case 0: /* strex */ + gen_store_exclusive(s, rd, rm, 15, addr, 2); + break; + case 1: /* strexd */ + gen_store_exclusive(s, rd, rm, rm + 1, addr, 3); + break; + case 2: /* strexb */ + gen_store_exclusive(s, rd, rm, 15, addr, 0); + break; + case 3: /* strexh */ + gen_store_exclusive(s, rd, rm, 15, addr, 1); + break; + default: + abort(); + } + } + tcg_temp_free_i32(addr); + } else { + /* SWP instruction */ + rm = (insn) & 0xf; + + /* ??? This is not really atomic. However we know + we never have multiple CPUs running in parallel, + so it is good enough. */ + addr = load_reg(s, rn); + tmp = load_reg(s, rm); + tmp2 = tcg_temp_new_i32(); + if (insn & (1 << 22)) { + gen_aa32_ld8u(tmp2, addr, get_mem_index(s)); + gen_aa32_st8(tmp, addr, get_mem_index(s)); + } else { + gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(addr); + store_reg(s, rd, tmp2); + } + } + } else { + int address_offset; + bool load = insn & (1 << 20); + bool doubleword = false; + /* Misc load/store */ + rn = (insn >> 16) & 0xf; + rd = (insn >> 12) & 0xf; + + if (!load && (sh & 2)) { + /* doubleword */ + ARCH(5TE); + if (rd & 1) { + /* UNPREDICTABLE; we choose to UNDEF */ + goto illegal_op; + } + load = (sh & 1) == 0; + doubleword = true; + } + + addr = load_reg(s, rn); + if (insn & (1 << 24)) + gen_add_datah_offset(s, insn, 0, addr); + address_offset = 0; + + if (doubleword) { + if (!load) { + /* store */ + tmp = load_reg(s, rd); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + tcg_gen_addi_i32(addr, addr, 4); + tmp = load_reg(s, rd + 1); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } else { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + store_reg(s, rd, tmp); + tcg_gen_addi_i32(addr, addr, 4); + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + rd++; + } + address_offset = -4; + } else if (load) { + /* load */ + tmp = tcg_temp_new_i32(); + switch (sh) { + case 1: + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + case 2: + gen_aa32_ld8s(tmp, addr, get_mem_index(s)); + break; + default: + case 3: + gen_aa32_ld16s(tmp, addr, get_mem_index(s)); + break; + } + } else { + /* store */ + tmp = load_reg(s, rd); + gen_aa32_st16(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + /* Perform base writeback before the loaded value to + ensure correct behavior with overlapping index registers. + ldrd with base writeback is undefined if the + destination and index registers overlap. */ + if (!(insn & (1 << 24))) { + gen_add_datah_offset(s, insn, address_offset, addr); + store_reg(s, rn, addr); + } else if (insn & (1 << 21)) { + if (address_offset) + tcg_gen_addi_i32(addr, addr, address_offset); + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + if (load) { + /* Complete the load. */ + store_reg(s, rd, tmp); + } + } + break; + case 0x4: + case 0x5: + goto do_ldst; + case 0x6: + case 0x7: + if (insn & (1 << 4)) { + ARCH(6); + /* Armv6 Media instructions. */ + rm = insn & 0xf; + rn = (insn >> 16) & 0xf; + rd = (insn >> 12) & 0xf; + rs = (insn >> 8) & 0xf; + switch ((insn >> 23) & 3) { + case 0: /* Parallel add/subtract. */ + op1 = (insn >> 20) & 7; + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + sh = (insn >> 5) & 7; + if ((op1 & 3) == 0 || sh == 5 || sh == 6) + goto illegal_op; + gen_arm_parallel_addsub(op1, sh, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; + case 1: + if ((insn & 0x00700020) == 0) { + /* Halfword pack. */ + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + shift = (insn >> 7) & 0x1f; + if (insn & (1 << 6)) { + /* pkhtb */ + if (shift == 0) + shift = 31; + tcg_gen_sari_i32(tmp2, tmp2, shift); + tcg_gen_andi_i32(tmp, tmp, 0xffff0000); + tcg_gen_ext16u_i32(tmp2, tmp2); + } else { + /* pkhbt */ + if (shift) + tcg_gen_shli_i32(tmp2, tmp2, shift); + tcg_gen_ext16u_i32(tmp, tmp); + tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); + } + tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else if ((insn & 0x00200020) == 0x00200000) { + /* [us]sat */ + tmp = load_reg(s, rm); + shift = (insn >> 7) & 0x1f; + if (insn & (1 << 6)) { + if (shift == 0) + shift = 31; + tcg_gen_sari_i32(tmp, tmp, shift); + } else { + tcg_gen_shli_i32(tmp, tmp, shift); + } + sh = (insn >> 16) & 0x1f; + tmp2 = tcg_const_i32(sh); + if (insn & (1 << 22)) + gen_helper_usat(tmp, cpu_env, tmp, tmp2); + else + gen_helper_ssat(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else if ((insn & 0x00300fe0) == 0x00200f20) { + /* [us]sat16 */ + tmp = load_reg(s, rm); + sh = (insn >> 16) & 0x1f; + tmp2 = tcg_const_i32(sh); + if (insn & (1 << 22)) + gen_helper_usat16(tmp, cpu_env, tmp, tmp2); + else + gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else if ((insn & 0x00700fe0) == 0x00000fa0) { + /* Select bytes. */ + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + tmp3 = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); + gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); + tcg_temp_free_i32(tmp3); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else if ((insn & 0x000003e0) == 0x00000060) { + tmp = load_reg(s, rm); + shift = (insn >> 10) & 3; + /* ??? In many cases it's not necessary to do a + rotate, a shift is sufficient. */ + if (shift != 0) + tcg_gen_rotri_i32(tmp, tmp, shift * 8); + op1 = (insn >> 20) & 7; + switch (op1) { + case 0: gen_sxtb16(tmp); break; + case 2: gen_sxtb(tmp); break; + case 3: gen_sxth(tmp); break; + case 4: gen_uxtb16(tmp); break; + case 6: gen_uxtb(tmp); break; + case 7: gen_uxth(tmp); break; + default: goto illegal_op; + } + if (rn != 15) { + tmp2 = load_reg(s, rn); + if ((op1 & 3) == 0) { + gen_add16(tmp, tmp2); + } else { + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + } + store_reg(s, rd, tmp); + } else if ((insn & 0x003f0f60) == 0x003f0f20) { + /* rev */ + tmp = load_reg(s, rm); + if (insn & (1 << 22)) { + if (insn & (1 << 7)) { + gen_revsh(tmp); + } else { + ARCH(6T2); + gen_helper_rbit(tmp, tmp); + } + } else { + if (insn & (1 << 7)) + gen_rev16(tmp); + else + tcg_gen_bswap32_i32(tmp, tmp); + } + store_reg(s, rd, tmp); + } else { + goto illegal_op; + } + break; + case 2: /* Multiplies (Type 3). */ + switch ((insn >> 20) & 0x7) { + case 5: + if (((insn >> 6) ^ (insn >> 7)) & 1) { + /* op2 not 00x or 11x : UNDEF */ + goto illegal_op; + } + /* Signed multiply most significant [accumulate]. + (SMMUL, SMMLA, SMMLS) */ + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + tmp64 = gen_muls_i64_i32(tmp, tmp2); + + if (rd != 15) { + tmp = load_reg(s, rd); + if (insn & (1 << 6)) { + tmp64 = gen_subq_msw(tmp64, tmp); + } else { + tmp64 = gen_addq_msw(tmp64, tmp); + } + } + if (insn & (1 << 5)) { + tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); + } + tcg_gen_shri_i64(tmp64, tmp64, 32); + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, tmp64); + tcg_temp_free_i64(tmp64); + store_reg(s, rn, tmp); + break; + case 0: + case 4: + /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */ + if (insn & (1 << 7)) { + goto illegal_op; + } + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + if (insn & (1 << 5)) + gen_swap_half(tmp2); + gen_smul_dual(tmp, tmp2); + if (insn & (1 << 22)) { + /* smlald, smlsld */ + TCGv_i64 tmp64_2; + + tmp64 = tcg_temp_new_i64(); + tmp64_2 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp64, tmp); + tcg_gen_ext_i32_i64(tmp64_2, tmp2); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + if (insn & (1 << 6)) { + tcg_gen_sub_i64(tmp64, tmp64, tmp64_2); + } else { + tcg_gen_add_i64(tmp64, tmp64, tmp64_2); + } + tcg_temp_free_i64(tmp64_2); + gen_addq(s, tmp64, rd, rn); + gen_storeq_reg(s, rd, rn, tmp64); + tcg_temp_free_i64(tmp64); + } else { + /* smuad, smusd, smlad, smlsd */ + if (insn & (1 << 6)) { + /* This subtraction cannot overflow. */ + tcg_gen_sub_i32(tmp, tmp, tmp2); + } else { + /* This addition cannot overflow 32 bits; + * however it may overflow considered as a + * signed operation, in which case we must set + * the Q flag. + */ + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); + if (rd != 15) + { + tmp2 = load_reg(s, rd); + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + store_reg(s, rn, tmp); + } + break; + case 1: + case 3: + /* SDIV, UDIV */ + if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) { + goto illegal_op; + } + if (((insn >> 5) & 7) || (rd != 15)) { + goto illegal_op; + } + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + if (insn & (1 << 21)) { + gen_helper_udiv(tmp, tmp, tmp2); + } else { + gen_helper_sdiv(tmp, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); + store_reg(s, rn, tmp); + break; + default: + goto illegal_op; + } + break; + case 3: + op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7); + switch (op1) { + case 0: /* Unsigned sum of absolute differences. */ + ARCH(6); + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + gen_helper_usad8(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + if (rd != 15) { + tmp2 = load_reg(s, rd); + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + store_reg(s, rn, tmp); + break; + case 0x20: case 0x24: case 0x28: case 0x2c: + /* Bitfield insert/clear. */ + ARCH(6T2); + shift = (insn >> 7) & 0x1f; + i = (insn >> 16) & 0x1f; + if (i < shift) { + /* UNPREDICTABLE; we choose to UNDEF */ + goto illegal_op; + } + i = i + 1 - shift; + if (rm == 15) { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } else { + tmp = load_reg(s, rm); + } + if (i != 32) { + tmp2 = load_reg(s, rd); + tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i); + tcg_temp_free_i32(tmp2); + } + store_reg(s, rd, tmp); + break; + case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ + case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ + ARCH(6T2); + tmp = load_reg(s, rm); + shift = (insn >> 7) & 0x1f; + i = ((insn >> 16) & 0x1f) + 1; + if (shift + i > 32) + goto illegal_op; + if (i < 32) { + if (op1 & 0x20) { + gen_ubfx(tmp, shift, (1u << i) - 1); + } else { + gen_sbfx(tmp, shift, i); + } + } + store_reg(s, rd, tmp); + break; + default: + goto illegal_op; + } + break; + } + break; + } + do_ldst: + /* Check for undefined extension instructions + * per the ARM Bible IE: + * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx + */ + sh = (0xf << 20) | (0xf << 4); + if (op1 == 0x7 && ((insn & sh) == sh)) + { + goto illegal_op; + } + /* load/store byte/word */ + rn = (insn >> 16) & 0xf; + rd = (insn >> 12) & 0xf; + tmp2 = load_reg(s, rn); + if ((insn & 0x01200000) == 0x00200000) { + /* ldrt/strt */ + i = get_a32_user_mem_index(s); + } else { + i = get_mem_index(s); + } + if (insn & (1 << 24)) + gen_add_data_offset(s, insn, tmp2); + if (insn & (1 << 20)) { + /* load */ + tmp = tcg_temp_new_i32(); + if (insn & (1 << 22)) { + gen_aa32_ld8u(tmp, tmp2, i); + } else { + gen_aa32_ld32u(tmp, tmp2, i); + } + } else { + /* store */ + tmp = load_reg(s, rd); + if (insn & (1 << 22)) { + gen_aa32_st8(tmp, tmp2, i); + } else { + gen_aa32_st32(tmp, tmp2, i); + } + tcg_temp_free_i32(tmp); + } + if (!(insn & (1 << 24))) { + gen_add_data_offset(s, insn, tmp2); + store_reg(s, rn, tmp2); + } else if (insn & (1 << 21)) { + store_reg(s, rn, tmp2); + } else { + tcg_temp_free_i32(tmp2); + } + if (insn & (1 << 20)) { + /* Complete the load. */ + store_reg_from_load(s, rd, tmp); + } + break; + case 0x08: + case 0x09: + { + int j, n, loaded_base; + bool exc_return = false; + bool is_load = extract32(insn, 20, 1); + bool user = false; + TCGv_i32 loaded_var; + /* load/store multiple words */ + /* XXX: store correct base if write back */ + if (insn & (1 << 22)) { + /* LDM (user), LDM (exception return) and STM (user) */ + if (IS_USER(s)) + goto illegal_op; /* only usable in supervisor mode */ + + if (is_load && extract32(insn, 15, 1)) { + exc_return = true; + } else { + user = true; + } + } + rn = (insn >> 16) & 0xf; + addr = load_reg(s, rn); + + /* compute total size */ + loaded_base = 0; + TCGV_UNUSED_I32(loaded_var); + n = 0; + for(i=0;i<16;i++) { + if (insn & (1 << i)) + n++; + } + /* XXX: test invalid n == 0 case ? */ + if (insn & (1 << 23)) { + if (insn & (1 << 24)) { + /* pre increment */ + tcg_gen_addi_i32(addr, addr, 4); + } else { + /* post increment */ + } + } else { + if (insn & (1 << 24)) { + /* pre decrement */ + tcg_gen_addi_i32(addr, addr, -(n * 4)); + } else { + /* post decrement */ + if (n != 1) + tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); + } + } + j = 0; + for(i=0;i<16;i++) { + if (insn & (1 << i)) { + if (is_load) { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + if (user) { + tmp2 = tcg_const_i32(i); + gen_helper_set_user_reg(cpu_env, tmp2, tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + } else if (i == rn) { + loaded_var = tmp; + loaded_base = 1; + } else { + store_reg_from_load(s, i, tmp); + } + } else { + /* store */ + if (i == 15) { + /* special case: r15 = PC + 8 */ + val = (long)s->pc + 4; + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + } else if (user) { + tmp = tcg_temp_new_i32(); + tmp2 = tcg_const_i32(i); + gen_helper_get_user_reg(tmp, cpu_env, tmp2); + tcg_temp_free_i32(tmp2); + } else { + tmp = load_reg(s, i); + } + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + j++; + /* no need to add after the last transfer */ + if (j != n) + tcg_gen_addi_i32(addr, addr, 4); + } + } + if (insn & (1 << 21)) { + /* write back */ + if (insn & (1 << 23)) { + if (insn & (1 << 24)) { + /* pre increment */ + } else { + /* post increment */ + tcg_gen_addi_i32(addr, addr, 4); + } + } else { + if (insn & (1 << 24)) { + /* pre decrement */ + if (n != 1) + tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); + } else { + /* post decrement */ + tcg_gen_addi_i32(addr, addr, -(n * 4)); + } + } + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + if (loaded_base) { + store_reg(s, rn, loaded_var); + } + if (exc_return) { + /* Restore CPSR from SPSR. */ + tmp = load_cpu_field(spsr); + gen_set_cpsr(tmp, CPSR_ERET_MASK); + tcg_temp_free_i32(tmp); + s->is_jmp = DISAS_JUMP; + } + } + break; + case 0xa: + case 0xb: + { + int32_t offset; + + /* branch (and link) */ + val = (int32_t)s->pc; + if (insn & (1 << 24)) { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + store_reg(s, 14, tmp); + } + offset = sextract32(insn << 2, 0, 26); + val += offset + 4; + gen_jmp(s, val); + } + break; + case 0xc: + case 0xd: + case 0xe: + if (((insn >> 8) & 0xe) == 10) { + /* VFP. */ + if (disas_vfp_insn(s, insn)) { + goto illegal_op; + } + } else if (disas_coproc_insn(s, insn)) { + /* Coprocessor. */ + goto illegal_op; + } + break; + case 0xf: + /* swi */ + gen_set_pc_im(s, s->pc); + s->svc_imm = extract32(insn, 0, 24); + s->is_jmp = DISAS_SWI; + break; + default: + illegal_op: + gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); + break; + } + } +} + +/* Return true if this is a Thumb-2 logical op. */ +static int +thumb2_logic_op(int op) +{ + return (op < 8); +} + +/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero + then set condition code flags based on the result of the operation. + If SHIFTER_OUT is nonzero then set the carry flag for logical operations + to the high bit of T1. + Returns zero if the opcode is valid. */ + +static int +gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, + TCGv_i32 t0, TCGv_i32 t1) +{ + int logic_cc; + + logic_cc = 0; + switch (op) { + case 0: /* and */ + tcg_gen_and_i32(t0, t0, t1); + logic_cc = conds; + break; + case 1: /* bic */ + tcg_gen_andc_i32(t0, t0, t1); + logic_cc = conds; + break; + case 2: /* orr */ + tcg_gen_or_i32(t0, t0, t1); + logic_cc = conds; + break; + case 3: /* orn */ + tcg_gen_orc_i32(t0, t0, t1); + logic_cc = conds; + break; + case 4: /* eor */ + tcg_gen_xor_i32(t0, t0, t1); + logic_cc = conds; + break; + case 8: /* add */ + if (conds) + gen_add_CC(t0, t0, t1); + else + tcg_gen_add_i32(t0, t0, t1); + break; + case 10: /* adc */ + if (conds) + gen_adc_CC(t0, t0, t1); + else + gen_adc(t0, t1); + break; + case 11: /* sbc */ + if (conds) { + gen_sbc_CC(t0, t0, t1); + } else { + gen_sub_carry(t0, t0, t1); + } + break; + case 13: /* sub */ + if (conds) + gen_sub_CC(t0, t0, t1); + else + tcg_gen_sub_i32(t0, t0, t1); + break; + case 14: /* rsb */ + if (conds) + gen_sub_CC(t0, t1, t0); + else + tcg_gen_sub_i32(t0, t1, t0); + break; + default: /* 5, 6, 7, 9, 12, 15. */ + return 1; + } + if (logic_cc) { + gen_logic_CC(t0); + if (shifter_out) + gen_set_CF_bit31(t1); + } + return 0; +} + +/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction + is not legal. */ +static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1) +{ + uint32_t insn, imm, shift, offset; + uint32_t rd, rn, rm, rs; + TCGv_i32 tmp; + TCGv_i32 tmp2; + TCGv_i32 tmp3; + TCGv_i32 addr; + TCGv_i64 tmp64; + int op; + int shiftop; + int conds; + int logic_cc; + + if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2) + || arm_dc_feature(s, ARM_FEATURE_M))) { + /* Thumb-1 cores may need to treat bl and blx as a pair of + 16-bit instructions to get correct prefetch abort behavior. */ + insn = insn_hw1; + if ((insn & (1 << 12)) == 0) { + ARCH(5); + /* Second half of blx. */ + offset = ((insn & 0x7ff) << 1); + tmp = load_reg(s, 14); + tcg_gen_addi_i32(tmp, tmp, offset); + tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); + + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, s->pc | 1); + store_reg(s, 14, tmp2); + gen_bx(s, tmp); + return 0; + } + if (insn & (1 << 11)) { + /* Second half of bl. */ + offset = ((insn & 0x7ff) << 1) | 1; + tmp = load_reg(s, 14); + tcg_gen_addi_i32(tmp, tmp, offset); + + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, s->pc | 1); + store_reg(s, 14, tmp2); + gen_bx(s, tmp); + return 0; + } + if ((s->pc & ~TARGET_PAGE_MASK) == 0) { + /* Instruction spans a page boundary. Implement it as two + 16-bit instructions in case the second half causes an + prefetch abort. */ + offset = ((int32_t)insn << 21) >> 9; + tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset); + return 0; + } + /* Fall through to 32-bit decode. */ + } + + insn = arm_lduw_code(env, s->pc, s->bswap_code); + s->pc += 2; + insn |= (uint32_t)insn_hw1 << 16; + + if ((insn & 0xf800e800) != 0xf000e800) { + ARCH(6T2); + } + + rn = (insn >> 16) & 0xf; + rs = (insn >> 12) & 0xf; + rd = (insn >> 8) & 0xf; + rm = insn & 0xf; + switch ((insn >> 25) & 0xf) { + case 0: case 1: case 2: case 3: + /* 16-bit instructions. Should never happen. */ + abort(); + case 4: + if (insn & (1 << 22)) { + /* Other load/store, table branch. */ + if (insn & 0x01200000) { + /* Load/store doubleword. */ + if (rn == 15) { + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~3); + } else { + addr = load_reg(s, rn); + } + offset = (insn & 0xff) * 4; + if ((insn & (1 << 23)) == 0) + offset = -offset; + if (insn & (1 << 24)) { + tcg_gen_addi_i32(addr, addr, offset); + offset = 0; + } + if (insn & (1 << 20)) { + /* ldrd */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + store_reg(s, rs, tmp); + tcg_gen_addi_i32(addr, addr, 4); + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + store_reg(s, rd, tmp); + } else { + /* strd */ + tmp = load_reg(s, rs); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + tcg_gen_addi_i32(addr, addr, 4); + tmp = load_reg(s, rd); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + if (insn & (1 << 21)) { + /* Base writeback. */ + if (rn == 15) + goto illegal_op; + tcg_gen_addi_i32(addr, addr, offset - 4); + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + } else if ((insn & (1 << 23)) == 0) { + /* Load/store exclusive word. */ + addr = tcg_temp_local_new_i32(); + load_reg_var(s, addr, rn); + tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); + if (insn & (1 << 20)) { + gen_load_exclusive(s, rs, 15, addr, 2); + } else { + gen_store_exclusive(s, rd, rs, 15, addr, 2); + } + tcg_temp_free_i32(addr); + } else if ((insn & (7 << 5)) == 0) { + /* Table Branch. */ + if (rn == 15) { + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc); + } else { + addr = load_reg(s, rn); + } + tmp = load_reg(s, rm); + tcg_gen_add_i32(addr, addr, tmp); + if (insn & (1 << 4)) { + /* tbh */ + tcg_gen_add_i32(addr, addr, tmp); + tcg_temp_free_i32(tmp); + tmp = tcg_temp_new_i32(); + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + } else { /* tbb */ + tcg_temp_free_i32(tmp); + tmp = tcg_temp_new_i32(); + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + } + tcg_temp_free_i32(addr); + tcg_gen_shli_i32(tmp, tmp, 1); + tcg_gen_addi_i32(tmp, tmp, s->pc); + store_reg(s, 15, tmp); + } else { + int op2 = (insn >> 6) & 0x3; + op = (insn >> 4) & 0x3; + switch (op2) { + case 0: + goto illegal_op; + case 1: + /* Load/store exclusive byte/halfword/doubleword */ + if (op == 2) { + goto illegal_op; + } + ARCH(7); + break; + case 2: + /* Load-acquire/store-release */ + if (op == 3) { + goto illegal_op; + } + /* Fall through */ + case 3: + /* Load-acquire/store-release exclusive */ + ARCH(8); + break; + } + addr = tcg_temp_local_new_i32(); + load_reg_var(s, addr, rn); + if (!(op2 & 1)) { + if (insn & (1 << 20)) { + tmp = tcg_temp_new_i32(); + switch (op) { + case 0: /* ldab */ + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + break; + case 1: /* ldah */ + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + case 2: /* lda */ + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + store_reg(s, rs, tmp); + } else { + tmp = load_reg(s, rs); + switch (op) { + case 0: /* stlb */ + gen_aa32_st8(tmp, addr, get_mem_index(s)); + break; + case 1: /* stlh */ + gen_aa32_st16(tmp, addr, get_mem_index(s)); + break; + case 2: /* stl */ + gen_aa32_st32(tmp, addr, get_mem_index(s)); + break; + default: + abort(); + } + tcg_temp_free_i32(tmp); + } + } else if (insn & (1 << 20)) { + gen_load_exclusive(s, rs, rd, addr, op); + } else { + gen_store_exclusive(s, rm, rs, rd, addr, op); + } + tcg_temp_free_i32(addr); + } + } else { + /* Load/store multiple, RFE, SRS. */ + if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { + /* RFE, SRS: not available in user mode or on M profile */ + if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) { + goto illegal_op; + } + if (insn & (1 << 20)) { + /* rfe */ + addr = load_reg(s, rn); + if ((insn & (1 << 24)) == 0) + tcg_gen_addi_i32(addr, addr, -8); + /* Load PC into tmp and CPSR into tmp2. */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + tcg_gen_addi_i32(addr, addr, 4); + tmp2 = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); + if (insn & (1 << 21)) { + /* Base writeback. */ + if (insn & (1 << 24)) { + tcg_gen_addi_i32(addr, addr, 4); + } else { + tcg_gen_addi_i32(addr, addr, -4); + } + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + gen_rfe(s, tmp, tmp2); + } else { + /* srs */ + gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2, + insn & (1 << 21)); + } + } else { + int i, loaded_base = 0; + TCGv_i32 loaded_var; + /* Load/store multiple. */ + addr = load_reg(s, rn); + offset = 0; + for (i = 0; i < 16; i++) { + if (insn & (1 << i)) + offset += 4; + } + if (insn & (1 << 24)) { + tcg_gen_addi_i32(addr, addr, -offset); + } + + TCGV_UNUSED_I32(loaded_var); + for (i = 0; i < 16; i++) { + if ((insn & (1 << i)) == 0) + continue; + if (insn & (1 << 20)) { + /* Load. */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + if (i == 15) { + gen_bx(s, tmp); + } else if (i == rn) { + loaded_var = tmp; + loaded_base = 1; + } else { + store_reg(s, i, tmp); + } + } else { + /* Store. */ + tmp = load_reg(s, i); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_gen_addi_i32(addr, addr, 4); + } + if (loaded_base) { + store_reg(s, rn, loaded_var); + } + if (insn & (1 << 21)) { + /* Base register writeback. */ + if (insn & (1 << 24)) { + tcg_gen_addi_i32(addr, addr, -offset); + } + /* Fault if writeback register is in register list. */ + if (insn & (1 << rn)) + goto illegal_op; + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + } + } + break; + case 5: + + op = (insn >> 21) & 0xf; + if (op == 6) { + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + /* Halfword pack. */ + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3); + if (insn & (1 << 5)) { + /* pkhtb */ + if (shift == 0) + shift = 31; + tcg_gen_sari_i32(tmp2, tmp2, shift); + tcg_gen_andi_i32(tmp, tmp, 0xffff0000); + tcg_gen_ext16u_i32(tmp2, tmp2); + } else { + /* pkhbt */ + if (shift) + tcg_gen_shli_i32(tmp2, tmp2, shift); + tcg_gen_ext16u_i32(tmp, tmp); + tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); + } + tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else { + /* Data processing register constant shift. */ + if (rn == 15) { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } else { + tmp = load_reg(s, rn); + } + tmp2 = load_reg(s, rm); + + shiftop = (insn >> 4) & 3; + shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); + conds = (insn & (1 << 20)) != 0; + logic_cc = (conds && thumb2_logic_op(op)); + gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); + if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) + goto illegal_op; + tcg_temp_free_i32(tmp2); + if (rd != 15) { + store_reg(s, rd, tmp); + } else { + tcg_temp_free_i32(tmp); + } + } + break; + case 13: /* Misc data processing. */ + op = ((insn >> 22) & 6) | ((insn >> 7) & 1); + if (op < 4 && (insn & 0xf000) != 0xf000) + goto illegal_op; + switch (op) { + case 0: /* Register controlled shift. */ + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + if ((insn & 0x70) != 0) + goto illegal_op; + op = (insn >> 21) & 3; + logic_cc = (insn & (1 << 20)) != 0; + gen_arm_shift_reg(tmp, op, tmp2, logic_cc); + if (logic_cc) + gen_logic_CC(tmp); + store_reg_bx(s, rd, tmp); + break; + case 1: /* Sign/zero extend. */ + op = (insn >> 20) & 7; + switch (op) { + case 0: /* SXTAH, SXTH */ + case 1: /* UXTAH, UXTH */ + case 4: /* SXTAB, SXTB */ + case 5: /* UXTAB, UXTB */ + break; + case 2: /* SXTAB16, SXTB16 */ + case 3: /* UXTAB16, UXTB16 */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + break; + default: + goto illegal_op; + } + if (rn != 15) { + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + } + tmp = load_reg(s, rm); + shift = (insn >> 4) & 3; + /* ??? In many cases it's not necessary to do a + rotate, a shift is sufficient. */ + if (shift != 0) + tcg_gen_rotri_i32(tmp, tmp, shift * 8); + op = (insn >> 20) & 7; + switch (op) { + case 0: gen_sxth(tmp); break; + case 1: gen_uxth(tmp); break; + case 2: gen_sxtb16(tmp); break; + case 3: gen_uxtb16(tmp); break; + case 4: gen_sxtb(tmp); break; + case 5: gen_uxtb(tmp); break; + default: + g_assert_not_reached(); + } + if (rn != 15) { + tmp2 = load_reg(s, rn); + if ((op >> 1) == 1) { + gen_add16(tmp, tmp2); + } else { + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + } + store_reg(s, rd, tmp); + break; + case 2: /* SIMD add/subtract. */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + op = (insn >> 20) & 7; + shift = (insn >> 4) & 7; + if ((op & 3) == 3 || (shift & 3) == 3) + goto illegal_op; + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; + case 3: /* Other data processing. */ + op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); + if (op < 4) { + /* Saturating add/subtract. */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + if (op & 1) + gen_helper_double_saturate(tmp, cpu_env, tmp); + if (op & 2) + gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp); + else + gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } else { + switch (op) { + case 0x0a: /* rbit */ + case 0x08: /* rev */ + case 0x09: /* rev16 */ + case 0x0b: /* revsh */ + case 0x18: /* clz */ + break; + case 0x10: /* sel */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + break; + case 0x20: /* crc32/crc32c */ + case 0x21: + case 0x22: + case 0x28: + case 0x29: + case 0x2a: + if (!arm_dc_feature(s, ARM_FEATURE_CRC)) { + goto illegal_op; + } + break; + default: + goto illegal_op; + } + tmp = load_reg(s, rn); + switch (op) { + case 0x0a: /* rbit */ + gen_helper_rbit(tmp, tmp); + break; + case 0x08: /* rev */ + tcg_gen_bswap32_i32(tmp, tmp); + break; + case 0x09: /* rev16 */ + gen_rev16(tmp); + break; + case 0x0b: /* revsh */ + gen_revsh(tmp); + break; + case 0x10: /* sel */ + tmp2 = load_reg(s, rm); + tmp3 = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); + gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); + tcg_temp_free_i32(tmp3); + tcg_temp_free_i32(tmp2); + break; + case 0x18: /* clz */ + gen_helper_clz(tmp, tmp); + break; + case 0x20: + case 0x21: + case 0x22: + case 0x28: + case 0x29: + case 0x2a: + { + /* crc32/crc32c */ + uint32_t sz = op & 0x3; + uint32_t c = op & 0x8; + + tmp2 = load_reg(s, rm); + if (sz == 0) { + tcg_gen_andi_i32(tmp2, tmp2, 0xff); + } else if (sz == 1) { + tcg_gen_andi_i32(tmp2, tmp2, 0xffff); + } + tmp3 = tcg_const_i32(1 << sz); + if (c) { + gen_helper_crc32c(tmp, tmp, tmp2, tmp3); + } else { + gen_helper_crc32(tmp, tmp, tmp2, tmp3); + } + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp3); + break; + } + default: + g_assert_not_reached(); + } + } + store_reg(s, rd, tmp); + break; + case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ + switch ((insn >> 20) & 7) { + case 0: /* 32 x 32 -> 32 */ + case 7: /* Unsigned sum of absolute differences. */ + break; + case 1: /* 16 x 16 -> 32 */ + case 2: /* Dual multiply add. */ + case 3: /* 32 * 16 -> 32msb */ + case 4: /* Dual multiply subtract. */ + case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + goto illegal_op; + } + break; + } + op = (insn >> 4) & 0xf; + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + switch ((insn >> 20) & 7) { + case 0: /* 32 x 32 -> 32 */ + tcg_gen_mul_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + if (rs != 15) { + tmp2 = load_reg(s, rs); + if (op) + tcg_gen_sub_i32(tmp, tmp2, tmp); + else + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + break; + case 1: /* 16 x 16 -> 32 */ + gen_mulxy(tmp, tmp2, op & 2, op & 1); + tcg_temp_free_i32(tmp2); + if (rs != 15) { + tmp2 = load_reg(s, rs); + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + break; + case 2: /* Dual multiply add. */ + case 4: /* Dual multiply subtract. */ + if (op) + gen_swap_half(tmp2); + gen_smul_dual(tmp, tmp2); + if (insn & (1 << 22)) { + /* This subtraction cannot overflow. */ + tcg_gen_sub_i32(tmp, tmp, tmp2); + } else { + /* This addition cannot overflow 32 bits; + * however it may overflow considered as a signed + * operation, in which case we must set the Q flag. + */ + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); + if (rs != 15) + { + tmp2 = load_reg(s, rs); + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + break; + case 3: /* 32 * 16 -> 32msb */ + if (op) + tcg_gen_sari_i32(tmp2, tmp2, 16); + else + gen_sxth(tmp2); + tmp64 = gen_muls_i64_i32(tmp, tmp2); + tcg_gen_shri_i64(tmp64, tmp64, 16); + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, tmp64); + tcg_temp_free_i64(tmp64); + if (rs != 15) + { + tmp2 = load_reg(s, rs); + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + break; + case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ + tmp64 = gen_muls_i64_i32(tmp, tmp2); + if (rs != 15) { + tmp = load_reg(s, rs); + if (insn & (1 << 20)) { + tmp64 = gen_addq_msw(tmp64, tmp); + } else { + tmp64 = gen_subq_msw(tmp64, tmp); + } + } + if (insn & (1 << 4)) { + tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); + } + tcg_gen_shri_i64(tmp64, tmp64, 32); + tmp = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(tmp, tmp64); + tcg_temp_free_i64(tmp64); + break; + case 7: /* Unsigned sum of absolute differences. */ + gen_helper_usad8(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + if (rs != 15) { + tmp2 = load_reg(s, rs); + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + } + break; + } + store_reg(s, rd, tmp); + break; + case 6: case 7: /* 64-bit multiply, Divide. */ + op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); + tmp = load_reg(s, rn); + tmp2 = load_reg(s, rm); + if ((op & 0x50) == 0x10) { + /* sdiv, udiv */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) { + goto illegal_op; + } + if (op & 0x20) + gen_helper_udiv(tmp, tmp, tmp2); + else + gen_helper_sdiv(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else if ((op & 0xe) == 0xc) { + /* Dual multiply accumulate long. */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + goto illegal_op; + } + if (op & 1) + gen_swap_half(tmp2); + gen_smul_dual(tmp, tmp2); + if (op & 0x10) { + tcg_gen_sub_i32(tmp, tmp, tmp2); + } else { + tcg_gen_add_i32(tmp, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); + /* BUGFIX */ + tmp64 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp64, tmp); + tcg_temp_free_i32(tmp); + gen_addq(s, tmp64, rs, rd); + gen_storeq_reg(s, rs, rd, tmp64); + tcg_temp_free_i64(tmp64); + } else { + if (op & 0x20) { + /* Unsigned 64-bit multiply */ + tmp64 = gen_mulu_i64_i32(tmp, tmp2); + } else { + if (op & 8) { + /* smlalxy */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + goto illegal_op; + } + gen_mulxy(tmp, tmp2, op & 2, op & 1); + tcg_temp_free_i32(tmp2); + tmp64 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp64, tmp); + tcg_temp_free_i32(tmp); + } else { + /* Signed 64-bit multiply */ + tmp64 = gen_muls_i64_i32(tmp, tmp2); + } + } + if (op & 4) { + /* umaal */ + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + tcg_temp_free_i64(tmp64); + goto illegal_op; + } + gen_addq_lo(s, tmp64, rs); + gen_addq_lo(s, tmp64, rd); + } else if (op & 0x40) { + /* 64-bit accumulate. */ + gen_addq(s, tmp64, rs, rd); + } + gen_storeq_reg(s, rs, rd, tmp64); + tcg_temp_free_i64(tmp64); + } + break; + } + break; + case 6: case 7: case 14: case 15: + /* Coprocessor. */ + if (((insn >> 24) & 3) == 3) { + /* Translate into the equivalent ARM encoding. */ + insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); + if (disas_neon_data_insn(s, insn)) { + goto illegal_op; + } + } else if (((insn >> 8) & 0xe) == 10) { + if (disas_vfp_insn(s, insn)) { + goto illegal_op; + } + } else { + if (insn & (1 << 28)) + goto illegal_op; + if (disas_coproc_insn(s, insn)) { + goto illegal_op; + } + } + break; + case 8: case 9: case 10: case 11: + if (insn & (1 << 15)) { + /* Branches, misc control. */ + if (insn & 0x5000) { + /* Unconditional branch. */ + /* signextend(hw1[10:0]) -> offset[:12]. */ + offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff; + /* hw1[10:0] -> offset[11:1]. */ + offset |= (insn & 0x7ff) << 1; + /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22] + offset[24:22] already have the same value because of the + sign extension above. */ + offset ^= ((~insn) & (1 << 13)) << 10; + offset ^= ((~insn) & (1 << 11)) << 11; + + if (insn & (1 << 14)) { + /* Branch and link. */ + tcg_gen_movi_i32(cpu_R[14], s->pc | 1); + } + + offset += s->pc; + if (insn & (1 << 12)) { + /* b/bl */ + gen_jmp(s, offset); + } else { + /* blx */ + offset &= ~(uint32_t)2; + /* thumb2 bx, no need to check */ + gen_bx_im(s, offset); + } + } else if (((insn >> 23) & 7) == 7) { + /* Misc control */ + if (insn & (1 << 13)) + goto illegal_op; + + if (insn & (1 << 26)) { + if (!(insn & (1 << 20))) { + /* Hypervisor call (v7) */ + int imm16 = extract32(insn, 16, 4) << 12 + | extract32(insn, 0, 12); + ARCH(7); + if (IS_USER(s)) { + goto illegal_op; + } + gen_hvc(s, imm16); + } else { + /* Secure monitor call (v6+) */ + ARCH(6K); + if (IS_USER(s)) { + goto illegal_op; + } + gen_smc(s); + } + } else { + op = (insn >> 20) & 7; + switch (op) { + case 0: /* msr cpsr. */ + if (arm_dc_feature(s, ARM_FEATURE_M)) { + tmp = load_reg(s, rn); + addr = tcg_const_i32(insn & 0xff); + gen_helper_v7m_msr(cpu_env, addr, tmp); + tcg_temp_free_i32(addr); + tcg_temp_free_i32(tmp); + gen_lookup_tb(s); + break; + } + /* fall through */ + case 1: /* msr spsr. */ + if (arm_dc_feature(s, ARM_FEATURE_M)) { + goto illegal_op; + } + tmp = load_reg(s, rn); + if (gen_set_psr(s, + msr_mask(s, (insn >> 8) & 0xf, op == 1), + op == 1, tmp)) + goto illegal_op; + break; + case 2: /* cps, nop-hint. */ + if (((insn >> 8) & 7) == 0) { + gen_nop_hint(s, insn & 0xff); + } + /* Implemented as NOP in user mode. */ + if (IS_USER(s)) + break; + offset = 0; + imm = 0; + if (insn & (1 << 10)) { + if (insn & (1 << 7)) + offset |= CPSR_A; + if (insn & (1 << 6)) + offset |= CPSR_I; + if (insn & (1 << 5)) + offset |= CPSR_F; + if (insn & (1 << 9)) + imm = CPSR_A | CPSR_I | CPSR_F; + } + if (insn & (1 << 8)) { + offset |= 0x1f; + imm |= (insn & 0x1f); + } + if (offset) { + gen_set_psr_im(s, offset, 0, imm); + } + break; + case 3: /* Special control operations. */ + ARCH(7); + op = (insn >> 4) & 0xf; + switch (op) { + case 2: /* clrex */ + gen_clrex(s); + break; + case 4: /* dsb */ + case 5: /* dmb */ + /* These execute as NOPs. */ + break; + case 6: /* isb */ + /* We need to break the TB after this insn + * to execute self-modifying code correctly + * and also to take any pending interrupts + * immediately. + */ + gen_lookup_tb(s); + break; + default: + goto illegal_op; + } + break; + case 4: /* bxj */ + /* Trivial implementation equivalent to bx. */ + tmp = load_reg(s, rn); + gen_bx(s, tmp); + break; + case 5: /* Exception return. */ + if (IS_USER(s)) { + goto illegal_op; + } + if (rn != 14 || rd != 15) { + goto illegal_op; + } + tmp = load_reg(s, rn); + tcg_gen_subi_i32(tmp, tmp, insn & 0xff); + gen_exception_return(s, tmp); + break; + case 6: /* mrs cpsr. */ + tmp = tcg_temp_new_i32(); + if (arm_dc_feature(s, ARM_FEATURE_M)) { + addr = tcg_const_i32(insn & 0xff); + gen_helper_v7m_mrs(tmp, cpu_env, addr); + tcg_temp_free_i32(addr); + } else { + gen_helper_cpsr_read(tmp, cpu_env); + } + store_reg(s, rd, tmp); + break; + case 7: /* mrs spsr. */ + /* Not accessible in user mode. */ + if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) { + goto illegal_op; + } + tmp = load_cpu_field(spsr); + store_reg(s, rd, tmp); + break; + } + } + } else { + /* Conditional branch. */ + op = (insn >> 22) & 0xf; + /* Generate a conditional jump to next instruction. */ + s->condlabel = gen_new_label(); + arm_gen_test_cc(op ^ 1, s->condlabel); + s->condjmp = 1; + + /* offset[11:1] = insn[10:0] */ + offset = (insn & 0x7ff) << 1; + /* offset[17:12] = insn[21:16]. */ + offset |= (insn & 0x003f0000) >> 4; + /* offset[31:20] = insn[26]. */ + offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11; + /* offset[18] = insn[13]. */ + offset |= (insn & (1 << 13)) << 5; + /* offset[19] = insn[11]. */ + offset |= (insn & (1 << 11)) << 8; + + /* jump to the offset */ + gen_jmp(s, s->pc + offset); + } + } else { + /* Data processing immediate. */ + if (insn & (1 << 25)) { + if (insn & (1 << 24)) { + if (insn & (1 << 20)) + goto illegal_op; + /* Bitfield/Saturate. */ + op = (insn >> 21) & 7; + imm = insn & 0x1f; + shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); + if (rn == 15) { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } else { + tmp = load_reg(s, rn); + } + switch (op) { + case 2: /* Signed bitfield extract. */ + imm++; + if (shift + imm > 32) + goto illegal_op; + if (imm < 32) + gen_sbfx(tmp, shift, imm); + break; + case 6: /* Unsigned bitfield extract. */ + imm++; + if (shift + imm > 32) + goto illegal_op; + if (imm < 32) + gen_ubfx(tmp, shift, (1u << imm) - 1); + break; + case 3: /* Bitfield insert/clear. */ + if (imm < shift) + goto illegal_op; + imm = imm + 1 - shift; + if (imm != 32) { + tmp2 = load_reg(s, rd); + tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm); + tcg_temp_free_i32(tmp2); + } + break; + case 7: + goto illegal_op; + default: /* Saturate. */ + if (shift) { + if (op & 1) + tcg_gen_sari_i32(tmp, tmp, shift); + else + tcg_gen_shli_i32(tmp, tmp, shift); + } + tmp2 = tcg_const_i32(imm); + if (op & 4) { + /* Unsigned. */ + if ((op & 1) && shift == 0) { + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + goto illegal_op; + } + gen_helper_usat16(tmp, cpu_env, tmp, tmp2); + } else { + gen_helper_usat(tmp, cpu_env, tmp, tmp2); + } + } else { + /* Signed. */ + if ((op & 1) && shift == 0) { + if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + goto illegal_op; + } + gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); + } else { + gen_helper_ssat(tmp, cpu_env, tmp, tmp2); + } + } + tcg_temp_free_i32(tmp2); + break; + } + store_reg(s, rd, tmp); + } else { + imm = ((insn & 0x04000000) >> 15) + | ((insn & 0x7000) >> 4) | (insn & 0xff); + if (insn & (1 << 22)) { + /* 16-bit immediate. */ + imm |= (insn >> 4) & 0xf000; + if (insn & (1 << 23)) { + /* movt */ + tmp = load_reg(s, rd); + tcg_gen_ext16u_i32(tmp, tmp); + tcg_gen_ori_i32(tmp, tmp, imm << 16); + } else { + /* movw */ + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, imm); + } + } else { + /* Add/sub 12-bit immediate. */ + if (rn == 15) { + offset = s->pc & ~(uint32_t)3; + if (insn & (1 << 23)) + offset -= imm; + else + offset += imm; + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, offset); + } else { + tmp = load_reg(s, rn); + if (insn & (1 << 23)) + tcg_gen_subi_i32(tmp, tmp, imm); + else + tcg_gen_addi_i32(tmp, tmp, imm); + } + } + store_reg(s, rd, tmp); + } + } else { + int shifter_out = 0; + /* modified 12-bit immediate. */ + shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); + imm = (insn & 0xff); + switch (shift) { + case 0: /* XY */ + /* Nothing to do. */ + break; + case 1: /* 00XY00XY */ + imm |= imm << 16; + break; + case 2: /* XY00XY00 */ + imm |= imm << 16; + imm <<= 8; + break; + case 3: /* XYXYXYXY */ + imm |= imm << 16; + imm |= imm << 8; + break; + default: /* Rotated constant. */ + shift = (shift << 1) | (imm >> 7); + imm |= 0x80; + imm = imm << (32 - shift); + shifter_out = 1; + break; + } + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, imm); + rn = (insn >> 16) & 0xf; + if (rn == 15) { + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } else { + tmp = load_reg(s, rn); + } + op = (insn >> 21) & 0xf; + if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, + shifter_out, tmp, tmp2)) + goto illegal_op; + tcg_temp_free_i32(tmp2); + rd = (insn >> 8) & 0xf; + if (rd != 15) { + store_reg(s, rd, tmp); + } else { + tcg_temp_free_i32(tmp); + } + } + } + break; + case 12: /* Load/store single data item. */ + { + int postinc = 0; + int writeback = 0; + int memidx; + if ((insn & 0x01100000) == 0x01000000) { + if (disas_neon_ls_insn(s, insn)) { + goto illegal_op; + } + break; + } + op = ((insn >> 21) & 3) | ((insn >> 22) & 4); + if (rs == 15) { + if (!(insn & (1 << 20))) { + goto illegal_op; + } + if (op != 2) { + /* Byte or halfword load space with dest == r15 : memory hints. + * Catch them early so we don't emit pointless addressing code. + * This space is a mix of: + * PLD/PLDW/PLI, which we implement as NOPs (note that unlike + * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP + * cores) + * unallocated hints, which must be treated as NOPs + * UNPREDICTABLE space, which we NOP or UNDEF depending on + * which is easiest for the decoding logic + * Some space which must UNDEF + */ + int op1 = (insn >> 23) & 3; + int op2 = (insn >> 6) & 0x3f; + if (op & 2) { + goto illegal_op; + } + if (rn == 15) { + /* UNPREDICTABLE, unallocated hint or + * PLD/PLDW/PLI (literal) + */ + return 0; + } + if (op1 & 1) { + return 0; /* PLD/PLDW/PLI or unallocated hint */ + } + if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { + return 0; /* PLD/PLDW/PLI or unallocated hint */ + } + /* UNDEF space, or an UNPREDICTABLE */ + return 1; + } + } + memidx = get_mem_index(s); + if (rn == 15) { + addr = tcg_temp_new_i32(); + /* PC relative. */ + /* s->pc has already been incremented by 4. */ + imm = s->pc & 0xfffffffc; + if (insn & (1 << 23)) + imm += insn & 0xfff; + else + imm -= insn & 0xfff; + tcg_gen_movi_i32(addr, imm); + } else { + addr = load_reg(s, rn); + if (insn & (1 << 23)) { + /* Positive offset. */ + imm = insn & 0xfff; + tcg_gen_addi_i32(addr, addr, imm); + } else { + imm = insn & 0xff; + switch ((insn >> 8) & 0xf) { + case 0x0: /* Shifted Register. */ + shift = (insn >> 4) & 0xf; + if (shift > 3) { + tcg_temp_free_i32(addr); + goto illegal_op; + } + tmp = load_reg(s, rm); + if (shift) + tcg_gen_shli_i32(tmp, tmp, shift); + tcg_gen_add_i32(addr, addr, tmp); + tcg_temp_free_i32(tmp); + break; + case 0xc: /* Negative offset. */ + tcg_gen_addi_i32(addr, addr, -imm); + break; + case 0xe: /* User privilege. */ + tcg_gen_addi_i32(addr, addr, imm); + memidx = get_a32_user_mem_index(s); + break; + case 0x9: /* Post-decrement. */ + imm = -imm; + /* Fall through. */ + case 0xb: /* Post-increment. */ + postinc = 1; + writeback = 1; + break; + case 0xd: /* Pre-decrement. */ + imm = -imm; + /* Fall through. */ + case 0xf: /* Pre-increment. */ + tcg_gen_addi_i32(addr, addr, imm); + writeback = 1; + break; + default: + tcg_temp_free_i32(addr); + goto illegal_op; + } + } + } + if (insn & (1 << 20)) { + /* Load. */ + tmp = tcg_temp_new_i32(); + switch (op) { + case 0: + gen_aa32_ld8u(tmp, addr, memidx); + break; + case 4: + gen_aa32_ld8s(tmp, addr, memidx); + break; + case 1: + gen_aa32_ld16u(tmp, addr, memidx); + break; + case 5: + gen_aa32_ld16s(tmp, addr, memidx); + break; + case 2: + gen_aa32_ld32u(tmp, addr, memidx); + break; + default: + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(addr); + goto illegal_op; + } + if (rs == 15) { + gen_bx(s, tmp); + } else { + store_reg(s, rs, tmp); + } + } else { + /* Store. */ + tmp = load_reg(s, rs); + switch (op) { + case 0: + gen_aa32_st8(tmp, addr, memidx); + break; + case 1: + gen_aa32_st16(tmp, addr, memidx); + break; + case 2: + gen_aa32_st32(tmp, addr, memidx); + break; + default: + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(addr); + goto illegal_op; + } + tcg_temp_free_i32(tmp); + } + if (postinc) + tcg_gen_addi_i32(addr, addr, imm); + if (writeback) { + store_reg(s, rn, addr); + } else { + tcg_temp_free_i32(addr); + } + } + break; + default: + goto illegal_op; + } + return 0; +illegal_op: + return 1; +} + +static void disas_thumb_insn(CPUARMState *env, DisasContext *s) +{ + uint32_t val, insn, op, rm, rn, rd, shift, cond; + int32_t offset; + int i; + TCGv_i32 tmp; + TCGv_i32 tmp2; + TCGv_i32 addr; + + if (s->condexec_mask) { + cond = s->condexec_cond; + if (cond != 0x0e) { /* Skip conditional when condition is AL. */ + s->condlabel = gen_new_label(); + arm_gen_test_cc(cond ^ 1, s->condlabel); + s->condjmp = 1; + } + } + + insn = arm_lduw_code(env, s->pc, s->bswap_code); + s->pc += 2; + + switch (insn >> 12) { + case 0: case 1: + + rd = insn & 7; + op = (insn >> 11) & 3; + if (op == 3) { + /* add/subtract */ + rn = (insn >> 3) & 7; + tmp = load_reg(s, rn); + if (insn & (1 << 10)) { + /* immediate */ + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, (insn >> 6) & 7); + } else { + /* reg */ + rm = (insn >> 6) & 7; + tmp2 = load_reg(s, rm); + } + if (insn & (1 << 9)) { + if (s->condexec_mask) + tcg_gen_sub_i32(tmp, tmp, tmp2); + else + gen_sub_CC(tmp, tmp, tmp2); + } else { + if (s->condexec_mask) + tcg_gen_add_i32(tmp, tmp, tmp2); + else + gen_add_CC(tmp, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + } else { + /* shift immediate */ + rm = (insn >> 3) & 7; + shift = (insn >> 6) & 0x1f; + tmp = load_reg(s, rm); + gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0); + if (!s->condexec_mask) + gen_logic_CC(tmp); + store_reg(s, rd, tmp); + } + break; + case 2: case 3: + /* arithmetic large immediate */ + op = (insn >> 11) & 3; + rd = (insn >> 8) & 0x7; + if (op == 0) { /* mov */ + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, insn & 0xff); + if (!s->condexec_mask) + gen_logic_CC(tmp); + store_reg(s, rd, tmp); + } else { + tmp = load_reg(s, rd); + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, insn & 0xff); + switch (op) { + case 1: /* cmp */ + gen_sub_CC(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + break; + case 2: /* add */ + if (s->condexec_mask) + tcg_gen_add_i32(tmp, tmp, tmp2); + else + gen_add_CC(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; + case 3: /* sub */ + if (s->condexec_mask) + tcg_gen_sub_i32(tmp, tmp, tmp2); + else + gen_sub_CC(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; + } + } + break; + case 4: + if (insn & (1 << 11)) { + rd = (insn >> 8) & 7; + /* load pc-relative. Bit 1 of PC is ignored. */ + val = s->pc + 2 + ((insn & 0xff) * 4); + val &= ~(uint32_t)2; + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, val); + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(addr); + store_reg(s, rd, tmp); + break; + } + if (insn & (1 << 10)) { + /* data processing extended or blx */ + rd = (insn & 7) | ((insn >> 4) & 8); + rm = (insn >> 3) & 0xf; + op = (insn >> 8) & 3; + switch (op) { + case 0: /* add */ + tmp = load_reg(s, rd); + tmp2 = load_reg(s, rm); + tcg_gen_add_i32(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; + case 1: /* cmp */ + tmp = load_reg(s, rd); + tmp2 = load_reg(s, rm); + gen_sub_CC(tmp, tmp, tmp2); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; + case 2: /* mov/cpy */ + tmp = load_reg(s, rm); + store_reg(s, rd, tmp); + break; + case 3:/* branch [and link] exchange thumb register */ + tmp = load_reg(s, rm); + if (insn & (1 << 7)) { + ARCH(5); + val = (uint32_t)s->pc | 1; + tmp2 = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp2, val); + store_reg(s, 14, tmp2); + } + /* already thumb, no need to check */ + gen_bx(s, tmp); + break; + } + break; + } + + /* data processing register */ + rd = insn & 7; + rm = (insn >> 3) & 7; + op = (insn >> 6) & 0xf; + if (op == 2 || op == 3 || op == 4 || op == 7) { + /* the shift/rotate ops want the operands backwards */ + val = rm; + rm = rd; + rd = val; + val = 1; + } else { + val = 0; + } + + if (op == 9) { /* neg */ + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + } else if (op != 0xf) { /* mvn doesn't read its first operand */ + tmp = load_reg(s, rd); + } else { + TCGV_UNUSED_I32(tmp); + } + + tmp2 = load_reg(s, rm); + switch (op) { + case 0x0: /* and */ + tcg_gen_and_i32(tmp, tmp, tmp2); + if (!s->condexec_mask) + gen_logic_CC(tmp); + break; + case 0x1: /* eor */ + tcg_gen_xor_i32(tmp, tmp, tmp2); + if (!s->condexec_mask) + gen_logic_CC(tmp); + break; + case 0x2: /* lsl */ + if (s->condexec_mask) { + gen_shl(tmp2, tmp2, tmp); + } else { + gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp); + gen_logic_CC(tmp2); + } + break; + case 0x3: /* lsr */ + if (s->condexec_mask) { + gen_shr(tmp2, tmp2, tmp); + } else { + gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp); + gen_logic_CC(tmp2); + } + break; + case 0x4: /* asr */ + if (s->condexec_mask) { + gen_sar(tmp2, tmp2, tmp); + } else { + gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp); + gen_logic_CC(tmp2); + } + break; + case 0x5: /* adc */ + if (s->condexec_mask) { + gen_adc(tmp, tmp2); + } else { + gen_adc_CC(tmp, tmp, tmp2); + } + break; + case 0x6: /* sbc */ + if (s->condexec_mask) { + gen_sub_carry(tmp, tmp, tmp2); + } else { + gen_sbc_CC(tmp, tmp, tmp2); + } + break; + case 0x7: /* ror */ + if (s->condexec_mask) { + tcg_gen_andi_i32(tmp, tmp, 0x1f); + tcg_gen_rotr_i32(tmp2, tmp2, tmp); + } else { + gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp); + gen_logic_CC(tmp2); + } + break; + case 0x8: /* tst */ + tcg_gen_and_i32(tmp, tmp, tmp2); + gen_logic_CC(tmp); + rd = 16; + break; + case 0x9: /* neg */ + if (s->condexec_mask) + tcg_gen_neg_i32(tmp, tmp2); + else + gen_sub_CC(tmp, tmp, tmp2); + break; + case 0xa: /* cmp */ + gen_sub_CC(tmp, tmp, tmp2); + rd = 16; + break; + case 0xb: /* cmn */ + gen_add_CC(tmp, tmp, tmp2); + rd = 16; + break; + case 0xc: /* orr */ + tcg_gen_or_i32(tmp, tmp, tmp2); + if (!s->condexec_mask) + gen_logic_CC(tmp); + break; + case 0xd: /* mul */ + tcg_gen_mul_i32(tmp, tmp, tmp2); + if (!s->condexec_mask) + gen_logic_CC(tmp); + break; + case 0xe: /* bic */ + tcg_gen_andc_i32(tmp, tmp, tmp2); + if (!s->condexec_mask) + gen_logic_CC(tmp); + break; + case 0xf: /* mvn */ + tcg_gen_not_i32(tmp2, tmp2); + if (!s->condexec_mask) + gen_logic_CC(tmp2); + val = 1; + rm = rd; + break; + } + if (rd != 16) { + if (val) { + store_reg(s, rm, tmp2); + if (op != 0xf) + tcg_temp_free_i32(tmp); + } else { + store_reg(s, rd, tmp); + tcg_temp_free_i32(tmp2); + } + } else { + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + } + break; + + case 5: + /* load/store register offset. */ + rd = insn & 7; + rn = (insn >> 3) & 7; + rm = (insn >> 6) & 7; + op = (insn >> 9) & 7; + addr = load_reg(s, rn); + tmp = load_reg(s, rm); + tcg_gen_add_i32(addr, addr, tmp); + tcg_temp_free_i32(tmp); + + if (op < 3) { /* store */ + tmp = load_reg(s, rd); + } else { + tmp = tcg_temp_new_i32(); + } + + switch (op) { + case 0: /* str */ + gen_aa32_st32(tmp, addr, get_mem_index(s)); + break; + case 1: /* strh */ + gen_aa32_st16(tmp, addr, get_mem_index(s)); + break; + case 2: /* strb */ + gen_aa32_st8(tmp, addr, get_mem_index(s)); + break; + case 3: /* ldrsb */ + gen_aa32_ld8s(tmp, addr, get_mem_index(s)); + break; + case 4: /* ldr */ + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + break; + case 5: /* ldrh */ + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + break; + case 6: /* ldrb */ + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + break; + case 7: /* ldrsh */ + gen_aa32_ld16s(tmp, addr, get_mem_index(s)); + break; + } + if (op >= 3) { /* load */ + store_reg(s, rd, tmp); + } else { + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); + break; + + case 6: + /* load/store word immediate offset */ + rd = insn & 7; + rn = (insn >> 3) & 7; + addr = load_reg(s, rn); + val = (insn >> 4) & 0x7c; + tcg_gen_addi_i32(addr, addr, val); + + if (insn & (1 << 11)) { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + store_reg(s, rd, tmp); + } else { + /* store */ + tmp = load_reg(s, rd); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); + break; + + case 7: + /* load/store byte immediate offset */ + rd = insn & 7; + rn = (insn >> 3) & 7; + addr = load_reg(s, rn); + val = (insn >> 6) & 0x1f; + tcg_gen_addi_i32(addr, addr, val); + + if (insn & (1 << 11)) { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld8u(tmp, addr, get_mem_index(s)); + store_reg(s, rd, tmp); + } else { + /* store */ + tmp = load_reg(s, rd); + gen_aa32_st8(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); + break; + + case 8: + /* load/store halfword immediate offset */ + rd = insn & 7; + rn = (insn >> 3) & 7; + addr = load_reg(s, rn); + val = (insn >> 5) & 0x3e; + tcg_gen_addi_i32(addr, addr, val); + + if (insn & (1 << 11)) { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld16u(tmp, addr, get_mem_index(s)); + store_reg(s, rd, tmp); + } else { + /* store */ + tmp = load_reg(s, rd); + gen_aa32_st16(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); + break; + + case 9: + /* load/store from stack */ + rd = (insn >> 8) & 7; + addr = load_reg(s, 13); + val = (insn & 0xff) * 4; + tcg_gen_addi_i32(addr, addr, val); + + if (insn & (1 << 11)) { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + store_reg(s, rd, tmp); + } else { + /* store */ + tmp = load_reg(s, rd); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); + break; + + case 10: + /* add to high reg */ + rd = (insn >> 8) & 7; + if (insn & (1 << 11)) { + /* SP */ + tmp = load_reg(s, 13); + } else { + /* PC. bit 1 is ignored. */ + tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2); + } + val = (insn & 0xff) * 4; + tcg_gen_addi_i32(tmp, tmp, val); + store_reg(s, rd, tmp); + break; + + case 11: + /* misc */ + op = (insn >> 8) & 0xf; + switch (op) { + case 0: + /* adjust stack pointer */ + tmp = load_reg(s, 13); + val = (insn & 0x7f) * 4; + if (insn & (1 << 7)) + val = -(int32_t)val; + tcg_gen_addi_i32(tmp, tmp, val); + store_reg(s, 13, tmp); + break; + + case 2: /* sign/zero extend. */ + ARCH(6); + rd = insn & 7; + rm = (insn >> 3) & 7; + tmp = load_reg(s, rm); + switch ((insn >> 6) & 3) { + case 0: gen_sxth(tmp); break; + case 1: gen_sxtb(tmp); break; + case 2: gen_uxth(tmp); break; + case 3: gen_uxtb(tmp); break; + } + store_reg(s, rd, tmp); + break; + case 4: case 5: case 0xc: case 0xd: + /* push/pop */ + addr = load_reg(s, 13); + if (insn & (1 << 8)) + offset = 4; + else + offset = 0; + for (i = 0; i < 8; i++) { + if (insn & (1 << i)) + offset += 4; + } + if ((insn & (1 << 11)) == 0) { + tcg_gen_addi_i32(addr, addr, -offset); + } + for (i = 0; i < 8; i++) { + if (insn & (1 << i)) { + if (insn & (1 << 11)) { + /* pop */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + store_reg(s, i, tmp); + } else { + /* push */ + tmp = load_reg(s, i); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + /* advance to the next address. */ + tcg_gen_addi_i32(addr, addr, 4); + } + } + TCGV_UNUSED_I32(tmp); + if (insn & (1 << 8)) { + if (insn & (1 << 11)) { + /* pop pc */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + /* don't set the pc until the rest of the instruction + has completed */ + } else { + /* push lr */ + tmp = load_reg(s, 14); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + tcg_gen_addi_i32(addr, addr, 4); + } + if ((insn & (1 << 11)) == 0) { + tcg_gen_addi_i32(addr, addr, -offset); + } + /* write back the new stack pointer */ + store_reg(s, 13, addr); + /* set the new PC value */ + if ((insn & 0x0900) == 0x0900) { + store_reg_from_load(s, 15, tmp); + } + break; + + case 1: case 3: case 9: case 11: /* czb */ + rm = insn & 7; + tmp = load_reg(s, rm); + s->condlabel = gen_new_label(); + s->condjmp = 1; + if (insn & (1 << 11)) + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel); + else + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel); + tcg_temp_free_i32(tmp); + offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; + val = (uint32_t)s->pc + 2; + val += offset; + gen_jmp(s, val); + break; + + case 15: /* IT, nop-hint. */ + if ((insn & 0xf) == 0) { + gen_nop_hint(s, (insn >> 4) & 0xf); + break; + } + /* If Then. */ + s->condexec_cond = (insn >> 4) & 0xe; + s->condexec_mask = insn & 0x1f; + /* No actual code generated for this insn, just setup state. */ + break; + + case 0xe: /* bkpt */ + { + int imm8 = extract32(insn, 0, 8); + ARCH(5); + gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true), + default_exception_el(s)); + break; + } + + case 0xa: /* rev */ + ARCH(6); + rn = (insn >> 3) & 0x7; + rd = insn & 0x7; + tmp = load_reg(s, rn); + switch ((insn >> 6) & 3) { + case 0: tcg_gen_bswap32_i32(tmp, tmp); break; + case 1: gen_rev16(tmp); break; + case 3: gen_revsh(tmp); break; + default: goto illegal_op; + } + store_reg(s, rd, tmp); + break; + + case 6: + switch ((insn >> 5) & 7) { + case 2: + /* setend */ + ARCH(6); + if (((insn >> 3) & 1) != s->bswap_code) { + /* Dynamic endianness switching not implemented. */ + qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n"); + goto illegal_op; + } + break; + case 3: + /* cps */ + ARCH(6); + if (IS_USER(s)) { + break; + } + if (arm_dc_feature(s, ARM_FEATURE_M)) { + tmp = tcg_const_i32((insn & (1 << 4)) != 0); + /* FAULTMASK */ + if (insn & 1) { + addr = tcg_const_i32(19); + gen_helper_v7m_msr(cpu_env, addr, tmp); + tcg_temp_free_i32(addr); + } + /* PRIMASK */ + if (insn & 2) { + addr = tcg_const_i32(16); + gen_helper_v7m_msr(cpu_env, addr, tmp); + tcg_temp_free_i32(addr); + } + tcg_temp_free_i32(tmp); + gen_lookup_tb(s); + } else { + if (insn & (1 << 4)) { + shift = CPSR_A | CPSR_I | CPSR_F; + } else { + shift = 0; + } + gen_set_psr_im(s, ((insn & 7) << 6), 0, shift); + } + break; + default: + goto undef; + } + break; + + default: + goto undef; + } + break; + + case 12: + { + /* load/store multiple */ + TCGv_i32 loaded_var; + TCGV_UNUSED_I32(loaded_var); + rn = (insn >> 8) & 0x7; + addr = load_reg(s, rn); + for (i = 0; i < 8; i++) { + if (insn & (1 << i)) { + if (insn & (1 << 11)) { + /* load */ + tmp = tcg_temp_new_i32(); + gen_aa32_ld32u(tmp, addr, get_mem_index(s)); + if (i == rn) { + loaded_var = tmp; + } else { + store_reg(s, i, tmp); + } + } else { + /* store */ + tmp = load_reg(s, i); + gen_aa32_st32(tmp, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp); + } + /* advance to the next address */ + tcg_gen_addi_i32(addr, addr, 4); + } + } + if ((insn & (1 << rn)) == 0) { + /* base reg not in list: base register writeback */ + store_reg(s, rn, addr); + } else { + /* base reg in list: if load, complete it now */ + if (insn & (1 << 11)) { + store_reg(s, rn, loaded_var); + } + tcg_temp_free_i32(addr); + } + break; + } + case 13: + /* conditional branch or swi */ + cond = (insn >> 8) & 0xf; + if (cond == 0xe) + goto undef; + + if (cond == 0xf) { + /* swi */ + gen_set_pc_im(s, s->pc); + s->svc_imm = extract32(insn, 0, 8); + s->is_jmp = DISAS_SWI; + break; + } + /* generate a conditional jump to next instruction */ + s->condlabel = gen_new_label(); + arm_gen_test_cc(cond ^ 1, s->condlabel); + s->condjmp = 1; + + /* jump to the offset */ + val = (uint32_t)s->pc + 2; + offset = ((int32_t)insn << 24) >> 24; + val += offset << 1; + gen_jmp(s, val); + break; + + case 14: + if (insn & (1 << 11)) { + if (disas_thumb2_insn(env, s, insn)) + goto undef32; + break; + } + /* unconditional branch */ + val = (uint32_t)s->pc; + offset = ((int32_t)insn << 21) >> 21; + val += (offset << 1) + 2; + gen_jmp(s, val); + break; + + case 15: + if (disas_thumb2_insn(env, s, insn)) + goto undef32; + break; + } + return; +undef32: + gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); + return; +illegal_op: +undef: + gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(), + default_exception_el(s)); +} + +static bool insn_crosses_page(CPUARMState *env, DisasContext *s) +{ + /* Return true if the insn at dc->pc might cross a page boundary. + * (False positives are OK, false negatives are not.) + */ + uint16_t insn; + + if ((s->pc & 3) == 0) { + /* At a 4-aligned address we can't be crossing a page */ + return false; + } + + /* This must be a Thumb insn */ + insn = arm_lduw_code(env, s->pc, s->bswap_code); + + if ((insn >> 11) >= 0x1d) { + /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the + * First half of a 32-bit Thumb insn. Thumb-1 cores might + * end up actually treating this as two 16-bit insns (see the + * code at the start of disas_thumb2_insn()) but we don't bother + * to check for that as it is unlikely, and false positives here + * are harmless. + */ + return true; + } + /* Definitely a 16-bit insn, can't be crossing a page. */ + return false; +} + +/* generate intermediate code in gen_opc_buf and gen_opparam_buf for + basic block 'tb'. */ +void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + DisasContext dc1, *dc = &dc1; + target_ulong pc_start; + target_ulong next_page_start; + int num_insns; + int max_insns; + bool end_of_page; + + /* generate intermediate code */ + + /* The A64 decoder has its own top level loop, because it doesn't need + * the A32/T32 complexity to do with conditional execution/IT blocks/etc. + */ + if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) { + gen_intermediate_code_a64(cpu, tb); + return; + } + + pc_start = tb->pc; + + dc->tb = tb; + + dc->is_jmp = DISAS_NEXT; + dc->pc = pc_start; + dc->singlestep_enabled = cs->singlestep_enabled; + dc->condjmp = 0; + + dc->aarch64 = 0; + /* If we are coming from secure EL0 in a system with a 32-bit EL3, then + * there is no secure EL1, so we route exceptions to EL3. + */ + dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) && + !arm_el_is_aa64(env, 3); + dc->thumb = ARM_TBFLAG_THUMB(tb->flags); + dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags); + dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1; + dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4; + dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags); + dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx); +#if !defined(CONFIG_USER_ONLY) + dc->user = (dc->current_el == 0); +#endif + dc->ns = ARM_TBFLAG_NS(tb->flags); + dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags); + dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags); + dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); + dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags); + dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags); + dc->cp_regs = cpu->cp_regs; + dc->features = env->features; + + /* Single step state. The code-generation logic here is: + * SS_ACTIVE == 0: + * generate code with no special handling for single-stepping (except + * that anything that can make us go to SS_ACTIVE == 1 must end the TB; + * this happens anyway because those changes are all system register or + * PSTATE writes). + * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending) + * emit code for one insn + * emit code to clear PSTATE.SS + * emit code to generate software step exception for completed step + * end TB (as usual for having generated an exception) + * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending) + * emit code to generate a software step exception + * end the TB + */ + dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags); + dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags); + dc->is_ldex = false; + dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */ + + cpu_F0s = tcg_temp_new_i32(); + cpu_F1s = tcg_temp_new_i32(); + cpu_F0d = tcg_temp_new_i64(); + cpu_F1d = tcg_temp_new_i64(); + cpu_V0 = cpu_F0d; + cpu_V1 = cpu_F1d; + /* FIXME: cpu_M0 can probably be the same as cpu_V0. */ + cpu_M0 = tcg_temp_new_i64(); + next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; + num_insns = 0; + max_insns = tb->cflags & CF_COUNT_MASK; + if (max_insns == 0) { + max_insns = CF_COUNT_MASK; + } + if (max_insns > TCG_MAX_INSNS) { + max_insns = TCG_MAX_INSNS; + } + + gen_tb_start(tb); + + tcg_clear_temp_count(); + + /* A note on handling of the condexec (IT) bits: + * + * We want to avoid the overhead of having to write the updated condexec + * bits back to the CPUARMState for every instruction in an IT block. So: + * (1) if the condexec bits are not already zero then we write + * zero back into the CPUARMState now. This avoids complications trying + * to do it at the end of the block. (For example if we don't do this + * it's hard to identify whether we can safely skip writing condexec + * at the end of the TB, which we definitely want to do for the case + * where a TB doesn't do anything with the IT state at all.) + * (2) if we are going to leave the TB then we call gen_set_condexec() + * which will write the correct value into CPUARMState if zero is wrong. + * This is done both for leaving the TB at the end, and for leaving + * it because of an exception we know will happen, which is done in + * gen_exception_insn(). The latter is necessary because we need to + * leave the TB with the PC/IT state just prior to execution of the + * instruction which caused the exception. + * (3) if we leave the TB unexpectedly (eg a data abort on a load) + * then the CPUARMState will be wrong and we need to reset it. + * This is handled in the same way as restoration of the + * PC in these situations; we save the value of the condexec bits + * for each PC via tcg_gen_insn_start(), and restore_state_to_opc() + * then uses this to restore them after an exception. + * + * Note that there are no instructions which can read the condexec + * bits, and none which can write non-static values to them, so + * we don't need to care about whether CPUARMState is correct in the + * middle of a TB. + */ + + /* Reset the conditional execution bits immediately. This avoids + complications trying to do it at the end of the block. */ + if (dc->condexec_mask || dc->condexec_cond) + { + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, 0); + store_cpu_field(tmp, condexec_bits); + } + do { + tcg_gen_insn_start(dc->pc, + (dc->condexec_cond << 4) | (dc->condexec_mask >> 1)); + num_insns++; + +#ifdef CONFIG_USER_ONLY + /* Intercept jump to the magic kernel page. */ + if (dc->pc >= 0xffff0000) { + /* We always get here via a jump, so know we are not in a + conditional execution block. */ + gen_exception_internal(EXCP_KERNEL_TRAP); + dc->is_jmp = DISAS_EXC; + break; + } +#else + if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) { + /* We always get here via a jump, so know we are not in a + conditional execution block. */ + gen_exception_internal(EXCP_EXCEPTION_EXIT); + dc->is_jmp = DISAS_EXC; + break; + } +#endif + + if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { + CPUBreakpoint *bp; + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { + if (bp->pc == dc->pc) { + if (bp->flags & BP_CPU) { + gen_set_condexec(dc); + gen_set_pc_im(dc, dc->pc); + gen_helper_check_breakpoints(cpu_env); + /* End the TB early; it's likely not going to be executed */ + dc->is_jmp = DISAS_UPDATE; + } else { + gen_exception_internal_insn(dc, 0, EXCP_DEBUG); + /* The address covered by the breakpoint must be + included in [tb->pc, tb->pc + tb->size) in order + to for it to be properly cleared -- thus we + increment the PC here so that the logic setting + tb->size below does the right thing. */ + /* TODO: Advance PC by correct instruction length to + * avoid disassembler error messages */ + dc->pc += 2; + goto done_generating; + } + break; + } + } + } + + if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { + gen_io_start(); + } + + if (dc->ss_active && !dc->pstate_ss) { + /* Singlestep state is Active-pending. + * If we're in this state at the start of a TB then either + * a) we just took an exception to an EL which is being debugged + * and this is the first insn in the exception handler + * b) debug exceptions were masked and we just unmasked them + * without changing EL (eg by clearing PSTATE.D) + * In either case we're going to take a swstep exception in the + * "did not step an insn" case, and so the syndrome ISV and EX + * bits should be zero. + */ + assert(num_insns == 1); + gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0), + default_exception_el(dc)); + goto done_generating; + } + + if (dc->thumb) { + disas_thumb_insn(env, dc); + if (dc->condexec_mask) { + dc->condexec_cond = (dc->condexec_cond & 0xe) + | ((dc->condexec_mask >> 4) & 1); + dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f; + if (dc->condexec_mask == 0) { + dc->condexec_cond = 0; + } + } + } else { + unsigned int insn = arm_ldl_code(env, dc->pc, dc->bswap_code); + dc->pc += 4; + disas_arm_insn(dc, insn); + } + + if (dc->condjmp && !dc->is_jmp) { + gen_set_label(dc->condlabel); + dc->condjmp = 0; + } + + if (tcg_check_temp_count()) { + fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n", + dc->pc); + } + + /* Translation stops when a conditional branch is encountered. + * Otherwise the subsequent code could get translated several times. + * Also stop translation when a page boundary is reached. This + * ensures prefetch aborts occur at the right place. */ + + /* We want to stop the TB if the next insn starts in a new page, + * or if it spans between this page and the next. This means that + * if we're looking at the last halfword in the page we need to + * see if it's a 16-bit Thumb insn (which will fit in this TB) + * or a 32-bit Thumb insn (which won't). + * This is to avoid generating a silly TB with a single 16-bit insn + * in it at the end of this page (which would execute correctly + * but isn't very efficient). + */ + end_of_page = (dc->pc >= next_page_start) || + ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc)); + + } while (!dc->is_jmp && !tcg_op_buf_full() && + !cs->singlestep_enabled && + !singlestep && + !dc->ss_active && + !end_of_page && + num_insns < max_insns); + + if (tb->cflags & CF_LAST_IO) { + if (dc->condjmp) { + /* FIXME: This can theoretically happen with self-modifying + code. */ + cpu_abort(cs, "IO on conditional branch instruction"); + } + gen_io_end(); + } + + /* At this stage dc->condjmp will only be set when the skipped + instruction was a conditional branch or trap, and the PC has + already been written. */ + if (unlikely(cs->singlestep_enabled || dc->ss_active)) { + /* Make sure the pc is updated, and raise a debug exception. */ + if (dc->condjmp) { + gen_set_condexec(dc); + if (dc->is_jmp == DISAS_SWI) { + gen_ss_advance(dc); + gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), + default_exception_el(dc)); + } else if (dc->is_jmp == DISAS_HVC) { + gen_ss_advance(dc); + gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); + } else if (dc->is_jmp == DISAS_SMC) { + gen_ss_advance(dc); + gen_exception(EXCP_SMC, syn_aa32_smc(), 3); + } else if (dc->ss_active) { + gen_step_complete_exception(dc); + } else { + gen_exception_internal(EXCP_DEBUG); + } + gen_set_label(dc->condlabel); + } + if (dc->condjmp || dc->is_jmp == DISAS_NEXT || + dc->is_jmp == DISAS_UPDATE) { + gen_set_pc_im(dc, dc->pc); + dc->condjmp = 0; + } + gen_set_condexec(dc); + if (dc->is_jmp == DISAS_SWI && !dc->condjmp) { + gen_ss_advance(dc); + gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), + default_exception_el(dc)); + } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) { + gen_ss_advance(dc); + gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); + } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) { + gen_ss_advance(dc); + gen_exception(EXCP_SMC, syn_aa32_smc(), 3); + } else if (dc->ss_active) { + gen_step_complete_exception(dc); + } else { + /* FIXME: Single stepping a WFI insn will not halt + the CPU. */ + gen_exception_internal(EXCP_DEBUG); + } + } else { + /* While branches must always occur at the end of an IT block, + there are a few other things that can cause us to terminate + the TB in the middle of an IT block: + - Exception generating instructions (bkpt, swi, undefined). + - Page boundaries. + - Hardware watchpoints. + Hardware breakpoints have already been handled and skip this code. + */ + gen_set_condexec(dc); + switch(dc->is_jmp) { + case DISAS_NEXT: + gen_goto_tb(dc, 1, dc->pc); + break; + case DISAS_UPDATE: + gen_set_pc_im(dc, dc->pc); + /* fall through */ + case DISAS_JUMP: + default: + /* indicate that the hash table must be used to find the next TB */ + tcg_gen_exit_tb(0); + break; + case DISAS_TB_JUMP: + /* nothing more to generate */ + break; + case DISAS_WFI: + gen_helper_wfi(cpu_env); + /* The helper doesn't necessarily throw an exception, but we + * must go back to the main loop to check for interrupts anyway. + */ + tcg_gen_exit_tb(0); + break; + case DISAS_WFE: + gen_helper_wfe(cpu_env); + break; + case DISAS_YIELD: + gen_helper_yield(cpu_env); + break; + case DISAS_SWI: + gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), + default_exception_el(dc)); + break; + case DISAS_HVC: + gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); + break; + case DISAS_SMC: + gen_exception(EXCP_SMC, syn_aa32_smc(), 3); + break; + } + if (dc->condjmp) { + gen_set_label(dc->condlabel); + gen_set_condexec(dc); + gen_goto_tb(dc, 1, dc->pc); + dc->condjmp = 0; + } + } + +done_generating: + gen_tb_end(tb, num_insns); + +#ifdef DEBUG_DISAS + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + qemu_log("----------------\n"); + qemu_log("IN: %s\n", lookup_symbol(pc_start)); + log_target_disas(cs, pc_start, dc->pc - pc_start, + dc->thumb | (dc->bswap_code << 1)); + qemu_log("\n"); + } +#endif + tb->size = dc->pc - pc_start; + tb->icount = num_insns; +} + +static const char *cpu_mode_names[16] = { + "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt", + "???", "???", "hyp", "und", "???", "???", "???", "sys" +}; + +void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, + int flags) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + int i; + uint32_t psr; + const char *ns_status; + + if (is_a64(env)) { + aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags); + return; + } + + for(i=0;i<16;i++) { + cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]); + if ((i % 4) == 3) + cpu_fprintf(f, "\n"); + else + cpu_fprintf(f, " "); + } + psr = cpsr_read(env); + + if (arm_feature(env, ARM_FEATURE_EL3) && + (psr & CPSR_M) != ARM_CPU_MODE_MON) { + ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S "; + } else { + ns_status = ""; + } + + cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n", + psr, + psr & (1 << 31) ? 'N' : '-', + psr & (1 << 30) ? 'Z' : '-', + psr & (1 << 29) ? 'C' : '-', + psr & (1 << 28) ? 'V' : '-', + psr & CPSR_T ? 'T' : 'A', + ns_status, + cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26); + + if (flags & CPU_DUMP_FPU) { + int numvfpregs = 0; + if (arm_feature(env, ARM_FEATURE_VFP)) { + numvfpregs += 16; + } + if (arm_feature(env, ARM_FEATURE_VFP3)) { + numvfpregs += 16; + } + for (i = 0; i < numvfpregs; i++) { + uint64_t v = float64_val(env->vfp.regs[i]); + cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n", + i * 2, (uint32_t)v, + i * 2 + 1, (uint32_t)(v >> 32), + i, v); + } + cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); + } + + /* When doing the 'mon info registers' command, we get passed the CPU_DUMP_FPU flag. + * There is not flag for supervisor registers, but include those if asked for the FPU + * registers */ + if (flags & CPU_DUMP_FPU) { + cpu_fprintf(f, "xPSR: %08x\n", xpsr_read(env)); + cpu_fprintf(f, "MSP: %08x\n", + env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]); + cpu_fprintf(f, "PSP: %08x\n", + env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp); + cpu_fprintf(f, "PRIMASK: %08x\n", (env->daif & PSTATE_I) != 0); + cpu_fprintf(f, "BASEPRI: %08x\n", env->v7m.basepri); + cpu_fprintf(f, "FAULTMASK: %08x\n", (env->daif & PSTATE_F) != 0); + cpu_fprintf(f, "CONTROL: %08x\n", env->v7m.control); + } +} + +void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, + target_ulong *data) +{ + if (is_a64(env)) { + env->pc = data[0]; + env->condexec_bits = 0; + } else { + env->regs[15] = data[0]; + env->condexec_bits = data[1]; + } +} diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000000000..2e15eca3c5b07 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,674 @@ +export SRC_PATH + +qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py + +# Get the list of all supported sysemu targets +SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \ + $(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak))) + +check-unit-y = tests/check-qdict$(EXESUF) +gcov-files-check-qdict-y = qobject/qdict.c +check-unit-y += tests/check-qfloat$(EXESUF) +gcov-files-check-qfloat-y = qobject/qfloat.c +check-unit-y += tests/check-qint$(EXESUF) +gcov-files-check-qint-y = qobject/qint.c +check-unit-y += tests/check-qstring$(EXESUF) +gcov-files-check-qstring-y = qobject/qstring.c +check-unit-y += tests/check-qlist$(EXESUF) +gcov-files-check-qlist-y = qobject/qlist.c +check-unit-y += tests/check-qjson$(EXESUF) +gcov-files-check-qjson-y = qobject/qjson.c +check-unit-y += tests/test-qmp-output-visitor$(EXESUF) +gcov-files-test-qmp-output-visitor-y = qapi/qmp-output-visitor.c +check-unit-y += tests/test-qmp-input-visitor$(EXESUF) +gcov-files-test-qmp-input-visitor-y = qapi/qmp-input-visitor.c +check-unit-y += tests/test-qmp-input-strict$(EXESUF) +check-unit-y += tests/test-qmp-commands$(EXESUF) +gcov-files-test-qmp-commands-y = qapi/qmp-dispatch.c +check-unit-y += tests/test-string-input-visitor$(EXESUF) +gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c +check-unit-y += tests/test-string-output-visitor$(EXESUF) +gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c +check-unit-y += tests/test-qmp-event$(EXESUF) +gcov-files-test-qmp-event-y += qapi/qmp-event.c +check-unit-y += tests/test-opts-visitor$(EXESUF) +gcov-files-test-opts-visitor-y = qapi/opts-visitor.c +check-unit-y += tests/test-coroutine$(EXESUF) +gcov-files-test-coroutine-y = coroutine-$(CONFIG_COROUTINE_BACKEND).c +check-unit-y += tests/test-visitor-serialization$(EXESUF) +check-unit-y += tests/test-iov$(EXESUF) +gcov-files-test-iov-y = util/iov.c +check-unit-y += tests/test-aio$(EXESUF) +check-unit-$(CONFIG_POSIX) += tests/test-rfifolock$(EXESUF) +check-unit-y += tests/test-throttle$(EXESUF) +gcov-files-test-aio-$(CONFIG_WIN32) = aio-win32.c +gcov-files-test-aio-$(CONFIG_POSIX) = aio-posix.c +check-unit-y += tests/test-thread-pool$(EXESUF) +gcov-files-test-thread-pool-y = thread-pool.c +gcov-files-test-hbitmap-y = util/hbitmap.c +check-unit-y += tests/test-hbitmap$(EXESUF) +gcov-files-test-hbitmap-y = blockjob.c +check-unit-y += tests/test-blockjob-txn$(EXESUF) +check-unit-y += tests/test-x86-cpuid$(EXESUF) +# all code tested by test-x86-cpuid is inside topology.h +gcov-files-test-x86-cpuid-y = +ifeq ($(CONFIG_SOFTMMU),y) +check-unit-y += tests/test-xbzrle$(EXESUF) +gcov-files-test-xbzrle-y = migration/xbzrle.c +check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF) +endif +check-unit-y += tests/test-cutils$(EXESUF) +gcov-files-test-cutils-y += util/cutils.c +check-unit-y += tests/test-mul64$(EXESUF) +gcov-files-test-mul64-y = util/host-utils.c +check-unit-y += tests/test-int128$(EXESUF) +# all code tested by test-int128 is inside int128.h +gcov-files-test-int128-y = +check-unit-y += tests/rcutorture$(EXESUF) +gcov-files-rcutorture-y = util/rcu.c +check-unit-y += tests/test-rcu-list$(EXESUF) +gcov-files-test-rcu-list-y = util/rcu.c +check-unit-y += tests/test-bitops$(EXESUF) +check-unit-$(CONFIG_HAS_GLIB_SUBPROCESS_TESTS) += tests/test-qdev-global-props$(EXESUF) +check-unit-y += tests/check-qom-interface$(EXESUF) +gcov-files-check-qom-interface-y = qom/object.c +check-unit-y += tests/check-qom-proplist$(EXESUF) +gcov-files-check-qom-proplist-y = qom/object.c +check-unit-y += tests/test-qemu-opts$(EXESUF) +gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c +check-unit-y += tests/test-write-threshold$(EXESUF) +gcov-files-test-write-threshold-y = block/write-threshold.c +check-unit-$(CONFIG_GNUTLS_HASH) += tests/test-crypto-hash$(EXESUF) +check-unit-y += tests/test-crypto-cipher$(EXESUF) +check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF) +check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF) +check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF) +check-unit-y += tests/test-timed-average$(EXESUF) + +check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh + +# All QTests for now are POSIX-only, but the dependencies are +# really in libqtest, not in the testcases themselves. + +check-qtest-generic-y = tests/device-introspect-test$(EXESUF) +gcov-files-generic-y = qdev-monitor.c qmp.c + +gcov-files-ipack-y += hw/ipack/ipack.c +check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF) +gcov-files-ipack-y += hw/char/ipoctal232.c + +check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF) +gcov-files-virtioserial-y += hw/char/virtio-console.c + +gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c +check-qtest-virtio-y += tests/virtio-net-test$(EXESUF) +gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c +check-qtest-virtio-y += tests/virtio-balloon-test$(EXESUF) +gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio-balloon.c +check-qtest-virtio-y += tests/virtio-blk-test$(EXESUF) +gcov-files-virtio-y += i386-softmmu/hw/block/virtio-blk.c +check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF) +gcov-files-virtio-y += hw/virtio/virtio-rng.c +check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF) +gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c +ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) +check-qtest-virtio-y += tests/virtio-9p-test$(EXESUF) +gcov-files-virtio-y += hw/9pfs/virtio-9p.c +gcov-files-virtio-y += i386-softmmu/hw/9pfs/virtio-9p-device.c +endif +check-qtest-virtio-y += tests/virtio-serial-test$(EXESUF) +gcov-files-virtio-y += i386-softmmu/hw/char/virtio-serial-bus.c +check-qtest-virtio-y += $(check-qtest-virtioserial-y) +gcov-files-virtio-y += $(gcov-files-virtioserial-y) + +check-qtest-pci-y += tests/e1000-test$(EXESUF) +gcov-files-pci-y += hw/net/e1000.c +check-qtest-pci-y += tests/rtl8139-test$(EXESUF) +gcov-files-pci-y += hw/net/rtl8139.c +check-qtest-pci-y += tests/pcnet-test$(EXESUF) +gcov-files-pci-y += hw/net/pcnet.c +gcov-files-pci-y += hw/net/pcnet-pci.c +check-qtest-pci-y += tests/eepro100-test$(EXESUF) +gcov-files-pci-y += hw/net/eepro100.c +check-qtest-pci-y += tests/ne2000-test$(EXESUF) +gcov-files-pci-y += hw/net/ne2000.c +check-qtest-pci-y += tests/nvme-test$(EXESUF) +gcov-files-pci-y += hw/block/nvme.c +check-qtest-pci-y += tests/ac97-test$(EXESUF) +gcov-files-pci-y += hw/audio/ac97.c +check-qtest-pci-y += tests/es1370-test$(EXESUF) +gcov-files-pci-y += hw/audio/es1370.c +check-qtest-pci-y += $(check-qtest-virtio-y) +gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c +check-qtest-pci-y += tests/tpci200-test$(EXESUF) +gcov-files-pci-y += hw/ipack/tpci200.c +check-qtest-pci-y += $(check-qtest-ipack-y) +gcov-files-pci-y += $(gcov-files-ipack-y) +check-qtest-pci-y += tests/display-vga-test$(EXESUF) +gcov-files-pci-y += hw/display/vga.c +gcov-files-pci-y += hw/display/cirrus_vga.c +gcov-files-pci-y += hw/display/vga-pci.c +gcov-files-pci-y += hw/display/virtio-gpu.c +gcov-files-pci-y += hw/display/virtio-gpu-pci.c +gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c +check-qtest-pci-y += tests/intel-hda-test$(EXESUF) +gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c +check-qtest-pci-$(CONFIG_POSIX) += tests/ivshmem-test$(EXESUF) +gcov-files-pci-y += hw/misc/ivshmem.c + +check-qtest-i386-y = tests/endianness-test$(EXESUF) +check-qtest-i386-y += tests/fdc-test$(EXESUF) +gcov-files-i386-y = hw/block/fdc.c +check-qtest-i386-y += tests/ide-test$(EXESUF) +check-qtest-i386-y += tests/ahci-test$(EXESUF) +check-qtest-i386-y += tests/hd-geo-test$(EXESUF) +gcov-files-i386-y += hw/block/hd-geometry.c +check-qtest-i386-y += tests/boot-order-test$(EXESUF) +check-qtest-i386-y += tests/bios-tables-test$(EXESUF) +check-qtest-i386-y += tests/rtc-test$(EXESUF) +check-qtest-i386-y += tests/i440fx-test$(EXESUF) +check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) +check-qtest-i386-y += tests/drive_del-test$(EXESUF) +check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF) +check-qtest-i386-y += tests/tco-test$(EXESUF) +gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c +check-qtest-i386-y += $(check-qtest-pci-y) +gcov-files-i386-y += $(gcov-files-pci-y) +check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) +gcov-files-i386-y += hw/net/vmxnet3.c +gcov-files-i386-y += hw/net/vmxnet_rx_pkt.c +gcov-files-i386-y += hw/net/vmxnet_tx_pkt.c +check-qtest-i386-y += tests/pvpanic-test$(EXESUF) +gcov-files-i386-y += i386-softmmu/hw/misc/pvpanic.c +check-qtest-i386-y += tests/i82801b11-test$(EXESUF) +gcov-files-i386-y += hw/pci-bridge/i82801b11.c +check-qtest-i386-y += tests/ioh3420-test$(EXESUF) +gcov-files-i386-y += hw/pci-bridge/ioh3420.c +check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF) +gcov-files-i386-y += hw/usb/hcd-ohci.c +check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF) +gcov-files-i386-y += hw/usb/hcd-uhci.c +check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF) +gcov-files-i386-y += hw/usb/hcd-ehci.c +gcov-files-i386-y += hw/usb/dev-hid.c +gcov-files-i386-y += hw/usb/dev-storage.c +check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF) +gcov-files-i386-y += hw/usb/hcd-xhci.c +check-qtest-i386-y += tests/pc-cpu-test$(EXESUF) +check-qtest-i386-y += tests/q35-test$(EXESUF) +gcov-files-i386-y += hw/pci-host/q35.c +check-qtest-i386-$(CONFIG_VHOST_NET_TEST_i386) += tests/vhost-user-test$(EXESUF) +ifeq ($(CONFIG_VHOST_NET_TEST_i386),) +check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += tests/vhost-user-test$(EXESUF) +endif +check-qtest-i386-y += tests/test-netfilter$(EXESUF) +check-qtest-x86_64-y = $(check-qtest-i386-y) +gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c +gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) +check-qtest-mips-y = tests/endianness-test$(EXESUF) +check-qtest-mips64-y = tests/endianness-test$(EXESUF) +check-qtest-mips64el-y = tests/endianness-test$(EXESUF) +check-qtest-ppc-y = tests/endianness-test$(EXESUF) +check-qtest-ppc64-y = tests/endianness-test$(EXESUF) +check-qtest-sh4-y = tests/endianness-test$(EXESUF) +check-qtest-sh4eb-y = tests/endianness-test$(EXESUF) +check-qtest-sparc64-y = tests/endianness-test$(EXESUF) +#check-qtest-sparc-y = tests/m48t59-test$(EXESUF) +#check-qtest-sparc64-y += tests/m48t59-test$(EXESUF) +gcov-files-sparc-y += hw/timer/m48t59.c +gcov-files-sparc64-y += hw/timer/m48t59.c +check-qtest-arm-y = tests/tmp105-test$(EXESUF) +gcov-files-arm-y += hw/misc/tmp105.c +check-qtest-arm-y += tests/ds1338-test$(EXESUF) +check-qtest-arm-y += tests/test-stm32$(EXESUF) +check-qtest-arm-y += tests/virtio-blk-test$(EXESUF) +gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c +check-qtest-ppc-y += tests/boot-order-test$(EXESUF) +check-qtest-ppc64-y += tests/boot-order-test$(EXESUF) +check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF) +gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c +check-qtest-microblazeel-y = $(check-qtest-microblaze-y) +check-qtest-xtensaeb-y = $(check-qtest-xtensa-y) + +check-qtest-generic-y += tests/qom-test$(EXESUF) + +qapi-schema += alternate-array.json +qapi-schema += alternate-base.json +qapi-schema += alternate-clash.json +qapi-schema += alternate-conflict-dict.json +qapi-schema += alternate-conflict-string.json +qapi-schema += alternate-empty.json +qapi-schema += alternate-nested.json +qapi-schema += alternate-unknown.json +qapi-schema += args-alternate.json +qapi-schema += args-any.json +qapi-schema += args-array-empty.json +qapi-schema += args-array-unknown.json +qapi-schema += args-int.json +qapi-schema += args-invalid.json +qapi-schema += args-member-array-bad.json +qapi-schema += args-member-unknown.json +qapi-schema += args-name-clash.json +qapi-schema += args-union.json +qapi-schema += args-unknown.json +qapi-schema += bad-base.json +qapi-schema += bad-data.json +qapi-schema += bad-ident.json +qapi-schema += bad-type-bool.json +qapi-schema += bad-type-dict.json +qapi-schema += bad-type-int.json +qapi-schema += command-int.json +qapi-schema += comments.json +qapi-schema += double-data.json +qapi-schema += double-type.json +qapi-schema += duplicate-key.json +qapi-schema += empty.json +qapi-schema += enum-bad-name.json +qapi-schema += enum-bad-prefix.json +qapi-schema += enum-clash-member.json +qapi-schema += enum-dict-member.json +qapi-schema += enum-int-member.json +qapi-schema += enum-max-member.json +qapi-schema += enum-missing-data.json +qapi-schema += enum-wrong-data.json +qapi-schema += escape-outside-string.json +qapi-schema += escape-too-big.json +qapi-schema += escape-too-short.json +qapi-schema += event-case.json +qapi-schema += event-max.json +qapi-schema += event-nest-struct.json +qapi-schema += flat-union-array-branch.json +qapi-schema += flat-union-bad-base.json +qapi-schema += flat-union-bad-discriminator.json +qapi-schema += flat-union-base-any.json +qapi-schema += flat-union-base-union.json +qapi-schema += flat-union-clash-branch.json +qapi-schema += flat-union-clash-member.json +qapi-schema += flat-union-clash-type.json +qapi-schema += flat-union-empty.json +qapi-schema += flat-union-inline.json +qapi-schema += flat-union-int-branch.json +qapi-schema += flat-union-invalid-branch-key.json +qapi-schema += flat-union-invalid-discriminator.json +qapi-schema += flat-union-no-base.json +qapi-schema += flat-union-optional-discriminator.json +qapi-schema += flat-union-string-discriminator.json +qapi-schema += funny-char.json +qapi-schema += ident-with-escape.json +qapi-schema += include-before-err.json +qapi-schema += include-cycle.json +qapi-schema += include-format-err.json +qapi-schema += include-nested-err.json +qapi-schema += include-no-file.json +qapi-schema += include-non-file.json +qapi-schema += include-relpath.json +qapi-schema += include-repetition.json +qapi-schema += include-self-cycle.json +qapi-schema += include-simple.json +qapi-schema += indented-expr.json +qapi-schema += leading-comma-list.json +qapi-schema += leading-comma-object.json +qapi-schema += missing-colon.json +qapi-schema += missing-comma-list.json +qapi-schema += missing-comma-object.json +qapi-schema += missing-type.json +qapi-schema += nested-struct-data.json +qapi-schema += non-objects.json +qapi-schema += qapi-schema-test.json +qapi-schema += quoted-structural-chars.json +qapi-schema += redefined-builtin.json +qapi-schema += redefined-command.json +qapi-schema += redefined-event.json +qapi-schema += redefined-type.json +qapi-schema += reserved-command-q.json +qapi-schema += reserved-member-has.json +qapi-schema += reserved-member-q.json +qapi-schema += reserved-member-u.json +qapi-schema += reserved-type-kind.json +qapi-schema += reserved-type-list.json +qapi-schema += returns-alternate.json +qapi-schema += returns-array-bad.json +qapi-schema += returns-dict.json +qapi-schema += returns-unknown.json +qapi-schema += returns-whitelist.json +qapi-schema += struct-base-clash-deep.json +qapi-schema += struct-base-clash.json +qapi-schema += struct-data-invalid.json +qapi-schema += struct-member-invalid.json +qapi-schema += trailing-comma-list.json +qapi-schema += trailing-comma-object.json +qapi-schema += type-bypass-bad-gen.json +qapi-schema += unclosed-list.json +qapi-schema += unclosed-object.json +qapi-schema += unclosed-string.json +qapi-schema += unicode-str.json +qapi-schema += union-bad-branch.json +qapi-schema += union-base-no-discriminator.json +qapi-schema += union-clash-branches.json +qapi-schema += union-clash-data.json +qapi-schema += union-clash-type.json +qapi-schema += union-empty.json +qapi-schema += union-invalid-base.json +qapi-schema += union-max.json +qapi-schema += union-optional-branch.json +qapi-schema += union-unknown.json +qapi-schema += unknown-escape.json +qapi-schema += unknown-expr-key.json +check-qapi-schema-y := $(addprefix tests/qapi-schema/, $(qapi-schema)) + +GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \ + tests/test-qmp-commands.h tests/test-qapi-event.h \ + tests/test-qmp-introspect.h + +test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ + tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \ + tests/test-coroutine.o tests/test-string-output-visitor.o \ + tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \ + tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ + tests/test-qmp-commands.o tests/test-visitor-serialization.o \ + tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \ + tests/test-opts-visitor.o tests/test-qmp-event.o \ + tests/rcutorture.o tests/test-rcu-list.o + +$(test-obj-y): QEMU_INCLUDES += -Itests +QEMU_CFLAGS += -I$(SRC_PATH)/tests + + +# Deps that are common to various different sets of tests below +test-util-obj-y = libqemuutil.a libqemustub.a +test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y) +test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \ + tests/test-qapi-event.o tests/test-qmp-introspect.o \ + $(test-qom-obj-y) +test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y) +test-block-obj-y = $(block-obj-y) $(test-crypto-obj-y) + +tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y) +tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y) +tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y) +tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y) +tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y) +tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y) +tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) +tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y) +tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y) +tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y) +tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o $(test-util-obj-y) +tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y) +tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y) +tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y) +tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y) +tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) +tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o +tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o page_cache.o $(test-util-obj-y) +tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o +tests/test-int128$(EXESUF): tests/test-int128.o +tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y) +tests/test-rcu-list$(EXESUF): tests/test-rcu-list.o $(test-util-obj-y) + +tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ + hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\ + hw/core/irq.o \ + hw/core/fw-path-provider.o \ + $(test-qapi-obj-y) +tests/test-vmstate$(EXESUF): tests/test-vmstate.o \ + migration/vmstate.o migration/qemu-file.o migration/qemu-file-buf.o \ + migration/qemu-file-unix.o qjson.o \ + $(test-qom-obj-y) +tests/test-timed-average$(EXESUF): tests/test-timed-average.o qemu-timer.o \ + $(test-util-obj-y) + +tests/test-qapi-types.c tests/test-qapi-types.h :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \ + $(gen-out-type) -o tests -p "test-" $<, \ + " GEN $@") +tests/test-qapi-visit.c tests/test-qapi-visit.h :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \ + $(gen-out-type) -o tests -p "test-" $<, \ + " GEN $@") +tests/test-qmp-commands.h tests/test-qmp-marshal.c :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \ + $(gen-out-type) -o tests -p "test-" $<, \ + " GEN $@") +tests/test-qapi-event.c tests/test-qapi-event.h :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \ + $(gen-out-type) -o tests -p "test-" $<, \ + " GEN $@") +tests/test-qmp-introspect.c tests/test-qmp-introspect.h :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-introspect.py \ + $(gen-out-type) -o tests -p "test-" $<, \ + " GEN $@") + +tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) +tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) +tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) +tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) +tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) +tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) +tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) +tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) +tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) + +tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y) +tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y) +tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y) +tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y) + +tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS) +tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS) +tests/pkix_asn1_tab.o-cflags := $(TASN1_CFLAGS) + +tests/test-crypto-tlscredsx509.o-cflags := $(TASN1_CFLAGS) +tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \ + tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) + +tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS) +tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \ + tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) + +libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o +libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o +libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o +libqos-pc-obj-y += tests/libqos/malloc-pc.o tests/libqos/libqos-pc.o +libqos-pc-obj-y += tests/libqos/ahci.o +libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o +libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o +libqos-usb-obj-y = $(libqos-pc-obj-y) tests/libqos/usb.o +libqos-virtio-obj-y = $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o + +tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o +tests/rtc-test$(EXESUF): tests/rtc-test.o +tests/m48t59-test$(EXESUF): tests/m48t59-test.o +tests/endianness-test$(EXESUF): tests/endianness-test.o +tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) +tests/fdc-test$(EXESUF): tests/fdc-test.o +tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y) +tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) +tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o +tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y) +tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o $(libqos-obj-y) +tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) +tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y) +tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y) +tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y) +tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) +tests/e1000-test$(EXESUF): tests/e1000-test.o +tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y) +tests/pcnet-test$(EXESUF): tests/pcnet-test.o +tests/eepro100-test$(EXESUF): tests/eepro100-test.o +tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o +tests/ne2000-test$(EXESUF): tests/ne2000-test.o +tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o +tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y) +tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o +tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o $(libqos-virtio-obj-y) +tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o $(libqos-pc-obj-y) $(libqos-virtio-obj-y) +tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o $(libqos-pc-obj-y) +tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y) +tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o +tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o +tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o +tests/tpci200-test$(EXESUF): tests/tpci200-test.o +tests/display-vga-test$(EXESUF): tests/display-vga-test.o +tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o +tests/qom-test$(EXESUF): tests/qom-test.o +tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-pc-obj-y) +tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y) +tests/nvme-test$(EXESUF): tests/nvme-test.o +tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o +tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o +tests/ac97-test$(EXESUF): tests/ac97-test.o +tests/es1370-test$(EXESUF): tests/es1370-test.o +tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o +tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o +tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) +tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y) +tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y) +tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y) +tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o +tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) +tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o +tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y) +tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y) +tests/test-stm32$(EXESUF): tests/test-stm32.o +tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y) +tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) +tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o + +ifeq ($(CONFIG_POSIX),y) +LIBS += -lutil +endif + +# QTest rules + +TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS))) +ifeq ($(CONFIG_POSIX),y) +QTEST_TARGETS = $(TARGETS) +check-qtest-y=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) +check-qtest-y += $(check-qtest-generic-y) +else +QTEST_TARGETS = +endif + +qtest-obj-y = tests/libqtest.o $(test-util-obj-y) +$(check-qtest-y): $(qtest-obj-y) + +tests/test-qga: tests/test-qga.o $(qtest-obj-y) + +.PHONY: check-help +check-help: + @echo "Regression testing targets:" + @echo + @echo " make check Run all tests" + @echo " make check-qtest-TARGET Run qtest tests for given target" + @echo " make check-qtest Run qtest tests" + @echo " make check-unit Run qobject tests" + @echo " make check-qapi-schema Run QAPI schema tests" + @echo " make check-block Run block tests" + @echo " make check-report.html Generates an HTML test report" + @echo " make check-clean Clean the tests" + @echo + @echo "Please note that HTML reports do not regenerate if the unit tests" + @echo "has not changed." + @echo + @echo "The variable SPEED can be set to control the gtester speed setting." + @echo "Default options are -k and (for make V=1) --verbose; they can be" + @echo "changed with variable GTESTER_OPTIONS." + +SPEED = quick +GTESTER_OPTIONS = -k $(if $(V),--verbose,-q) +GCOV_OPTIONS = -n $(if $(V),-f,) + +# gtester tests, possibly with verbose output + +.PHONY: $(patsubst %, check-qtest-%, $(QTEST_TARGETS)) +$(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y) + $(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,) + $(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \ + QTEST_QEMU_IMG=qemu-img$(EXESUF) \ + MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \ + gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y) $(check-qtest-generic-y),"GTESTER $@") + $(if $(CONFIG_GCOV),@for f in $(gcov-files-$*-y) $(gcov-files-generic-y); do \ + echo Gcov report for $$f:;\ + $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \ + done,) + +.PHONY: $(patsubst %, check-%, $(check-unit-y)) +$(patsubst %, check-%, $(check-unit-y)): check-%: % + $(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,) + $(call quiet-command, \ + MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \ + gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*") + $(if $(CONFIG_GCOV),@for f in $(gcov-files-$(subst tests/,,$*)-y) $(gcov-files-generic-y); do \ + echo Gcov report for $$f:;\ + $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \ + done,) + +# gtester tests with XML output + +$(patsubst %, check-report-qtest-%.xml, $(QTEST_TARGETS)): check-report-qtest-%.xml: $(check-qtest-y) + $(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \ + QTEST_QEMU_IMG=qemu-img$(EXESUF) \ + gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $(check-qtest-$*-y) $(check-qtest-generic-y),"GTESTER $@") + +check-report-unit.xml: $(check-unit-y) + $(call quiet-command,gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $^, "GTESTER $@") + +# Reports and overall runs + +check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check-report-unit.xml + $(call quiet-command,$(SRC_PATH)/scripts/gtester-cat $^ > $@, " GEN $@") + +check-report.html: check-report.xml + $(call quiet-command,gtester-report $< > $@, " GEN $@") + + +# Other tests + +QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = tests/qemu-iotests/socket_scm_helper$(EXESUF) + +.PHONY: check-tests/qemu-iotests-quick.sh +check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) $(QEMU_IOTESTS_HELPERS-y) + $< + +.PHONY: check-tests/test-qapi.py +check-tests/test-qapi.py: tests/test-qapi.py + +.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y)) +$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json + $(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \ + $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \ + $^ >$*.test.out 2>$*.test.err; \ + echo $$? >$*.test.exit, \ + " TEST $*.out") + @diff -q $(SRC_PATH)/$*.out $*.test.out + @# Sanitize error messages (make them independent of build directory) + @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -q $(SRC_PATH)/$*.err - + @diff -q $(SRC_PATH)/$*.exit $*.test.exit + +# Consolidated targets + +.PHONY: check-qapi-schema check-qtest check-unit check check-clean +check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y)) +check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS)) +check-unit: $(patsubst %,check-%, $(check-unit-y)) +check-block: $(patsubst %,check-%, $(check-block-y)) +check: check-qapi-schema check-unit check-qtest +check-clean: + $(MAKE) -C tests/tcg clean + rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y) + rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), $(check-qtest-$(target)-y)) $(check-qtest-generic-y)) + +clean: check-clean + +# Build the help program automatically + +all: $(QEMU_IOTESTS_HELPERS-y) + +-include $(wildcard tests/*.d) +-include $(wildcard tests/libqos/*.d) diff --git a/tests/libqtest.c b/tests/libqtest.c new file mode 100644 index 0000000000000..da212d2efde06 --- /dev/null +++ b/tests/libqtest.c @@ -0,0 +1,1060 @@ +/* + * QTest + * + * Copyright IBM, Corp. 2012 + * Copyright Red Hat, Inc. 2012 + * Copyright SUSE LINUX Products GmbH 2013 + * + * Authors: + * Anthony Liguori + * Paolo Bonzini + * Andreas Färber + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#include "libqtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qemu/compiler.h" +#include "qemu/osdep.h" +#include "qapi/qmp/json-parser.h" +#include "qapi/qmp/json-streamer.h" +#include "qapi/qmp/qjson.h" + +#define MAX_GPIO_INTERCEPTS 20 +#define MAX_IRQ 256 +#define SOCKET_TIMEOUT 5 + +QTestState *global_qtest; + +typedef struct SocketInfo +{ + int sock; + int fd; + const char *path; +} SocketInfo; + + +struct QTestState +{ + bool irq_level[MAX_GPIO_INTERCEPTS][MAX_IRQ]; + GString *rx; + pid_t qemu_pid; /* our child QEMU process */ + + // beckus - stm32 specific stuff + /////////////////////////////////////////////// + gpio_id last_intercept_gpio_id; + + // replaces the fd member in upstread + SocketInfo qtest_socket; + // replaces the qmp_fd member in upstream + SocketInfo qmp_socket; + + int num_serial_ports; + SocketInfo *serial_port_sockets; +}; + +static GHookList abrt_hooks; +static GList *qtest_instances; +static struct sigaction sigact_old; + +#define g_assert_no_errno(ret) do { \ + g_assert_cmpint(ret, !=, -1); \ +} while (0) + +static gchar *get_temp_file_path(const gchar *name) +{ + return g_strdup_printf("/tmp/qtest-%d.%s", getpid(), name); +} + +static void init_socket(SocketInfo *socket_info) +{ + struct sockaddr_un addr; + int sock; + int ret; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + g_assert_no_errno(sock); + + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socket_info->path); + qemu_set_cloexec(sock); + + do { + ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)); + } while (ret == -1 && errno == EINTR); + g_assert_no_errno(ret); + ret = listen(sock, 1); + g_assert_no_errno(ret); + + socket_info->sock = sock; +} + +static void socket_accept(SocketInfo *socket_info) +{ + struct sockaddr_un addr; + socklen_t addrlen; + int sock = socket_info->sock; + int ret; + struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT, + .tv_usec = 0 }; + + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, + sizeof(timeout)); + + do { + addrlen = sizeof(addr); + ret = accept(sock, (struct sockaddr *)&addr, &addrlen); + } while (ret == -1 && errno == EINTR); + if (ret == -1) { + fprintf(stderr, "%s failed: %s\n", __func__, strerror(errno)); + } + close(sock); + + socket_info->fd = ret; +} + +static void kill_qemu(QTestState *s) +{ + if (s->qemu_pid != -1) { + kill(s->qemu_pid, SIGTERM); + waitpid(s->qemu_pid, NULL, 0); + } +} + +static void kill_qemu_hook_func(void *s) +{ + kill_qemu(s); +} + +static void sigabrt_handler(int signo) +{ + g_hook_list_invoke(&abrt_hooks, FALSE); +} + +static void setup_sigabrt_handler(void) +{ + struct sigaction sigact; + + /* Catch SIGABRT to clean up on g_assert() failure */ + sigact = (struct sigaction){ + .sa_handler = sigabrt_handler, + .sa_flags = SA_RESETHAND, + }; + sigemptyset(&sigact.sa_mask); + sigaction(SIGABRT, &sigact, &sigact_old); +} + +static void cleanup_sigabrt_handler(void) +{ + sigaction(SIGABRT, &sigact_old, NULL); +} + +void qtest_add_abrt_handler(GHookFunc fn, const void *data) +{ + GHook *hook; + + /* Only install SIGABRT handler once */ + if (!abrt_hooks.is_setup) { + g_hook_list_init(&abrt_hooks, sizeof(GHook)); + setup_sigabrt_handler(); + } + + hook = g_hook_alloc(&abrt_hooks); + hook->func = fn; + hook->data = (void *)data; + + g_hook_prepend(&abrt_hooks, hook); +} + +QTestState *qtest_init(const char *extra_args, int num_serial_ports) +{ + QTestState *s; + int i, j; + gchar *command; + GString *extra_socket_args; + const char *qemu_binary, *external_args, *qtest_log_path; + + qemu_binary = getenv("QTEST_QEMU_BINARY"); + g_assert(qemu_binary != NULL); + + external_args = getenv("QTEST_QEMU_ARGS"); + qtest_log_path = getenv("QTEST_LOG_FILE"); + + s = g_malloc(sizeof(*s)); + + s->qtest_socket.path = get_temp_file_path("sock"); + s->qmp_socket.path = get_temp_file_path("qmp"); + + init_socket(&s->qtest_socket); + init_socket(&s->qmp_socket); + + qtest_add_abrt_handler(kill_qemu_hook_func, s); + + s->num_serial_ports = num_serial_ports; + s->serial_port_sockets = g_malloc(num_serial_ports * sizeof(SocketInfo)); + extra_socket_args = g_string_new(""); + for(i = 0; i < num_serial_ports; i++) { + gchar *serial_socket_path; + gchar *socket_name = g_strdup_printf("serial%d", i); + serial_socket_path = get_temp_file_path(socket_name); + s->serial_port_sockets[i].path = serial_socket_path; + g_string_append_printf(extra_socket_args, + "-serial unix:%s,nowait ", + serial_socket_path); + init_socket(&s->serial_port_sockets[i]); + } + + s->qemu_pid = fork(); + if (s->qemu_pid == 0) { + setenv("QEMU_AUDIO_DRV", "none", true); + command = g_strdup_printf("exec %s " + "-qtest unix:%s,nowait " + "-qtest-log %s " + "-qmp unix:%s,nowait " + "-machine accel=qtest " + "-display none " + "%s " + "%s " + "%s", + qemu_binary, + s->qtest_socket.path, + qtest_log_path ?: "/dev/null", + s->qmp_socket.path, + extra_socket_args->str, + extra_args ?: "", + external_args ?: ""); + //printf("%s\n", command); + execlp("/bin/sh", "sh", "-c", command, NULL); + exit(1); + } + + socket_accept(&s->qtest_socket); + socket_accept(&s->qmp_socket); + for(i = 0; i < num_serial_ports; i++) { + socket_accept(&s->serial_port_sockets[i]); + } + + s->rx = g_string_new(""); + + s->last_intercept_gpio_id = -1; + for(i = 0; i < MAX_GPIO_INTERCEPTS; i++) { + for (j = 0; j < MAX_IRQ; j++) { + s->irq_level[i][j] = false; + } + } + + + /* Read the QMP greeting and then do the handshake */ + qtest_qmp_discard_response(s, ""); + qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }"); + + if (getenv("QTEST_STOP")) { + kill(s->qemu_pid, SIGSTOP); + } + + g_string_free(extra_socket_args, true); + + return s; +} + +void qtest_quit(QTestState *s) +{ + int i; + + qtest_instances = g_list_remove(qtest_instances, s); + g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s)); + + /* Uninstall SIGABRT handler on last instance */ + if (!qtest_instances) { + cleanup_sigabrt_handler(); + } + + kill_qemu(s); + unlink(s->qtest_socket.path); + unlink(s->qmp_socket.path); + close(s->qtest_socket.fd); + close(s->qmp_socket.fd); + for(i = 0; i < s->num_serial_ports; i++) { + unlink(s->serial_port_sockets[i].path); + } + g_free(s->serial_port_sockets); + g_string_free(s->rx, true); + g_free(s); +} + +static void socket_send(int fd, const char *buf, size_t size) +{ + size_t offset; + + offset = 0; + while (offset < size) { + ssize_t len; + + len = write(fd, buf + offset, size - offset); + if (len == -1 && errno == EINTR) { + continue; + } + + g_assert_no_errno(len); + g_assert_cmpint(len, >, 0); + + offset += len; + } +} + +static void socket_sendf(int fd, const char *fmt, va_list ap) +{ + gchar *str = g_strdup_vprintf(fmt, ap); + size_t size = strlen(str); + + socket_send(fd, str, size); + g_free(str); +} + +static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + socket_sendf(s->qtest_socket.fd, fmt, ap); + va_end(ap); +} + +static GString *qtest_recv_line(QTestState *s) +{ + GString *line; + size_t offset; + char *eol; + + while ((eol = strchr(s->rx->str, '\n')) == NULL) { + ssize_t len; + char buffer[1024]; + + len = read(s->qtest_socket.fd, buffer, sizeof(buffer)); + if (len == -1 && errno == EINTR) { + continue; + } + + if (len == -1 || len == 0) { + fprintf(stderr, "Broken pipe\n"); + exit(1); + } + + g_string_append_len(s->rx, buffer, len); + } + + offset = eol - s->rx->str; + line = g_string_new_len(s->rx->str, offset); + g_string_erase(s->rx, 0, offset + 1); + + return line; +} + +static gchar **qtest_rsp(QTestState *s, int expected_args) +{ + GString *line; + gchar **words; + int i; + +redo: + line = qtest_recv_line(s); + words = g_strsplit(line->str, " ", 0); + if (strcmp(words[0], "FAIL") == 0) { + g_assert_cmpstr(line->str, ==, "OK"); + } + g_string_free(line, TRUE); + + if (strcmp(words[0], "IRQ") == 0) { + int irq; + gpio_id id; + + g_assert(words[1] != NULL); + g_assert(words[2] != NULL); + g_assert(words[3] != NULL); + + id = strtoul(words[2], NULL, 0); + g_assert_cmpint(id, >=, 0); + g_assert_cmpint(id, <, MAX_GPIO_INTERCEPTS); + + irq = strtoul(words[3], NULL, 0); + g_assert_cmpint(irq, >=, 0); + g_assert_cmpint(irq, <, MAX_IRQ); + + if (strcmp(words[1], "raise") == 0) { + s->irq_level[id][irq] = true; + } else { + s->irq_level[id][irq] = false; + } + + g_strfreev(words); + goto redo; + } + + g_assert(words[0] != NULL); + g_assert_cmpstr(words[0], ==, "OK"); + + if (expected_args) { + for (i = 0; i < expected_args; i++) { + g_assert(words[i] != NULL); + } + } else { + g_strfreev(words); + } + + return words; +} + +typedef struct { + JSONMessageParser parser; + QDict *response; +} QMPResponseParser; + +static void qmp_response(JSONMessageParser *parser, GQueue *tokens) +{ + QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser); + QObject *obj; + + obj = json_parser_parse(tokens, NULL); + if (!obj) { + fprintf(stderr, "QMP JSON response parsing failed\n"); + exit(1); + } + + g_assert(qobject_type(obj) == QTYPE_QDICT); + g_assert(!qmp->response); + qmp->response = (QDict *)obj; +} + +QDict *qmp_fd_receive(int fd) +{ + QMPResponseParser qmp; + bool log = getenv("QTEST_LOG") != NULL; + + qmp.response = NULL; + json_message_parser_init(&qmp.parser, qmp_response); + while (!qmp.response) { + ssize_t len; + char c; + + len = read(fd, &c, 1); + if (len == -1 && errno == EINTR) { + continue; + } + + if (len == -1 || len == 0) { + fprintf(stderr, "Broken pipe\n"); + exit(1); + } + + if (log) { + len = write(2, &c, 1); + } + json_message_parser_feed(&qmp.parser, &c, 1); + } + json_message_parser_destroy(&qmp.parser); + + return qmp.response; +} + +QDict *qtest_qmp_receive(QTestState *s) +{ + return qmp_fd_receive(s->qmp_socket.fd); +} + +/** + * Allow users to send a message without waiting for the reply, + * in the case that they choose to discard all replies up until + * a particular EVENT is received. + */ +void qmp_fd_sendv(int fd, const char *fmt, va_list ap) +{ + va_list ap_copy; + QObject *qobj; + + /* Going through qobject ensures we escape strings properly. + * This seemingly unnecessary copy is required in case va_list + * is an array type. + */ + va_copy(ap_copy, ap); + qobj = qobject_from_jsonv(fmt, &ap_copy); + va_end(ap_copy); + + /* No need to send anything for an empty QObject. */ + if (qobj) { + int log = getenv("QTEST_LOG") != NULL; + QString *qstr = qobject_to_json(qobj); + const char *str = qstring_get_str(qstr); + size_t size = qstring_get_length(qstr); + + if (log) { + fprintf(stderr, "%s", str); + } + /* Send QMP request */ + socket_send(fd, str, size); + + QDECREF(qstr); + qobject_decref(qobj); + } +} + +void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap) +{ + qmp_fd_sendv(s->qmp_socket.fd, fmt, ap); +} + +QDict *qmp_fdv(int fd, const char *fmt, va_list ap) +{ + qmp_fd_sendv(fd, fmt, ap); + + return qmp_fd_receive(fd); +} + +QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap) +{ + qtest_async_qmpv(s, fmt, ap); + + /* Receive reply */ + return qtest_qmp_receive(s); +} + +QDict *qmp_fd(int fd, const char *fmt, ...) +{ + va_list ap; + QDict *response; + + va_start(ap, fmt); + response = qmp_fdv(fd, fmt, ap); + va_end(ap); + return response; +} + +void qmp_fd_send(int fd, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + qmp_fd_sendv(fd, fmt, ap); + va_end(ap); +} + +QDict *qtest_qmp(QTestState *s, const char *fmt, ...) +{ + va_list ap; + QDict *response; + + va_start(ap, fmt); + response = qtest_qmpv(s, fmt, ap); + va_end(ap); + return response; +} + +void qtest_async_qmp(QTestState *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + qtest_async_qmpv(s, fmt, ap); + va_end(ap); +} + +void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap) +{ + QDict *response = qtest_qmpv(s, fmt, ap); + QDECREF(response); +} + +void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...) +{ + va_list ap; + QDict *response; + + va_start(ap, fmt); + response = qtest_qmpv(s, fmt, ap); + va_end(ap); + QDECREF(response); +} + +void qtest_qmp_eventwait(QTestState *s, const char *event) +{ + QDict *response; + + for (;;) { + response = qtest_qmp_receive(s); + if ((qdict_haskey(response, "event")) && + (strcmp(qdict_get_str(response, "event"), event) == 0)) { + QDECREF(response); + break; + } + QDECREF(response); + } +} + +char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap) +{ + char *cmd; + QDict *resp; + char *ret; + + cmd = g_strdup_vprintf(fmt, ap); + resp = qtest_qmp(s, "{'execute': 'human-monitor-command'," + " 'arguments': {'command-line': %s}}", + cmd); + ret = g_strdup(qdict_get_try_str(resp, "return")); + g_assert(ret); + QDECREF(resp); + g_free(cmd); + return ret; +} + +char *qtest_hmp(QTestState *s, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = qtest_hmpv(s, fmt, ap); + va_end(ap); + return ret; +} + +const char *qtest_get_arch(void) +{ + const char *qemu = getenv("QTEST_QEMU_BINARY"); + g_assert(qemu != NULL); + const char *end = strrchr(qemu, '/'); + + return end + strlen("/qemu-system-"); +} + +bool qtest_get_irq(QTestState *s, int num) +{ + g_assert(s->last_intercept_gpio_id >= 0); + return qtest_get_irq_for_gpio(s, 0, num); +} + +bool qtest_get_irq_for_gpio(QTestState *s, gpio_id id, int num) +{ + /* dummy operation in order to make sure irq is up to date */ + qtest_inb(s, 0); + + return s->irq_level[id][num]; +} + +static int64_t qtest_clock_rsp(QTestState *s) +{ + gchar **words; + int64_t clock; + words = qtest_rsp(s, 2); + clock = g_ascii_strtoll(words[1], NULL, 0); + g_strfreev(words); + return clock; +} + +int64_t qtest_clock_step_next(QTestState *s) +{ + qtest_sendf(s, "clock_step\n"); + return qtest_clock_rsp(s); +} + +int64_t qtest_clock_step(QTestState *s, int64_t step) +{ + qtest_sendf(s, "clock_step %"PRIi64"\n", step); + return qtest_clock_rsp(s); +} + +int64_t qtest_clock_set(QTestState *s, int64_t val) +{ + qtest_sendf(s, "clock_set %"PRIi64"\n", val); + return qtest_clock_rsp(s); +} + +static gpio_id get_next_intercept_gpio_id(QTestState *s) +{ + gpio_id next_gpio_id = ++(s->last_intercept_gpio_id); + g_assert(next_gpio_id < MAX_GPIO_INTERCEPTS); + return next_gpio_id; +} + +gpio_id qtest_irq_intercept_out(QTestState *s, const char *qom_path) +{ + gpio_id next_gpio_id = get_next_intercept_gpio_id(s); + qtest_sendf(s, "irq_intercept_out %s %d\n", qom_path, next_gpio_id); + qtest_rsp(s, 0); + return next_gpio_id; +} + +gpio_id qtest_irq_intercept_in(QTestState *s, const char *qom_path) +{ + gpio_id next_gpio_id = get_next_intercept_gpio_id(s); + qtest_sendf(s, "irq_intercept_in %s %d\n", qom_path, next_gpio_id); + qtest_rsp(s, 0); + return next_gpio_id; +} + +void qtest_set_irq_in(QTestState *s, const char *string, int num, int level) +{ + qtest_sendf(s, "set_irq_in %s %d %s\n", string, num, + level ? "raise" : "lower"); + qtest_rsp(s, 0); +} + +static SocketInfo *get_serial_port_socket(QTestState *s, int serial_socket_num) +{ + g_assert(serial_socket_num >= 0 && + serial_socket_num < s->num_serial_ports); + return &s->serial_port_sockets[serial_socket_num]; +} + +void qtest_write_serial_port(QTestState *s, + int serial_port_num, + const char *fmt, ...) +{ + va_list ap; + SocketInfo *socket_info = get_serial_port_socket(s, serial_port_num); + + va_start(ap, fmt); + socket_sendf(socket_info->fd, fmt, ap); + va_end(ap); +} + +uint8_t qtest_read_serial_port_byte(QTestState *s, int serial_port_num) +{ + ssize_t len; + uint8_t buffer; + SocketInfo *socket_info = get_serial_port_socket(s, serial_port_num); + + do { + len = read(socket_info->fd, &buffer, sizeof(buffer)); + if (errno == EINTR) { + continue; + } + + if (len == -1 || len == 0) { + fprintf(stderr, "No character to read from socket %d\n", + serial_port_num); + g_assert(false); + } + } while(len == -1); + + g_assert_cmpint(len, ==, 1); + + return buffer; +} + +static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value) +{ + qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value); + qtest_rsp(s, 0); +} + +void qtest_outb(QTestState *s, uint16_t addr, uint8_t value) +{ + qtest_out(s, "outb", addr, value); +} + +void qtest_outw(QTestState *s, uint16_t addr, uint16_t value) +{ + qtest_out(s, "outw", addr, value); +} + +void qtest_outl(QTestState *s, uint16_t addr, uint32_t value) +{ + qtest_out(s, "outl", addr, value); +} + +static uint32_t qtest_in(QTestState *s, const char *cmd, uint16_t addr) +{ + gchar **args; + uint32_t value; + + qtest_sendf(s, "%s 0x%x\n", cmd, addr); + args = qtest_rsp(s, 2); + value = strtoul(args[1], NULL, 0); + g_strfreev(args); + + return value; +} + +uint8_t qtest_inb(QTestState *s, uint16_t addr) +{ + return qtest_in(s, "inb", addr); +} + +uint16_t qtest_inw(QTestState *s, uint16_t addr) +{ + return qtest_in(s, "inw", addr); +} + +uint32_t qtest_inl(QTestState *s, uint16_t addr) +{ + return qtest_in(s, "inl", addr); +} + +static void qtest_write(QTestState *s, const char *cmd, uint64_t addr, + uint64_t value) +{ + qtest_sendf(s, "%s 0x%" PRIx64 " 0x%" PRIx64 "\n", cmd, addr, value); + qtest_rsp(s, 0); +} + +void qtest_writeb(QTestState *s, uint64_t addr, uint8_t value) +{ + qtest_write(s, "writeb", addr, value); +} + +void qtest_writew(QTestState *s, uint64_t addr, uint16_t value) +{ + qtest_write(s, "writew", addr, value); +} + +void qtest_writel(QTestState *s, uint64_t addr, uint32_t value) +{ + qtest_write(s, "writel", addr, value); +} + +void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value) +{ + qtest_write(s, "writeq", addr, value); +} + +static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr) +{ + gchar **args; + uint64_t value; + + qtest_sendf(s, "%s 0x%" PRIx64 "\n", cmd, addr); + args = qtest_rsp(s, 2); + value = strtoull(args[1], NULL, 0); + g_strfreev(args); + + return value; +} + +uint8_t qtest_readb(QTestState *s, uint64_t addr) +{ + return qtest_read(s, "readb", addr); +} + +uint16_t qtest_readw(QTestState *s, uint64_t addr) +{ + return qtest_read(s, "readw", addr); +} + +uint32_t qtest_readl(QTestState *s, uint64_t addr) +{ + return qtest_read(s, "readl", addr); +} + +uint64_t qtest_readq(QTestState *s, uint64_t addr) +{ + return qtest_read(s, "readq", addr); +} + +static int hex2nib(char ch) +{ + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } else if (ch >= 'a' && ch <= 'f') { + return 10 + (ch - 'a'); + } else if (ch >= 'A' && ch <= 'F') { + return 10 + (ch - 'a'); + } else { + return -1; + } +} + +void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size) +{ + uint8_t *ptr = data; + gchar **args; + size_t i; + + qtest_sendf(s, "read 0x%" PRIx64 " 0x%zx\n", addr, size); + args = qtest_rsp(s, 2); + + for (i = 0; i < size; i++) { + ptr[i] = hex2nib(args[1][2 + (i * 2)]) << 4; + ptr[i] |= hex2nib(args[1][2 + (i * 2) + 1]); + } + + g_strfreev(args); +} + +void qtest_add_func(const char *str, void (*fn)(void)) +{ + gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); + g_test_add_func(path, fn); + g_free(path); +} + +void qtest_add_data_func(const char *str, const void *data, + void (*fn)(const void *)) +{ + gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); + g_test_add_data_func(path, data, fn); + g_free(path); +} + +void qtest_bufwrite(QTestState *s, uint64_t addr, const void *data, size_t size) +{ + gchar *bdata; + + bdata = g_base64_encode(data, size); + qtest_sendf(s, "b64write 0x%" PRIx64 " 0x%zx ", addr, size); + socket_send(s->qtest_socket.fd, bdata, strlen(bdata)); + socket_send(s->qtest_socket.fd, "\n", 1); + qtest_rsp(s, 0); + g_free(bdata); +} + +void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size) +{ + gchar **args; + size_t len; + + qtest_sendf(s, "b64read 0x%" PRIx64 " 0x%zx\n", addr, size); + args = qtest_rsp(s, 2); + + g_base64_decode_inplace(args[1], &len); + if (size != len) { + fprintf(stderr, "bufread: asked for %zu bytes but decoded %zu\n", + size, len); + len = MIN(len, size); + } + + memcpy(data, args[1], len); + g_strfreev(args); +} + +void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size) +{ + const uint8_t *ptr = data; + size_t i; + char *enc = g_malloc(2 * size + 1); + + for (i = 0; i < size; i++) { + sprintf(&enc[i * 2], "%02x", ptr[i]); + } + + qtest_sendf(s, "write 0x%" PRIx64 " 0x%zx 0x%s\n", addr, size, enc); + qtest_rsp(s, 0); + g_free(enc); +} + +void qtest_memset(QTestState *s, uint64_t addr, uint8_t pattern, size_t size) +{ + qtest_sendf(s, "memset 0x%" PRIx64 " 0x%zx 0x%02x\n", addr, size, pattern); + qtest_rsp(s, 0); +} + +void write_serial_port(int serial_port_num, const char *fmt, ...) +{ + va_list ap; + SocketInfo *socket_info = get_serial_port_socket(global_qtest, + serial_port_num); + + va_start(ap, fmt); + socket_sendf(socket_info->fd, fmt, ap); + va_end(ap); +} + +QDict *qmp(const char *fmt, ...) +{ + va_list ap; + QDict *response; + + va_start(ap, fmt); + response = qtest_qmpv(global_qtest, fmt, ap); + va_end(ap); + return response; +} + +void qmp_async(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + qtest_async_qmpv(global_qtest, fmt, ap); + va_end(ap); +} + +void qmp_discard_response(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + qtest_qmpv_discard_response(global_qtest, fmt, ap); + va_end(ap); +} +char *hmp(const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = qtest_hmpv(global_qtest, fmt, ap); + va_end(ap); + return ret; +} + +bool qtest_big_endian(void) +{ + const char *arch = qtest_get_arch(); + int i; + + static const struct { + const char *arch; + bool big_endian; + } endianness[] = { + { "aarch64", false }, + { "alpha", false }, + { "arm", false }, + { "cris", false }, + { "i386", false }, + { "lm32", true }, + { "m68k", true }, + { "microblaze", true }, + { "microblazeel", false }, + { "mips", true }, + { "mips64", true }, + { "mips64el", false }, + { "mipsel", false }, + { "moxie", true }, + { "or32", true }, + { "ppc", true }, + { "ppc64", true }, + { "ppcemb", true }, + { "s390x", true }, + { "sh4", false }, + { "sh4eb", true }, + { "sparc", true }, + { "sparc64", true }, + { "unicore32", false }, + { "x86_64", false }, + { "xtensa", false }, + { "xtensaeb", true }, + {}, + }; + + for (i = 0; endianness[i].arch; i++) { + if (strcmp(endianness[i].arch, arch) == 0) { + return endianness[i].big_endian; + } + } + + return false; +} diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index 413cc4e0f4ab2..8c64ba0235234 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -463,7 +463,16 @@ wrote 65536/65536 bytes at offset 2147483648 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 3221225472 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - (0.00/100%) (12.50/100%) (25.00/100%) (37.50/100%) (50.00/100%) (62.50/100%) (75.00/100%) (87.50/100%) (100.00/100%) (100.00/100%) + (0.00/100%) + (12.50/100%) + (25.00/100%) + (37.50/100%) + (50.00/100%) + (62.50/100%) + (75.00/100%) + (87.50/100%) + (100.00/100%) + (100.00/100%) No errors were found on the image. === Testing progress report with snapshot === @@ -478,7 +487,24 @@ wrote 65536/65536 bytes at offset 2147483648 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 3221225472 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - (0.00/100%) (6.25/100%) (12.50/100%) (18.75/100%) (25.00/100%) (31.25/100%) (37.50/100%) (43.75/100%) (50.00/100%) (56.25/100%) (62.50/100%) (68.75/100%) (75.00/100%) (81.25/100%) (87.50/100%) (93.75/100%) (100.00/100%) (100.00/100%) + (0.00/100%) + (6.25/100%) + (12.50/100%) + (18.75/100%) + (25.00/100%) + (31.25/100%) + (37.50/100%) + (43.75/100%) + (50.00/100%) + (56.25/100%) + (62.50/100%) + (68.75/100%) + (75.00/100%) + (81.25/100%) + (87.50/100%) + (93.75/100%) + (100.00/100%) + (100.00/100%) No errors were found on the image. === Testing version downgrade with external data file === diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out index b10c71db03c82..138d42502e443 100644 --- a/tests/qemu-iotests/067.out +++ b/tests/qemu-iotests/067.out @@ -69,6 +69,83 @@ Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk -device vir "return": { } } +<<<<<<< HEAD +======= +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "RESET" +} +{ + "return": [ + { + "io-status": "ok", + "device": "ide1-cd0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + }, + { + "device": "floppy0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + }, + { + "device": "sd0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + } + ] +} +{ + "return": { + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "ide1-cd0", + "tray-open": true + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "floppy0", + "tray-open": true + } +} + +>>>>>>> 919b29ba7d... Pebble Qemu === -drive/device_add and device_del === @@ -140,6 +217,83 @@ Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk "return": { } } +<<<<<<< HEAD +======= +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "RESET" +} +{ + "return": [ + { + "io-status": "ok", + "device": "ide1-cd0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + }, + { + "device": "floppy0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + }, + { + "device": "sd0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + } + ] +} +{ + "return": { + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "ide1-cd0", + "tray-open": true + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "floppy0", + "tray-open": true + } +} + +>>>>>>> 919b29ba7d... Pebble Qemu === drive_add/device_add and device_del === @@ -214,6 +368,83 @@ Testing: "return": { } } +<<<<<<< HEAD +======= +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "RESET" +} +{ + "return": [ + { + "io-status": "ok", + "device": "ide1-cd0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + }, + { + "device": "floppy0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + }, + { + "device": "sd0", + "locked": false, + "removable": true, + "tray_open": false, + "type": "unknown" + } + ] +} +{ + "return": { + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "ide1-cd0", + "tray-open": true + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "floppy0", + "tray-open": true + } +} + +>>>>>>> 919b29ba7d... Pebble Qemu === blockdev_add/device_add and device_del === @@ -411,4 +642,74 @@ Testing: -device virtio-scsi -device scsi-cd,id=cd0 "return": { } } +<<<<<<< HEAD +======= + "type": "qcow2", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "backing_file_depth": 0, + "drv": "qcow2", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "TEST_DIR/t.qcow2", + "encryption_key_missing": false + }, + "tray_open": false, + "type": "unknown" + } + ] +} +{ + "return": { + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN" +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "ide1-cd0", + "tray-open": true + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "DEVICE_TRAY_MOVED", + "data": { + "device": "floppy0", + "tray-open": true + } +} + +>>>>>>> 919b29ba7d... Pebble Qemu *** done diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out index bca0c02f5c09a..035025630ec57 100644 --- a/tests/qemu-iotests/071.out +++ b/tests/qemu-iotests/071.out @@ -46,7 +46,15 @@ QMP_VERSION read failed: Input/output error {"return": ""} {"return": {}} +<<<<<<< HEAD {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} +======= +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} +QEMU_PROG: Failed to flush the L2 table cache: Input/output error +QEMU_PROG: Failed to flush the refcount block cache: Input/output error +QEMU_PROG: Failed to flush the L2 table cache: Input/output error +QEMU_PROG: Failed to flush the refcount block cache: Input/output error +>>>>>>> 919b29ba7d... Pebble Qemu === Testing blkverify on existing block device === @@ -88,5 +96,7 @@ read failed: Input/output error {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} QEMU_PROG: Failed to flush the L2 table cache: Input/output error QEMU_PROG: Failed to flush the refcount block cache: Input/output error +QEMU_PROG: Failed to flush the L2 table cache: Input/output error +QEMU_PROG: Failed to flush the refcount block cache: Input/output error *** done diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out index 2d92ea847b010..43e9489a1c5fa 100644 --- a/tests/qemu-iotests/087.out +++ b/tests/qemu-iotests/087.out @@ -64,6 +64,12 @@ QMP_VERSION {"return": {}} {"error": {"class": "GenericError", "desc": "Parameter 'driver' is missing"}} {"return": {}} +<<<<<<< HEAD {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} +======= +{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'driver', expected: string"}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} +>>>>>>> 919b29ba7d... Pebble Qemu *** done diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index f5cf93c38629e..ce13ae7c27623 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -45,6 +45,22 @@ QTestState *qtest_initf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); */ QTestState *qtest_vinitf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +typedef int gpio_id; + +/* When running a QTest program stand-alone, the following environment variables + * may be set: + * + * Mandatory: + * QTEST_QEMU_BINARY: The QEMU binary to use. It is set automatically when + * running "make check". + * (e.g. "../arm-softmmu/qemu-system-arm") + * + * Optional: + * QTEST_QEMU_ARGS: Extra arguments to pass to QEMU (e.g. "-d"). + * QTEST_LOG_FILE: A file to which QTest log messages should be written + * (e.g. "/tmp/qtest.log"). + */ + /** * qtest_init: * @extra_args: other arguments to pass to QEMU. CAUTION: these @@ -52,7 +68,7 @@ QTestState *qtest_vinitf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); * * Returns: #QTestState instance. */ -QTestState *qtest_init(const char *extra_args); +QTestState *qtest_init(const char *extra_args, int num_serial_ports); /** * qtest_init_without_qmp_handshake: @@ -271,6 +287,16 @@ void qtest_module_load(QTestState *s, const char *prefix, const char *libname); */ bool qtest_get_irq(QTestState *s, int num); +/** + * qtest_get_irq_for_gpio: + * @s: #QTestState instance to operate on. + * @id: GPIO to operate on (see qtest_irq_intercept_in/out). + * @num: Interrupt to observe. + * + * Returns: The level of the @num interrupt. + */ +bool qtest_get_irq_for_gpio(QTestState *s, gpio_id id, int num); + /** * qtest_irq_intercept_in: * @s: #QTestState instance to operate on. @@ -278,8 +304,9 @@ bool qtest_get_irq(QTestState *s, int num); * * Associate qtest irqs with the GPIO-in pins of the device * whose path is specified by @string. + * Returns an id value that can be used when calling qtest_get_irq. */ -void qtest_irq_intercept_in(QTestState *s, const char *string); +gpio_id qtest_irq_intercept_in(QTestState *s, const char *string); /** * qtest_irq_intercept_out: @@ -288,8 +315,46 @@ void qtest_irq_intercept_in(QTestState *s, const char *string); * * Associate qtest irqs with the GPIO-out pins of the device * whose path is specified by @string. + * Returns an id value that can be used when calling qtest_get_irq. */ -void qtest_irq_intercept_out(QTestState *s, const char *string); +gpio_id qtest_irq_intercept_out(QTestState *s, const char *string); + +/** + * qtest_set_irq_in: + * @s: #QTestState instance to operate on. + * @string: QOM path of a device. + * @num: Interrupt to set (specifies a GPIO-in pin) + * @level: new IRQ level + * + * Sets the GPIO-in pin level of the device whose path is specified by @string. + */ +void qtest_set_irq_in(QTestState *s, const char *string, int num, int level); + +/** + * write_serial_port: + * @s: #QTestState instance to operate on. + * @serial_port_num: Indicates the serial port to write to + * (see qtest_start_with_serial). + * @fmt: The printf style format string to write. + * + * Sends a string to the specified virtual serial port. + */ +void qtest_write_serial_port(QTestState *s, + int serial_port_num, + const char *fmt, ...); + +/** + * read_serial_port_byte: + * @s: #QTestState instance to operate on. + * @serial_port_num: Indicates the serial port to read from + * (see qtest_start_with_serial). + * + * Reads an byte (8-bit value) from the specified virtual serial port. + * If there is no byte to read, an assertion failure will occur. + * + * Returns: Value read. + */ +uint8_t qtest_read_serial_port_byte(QTestState *s, int serial_port_num); /** * qtest_set_irq_in: @@ -627,11 +692,329 @@ void qtest_add_data_func_full(const char *str, void *data, void qtest_add_abrt_handler(GHookFunc fn, const void *data); /** +<<<<<<< HEAD:tests/qtest/libqtest.h * qtest_qmp_assert_success: * @qts: QTestState instance to operate on * @fmt...: QMP message to send to qemu, formatted like * qobject_from_jsonf_nofail(). See parse_escape() for what's * supported after '%'. +======= + * qtest_start: + * @args: other arguments to pass to QEMU + * + * Start QEMU and assign the resulting #QTestState to a global variable. + * The global variable is used by "shortcut" functions documented below. + * + * Returns: #QTestState instance. + */ +static inline QTestState *qtest_start(const char *args) +{ + global_qtest = qtest_init(args, 0); + return global_qtest; +} + +/** + * qtest_start_with_serial: + * @args: See qtest_start + * @num_sockets: number of extra sockets to + * + * Works the same way as qtest_start, except creates a connection to the + * specified number of virtual serial ports. + * + * Use write_serial_port and read_serial_port_byte to communicate via these + * connections. These functions require a serial port number. The serial + * ports are numbered in the same order that they are specified on + * the QEMU command line (using the -serial option). The first serial port + * specified on the command line is numbered 0, the second port is numbered 1, + * and so on. + */ +static inline QTestState *qtest_start_with_serial(const char *args, + int num_serial_ports) +{ + global_qtest = qtest_init(args, num_serial_ports); + return global_qtest; +} + +/** + * qtest_end: + * + * Shut down the QEMU process started by qtest_start(). + */ +static inline void qtest_end(void) +{ + qtest_quit(global_qtest); + global_qtest = NULL; +} + +/** + * qmp: + * @fmt...: QMP message to send to qemu + * + * Sends a QMP message to QEMU and returns the response. + */ +QDict *qmp(const char *fmt, ...); + +/** + * qmp_async: + * @fmt...: QMP message to send to qemu + * + * Sends a QMP message to QEMU and leaves the response in the stream. + */ +void qmp_async(const char *fmt, ...); + +/** + * qmp_discard_response: + * @fmt...: QMP message to send to qemu + * + * Sends a QMP message to QEMU and consumes the response. + */ +void qmp_discard_response(const char *fmt, ...); + +/** + * qmp_receive: + * + * Reads a QMP message from QEMU and returns the response. + */ +static inline QDict *qmp_receive(void) +{ + return qtest_qmp_receive(global_qtest); +} + +/** + * qmp_eventwait: + * @s: #event event to wait for. + * + * Continuosly polls for QMP responses until it receives the desired event. + */ +static inline void qmp_eventwait(const char *event) +{ + return qtest_qmp_eventwait(global_qtest, event); +} + +/** + * hmp: + * @fmt...: HMP command to send to QEMU + * + * Send HMP command to QEMU via QMP's human-monitor-command. + * + * Returns: the command's output. The caller should g_free() it. + */ +char *hmp(const char *fmt, ...); + +/** + * get_irq: + * @num: Interrupt to observe. + * + * Returns: The level of the @num interrupt. + */ +static inline bool get_irq(int num) +{ + return qtest_get_irq(global_qtest, num); +} + +/** + * get_irq_for_gpio: + * @id: GPIO to operate on (see qtest_irq_intercept_in/out). + * @num: Interrupt to observe. + * + * Returns: The level of the @num interrupt. + */ +static inline bool get_irq_for_gpio(gpio_id id, int num) +{ + return qtest_get_irq_for_gpio(global_qtest, id, num); +} + +/** + * irq_intercept_in: + * @string: QOM path of a device. + * + * Associate qtest irqs with the GPIO-in pins of the device + * whose path is specified by @string. + */ +static inline void irq_intercept_in(const char *string) +{ + qtest_irq_intercept_in(global_qtest, string); +} + +/** + * qtest_irq_intercept_out: + * @string: QOM path of a device. + * + * Associate qtest irqs with the GPIO-out pins of the device + * whose path is specified by @string. + */ +static inline void irq_intercept_out(const char *string) +{ + qtest_irq_intercept_out(global_qtest, string); +} + +/** + * set_irq_in: + * @string: QOM path of a device. + * @num: Interrupt to set (specifies a GPIO-in pin) + * @level: new IRQ level + * + * Sets the GPIO-in pin level of the device whose path is specified by @string. + */ +static inline void set_irq_in(const char *string, int num, int level) +{ + qtest_set_irq_in(global_qtest, string, num, level); +} + +/** + * write_serial_port: + * @serial_port_num: Indicates the serial port to write to + * (see qtest_start_with_serial). + * @fmt: The printf style format string to write. + * + * Sends a string to the specified virtual serial port. + */ +void write_serial_port(int serial_port_num, const char *fmt, ...); + +/** + * read_serial_port_byte: + * @serial_port_num: Indicates the serial port to read from + * (see qtest_start_with_serial). + * + * Reads an byte (8-bit value) from the specified virtual serial port. + * If there is no byte to read, an assertion failure will occur. + * + * Returns: Value read. + */ +static inline uint8_t read_serial_port_byte(int serial_port_num) +{ + return qtest_read_serial_port_byte(global_qtest, serial_port_num); +} + +/** + * outb: + * @addr: I/O port to write to. + * @value: Value being written. + * + * Write an 8-bit value to an I/O port. + */ +static inline void outb(uint16_t addr, uint8_t value) +{ + qtest_outb(global_qtest, addr, value); +} + +/** + * outw: + * @addr: I/O port to write to. + * @value: Value being written. + * + * Write a 16-bit value to an I/O port. + */ +static inline void outw(uint16_t addr, uint16_t value) +{ + qtest_outw(global_qtest, addr, value); +} + +/** + * outl: + * @addr: I/O port to write to. + * @value: Value being written. + * + * Write a 32-bit value to an I/O port. + */ +static inline void outl(uint16_t addr, uint32_t value) +{ + qtest_outl(global_qtest, addr, value); +} + +/** + * inb: + * @addr: I/O port to read from. + * + * Reads an 8-bit value from an I/O port. + * + * Returns: Value read. + */ +static inline uint8_t inb(uint16_t addr) +{ + return qtest_inb(global_qtest, addr); +} + +/** + * inw: + * @addr: I/O port to read from. + * + * Reads a 16-bit value from an I/O port. + * + * Returns: Value read. + */ +static inline uint16_t inw(uint16_t addr) +{ + return qtest_inw(global_qtest, addr); +} + +/** + * inl: + * @addr: I/O port to read from. + * + * Reads a 32-bit value from an I/O port. + * + * Returns: Value read. + */ +static inline uint32_t inl(uint16_t addr) +{ + return qtest_inl(global_qtest, addr); +} + +/** + * writeb: + * @addr: Guest address to write to. + * @value: Value being written. + * + * Writes an 8-bit value to guest memory. + */ +static inline void writeb(uint64_t addr, uint8_t value) +{ + qtest_writeb(global_qtest, addr, value); +} + +/** + * writew: + * @addr: Guest address to write to. + * @value: Value being written. + * + * Writes a 16-bit value to guest memory. + */ +static inline void writew(uint64_t addr, uint16_t value) +{ + qtest_writew(global_qtest, addr, value); +} + +/** + * writel: + * @addr: Guest address to write to. + * @value: Value being written. + * + * Writes a 32-bit value to guest memory. + */ +static inline void writel(uint64_t addr, uint32_t value) +{ + qtest_writel(global_qtest, addr, value); +} + +/** + * writeq: + * @addr: Guest address to write to. + * @value: Value being written. + * + * Writes a 64-bit value to guest memory. + */ +static inline void writeq(uint64_t addr, uint64_t value) +{ + qtest_writeq(global_qtest, addr, value); +} + +/** + * readb: + * @addr: Guest address to read from. + * + * Reads an 8-bit value from guest memory. +>>>>>>> 919b29ba7d... Pebble Qemu:tests/libqtest.h * * Sends a QMP message to QEMU and asserts that a 'return' key is present in * the response. diff --git a/tests/test-stm32.c b/tests/test-stm32.c new file mode 100644 index 0000000000000..bb8166fe72fb8 --- /dev/null +++ b/tests/test-stm32.c @@ -0,0 +1,311 @@ +/* + * QTest testcase for the STM32 Microcontroller + * + * Copyright 2013 + * + * Authors: + * Andre Beckus + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#include "libqtest.h" + +#include +#include + +// These are only needed for getpid +#include +#include + +#define GPIOA_BASE_ADDR 0x40010800 +#define GPIOB_BASE_ADDR 0x40010c00 +#define GPIOC_BASE_ADDR 0x40011000 +#define RCC_BASE_ADDR 0x40021000 +#define AFIO_BASE_ADDR 0x40010000 +#define EXTI_BASE_ADDR 0x40010400 +#define UART2_BASE_ADDR 0x40004400 + +const char *dummy_kernel_path = "tests/test-stm32-dummy-kernel.bin"; +const uint32_t dummy_kernel_data = 0x12345678; + +const int uart2_socket_num = 0; + +gpio_id gpio_a_out_id; +gpio_id nvic_in_id; +//gpio_id gpio_b_out_id; + +//int uart_sock, uart_fd; + +static void write_dummy_kernel_bin(void) +{ + FILE *kernel_file = fopen(dummy_kernel_path, "wb"); + g_assert(kernel_file); + + size_t write_size = fwrite(&dummy_kernel_data, 4, 1, kernel_file); + g_assert(write_size == 1); + + int close_result = fclose(kernel_file); + g_assert(close_result == 0); +} + +static void enable_all_periph_clocks(void) +{ + writel(RCC_BASE_ADDR + 0x18, 0x0038fffd); + writel(RCC_BASE_ADDR + 0x1c, 0x3afec9ff); +} + +static void config_gpio(uint32_t gpio_base_addr, + uint32_t config_value_high, + uint32_t config_value_low) +{ + writel(gpio_base_addr + 0x00, config_value_low); + writel(gpio_base_addr + 0x04, config_value_high); +} + +static void test_flash_alias(void) +{ + g_assert_cmpint(readl(0), ==, dummy_kernel_data); + g_assert_cmpint(readl(0x08000000), ==, dummy_kernel_data); + + g_assert_cmpint(readw(2), ==, dummy_kernel_data >> 16); + g_assert_cmpint(readw(0x08000002), ==, dummy_kernel_data >> 16); +} + +static void test_gpio_read(void) +{ + const uint32_t addr_idr = GPIOA_BASE_ADDR + 0x08; // Input Data Register + uint32_t value; + + config_gpio(GPIOA_BASE_ADDR, 0x44444444, 0x44444444); // All inputs + + value = readl(addr_idr); + g_assert_cmpint(value, ==, 0); + + set_irq_in("/machine/stm32/gpio[a]", 0, 1); + + value = readl(addr_idr); + g_assert_cmpint(value, ==, 1); + + set_irq_in("/machine/stm32/gpio[a]", 7, 1); + + value = readl(addr_idr); + g_assert_cmpint(value, ==, 0x81); +} + +static void test_gpio_write(void) +{ + const uint32_t addr_odr = GPIOA_BASE_ADDR + 0x0c; // Output Data Register + const uint32_t addr_bsrr = GPIOA_BASE_ADDR + 0x10; // Bit Set Reset Register + const uint32_t addr_brr = GPIOA_BASE_ADDR + 0x14; // Bit Reset Register + + config_gpio(GPIOA_BASE_ADDR, 0x33333333, 0x33333333); // All outputs + + writel(addr_odr, 0x00000000); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 0); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 0); + + writel(addr_odr, 0x0000ffff); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 1); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 1); + + writel(addr_brr, 0x00008001); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 0); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x1), ==, 1); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 0); + + writel(addr_bsrr, 0x00028001); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 1); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x1), ==, 0); + g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 1); + + writel(addr_bsrr, 0x0000ffef); + + + //config_gpio(GPIOB_BASE_ADDR, 0x33333333, 0x33333333); // All outputs + + //writel(GPIOB_BASE_ADDR + 0x0c, 0x00000000); + //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0x0), ==, 0); + //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0xf), ==, 0); + + //writel(GPIOB_BASE_ADDR + 0x0c, 0x0000ffff); + //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0x0), ==, 1); + //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0xf), ==, 1); +} + +static void test_gpio_interrupt(void) +{ + config_gpio(GPIOA_BASE_ADDR, 0x44444444, 0x44444444); // All inputs + + set_irq_in("/machine/stm32/gpio[a]", 0, 0); + + writel(EXTI_BASE_ADDR + 0x00, 0x000fffff); // All interrupts enabled + writel(EXTI_BASE_ADDR + 0x08, 0x000fffff); // All rising triggers + writel(EXTI_BASE_ADDR + 0x0c, 0x000fffff); // All falling triggers + + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + set_irq_in("/machine/stm32/gpio[a]", 0, 1); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); + set_irq_in("/machine/stm32/gpio[a]", 0, 0); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); + + writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts + + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + set_irq_in("/machine/stm32/gpio[a]", 0, 1); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); + writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + set_irq_in("/machine/stm32/gpio[a]", 0, 0); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); + writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts + + set_irq_in("/machine/stm32/gpio[b]", 0, 0); + set_irq_in("/machine/stm32/gpio[b]", 0, 1); + set_irq_in("/machine/stm32/gpio[b]", 0, 0); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + + writel(AFIO_BASE_ADDR + 0x08, 0x00000001); // Attach EXTI0 to Port B + + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + set_irq_in("/machine/stm32/gpio[b]", 0, 1); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); + writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x7), ==, 0); + writel(EXTI_BASE_ADDR + 0x10, 0x00000003); // Clear all interrupts + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x7), ==, 1); + g_assert_cmpint(readl(EXTI_BASE_ADDR + 0x10), ==, 0x00000003); + writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x7), ==, 0); + g_assert_cmpint(readl(EXTI_BASE_ADDR + 0x10), ==, 0x00000000); +} + +static void test_uart(void) +{ + uint32_t status; + uint8_t recv_byte; + uint8_t sent_byte; + uint32_t cr1_enabled = 0x0000200c; + + /* TODO: Clean this up and modularize. */ + + // All inputs except pin 2 (which is the transmit pin). + config_gpio(GPIOA_BASE_ADDR, 0x44444444, 0x44444b44); + + writel(UART2_BASE_ADDR + 0x0c, cr1_enabled); // Enable UART, Transmit, and Receive + + status = readl(UART2_BASE_ADDR + 0x00); + g_assert_cmpint(status & 0x020, ==, 0); + + write_serial_port(uart2_socket_num, "A"); + //TODO: Add a timeout to avoid infinite loop + do { + status = readl(UART2_BASE_ADDR + 0x00); + } while((status & 0x020) == 0); + recv_byte = readl(UART2_BASE_ADDR + 0x04); + g_assert_cmpint(recv_byte, ==, 'A'); + + write_serial_port(uart2_socket_num, "B"); + //TODO: Add a timeout to avoid infinite loop + do { + status = readl(UART2_BASE_ADDR + 0x00); + } while((status & 0x020) == 0); + recv_byte = readl(UART2_BASE_ADDR + 0x04); + g_assert_cmpint(recv_byte, ==, 'B'); + + writel(UART2_BASE_ADDR + 0x04, 'C'); // Transmit a character + sent_byte = read_serial_port_byte(uart2_socket_num); + g_assert_cmpint(sent_byte, ==, 'C'); + + writel(UART2_BASE_ADDR + 0x04, 'D'); // Transmit a character + sent_byte = read_serial_port_byte(uart2_socket_num); + g_assert_cmpint(sent_byte, ==, 'D'); + + writel(UART2_BASE_ADDR + 0x0c, cr1_enabled | 0x0020); // Receive interrupt + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 0); + write_serial_port(uart2_socket_num, "E"); + //TODO: Add a timeout to avoid infinite loop + do { + status = readl(UART2_BASE_ADDR + 0x00); + } while((status & 0x020) == 0); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 1); + recv_byte = readl(UART2_BASE_ADDR + 0x04); + g_assert_cmpint(recv_byte, ==, 'E'); + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 0); + + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 0); + writel(UART2_BASE_ADDR + 0x0c, cr1_enabled | 0x0040); // transmit complete interrupt + writel(UART2_BASE_ADDR + 0x04, 'F'); // Transmit a character + //TODO: Add a timeout to avoid infinite loop + do { + status = readl(UART2_BASE_ADDR + 0x00); + } while((status & 0x040) == 0); // Loop until transmit complete + g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 1); + sent_byte = read_serial_port_byte(uart2_socket_num); + g_assert_cmpint(sent_byte, ==, 'F'); + + // Test half-word (16 bit) memory accesses. + // Note that half-word memory accesses are only supported in the UART + // if they are word (32 bit) address aligned. + writew(UART2_BASE_ADDR + 0x0c, 0); + writew(UART2_BASE_ADDR + 0x0e, 0); + g_assert_cmpint(readw(UART2_BASE_ADDR + 0x0c), ==, 0); + g_assert_cmpint(readw(UART2_BASE_ADDR + 0x0e), ==, 0); + writew(UART2_BASE_ADDR + 0x0c, 0x200c); + g_assert_cmpint(readw(UART2_BASE_ADDR + 0x0c), ==, 0x200c); + + + // To do: test TXE interrupt, overflow, simulated delays, TC clearing + // These get tough to do because they involve race conditions. + // Maybe we can add a property for testing to tell the uart to pause + // when sending a character so that the unit tests can check things + // out and then change the property back to resume operations. + // Of course, this interferes with and complicates the unit under test, making + // it more prone to defects. + // Maybe if timers were objects, they could have the test properties instead + // so that we did not need to add test logic into the UART itself..... +} + +int main(int argc, char **argv) +{ + QTestState *s = NULL; + int ret; + + g_test_init(&argc, &argv, NULL); + + write_dummy_kernel_bin(); + + gchar *qemu_args = g_strdup_printf("-display none " + "-machine stm32-p103 " + "-kernel %s", + dummy_kernel_path); + s = qtest_start_with_serial(qemu_args, 1); + + enable_all_periph_clocks(); + + gpio_a_out_id = qtest_irq_intercept_out(s, "/machine/stm32/gpio[a]"); + nvic_in_id = qtest_irq_intercept_in(s, "/machine/stm32/nvic"); + //gpio_b_out_id = qtest_irq_intercept_out(s, "/machine/stm32/gpio[b]"); + + qtest_add_func("/stm32/flash/alias", test_flash_alias); + qtest_add_func("/stm32/gpio/read", test_gpio_read); + qtest_add_func("/stm32/gpio/write", test_gpio_write); + qtest_add_func("/stm32/gpio/interrupt", test_gpio_interrupt); + qtest_add_func("/stm32/uart", test_uart); + + ret = g_test_run(); + + if (s) { + qtest_quit(s); + } + + unlink(qemu_args); + g_free(qemu_args); + + return ret; +} diff --git a/ui/cocoa.m b/ui/cocoa.m index cb556e4e6689d..a0ab851992948 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -544,14 +544,11 @@ - (void) switchSurface:(pixman_image_t *)image [[fullScreenWindow contentView] setFrame:[[NSScreen mainScreen] frame]]; [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:NO animate:NO]; } else { - if (qemu_name) + if (qemu_name) { [normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s", qemu_name]]; + } [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:YES animate:NO]; } - - if (isResize) { - [normalWindow center]; - } } - (void) toggleFullScreen:(id)sender @@ -950,6 +947,9 @@ - (bool) handleEventLocked:(NSEvent *)event - (void) grabMouse { +#ifdef NO_MOUSE + return; +#endif COCOA_DEBUG("QemuCocoaView: grabMouse\n"); if (!isFullscreen) { @@ -968,6 +968,9 @@ - (void) grabMouse - (void) ungrabMouse { +#ifdef NO_MOUSE + return; +#endif COCOA_DEBUG("QemuCocoaView: ungrabMouse\n"); if (!isFullscreen) { @@ -1090,9 +1093,19 @@ - (id) init // set the supported image file types that can be opened supportedImageFileTypes = [NSArray arrayWithObjects: @"img", @"iso", @"dmg", +<<<<<<< HEAD @"qcow", @"qcow2", @"cloop", @"vmdk", @"cdr", @"toast", nil]; [self make_about_window]; +======= + @"qcow", @"qcow2", @"cloop", @"vmdk", nil]; + + // Save window position + [[normalWindow windowController] setShouldCascadeWindows:NO]; + [normalWindow setFrameAutosaveName:@"normalWindow"]; + + [normalWindow makeKeyAndOrderFront:self]; +>>>>>>> 919b29ba7d... Pebble Qemu } return self; } @@ -1343,6 +1356,9 @@ - (void)changeDeviceMedia:(id)sender /* Verifies if the user really wants to quit */ - (BOOL)verifyQuit { +#ifdef SKIP_QUIT_PROMPT + return YES; +#else NSAlert *alert = [NSAlert new]; [alert autorelease]; [alert setMessageText: @"Are you sure you want to quit QEMU?"]; @@ -1353,6 +1369,7 @@ - (BOOL)verifyQuit } else { return NO; } +#endif } /* The action method for the About menu item */ @@ -1580,6 +1597,24 @@ static void create_initial_menus(void) menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease]; [menuItem setSubmenu:menu]; [[NSApp mainMenu] addItem:menuItem]; +<<<<<<< HEAD +======= + + // Create an Application controller + QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init]; + [NSApp setDelegate:appController]; + + // Bring application to the front of all windows + [NSApp activateIgnoringOtherApps:YES]; + + // Start the main event loop + [NSApp run]; + + [appController release]; + [pool release]; + + return 0; +>>>>>>> 919b29ba7d... Pebble Qemu } /* Returns a name for a given console */ diff --git a/ui/gtk.c b/ui/gtk.c index 030b251c6109e..f94fd123163a2 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1483,6 +1483,9 @@ static void gd_ungrab_keyboard(GtkDisplayState *s) static void gd_grab_pointer(VirtualConsole *vc, const char *reason) { +#ifdef NO_MOUSE + return; +#endif GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area); if (vc->s->ptr_owner) { @@ -1515,6 +1518,9 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason) static void gd_ungrab_pointer(GtkDisplayState *s) { +#ifdef NO_MOUSE + return; +#endif VirtualConsole *vc = s->ptr_owner; GdkDisplay *display; diff --git a/ui/sdl.c b/ui/sdl.c new file mode 100644 index 0000000000000..b008f8dd035d2 --- /dev/null +++ b/ui/sdl.c @@ -0,0 +1,1009 @@ +/* + * QEMU SDL display driver + * + * Copyright (c) 2003 Fabrice Bellard + * + * 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. + */ + +/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */ +#undef WIN32_LEAN_AND_MEAN + +#include +#include + +#include "qemu-common.h" +#include "ui/console.h" +#include "ui/input.h" +#include "sysemu/sysemu.h" +#include "x_keymap.h" +#include "sdl_zoom.h" + +static DisplayChangeListener *dcl; +static DisplaySurface *surface; +static SDL_Surface *real_screen; +static SDL_Surface *guest_screen = NULL; +static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ +static int last_vm_running; +static bool gui_saved_scaling; +static int gui_saved_width; +static int gui_saved_height; +static int gui_saved_grab; +static int gui_fullscreen; +static int gui_noframe; +static int gui_key_modifier_pressed; +static int gui_keysym; +static int gui_grab_code = KMOD_LALT | KMOD_LCTRL; +static uint8_t modifiers_state[256]; +static SDL_Cursor *sdl_cursor_normal; +static SDL_Cursor *sdl_cursor_hidden; +static int absolute_enabled = 0; +static int guest_cursor = 0; +static int guest_x, guest_y; +static SDL_Cursor *guest_sprite = NULL; +static SDL_PixelFormat host_format; +static int scaling_active = 0; +static Notifier mouse_mode_notifier; + +#if 0 +#define DEBUG_SDL +#endif + +static void sdl_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ + SDL_Rect rec; + rec.x = x; + rec.y = y; + rec.w = w; + rec.h = h; + +#ifdef DEBUG_SDL + printf("SDL: Updating x=%d y=%d w=%d h=%d (scaling: %d)\n", + x, y, w, h, scaling_active); +#endif + + if (guest_screen) { + if (!scaling_active) { + SDL_BlitSurface(guest_screen, &rec, real_screen, &rec); + } else { + if (sdl_zoom_blit(guest_screen, real_screen, SMOOTHING_ON, &rec) < 0) { + fprintf(stderr, "Zoom blit failed\n"); + exit(1); + } + } + } + SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h); +} + +static void do_sdl_resize(int width, int height, int bpp) +{ + int flags; + SDL_Surface *tmp_screen; + +#ifdef DEBUG_SDL + printf("SDL: Resizing to %dx%d bpp %d\n", width, height, bpp); +#endif + + flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; + if (gui_fullscreen) { + flags |= SDL_FULLSCREEN; + } else { + flags |= SDL_RESIZABLE; + } + if (gui_noframe) + flags |= SDL_NOFRAME; + + tmp_screen = SDL_SetVideoMode(width, height, bpp, flags); + if (!real_screen) { + if (!tmp_screen) { + fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", + width, height, bpp, SDL_GetError()); + exit(1); + } + } else { + /* + * Revert to the previous video mode if the change of resizing or + * resolution failed. + */ + if (!tmp_screen) { + fprintf(stderr, "Failed to set SDL display (%dx%dx%d): %s\n", + width, height, bpp, SDL_GetError()); + return; + } + } + + real_screen = tmp_screen; +} + +static void sdl_switch(DisplayChangeListener *dcl, + DisplaySurface *new_surface) +{ + PixelFormat pf; + + /* temporary hack: allows to call sdl_switch to handle scaling changes */ + if (new_surface) { + surface = new_surface; + } + pf = qemu_pixelformat_from_pixman(surface->format); + + if (!scaling_active) { + do_sdl_resize(surface_width(surface), surface_height(surface), 0); + } else if (real_screen->format->BitsPerPixel != + surface_bits_per_pixel(surface)) { + do_sdl_resize(real_screen->w, real_screen->h, + surface_bits_per_pixel(surface)); + } + + if (guest_screen != NULL) { + SDL_FreeSurface(guest_screen); + } + +#ifdef DEBUG_SDL + printf("SDL: Creating surface with masks: %08x %08x %08x %08x\n", + pf.rmask, pf.gmask, pf.bmask, pf.amask); +#endif + + guest_screen = SDL_CreateRGBSurfaceFrom + (surface_data(surface), + surface_width(surface), surface_height(surface), + surface_bits_per_pixel(surface), surface_stride(surface), + pf.rmask, pf.gmask, + pf.bmask, pf.amask); +} + +static bool sdl_check_format(DisplayChangeListener *dcl, + pixman_format_code_t format) +{ + /* + * We let SDL convert for us a few more formats than, + * the native ones. Thes are the ones I have tested. + */ + return (format == PIXMAN_x8r8g8b8 || + format == PIXMAN_b8g8r8x8 || + format == PIXMAN_x1r5g5b5 || + format == PIXMAN_r5g6b5); +} + +/* generic keyboard conversion */ + +#include "sdl_keysym.h" + +static kbd_layout_t *kbd_layout = NULL; + +static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) +{ + int keysym; + /* workaround for X11+SDL bug with AltGR */ + keysym = ev->keysym.sym; + if (keysym == 0 && ev->keysym.scancode == 113) + keysym = SDLK_MODE; + /* For Japanese key '\' and '|' */ + if (keysym == 92 && ev->keysym.scancode == 133) { + keysym = 0xa5; + } + return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK; +} + +/* specific keyboard conversions from scan codes */ + +#if defined(_WIN32) + +static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) +{ + return ev->keysym.scancode; +} + +#else + +#if defined(SDL_VIDEO_DRIVER_X11) +#include + +static int check_for_evdev(void) +{ + SDL_SysWMinfo info; + XkbDescPtr desc = NULL; + int has_evdev = 0; + char *keycodes = NULL; + + SDL_VERSION(&info.version); + if (!SDL_GetWMInfo(&info)) { + return 0; + } + desc = XkbGetKeyboard(info.info.x11.display, + XkbGBN_AllComponentsMask, + XkbUseCoreKbd); + if (desc && desc->names) { + keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes); + if (keycodes == NULL) { + fprintf(stderr, "could not lookup keycode name\n"); + } else if (strstart(keycodes, "evdev", NULL)) { + has_evdev = 1; + } else if (!strstart(keycodes, "xfree86", NULL)) { + fprintf(stderr, "unknown keycodes `%s', please report to " + "qemu-devel@nongnu.org\n", keycodes); + } + } + + if (desc) { + XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); + } + if (keycodes) { + XFree(keycodes); + } + return has_evdev; +} +#else +static int check_for_evdev(void) +{ + return 0; +} +#endif + +static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) +{ + int keycode; + static int has_evdev = -1; + + if (has_evdev == -1) + has_evdev = check_for_evdev(); + + keycode = ev->keysym.scancode; + + if (keycode < 9) { + keycode = 0; + } else if (keycode < 97) { + keycode -= 8; /* just an offset */ + } else if (keycode < 158) { + /* use conversion table */ + if (has_evdev) + keycode = translate_evdev_keycode(keycode - 97); + else + keycode = translate_xfree86_keycode(keycode - 97); + } else if (keycode == 208) { /* Hiragana_Katakana */ + keycode = 0x70; + } else if (keycode == 211) { /* backslash */ + keycode = 0x73; + } else { + keycode = 0; + } + return keycode; +} + +#endif + +static void reset_keys(void) +{ + int i; + for(i = 0; i < 256; i++) { + if (modifiers_state[i]) { + qemu_input_event_send_key_number(dcl->con, i, false); + modifiers_state[i] = 0; + } + } +} + +static void sdl_process_key(SDL_KeyboardEvent *ev) +{ + int keycode; + + if (ev->keysym.sym == SDLK_PAUSE) { + /* specific case */ + qemu_input_event_send_key_qcode(dcl->con, Q_KEY_CODE_PAUSE, + ev->type == SDL_KEYDOWN); + return; + } + + if (kbd_layout) { + keycode = sdl_keyevent_to_keycode_generic(ev); + } else { + keycode = sdl_keyevent_to_keycode(ev); + } + + switch(keycode) { + case 0x00: + /* sent when leaving window: reset the modifiers state */ + reset_keys(); + return; + case 0x2a: /* Left Shift */ + case 0x36: /* Right Shift */ + case 0x1d: /* Left CTRL */ + case 0x9d: /* Right CTRL */ + case 0x38: /* Left ALT */ + case 0xb8: /* Right ALT */ + if (ev->type == SDL_KEYUP) + modifiers_state[keycode] = 0; + else + modifiers_state[keycode] = 1; + break; +#define QEMU_SDL_VERSION ((SDL_MAJOR_VERSION << 8) + SDL_MINOR_VERSION) +#if QEMU_SDL_VERSION < 0x102 || QEMU_SDL_VERSION == 0x102 && SDL_PATCHLEVEL < 14 + /* SDL versions before 1.2.14 don't support key up for caps/num lock. */ + case 0x45: /* num lock */ + case 0x3a: /* caps lock */ + /* SDL does not send the key up event, so we generate it */ + qemu_input_event_send_key_number(dcl->con, keycode, true); + qemu_input_event_send_key_number(dcl->con, keycode, false); + return; +#endif + } + + /* now send the key code */ + qemu_input_event_send_key_number(dcl->con, keycode, + ev->type == SDL_KEYDOWN); +} + +static void sdl_update_caption(void) +{ + char win_title[1024]; + char icon_title[1024]; + const char *status = ""; + + if (!runstate_is_running()) + status = " [Stopped]"; + else if (gui_grab) { + if (alt_grab) + status = " - Press Ctrl-Alt-Shift to exit mouse grab"; + else if (ctrl_grab) + status = " - Press Right-Ctrl to exit mouse grab"; + else + status = " - Press Ctrl-Alt to exit mouse grab"; + } + + if (qemu_name) { + snprintf(win_title, sizeof(win_title), "QEMU (%s)%s", qemu_name, status); + snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name); + } else { + snprintf(win_title, sizeof(win_title), "QEMU%s", status); + snprintf(icon_title, sizeof(icon_title), "QEMU"); + } + + SDL_WM_SetCaption(win_title, icon_title); +} + +static void sdl_hide_cursor(void) +{ + if (!cursor_hide) + return; + + if (qemu_input_is_absolute()) { + SDL_ShowCursor(1); + SDL_SetCursor(sdl_cursor_hidden); + } else { + SDL_ShowCursor(0); + } +} + +static void sdl_show_cursor(void) +{ + if (!cursor_hide) + return; + + if (!qemu_input_is_absolute() || !qemu_console_is_graphic(NULL)) { + SDL_ShowCursor(1); + if (guest_cursor && + (gui_grab || qemu_input_is_absolute() || absolute_enabled)) + SDL_SetCursor(guest_sprite); + else + SDL_SetCursor(sdl_cursor_normal); + } +} + +static void sdl_grab_start(void) +{ +#ifdef NO_MOUSE + return; +#endif + /* + * If the application is not active, do not try to enter grab state. This + * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the + * application (SDL bug). + */ + if (!(SDL_GetAppState() & SDL_APPINPUTFOCUS)) { + return; + } + if (guest_cursor) { + SDL_SetCursor(guest_sprite); + if (!qemu_input_is_absolute() && !absolute_enabled) { + SDL_WarpMouse(guest_x, guest_y); + } + } else + sdl_hide_cursor(); + SDL_WM_GrabInput(SDL_GRAB_ON); + gui_grab = 1; + sdl_update_caption(); +} + +static void sdl_grab_end(void) +{ +#ifdef NO_MOUSE + return; +#endif + SDL_WM_GrabInput(SDL_GRAB_OFF); + gui_grab = 0; + sdl_show_cursor(); + sdl_update_caption(); +} + +static void absolute_mouse_grab(void) +{ + int mouse_x, mouse_y; + + SDL_GetMouseState(&mouse_x, &mouse_y); + if (mouse_x > 0 && mouse_x < real_screen->w - 1 && + mouse_y > 0 && mouse_y < real_screen->h - 1) { + sdl_grab_start(); + } +} + +static void sdl_mouse_mode_change(Notifier *notify, void *data) +{ + if (qemu_input_is_absolute()) { + if (!absolute_enabled) { + absolute_enabled = 1; + if (qemu_console_is_graphic(NULL)) { + absolute_mouse_grab(); + } + } + } else if (absolute_enabled) { + if (!gui_fullscreen) { + sdl_grab_end(); + } + absolute_enabled = 0; + } +} + +static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state) +{ + static uint32_t bmap[INPUT_BUTTON_MAX] = { + [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), + [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), + [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), + [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), + [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), + }; + static uint32_t prev_state; + + if (prev_state != state) { + qemu_input_update_buttons(dcl->con, bmap, prev_state, state); + prev_state = state; + } + + if (qemu_input_is_absolute()) { + qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x, + real_screen->w); + qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y, + real_screen->h); + } else { + if (guest_cursor) { + x -= guest_x; + y -= guest_y; + guest_x += x; + guest_y += y; + dx = x; + dy = y; + } + qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, dx); + qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, dy); + } + qemu_input_event_sync(); +} + +static void sdl_scale(int width, int height) +{ + int bpp = real_screen->format->BitsPerPixel; + +#ifdef DEBUG_SDL + printf("SDL: Scaling to %dx%d bpp %d\n", width, height, bpp); +#endif + + if (bpp != 16 && bpp != 32) { + bpp = 32; + } + do_sdl_resize(width, height, bpp); + scaling_active = 1; +} + +static void toggle_full_screen(void) +{ + int width = surface_width(surface); + int height = surface_height(surface); + int bpp = surface_bits_per_pixel(surface); + + gui_fullscreen = !gui_fullscreen; + if (gui_fullscreen) { + gui_saved_width = real_screen->w; + gui_saved_height = real_screen->h; + gui_saved_scaling = scaling_active; + + do_sdl_resize(width, height, bpp); + scaling_active = 0; + + gui_saved_grab = gui_grab; + sdl_grab_start(); + } else { + if (gui_saved_scaling) { + sdl_scale(gui_saved_width, gui_saved_height); + } else { + do_sdl_resize(width, height, 0); + } + if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) { + sdl_grab_end(); + } + } + graphic_hw_invalidate(NULL); + graphic_hw_update(NULL); +} + +static void handle_keydown(SDL_Event *ev) +{ + int mod_state; + int keycode; + + if (alt_grab) { + mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == + (gui_grab_code | KMOD_LSHIFT); + } else if (ctrl_grab) { + mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; + } else { + mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code; + } + gui_key_modifier_pressed = mod_state; + + if (gui_key_modifier_pressed) { + keycode = sdl_keyevent_to_keycode(&ev->key); + switch (keycode) { + case 0x21: /* 'f' key on US keyboard */ + toggle_full_screen(); + gui_keysym = 1; + break; + case 0x16: /* 'u' key on US keyboard */ + if (scaling_active) { + scaling_active = 0; + sdl_switch(dcl, NULL); + graphic_hw_invalidate(NULL); + graphic_hw_update(NULL); + } + gui_keysym = 1; + break; + case 0x02 ... 0x0a: /* '1' to '9' keys */ + /* Reset the modifiers sent to the current console */ + reset_keys(); + console_select(keycode - 0x02); + gui_keysym = 1; + if (gui_fullscreen) { + break; + } + if (!qemu_console_is_graphic(NULL)) { + /* release grab if going to a text console */ + if (gui_grab) { + sdl_grab_end(); + } else if (absolute_enabled) { + sdl_show_cursor(); + } + } else if (absolute_enabled) { + sdl_hide_cursor(); + absolute_mouse_grab(); + } + break; + case 0x1b: /* '+' */ + case 0x35: /* '-' */ + if (!gui_fullscreen) { + int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50), + 160); + int height = (surface_height(surface) * width) / + surface_width(surface); + + sdl_scale(width, height); + graphic_hw_invalidate(NULL); + graphic_hw_update(NULL); + gui_keysym = 1; + } + default: + break; + } + } else if (!qemu_console_is_graphic(NULL)) { + int keysym = 0; + + if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { + switch (ev->key.keysym.sym) { + case SDLK_UP: + keysym = QEMU_KEY_CTRL_UP; + break; + case SDLK_DOWN: + keysym = QEMU_KEY_CTRL_DOWN; + break; + case SDLK_LEFT: + keysym = QEMU_KEY_CTRL_LEFT; + break; + case SDLK_RIGHT: + keysym = QEMU_KEY_CTRL_RIGHT; + break; + case SDLK_HOME: + keysym = QEMU_KEY_CTRL_HOME; + break; + case SDLK_END: + keysym = QEMU_KEY_CTRL_END; + break; + case SDLK_PAGEUP: + keysym = QEMU_KEY_CTRL_PAGEUP; + break; + case SDLK_PAGEDOWN: + keysym = QEMU_KEY_CTRL_PAGEDOWN; + break; + default: + break; + } + } else { + switch (ev->key.keysym.sym) { + case SDLK_UP: + keysym = QEMU_KEY_UP; + break; + case SDLK_DOWN: + keysym = QEMU_KEY_DOWN; + break; + case SDLK_LEFT: + keysym = QEMU_KEY_LEFT; + break; + case SDLK_RIGHT: + keysym = QEMU_KEY_RIGHT; + break; + case SDLK_HOME: + keysym = QEMU_KEY_HOME; + break; + case SDLK_END: + keysym = QEMU_KEY_END; + break; + case SDLK_PAGEUP: + keysym = QEMU_KEY_PAGEUP; + break; + case SDLK_PAGEDOWN: + keysym = QEMU_KEY_PAGEDOWN; + break; + case SDLK_BACKSPACE: + keysym = QEMU_KEY_BACKSPACE; + break; + case SDLK_DELETE: + keysym = QEMU_KEY_DELETE; + break; + default: + break; + } + } + if (keysym) { + kbd_put_keysym(keysym); + } else if (ev->key.keysym.unicode != 0) { + kbd_put_keysym(ev->key.keysym.unicode); + } + } + if (qemu_console_is_graphic(NULL) && !gui_keysym) { + sdl_process_key(&ev->key); + } +} + +static void handle_keyup(SDL_Event *ev) +{ + int mod_state; + + if (!alt_grab) { + mod_state = (ev->key.keysym.mod & gui_grab_code); + } else { + mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT)); + } + if (!mod_state && gui_key_modifier_pressed) { + gui_key_modifier_pressed = 0; + if (gui_keysym == 0) { + /* exit/enter grab if pressing Ctrl-Alt */ + if (!gui_grab) { + if (qemu_console_is_graphic(NULL)) { + sdl_grab_start(); + } + } else if (!gui_fullscreen) { + sdl_grab_end(); + } + /* SDL does not send back all the modifiers key, so we must + * correct it. */ + reset_keys(); + return; + } + gui_keysym = 0; + } + if (qemu_console_is_graphic(NULL) && !gui_keysym) { + sdl_process_key(&ev->key); + } +} + +static void handle_mousemotion(SDL_Event *ev) +{ + int max_x, max_y; + + if (qemu_console_is_graphic(NULL) && + (qemu_input_is_absolute() || absolute_enabled)) { + max_x = real_screen->w - 1; + max_y = real_screen->h - 1; + if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 || + ev->motion.x == max_x || ev->motion.y == max_y)) { + sdl_grab_end(); + } + if (!gui_grab && + (ev->motion.x > 0 && ev->motion.x < max_x && + ev->motion.y > 0 && ev->motion.y < max_y)) { + sdl_grab_start(); + } + } + if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { + sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, + ev->motion.x, ev->motion.y, ev->motion.state); + } +} + +static void handle_mousebutton(SDL_Event *ev) +{ + int buttonstate = SDL_GetMouseState(NULL, NULL); + SDL_MouseButtonEvent *bev; + + if (!qemu_console_is_graphic(NULL)) { + return; + } + + bev = &ev->button; + if (!gui_grab && !qemu_input_is_absolute()) { + if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) { + /* start grabbing all events */ + sdl_grab_start(); + } + } else { + if (ev->type == SDL_MOUSEBUTTONDOWN) { + buttonstate |= SDL_BUTTON(bev->button); + } else { + buttonstate &= ~SDL_BUTTON(bev->button); + } + sdl_send_mouse_event(0, 0, bev->x, bev->y, buttonstate); + } +} + +static void handle_activation(SDL_Event *ev) +{ +#ifdef _WIN32 + /* Disable grab if the window no longer has the focus + * (Windows-only workaround) */ + if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS && + !ev->active.gain && !gui_fullscreen) { + sdl_grab_end(); + } +#endif + if (!gui_grab && ev->active.gain && qemu_console_is_graphic(NULL) && + (qemu_input_is_absolute() || absolute_enabled)) { + absolute_mouse_grab(); + } + if (ev->active.state & SDL_APPACTIVE) { + if (ev->active.gain) { + /* Back to default interval */ + update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT); + } else { + /* Sleeping interval. Not using the long default here as + * sdl_refresh does not only update the guest screen, but + * also checks for gui events. */ + update_displaychangelistener(dcl, 500); + } + } +} + +static void sdl_refresh(DisplayChangeListener *dcl) +{ + SDL_Event ev1, *ev = &ev1; + + if (last_vm_running != runstate_is_running()) { + last_vm_running = runstate_is_running(); + sdl_update_caption(); + } + + graphic_hw_update(NULL); + SDL_EnableUNICODE(!qemu_console_is_graphic(NULL)); + + while (SDL_PollEvent(ev)) { + switch (ev->type) { + case SDL_VIDEOEXPOSE: + sdl_update(dcl, 0, 0, real_screen->w, real_screen->h); + break; + case SDL_KEYDOWN: + handle_keydown(ev); + break; + case SDL_KEYUP: + handle_keyup(ev); + break; + case SDL_QUIT: + if (!no_quit) { + no_shutdown = 0; + qemu_system_shutdown_request(); + } + break; + case SDL_MOUSEMOTION: + handle_mousemotion(ev); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + handle_mousebutton(ev); + break; + case SDL_ACTIVEEVENT: + handle_activation(ev); + break; + case SDL_VIDEORESIZE: + sdl_scale(ev->resize.w, ev->resize.h); + graphic_hw_invalidate(NULL); + graphic_hw_update(NULL); + break; + default: + break; + } + } +} + +static void sdl_mouse_warp(DisplayChangeListener *dcl, + int x, int y, int on) +{ + if (on) { + if (!guest_cursor) + sdl_show_cursor(); + if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { + SDL_SetCursor(guest_sprite); + if (!qemu_input_is_absolute() && !absolute_enabled) { + SDL_WarpMouse(x, y); + } + } + } else if (gui_grab) + sdl_hide_cursor(); + guest_cursor = on; + guest_x = x, guest_y = y; +} + +static void sdl_mouse_define(DisplayChangeListener *dcl, + QEMUCursor *c) +{ + uint8_t *image, *mask; + int bpl; + + if (guest_sprite) + SDL_FreeCursor(guest_sprite); + + bpl = cursor_get_mono_bpl(c); + image = g_malloc0(bpl * c->height); + mask = g_malloc0(bpl * c->height); + cursor_get_mono_image(c, 0x000000, image); + cursor_get_mono_mask(c, 0, mask); + guest_sprite = SDL_CreateCursor(image, mask, c->width, c->height, + c->hot_x, c->hot_y); + g_free(image); + g_free(mask); + + if (guest_cursor && + (gui_grab || qemu_input_is_absolute() || absolute_enabled)) + SDL_SetCursor(guest_sprite); +} + +static void sdl_cleanup(void) +{ + if (guest_sprite) + SDL_FreeCursor(guest_sprite); + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + +static const DisplayChangeListenerOps dcl_ops = { + .dpy_name = "sdl", + .dpy_gfx_update = sdl_update, + .dpy_gfx_switch = sdl_switch, + .dpy_gfx_check_format = sdl_check_format, + .dpy_refresh = sdl_refresh, + .dpy_mouse_set = sdl_mouse_warp, + .dpy_cursor_define = sdl_mouse_define, +}; + +void sdl_display_early_init(int opengl) +{ + if (opengl == 1 /* on */) { + fprintf(stderr, + "SDL1 display code has no opengl support.\n" + "Please recompile qemu with SDL2, using\n" + "./configure --enable-sdl --with-sdlabi=2.0\n"); + } +} + +void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) +{ + int flags; + uint8_t data = 0; + const SDL_VideoInfo *vi; + char *filename; + +#if defined(__APPLE__) + /* always use generic keymaps */ + if (!keyboard_layout) + keyboard_layout = "en-us"; +#endif + if(keyboard_layout) { + kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout); + if (!kbd_layout) + exit(1); + } + + if (no_frame) + gui_noframe = 1; + + if (!full_screen) { + setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0); + } +#ifdef __linux__ + /* on Linux, SDL may use fbcon|directfb|svgalib when run without + * accessible $DISPLAY to open X11 window. This is often the case + * when qemu is run using sudo. But in this case, and when actually + * run in X11 environment, SDL fights with X11 for the video card, + * making current display unavailable, often until reboot. + * So make x11 the default SDL video driver if this variable is unset. + * This is a bit hackish but saves us from bigger problem. + * Maybe it's a good idea to fix this in SDL instead. + */ + setenv("SDL_VIDEODRIVER", "x11", 0); +#endif + + /* Enable normal up/down events for Caps-Lock and Num-Lock keys. + * This requires SDL >= 1.2.14. */ + setenv("SDL_DISABLE_LOCK_KEYS", "1", 1); + + flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE; + if (SDL_Init (flags)) { + fprintf(stderr, "Could not initialize SDL(%s) - exiting\n", + SDL_GetError()); + exit(1); + } + vi = SDL_GetVideoInfo(); + host_format = *(vi->vfmt); + + /* Load a 32x32x4 image. White pixels are transparent. */ + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp"); + if (filename) { + SDL_Surface *image = SDL_LoadBMP(filename); + if (image) { + uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255); + SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey); + SDL_WM_SetIcon(image, NULL); + } + g_free(filename); + } + + if (full_screen) { + gui_fullscreen = 1; + sdl_grab_start(); + } + + dcl = g_new0(DisplayChangeListener, 1); + dcl->ops = &dcl_ops; + register_displaychangelistener(dcl); + + mouse_mode_notifier.notify = sdl_mouse_mode_change; + qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier); + + sdl_update_caption(); + SDL_EnableKeyRepeat(250, 50); + gui_grab = 0; + + sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0); + sdl_cursor_normal = SDL_GetCursor(); + + atexit(sdl_cleanup); +} diff --git a/ui/sdl2.c b/ui/sdl2.c index 3c9424eb42c3f..f70e7e55079a8 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -197,6 +197,9 @@ static void sdl_show_cursor(struct sdl2_console *scon) static void sdl_grab_start(struct sdl2_console *scon) { +#ifdef NO_MOUSE + return; +#endif QemuConsole *con = scon ? scon->dcl.con : NULL; if (!con || !qemu_console_is_graphic(con)) { @@ -225,6 +228,9 @@ static void sdl_grab_start(struct sdl2_console *scon) static void sdl_grab_end(struct sdl2_console *scon) { +#ifdef NO_MOUSE + return; +#endif SDL_SetWindowGrab(scon->real_window, SDL_FALSE); gui_grab = 0; sdl_show_cursor(scon); diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 95c9703c72401..64da1ef10ad33 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -45,6 +45,37 @@ static void vncws_tls_handshake_done(QIOTask *task, } } +<<<<<<< HEAD +======= +void vncws_tls_handshake_io(void *opaque) +{ + VncState *vs = (VncState *)opaque; + Error *err = NULL; + + if (!vs->tls) { + vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds, + NULL, + vs->vd->tlsaclname, + QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, + &err); + } + if (!vs->tls) { + VNC_DEBUG("Failed to setup TLS %s\n", + error_get_pretty(err)); + error_free(err); + vnc_client_error(vs); + return; + } + + qcrypto_tls_session_set_callbacks(vs->tls, + vnc_tls_push, + vnc_tls_pull, + vs); + + VNC_DEBUG("Start TLS WS handshake process\n"); + vncws_start_tls_handshake(vs); +} +>>>>>>> 919b29ba7d... Pebble Qemu gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED, GIOCondition condition G_GNUC_UNUSED, diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 838980aaa55b4..f01449736fd8d 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -541,11 +541,15 @@ void qemu_thread_create(QemuThread *thread, const char *name, /* Leave signal handling to the iothread. */ sigfillset(&set); +<<<<<<< HEAD /* Blocking the signals can result in undefined behaviour. */ sigdelset(&set, SIGSEGV); sigdelset(&set, SIGFPE); sigdelset(&set, SIGILL); /* TODO avoid SIGBUS loss on macOS */ +======= + sigemptyset(&oldset); /* keeps valgrind happy */ +>>>>>>> 919b29ba7d... Pebble Qemu pthread_sigmask(SIG_SETMASK, &set, &oldset); qemu_thread_args = g_new0(QemuThreadArgs, 1); From 12c1f6847daa6fda2c3fbc972693d2939aa194c9 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Sat, 5 Sep 2020 01:55:00 +0200 Subject: [PATCH 2/2] Make stuff run --- CMakeLists.txt | 8 +- Makefile | 22 - Makefile.objs | 6 - README.rst | 71 - VERSION | 4 - block/qcow2-cache.c | 4 - block/qcow2.c | 9 - block/quorum.c | 4 - block/raw-posix.c | 2634 ------- configure | 9 +- crypto/tlssession.c | 3 +- default-configs/arm-softmmu.mak | 83 +- docs/qapi-code-gen.txt | 1183 --- hw/arm/Kconfig | 4 + hw/arm/Makefile.objs | 3 - hw/arm/armv7m.c | 141 - hw/arm/pebble.c | 38 +- hw/arm/pebble.h | 3 - hw/arm/pebble_control.c | 28 +- hw/arm/pebble_control.h | 4 +- hw/arm/pebble_robert.c | 9 +- hw/arm/pebble_silk.c | 8 +- hw/arm/stellaris.c | 5 - hw/arm/stm32.c | 6 +- hw/arm/stm32_clktree.c | 2 + hw/arm/stm32_exti.c | 19 +- hw/arm/stm32_flash.c | 18 +- hw/arm/stm32_p103.c | 7 +- hw/arm/stm32_rcc.c | 19 +- hw/arm/stm32f1xx.c | 6 +- hw/arm/stm32f1xx_rcc.c | 27 +- hw/arm/stm32f205_soc.c | 5 - hw/arm/stm32f2xx.c | 158 +- hw/arm/stm32f2xx_adc.c | 20 +- hw/arm/stm32f2xx_crc.c | 22 +- hw/arm/stm32f2xx_dma.c | 23 +- hw/arm/stm32f2xx_dummy.c | 20 +- hw/arm/stm32f2xx_flash.c | 33 +- hw/arm/stm32f2xx_gpio.c | 21 +- hw/arm/stm32f2xx_i2c.c | 20 +- hw/arm/stm32f2xx_pwr.c | 21 +- hw/arm/stm32f2xx_rcc.c | 22 +- hw/arm/stm32f2xx_rtc.c | 24 +- hw/arm/stm32f2xx_syscfg.c | 20 +- hw/arm/stm32f2xx_tim.c | 21 +- hw/arm/stm32f4xx.c | 161 +- hw/arm/stm32f7xx.c | 57 +- hw/arm/stm32f7xx_i2c.c | 16 +- hw/arm/stm32f7xx_lptim.c | 20 +- hw/block/Makefile.objs | 6 +- hw/block/m25p80.c | 5 +- hw/block/mt25q.c | 44 +- hw/block/mx25u.c | 44 +- hw/block/pflash_jedec_424.c | 216 +- hw/char/Makefile.objs | 8 +- hw/char/stm32_uart.c | 31 +- hw/char/stm32f7xx_uart.c | 23 +- hw/core/irq.c | 35 +- hw/core/qdev.c | 3 +- hw/display/Makefile.objs | 6 +- hw/display/ls013b7dh01.c | 16 +- hw/display/pebble_snowy_display.c | 1 + hw/gpio/Makefile.objs | 7 +- hw/gpio/stm32_afio.c | 29 +- hw/gpio/stm32_exti.c | 12 +- hw/gpio/stm32_gpio.c | 15 +- hw/i386/kvm/pci-assign.c | 1901 ----- hw/i386/pc.c | 6 - hw/i386/pc_piix.c | 198 +- hw/ide/ahci.c | 30 - hw/intc/arm_gic.c | 6 - hw/intc/armv7m_nvic.c | 468 -- hw/net/vmxnet3.c | 8 - hw/ssi/Makefile.objs | 8 +- hw/ssi/stm32f2xx_spi.c | 211 - hw/ssi/stm32f2xx_spi_pbl.c | 224 + hw/ssi/stm32f412_qspi.c | 24 +- include/hw/arm/boot.h | 19 - include/hw/arm/stm32.h | 200 +- include/hw/block/flash.h | 40 +- include/hw/irq.h | 10 +- include/hw/sysbus.h | 7 - monitor.c | 4244 ---------- qemu-char.c | 4393 ----------- qtest.c | 92 +- target-arm/arm-semi.c | 660 -- target-arm/cpu.c | 1509 ---- target-arm/cpu.h | 2060 ----- target-arm/helper.c | 8971 --------------------- target-arm/internals.h | 445 -- target-arm/machine.c | 355 - target-arm/op_helper.c | 1009 --- target-arm/translate.c | 11688 ---------------------------- tests/Makefile | 674 -- tests/libqtest.c | 1060 --- tests/qemu-iotests/061.out | 30 +- tests/qemu-iotests/067.out | 301 - tests/qemu-iotests/071.out | 10 - tests/qemu-iotests/087.out | 6 - tests/qtest/libqtest.h | 389 +- tests/test-stm32.c | 311 - ui/cocoa.m | 35 +- ui/sdl.c | 1009 --- ui/vnc-ws.c | 31 - util/qemu-thread-posix.c | 4 - 105 files changed, 1171 insertions(+), 47047 deletions(-) delete mode 100644 block/raw-posix.c delete mode 100644 docs/qapi-code-gen.txt delete mode 100644 hw/i386/kvm/pci-assign.c create mode 100644 hw/ssi/stm32f2xx_spi_pbl.c delete mode 100644 monitor.c delete mode 100644 qemu-char.c delete mode 100644 target-arm/arm-semi.c delete mode 100644 target-arm/cpu.c delete mode 100644 target-arm/cpu.h delete mode 100644 target-arm/helper.c delete mode 100644 target-arm/internals.h delete mode 100644 target-arm/machine.c delete mode 100644 target-arm/op_helper.c delete mode 100644 target-arm/translate.c delete mode 100644 tests/Makefile delete mode 100644 tests/libqtest.c delete mode 100644 tests/test-stm32.c delete mode 100644 ui/sdl.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ce5a6fcf3c49..8d55c742daf17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,13 @@ project(qemu_dev) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -file(GLOB_RECURSE src "*.c") +file(GLOB_RECURSE src "*.c" ".h") set(SOURCES ${src}) -include_directories(include) -add_custom_target(qemu_dev COMMAND make - CLION_EXE_DIR=${PROJECT_BINARY_DIR}) +add_executable(qemu_dev ${SOURCES}) +target_compile_options(qemu_dev PRIVATE -iquote "${CMAKE_CURRENT_SOURCE_DIR}/include") +#target_include_directories(qemu_dev PRIVATE include) diff --git a/Makefile b/Makefile index 11d36c2423945..8a9113e6663eb 100644 --- a/Makefile +++ b/Makefile @@ -494,7 +494,6 @@ qemu-version.h: FORCE config-host.h: config-host.h-timestamp config-host.h-timestamp: config-host.mak -<<<<<<< HEAD qemu-options.def: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"GEN","$@") @@ -511,27 +510,6 @@ $(SOFTMMU_ALL_RULES): config-all-devices.mak ifdef DECOMPRESS_EDK2_BLOBS $(SOFTMMU_ALL_RULES): $(edk2-decompressed) endif -======= -qemu-options.def: $(SRC_PATH)/qemu-options.hx - $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") - -SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) -SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES)) - -$(SOFTMMU_SUBDIR_RULES): $(block-obj-y) -$(SOFTMMU_SUBDIR_RULES): $(crypto-obj-y) -$(SOFTMMU_SUBDIR_RULES): $(qom-obj-y) -$(SOFTMMU_SUBDIR_RULES): config-all-devices.mak - -subdir-%: - $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" all,) - -subdir-pixman: pixman/Makefile - $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" all,) - -pixman/Makefile: $(SRC_PATH)/pixman/configure - (cd pixman; CFLAGS="$(CFLAGS) -fPIC $(extra_cflags) $(extra_ldflags)" $(SRC_PATH)/pixman/configure $(AUTOCONF_HOST) --disable-gtk --disable-shared --enable-static) ->>>>>>> 919b29ba7d... Pebble Qemu SOFTMMU_FUZZ_RULES=$(filter %-softmmu/fuzz, $(TARGET_DIRS_RULES)) $(SOFTMMU_FUZZ_RULES): $(authz-obj-y) diff --git a/Makefile.objs b/Makefile.objs index bdcb689abdff0..69b6addb53169 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -1,14 +1,8 @@ ####################################################################### # Common libraries for tools and emulators stub-obj-y = stubs/ -<<<<<<< HEAD util-obj-y = crypto/ util/ qobject/ qapi/ qom-obj-y = qom/ -======= -util-obj-y = util/ qobject/ qapi/ -util-obj-y += crypto/ -util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o ->>>>>>> 919b29ba7d... Pebble Qemu ####################################################################### # code used by both qemu system emulation and qemu-img diff --git a/README.rst b/README.rst index 9e99bec861e01..7497709291dc9 100644 --- a/README.rst +++ b/README.rst @@ -1,77 +1,6 @@ -<<<<<<< HEAD:README.rst =========== QEMU README =========== -======= -QEMU with STM32 Microcontroller Implementation - -Official Homepage: http://beckus.github.io/qemu_stm32/ - -OVERVIEW -This is a copy of QEMU that has been modified to include an implementation -of the STM32 microcontroller. It also implements an Olimex STM32_P103 -developmentvboard. This project runs the demos located in the -stm32_p103_demos project located at: https://github.com/beckus/stm32_p103_demos . - -Commands for a typical build: -./configure --enable-debug --target-list="arm-softmmu" -make - -Useful make commands when rebuilding: - make defconfig - make clean - -The generated executable is arm-softmmu/qemu-system-arm . - -Other configure options which control the STM32 implementation: - - --extra-cflags=-DDEBUG_CLKTREE - Print out clock tree debug statements. - - --extra-cflags=-DDEBUG_STM32_RCC - Print RCC debug statements. - - --extra-cflags=-DDEBUG_STM32_UART - Print UART debug statements. - - --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY - Disable the BAUD rate timing simulation - (i.e. the UART will transmit or receive as fast as possible, rather than - using a realistic delay). - - --extra-cflags=-DSTM32_UART_ENABLE_OVERRUN - Enable setting of the overrun flag if a character is - received before the last one is processed. If this is not set, the UART - will not receive the next character until the previous one is read by - software. Although less realisitic, this is safer in case the VM is - running slow. - -Other QEMU configure options which are useful for troubleshooting: - --extra-cflags=-DDEBUG_GIC - -qemu-system-arm options which are useful for trobuleshooting: - -d ? - To see available log levels - - -d cpu,in_asm - Enable logging to view the CPU state during execution and the ARM - instructions which are being executed. I believe --enable-debug must be - used for this to work. - By default, you can find the output in /tmp/qemu.log: - -UNIT TESTING -Unit test scripts are included for the STM32 implementation. -These test will be executed when running "make" with the standard -check targets (see tests/Makefile for documentation of QEMU's unit -testing features): - make check - make check-qtest-arm - - - -The original QEMU README follows: - ->>>>>>> 919b29ba7d... Pebble Qemu:README QEMU is a generic and open source machine & userspace emulator and virtualizer. diff --git a/VERSION b/VERSION index 09854fb74eea1..0062ac971805f 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1 @@ -<<<<<<< HEAD 5.0.0 -======= -2.5.0-pebble4 ->>>>>>> 919b29ba7d... Pebble Qemu diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 72236433351ee..7444b9c4ab037 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -308,12 +308,8 @@ int qcow2_cache_empty(BlockDriverState *bs, Qcow2Cache *c) c->entries[i].offset = 0; c->entries[i].lru_counter = 0; } -<<<<<<< HEAD qcow2_cache_table_release(c, 0, c->size); -======= - qcow2_cache_table_release(bs, c, 0, c->size); ->>>>>>> 919b29ba7d... Pebble Qemu c->lru_counter = 0; diff --git a/block/qcow2.c b/block/qcow2.c index 18ed2c14ac6cd..b524b0c53f847 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1253,11 +1253,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, Error *local_err = NULL; uint64_t ext_end; uint64_t l1_vm_state_index; -<<<<<<< HEAD bool update_header = false; -======= - uint64_t l2_cache_size, refcount_cache_size; ->>>>>>> 919b29ba7d... Pebble Qemu ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); if (ret < 0) { @@ -1520,11 +1516,6 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, if (ret < 0) { goto fail; } - if (s->l2_table_cache == NULL || s->refcount_block_cache == NULL) { - error_setg(errp, "Could not allocate metadata caches"); - ret = -ENOMEM; - goto fail; - } s->flags = flags; diff --git a/block/quorum.c b/block/quorum.c index 01f45b8740c66..6d7a56bd93d8e 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -929,7 +929,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, } s->threshold = qemu_opt_get_number(opts, QUORUM_OPT_VOTE_THRESHOLD, 0); -<<<<<<< HEAD /* and validate it against s->num_children */ ret = quorum_valid_threshold(s->threshold, s->num_children, &local_err); if (ret < 0) { @@ -943,9 +942,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, ret = qapi_enum_parse(&QuorumReadPattern_lookup, pattern_str, -EINVAL, NULL); } -======= - ret = parse_read_pattern(qemu_opt_get(opts, QUORUM_OPT_READ_PATTERN)); ->>>>>>> 919b29ba7d... Pebble Qemu if (ret < 0) { error_setg(&local_err, "Please set read-pattern as fifo or quorum"); goto exit; diff --git a/block/raw-posix.c b/block/raw-posix.c deleted file mode 100644 index 5f19a40697777..0000000000000 --- a/block/raw-posix.c +++ /dev/null @@ -1,2634 +0,0 @@ -/* - * Block driver for RAW files (posix) - * - * Copyright (c) 2006 Fabrice Bellard - * - * 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-common.h" -#include "qemu/error-report.h" -#include "qemu/timer.h" -#include "qemu/log.h" -#include "block/block_int.h" -#include "qemu/module.h" -#include "trace.h" -#include "block/thread-pool.h" -#include "qemu/iov.h" -#include "raw-aio.h" -#include "qapi/util.h" -#include "qapi/qmp/qstring.h" - -#if defined(__APPLE__) && (__MACH__) -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#endif - -#ifdef __sun__ -#define _POSIX_PTHREAD_SEMANTICS 1 -#include -#endif -#ifdef __linux__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __s390__ -#include -#endif -#ifndef FS_NOCOW_FL -#define FS_NOCOW_FL 0x00800000 /* Do not cow file */ -#endif -#endif -#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_FALLOCATE_ZERO_RANGE) -#include -#endif -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#endif - -#ifdef __OpenBSD__ -#include -#include -#include -#endif - -#ifdef __NetBSD__ -#include -#include -#include -#include -#endif - -#ifdef __DragonFly__ -#include -#include -#endif - -#ifdef CONFIG_XFS -#include -#endif - -//#define DEBUG_BLOCK - -#ifdef DEBUG_BLOCK -# define DEBUG_BLOCK_PRINT 1 -#else -# define DEBUG_BLOCK_PRINT 0 -#endif -#define DPRINTF(fmt, ...) \ -do { \ - if (DEBUG_BLOCK_PRINT) { \ - printf(fmt, ## __VA_ARGS__); \ - } \ -} while (0) - -/* OS X does not have O_DSYNC */ -#ifndef O_DSYNC -#ifdef O_SYNC -#define O_DSYNC O_SYNC -#elif defined(O_FSYNC) -#define O_DSYNC O_FSYNC -#endif -#endif - -/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */ -#ifndef O_DIRECT -#define O_DIRECT O_DSYNC -#endif - -#define FTYPE_FILE 0 -#define FTYPE_CD 1 - -#define MAX_BLOCKSIZE 4096 - -typedef struct BDRVRawState { - int fd; - int type; - int open_flags; - size_t buf_align; - -#ifdef CONFIG_LINUX_AIO - int use_aio; - void *aio_ctx; -#endif -#ifdef CONFIG_XFS - bool is_xfs:1; -#endif - bool has_discard:1; - bool has_write_zeroes:1; - bool discard_zeroes:1; - bool has_fallocate; - bool needs_alignment; -} BDRVRawState; - -typedef struct BDRVRawReopenState { - int fd; - int open_flags; -#ifdef CONFIG_LINUX_AIO - int use_aio; -#endif -} BDRVRawReopenState; - -static int fd_open(BlockDriverState *bs); -static int64_t raw_getlength(BlockDriverState *bs); - -typedef struct RawPosixAIOData { - BlockDriverState *bs; - int aio_fildes; - union { - struct iovec *aio_iov; - void *aio_ioctl_buf; - }; - int aio_niov; - uint64_t aio_nbytes; -#define aio_ioctl_cmd aio_nbytes /* for QEMU_AIO_IOCTL */ - off_t aio_offset; - int aio_type; -} RawPosixAIOData; - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -static int cdrom_reopen(BlockDriverState *bs); -#endif - -#if defined(__NetBSD__) -static int raw_normalize_devicepath(const char **filename) -{ - static char namebuf[PATH_MAX]; - const char *dp, *fname; - struct stat sb; - - fname = *filename; - dp = strrchr(fname, '/'); - if (lstat(fname, &sb) < 0) { - fprintf(stderr, "%s: stat failed: %s\n", - fname, strerror(errno)); - return -errno; - } - - if (!S_ISBLK(sb.st_mode)) { - return 0; - } - - if (dp == NULL) { - snprintf(namebuf, PATH_MAX, "r%s", fname); - } else { - snprintf(namebuf, PATH_MAX, "%.*s/r%s", - (int)(dp - fname), fname, dp + 1); - } - fprintf(stderr, "%s is a block device", fname); - *filename = namebuf; - fprintf(stderr, ", using %s\n", *filename); - - return 0; -} -#else -static int raw_normalize_devicepath(const char **filename) -{ - return 0; -} -#endif - -/* - * Get logical block size via ioctl. On success store it in @sector_size_p. - */ -static int probe_logical_blocksize(int fd, unsigned int *sector_size_p) -{ - unsigned int sector_size; - bool success = false; - - errno = ENOTSUP; - - /* Try a few ioctls to get the right size */ -#ifdef BLKSSZGET - if (ioctl(fd, BLKSSZGET, §or_size) >= 0) { - *sector_size_p = sector_size; - success = true; - } -#endif -#ifdef DKIOCGETBLOCKSIZE - if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { - *sector_size_p = sector_size; - success = true; - } -#endif -#ifdef DIOCGSECTORSIZE - if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) { - *sector_size_p = sector_size; - success = true; - } -#endif - - return success ? 0 : -errno; -} - -/** - * Get physical block size of @fd. - * On success, store it in @blk_size and return 0. - * On failure, return -errno. - */ -static int probe_physical_blocksize(int fd, unsigned int *blk_size) -{ -#ifdef BLKPBSZGET - if (ioctl(fd, BLKPBSZGET, blk_size) < 0) { - return -errno; - } - return 0; -#else - return -ENOTSUP; -#endif -} - -/* Check if read is allowed with given memory buffer and length. - * - * This function is used to check O_DIRECT memory buffer and request alignment. - */ -static bool raw_is_io_aligned(int fd, void *buf, size_t len) -{ - ssize_t ret = pread(fd, buf, len, 0); - - if (ret >= 0) { - return true; - } - -#ifdef __linux__ - /* The Linux kernel returns EINVAL for misaligned O_DIRECT reads. Ignore - * other errors (e.g. real I/O error), which could happen on a failed - * drive, since we only care about probing alignment. - */ - if (errno != EINVAL) { - return true; - } -#endif - - return false; -} - -static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) -{ - BDRVRawState *s = bs->opaque; - char *buf; - size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize()); - - /* For SCSI generic devices the alignment is not really used. - With buffered I/O, we don't have any restrictions. */ - if (bdrv_is_sg(bs) || !s->needs_alignment) { - bs->request_alignment = 1; - s->buf_align = 1; - return; - } - - bs->request_alignment = 0; - s->buf_align = 0; - /* Let's try to use the logical blocksize for the alignment. */ - if (probe_logical_blocksize(fd, &bs->request_alignment) < 0) { - bs->request_alignment = 0; - } -#ifdef CONFIG_XFS - if (s->is_xfs) { - struct dioattr da; - if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) { - bs->request_alignment = da.d_miniosz; - /* The kernel returns wrong information for d_mem */ - /* s->buf_align = da.d_mem; */ - } - } -#endif - - /* If we could not get the sizes so far, we can only guess them */ - if (!s->buf_align) { - size_t align; - buf = qemu_memalign(max_align, 2 * max_align); - for (align = 512; align <= max_align; align <<= 1) { - if (raw_is_io_aligned(fd, buf + align, max_align)) { - s->buf_align = align; - break; - } - } - qemu_vfree(buf); - } - - if (!bs->request_alignment) { - size_t align; - buf = qemu_memalign(s->buf_align, max_align); - for (align = 512; align <= max_align; align <<= 1) { - if (raw_is_io_aligned(fd, buf, align)) { - bs->request_alignment = align; - break; - } - } - qemu_vfree(buf); - } - - if (!s->buf_align || !bs->request_alignment) { - error_setg(errp, "Could not find working O_DIRECT alignment. " - "Try cache.direct=off."); - } -} - -static void raw_parse_flags(int bdrv_flags, int *open_flags) -{ - assert(open_flags != NULL); - - *open_flags |= O_BINARY; - *open_flags &= ~O_ACCMODE; - if (bdrv_flags & BDRV_O_RDWR) { - *open_flags |= O_RDWR; - } else { - *open_flags |= O_RDONLY; - } - - /* Use O_DSYNC for write-through caching, no flags for write-back caching, - * and O_DIRECT for no caching. */ - if ((bdrv_flags & BDRV_O_NOCACHE)) { - *open_flags |= O_DIRECT; - } -} - -static void raw_detach_aio_context(BlockDriverState *bs) -{ -#ifdef CONFIG_LINUX_AIO - BDRVRawState *s = bs->opaque; - - if (s->use_aio) { - laio_detach_aio_context(s->aio_ctx, bdrv_get_aio_context(bs)); - } -#endif -} - -static void raw_attach_aio_context(BlockDriverState *bs, - AioContext *new_context) -{ -#ifdef CONFIG_LINUX_AIO - BDRVRawState *s = bs->opaque; - - if (s->use_aio) { - laio_attach_aio_context(s->aio_ctx, new_context); - } -#endif -} - -#ifdef CONFIG_LINUX_AIO -static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags) -{ - int ret = -1; - assert(aio_ctx != NULL); - assert(use_aio != NULL); - /* - * Currently Linux do AIO only for files opened with O_DIRECT - * specified so check NOCACHE flag too - */ - if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) == - (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) { - - /* if non-NULL, laio_init() has already been run */ - if (*aio_ctx == NULL) { - *aio_ctx = laio_init(); - if (!*aio_ctx) { - goto error; - } - } - *use_aio = 1; - } else { - *use_aio = 0; - } - - ret = 0; - -error: - return ret; -} -#endif - -static void raw_parse_filename(const char *filename, QDict *options, - Error **errp) -{ - /* The filename does not have to be prefixed by the protocol name, since - * "file" is the default protocol; therefore, the return value of this - * function call can be ignored. */ - strstart(filename, "file:", &filename); - - qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); -} - -static QemuOptsList raw_runtime_opts = { - .name = "raw", - .head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), - .desc = { - { - .name = "filename", - .type = QEMU_OPT_STRING, - .help = "File name of the image", - }, - { /* end of list */ } - }, -}; - -static int raw_open_common(BlockDriverState *bs, QDict *options, - int bdrv_flags, int open_flags, Error **errp) -{ - BDRVRawState *s = bs->opaque; - QemuOpts *opts; - Error *local_err = NULL; - const char *filename = NULL; - int fd, ret; - struct stat st; - - opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort); - qemu_opts_absorb_qdict(opts, options, &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret = -EINVAL; - goto fail; - } - - filename = qemu_opt_get(opts, "filename"); - - ret = raw_normalize_devicepath(&filename); - if (ret != 0) { - error_setg_errno(errp, -ret, "Could not normalize device path"); - goto fail; - } - - s->open_flags = open_flags; - raw_parse_flags(bdrv_flags, &s->open_flags); - - s->fd = -1; - fd = qemu_open(filename, s->open_flags, 0644); - if (fd < 0) { - ret = -errno; - if (ret == -EROFS) { - ret = -EACCES; - } - goto fail; - } - s->fd = fd; - -#ifdef CONFIG_LINUX_AIO - if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) { - qemu_close(fd); - ret = -errno; - error_setg_errno(errp, -ret, "Could not set AIO state"); - goto fail; - } - if (!s->use_aio && (bdrv_flags & BDRV_O_NATIVE_AIO)) { - error_printf("WARNING: aio=native was specified for '%s', but " - "it requires cache.direct=on, which was not " - "specified. Falling back to aio=threads.\n" - " This will become an error condition in " - "future QEMU versions.\n", - bs->filename); - } -#else - if (bdrv_flags & BDRV_O_NATIVE_AIO) { - error_printf("WARNING: aio=native was specified for '%s', but " - "is not supported in this build. Falling back to " - "aio=threads.\n" - " This will become an error condition in " - "future QEMU versions.\n", - bs->filename); - } -#endif /* !defined(CONFIG_LINUX_AIO) */ - - s->has_discard = true; - s->has_write_zeroes = true; - if ((bs->open_flags & BDRV_O_NOCACHE) != 0) { - s->needs_alignment = true; - } - - if (fstat(s->fd, &st) < 0) { - ret = -errno; - error_setg_errno(errp, errno, "Could not stat file"); - goto fail; - } - if (S_ISREG(st.st_mode)) { - s->discard_zeroes = true; - s->has_fallocate = true; - } - if (S_ISBLK(st.st_mode)) { -#ifdef BLKDISCARDZEROES - unsigned int arg; - if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) { - s->discard_zeroes = true; - } -#endif -#ifdef __linux__ - /* On Linux 3.10, BLKDISCARD leaves stale data in the page cache. Do - * not rely on the contents of discarded blocks unless using O_DIRECT. - * Same for BLKZEROOUT. - */ - if (!(bs->open_flags & BDRV_O_NOCACHE)) { - s->discard_zeroes = false; - s->has_write_zeroes = false; - } -#endif - } -#ifdef __FreeBSD__ - if (S_ISCHR(st.st_mode)) { - /* - * The file is a char device (disk), which on FreeBSD isn't behind - * a pager, so force all requests to be aligned. This is needed - * so QEMU makes sure all IO operations on the device are aligned - * to sector size, or else FreeBSD will reject them with EINVAL. - */ - s->needs_alignment = true; - } -#endif - -#ifdef CONFIG_XFS - if (platform_test_xfs_fd(s->fd)) { - s->is_xfs = true; - } -#endif - - raw_attach_aio_context(bs, bdrv_get_aio_context(bs)); - - ret = 0; -fail: - if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { - unlink(filename); - } - qemu_opts_del(opts); - return ret; -} - -static int raw_open(BlockDriverState *bs, QDict *options, int flags, - Error **errp) -{ - BDRVRawState *s = bs->opaque; - Error *local_err = NULL; - int ret; - - s->type = FTYPE_FILE; - ret = raw_open_common(bs, options, flags, 0, &local_err); - if (local_err) { - error_propagate(errp, local_err); - } - return ret; -} - -static int raw_reopen_prepare(BDRVReopenState *state, - BlockReopenQueue *queue, Error **errp) -{ - BDRVRawState *s; - BDRVRawReopenState *raw_s; - int ret = 0; - Error *local_err = NULL; - - assert(state != NULL); - assert(state->bs != NULL); - - s = state->bs->opaque; - - state->opaque = g_new0(BDRVRawReopenState, 1); - raw_s = state->opaque; - -#ifdef CONFIG_LINUX_AIO - raw_s->use_aio = s->use_aio; - - /* we can use s->aio_ctx instead of a copy, because the use_aio flag is - * valid in the 'false' condition even if aio_ctx is set, and raw_set_aio() - * won't override aio_ctx if aio_ctx is non-NULL */ - if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) { - error_setg(errp, "Could not set AIO state"); - return -1; - } -#endif - - if (s->type == FTYPE_CD) { - raw_s->open_flags |= O_NONBLOCK; - } - - raw_parse_flags(state->flags, &raw_s->open_flags); - - raw_s->fd = -1; - - int fcntl_flags = O_APPEND | O_NONBLOCK; -#ifdef O_NOATIME - fcntl_flags |= O_NOATIME; -#endif - -#ifdef O_ASYNC - /* Not all operating systems have O_ASYNC, and those that don't - * will not let us track the state into raw_s->open_flags (typically - * you achieve the same effect with an ioctl, for example I_SETSIG - * on Solaris). But we do not use O_ASYNC, so that's fine. - */ - assert((s->open_flags & O_ASYNC) == 0); -#endif - - if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) { - /* dup the original fd */ - /* TODO: use qemu fcntl wrapper */ -#ifdef F_DUPFD_CLOEXEC - raw_s->fd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0); -#else - raw_s->fd = dup(s->fd); - if (raw_s->fd != -1) { - qemu_set_cloexec(raw_s->fd); - } -#endif - if (raw_s->fd >= 0) { - ret = fcntl_setfl(raw_s->fd, raw_s->open_flags); - if (ret) { - qemu_close(raw_s->fd); - raw_s->fd = -1; - } - } - } - - /* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */ - if (raw_s->fd == -1) { - const char *normalized_filename = state->bs->filename; - ret = raw_normalize_devicepath(&normalized_filename); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not normalize device path"); - } else { - assert(!(raw_s->open_flags & O_CREAT)); - raw_s->fd = qemu_open(normalized_filename, raw_s->open_flags); - if (raw_s->fd == -1) { - error_setg_errno(errp, errno, "Could not reopen file"); - ret = -1; - } - } - } - - /* Fail already reopen_prepare() if we can't get a working O_DIRECT - * alignment with the new fd. */ - if (raw_s->fd != -1) { - raw_probe_alignment(state->bs, raw_s->fd, &local_err); - if (local_err) { - qemu_close(raw_s->fd); - raw_s->fd = -1; - error_propagate(errp, local_err); - ret = -EINVAL; - } - } - - return ret; -} - -static void raw_reopen_commit(BDRVReopenState *state) -{ - BDRVRawReopenState *raw_s = state->opaque; - BDRVRawState *s = state->bs->opaque; - - s->open_flags = raw_s->open_flags; - - qemu_close(s->fd); - s->fd = raw_s->fd; -#ifdef CONFIG_LINUX_AIO - s->use_aio = raw_s->use_aio; -#endif - - g_free(state->opaque); - state->opaque = NULL; -} - - -static void raw_reopen_abort(BDRVReopenState *state) -{ - BDRVRawReopenState *raw_s = state->opaque; - - /* nothing to do if NULL, we didn't get far enough */ - if (raw_s == NULL) { - return; - } - - if (raw_s->fd >= 0) { - qemu_close(raw_s->fd); - raw_s->fd = -1; - } - g_free(state->opaque); - state->opaque = NULL; -} - -static void raw_refresh_limits(BlockDriverState *bs, Error **errp) -{ - BDRVRawState *s = bs->opaque; - - raw_probe_alignment(bs, s->fd, errp); - bs->bl.min_mem_alignment = s->buf_align; - bs->bl.opt_mem_alignment = MAX(s->buf_align, getpagesize()); -} - -static int check_for_dasd(int fd) -{ -#ifdef BIODASDINFO2 - struct dasd_information2_t info = {0}; - - return ioctl(fd, BIODASDINFO2, &info); -#else - return -1; -#endif -} - -/** - * Try to get @bs's logical and physical block size. - * On success, store them in @bsz and return zero. - * On failure, return negative errno. - */ -static int hdev_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz) -{ - BDRVRawState *s = bs->opaque; - int ret; - - /* If DASD, get blocksizes */ - if (check_for_dasd(s->fd) < 0) { - return -ENOTSUP; - } - ret = probe_logical_blocksize(s->fd, &bsz->log); - if (ret < 0) { - return ret; - } - return probe_physical_blocksize(s->fd, &bsz->phys); -} - -/** - * Try to get @bs's geometry: cyls, heads, sectors. - * On success, store them in @geo and return 0. - * On failure return -errno. - * (Allows block driver to assign default geometry values that guest sees) - */ -#ifdef __linux__ -static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo) -{ - BDRVRawState *s = bs->opaque; - struct hd_geometry ioctl_geo = {0}; - uint32_t blksize; - - /* If DASD, get its geometry */ - if (check_for_dasd(s->fd) < 0) { - return -ENOTSUP; - } - if (ioctl(s->fd, HDIO_GETGEO, &ioctl_geo) < 0) { - return -errno; - } - /* HDIO_GETGEO may return success even though geo contains zeros - (e.g. certain multipath setups) */ - if (!ioctl_geo.heads || !ioctl_geo.sectors || !ioctl_geo.cylinders) { - return -ENOTSUP; - } - /* Do not return a geometry for partition */ - if (ioctl_geo.start != 0) { - return -ENOTSUP; - } - geo->heads = ioctl_geo.heads; - geo->sectors = ioctl_geo.sectors; - if (!probe_physical_blocksize(s->fd, &blksize)) { - /* overwrite cyls: HDIO_GETGEO result is incorrect for big drives */ - geo->cylinders = bdrv_nb_sectors(bs) / (blksize / BDRV_SECTOR_SIZE) - / (geo->heads * geo->sectors); - return 0; - } - geo->cylinders = ioctl_geo.cylinders; - - return 0; -} -#else /* __linux__ */ -static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo) -{ - return -ENOTSUP; -} -#endif - -static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) -{ - int ret; - - ret = ioctl(aiocb->aio_fildes, aiocb->aio_ioctl_cmd, aiocb->aio_ioctl_buf); - if (ret == -1) { - return -errno; - } - - return 0; -} - -static ssize_t handle_aiocb_flush(RawPosixAIOData *aiocb) -{ - int ret; - - ret = qemu_fdatasync(aiocb->aio_fildes); - if (ret == -1) { - return -errno; - } - return 0; -} - -#ifdef CONFIG_PREADV - -static bool preadv_present = true; - -static ssize_t -qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset) -{ - return preadv(fd, iov, nr_iov, offset); -} - -static ssize_t -qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset) -{ - return pwritev(fd, iov, nr_iov, offset); -} - -#else - -static bool preadv_present = false; - -static ssize_t -qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset) -{ - return -ENOSYS; -} - -static ssize_t -qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset) -{ - return -ENOSYS; -} - -#endif - -static ssize_t handle_aiocb_rw_vector(RawPosixAIOData *aiocb) -{ - ssize_t len; - - do { - if (aiocb->aio_type & QEMU_AIO_WRITE) - len = qemu_pwritev(aiocb->aio_fildes, - aiocb->aio_iov, - aiocb->aio_niov, - aiocb->aio_offset); - else - len = qemu_preadv(aiocb->aio_fildes, - aiocb->aio_iov, - aiocb->aio_niov, - aiocb->aio_offset); - } while (len == -1 && errno == EINTR); - - if (len == -1) { - return -errno; - } - return len; -} - -/* - * Read/writes the data to/from a given linear buffer. - * - * Returns the number of bytes handles or -errno in case of an error. Short - * reads are only returned if the end of the file is reached. - */ -static ssize_t handle_aiocb_rw_linear(RawPosixAIOData *aiocb, char *buf) -{ - ssize_t offset = 0; - ssize_t len; - - while (offset < aiocb->aio_nbytes) { - if (aiocb->aio_type & QEMU_AIO_WRITE) { - len = pwrite(aiocb->aio_fildes, - (const char *)buf + offset, - aiocb->aio_nbytes - offset, - aiocb->aio_offset + offset); - } else { - len = pread(aiocb->aio_fildes, - buf + offset, - aiocb->aio_nbytes - offset, - aiocb->aio_offset + offset); - } - if (len == -1 && errno == EINTR) { - continue; - } else if (len == -1 && errno == EINVAL && - (aiocb->bs->open_flags & BDRV_O_NOCACHE) && - !(aiocb->aio_type & QEMU_AIO_WRITE) && - offset > 0) { - /* O_DIRECT pread() may fail with EINVAL when offset is unaligned - * after a short read. Assume that O_DIRECT short reads only occur - * at EOF. Therefore this is a short read, not an I/O error. - */ - break; - } else if (len == -1) { - offset = -errno; - break; - } else if (len == 0) { - break; - } - offset += len; - } - - return offset; -} - -static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb) -{ - ssize_t nbytes; - char *buf; - - if (!(aiocb->aio_type & QEMU_AIO_MISALIGNED)) { - /* - * If there is just a single buffer, and it is properly aligned - * we can just use plain pread/pwrite without any problems. - */ - if (aiocb->aio_niov == 1) { - return handle_aiocb_rw_linear(aiocb, aiocb->aio_iov->iov_base); - } - /* - * We have more than one iovec, and all are properly aligned. - * - * Try preadv/pwritev first and fall back to linearizing the - * buffer if it's not supported. - */ - if (preadv_present) { - nbytes = handle_aiocb_rw_vector(aiocb); - if (nbytes == aiocb->aio_nbytes || - (nbytes < 0 && nbytes != -ENOSYS)) { - return nbytes; - } - preadv_present = false; - } - - /* - * XXX(hch): short read/write. no easy way to handle the reminder - * using these interfaces. For now retry using plain - * pread/pwrite? - */ - } - - /* - * Ok, we have to do it the hard way, copy all segments into - * a single aligned buffer. - */ - buf = qemu_try_blockalign(aiocb->bs, aiocb->aio_nbytes); - if (buf == NULL) { - return -ENOMEM; - } - - if (aiocb->aio_type & QEMU_AIO_WRITE) { - char *p = buf; - int i; - - for (i = 0; i < aiocb->aio_niov; ++i) { - memcpy(p, aiocb->aio_iov[i].iov_base, aiocb->aio_iov[i].iov_len); - p += aiocb->aio_iov[i].iov_len; - } - assert(p - buf == aiocb->aio_nbytes); - } - - nbytes = handle_aiocb_rw_linear(aiocb, buf); - if (!(aiocb->aio_type & QEMU_AIO_WRITE)) { - char *p = buf; - size_t count = aiocb->aio_nbytes, copy; - int i; - - for (i = 0; i < aiocb->aio_niov && count; ++i) { - copy = count; - if (copy > aiocb->aio_iov[i].iov_len) { - copy = aiocb->aio_iov[i].iov_len; - } - memcpy(aiocb->aio_iov[i].iov_base, p, copy); - assert(count >= copy); - p += copy; - count -= copy; - } - assert(count == 0); - } - qemu_vfree(buf); - - return nbytes; -} - -#ifdef CONFIG_XFS -static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes) -{ - struct xfs_flock64 fl; - int err; - - memset(&fl, 0, sizeof(fl)); - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = bytes; - - if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) { - err = errno; - DPRINTF("cannot write zero range (%s)\n", strerror(errno)); - return -err; - } - - return 0; -} - -static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes) -{ - struct xfs_flock64 fl; - int err; - - memset(&fl, 0, sizeof(fl)); - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = bytes; - - if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) { - err = errno; - DPRINTF("cannot punch hole (%s)\n", strerror(errno)); - return -err; - } - - return 0; -} -#endif - -static int translate_err(int err) -{ - if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP || - err == -ENOTTY) { - err = -ENOTSUP; - } - return err; -} - -#ifdef CONFIG_FALLOCATE -static int do_fallocate(int fd, int mode, off_t offset, off_t len) -{ - do { - if (fallocate(fd, mode, offset, len) == 0) { - return 0; - } - } while (errno == EINTR); - return translate_err(-errno); -} -#endif - -static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb) -{ - int ret = -ENOTSUP; - BDRVRawState *s = aiocb->bs->opaque; - - if (!s->has_write_zeroes) { - return -ENOTSUP; - } - -#ifdef BLKZEROOUT - do { - uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes }; - if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) { - return 0; - } - } while (errno == EINTR); - - ret = translate_err(-errno); -#endif - - if (ret == -ENOTSUP) { - s->has_write_zeroes = false; - } - return ret; -} - -static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb) -{ -#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS) - BDRVRawState *s = aiocb->bs->opaque; -#endif - - if (aiocb->aio_type & QEMU_AIO_BLKDEV) { - return handle_aiocb_write_zeroes_block(aiocb); - } - -#ifdef CONFIG_XFS - if (s->is_xfs) { - return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes); - } -#endif - -#ifdef CONFIG_FALLOCATE_ZERO_RANGE - if (s->has_write_zeroes) { - int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE, - aiocb->aio_offset, aiocb->aio_nbytes); - if (ret == 0 || ret != -ENOTSUP) { - return ret; - } - s->has_write_zeroes = false; - } -#endif - -#ifdef CONFIG_FALLOCATE_PUNCH_HOLE - if (s->has_discard && s->has_fallocate) { - int ret = do_fallocate(s->fd, - FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - aiocb->aio_offset, aiocb->aio_nbytes); - if (ret == 0) { - ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); - if (ret == 0 || ret != -ENOTSUP) { - return ret; - } - s->has_fallocate = false; - } else if (ret != -ENOTSUP) { - return ret; - } else { - s->has_discard = false; - } - } -#endif - -#ifdef CONFIG_FALLOCATE - if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) { - int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); - if (ret == 0 || ret != -ENOTSUP) { - return ret; - } else { - s->has_discard = false; - } - } -#endif - -#ifdef CONFIG_FALLOCATE - if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) { - int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); - if (ret == 0 || ret != -ENOTSUP) { - return ret; - } - s->has_fallocate = false; - } -#endif - - return -ENOTSUP; -} - -static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb) -{ - int ret = -EOPNOTSUPP; - BDRVRawState *s = aiocb->bs->opaque; - - if (!s->has_discard) { - return -ENOTSUP; - } - - if (aiocb->aio_type & QEMU_AIO_BLKDEV) { -#ifdef BLKDISCARD - do { - uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes }; - if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0) { - return 0; - } - } while (errno == EINTR); - - ret = -errno; -#endif - } else { -#ifdef CONFIG_XFS - if (s->is_xfs) { - return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes); - } -#endif - -#ifdef CONFIG_FALLOCATE_PUNCH_HOLE - ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - aiocb->aio_offset, aiocb->aio_nbytes); -#endif - } - - ret = translate_err(ret); - if (ret == -ENOTSUP) { - s->has_discard = false; - } - return ret; -} - -static int aio_worker(void *arg) -{ - RawPosixAIOData *aiocb = arg; - ssize_t ret = 0; - - switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { - case QEMU_AIO_READ: - ret = handle_aiocb_rw(aiocb); - if (ret >= 0 && ret < aiocb->aio_nbytes) { - iov_memset(aiocb->aio_iov, aiocb->aio_niov, ret, - 0, aiocb->aio_nbytes - ret); - - ret = aiocb->aio_nbytes; - } - if (ret == aiocb->aio_nbytes) { - ret = 0; - } else if (ret >= 0 && ret < aiocb->aio_nbytes) { - ret = -EINVAL; - } - break; - case QEMU_AIO_WRITE: - ret = handle_aiocb_rw(aiocb); - if (ret == aiocb->aio_nbytes) { - ret = 0; - } else if (ret >= 0 && ret < aiocb->aio_nbytes) { - ret = -EINVAL; - } - break; - case QEMU_AIO_FLUSH: - ret = handle_aiocb_flush(aiocb); - break; - case QEMU_AIO_IOCTL: - ret = handle_aiocb_ioctl(aiocb); - break; - case QEMU_AIO_DISCARD: - ret = handle_aiocb_discard(aiocb); - break; - case QEMU_AIO_WRITE_ZEROES: - ret = handle_aiocb_write_zeroes(aiocb); - break; - default: - fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type); - ret = -EINVAL; - break; - } - - g_free(aiocb); - return ret; -} - -static int paio_submit_co(BlockDriverState *bs, int fd, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - int type) -{ - RawPosixAIOData *acb = g_new(RawPosixAIOData, 1); - ThreadPool *pool; - - acb->bs = bs; - acb->aio_type = type; - acb->aio_fildes = fd; - - acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE; - acb->aio_offset = sector_num * BDRV_SECTOR_SIZE; - - if (qiov) { - acb->aio_iov = qiov->iov; - acb->aio_niov = qiov->niov; - assert(qiov->size == acb->aio_nbytes); - } - - trace_paio_submit_co(sector_num, nb_sectors, type); - pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); - return thread_pool_submit_co(pool, aio_worker, acb); -} - -static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque, int type) -{ - RawPosixAIOData *acb = g_new(RawPosixAIOData, 1); - ThreadPool *pool; - - acb->bs = bs; - acb->aio_type = type; - acb->aio_fildes = fd; - - acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE; - acb->aio_offset = sector_num * BDRV_SECTOR_SIZE; - - if (qiov) { - acb->aio_iov = qiov->iov; - acb->aio_niov = qiov->niov; - assert(qiov->size == acb->aio_nbytes); - } - - trace_paio_submit(acb, opaque, sector_num, nb_sectors, type); - pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); - return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); -} - -static BlockAIOCB *raw_aio_submit(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque, int type) -{ - BDRVRawState *s = bs->opaque; - - if (fd_open(bs) < 0) - return NULL; - - /* - * Check if the underlying device requires requests to be aligned, - * and if the request we are trying to submit is aligned or not. - * If this is the case tell the low-level driver that it needs - * to copy the buffer. - */ - if (s->needs_alignment) { - if (!bdrv_qiov_is_aligned(bs, qiov)) { - type |= QEMU_AIO_MISALIGNED; -#ifdef CONFIG_LINUX_AIO - } else if (s->use_aio) { - return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, - nb_sectors, cb, opaque, type); -#endif - } - } - - return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors, - cb, opaque, type); -} - -static void raw_aio_plug(BlockDriverState *bs) -{ -#ifdef CONFIG_LINUX_AIO - BDRVRawState *s = bs->opaque; - if (s->use_aio) { - laio_io_plug(bs, s->aio_ctx); - } -#endif -} - -static void raw_aio_unplug(BlockDriverState *bs) -{ -#ifdef CONFIG_LINUX_AIO - BDRVRawState *s = bs->opaque; - if (s->use_aio) { - laio_io_unplug(bs, s->aio_ctx, true); - } -#endif -} - -static void raw_aio_flush_io_queue(BlockDriverState *bs) -{ -#ifdef CONFIG_LINUX_AIO - BDRVRawState *s = bs->opaque; - if (s->use_aio) { - laio_io_unplug(bs, s->aio_ctx, false); - } -#endif -} - -static BlockAIOCB *raw_aio_readv(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) -{ - return raw_aio_submit(bs, sector_num, qiov, nb_sectors, - cb, opaque, QEMU_AIO_READ); -} - -static BlockAIOCB *raw_aio_writev(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) -{ - return raw_aio_submit(bs, sector_num, qiov, nb_sectors, - cb, opaque, QEMU_AIO_WRITE); -} - -static BlockAIOCB *raw_aio_flush(BlockDriverState *bs, - BlockCompletionFunc *cb, void *opaque) -{ - BDRVRawState *s = bs->opaque; - - if (fd_open(bs) < 0) - return NULL; - - return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH); -} - -static void raw_close(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - - raw_detach_aio_context(bs); - -#ifdef CONFIG_LINUX_AIO - if (s->use_aio) { - laio_cleanup(s->aio_ctx); - } -#endif - if (s->fd >= 0) { - qemu_close(s->fd); - s->fd = -1; - } -} - -static int raw_truncate(BlockDriverState *bs, int64_t offset) -{ - BDRVRawState *s = bs->opaque; - struct stat st; - - if (fstat(s->fd, &st)) { - return -errno; - } - - if (S_ISREG(st.st_mode)) { - if (ftruncate(s->fd, offset) < 0) { - return -errno; - } - } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { - if (offset > raw_getlength(bs)) { - return -EINVAL; - } - } else { - return -ENOTSUP; - } - - return 0; -} - -#ifdef __OpenBSD__ -static int64_t raw_getlength(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - int fd = s->fd; - struct stat st; - - if (fstat(fd, &st)) - return -errno; - if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { - struct disklabel dl; - - if (ioctl(fd, DIOCGDINFO, &dl)) - return -errno; - return (uint64_t)dl.d_secsize * - dl.d_partitions[DISKPART(st.st_rdev)].p_size; - } else - return st.st_size; -} -#elif defined(__NetBSD__) -static int64_t raw_getlength(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - int fd = s->fd; - struct stat st; - - if (fstat(fd, &st)) - return -errno; - if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { - struct dkwedge_info dkw; - - if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) { - return dkw.dkw_size * 512; - } else { - struct disklabel dl; - - if (ioctl(fd, DIOCGDINFO, &dl)) - return -errno; - return (uint64_t)dl.d_secsize * - dl.d_partitions[DISKPART(st.st_rdev)].p_size; - } - } else - return st.st_size; -} -#elif defined(__sun__) -static int64_t raw_getlength(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - struct dk_minfo minfo; - int ret; - int64_t size; - - ret = fd_open(bs); - if (ret < 0) { - return ret; - } - - /* - * Use the DKIOCGMEDIAINFO ioctl to read the size. - */ - ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo); - if (ret != -1) { - return minfo.dki_lbsize * minfo.dki_capacity; - } - - /* - * There are reports that lseek on some devices fails, but - * irc discussion said that contingency on contingency was overkill. - */ - size = lseek(s->fd, 0, SEEK_END); - if (size < 0) { - return -errno; - } - return size; -} -#elif defined(CONFIG_BSD) -static int64_t raw_getlength(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - int fd = s->fd; - int64_t size; - struct stat sb; -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) - int reopened = 0; -#endif - int ret; - - ret = fd_open(bs); - if (ret < 0) - return ret; - -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) -again: -#endif - if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { -#ifdef DIOCGMEDIASIZE - if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) -#elif defined(DIOCGPART) - { - struct partinfo pi; - if (ioctl(fd, DIOCGPART, &pi) == 0) - size = pi.media_size; - else - size = 0; - } - if (size == 0) -#endif -#if defined(__APPLE__) && defined(__MACH__) - { - uint64_t sectors = 0; - uint32_t sector_size = 0; - - if (ioctl(fd, DKIOCGETBLOCKCOUNT, §ors) == 0 - && ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) == 0) { - size = sectors * sector_size; - } else { - size = lseek(fd, 0LL, SEEK_END); - if (size < 0) { - return -errno; - } - } - } -#else - size = lseek(fd, 0LL, SEEK_END); - if (size < 0) { - return -errno; - } -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - switch(s->type) { - case FTYPE_CD: - /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */ - if (size == 2048LL * (unsigned)-1) - size = 0; - /* XXX no disc? maybe we need to reopen... */ - if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) { - reopened = 1; - goto again; - } - } -#endif - } else { - size = lseek(fd, 0, SEEK_END); - if (size < 0) { - return -errno; - } - } - return size; -} -#else -static int64_t raw_getlength(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - int ret; - int64_t size; - - ret = fd_open(bs); - if (ret < 0) { - return ret; - } - - size = lseek(s->fd, 0, SEEK_END); - if (size < 0) { - return -errno; - } - return size; -} -#endif - -static int64_t raw_get_allocated_file_size(BlockDriverState *bs) -{ - struct stat st; - BDRVRawState *s = bs->opaque; - - if (fstat(s->fd, &st) < 0) { - return -errno; - } - return (int64_t)st.st_blocks * 512; -} - -static int raw_create(const char *filename, QemuOpts *opts, Error **errp) -{ - int fd; - int result = 0; - int64_t total_size = 0; - bool nocow = false; - PreallocMode prealloc; - char *buf = NULL; - Error *local_err = NULL; - - strstart(filename, "file:", &filename); - - /* Read out options */ - total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), - BDRV_SECTOR_SIZE); - nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); - buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, buf, - PREALLOC_MODE_MAX, PREALLOC_MODE_OFF, - &local_err); - g_free(buf); - if (local_err) { - error_propagate(errp, local_err); - result = -EINVAL; - goto out; - } - - fd = qemu_open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, - 0644); - if (fd < 0) { - result = -errno; - error_setg_errno(errp, -result, "Could not create file"); - goto out; - } - - if (nocow) { -#ifdef __linux__ - /* Set NOCOW flag to solve performance issue on fs like btrfs. - * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value - * will be ignored since any failure of this operation should not - * block the left work. - */ - int attr; - if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) { - attr |= FS_NOCOW_FL; - ioctl(fd, FS_IOC_SETFLAGS, &attr); - } -#endif - } - - if (ftruncate(fd, total_size) != 0) { - result = -errno; - error_setg_errno(errp, -result, "Could not resize file"); - goto out_close; - } - - switch (prealloc) { -#ifdef CONFIG_POSIX_FALLOCATE - case PREALLOC_MODE_FALLOC: - /* posix_fallocate() doesn't set errno. */ - result = -posix_fallocate(fd, 0, total_size); - if (result != 0) { - error_setg_errno(errp, -result, - "Could not preallocate data for the new file"); - } - break; -#endif - case PREALLOC_MODE_FULL: - { - int64_t num = 0, left = total_size; - buf = g_malloc0(65536); - - while (left > 0) { - num = MIN(left, 65536); - result = write(fd, buf, num); - if (result < 0) { - result = -errno; - error_setg_errno(errp, -result, - "Could not write to the new file"); - break; - } - left -= result; - } - if (result >= 0) { - result = fsync(fd); - if (result < 0) { - result = -errno; - error_setg_errno(errp, -result, - "Could not flush new file to disk"); - } - } - g_free(buf); - break; - } - case PREALLOC_MODE_OFF: - break; - default: - result = -EINVAL; - error_setg(errp, "Unsupported preallocation mode: %s", - PreallocMode_lookup[prealloc]); - break; - } - -out_close: - if (qemu_close(fd) != 0 && result == 0) { - result = -errno; - error_setg_errno(errp, -result, "Could not close the new file"); - } -out: - return result; -} - -/* - * Find allocation range in @bs around offset @start. - * May change underlying file descriptor's file offset. - * If @start is not in a hole, store @start in @data, and the - * beginning of the next hole in @hole, and return 0. - * If @start is in a non-trailing hole, store @start in @hole and the - * beginning of the next non-hole in @data, and return 0. - * If @start is in a trailing hole or beyond EOF, return -ENXIO. - * If we can't find out, return a negative errno other than -ENXIO. - */ -static int find_allocation(BlockDriverState *bs, off_t start, - off_t *data, off_t *hole) -{ -#if defined SEEK_HOLE && defined SEEK_DATA - BDRVRawState *s = bs->opaque; - off_t offs; - - /* - * SEEK_DATA cases: - * D1. offs == start: start is in data - * D2. offs > start: start is in a hole, next data at offs - * D3. offs < 0, errno = ENXIO: either start is in a trailing hole - * or start is beyond EOF - * If the latter happens, the file has been truncated behind - * our back since we opened it. All bets are off then. - * Treating like a trailing hole is simplest. - * D4. offs < 0, errno != ENXIO: we learned nothing - */ - offs = lseek(s->fd, start, SEEK_DATA); - if (offs < 0) { - return -errno; /* D3 or D4 */ - } - assert(offs >= start); - - if (offs > start) { - /* D2: in hole, next data at offs */ - *hole = start; - *data = offs; - return 0; - } - - /* D1: in data, end not yet known */ - - /* - * SEEK_HOLE cases: - * H1. offs == start: start is in a hole - * If this happens here, a hole has been dug behind our back - * since the previous lseek(). - * H2. offs > start: either start is in data, next hole at offs, - * or start is in trailing hole, EOF at offs - * Linux treats trailing holes like any other hole: offs == - * start. Solaris seeks to EOF instead: offs > start (blech). - * If that happens here, a hole has been dug behind our back - * since the previous lseek(). - * H3. offs < 0, errno = ENXIO: start is beyond EOF - * If this happens, the file has been truncated behind our - * back since we opened it. Treat it like a trailing hole. - * H4. offs < 0, errno != ENXIO: we learned nothing - * Pretend we know nothing at all, i.e. "forget" about D1. - */ - offs = lseek(s->fd, start, SEEK_HOLE); - if (offs < 0) { - return -errno; /* D1 and (H3 or H4) */ - } - assert(offs >= start); - - if (offs > start) { - /* - * D1 and H2: either in data, next hole at offs, or it was in - * data but is now in a trailing hole. In the latter case, - * all bets are off. Treating it as if it there was data all - * the way to EOF is safe, so simply do that. - */ - *data = start; - *hole = offs; - return 0; - } - - /* D1 and H1 */ - return -EBUSY; -#else - return -ENOTSUP; -#endif -} - -/* - * Returns the allocation status of the specified sectors. - * - * If 'sector_num' is beyond the end of the disk image the return value is 0 - * and 'pnum' is set to 0. - * - * 'pnum' is set to the number of sectors (including and immediately following - * the specified sector) that are known to be in the same - * allocated/unallocated state. - * - * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes - * beyond the end of the disk image it will be clamped. - */ -static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, int *pnum) -{ - off_t start, data = 0, hole = 0; - int64_t total_size; - int ret; - - ret = fd_open(bs); - if (ret < 0) { - return ret; - } - - start = sector_num * BDRV_SECTOR_SIZE; - total_size = bdrv_getlength(bs); - if (total_size < 0) { - return total_size; - } else if (start >= total_size) { - *pnum = 0; - return 0; - } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) { - nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE); - } - - ret = find_allocation(bs, start, &data, &hole); - if (ret == -ENXIO) { - /* Trailing hole */ - *pnum = nb_sectors; - ret = BDRV_BLOCK_ZERO; - } else if (ret < 0) { - /* No info available, so pretend there are no holes */ - *pnum = nb_sectors; - ret = BDRV_BLOCK_DATA; - } else if (data == start) { - /* On a data extent, compute sectors to the end of the extent, - * possibly including a partial sector at EOF. */ - *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE)); - ret = BDRV_BLOCK_DATA; - } else { - /* On a hole, compute sectors to the beginning of the next extent. */ - assert(hole == start); - *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE); - ret = BDRV_BLOCK_ZERO; - } - return ret | BDRV_BLOCK_OFFSET_VALID | start; -} - -static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) -{ - BDRVRawState *s = bs->opaque; - - return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors, - cb, opaque, QEMU_AIO_DISCARD); -} - -static int coroutine_fn raw_co_write_zeroes( - BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) -{ - BDRVRawState *s = bs->opaque; - - if (!(flags & BDRV_REQ_MAY_UNMAP)) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, - QEMU_AIO_WRITE_ZEROES); - } else if (s->discard_zeroes) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, - QEMU_AIO_DISCARD); - } - return -ENOTSUP; -} - -static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) -{ - BDRVRawState *s = bs->opaque; - - bdi->unallocated_blocks_are_zero = s->discard_zeroes; - bdi->can_write_zeroes_with_unmap = s->discard_zeroes; - return 0; -} - -static QemuOptsList raw_create_opts = { - .name = "raw-create-opts", - .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head), - .desc = { - { - .name = BLOCK_OPT_SIZE, - .type = QEMU_OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_NOCOW, - .type = QEMU_OPT_BOOL, - .help = "Turn off copy-on-write (valid only on btrfs)" - }, - { - .name = BLOCK_OPT_PREALLOC, - .type = QEMU_OPT_STRING, - .help = "Preallocation mode (allowed values: off, falloc, full)" - }, - { /* end of list */ } - } -}; - -BlockDriver bdrv_file = { - .format_name = "file", - .protocol_name = "file", - .instance_size = sizeof(BDRVRawState), - .bdrv_needs_filename = true, - .bdrv_probe = NULL, /* no probe for protocols */ - .bdrv_parse_filename = raw_parse_filename, - .bdrv_file_open = raw_open, - .bdrv_reopen_prepare = raw_reopen_prepare, - .bdrv_reopen_commit = raw_reopen_commit, - .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_close = raw_close, - .bdrv_create = raw_create, - .bdrv_has_zero_init = bdrv_has_zero_init_1, - .bdrv_co_get_block_status = raw_co_get_block_status, - .bdrv_co_write_zeroes = raw_co_write_zeroes, - - .bdrv_aio_readv = raw_aio_readv, - .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_flush = raw_aio_flush, - .bdrv_aio_discard = raw_aio_discard, - .bdrv_refresh_limits = raw_refresh_limits, - .bdrv_io_plug = raw_aio_plug, - .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, - - .bdrv_truncate = raw_truncate, - .bdrv_getlength = raw_getlength, - .bdrv_get_info = raw_get_info, - .bdrv_get_allocated_file_size - = raw_get_allocated_file_size, - - .bdrv_detach_aio_context = raw_detach_aio_context, - .bdrv_attach_aio_context = raw_attach_aio_context, - - .create_opts = &raw_create_opts, -}; - -/***********************************************/ -/* host device */ - -#if defined(__APPLE__) && defined(__MACH__) -static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ); -static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, - CFIndex maxPathSize, int flags); -kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) -{ - kern_return_t kernResult; - mach_port_t masterPort; - CFMutableDictionaryRef classesToMatch; - - kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort ); - if ( KERN_SUCCESS != kernResult ) { - printf( "IOMasterPort returned %d\n", kernResult ); - } - - classesToMatch = IOServiceMatching( kIOCDMediaClass ); - if ( classesToMatch == NULL ) { - printf( "IOServiceMatching returned a NULL dictionary.\n" ); - } else { - CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue ); - } - kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator ); - if ( KERN_SUCCESS != kernResult ) - { - printf( "IOServiceGetMatchingServices returned %d\n", kernResult ); - } - - return kernResult; -} - -kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, - CFIndex maxPathSize, int flags) -{ - io_object_t nextMedia; - kern_return_t kernResult = KERN_FAILURE; - *bsdPath = '\0'; - nextMedia = IOIteratorNext( mediaIterator ); - if ( nextMedia ) - { - CFTypeRef bsdPathAsCFString; - bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 ); - if ( bsdPathAsCFString ) { - size_t devPathLength; - strcpy( bsdPath, _PATH_DEV ); - if (flags & BDRV_O_NOCACHE) { - strcat(bsdPath, "r"); - } - devPathLength = strlen( bsdPath ); - if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) { - kernResult = KERN_SUCCESS; - } - CFRelease( bsdPathAsCFString ); - } - IOObjectRelease( nextMedia ); - } - - return kernResult; -} - -#endif - -static int hdev_probe_device(const char *filename) -{ - struct stat st; - - /* allow a dedicated CD-ROM driver to match with a higher priority */ - if (strstart(filename, "/dev/cdrom", NULL)) - return 50; - - if (stat(filename, &st) >= 0 && - (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { - return 100; - } - - return 0; -} - -static int check_hdev_writable(BDRVRawState *s) -{ -#if defined(BLKROGET) - /* Linux block devices can be configured "read-only" using blockdev(8). - * This is independent of device node permissions and therefore open(2) - * with O_RDWR succeeds. Actual writes fail with EPERM. - * - * bdrv_open() is supposed to fail if the disk is read-only. Explicitly - * check for read-only block devices so that Linux block devices behave - * properly. - */ - struct stat st; - int readonly = 0; - - if (fstat(s->fd, &st)) { - return -errno; - } - - if (!S_ISBLK(st.st_mode)) { - return 0; - } - - if (ioctl(s->fd, BLKROGET, &readonly) < 0) { - return -errno; - } - - if (readonly) { - return -EACCES; - } -#endif /* defined(BLKROGET) */ - return 0; -} - -static void hdev_parse_filename(const char *filename, QDict *options, - Error **errp) -{ - /* The prefix is optional, just as for "file". */ - strstart(filename, "host_device:", &filename); - - qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); -} - -static bool hdev_is_sg(BlockDriverState *bs) -{ - -#if defined(__linux__) - - struct stat st; - struct sg_scsi_id scsiid; - int sg_version; - - if (stat(bs->filename, &st) >= 0 && S_ISCHR(st.st_mode) && - !bdrv_ioctl(bs, SG_GET_VERSION_NUM, &sg_version) && - !bdrv_ioctl(bs, SG_GET_SCSI_ID, &scsiid)) { - DPRINTF("SG device found: type=%d, version=%d\n", - scsiid.scsi_type, sg_version); - return true; - } - -#endif - - return false; -} - -static int hdev_open(BlockDriverState *bs, QDict *options, int flags, - Error **errp) -{ - BDRVRawState *s = bs->opaque; - Error *local_err = NULL; - int ret; - -#if defined(__APPLE__) && defined(__MACH__) - const char *filename = qdict_get_str(options, "filename"); - - if (strstart(filename, "/dev/cdrom", NULL)) { - kern_return_t kernResult; - io_iterator_t mediaIterator; - char bsdPath[ MAXPATHLEN ]; - int fd; - - kernResult = FindEjectableCDMedia( &mediaIterator ); - kernResult = GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath), - flags); - if ( bsdPath[ 0 ] != '\0' ) { - strcat(bsdPath,"s0"); - /* some CDs don't have a partition 0 */ - fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); - if (fd < 0) { - bsdPath[strlen(bsdPath)-1] = '1'; - } else { - qemu_close(fd); - } - filename = bsdPath; - qdict_put(options, "filename", qstring_from_str(filename)); - } - - if ( mediaIterator ) - IOObjectRelease( mediaIterator ); - } -#endif - - s->type = FTYPE_FILE; - - ret = raw_open_common(bs, options, flags, 0, &local_err); - if (ret < 0) { - if (local_err) { - error_propagate(errp, local_err); - } - return ret; - } - - /* Since this does ioctl the device must be already opened */ - bs->sg = hdev_is_sg(bs); - - if (flags & BDRV_O_RDWR) { - ret = check_hdev_writable(s); - if (ret < 0) { - raw_close(bs); - error_setg_errno(errp, -ret, "The device is not writable"); - return ret; - } - } - - return ret; -} - -#if defined(__linux__) - -static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs, - unsigned long int req, void *buf, - BlockCompletionFunc *cb, void *opaque) -{ - BDRVRawState *s = bs->opaque; - RawPosixAIOData *acb; - ThreadPool *pool; - - if (fd_open(bs) < 0) - return NULL; - - acb = g_new(RawPosixAIOData, 1); - acb->bs = bs; - acb->aio_type = QEMU_AIO_IOCTL; - acb->aio_fildes = s->fd; - acb->aio_offset = 0; - acb->aio_ioctl_buf = buf; - acb->aio_ioctl_cmd = req; - pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); - return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); -} -#endif /* linux */ - -static int fd_open(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - - /* this is just to ensure s->fd is sane (its called by io ops) */ - if (s->fd >= 0) - return 0; - return -EIO; -} - -static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - BlockCompletionFunc *cb, void *opaque) -{ - BDRVRawState *s = bs->opaque; - - if (fd_open(bs) < 0) { - return NULL; - } - return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors, - cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); -} - -static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) -{ - BDRVRawState *s = bs->opaque; - int rc; - - rc = fd_open(bs); - if (rc < 0) { - return rc; - } - if (!(flags & BDRV_REQ_MAY_UNMAP)) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, - QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV); - } else if (s->discard_zeroes) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, - QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); - } - return -ENOTSUP; -} - -static int hdev_create(const char *filename, QemuOpts *opts, - Error **errp) -{ - int fd; - int ret = 0; - struct stat stat_buf; - int64_t total_size = 0; - bool has_prefix; - - /* This function is used by both protocol block drivers and therefore either - * of these prefixes may be given. - * The return value has to be stored somewhere, otherwise this is an error - * due to -Werror=unused-value. */ - has_prefix = - strstart(filename, "host_device:", &filename) || - strstart(filename, "host_cdrom:" , &filename); - - (void)has_prefix; - - ret = raw_normalize_devicepath(&filename); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not normalize device path"); - return ret; - } - - /* Read out options */ - total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), - BDRV_SECTOR_SIZE); - - fd = qemu_open(filename, O_WRONLY | O_BINARY); - if (fd < 0) { - ret = -errno; - error_setg_errno(errp, -ret, "Could not open device"); - return ret; - } - - if (fstat(fd, &stat_buf) < 0) { - ret = -errno; - error_setg_errno(errp, -ret, "Could not stat device"); - } else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) { - error_setg(errp, - "The given file is neither a block nor a character device"); - ret = -ENODEV; - } else if (lseek(fd, 0, SEEK_END) < total_size) { - error_setg(errp, "Device is too small"); - ret = -ENOSPC; - } - - qemu_close(fd); - return ret; -} - -static BlockDriver bdrv_host_device = { - .format_name = "host_device", - .protocol_name = "host_device", - .instance_size = sizeof(BDRVRawState), - .bdrv_needs_filename = true, - .bdrv_probe_device = hdev_probe_device, - .bdrv_parse_filename = hdev_parse_filename, - .bdrv_file_open = hdev_open, - .bdrv_close = raw_close, - .bdrv_reopen_prepare = raw_reopen_prepare, - .bdrv_reopen_commit = raw_reopen_commit, - .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_opts = &raw_create_opts, - .bdrv_co_write_zeroes = hdev_co_write_zeroes, - - .bdrv_aio_readv = raw_aio_readv, - .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_flush = raw_aio_flush, - .bdrv_aio_discard = hdev_aio_discard, - .bdrv_refresh_limits = raw_refresh_limits, - .bdrv_io_plug = raw_aio_plug, - .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, - - .bdrv_truncate = raw_truncate, - .bdrv_getlength = raw_getlength, - .bdrv_get_info = raw_get_info, - .bdrv_get_allocated_file_size - = raw_get_allocated_file_size, - .bdrv_probe_blocksizes = hdev_probe_blocksizes, - .bdrv_probe_geometry = hdev_probe_geometry, - - .bdrv_detach_aio_context = raw_detach_aio_context, - .bdrv_attach_aio_context = raw_attach_aio_context, - - /* generic scsi device */ -#ifdef __linux__ - .bdrv_aio_ioctl = hdev_aio_ioctl, -#endif -}; - -#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -static void cdrom_parse_filename(const char *filename, QDict *options, - Error **errp) -{ - /* The prefix is optional, just as for "file". */ - strstart(filename, "host_cdrom:", &filename); - - qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); -} -#endif - -#ifdef __linux__ -static int cdrom_open(BlockDriverState *bs, QDict *options, int flags, - Error **errp) -{ - BDRVRawState *s = bs->opaque; - Error *local_err = NULL; - int ret; - - s->type = FTYPE_CD; - - /* open will not fail even if no CD is inserted, so add O_NONBLOCK */ - ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err); - if (local_err) { - error_propagate(errp, local_err); - } - return ret; -} - -static int cdrom_probe_device(const char *filename) -{ - int fd, ret; - int prio = 0; - struct stat st; - - fd = qemu_open(filename, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - goto out; - } - ret = fstat(fd, &st); - if (ret == -1 || !S_ISBLK(st.st_mode)) { - goto outc; - } - - /* Attempt to detect via a CDROM specific ioctl */ - ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); - if (ret >= 0) - prio = 100; - -outc: - qemu_close(fd); -out: - return prio; -} - -static bool cdrom_is_inserted(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - int ret; - - ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); - return ret == CDS_DISC_OK; -} - -static void cdrom_eject(BlockDriverState *bs, bool eject_flag) -{ - BDRVRawState *s = bs->opaque; - - if (eject_flag) { - if (ioctl(s->fd, CDROMEJECT, NULL) < 0) - perror("CDROMEJECT"); - } else { - if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0) - perror("CDROMEJECT"); - } -} - -static void cdrom_lock_medium(BlockDriverState *bs, bool locked) -{ - BDRVRawState *s = bs->opaque; - - if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) { - /* - * Note: an error can happen if the distribution automatically - * mounts the CD-ROM - */ - /* perror("CDROM_LOCKDOOR"); */ - } -} - -static BlockDriver bdrv_host_cdrom = { - .format_name = "host_cdrom", - .protocol_name = "host_cdrom", - .instance_size = sizeof(BDRVRawState), - .bdrv_needs_filename = true, - .bdrv_probe_device = cdrom_probe_device, - .bdrv_parse_filename = cdrom_parse_filename, - .bdrv_file_open = cdrom_open, - .bdrv_close = raw_close, - .bdrv_reopen_prepare = raw_reopen_prepare, - .bdrv_reopen_commit = raw_reopen_commit, - .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_opts = &raw_create_opts, - - .bdrv_aio_readv = raw_aio_readv, - .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_flush = raw_aio_flush, - .bdrv_refresh_limits = raw_refresh_limits, - .bdrv_io_plug = raw_aio_plug, - .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, - - .bdrv_truncate = raw_truncate, - .bdrv_getlength = raw_getlength, - .has_variable_length = true, - .bdrv_get_allocated_file_size - = raw_get_allocated_file_size, - - .bdrv_detach_aio_context = raw_detach_aio_context, - .bdrv_attach_aio_context = raw_attach_aio_context, - - /* removable device support */ - .bdrv_is_inserted = cdrom_is_inserted, - .bdrv_eject = cdrom_eject, - .bdrv_lock_medium = cdrom_lock_medium, - - /* generic scsi device */ - .bdrv_aio_ioctl = hdev_aio_ioctl, -}; -#endif /* __linux__ */ - -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) -static int cdrom_open(BlockDriverState *bs, QDict *options, int flags, - Error **errp) -{ - BDRVRawState *s = bs->opaque; - Error *local_err = NULL; - int ret; - - s->type = FTYPE_CD; - - ret = raw_open_common(bs, options, flags, 0, &local_err); - if (ret) { - if (local_err) { - error_propagate(errp, local_err); - } - return ret; - } - - /* make sure the door isn't locked at this time */ - ioctl(s->fd, CDIOCALLOW); - return 0; -} - -static int cdrom_probe_device(const char *filename) -{ - if (strstart(filename, "/dev/cd", NULL) || - strstart(filename, "/dev/acd", NULL)) - return 100; - return 0; -} - -static int cdrom_reopen(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - int fd; - - /* - * Force reread of possibly changed/newly loaded disc, - * FreeBSD seems to not notice sometimes... - */ - if (s->fd >= 0) - qemu_close(s->fd); - fd = qemu_open(bs->filename, s->open_flags, 0644); - if (fd < 0) { - s->fd = -1; - return -EIO; - } - s->fd = fd; - - /* make sure the door isn't locked at this time */ - ioctl(s->fd, CDIOCALLOW); - return 0; -} - -static bool cdrom_is_inserted(BlockDriverState *bs) -{ - return raw_getlength(bs) > 0; -} - -static void cdrom_eject(BlockDriverState *bs, bool eject_flag) -{ - BDRVRawState *s = bs->opaque; - - if (s->fd < 0) - return; - - (void) ioctl(s->fd, CDIOCALLOW); - - if (eject_flag) { - if (ioctl(s->fd, CDIOCEJECT) < 0) - perror("CDIOCEJECT"); - } else { - if (ioctl(s->fd, CDIOCCLOSE) < 0) - perror("CDIOCCLOSE"); - } - - cdrom_reopen(bs); -} - -static void cdrom_lock_medium(BlockDriverState *bs, bool locked) -{ - BDRVRawState *s = bs->opaque; - - if (s->fd < 0) - return; - if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) { - /* - * Note: an error can happen if the distribution automatically - * mounts the CD-ROM - */ - /* perror("CDROM_LOCKDOOR"); */ - } -} - -static BlockDriver bdrv_host_cdrom = { - .format_name = "host_cdrom", - .protocol_name = "host_cdrom", - .instance_size = sizeof(BDRVRawState), - .bdrv_needs_filename = true, - .bdrv_probe_device = cdrom_probe_device, - .bdrv_parse_filename = cdrom_parse_filename, - .bdrv_file_open = cdrom_open, - .bdrv_close = raw_close, - .bdrv_reopen_prepare = raw_reopen_prepare, - .bdrv_reopen_commit = raw_reopen_commit, - .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_opts = &raw_create_opts, - - .bdrv_aio_readv = raw_aio_readv, - .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_flush = raw_aio_flush, - .bdrv_refresh_limits = raw_refresh_limits, - .bdrv_io_plug = raw_aio_plug, - .bdrv_io_unplug = raw_aio_unplug, - .bdrv_flush_io_queue = raw_aio_flush_io_queue, - - .bdrv_truncate = raw_truncate, - .bdrv_getlength = raw_getlength, - .has_variable_length = true, - .bdrv_get_allocated_file_size - = raw_get_allocated_file_size, - - .bdrv_detach_aio_context = raw_detach_aio_context, - .bdrv_attach_aio_context = raw_attach_aio_context, - - /* removable device support */ - .bdrv_is_inserted = cdrom_is_inserted, - .bdrv_eject = cdrom_eject, - .bdrv_lock_medium = cdrom_lock_medium, -}; -#endif /* __FreeBSD__ */ - -static void bdrv_file_init(void) -{ - /* - * Register all the drivers. Note that order is important, the driver - * registered last will get probed first. - */ - bdrv_register(&bdrv_file); - bdrv_register(&bdrv_host_device); -#ifdef __linux__ - bdrv_register(&bdrv_host_cdrom); -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - bdrv_register(&bdrv_host_cdrom); -#endif -} - -block_init(bdrv_file_init); diff --git a/configure b/configure index 6aa07f3a6c53f..b9eb0dd68a9b0 100755 --- a/configure +++ b/configure @@ -1498,13 +1498,11 @@ for opt do ;; --enable-numa) numa="yes" ;; -<<<<<<< HEAD --disable-libxml2) libxml2="no" ;; --enable-libxml2) libxml2="yes" -======= + ;; --disable-mouse) mouse="no" ->>>>>>> 919b29ba7d... Pebble Qemu ;; --disable-tcmalloc) tcmalloc="no" ;; @@ -6725,7 +6723,6 @@ echo "NUMA host support $numa" echo "libxml2 $libxml2" echo "tcmalloc support $tcmalloc" echo "jemalloc support $jemalloc" -<<<<<<< HEAD echo "avx2 optimization $avx2_opt" echo "avx512f optimization $avx512f_opt" echo "replication support $replication" @@ -6746,6 +6743,7 @@ echo "default devices $default_devices" echo "plugin support $plugins" echo "fuzzing support $fuzzing" echo "gdb $gdb_bin" +echo "Mouse support $mouse" if test "$supported_cpu" = "no"; then echo @@ -6759,9 +6757,6 @@ if test "$supported_cpu" = "no"; then echo "if you care about QEMU on this platform you should contact" echo "us upstream at qemu-devel@nongnu.org." fi -======= -echo "Mouse support $mouse" ->>>>>>> 919b29ba7d... Pebble Qemu if test "$supported_os" = "no"; then echo diff --git a/crypto/tlssession.c b/crypto/tlssession.c index a5f8ec16c4dfb..33203e8ca711d 100644 --- a/crypto/tlssession.c +++ b/crypto/tlssession.c @@ -227,8 +227,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds, goto error; } - if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER && - creds->verifyPeer) { + if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { /* This requests, but does not enforce a client cert. * The cert checking code later does enforcement */ gnutls_certificate_server_set_request(session->handle, diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 71eac79b5ca21..c791ab3d4d637 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -1,51 +1,45 @@ # Default configuration for arm-softmmu -<<<<<<< HEAD # TODO: ARM_V7M is currently always required - make this more flexible! CONFIG_ARM_V7M=y -======= -include pci.mak -include usb.mak -CONFIG_VGA=y -CONFIG_ISA_MMIO=y -CONFIG_NAND=y -CONFIG_ECC=y -CONFIG_SERIAL=y -CONFIG_PTIMER=y -CONFIG_SD=y -CONFIG_MAX7310=y -CONFIG_WM8750=y -CONFIG_TWL92230=y -CONFIG_TSC2005=y -CONFIG_LM832X=y -CONFIG_TMP105=y -CONFIG_STELLARIS=y -CONFIG_STELLARIS_INPUT=y -CONFIG_STELLARIS_ENET=y -CONFIG_STM32=y -CONFIG_SSD0303=y -CONFIG_SSD0323=y -CONFIG_LS013B7DH01=y -CONFIG_PEBBLE_SNOWY_DISPLAY=y -CONFIG_ADS7846=y -CONFIG_MAX111X=y -CONFIG_SSI=y -CONFIG_SSI_SD=y -CONFIG_SSI_M25P80=y -CONFIG_LAN9118=y -CONFIG_SMC91C111=y -CONFIG_ALLWINNER_EMAC=y -CONFIG_IMX_FEC=y -CONFIG_DS1338=y -CONFIG_PFLASH_CFI01=y -CONFIG_PFLASH_CFI02=y -CONFIG_PFLASH_JEDEC_424=y -CONFIG_MICRODRIVE=y -CONFIG_USB=y -CONFIG_USB_MUSB=y -CONFIG_USB_EHCI_SYSBUS=y -CONFIG_PLATFORM_BUS=y ->>>>>>> 919b29ba7d... Pebble Qemu + +# CONFIG_ISA_MMIO=y +# CONFIG_ECC=y +# CONFIG_SERIAL=y +# CONFIG_PTIMER=y +# CONFIG_SD=y +# CONFIG_MAX7310=y +# CONFIG_WM8750=y +# CONFIG_TWL92230=y +# CONFIG_TSC2005=y +# CONFIG_LM832X=y +# CONFIG_TMP105=y +# CONFIG_STELLARIS=y +# CONFIG_STELLARIS_INPUT=y +# CONFIG_STELLARIS_ENET=y +# CONFIG_STM32=y +# CONFIG_SSD0303=y +# CONFIG_SSD0323=y +# CONFIG_LS013B7DH01=y +# CONFIG_PEBBLE_SNOWY_DISPLAY=y +# CONFIG_ADS7846=y +# CONFIG_MAX111X=y +# CONFIG_SSI=y +# CONFIG_SSI_SD=y +# CONFIG_SSI_M25P80=y +# CONFIG_LAN9118=y +# CONFIG_SMC91C111=y +# CONFIG_ALLWINNER_EMAC=y +# CONFIG_IMX_FEC=y +# CONFIG_DS1338=y +# CONFIG_PFLASH_CFI01=y +# CONFIG_PFLASH_CFI02=y +# CONFIG_PFLASH_JEDEC_424=y +# CONFIG_MICRODRIVE=y +# CONFIG_USB=y +# CONFIG_USB_MUSB=y +# CONFIG_USB_EHCI_SYSBUS=y +# CONFIG_PLATFORM_BUS=y # CONFIG_PCI_DEVICES=n # CONFIG_TEST_DEVICES=n @@ -86,3 +80,4 @@ CONFIG_FSL_IMX7=y CONFIG_FSL_IMX6UL=y CONFIG_SEMIHOSTING=y CONFIG_ALLWINNER_H3=y +CONFIG_STM32=y diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt deleted file mode 100644 index 5a89004c22e08..0000000000000 --- a/docs/qapi-code-gen.txt +++ /dev/null @@ -1,1183 +0,0 @@ -= How to use the QAPI code generator = - -Copyright IBM Corp. 2011 -Copyright (C) 2012-2015 Red Hat, Inc. - -This work is licensed under the terms of the GNU GPL, version 2 or -later. See the COPYING file in the top-level directory. - -== Introduction == - -QAPI is a native C API within QEMU which provides management-level -functionality to internal and external users. For external -users/processes, this interface is made available by a JSON-based wire -format for the QEMU Monitor Protocol (QMP) for controlling qemu, as -well as the QEMU Guest Agent (QGA) for communicating with the guest. -The remainder of this document uses "Client JSON Protocol" when -referring to the wire contents of a QMP or QGA connection. - -To map Client JSON Protocol interfaces to the native C QAPI -implementations, a JSON-based schema is used to define types and -function signatures, and a set of scripts is used to generate types, -signatures, and marshaling/dispatch code. This document will describe -how the schemas, scripts, and resulting code are used. - - -== QMP/Guest agent schema == - -A QAPI schema file is designed to be loosely based on JSON -(http://www.ietf.org/rfc/rfc7159.txt) with changes for quoting style -and the use of comments; a QAPI schema file is then parsed by a python -code generation program. A valid QAPI schema consists of a series of -top-level expressions, with no commas between them. Where -dictionaries (JSON objects) are used, they are parsed as python -OrderedDicts so that ordering is preserved (for predictable layout of -generated C structs and parameter lists). Ordering doesn't matter -between top-level expressions or the keys within an expression, but -does matter within dictionary values for 'data' and 'returns' members -of a single expression. QAPI schema input is written using 'single -quotes' instead of JSON's "double quotes" (in contrast, Client JSON -Protocol uses no comments, and while input accepts 'single quotes' as -an extension, output is strict JSON using only "double quotes"). As -in JSON, trailing commas are not permitted in arrays or dictionaries. -Input must be ASCII (although QMP supports full Unicode strings, the -QAPI parser does not). At present, there is no place where a QAPI -schema requires the use of JSON numbers or null. - -Comments are allowed; anything between an unquoted # and the following -newline is ignored. Although there is not yet a documentation -generator, a form of stylized comments has developed for consistently -documenting details about an expression and when it was added to the -schema. The documentation is delimited between two lines of ##, then -the first line names the expression, an optional overview is provided, -then individual documentation about each member of 'data' is provided, -and finally, a 'Since: x.y.z' tag lists the release that introduced -the expression. Optional fields are tagged with the phrase -'#optional', often with their default value; and extensions added -after the expression was first released are also given a '(since -x.y.z)' comment. For example: - - ## - # @BlockStats: - # - # Statistics of a virtual block device or a block backing device. - # - # @device: #optional If the stats are for a virtual block device, the name - # corresponding to the virtual block device. - # - # @stats: A @BlockDeviceStats for the device. - # - # @parent: #optional This describes the file block device if it has one. - # - # @backing: #optional This describes the backing block device if it has one. - # (Since 2.0) - # - # Since: 0.14.0 - ## - { 'struct': 'BlockStats', - 'data': {'*device': 'str', 'stats': 'BlockDeviceStats', - '*parent': 'BlockStats', - '*backing': 'BlockStats'} } - -The schema sets up a series of types, as well as commands and events -that will use those types. Forward references are allowed: the parser -scans in two passes, where the first pass learns all type names, and -the second validates the schema and generates the code. This allows -the definition of complex structs that can have mutually recursive -types, and allows for indefinite nesting of Client JSON Protocol that -satisfies the schema. A type name should not be defined more than -once. It is permissible for the schema to contain additional types -not used by any commands or events in the Client JSON Protocol, for -the side effect of generated C code used internally. - -There are seven top-level expressions recognized by the parser: -'include', 'command', 'struct', 'enum', 'union', 'alternate', and -'event'. There are several groups of types: simple types (a number of -built-in types, such as 'int' and 'str'; as well as enumerations), -complex types (structs and two flavors of unions), and alternate types -(a choice between other types). The 'command' and 'event' expressions -can refer to existing types by name, or list an anonymous type as a -dictionary. Listing a type name inside an array refers to a -single-dimension array of that type; multi-dimension arrays are not -directly supported (although an array of a complex struct that -contains an array member is possible). - -Types, commands, and events share a common namespace. Therefore, -generally speaking, type definitions should always use CamelCase for -user-defined type names, while built-in types are lowercase. Type -definitions should not end in 'Kind', as this namespace is used for -creating implicit C enums for visiting union types, or in 'List', as -this namespace is used for creating array types. Command names, -and field names within a type, should be all lower case with words -separated by a hyphen. However, some existing older commands and -complex types use underscore; when extending such expressions, -consistency is preferred over blindly avoiding underscore. Event -names should be ALL_CAPS with words separated by underscore. Field -names cannot start with 'has-' or 'has_', as this is reserved for -tracking optional fields. - -Any name (command, event, type, field, or enum value) beginning with -"x-" is marked experimental, and may be withdrawn or changed -incompatibly in a future release. Downstream vendors may add -extensions; such extensions should begin with a prefix matching -"__RFQDN_" (for the reverse-fully-qualified-domain-name of the -vendor), even if the rest of the name uses dash (example: -__com.redhat_drive-mirror). Other than downstream extensions (with -leading underscore and the use of dots), all names should begin with a -letter, and contain only ASCII letters, digits, dash, and underscore. -Names beginning with 'q_' are reserved for the generator: QMP names -that resemble C keywords or other problematic strings will be munged -in C to use this prefix. For example, a field named "default" in -qapi becomes "q_default" in the generated C code. - -In the rest of this document, usage lines are given for each -expression type, with literal strings written in lower case and -placeholders written in capitals. If a literal string includes a -prefix of '*', that key/value pair can be omitted from the expression. -For example, a usage statement that includes '*base':STRUCT-NAME -means that an expression has an optional key 'base', which if present -must have a value that forms a struct name. - -There are seven top-level expressions recognized by the parser: -'include', 'command', 'struct', 'enum', 'union', 'alternate', and -'event'. There are several groups of types: simple types (a number of -built-in types, such as 'int' and 'str'; as well as enumerations), -complex types (structs and two flavors of unions), and alternate types -(a choice between other types). The 'command' and 'event' expressions -can refer to existing types by name, or list an anonymous type as a -dictionary. Listing a type name inside an array refers to a -single-dimension array of that type; multi-dimension arrays are not -directly supported (although an array of a complex struct that -contains an array member is possible). - -Types, commands, and events share a common namespace. Therefore, -generally speaking, type definitions should always use CamelCase for -user-defined type names, while built-in types are lowercase. Type -definitions should not end in 'Kind', as this namespace is used for -creating implicit C enums for visiting union types. Command names, -and field names within a type, should be all lower case with words -separated by a hyphen. However, some existing older commands and -complex types use underscore; when extending such expressions, -consistency is preferred over blindly avoiding underscore. Event -names should be ALL_CAPS with words separated by underscore. The -special string '**' appears for some commands that manually perform -their own type checking rather than relying on the type-safe code -produced by the qapi code generators. - -Any name (command, event, type, field, or enum value) beginning with -"x-" is marked experimental, and may be withdrawn or changed -incompatibly in a future release. Downstream vendors may add -extensions; such extensions should begin with a prefix matching -"__RFQDN_" (for the reverse-fully-qualified-domain-name of the -vendor), even if the rest of the name uses dash (example: -__com.redhat_drive-mirror). Other than downstream extensions (with -leading underscore and the use of dots), all names should begin with a -letter, and contain only ASCII letters, digits, dash, and underscore. -It is okay to reuse names that match C keywords; the generator will -rename a field named "default" in the QAPI to "q_default" in the -generated C code. - -In the rest of this document, usage lines are given for each -expression type, with literal strings written in lower case and -placeholders written in capitals. If a literal string includes a -prefix of '*', that key/value pair can be omitted from the expression. -For example, a usage statement that includes '*base':STRUCT-NAME -means that an expression has an optional key 'base', which if present -must have a value that forms a struct name. - - -=== Built-in Types === - -The following types are predefined, and map to C as follows: - - Schema C JSON - str char * any JSON string, UTF-8 - number double any JSON number - int int64_t a JSON number without fractional part - that fits into the C integer type - int8 int8_t likewise - int16 int16_t likewise - int32 int32_t likewise - int64 int64_t likewise - uint8 uint8_t likewise - uint16 uint16_t likewise - uint32 uint32_t likewise - uint64 uint64_t likewise - size uint64_t like uint64_t, except StringInputVisitor - accepts size suffixes - bool bool JSON true or false - any QObject * any JSON value - - -=== Includes === - -Usage: { 'include': STRING } - -The QAPI schema definitions can be modularized using the 'include' directive: - - { 'include': 'path/to/file.json' } - -The directive is evaluated recursively, and include paths are relative to the -file using the directive. Multiple includes of the same file are -idempotent. No other keys should appear in the expression, and the include -value should be a string. - -As a matter of style, it is a good idea to have all files be -self-contained, but at the moment, nothing prevents an included file -from making a forward reference to a type that is only introduced by -an outer file. The parser may be made stricter in the future to -prevent incomplete include files. - -As a matter of style, it is a good idea to have all files be -self-contained, but at the moment, nothing prevents an included file -from making a forward reference to a type that is only introduced by -an outer file. The parser may be made stricter in the future to -prevent incomplete include files. - -=== Struct types === - -Usage: { 'struct': STRING, 'data': DICT, '*base': STRUCT-NAME } - -A struct is a dictionary containing a single 'data' key whose -value is a dictionary. This corresponds to a struct in C or an Object -in JSON. Each value of the 'data' dictionary must be the name of a -type, or a one-element array containing a type name. An example of a -struct is: - - { 'struct': 'MyType', - - { 'struct': 'MyType', - 'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } } - -The use of '*' as a prefix to the name means the member is optional in -the corresponding JSON protocol usage. - -The default initialization value of an optional argument should not be changed -between versions of QEMU unless the new default maintains backward -compatibility to the user-visible behavior of the old default. - -With proper documentation, this policy still allows some flexibility; for -example, documenting that a default of 0 picks an optimal buffer size allows -one release to declare the optimal size at 512 while another release declares -the optimal size at 4096 - the user-visible behavior is not the bytes used by -the buffer, but the fact that the buffer was optimal size. - -On input structures (only mentioned in the 'data' side of a command), changing -from mandatory to optional is safe (older clients will supply the option, and -newer clients can benefit from the default); changing from optional to -mandatory is backwards incompatible (older clients may be omitting the option, -and must continue to work). - -On output structures (only mentioned in the 'returns' side of a command), -changing from mandatory to optional is in general unsafe (older clients may be -expecting the field, and could crash if it is missing), although it can be done -if the only way that the optional argument will be omitted is when it is -triggered by the presence of a new input flag to the command that older clients -don't know to send. Changing from optional to mandatory is safe. - -A structure that is used in both input and output of various commands -must consider the backwards compatibility constraints of both directions -of use. - -A struct definition can specify another struct as its base. -In this case, the fields of the base type are included as top-level fields -of the new struct's dictionary in the Client JSON Protocol wire -format. An example definition is: - - { 'struct': 'BlockdevOptionsGenericFormat', 'data': { 'file': 'str' } } - { 'struct': 'BlockdevOptionsGenericCOWFormat', - 'base': 'BlockdevOptionsGenericFormat', - 'data': { '*backing': 'str' } } - -An example BlockdevOptionsGenericCOWFormat object on the wire could use -both fields like this: - - { "file": "/some/place/my-image", - "backing": "/some/place/my-backing-file" } - - -=== Enumeration types === - -Usage: { 'enum': STRING, 'data': ARRAY-OF-STRING } - { 'enum': STRING, '*prefix': STRING, 'data': ARRAY-OF-STRING } - -An enumeration type is a dictionary containing a single 'data' key -whose value is a list of strings. An example enumeration is: - - { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] } - -Nothing prevents an empty enumeration, although it is probably not -useful. The list of strings should be lower case; if an enum name -represents multiple words, use '-' between words. The string 'max' is -not allowed as an enum value, and values should not be repeated. - -The enum constants will be named by using a heuristic to turn the -type name into a set of underscore separated words. For the example -above, 'MyEnum' will turn into 'MY_ENUM' giving a constant name -of 'MY_ENUM_VALUE1' for the first value. If the default heuristic -does not result in a desirable name, the optional 'prefix' field -can be used when defining the enum. - -The enumeration values are passed as strings over the Client JSON -Protocol, but are encoded as C enum integral values in generated code. -While the C code starts numbering at 0, it is better to use explicit -comparisons to enum values than implicit comparisons to 0; the C code -will also include a generated enum member ending in _MAX for tracking -the size of the enum, useful when using common functions for -converting between strings and enum values. Since the wire format -always passes by name, it is acceptable to reorder or add new -enumeration members in any location without breaking clients of Client -JSON Protocol; however, removing enum values would break -compatibility. For any struct that has a field that will only contain -a finite set of string values, using an enum type for that field is -better than open-coding the field to be type 'str'. - - -=== Union types === - -Usage: { 'union': STRING, 'data': DICT } -or: { 'union': STRING, 'data': DICT, 'base': STRUCT-NAME, - 'discriminator': ENUM-MEMBER-OF-BASE } - -Union types are used to let the user choose between several different -variants for an object. There are two flavors: simple (no -discriminator or base), flat (both discriminator and base). A union -type is defined using a data dictionary as explained in the following -paragraphs. - -A simple union type defines a mapping from automatic discriminator -values to data types like in this example: - - { 'struct': 'FileOptions', 'data': { 'filename': 'str' } } - { 'struct': 'Qcow2Options', - 'data': { 'backing-file': 'str', 'lazy-refcounts': 'bool' } } - - { 'union': 'BlockdevOptions', - 'data': { 'file': 'FileOptions', - 'qcow2': 'Qcow2Options' } } - -In the Client JSON Protocol, a simple union is represented by a -dictionary that contains the 'type' field as a discriminator, and a -'data' field that is of the specified data type corresponding to the -discriminator value, as in these examples: - - { "type": "file", "data" : { "filename": "/some/place/my-image" } } - { "type": "qcow2", "data" : { "backing-file": "/some/place/my-image", - "lazy-refcounts": true } } - -The generated C code uses a struct containing a union. Additionally, -an implicit C enum 'NameKind' is created, corresponding to the union -'Name', for accessing the various branches of the union. No branch of -the union can be named 'max', as this would collide with the implicit -enum. The value for each branch can be of any type. - -A flat union definition specifies a struct as its base, and -avoids nesting on the wire. All branches of the union must be -complex types, and the top-level fields of the union dictionary on -the wire will be combination of fields from both the base type and the -appropriate branch type (when merging two dictionaries, there must be -no keys in common). The 'discriminator' field must be the name of an -enum-typed member of the base struct. -The following example enhances the above simple union example by -adding a common field 'readonly', renaming the discriminator to -something more applicable, and reducing the number of {} required on -the wire: - - { 'enum': 'BlockdevDriver', 'data': [ 'file', 'qcow2' ] } - { 'struct': 'BlockdevCommonOptions', - 'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } } - 'discriminator': 'driver', - 'data': { 'file': 'FileOptions', -Resulting in these JSON objects: - { "driver": "file", "readonly": true, - "filename": "/some/place/my-image" } - { "driver": "qcow2", "readonly": false, - "backing-file": "/some/place/my-image", "lazy-refcounts": true } - -Notice that in a flat union, the discriminator name is controlled by -the user, but because it must map to a base member with enum type, the -code generator can ensure that branches exist for all values of the -enum (although the order of the keys need not match the declaration of -the enum). In the resulting generated C data types, a flat union is -represented as a struct with the base member fields included directly, -and then a union of structures for each branch of the struct. - -A simple union can always be re-written as a flat union where the base -class has a single member named 'type', and where each branch of the -union has a struct with a single member named 'data'. That is, - - { 'union': 'Simple', 'data': { 'one': 'str', 'two': 'int' } } - -is identical on the wire to: - - { 'enum': 'Enum', 'data': ['one', 'two'] } - { 'struct': 'Base', 'data': { 'type': 'Enum' } } - { 'struct': 'Branch1', 'data': { 'data': 'str' } } - { 'struct': 'Branch2', 'data': { 'data': 'int' } } - { 'union': 'Flat', 'base': 'Base', 'discriminator': 'type', - 'data': { 'one': 'Branch1', 'two': 'Branch2' } } - -Notice that in a flat union, the discriminator name is controlled by -the user, but because it must map to a base member with enum type, the -code generator can ensure that branches exist for all values of the -enum (although the order of the keys need not match the declaration of -the enum). In the resulting generated C data types, a flat union is -represented as a struct with the base member fields included directly, -and then a union of structures for each branch of the struct. - -=== Alternate types === - -Usage: { 'alternate': STRING, 'data': DICT } - -An alternate type is one that allows a choice between two or more JSON -data types (string, integer, number, or object, but currently not -array) on the wire. The definition is similar to a simple union type, -where each branch of the union names a QAPI type. For example: - - { 'alternate': 'BlockRef', - { 'union': 'Flat': 'base': 'Base', 'discriminator': 'type', - 'data': { 'one': 'Branch1', 'two': 'Branch2' } } - - -=== Alternate types === - -Usage: { 'alternate': STRING, 'data': DICT } - -An alternate type is one that allows a choice between two or more JSON -data types (string, integer, number, or object, but currently not -array) on the wire. The definition is similar to a simple union type, -where each branch of the union names a QAPI type. For example: - - { 'alternate': 'BlockRef', - 'data': { 'definition': 'BlockdevOptions', - 'reference': 'str' } } - -Just like for a simple union, an implicit C enum 'NameKind' is created -to enumerate the branches for the alternate 'Name'. - -Unlike a union, the discriminator string is never passed on the wire -for the Client JSON Protocol. Instead, the value's JSON type serves -as an implicit discriminator, which in turn means that an alternate -can only express a choice between types represented differently in -JSON. If a branch is typed as the 'bool' built-in, the alternate -accepts true and false; if it is typed as any of the various numeric -built-ins, it accepts a JSON number; if it is typed as a 'str' -built-in or named enum type, it accepts a JSON string; and if it is -typed as a complex type (struct or union), it accepts a JSON object. -Two different complex types, for instance, aren't permitted, because -both are represented as a JSON object. - -The example alternate declaration above allows using both of the -following example objects: - - { "file": "my_existing_block_device_id" } - { "file": { "driver": "file", - "readonly": false, - "filename": "/tmp/mydisk.qcow2" } } - - -=== Commands === - -Usage: { 'command': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT, - '*returns': TYPE-NAME, - '*gen': false, '*success-response': false } - -Commands are defined by using a dictionary containing several members, -where three members are most common. The 'command' member is a -mandatory string, and determines the "execute" value passed in a -Client JSON Protocol command exchange. - -The 'data' argument maps to the "arguments" dictionary passed in as -part of a Client JSON Protocol command. The 'data' member is optional -and defaults to {} (an empty dictionary). If present, it must be the -string name of a complex type, or a dictionary that declares an -anonymous type with the same semantics as a 'struct' expression, with -one exception noted below when 'gen' is used. - -The 'returns' member describes what will appear in the "return" field -of a Client JSON Protocol reply on successful completion of a command. -The member is optional from the command declaration; if absent, the -"return" field will be an empty dictionary. If 'returns' is present, -it must be the string name of a complex or built-in type, a -one-element array containing the name of a complex or built-in type, -with one exception noted below when 'gen' is used. Although it is -permitted to have the 'returns' member name a built-in type or an -array of built-in types, any command that does this cannot be extended -to return additional information in the future; thus, new commands -should strongly consider returning a dictionary-based type or an array -of dictionaries, even if the dictionary only contains one field at the -present. - -All commands in Client JSON Protocol use a dictionary to report -failure, with no way to specify that in QAPI. Where the error return -is different than the usual GenericError class in order to help the -client react differently to certain error conditions, it is worth -documenting this in the comments before the command declaration. - -Some example commands: - - { 'command': 'my-first-command', - 'data': { 'arg1': 'str', '*arg2': 'str' } } - { 'struct': 'MyType', 'data': { '*value': 'str' } } - { 'command': 'my-second-command', - 'returns': [ 'MyType' ] } - -which would validate this Client JSON Protocol transaction: - - => { "execute": "my-first-command", - "arguments": { "arg1": "hello" } } - <= { "return": { } } - => { "execute": "my-second-command" } - <= { "return": [ { "value": "one" }, { } ] } - -In rare cases, QAPI cannot express a type-safe representation of a -corresponding Client JSON Protocol command. You then have to suppress -generation of a marshalling function by including a key 'gen' with -boolean value false, and instead write your own function. Please try -to avoid adding new commands that rely on this, and instead use -type-safe unions. For an example of this usage: - - { 'command': 'netdev_add', - 'data': {'type': 'str', 'id': 'str'}, - 'gen': false } - -Normally, the QAPI schema is used to describe synchronous exchanges, -where a response is expected. But in some cases, the action of a -command is expected to change state in a way that a successful -response is not possible (although the command will still return a -normal dictionary error on failure). When a successful reply is not -possible, the command expression should include the optional key -'success-response' with boolean value false. So far, only QGA makes -use of this field. -'success-response' with boolean value false. So far, only QGA makes -use of this field. - - -=== Events === - -Usage: { 'event': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT } - -Events are defined with the keyword 'event'. It is not allowed to -name an event 'MAX', since the generator also produces a C enumeration -of all event names with a generated _MAX value at the end. When -'data' is also specified, additional info will be included in the -event, with similar semantics to a 'struct' expression. Finally there -will be C API generated in qapi-event.h; when called by QEMU code, a -message with timestamp will be emitted on the wire. - -An example event is: - -{ 'event': 'EVENT_C', - 'data': { '*a': 'int', 'b': 'str' } } - -Resulting in this JSON object: - -{ "event": "EVENT_C", - "data": { "b": "test string" }, - "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } - - -== Client JSON Protocol introspection == - -Clients of a Client JSON Protocol commonly need to figure out what -exactly the server (QEMU) supports. - -For this purpose, QMP provides introspection via command -query-qmp-schema. QGA currently doesn't support introspection. - -While Client JSON Protocol wire compatibility should be maintained -between qemu versions, we cannot make the same guarantees for -introspection stability. For example, one version of qemu may provide -a non-variant optional member of a struct, and a later version rework -the member to instead be non-optional and associated with a variant. -Likewise, one version of qemu may list a member with open-ended type -'str', and a later version could convert it to a finite set of strings -via an enum type; or a member may be converted from a specific type to -an alternate that represents a choice between the original type and -something else. - -query-qmp-schema returns a JSON array of SchemaInfo objects. These -objects together describe the wire ABI, as defined in the QAPI schema. -There is no specified order to the SchemaInfo objects returned; a -client must search for a particular name throughout the entire array -to learn more about that name, but is at least guaranteed that there -will be no collisions between type, command, and event names. - -However, the SchemaInfo can't reflect all the rules and restrictions -that apply to QMP. It's interface introspection (figuring out what's -there), not interface specification. The specification is in the QAPI -schema. To understand how QMP is to be used, you need to study the -QAPI schema. - -Like any other command, query-qmp-schema is itself defined in the QAPI -schema, along with the SchemaInfo type. This text attempts to give an -overview how things work. For details you need to consult the QAPI -schema. - -SchemaInfo objects have common members "name" and "meta-type", and -additional variant members depending on the value of meta-type. - -Each SchemaInfo object describes a wire ABI entity of a certain -meta-type: a command, event or one of several kinds of type. - -SchemaInfo for commands and events have the same name as in the QAPI -schema. - -Command and event names are part of the wire ABI, but type names are -not. Therefore, the SchemaInfo for types have auto-generated -meaningless names. For readability, the examples in this section use -meaningful type names instead. - -To examine a type, start with a command or event using it, then follow -references by name. - -QAPI schema definitions not reachable that way are omitted. - -The SchemaInfo for a command has meta-type "command", and variant -members "arg-type" and "ret-type". On the wire, the "arguments" -member of a client's "execute" command must conform to the object type -named by "arg-type". The "return" member that the server passes in a -success response conforms to the type named by "ret-type". - -If the command takes no arguments, "arg-type" names an object type -without members. Likewise, if the command returns nothing, "ret-type" -names an object type without members. - -Example: the SchemaInfo for command query-qmp-schema - - { "name": "query-qmp-schema", "meta-type": "command", - "arg-type": ":empty", "ret-type": "SchemaInfoList" } - - Type ":empty" is an object type without members, and type - "SchemaInfoList" is the array of SchemaInfo type. - -The SchemaInfo for an event has meta-type "event", and variant member -"arg-type". On the wire, a "data" member that the server passes in an -event conforms to the object type named by "arg-type". - -If the event carries no additional information, "arg-type" names an -object type without members. The event may not have a data member on -the wire then. - -Each command or event defined with dictionary-valued 'data' in the -QAPI schema implicitly defines an object type. - -Example: the SchemaInfo for EVENT_C from section Events - - { "name": "EVENT_C", "meta-type": "event", - "arg-type": ":obj-EVENT_C-arg" } - - Type ":obj-EVENT_C-arg" is an implicitly defined object type with - the two members from the event's definition. - -The SchemaInfo for struct and union types has meta-type "object". - -The SchemaInfo for a struct type has variant member "members". - -The SchemaInfo for a union type additionally has variant members "tag" -and "variants". - -"members" is a JSON array describing the object's common members, if -any. Each element is a JSON object with members "name" (the member's -name), "type" (the name of its type), and optionally "default". The -member is optional if "default" is present. Currently, "default" can -only have value null. Other values are reserved for future -extensions. The "members" array is in no particular order; clients -must search the entire object when learning whether a particular -member is supported. - -Example: the SchemaInfo for MyType from section Struct types - - { "name": "MyType", "meta-type": "object", - "members": [ - { "name": "member1", "type": "str" }, - { "name": "member2", "type": "int" }, - { "name": "member3", "type": "str", "default": null } ] } - -"tag" is the name of the common member serving as type tag. -"variants" is a JSON array describing the object's variant members. -Each element is a JSON object with members "case" (the value of type -tag this element applies to) and "type" (the name of an object type -that provides the variant members for this type tag value). The -"variants" array is in no particular order, and is not guaranteed to -list cases in the same order as the corresponding "tag" enum type. - -Example: the SchemaInfo for flat union BlockdevOptions from section -Union types - - { "name": "BlockdevOptions", "meta-type": "object", - "members": [ - { "name": "driver", "type": "BlockdevDriver" }, - { "name": "readonly", "type": "bool"} ], - "tag": "driver", - "variants": [ - { "case": "file", "type": "FileOptions" }, - { "case": "qcow2", "type": "Qcow2Options" } ] } - -Note that base types are "flattened": its members are included in the -"members" array. - -A simple union implicitly defines an enumeration type for its implicit -discriminator (called "type" on the wire, see section Union types). - -A simple union implicitly defines an object type for each of its -variants. - -Example: the SchemaInfo for simple union BlockdevOptions from section -Union types - - { "name": "BlockdevOptions", "meta-type": "object", - "members": [ - { "name": "kind", "type": "BlockdevOptionsKind" } ], - "tag": "type", - "variants": [ - { "case": "file", "type": ":obj-FileOptions-wrapper" }, - { "case": "qcow2", "type": ":obj-Qcow2Options-wrapper" } ] } - - Enumeration type "BlockdevOptionsKind" and the object types - ":obj-FileOptions-wrapper", ":obj-Qcow2Options-wrapper" are - implicitly defined. - -The SchemaInfo for an alternate type has meta-type "alternate", and -variant member "members". "members" is a JSON array. Each element is -a JSON object with member "type", which names a type. Values of the -alternate type conform to exactly one of its member types. There is -no guarantee on the order in which "members" will be listed. - -Example: the SchemaInfo for BlockRef from section Alternate types - - { "name": "BlockRef", "meta-type": "alternate", - "members": [ - { "type": "BlockdevOptions" }, - { "type": "str" } ] } - -The SchemaInfo for an array type has meta-type "array", and variant -member "element-type", which names the array's element type. Array -types are implicitly defined. For convenience, the array's name may -resemble the element type; however, clients should examine member -"element-type" instead of making assumptions based on parsing member -"name". - -Example: the SchemaInfo for ['str'] - - { "name": "[str]", "meta-type": "array", - "element-type": "str" } - -The SchemaInfo for an enumeration type has meta-type "enum" and -variant member "values". The values are listed in no particular -order; clients must search the entire enum when learning whether a -particular value is supported. - -Example: the SchemaInfo for MyEnum from section Enumeration types - - { "name": "MyEnum", "meta-type": "enum", - "values": [ "value1", "value2", "value3" ] } - -The SchemaInfo for a built-in type has the same name as the type in -the QAPI schema (see section Built-in Types), with one exception -detailed below. It has variant member "json-type" that shows how -values of this type are encoded on the wire. - -Example: the SchemaInfo for str - - { "name": "str", "meta-type": "builtin", "json-type": "string" } - -The QAPI schema supports a number of integer types that only differ in -how they map to C. They are identical as far as SchemaInfo is -concerned. Therefore, they get all mapped to a single type "int" in -SchemaInfo. - -As explained above, type names are not part of the wire ABI. Not even -the names of built-in types. Clients should examine member -"json-type" instead of hard-coding names of built-in types. - - -== Code generation == - -Schemas are fed into four scripts to generate all the code/files that, -paired with the core QAPI libraries, comprise everything required to -take JSON commands read in by a Client JSON Protocol server, unmarshal -the arguments into the underlying C types, call into the corresponding -C function, and map the response back to a Client JSON Protocol -response to be returned to the user. - -As an example, we'll use the following schema, which describes a single -complex user-defined type (which will produce a C struct, along with a list -node structure that can be used to chain together a list of such types in -case we want to accept/return a list of this type with a command), and a -command which takes that type as a parameter and returns the same type: - - $ cat example-schema.json - { 'struct': 'UserDefOne', - 'data': { 'integer': 'int', 'string': 'str' } } - - { 'command': 'my-command', - 'data': {'arg1': 'UserDefOne'}, - 'returns': 'UserDefOne' } - - { 'event': 'MY_EVENT' } - -=== scripts/qapi-types.py === - -Used to generate the C types defined by a schema. The following files are -created: - -$(prefix)qapi-types.h - C types corresponding to types defined in - the schema you pass in -$(prefix)qapi-types.c - Cleanup functions for the above C types - -The $(prefix) is an optional parameter used as a namespace to keep the -generated code from one schema/code-generation separated from others so code -can be generated/used from multiple schemas without clobbering previously -created code. - -Example: - - $ python scripts/qapi-types.py --output-dir="qapi-generated" \ - --prefix="example-" example-schema.json - $ cat qapi-generated/example-qapi-types.c -[Uninteresting stuff omitted...] - - void qapi_free_UserDefOne(UserDefOne *obj) - { - QapiDeallocVisitor *qdv; - Visitor *v; - - if (!obj) { - return; - } - - qdv = qapi_dealloc_visitor_new(); - v = qapi_dealloc_get_visitor(qdv); - visit_type_UserDefOne(v, &obj, NULL, NULL); - qapi_dealloc_visitor_cleanup(qdv); - } - - void qapi_free_UserDefOneList(UserDefOneList *obj) - { - QapiDeallocVisitor *qdv; - Visitor *v; - - if (!obj) { - return; - } - - qdv = qapi_dealloc_visitor_new(); - v = qapi_dealloc_get_visitor(qdv); - visit_type_UserDefOneList(v, &obj, NULL, NULL); - qapi_dealloc_visitor_cleanup(qdv); - } - $ cat qapi-generated/example-qapi-types.h -[Uninteresting stuff omitted...] - - #ifndef EXAMPLE_QAPI_TYPES_H - #define EXAMPLE_QAPI_TYPES_H - -[Built-in types omitted...] - - typedef struct UserDefOne UserDefOne; - - typedef struct UserDefOneList UserDefOneList; - - struct UserDefOne { - int64_t integer; - char *string; - }; - - void qapi_free_UserDefOne(UserDefOne *obj); - - struct UserDefOneList { - union { - UserDefOne *value; - uint64_t padding; - }; - UserDefOneList *next; - }; - - void qapi_free_UserDefOneList(UserDefOneList *obj); - - #endif - -=== scripts/qapi-visit.py === - -Used to generate the visitor functions used to walk through and convert -a QObject (as provided by QMP) to a native C data structure and -vice-versa, as well as the visitor function used to dealloc a complex -schema-defined C type. - -The following files are generated: - -$(prefix)qapi-visit.c: visitor function for a particular C type, used - to automagically convert QObjects into the - corresponding C type and vice-versa, as well - as for deallocating memory for an existing C - type - -$(prefix)qapi-visit.h: declarations for previously mentioned visitor - functions - -Example: - - $ python scripts/qapi-visit.py --output-dir="qapi-generated" - --prefix="example-" example-schema.json - $ cat qapi-generated/example-qapi-visit.c -[Uninteresting stuff omitted...] - - static void visit_type_UserDefOne_fields(Visitor *v, UserDefOne **obj, Error **errp) - { - Error *err = NULL; - - visit_type_int(v, &(*obj)->integer, "integer", &err); - if (err) { - goto out; - } - visit_type_str(v, &(*obj)->string, "string", &err); - if (err) { - goto out; - } - - out: - error_propagate(errp, err); - } - - void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name, Error **errp) - { - Error *err = NULL; - - visit_start_struct(v, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), &err); - if (!err) { - if (*obj) { - visit_type_UserDefOne_fields(v, obj, errp); - } - visit_end_struct(v, &err); - } - error_propagate(errp, err); - } - - void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const char *name, Error **errp) - { - Error *err = NULL; - GenericList *i, **prev; - - visit_start_list(v, name, &err); - if (err) { - goto out; - } - - for (prev = (GenericList **)obj; - !err && (i = visit_next_list(v, prev, &err)) != NULL; - prev = &i) { - UserDefOneList *native_i = (UserDefOneList *)i; - visit_type_UserDefOne(v, &native_i->value, NULL, &err); - } - - error_propagate(errp, err); - err = NULL; - visit_end_list(v, &err); - out: - error_propagate(errp, err); - } - $ cat qapi-generated/example-qapi-visit.h -[Uninteresting stuff omitted...] - - #ifndef EXAMPLE_QAPI_VISIT_H - #define EXAMPLE_QAPI_VISIT_H - -[Visitors for built-in types omitted...] - - void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name, Error **errp); - void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const char *name, Error **errp); - - #endif - -=== scripts/qapi-commands.py === - -Used to generate the marshaling/dispatch functions for the commands defined -in the schema. The following files are generated: - -$(prefix)qmp-marshal.c: command marshal/dispatch functions for each - QMP command defined in the schema. Functions - generated by qapi-visit.py are used to - convert QObjects received from the wire into - function parameters, and uses the same - visitor functions to convert native C return - values to QObjects from transmission back - over the wire. - -$(prefix)qmp-commands.h: Function prototypes for the QMP commands - specified in the schema. - -Example: - - $ python scripts/qapi-commands.py --output-dir="qapi-generated" - --prefix="example-" example-schema.json - $ cat qapi-generated/example-qmp-marshal.c -[Uninteresting stuff omitted...] - - static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in, QObject **ret_out, Error **errp) - { - Error *err = NULL; - QmpOutputVisitor *qov = qmp_output_visitor_new(); - QapiDeallocVisitor *qdv; - Visitor *v; - - v = qmp_output_get_visitor(qov); - visit_type_UserDefOne(v, &ret_in, "unused", &err); - if (err) { - goto out; - } - *ret_out = qmp_output_get_qobject(qov); - - out: - error_propagate(errp, err); - qmp_output_visitor_cleanup(qov); - qdv = qapi_dealloc_visitor_new(); - v = qapi_dealloc_get_visitor(qdv); - visit_type_UserDefOne(v, &ret_in, "unused", NULL); - qapi_dealloc_visitor_cleanup(qdv); - } - - static void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp) - { - Error *err = NULL; - UserDefOne *retval; - QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args)); - QapiDeallocVisitor *qdv; - Visitor *v; - UserDefOne *arg1 = NULL; - - v = qmp_input_get_visitor(qiv); - visit_type_UserDefOne(v, &arg1, "arg1", &err); - if (err) { - goto out; - } - - retval = qmp_my_command(arg1, &err); - if (err) { - goto out; - } - - qmp_marshal_output_UserDefOne(retval, ret, &err); - - out: - error_propagate(errp, err); - qmp_input_visitor_cleanup(qiv); - qdv = qapi_dealloc_visitor_new(); - v = qapi_dealloc_get_visitor(qdv); - visit_type_UserDefOne(v, &arg1, "arg1", NULL); - qapi_dealloc_visitor_cleanup(qdv); - } - - static void qmp_init_marshal(void) - { - qmp_register_command("my-command", qmp_marshal_my_command, QCO_NO_OPTIONS); - } - - qapi_init(qmp_init_marshal); - $ cat qapi-generated/example-qmp-commands.h -[Uninteresting stuff omitted...] - - #ifndef EXAMPLE_QMP_COMMANDS_H - #define EXAMPLE_QMP_COMMANDS_H - - #include "example-qapi-types.h" - #include "qapi/qmp/qdict.h" - #include "qapi/error.h" - - UserDefOne *qmp_my_command(UserDefOne *arg1, Error **errp); - - #endif - -=== scripts/qapi-event.py === - -Used to generate the event-related C code defined by a schema. The -following files are created: - -$(prefix)qapi-event.h - Function prototypes for each event type, plus an - enumeration of all event names -$(prefix)qapi-event.c - Implementation of functions to send an event - -Example: - - $ python scripts/qapi-event.py --output-dir="qapi-generated" - --prefix="example-" example-schema.json - $ cat qapi-generated/example-qapi-event.c -[Uninteresting stuff omitted...] - - void qapi_event_send_my_event(Error **errp) - { - QDict *qmp; - Error *err = NULL; - QMPEventFuncEmit emit; - emit = qmp_event_get_func_emit(); - if (!emit) { - return; - } - - qmp = qmp_event_build_dict("MY_EVENT"); - - emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp, &err); - - error_propagate(errp, err); - QDECREF(qmp); - } - - const char *const example_QAPIEvent_lookup[] = { - [EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT", - [EXAMPLE_QAPI_EVENT_MAX] = NULL, - }; - $ cat qapi-generated/example-qapi-event.h -[Uninteresting stuff omitted...] - - #ifndef EXAMPLE_QAPI_EVENT_H - #define EXAMPLE_QAPI_EVENT_H - - #include "qapi/error.h" - #include "qapi/qmp/qdict.h" - #include "example-qapi-types.h" - - - void qapi_event_send_my_event(Error **errp); - - typedef enum example_QAPIEvent { - EXAMPLE_QAPI_EVENT_MY_EVENT = 0, - EXAMPLE_QAPI_EVENT_MAX = 1, - } example_QAPIEvent; - - extern const char *const example_QAPIEvent_lookup[]; - - #endif - -=== scripts/qapi-introspect.py === - -Used to generate the introspection C code for a schema. The following -files are created: - -$(prefix)qmp-introspect.c - Defines a string holding a JSON - description of the schema. -$(prefix)qmp-introspect.h - Declares the above string. - -Example: - - $ python scripts/qapi-introspect.py --output-dir="qapi-generated" - --prefix="example-" example-schema.json - $ cat qapi-generated/example-qmp-introspect.c -[Uninteresting stuff omitted...] - - const char example_qmp_schema_json[] = "[" - "{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, " - "{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"2\"}, " - "{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, " - "{\"members\": [{\"name\": \"arg1\", \"type\": \"2\"}], \"meta-type\": \"object\", \"name\": \"1\"}, " - "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, " - "{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": \"int\"}, " - "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}]"; - $ cat qapi-generated/example-qmp-introspect.h -[Uninteresting stuff omitted...] - - #ifndef EXAMPLE_QMP_INTROSPECT_H - #define EXAMPLE_QMP_INTROSPECT_H - - extern const char example_qmp_schema_json[]; - - #endif diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 188419dc1e74a..10fc01a0b22e5 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -494,3 +494,7 @@ config ARMSSE_CPUID config ARMSSE_MHU bool + +config STM32 + bool + select ARM_V7M diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 96ff08bfff015..a3956a4bb93d7 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -43,7 +43,6 @@ obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o -<<<<<<< HEAD obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o aspeed_ast2600.o obj-$(CONFIG_MPS2) += mps2.o @@ -55,7 +54,6 @@ obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o obj-$(CONFIG_NRF51_SOC) += nrf51_soc.o -======= obj-y += stm32.o stm32_rcc.o stm32_clktree.o stm32_p103.o obj-y += stm32f1xx.o stm32f2xx.o stm32f4xx.o stm32f7xx.o stm32_flash.o @@ -75,4 +73,3 @@ obj-y += pebble_control.o obj-y += pebble_robert.o obj-y += pebble_silk.o ->>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 32c35843c70a2..7531b97ccd3ee 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -12,12 +12,7 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/sysbus.h" -<<<<<<< HEAD #include "hw/arm/boot.h" -======= -#include "hw/arm/arm.h" -#include "hw/arm/stm32.h" ->>>>>>> 919b29ba7d... Pebble Qemu #include "hw/loader.h" #include "hw/qdev-properties.h" #include "elf.h" @@ -274,7 +269,6 @@ static void armv7m_realize(DeviceState *dev, Error **errp) } } -<<<<<<< HEAD static Property armv7m_properties[] = { DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type), DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION, @@ -295,27 +289,6 @@ static void armv7m_class_init(ObjectClass *klass, void *data) dc->realize = armv7m_realize; device_class_set_props(dc, armv7m_properties); -======= -static void armv7m_bitband_init(Object *parent) -{ - DeviceState *dev; - - dev = qdev_create(NULL, TYPE_BITBAND); - qdev_prop_set_uint32(dev, "base", 0x20000000); - if(parent) { - object_property_add_child(parent, "bitband-sram", OBJECT(dev), NULL); - } - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x22000000); - - dev = qdev_create(NULL, TYPE_BITBAND); - qdev_prop_set_uint32(dev, "base", 0x40000000); - if(parent) { - object_property_add_child(parent, "bitband-periph", OBJECT(dev), NULL); - } - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x42000000); ->>>>>>> 919b29ba7d... Pebble Qemu } static const TypeInfo armv7m_info = { @@ -333,121 +306,15 @@ static void armv7m_reset(void *opaque) cpu_reset(CPU(cpu)); } -<<<<<<< HEAD void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) { -======= -/* Init CPU and memory for a v7-M based board. - flash_size and sram_size are in bytes. - Returns the NVIC array. */ - - -DeviceState *armv7m_init(Object *parent, MemoryRegion *system_memory, - int flash_size, int sram_size, int num_irq, - const char *kernel_filename, const char *cpu_model) -{ - ARMCPU *cpu; - return armv7m_translated_init(parent, system_memory, flash_size, sram_size, num_irq, - kernel_filename, NULL, NULL, cpu_model, &cpu); -} - -DeviceState *armv7m_translated_init(Object *parent, MemoryRegion *system_memory, - int flash_size, int sram_size, int num_irq, - const char *kernel_filename, - uint64_t (*translate_fn)(void *, uint64_t), - void *translate_opaque, - const char *cpu_model, - ARMCPU **cpu_device) -{ - ARMCPU *cpu; - CPUARMState *env; - DeviceState *nvic; - if (num_irq == 0) { - num_irq = STM32_MAX_IRQ + 1; - } ->>>>>>> 919b29ba7d... Pebble Qemu int image_size; uint64_t entry; uint64_t lowaddr; int big_endian; -<<<<<<< HEAD AddressSpace *as; int asidx; CPUState *cs = CPU(cpu); -======= - MemoryRegion *hack = g_new(MemoryRegion, 1); - MemoryRegion *flash = NULL; - MemoryRegion *sram = g_new(MemoryRegion, 1); - ObjectClass *cpu_oc; - Error *err = NULL; - - if (kernel_filename) { - flash = g_new(MemoryRegion, 1); - } - - if (cpu_model == NULL) { - cpu_model = "cortex-m3"; - } - cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); - cpu = ARM_CPU(object_new(object_class_get_name(cpu_oc))); - if (cpu == NULL) { - fprintf(stderr, "Unable to find CPU definition\n"); - exit(1); - } - /* On Cortex-M3/M4, the MPU has 8 windows */ - object_property_set_int(OBJECT(cpu), 8, "pmsav7-dregion", &err); - if (err) { - error_report_err(err); - exit(1); - } - object_property_set_bool(OBJECT(cpu), true, "realized", &err); - if (err) { - error_report_err(err); - exit(1); - } - *cpu_device = cpu; - env = &cpu->env; - - if (kernel_filename) { - memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size, &err); - vmstate_register_ram_global(flash); - memory_region_set_readonly(flash, true); - memory_region_add_subregion(system_memory, 0, flash); - } - - if (sram_size) { - memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size, &err); - vmstate_register_ram_global(sram); - memory_region_add_subregion(system_memory, 0x20000000, sram); - } - armv7m_bitband_init(parent); - - /* If this is an M4, create the core-coupled memory region */ - if (!strcmp(cpu_model, "cortex-m4")) { - MemoryRegion *ccm = g_new(MemoryRegion, 1); - memory_region_init_ram(ccm, NULL, "armv7m.ccm", 64 * 1024 /* 64K */, &err); - vmstate_register_ram_global(ccm); - memory_region_add_subregion(system_memory, 0x10000000, ccm); - } - - nvic = qdev_create(NULL, "armv7m_nvic"); - qdev_prop_set_uint32(nvic, "num-irq", num_irq); - env->nvic = nvic; - if(parent) { - object_property_add_child(parent, "nvic", OBJECT(nvic), NULL); - } - qdev_init_nofail(nvic); - - // Connect the nvic's CPU #0 "parent_irq" output to the CPU's IRQ input handler - sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, - qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ)); ->>>>>>> 919b29ba7d... Pebble Qemu - - // Connect the nvic's "wakeup_out" output to the CPU's WKUP input handler - qemu_irq cpu_wakeup_in = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_WKUP); - qdev_connect_gpio_out_named(DEVICE(nvic), "wakeup_out", 0, cpu_wakeup_in); - - #ifdef TARGET_WORDS_BIGENDIAN big_endian = 1; @@ -455,7 +322,6 @@ DeviceState *armv7m_translated_init(Object *parent, MemoryRegion *system_memory, big_endian = 0; #endif -<<<<<<< HEAD if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { asidx = ARMASIdx_S; } else { @@ -470,13 +336,6 @@ DeviceState *armv7m_translated_init(Object *parent, MemoryRegion *system_memory, if (image_size < 0) { image_size = load_image_targphys_as(kernel_filename, 0, mem_size, as); -======= - if (kernel_filename) { - image_size = load_elf(kernel_filename, translate_fn, translate_opaque, &entry, &lowaddr, - NULL, big_endian, EM_ARM, 1); - if (image_size < 0) { - image_size = load_image_targphys(kernel_filename, 0, flash_size); ->>>>>>> 919b29ba7d... Pebble Qemu lowaddr = 0; } if (image_size < 0) { diff --git a/hw/arm/pebble.c b/hw/arm/pebble.c index 4c1c6d8c77e6f..eda4bd27a7444 100644 --- a/hw/arm/pebble.c +++ b/hw/arm/pebble.c @@ -20,7 +20,8 @@ * SOFTWARE. */ -#include "hw/ssi.h" +#include "qemu/osdep.h" +#include "hw/ssi/ssi.h" #include "hw/boards.h" #include "hw/block/flash.h" #include "sysemu/sysemu.h" @@ -28,6 +29,9 @@ #include "ui/console.h" #include "pebble_control.h" #include "pebble.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" +#include "qapi/error.h" // Disable jiggling the display when Pebble vibration is on. //#define PEBBLE_NO_DISPLAY_VIBRATE @@ -251,10 +255,10 @@ void pebble_connect_uarts(Stm32Uart *uart[], const PblBoardConfig *board_config) // This UART is used for control messages, put in our pebble_control device in between // the qemu serial chr and the uart. This enables us to intercept and act selectively // act on messages sent to the Pebble in QEMU before they get to it. - s_pebble_control = pebble_control_create(serial_hds[1], + s_pebble_control = pebble_control_create(serial_hd(1), uart[board_config->pebble_control_uart_index]); - stm32_uart_connect(uart[board_config->dbgserial_uart_index], serial_hds[2], 0); + stm32_uart_connect(uart[board_config->dbgserial_uart_index], serial_hd(2), 0); } void pebble_connect_uarts_stm32f7xx(Stm32F7xxUart *uart[], const PblBoardConfig *board_config) @@ -262,10 +266,10 @@ void pebble_connect_uarts_stm32f7xx(Stm32F7xxUart *uart[], const PblBoardConfig // This UART is used for control messages, put in our pebble_control device in between // the qemu serial chr and the uart. This enables us to intercept and act selectively // act on messages sent to the Pebble in QEMU before they get to it. - s_pebble_control = pebble_control_create_stm32f7xx(serial_hds[1], + s_pebble_control = pebble_control_create_stm32f7xx(serial_hd(1), uart[board_config->pebble_control_uart_index]); - stm32f7xx_uart_connect(uart[board_config->dbgserial_uart_index], serial_hds[2], 0); + stm32f7xx_uart_connect(uart[board_config->dbgserial_uart_index], serial_hd(2), 0); } @@ -388,6 +392,12 @@ static void pebble_32f2_init(MachineState *machine, const PblBoardConfig *board_ /* SPI flash */ spi = (SSIBus *)qdev_get_child_bus(stm.spi_dev[0], "ssi"); spi_flash = ssi_create_slave_no_init(spi, "n25q032a11"); + DriveInfo *dinfo = drive_get_next(IF_MTD); + if (dinfo) { + qdev_prop_set_drive(spi_flash, "drive", + blk_by_legacy_dinfo(dinfo), + &error_fatal); + } qdev_init_nofail(spi_flash); qemu_irq cs; @@ -413,8 +423,8 @@ static void pebble_32f2_init(MachineState *machine, const PblBoardConfig *board_ qemu_irq display_power; display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); - qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, - display_power); +//NVIC qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, +//NVIC display_power); // Connect up the uarts pebble_connect_uarts(uart, board_config); @@ -534,8 +544,8 @@ void pebble_32f439_init(MachineState *machine, const PblBoardConfig *board_confi qemu_irq display_power; display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); - qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, - display_power); +//NVIC qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, +// display_power); // Connect up the uarts @@ -585,15 +595,13 @@ static void pebble_board_vibe_ctl(void *opaque, int n, int level) } -static int pebble_board_init(SysBusDevice *dev) +static void pebble_board_init(Object *dev) { //PebbleBoard *s = FROM_SYSBUS(PebbleBoard, dev); /* This callback informs us that the vibrate is on/orr */ qdev_init_gpio_in_named(DEVICE(dev), pebble_board_vibe_ctl, "pebble_board_vibe_in", 1); - - return 0; } static Property pebble_board_properties[] = { @@ -605,15 +613,15 @@ static Property pebble_board_properties[] = { static void pebble_board_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = pebble_board_init; - dc->props = pebble_board_properties; + + device_class_set_props(dc, pebble_board_properties); } static const TypeInfo pebble_board_info = { .name = "pebble_board", .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PebbleBoard), + .instance_init = pebble_board_init, .class_init = pebble_board_class_init, }; diff --git a/hw/arm/pebble.h b/hw/arm/pebble.h index 80898d52c995b..aea857abbe10a 100644 --- a/hw/arm/pebble.h +++ b/hw/arm/pebble.h @@ -1,6 +1,3 @@ -#include -#include -#include #include "stm32f2xx.h" #include "stm32f4xx.h" #include "stm32f7xx.h" diff --git a/hw/arm/pebble_control.c b/hw/arm/pebble_control.c index f77d7b0920b4f..69fe2d3dd38e1 100644 --- a/hw/arm/pebble_control.c +++ b/hw/arm/pebble_control.c @@ -20,11 +20,13 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" -#include "sysemu/char.h" +#include "chardev/char.h" #include "qemu/timer.h" #include "qemu/sockets.h" +#include "qemu/log.h" #include "pebble_control.h" #include "pebble.h" @@ -156,7 +158,7 @@ struct PebbleControl { // The qemu_chr driver that connects to the host over a socket connection. We receive // data from this device, interpret it, and either process it directly in here or forward // it onto the uart in the emulated pebble. - CharDriverState *chr; + Chardev *chr; // The uart used by the emulated Pebble. We send data to it using its IOHandler // callbacks. Data written to the UART by the emulated Pebble gets passed onto us @@ -493,7 +495,7 @@ void pebble_control_send_vibe_notification(PebbleControl *s, bool on) } // ----------------------------------------------------------------------------------- -PebbleControl *pebble_control_create(CharDriverState *chr, Stm32Uart *uart) +PebbleControl *pebble_control_create(Chardev *chr, Stm32Uart *uart) { PebbleControl *s = malloc(sizeof(PebbleControl)); memset(s, 0, sizeof(*s)); @@ -514,19 +516,22 @@ PebbleControl *pebble_control_create(CharDriverState *chr, Stm32Uart *uart) stm32_uart_get_rcv_handlers(uart, &s->uart_chr_can_read, &s->uart_chr_read, &s->uart_chr_event); // Install our own receive handlers into the CharDriver - qemu_chr_add_handlers( - chr, + qemu_chr_fe_set_handlers( + &chr, pebble_control_can_receive, pebble_control_receive, pebble_control_event, - (void *)s); + NULL, + (void *)s, + NULL, + true); } return s; } // ----------------------------------------------------------------------------------- -PebbleControl *pebble_control_create_stm32f7xx(CharDriverState *chr, Stm32F7xxUart *uart) +PebbleControl *pebble_control_create_stm32f7xx(Chardev *chr, Stm32F7xxUart *uart) { PebbleControl *s = malloc(sizeof(PebbleControl)); memset(s, 0, sizeof(*s)); @@ -547,12 +552,15 @@ PebbleControl *pebble_control_create_stm32f7xx(CharDriverState *chr, Stm32F7xxUa stm32f7xx_uart_get_rcv_handlers(uart, &s->uart_chr_can_read, &s->uart_chr_read, &s->uart_chr_event); // Install our own receive handlers into the CharDriver - qemu_chr_add_handlers( - chr, + qemu_chr_fe_set_handlers( + &chr, pebble_control_can_receive, pebble_control_receive, pebble_control_event, - (void *)s); + NULL, + (void *)s, + NULL, + true); } return s; diff --git a/hw/arm/pebble_control.h b/hw/arm/pebble_control.h index 3cf220264e158..2530ff34f4067 100644 --- a/hw/arm/pebble_control.h +++ b/hw/arm/pebble_control.h @@ -3,8 +3,8 @@ typedef struct PebbleControl PebbleControl; -PebbleControl *pebble_control_create(CharDriverState *chr, Stm32Uart *uart); -PebbleControl *pebble_control_create_stm32f7xx(CharDriverState *chr, Stm32F7xxUart *uart); +PebbleControl *pebble_control_create(Chardev *chr, Stm32Uart *uart); +PebbleControl *pebble_control_create_stm32f7xx(Chardev *chr, Stm32F7xxUart *uart); void pebble_control_send_vibe_notification(PebbleControl *s, bool on); diff --git a/hw/arm/pebble_robert.c b/hw/arm/pebble_robert.c index 7180cc4009b60..7613e8b497679 100644 --- a/hw/arm/pebble_robert.c +++ b/hw/arm/pebble_robert.c @@ -1,7 +1,8 @@ +#include "qemu/osdep.h" #include "pebble.h" #include "hw/boards.h" -#include "hw/ssi.h" - +#include "hw/ssi/ssi.h" +#include "hw/qdev-properties.h" const static PblBoardConfig s_board_config_robert_bb = { .dbgserial_uart_index = 2, // USART3 @@ -112,8 +113,8 @@ void pebble_32f7xx_init(MachineState *machine, const PblBoardConfig *board_confi qemu_irq display_power; display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); - qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, - display_power); +//NVIC qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, +//NVIC display_power); // Connect up the uarts pebble_connect_uarts_stm32f7xx(uart, board_config); diff --git a/hw/arm/pebble_silk.c b/hw/arm/pebble_silk.c index f3f224b65837d..9725dc0daa7e3 100644 --- a/hw/arm/pebble_silk.c +++ b/hw/arm/pebble_silk.c @@ -1,6 +1,8 @@ +#include "qemu/osdep.h" #include "pebble.h" #include "hw/boards.h" -#include "hw/ssi.h" +#include "hw/ssi/ssi.h" +#include "hw/qdev-properties.h" const static PblBoardConfig s_board_config_silk_bb = { .dbgserial_uart_index = 0, // USART1 @@ -86,8 +88,8 @@ void pebble_32f412_init(MachineState *machine, const PblBoardConfig *board_confi qemu_irq display_power; display_power = qdev_get_gpio_in_named(display_dev, "power_ctl", 0); - qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, - display_power); +//NVIC qdev_connect_gpio_out_named((DeviceState *)cpu->env.nvic, "power_out", 0, +//NVIC display_power); // Connect up the uarts diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 149ca82152ab1..d136ba1a92adf 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1308,7 +1308,6 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) &error_fatal); memory_region_add_subregion(system_memory, 0x20000000, sram); -<<<<<<< HEAD nvic = qdev_create(NULL, TYPE_ARMV7M); qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); @@ -1317,10 +1316,6 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) "memory", &error_abort); /* This will exit with an error if the user passed us a bad cpu_type */ qdev_init_nofail(nvic); -======= - nvic = armv7m_init(/* no parent */ NULL, system_memory, flash_size, 128 * 1024, NUM_IRQ_LINES, - kernel_filename, cpu_model); ->>>>>>> 919b29ba7d... Pebble Qemu qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, qemu_allocate_irq(&do_sys_reset, NULL, 0)); diff --git a/hw/arm/stm32.c b/hw/arm/stm32.c index ae6733abc1962..ed883a7c5d9ad 100644 --- a/hw/arm/stm32.c +++ b/hw/arm/stm32.c @@ -19,9 +19,11 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/arm/stm32.h" #include "exec/address-spaces.h" #include "exec/gdbstub.h" +#include "hw/qdev-properties.h" /* DEFINITIONS */ @@ -35,7 +37,7 @@ void stm32_hw_warn(const char *fmt, ...) fprintf(stderr, "qemu stm32: hardware warning: "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); - cpu_dump_state(first_cpu, stderr, fprintf, 0); + cpu_dump_state(first_cpu, stderr, 0); va_end(ap); } @@ -51,7 +53,7 @@ void stm32_create_uart_dev( qemu_irq irq) { char child_name[8]; - DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + DeviceState *uart_dev = qdev_create(NULL, TYPE_STM32_UART); QDEV_PROP_SET_PERIPH_T(uart_dev, "periph", periph); qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); qdev_prop_set_ptr(uart_dev, "stm32_gpio", gpio_dev); diff --git a/hw/arm/stm32_clktree.c b/hw/arm/stm32_clktree.c index 34270d660ca6a..cd81887230ca8 100644 --- a/hw/arm/stm32_clktree.c +++ b/hw/arm/stm32_clktree.c @@ -19,8 +19,10 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/arm/stm32_clktree.h" +#include "qemu/host-utils.h" /* DEFINITIONS*/ diff --git a/hw/arm/stm32_exti.c b/hw/arm/stm32_exti.c index ae1d7b63abc51..3112ffb77c5b7 100644 --- a/hw/arm/stm32_exti.c +++ b/hw/arm/stm32_exti.c @@ -19,7 +19,11 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/arm/stm32.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/hw.h" @@ -313,7 +317,7 @@ static const MemoryRegionOps stm32_exti_ops = { static void stm32_exti_reset(DeviceState *dev) { - Stm32Exti *s = FROM_SYSBUS(Stm32Exti, SYS_BUS_DEVICE(dev)); + Stm32Exti *s = STM32_EXTI(dev); s->EXTI_IMR = 0x00000000; s->EXTI_RTSR = 0x00000000; @@ -346,11 +350,12 @@ void stm32_exti_reset_gpio(Stm32Exti *s, unsigned exti_line, const uint8_t gpio_ /* DEVICE INITIALIZATION */ -static int stm32_exti_init(SysBusDevice *dev) +static void stm32_exti_realize(DeviceState *obj, Error **pError) { int i; - Stm32Exti *s = FROM_SYSBUS(Stm32Exti, dev); + Stm32Exti *s = STM32_EXTI(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); s->stm32_gpio = (stm32f2xx_gpio **)s->stm32_gpio_prop; @@ -363,8 +368,6 @@ static int stm32_exti_init(SysBusDevice *dev) } qdev_init_gpio_in(DEVICE(dev), stm32_exti_gpio_in_handler, EXTI_LINE_COUNT); - - return 0; } static Property stm32_exti_properties[] = { @@ -377,13 +380,13 @@ static void stm32_exti_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_exti_init; + dc->realize = stm32_exti_realize; dc->reset = stm32_exti_reset; - dc->props = stm32_exti_properties; + device_class_set_props(dc, stm32_exti_properties); } static TypeInfo stm32_exti_info = { - .name = "stm32_exti", + .name = TYPE_STM32_EXTI, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Exti), .class_init = stm32_exti_class_init diff --git a/hw/arm/stm32_flash.c b/hw/arm/stm32_flash.c index 740d9ac96dca2..393c9739bacce 100644 --- a/hw/arm/stm32_flash.c +++ b/hw/arm/stm32_flash.c @@ -29,7 +29,10 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/arm/stm32.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" //#include "exec-memory.h" typedef struct { @@ -62,9 +65,10 @@ static const MemoryRegionOps stm32_flash_ops = { .endianness = DEVICE_NATIVE_ENDIAN }; -static int stm32_flash_init(SysBusDevice *dev) +static void stm32_flash_init(Object *obj) { - Stm32Flash *s = FROM_SYSBUS(Stm32Flash, dev); + Stm32Flash *s = STM32_FLASH(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); memory_region_init_io( &s->iomem, @@ -73,8 +77,7 @@ static int stm32_flash_init(SysBusDevice *dev) &s, "stm32_flash", s->size); - sysbus_init_mmio(dev, &s->iomem); - return 0; + sysbus_init_mmio(sbd, &s->iomem); } static Property stm32_flash_properties[] = { @@ -85,16 +88,15 @@ static Property stm32_flash_properties[] = { static void stm32_flash_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_flash_init; - dc->props = stm32_flash_properties; + device_class_set_props(dc, stm32_flash_properties); } static TypeInfo stm32_flash_info = { - .name = "stm32_flash", + .name = TYPE_STM32_FLASH, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Flash), + .instance_init = stm32_flash_init, .class_init = stm32_flash_class_init, }; diff --git a/hw/arm/stm32_p103.c b/hw/arm/stm32_p103.c index 3ec75aa93a855..3c2c3f497ff43 100644 --- a/hw/arm/stm32_p103.c +++ b/hw/arm/stm32_p103.c @@ -20,13 +20,14 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "stm32f1xx.h" #include "hw/sysbus.h" -#include "hw/arm/arm.h" -#include "hw/devices.h" +#include "hw/arm/armv7m.h" #include "ui/console.h" #include "sysemu/sysemu.h" #include "hw/boards.h" +#include "hw/irq.h" typedef struct { @@ -121,7 +122,7 @@ static void stm32_p103_init(MachineState *machine) { /* Connect RS232 to UART */ stm32_uart_connect( s->stm32_uart[STM32_UART2_INDEX], - serial_hds[0], + serial_hd(0), STM32_USART2_NO_REMAP); } diff --git a/hw/arm/stm32_rcc.c b/hw/arm/stm32_rcc.c index 11c0e1dca08a9..f9841d3b0cd3e 100644 --- a/hw/arm/stm32_rcc.c +++ b/hw/arm/stm32_rcc.c @@ -1,8 +1,7 @@ -#include "stm32_rcc.h" +#include "qemu/osdep.h" #include "hw/arm/stm32.h" #include "hw/arm/stm32_clktree.h" - - +#include "stm32f2xx_rcc.h" /* PUBLIC FUNCTIONS */ @@ -17,8 +16,8 @@ void stm32_rcc_check_periph_clk(Stm32Rcc *s, stm32_periph_t periph) * is disabled is a bug and give a warning to unsuspecting programmers. * When I made this mistake on real hardware the write had no effect. */ - stm32_hw_warn("Warning: You are attempting to use the stm32_rcc peripheral while " - "its clock is disabled.\n"); + stm32_hw_warn("Warning: You are attempting to use the stm32_rcc peripheral %d while " + "its clock is disabled.\n", periph); } } @@ -27,11 +26,12 @@ void stm32_rcc_set_periph_clk_irq( stm32_periph_t periph, qemu_irq periph_irq) { - Clk clk = s->PERIPHCLK[periph]; + Stm32f2xxRcc*v = STM32F2XX_RCC(s); + Clk clk2 = v->PERIPHCLK[periph]; - assert(clk != NULL); + assert(clk2 != NULL); - clktree_adduser(clk, periph_irq); + clktree_adduser(clk2, periph_irq); } uint32_t stm32_rcc_get_periph_freq( @@ -40,7 +40,8 @@ uint32_t stm32_rcc_get_periph_freq( { Clk clk; - clk = s->PERIPHCLK[periph]; + Stm32f2xxRcc*v = STM32F2XX_RCC(s); + clk = v->PERIPHCLK[periph]; assert(clk != NULL); diff --git a/hw/arm/stm32f1xx.c b/hw/arm/stm32f1xx.c index da4f30e5a0a84..be33a529b871b 100644 --- a/hw/arm/stm32f1xx.c +++ b/hw/arm/stm32f1xx.c @@ -19,9 +19,11 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/arm/stm32.h" #include "stm32f1xx.h" #include "exec/address-spaces.h" +#include "hw/qdev-properties.h" /* PERIPHERALS */ @@ -116,7 +118,7 @@ void stm32f1xx_init( flash_size); memory_region_add_subregion(address_space_mem, 0x08000000, flash_alias_mem); - DeviceState *rcc_dev = qdev_create(NULL, "stm32f1xx_rcc"); + DeviceState *rcc_dev = qdev_create(NULL, TYPE_STM32F1XX_RCC); qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); object_property_add_child(stm32_container, "stm32f1xx_rcc", OBJECT(rcc_dev), NULL); @@ -176,7 +178,7 @@ void stm32f1xx_init( }; for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { const stm32_periph_t periph = STM32F1XX_UART1 + i; - DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + DeviceState *uart_dev = qdev_create(NULL, TYPE_STM32_UART); uart_dev->id = stm32f1xx_periph_name_arr[periph]; qdev_prop_set_int32(uart_dev, "periph", periph); qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); diff --git a/hw/arm/stm32f1xx_rcc.c b/hw/arm/stm32f1xx_rcc.c index 10458680dab3e..a028688f6bf65 100644 --- a/hw/arm/stm32f1xx_rcc.c +++ b/hw/arm/stm32f1xx_rcc.c @@ -20,9 +20,14 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "stm32f1xx_rcc.h" #include "qemu/timer.h" +#include "hw/hw.h" #include +#include "hw/qdev-properties.h" +#include "hw/timer/armv7m_systick.h" +#include "hw/irq.h" /* DEFINITIONS*/ @@ -523,7 +528,7 @@ static const MemoryRegionOps stm32_rcc_ops = { static void stm32_rcc_reset(DeviceState *dev) { - Stm32f1xxRcc *s = FROM_SYSBUS(Stm32f1xxRcc, SYS_BUS_DEVICE(dev)); + Stm32f1xxRcc *s = STM32F1XX_RCC(dev); stm32_rcc_RCC_CR_write(s, 0x00000083, true); stm32_rcc_RCC_CFGR_write(s, 0x00000000, true); @@ -552,7 +557,7 @@ static void stm32_rcc_hclk_upd_irq_handler(void *opaque, int n, int level) * (which is an unchanging number independent of the CPU frequency) to * system/external clock ticks. */ - system_clock_scale = get_ticks_per_sec() / hclk_freq; + system_clock_scale = NANOSECONDS_PER_SECOND / hclk_freq; } #ifdef DEBUG_STM32_RCC @@ -636,20 +641,19 @@ static void stm32_rcc_init_clk(Stm32f1xxRcc *s) s->PERIPHCLK[STM32F1XX_UART5] = clktree_create_clk("UART5", 1, 1, false, CLKTREE_NO_MAX_FREQ, 0, s->PCLK1, NULL); } -static int stm32_rcc_init(SysBusDevice *dev) +static void stm32_rcc_init(Object *obj) { - Stm32f1xxRcc *s = FROM_SYSBUS(Stm32f1xxRcc, dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + Stm32f1xxRcc *s = STM32F1XX_RCC(obj); memory_region_init_io(&s->iomem, OBJECT(s), &stm32_rcc_ops, s, "rcc", 0x1000); - sysbus_init_mmio(dev, &s->iomem); + sysbus_init_mmio(sbd, &s->iomem); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); stm32_rcc_init_clk(s); - - return 0; } @@ -663,17 +667,16 @@ static Property stm32_rcc_properties[] = { static void stm32_rcc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_rcc_init; dc->reset = stm32_rcc_reset; - dc->props = stm32_rcc_properties; + device_class_set_props(dc, stm32_rcc_properties); } static TypeInfo stm32_rcc_info = { - .name = "stm32f1xx_rcc", + .name = TYPE_STM32F1XX_RCC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32f1xxRcc), + .instance_init=stm32_rcc_init, .class_init = stm32_rcc_class_init }; diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index 4c24b60d92a80..118c3425591cc 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -105,7 +105,6 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) &error_fatal); memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram); -<<<<<<< HEAD armv7m = DEVICE(&s->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 96); qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type); @@ -117,10 +116,6 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) error_propagate(errp, err); return; } -======= - nvic = armv7m_init(/* no parent */ NULL, get_system_memory(), FLASH_SIZE, SRAM_SIZE, 96, - s->kernel_filename, s->cpu_model); ->>>>>>> 919b29ba7d... Pebble Qemu /* System configuration controller */ dev = DEVICE(&s->syscfg); diff --git a/hw/arm/stm32f2xx.c b/hw/arm/stm32f2xx.c index d8397d95495b8..9d89c13790f53 100644 --- a/hw/arm/stm32f2xx.c +++ b/hw/arm/stm32f2xx.c @@ -19,13 +19,18 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" +#include "sysemu/runstate.h" #include "hw/arm/stm32.h" #include "stm32f2xx.h" #include "exec/address-spaces.h" #include "exec/memory.h" -#include "hw/ssi.h" +#include "hw/ssi/ssi.h" +#include "hw/irq.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" // drive_get +#include "hw/qdev-properties.h" +#include "../../target/arm/cpu.h" static const char *stm32f2xx_periph_name_arr[] = { ENUM_STRING(STM32_UART1), @@ -84,44 +89,42 @@ static uint64_t kernel_load_translate_fn(void *opaque, uint64_t from_addr) { } static -void do_sys_reset(void *opaque, int n, int level) -{ +void do_sys_reset(void *opaque, int n, int level) { if (level) { - qemu_system_reset_request(); + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); } } void stm32f2xx_init( - ram_addr_t flash_size, - ram_addr_t ram_size, - const char *kernel_filename, - Stm32Gpio **stm32_gpio, - Stm32Uart **stm32_uart, - Stm32Timer **stm32_timer, - DeviceState **stm32_rtc, - uint32_t osc_freq, - uint32_t osc32_freq, - struct stm32f2xx *stm, - ARMCPU **cpu) -{ + ram_addr_t flash_size, + ram_addr_t ram_size, + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + Stm32Uart **stm32_uart, + Stm32Timer **stm32_timer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f2xx *stm, + ARMCPU **cpu) { MemoryRegion *address_space_mem = get_system_memory(); DriveInfo *dinfo; DeviceState *nvic; int i; - Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); + Object * stm32_container = container_get(qdev_get_machine(), "/stm32"); nvic = armv7m_translated_init( - stm32_container, - address_space_mem, - flash_size * 1024, - ram_size * 1024, - 0, /* default number of irqs */ - kernel_filename, - kernel_load_translate_fn, - NULL, - "cortex-m3", - cpu); + stm32_container, + address_space_mem, + flash_size * 1024, + ram_size * 1024, + 128, /* default number of irqs */ + kernel_filename, + kernel_load_translate_fn, + NULL, + ARM_CPU_TYPE_NAME("cortex-m3"), + cpu); qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, qemu_allocate_irq(&do_sys_reset, NULL, 0)); @@ -137,39 +140,39 @@ void stm32f2xx_init( MemoryRegionSection mrs = memory_region_find(address_space_mem, STM32_FLASH_ADDR_START, WORD_ACCESS_SIZE); MemoryRegion *flash_alias = g_new(MemoryRegion, 1); memory_region_init_alias( - flash_alias, - NULL, - "stm32f2xx.flash.alias", - mrs.mr, - 0, - flash_size * 1024); + flash_alias, + NULL, + "stm32f2xx.flash.alias", + mrs.mr, + 0, + flash_size * 1024); memory_region_add_subregion(address_space_mem, 0, flash_alias); - DeviceState *rcc_dev = qdev_create(NULL, "stm32f2xx_rcc"); + DeviceState *rcc_dev = qdev_create(NULL, TYPE_STM32F2XX_RCC); qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); stm32_init_periph(rcc_dev, STM32_RCC_PERIPH, 0x40023800, qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); - DeviceState **gpio_dev = (DeviceState **)g_malloc0(sizeof(DeviceState *) * STM32F2XX_GPIO_COUNT); - for(i = 0; i < STM32F2XX_GPIO_COUNT; i++) { + DeviceState **gpio_dev = (DeviceState **) g_malloc0(sizeof(DeviceState *) * STM32F2XX_GPIO_COUNT); + for (i = 0; i < STM32F2XX_GPIO_COUNT; i++) { stm32_periph_t periph = STM32_GPIOA + i; - gpio_dev[i] = qdev_create(NULL, "stm32f2xx_gpio"); + gpio_dev[i] = qdev_create(NULL, TYPE_STM32F2XX_GPIO); gpio_dev[i]->id = stm32f2xx_periph_name_arr[periph]; qdev_prop_set_int32(gpio_dev[i], "periph", periph); // qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); stm32_init_periph(gpio_dev[i], periph, 0x40020000 + (i * 0x400), NULL); - stm32_gpio[i] = (Stm32Gpio *)gpio_dev[i]; + stm32_gpio[i] = (Stm32Gpio *) gpio_dev[i]; } /* Connect the WKUP pin (GPIO A, pin 0) to the NVIC's WKUP handler */ - qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); - f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); +//NVIC qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); +//NVIC f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); /* EXTI */ - DeviceState *exti_dev = qdev_create(NULL, "stm32_exti"); + DeviceState *exti_dev = qdev_create(NULL, TYPE_STM32_EXTI); qdev_prop_set_ptr(exti_dev, "stm32_gpio", gpio_dev); stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40013C00, NULL); SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); @@ -189,7 +192,7 @@ void stm32f2xx_init( sysbus_connect_irq(exti_busdev, 12, qdev_get_gpio_in(nvic, STM32_TAMP_STAMP_IRQ)); sysbus_connect_irq(exti_busdev, 13, qdev_get_gpio_in(nvic, STM32_RTC_WKUP_IRQ)); - DeviceState *syscfg_dev = qdev_create(NULL, "stm32f2xx_syscfg"); + DeviceState *syscfg_dev = qdev_create(NULL, TYPE_STM32F2XX_SYSCFG); qdev_prop_set_ptr(syscfg_dev, "stm32_rcc", rcc_dev); qdev_prop_set_ptr(syscfg_dev, "stm32_exti", exti_dev); qdev_prop_set_bit(syscfg_dev, "boot0", 0); @@ -210,16 +213,16 @@ void stm32f2xx_init( for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { assert(i < STM32F2XX_UART_COUNT); const stm32_periph_t periph = STM32_UART1 + i; - DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + DeviceState *uart_dev = qdev_create(NULL, TYPE_STM32_UART); uart_dev->id = stm32f2xx_periph_name_arr[periph]; qdev_prop_set_int32(uart_dev, "periph", periph); - qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); + qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); // qdev_prop_set_ptr(uart_dev, "stm32_gpio", gpio_dev); // qdev_prop_set_ptr(uart_dev, "stm32_afio", afio_dev); // qdev_prop_set_ptr(uart_dev, "stm32_check_tx_pin_callback", (void *)stm32_afio_uart_check_tx_pin_callback); stm32_init_periph(uart_dev, periph, uart_desc[i].addr, - qdev_get_gpio_in(nvic, uart_desc[i].irq_idx)); - stm32_uart[i] = (Stm32Uart *)uart_dev; + qdev_get_gpio_in(nvic, uart_desc[i].irq_idx)); + stm32_uart[i] = (Stm32Uart *) uart_dev; } @@ -234,11 +237,11 @@ void stm32f2xx_init( }; for (i = 0; i < ARRAY_LENGTH(spi_desc); ++i) { const stm32_periph_t periph = STM32_SPI1 + i; - stm->spi_dev[i] = qdev_create(NULL, "stm32f2xx_spi"); + stm->spi_dev[i] = qdev_create(NULL, TYPE_STM32F2XX_SPI); stm->spi_dev[i]->id = stm32f2xx_periph_name_arr[periph]; qdev_prop_set_int32(stm->spi_dev[i], "periph", periph); stm32_init_periph(stm->spi_dev[i], periph, spi_desc[i].addr, - qdev_get_gpio_in(nvic, spi_desc[i].irq_idx)); + qdev_get_gpio_in(nvic, spi_desc[i].irq_idx)); } @@ -248,11 +251,11 @@ void stm32f2xx_init( // stm32_uart[STM32_UART4_INDEX] = stm32_create_uart_dev(STM32_UART4, rcc_dev, gpio_dev, afio_dev, 0x40004C00, qdev_get_gpio_in(nvic, STM32_UART4_IRQ]); // stm32_uart[STM32_UART5_INDEX] = stm32_create_uart_dev(STM32_UART5, rcc_dev, gpio_dev, afio_dev, 0x40005000, qdev_get_gpio_in(nvic, STM32_UART5_IRQ]); // stm32_uart[STM32_UART6_INDEX] = stm32_create_uart_dev(STM32_UART6, rcc_dev, gpio_dev, afio_dev, 0x40011400, qdev_get_gpio_in(nvic, STM32_UART6_IRQ]); - DeviceState *adc_dev = qdev_create(NULL, "stm32f2xx_adc"); + DeviceState *adc_dev = qdev_create(NULL, TYPE_STM32_ADC); stm32_init_periph(adc_dev, STM32_ADC1, 0x40012000, NULL); /* RTC real time clock */ - DeviceState *rtc_dev = qdev_create(NULL, "f2xx_rtc"); + DeviceState *rtc_dev = qdev_create(NULL, TYPE_STM32F2XX_RTC); *stm32_rtc = rtc_dev; stm32_init_periph(rtc_dev, STM32_RTC, 0x40002800, NULL); // Alarm A @@ -263,13 +266,13 @@ void stm32f2xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 2, qdev_get_gpio_in(exti_dev, 22)); /* Power management */ - DeviceState *pwr_dev = qdev_create(NULL, "f2xx_pwr"); + DeviceState *pwr_dev = qdev_create(NULL, TYPE_STM32F2XX_PWR); stm32_init_periph(pwr_dev, STM32_RTC, 0x40007000, NULL); - qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); +//NVIC qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); #define dummy_dev(name, start, size) do {\ - DeviceState *dummy = qdev_create(NULL, "f2xx_dummy"); \ + DeviceState *dummy = qdev_create(NULL, TYPE_STM32F2XX_DUMMY); \ qdev_prop_set_ptr(dummy, "name", (void *)name); \ qdev_prop_set_int32(dummy, "size", size); \ qdev_init_nofail(dummy); \ @@ -299,66 +302,71 @@ void stm32f2xx_init( assert(i < STM32F2XX_TIM_COUNT); const stm32_periph_t periph = STM32_TIM1 + timer_desc[i].timer_num - 1; - DeviceState *timer = qdev_create(NULL, "f2xx_tim"); + DeviceState *timer = qdev_create(NULL, TYPE_STM32F2XX_TIM); timer->id = stm32f2xx_periph_name_arr[periph]; stm32_init_periph(timer, periph, timer_desc[i].addr, qdev_get_gpio_in(nvic, timer_desc[i].irq_idx)); - stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *)timer; + stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *) timer; } - dummy_dev("Reserved", 0x40002400, 0x400); + dummy_dev("Reserved", 0x40002400, 0x400); // - dummy_dev("WWDG", 0x40002C00, 0x400); - dummy_dev("IWDG", 0x40003000, 0x400); - dummy_dev("Reserved", 0x40003400, 0x400); + dummy_dev("WWDG", 0x40002C00, 0x400); + dummy_dev("IWDG", 0x40003000, 0x400); + dummy_dev("Reserved", 0x40003400, 0x400); // // - dummy_dev("Reserved", 0x40004000, 0x400); + dummy_dev("Reserved", 0x40004000, 0x400); // // // // - DeviceState *i2c1 = qdev_create(NULL, "f2xx_i2c"); + DeviceState *i2c1 = qdev_create(NULL, TYPE_STM32F2XX_I2C); i2c1->id = stm32f2xx_periph_name_arr[STM32_I2C1]; qdev_prop_set_int32(i2c1, "periph", STM32_I2C1); stm32_init_periph(i2c1, STM32_I2C1, 0x40005400, qdev_get_gpio_in(nvic, STM32_I2C1_EV_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(i2c1), 1, qdev_get_gpio_in(nvic, STM32_I2C1_ER_IRQ)); - DeviceState *i2c2 = qdev_create(NULL, "f2xx_i2c"); + DeviceState *i2c2 = qdev_create(NULL, TYPE_STM32F2XX_I2C); i2c2->id = stm32f2xx_periph_name_arr[STM32_I2C2]; qdev_prop_set_int32(i2c2, "periph", STM32_I2C2); stm32_init_periph(i2c2, STM32_I2C2, 0x40005800, qdev_get_gpio_in(nvic, STM32_I2C2_EV_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(i2c2), 1, qdev_get_gpio_in(nvic, STM32_I2C2_ER_IRQ)); - DeviceState *i2c3 = qdev_create(NULL, "f2xx_i2c"); + DeviceState *i2c3 = qdev_create(NULL, TYPE_STM32F2XX_I2C); i2c3->id = stm32f2xx_periph_name_arr[STM32_I2C3]; qdev_prop_set_int32(i2c3, "periph", STM32_I2C3); stm32_init_periph(i2c3, STM32_I2C2, 0x40005C00, qdev_get_gpio_in(nvic, STM32_I2C3_EV_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(i2c3), 1, qdev_get_gpio_in(nvic, STM32_I2C3_ER_IRQ)); - dummy_dev("Reserved", 0x40006000, 0x400); - dummy_dev("BxCAN1", 0x40006400, 0x400); - dummy_dev("BxCAN2", 0x40006800, 0x400); - dummy_dev("Reserved", 0x40006C00, 0x400); + dummy_dev("OTP", 0x1FFF7800, 0x1FFF7A0F - 0x1FFF7800 + 1); + dummy_dev("FLASH_R", 0x40023C00, 0x400); + dummy_dev("DBGMCU", 0xe0042000, 0x100); + dummy_dev("U_ID", 0x1FFF7A10, 96 / 8); + + dummy_dev("Reserved", 0x40006000, 0x400); + dummy_dev("BxCAN1", 0x40006400, 0x400); + dummy_dev("BxCAN2", 0x40006800, 0x400); + dummy_dev("Reserved", 0x40006C00, 0x400); // PWR dummy_dev("DAC1/DAC2", 0x40007400, 0x400); - dummy_dev("Reserved", 0x40007800, 0x400); - dummy_dev("Reserved", 0x40008000, 0x8000); + dummy_dev("Reserved", 0x40007800, 0x400); + dummy_dev("Reserved", 0x40008000, 0x8000); dummy_dev("TIM1/PWM1", 0x40010000, 0x400); dummy_dev("TIM8/PWM2", 0x40010400, 0x400); // USART1 // USART6 - dummy_dev("Reserved", 0x40011800, 0x800); + dummy_dev("Reserved", 0x40011800, 0x800); // ADC1 - ADC2 - ADC3 // skipped reserved from here on - dummy_dev("SDIO", 0x40012C00, 0x400); + dummy_dev("SDIO", 0x40012C00, 0x400); // SPI1 // SYSCFG needed - DeviceState *crc = qdev_create(NULL, "f2xx_crc"); + DeviceState *crc = qdev_create(NULL, TYPE_STM32F2XX_CRC); stm32_init_periph(crc, STM32_CRC, 0x40023000, NULL); - - DeviceState *dma1 = qdev_create(NULL, "f2xx_dma"); + + DeviceState *dma1 = qdev_create(NULL, TYPE_STM32F2XX_DMA); stm32_init_periph(dma1, STM32_DMA1, 0x40026000, NULL); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 0, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM0_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 1, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM1_IRQ)); @@ -369,7 +377,7 @@ void stm32f2xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 6, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM6_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 7, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM7_IRQ)); - DeviceState *dma2 = qdev_create(NULL, "f2xx_dma"); + DeviceState *dma2 = qdev_create(NULL, TYPE_STM32F2XX_DMA); stm32_init_periph(dma2, STM32_DMA2, 0x40026400, NULL); sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 0, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM0_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 1, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM1_IRQ)); diff --git a/hw/arm/stm32f2xx_adc.c b/hw/arm/stm32f2xx_adc.c index a663fcd2d70ab..c686e885e245d 100644 --- a/hw/arm/stm32f2xx_adc.c +++ b/hw/arm/stm32f2xx_adc.c @@ -23,7 +23,10 @@ * QEMU model of the stm32f2xx ADC. */ +#include "qemu/osdep.h" #include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/qdev-properties.h" /* Per-ADC registers */ #define R_ADC_SR (0x00 / 4) @@ -194,17 +197,18 @@ static const MemoryRegionOps stm32f2xx_adc_ops = { static void f2xx_adc_reset(DeviceState *ds) { - stm32_adc *s = FROM_SYSBUS(stm32_adc, SYS_BUS_DEVICE(ds)); + stm32_adc *s = STM32_ADC(ds); /* Hack for low ambient light level (2500) */ s->regs[0][R_ADC_DR] = 2730; s->regs[1][R_ADC_DR] = 2500; } -static int -stm32f2xx_adc_init(SysBusDevice *dev) +static void +stm32f2xx_adc_init(Object *obj) { - stm32_adc *s = FROM_SYSBUS(stm32_adc, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + stm32_adc *s = STM32_ADC(obj); #if 0 sysbus_init_irq(dev, &s->irq); @@ -212,8 +216,6 @@ stm32f2xx_adc_init(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &stm32f2xx_adc_ops, s, "adc", 0x400); sysbus_init_mmio(dev, &s->iomem); - - return 0; } static Property stm32f2xx_adc_properties[] = { @@ -226,15 +228,15 @@ stm32f2xx_adc_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = stm32f2xx_adc_init; dc->reset = f2xx_adc_reset; - dc->props = stm32f2xx_adc_properties; + device_class_set_props(dc, stm32f2xx_adc_properties); } static const TypeInfo stm32f2xx_adc_info = { - .name = "stm32f2xx_adc", + .name = TYPE_STM32_ADC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(stm32_adc), + .instance_init = stm32f2xx_adc_init, .class_init = stm32f2xx_adc_class_init }; diff --git a/hw/arm/stm32f2xx_crc.c b/hw/arm/stm32f2xx_crc.c index fa5eb0450c291..3a8d321c9f276 100644 --- a/hw/arm/stm32f2xx_crc.c +++ b/hw/arm/stm32f2xx_crc.c @@ -22,7 +22,11 @@ /* * QEMU crc emulation */ + +#include "qemu/osdep.h" #include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/qdev-properties.h" #define R_CRC_DR (0x00 / 4) #define R_CRC_DR_RESET 0xffffffff @@ -182,21 +186,20 @@ static const MemoryRegionOps f2xx_crc_ops = { } }; -static int -f2xx_crc_init(SysBusDevice *dev) +static void +f2xx_crc_init(Object *obj) { - f2xx_crc *s = FROM_SYSBUS(f2xx_crc, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + f2xx_crc *s = STM32F2XX_CRC(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_crc_ops, s, "crc", 0x400); sysbus_init_mmio(dev, &s->iomem); - - return 0; } static void f2xx_crc_reset(DeviceState *ds) { - f2xx_crc *s = FROM_SYSBUS(f2xx_crc, SYS_BUS_DEVICE(ds)); + f2xx_crc *s = STM32F2XX_CRC(ds); s->crc = R_CRC_DR_RESET; } @@ -209,18 +212,17 @@ static void f2xx_crc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f2xx_crc_init; dc->reset = f2xx_crc_reset; //TODO: fix this: dc->no_user = 1; - dc->props = f2xx_crc_properties; + device_class_set_props(dc, f2xx_crc_properties); } static const TypeInfo f2xx_crc_info = { - .name = "f2xx_crc", + .name = TYPE_STM32F2XX_CRC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f2xx_crc), + .instance_init = f2xx_crc_init, .class_init = f2xx_crc_class_init, }; diff --git a/hw/arm/stm32f2xx_dma.c b/hw/arm/stm32f2xx_dma.c index eb04c43e488a3..75eaff8fa515e 100644 --- a/hw/arm/stm32f2xx_dma.c +++ b/hw/arm/stm32f2xx_dma.c @@ -22,7 +22,13 @@ /* * QEMU DMA controller device model */ + +#include "qemu/osdep.h" #include "hw/sysbus.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/arm/stm32.h" //#define DEBUG_STM32F2XX_DMA #ifdef DEBUG_STM32F2XX_DMA @@ -351,10 +357,11 @@ static const MemoryRegionOps f2xx_dma_ops = { } }; -static int -f2xx_dma_init(SysBusDevice *dev) +static void +f2xx_dma_init(Object *obj) { - f2xx_dma *s = FROM_SYSBUS(f2xx_dma, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + f2xx_dma *s = STM32F2XX_DMA(obj); int i; memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_dma_ops, s, "dma", 0x400); @@ -363,14 +370,12 @@ f2xx_dma_init(SysBusDevice *dev) for (i = 0; i < R_DMA_Sx_COUNT; i++) { sysbus_init_irq(dev, &s->stream[i].irq); } - - return 0; } static void f2xx_dma_reset(DeviceState *ds) { - f2xx_dma *s = FROM_SYSBUS(f2xx_dma, SYS_BUS_DEVICE(ds)); + f2xx_dma *s = STM32F2XX_DMA(ds); memset(&s->ifcr, 0, sizeof(s->ifcr)); @@ -391,17 +396,17 @@ f2xx_dma_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f2xx_dma_init; dc->reset = f2xx_dma_reset; //TODO: fix this: dc->no_user = 1; - dc->props = f2xx_dma_properties; + device_class_set_props(dc, f2xx_dma_properties); } static const TypeInfo f2xx_dma_info = { - .name = "f2xx_dma", + .name = TYPE_STM32F2XX_DMA, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f2xx_dma), + .instance_init = f2xx_dma_init, .class_init = f2xx_dma_class_init, }; diff --git a/hw/arm/stm32f2xx_dummy.c b/hw/arm/stm32f2xx_dummy.c index 0bc59879d2dfc..30e3efd482d4f 100644 --- a/hw/arm/stm32f2xx_dummy.c +++ b/hw/arm/stm32f2xx_dummy.c @@ -22,7 +22,12 @@ /* * QEMU dummy emulation */ + +#include "qemu/osdep.h" #include "hw/sysbus.h" +#include "qemu/log.h" +#include "hw/qdev-properties.h" +#include "hw/arm/stm32.h" typedef struct f2xx_dummy { SysBusDevice busdev; @@ -62,14 +67,14 @@ static const MemoryRegionOps f2xx_dummy_ops = { } }; -static int -f2xx_dummy_init(SysBusDevice *dev) +static void +f2xx_dummy_realize(DeviceState *obj, Error **pError) { - f2xx_dummy *s = FROM_SYSBUS(f2xx_dummy, dev); + f2xx_dummy *s = STM32F2XX_DUMMY(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_dummy_ops, s, "dummy", s->size); sysbus_init_mmio(dev, &s->iomem); - return 0; } static Property f2xx_dummy_properties[] = { @@ -82,15 +87,14 @@ static void f2xx_dummy_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f2xx_dummy_init; // TODO: fix this: dc->no_user = 1; - dc->props = f2xx_dummy_properties; + dc->realize = f2xx_dummy_realize; + device_class_set_props(dc, f2xx_dummy_properties); } static const TypeInfo f2xx_dummy_info = { - .name = "f2xx_dummy", + .name = TYPE_STM32F2XX_DUMMY, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f2xx_dummy), .class_init = f2xx_dummy_class_init, diff --git a/hw/arm/stm32f2xx_flash.c b/hw/arm/stm32f2xx_flash.c index f2a6492aa05c8..49336de41b5e5 100644 --- a/hw/arm/stm32f2xx_flash.c +++ b/hw/arm/stm32f2xx_flash.c @@ -20,13 +20,16 @@ * SOFTWARE. */ +#include "qemu/osdep.h" #include "sysemu/blockdev.h" #include "hw/hw.h" #include "hw/block/flash.h" #include "block/block.h" #include "sysemu/block-backend.h" #include "hw/sysbus.h" - +#include "hw/arm/stm32.h" +#include "hw/qdev-properties.h" +#include "migration/cpu.h" struct f2xx_flash { SysBusDevice busdev; @@ -42,10 +45,10 @@ struct f2xx_flash { f2xx_flash_t *f2xx_flash_register(BlockBackend *blk, hwaddr base, hwaddr size) { - DeviceState *dev = qdev_create(NULL, "f2xx.flash"); + DeviceState *dev = qdev_create(NULL, TYPE_STM32F2XX_FLASH); //SysBusDevice *busdev = SYS_BUS_DEVICE(dev); - f2xx_flash_t *flash = (f2xx_flash_t *)object_dynamic_cast(OBJECT(dev), - "f2xx.flash"); + f2xx_flash_t *flash = STM32F2XX_FLASH(dev); + qdev_prop_set_uint32(dev, "size", size); qdev_prop_set_uint64(dev, "base_address", base); if (blk) { @@ -85,16 +88,17 @@ static const MemoryRegionOps f2xx_flash_ops = { MemoryRegion *get_system_memory(void); /* XXX */ -static int f2xx_flash_init(SysBusDevice *dev) +static void f2xx_flash_init(DeviceState *obj, Error **pError) { Error *err = NULL; - f2xx_flash_t *flash = FROM_SYSBUS(typeof(*flash), dev); + f2xx_flash_t *flash = STM32F2XX_FLASH(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); // memory_region_init_rom_device(&flash->mem, &f2xx_flash_ops, flash, "name", // size); - memory_region_init_ram(&flash->mem, NULL, "f2xx.flash", flash->size, &err); + memory_region_init_ram(&flash->mem, OBJECT(flash), "f2xx.flash", flash->size, &err); - vmstate_register_ram(&flash->mem, DEVICE(flash)); +// vmstate_register_ram(&flash->mem, DEVICE(flash)); //vmstate_register_ram_global(&flash->mem); memory_region_set_readonly(&flash->mem, true); memory_region_add_subregion(get_system_memory(), flash->base_address, &flash->mem); @@ -104,15 +108,13 @@ static int f2xx_flash_init(SysBusDevice *dev) memset(flash->data, 0xff, flash->size); if (flash->blk) { int r; - r = blk_read(flash->blk, 0, flash->data, blk_getlength(flash->blk)/BDRV_SECTOR_SIZE); + r = blk_pread(flash->blk, 0, flash->data, blk_getlength(flash->blk)); if (r < 0) { vmstate_unregister_ram(&flash->mem, DEVICE(flash)); // memory_region_destroy(&flash->mem); - return 1; +// return 1; } } - - return 0; } static Property f2xx_flash_properties[] = { @@ -125,14 +127,13 @@ static Property f2xx_flash_properties[] = { static void f2xx_flash_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = f2xx_flash_init; - dc->props = f2xx_flash_properties; + dc->realize = f2xx_flash_init, + device_class_set_props(dc, f2xx_flash_properties); } static const TypeInfo f2xx_flash_info = { - .name = "f2xx.flash", + .name = TYPE_STM32F2XX_FLASH, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(struct f2xx_flash), .class_init = f2xx_flash_class_init, diff --git a/hw/arm/stm32f2xx_gpio.c b/hw/arm/stm32f2xx_gpio.c index b6afa0c9c261c..93b2975ce1443 100644 --- a/hw/arm/stm32f2xx_gpio.c +++ b/hw/arm/stm32f2xx_gpio.c @@ -23,8 +23,11 @@ * QEMU model of the stm32f2xx GPIO module */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" //#define DEBUG_STM32_GPIO #ifdef DEBUG_STM32_GPIO @@ -179,7 +182,7 @@ static const MemoryRegionOps stm32f2xx_gpio_ops = { static void stm32f2xx_gpio_reset(DeviceState *dev) { - stm32f2xx_gpio *s = FROM_SYSBUS(stm32f2xx_gpio, SYS_BUS_DEVICE(dev)); + stm32f2xx_gpio *s = STM32F2XX_GPIO(dev); switch (s->periph) { case 0: @@ -237,10 +240,11 @@ f2xx_gpio_wake_set(stm32f2xx_gpio *s, unsigned pin, qemu_irq irq) DPRINTF("GPIO %d set cpu_wake %d irq %p\n", s->periph, pin, irq); } -static int -stm32f2xx_gpio_init(SysBusDevice *dev) +static void +stm32f2xx_gpio_init(Object *obj) { - stm32f2xx_gpio *s = FROM_SYSBUS(stm32f2xx_gpio, dev); + stm32f2xx_gpio *s = STM32F2XX_GPIO(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); memory_region_init_io(&s->iomem, OBJECT(s), &stm32f2xx_gpio_ops, s, "gpio", 0x400); sysbus_init_mmio(dev, &s->iomem); @@ -248,8 +252,6 @@ stm32f2xx_gpio_init(SysBusDevice *dev) qdev_init_gpio_in(DEVICE(dev), f2xx_gpio_set, STM32_GPIO_PIN_COUNT); qdev_init_gpio_out(DEVICE(dev), s->pin, STM32_GPIO_PIN_COUNT); qdev_init_gpio_out_named(DEVICE(dev), s->alternate_function, "af", STM32_GPIO_PIN_COUNT); - - return 0; } static Property stm32f2xx_gpio_properties[] = { @@ -262,17 +264,16 @@ static void stm32f2xx_gpio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = stm32f2xx_gpio_init; dc->reset = stm32f2xx_gpio_reset; - dc->props = stm32f2xx_gpio_properties; + device_class_set_props(dc, stm32f2xx_gpio_properties); } static const TypeInfo stm32f2xx_gpio_info = { - .name = "stm32f2xx_gpio", + .name = TYPE_STM32F2XX_GPIO, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(stm32f2xx_gpio), + .instance_init = stm32f2xx_gpio_init, .class_init = stm32f2xx_gpio_class_init }; diff --git a/hw/arm/stm32f2xx_i2c.c b/hw/arm/stm32f2xx_i2c.c index f73dc8692aec8..68016eafa624a 100644 --- a/hw/arm/stm32f2xx_i2c.c +++ b/hw/arm/stm32f2xx_i2c.c @@ -23,9 +23,13 @@ * QEMU model of the stm32f2xx I2C controller. */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" #include "hw/i2c/i2c.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" #define R_I2C_CR1 (0x00 / 4) #define R_I2C_CR2 (0x04 / 4) @@ -245,18 +249,17 @@ f2xx_i2c_reset(DeviceState *dev) // s->regs[R_SR] = R_SR_RESET; } -static int -f2xx_i2c_init(SysBusDevice *dev) +static void +f2xx_i2c_init(Object *obj) { - struct f2xx_i2c *s = FROM_SYSBUS(struct f2xx_i2c, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + struct f2xx_i2c *s = STM32F2XX_I2C(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_i2c_ops, s, "i2c", 0x3ff); sysbus_init_mmio(dev, &s->iomem); sysbus_init_irq(dev, &s->evt_irq); sysbus_init_irq(dev, &s->err_irq); s->bus = i2c_init_bus(DEVICE(dev), "i2c"); - - return 0; } @@ -269,17 +272,16 @@ static void f2xx_i2c_class_init(ObjectClass *c, void *data) { DeviceClass *dc = DEVICE_CLASS(c); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); - sc->init = f2xx_i2c_init; dc->reset = f2xx_i2c_reset; - dc->props = f2xx_i2c_properties; + device_class_set_props(dc, f2xx_i2c_properties); } static const TypeInfo f2xx_i2c_info = { - .name = "f2xx_i2c", + .name = TYPE_STM32F2XX_I2C, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(struct f2xx_i2c), + .instance_init = f2xx_i2c_init, .class_init = f2xx_i2c_class_init }; diff --git a/hw/arm/stm32f2xx_pwr.c b/hw/arm/stm32f2xx_pwr.c index 33913929eec4b..25a5d0045ef02 100644 --- a/hw/arm/stm32f2xx_pwr.c +++ b/hw/arm/stm32f2xx_pwr.c @@ -22,9 +22,13 @@ /* * QEMU stm32f2xx RTC emulation */ + +#include "qemu/osdep.h" #include #include "hw/sysbus.h" #include "qemu/timer.h" +#include "hw/qdev-properties.h" +#include "hw/arm/stm32.h" //#define DEBUG_STM32F2XX_PWR #ifdef DEBUG_STM32F2XX_PWR @@ -140,24 +144,23 @@ bool f2xx_pwr_powerdown_deepsleep(void *opaqe) static void f2xx_pwr_reset(DeviceState *dev) { - f2xx_pwr *s = FROM_SYSBUS(f2xx_pwr, SYS_BUS_DEVICE(dev)); + f2xx_pwr *s = STM32F2XX_PWR(dev); memset(s->regs, 0, sizeof(s->regs)); } -static int -f2xx_pwr_init(SysBusDevice *dev) +static void +f2xx_pwr_init(Object *obj) { - f2xx_pwr *s = FROM_SYSBUS(f2xx_pwr, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + f2xx_pwr *s = STM32F2XX_PWR(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_pwr_ops, s, "pwr", 0x08); sysbus_init_mmio(dev, &s->iomem); s->regs[R_PWR_CR] = 0; s->regs[R_PWR_CSR] = 0; - - return 0; } static Property f2xx_pwr_properties[] = { @@ -169,16 +172,16 @@ f2xx_pwr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f2xx_pwr_init; dc->reset = f2xx_pwr_reset; - dc->props = f2xx_pwr_properties; + device_class_set_props(dc, f2xx_pwr_properties); } static const TypeInfo f2xx_pwr_info = { - .name = "f2xx_pwr", + .name = TYPE_STM32F2XX_PWR, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f2xx_pwr), + .instance_init = f2xx_pwr_init, .class_init = f2xx_pwr_class_init, }; diff --git a/hw/arm/stm32f2xx_rcc.c b/hw/arm/stm32f2xx_rcc.c index a55f760ad23cc..d8c2d2499f8d9 100644 --- a/hw/arm/stm32f2xx_rcc.c +++ b/hw/arm/stm32f2xx_rcc.c @@ -20,8 +20,13 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "stm32f2xx_rcc.h" #include "qemu/timer.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" +#include "hw/timer/armv7m_systick.h" #include @@ -922,7 +927,7 @@ static const MemoryRegionOps stm32_rcc_ops = { static void stm32_rcc_reset(DeviceState *dev) { - Stm32f2xxRcc *s = FROM_SYSBUS(Stm32f2xxRcc, SYS_BUS_DEVICE(dev)); + Stm32f2xxRcc *s = STM32F2XX_RCC(dev); stm32_rcc_RCC_CR_write(s, RCC_CR_RESET_VALUE, true); stm32_rcc_RCC_PLLCFGR_write(s, RCC_PLLCFGR_RESET_VALUE, true); @@ -952,7 +957,7 @@ static void stm32_rcc_hclk_upd_irq_handler(void *opaque, int n, int level) * (which is an unchanging number independent of the CPU frequency) to * system/external clock ticks. */ - system_clock_scale = get_ticks_per_sec() / hclk_freq; + system_clock_scale = NANOSECONDS_PER_SECOND / hclk_freq; } #ifdef DEBUG_STM32_RCC @@ -1085,9 +1090,10 @@ static void stm32_rcc_init_clk(Stm32f2xxRcc *s) -static int stm32_rcc_init(SysBusDevice *dev) +static void stm32_rcc_realize(DeviceState *obj, Error **pError) { - Stm32f2xxRcc *s = FROM_SYSBUS(Stm32f2xxRcc, dev); + Stm32f2xxRcc *s = STM32F2XX_RCC(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); memory_region_init_io(&s->iomem, OBJECT(s), &stm32_rcc_ops, s, "rcc", 0x40023BFF - 0x40023800 + 1); @@ -1097,8 +1103,6 @@ static int stm32_rcc_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); stm32_rcc_init_clk(s); - - return 0; } @@ -1114,13 +1118,13 @@ static void stm32_rcc_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_rcc_init; + dc->realize = stm32_rcc_realize, dc->reset = stm32_rcc_reset; - dc->props = stm32_rcc_properties; + device_class_set_props(dc, stm32_rcc_properties); } static TypeInfo stm32_rcc_info = { - .name = "stm32f2xx_rcc", + .name = TYPE_STM32F2XX_RCC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32f2xxRcc), .class_init = stm32_rcc_class_init diff --git a/hw/arm/stm32f2xx_rtc.c b/hw/arm/stm32f2xx_rtc.c index c37a7ed955073..9e512f0ea7e70 100644 --- a/hw/arm/stm32f2xx_rtc.c +++ b/hw/arm/stm32f2xx_rtc.c @@ -22,10 +22,16 @@ /* * QEMU stm32f2xx RTC emulation */ + +#include "qemu/osdep.h" #include #include "hw/sysbus.h" #include "qemu/timer.h" #include "hw/arm/stm32.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" +#include "qemu/bcd.h" +#include "qemu/cutils.h" // Define this to add extra BKUP registers past the normal ones implemented by the STM. // For Pebble emulation, we use these to pass settings flags to the emulated target @@ -613,14 +619,15 @@ static const MemoryRegionOps f2xx_rtc_ops = { static void f2xx_rtc_reset(DeviceState *dev) { - f2xx_rtc *s = FROM_SYSBUS(f2xx_rtc, SYS_BUS_DEVICE(dev)); + f2xx_rtc *s = STM32F2XX_RTC(dev); s->regs[R_RTC_CR] = 0; } -static int -f2xx_rtc_init(SysBusDevice *dev) +static void +f2xx_rtc_init(Object *obj) { - f2xx_rtc *s = FROM_SYSBUS(f2xx_rtc, dev); + f2xx_rtc *s = STM32F2XX_RTC(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_rtc_ops, s, "rtc", 0x03ff); sysbus_init_mmio(dev, &s->iomem); @@ -653,7 +660,6 @@ f2xx_rtc_init(SysBusDevice *dev) timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + period_ns); s->wu_timer = timer_new_ns(QEMU_CLOCK_REALTIME, f2xx_wu_timer, s); - return 0; } static Property f2xx_rtc_properties[] = { @@ -664,18 +670,18 @@ static void f2xx_rtc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f2xx_rtc_init; + //TODO: fix this: dc->no_user = 1; - dc->props = f2xx_rtc_properties; + device_class_set_props(dc, f2xx_rtc_properties); dc->reset = f2xx_rtc_reset; } static const TypeInfo f2xx_rtc_info = { - .name = "f2xx_rtc", + .name = TYPE_STM32F2XX_RTC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f2xx_rtc), + .instance_init = f2xx_rtc_init, .class_init = f2xx_rtc_class_init, }; diff --git a/hw/arm/stm32f2xx_syscfg.c b/hw/arm/stm32f2xx_syscfg.c index 3e4dbc6dd5a66..1ba1b7279ba7a 100644 --- a/hw/arm/stm32f2xx_syscfg.c +++ b/hw/arm/stm32f2xx_syscfg.c @@ -19,7 +19,10 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "stm32f2xx.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" @@ -216,7 +219,7 @@ static const MemoryRegionOps stm32_syscfg_ops = { static void stm32_syscfg_reset(DeviceState *dev) { - Stm32Syscfg *s = FROM_SYSBUS(Stm32Syscfg, SYS_BUS_DEVICE(dev)); + Stm32Syscfg *s = STM32F2XX_SYSCFG(dev); stm32_syscfg_SYSCFG_MEMRMP_write(s, 0x00000000, true); stm32_syscfg_SYSCFG_EXTICR_write(s, 0, 0x00000000, true); @@ -229,9 +232,10 @@ static void stm32_syscfg_reset(DeviceState *dev) /* DEVICE INITIALIZATION */ -static int stm32_syscfg_init(SysBusDevice *dev) +static void stm32_syscfg_realize(DeviceState *obj, Error **pError) { - Stm32Syscfg *s = FROM_SYSBUS(Stm32Syscfg, dev); + Stm32Syscfg *s = STM32F2XX_SYSCFG(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; s->stm32_exti = (Stm32Exti *)s->stm32_exti_prop; @@ -239,8 +243,6 @@ static int stm32_syscfg_init(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &stm32_syscfg_ops, s, "syscfg", 0x03ff); sysbus_init_mmio(dev, &s->iomem); - - return 0; } static Property stm32_syscfg_properties[] = { @@ -254,15 +256,14 @@ static Property stm32_syscfg_properties[] = { static void stm32_syscfg_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_syscfg_init; + dc->realize = stm32_syscfg_realize; dc->reset = stm32_syscfg_reset; - dc->props = stm32_syscfg_properties; + device_class_set_props(dc, stm32_syscfg_properties); } static TypeInfo stm32_syscfg_info = { - .name = "stm32f2xx_syscfg", + .name = TYPE_STM32F2XX_SYSCFG, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Syscfg), .class_init = stm32_syscfg_class_init @@ -274,3 +275,4 @@ static void stm32_syscfg_register_types(void) } type_init(stm32_syscfg_register_types) + diff --git a/hw/arm/stm32f2xx_tim.c b/hw/arm/stm32f2xx_tim.c index b974a3f349154..56ce6093bc50b 100644 --- a/hw/arm/stm32f2xx_tim.c +++ b/hw/arm/stm32f2xx_tim.c @@ -22,9 +22,13 @@ /* * QEMU stm32f2xx TIM emulation */ + +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" #include "qemu/timer.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" //#define DEBUG_STM32F2XX_TIM #ifdef DEBUG_STM32F2XX_TIM @@ -273,17 +277,18 @@ static const MemoryRegionOps f2xx_tim_ops = { static void f2xx_tim_reset(DeviceState *dev) { - f2xx_tim *s = FROM_SYSBUS(f2xx_tim, SYS_BUS_DEVICE(dev)); + f2xx_tim *s = STM32F2XX_TIM(dev); timer_del(s->timer); memset(&s->regs, 0, sizeof(s->regs)); } -static int -f2xx_tim_init(SysBusDevice *dev) +static void +f2xx_tim_init(Object *obj) { - f2xx_tim *s = FROM_SYSBUS(f2xx_tim, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + f2xx_tim *s = STM32F2XX_TIM(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f2xx_tim_ops, s, "tim", 0xa0); sysbus_init_mmio(dev, &s->iomem); @@ -295,8 +300,6 @@ f2xx_tim_init(SysBusDevice *dev) qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_ratio_changed, "pwm_ratio_changed", 1); qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_enable, "pwm_enable", 1); - - return 0; } static Property f2xx_tim_properties[] = { @@ -308,17 +311,17 @@ f2xx_tim_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f2xx_tim_init; //TODO: fix this: dc->no_user = 1; - dc->props = f2xx_tim_properties; + device_class_set_props(dc, f2xx_tim_properties); dc->reset = f2xx_tim_reset; } static const TypeInfo f2xx_tim_info = { - .name = "f2xx_tim", + .name = TYPE_STM32F2XX_TIM, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f2xx_tim), + .instance_init = f2xx_tim_init, .class_init = f2xx_tim_class_init, }; diff --git a/hw/arm/stm32f4xx.c b/hw/arm/stm32f4xx.c index 711cc7c88188d..50e910987668b 100644 --- a/hw/arm/stm32f4xx.c +++ b/hw/arm/stm32f4xx.c @@ -19,13 +19,18 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" +#include "sysemu/runstate.h" #include "hw/arm/stm32.h" #include "stm32f4xx.h" #include "exec/address-spaces.h" #include "exec/memory.h" -#include "hw/ssi.h" +#include "hw/ssi/ssi.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" // drive_get +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "../../target/arm/cpu.h" static const char *stm32f4xx_periph_name_arr[] = { ENUM_STRING(STM32_UART1), @@ -88,45 +93,43 @@ static uint64_t kernel_load_translate_fn(void *opaque, uint64_t from_addr) { } static -void do_sys_reset(void *opaque, int n, int level) -{ +void do_sys_reset(void *opaque, int n, int level) { if (level) { - qemu_system_reset_request(); + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); } } void stm32f4xx_init( - ram_addr_t flash_size, /* in KBytes */ - ram_addr_t ram_size, /* in KBytes */ - const char *kernel_filename, - Stm32Gpio **stm32_gpio, - const uint32_t *gpio_idr_masks, - Stm32Uart **stm32_uart, - Stm32Timer **stm32_timer, - DeviceState **stm32_rtc, - uint32_t osc_freq, - uint32_t osc32_freq, - struct stm32f4xx *stm, - ARMCPU **cpu) -{ + ram_addr_t flash_size, /* in KBytes */ + ram_addr_t ram_size, /* in KBytes */ + const char *kernel_filename, + Stm32Gpio **stm32_gpio, + const uint32_t *gpio_idr_masks, + Stm32Uart **stm32_uart, + Stm32Timer **stm32_timer, + DeviceState **stm32_rtc, + uint32_t osc_freq, + uint32_t osc32_freq, + struct stm32f4xx *stm, + ARMCPU **cpu) { MemoryRegion *address_space_mem = get_system_memory(); DriveInfo *dinfo; DeviceState *nvic; int i; - Object *stm32_container = container_get(qdev_get_machine(), "/stm32"); + Object * stm32_container = container_get(qdev_get_machine(), "/stm32"); nvic = armv7m_translated_init( - stm32_container, /* parent */ - address_space_mem, /* address space memory */ - flash_size * 1024, /* flash size in bytes */ - ram_size * 1024, /* sram size in bytes */ - 0, /* default number of irqs */ - kernel_filename, /* kernel filename */ - kernel_load_translate_fn, /* kernel translate address function */ - NULL, /* translate function opaque argument */ - "cortex-m4", /* cpu model */ - cpu); /* Returned cpu instance */ + stm32_container, /* parent */ + address_space_mem, /* address space memory */ + flash_size * 1024, /* flash size in bytes */ + ram_size * 1024, /* sram size in bytes */ + 128, /* default number of irqs */ + kernel_filename, /* kernel filename */ + kernel_load_translate_fn, /* kernel translate address function */ + NULL, /* translate function opaque argument */ + ARM_CPU_TYPE_NAME("cortex-m4"), /* cpu model */ + cpu); /* Returned cpu instance */ qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, qemu_allocate_irq(&do_sys_reset, NULL, 0)); @@ -145,50 +148,50 @@ void stm32f4xx_init( WORD_ACCESS_SIZE); MemoryRegion *flash_alias = g_new(MemoryRegion, 1); memory_region_init_alias( - flash_alias, /* alias memory region */ - NULL, /* owner */ - "stm32f4xx.flash.alias", /* name */ - mrs.mr, /* original region */ - 0, /* offset */ - flash_size * 1024); /* size in bytes */ + flash_alias, /* alias memory region */ + NULL, /* owner */ + "stm32f4xx.flash.alias", /* name */ + mrs.mr, /* original region */ + 0, /* offset */ + flash_size * 1024); /* size in bytes */ memory_region_add_subregion(address_space_mem, 0, flash_alias); /* Setup the RCC */ - DeviceState *rcc_dev = qdev_create(NULL, "stm32f2xx_rcc"); + DeviceState *rcc_dev = qdev_create(NULL, TYPE_STM32F2XX_RCC); qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); stm32_init_periph(rcc_dev, - STM32_RCC_PERIPH, /* periph index, not used */ - 0x40023800, /* base address */ - qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); /* irq */ + STM32_RCC_PERIPH, /* periph index, not used */ + 0x40023800, /* base address */ + qdev_get_gpio_in(nvic, STM32_RCC_IRQ)); /* irq */ /* Setup GPIOs */ - DeviceState **gpio_dev = (DeviceState **)g_malloc0(sizeof(DeviceState *) - * STM32F4XX_GPIO_COUNT); - for(i = 0; i < STM32F4XX_GPIO_COUNT; i++) { + DeviceState **gpio_dev = (DeviceState **) g_malloc0(sizeof(DeviceState *) + * STM32F4XX_GPIO_COUNT); + for (i = 0; i < STM32F4XX_GPIO_COUNT; i++) { stm32_periph_t periph = STM32_GPIOA + i; - gpio_dev[i] = qdev_create(NULL, "stm32f2xx_gpio"); + gpio_dev[i] = qdev_create(NULL, TYPE_STM32F2XX_GPIO); gpio_dev[i]->id = stm32f4xx_periph_name_arr[periph]; qdev_prop_set_int32(gpio_dev[i], "periph", periph); qdev_prop_set_uint32(gpio_dev[i], "idr-mask", gpio_idr_masks[i]); // qdev_prop_set_ptr(gpio_dev[i], "stm32_rcc", rcc_dev); stm32_init_periph(gpio_dev[i], periph, 0x40020000 + (i * 0x400), NULL /*irq*/); - stm32_gpio[i] = (Stm32Gpio *)gpio_dev[i]; + stm32_gpio[i] = (Stm32Gpio *) gpio_dev[i]; } /* Connect the WKUP pin (GPIO A, pin 0) to the NVIC's WKUP handler */ - qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); - f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); +//NVIC qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); +//NVIC f2xx_gpio_wake_set((stm32f2xx_gpio *) (stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); /* EXTI */ - DeviceState *exti_dev = qdev_create(NULL, "stm32_exti"); + DeviceState *exti_dev = qdev_create(NULL, TYPE_STM32_EXTI); qdev_prop_set_ptr(exti_dev, "stm32_gpio", gpio_dev); stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40013C00, NULL); SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); - + /* IRQs from EXTI to NVIC */ sysbus_connect_irq(exti_busdev, 0, qdev_get_gpio_in(nvic, STM32_EXTI0_IRQ)); sysbus_connect_irq(exti_busdev, 1, qdev_get_gpio_in(nvic, STM32_EXTI1_IRQ)); @@ -207,7 +210,7 @@ void stm32f4xx_init( /* System configuration controller */ - DeviceState *syscfg_dev = qdev_create(NULL, "stm32f2xx_syscfg"); + DeviceState *syscfg_dev = qdev_create(NULL, TYPE_STM32F2XX_SYSCFG); qdev_prop_set_ptr(syscfg_dev, "stm32_rcc", rcc_dev); qdev_prop_set_ptr(syscfg_dev, "stm32_exti", exti_dev); qdev_prop_set_bit(syscfg_dev, "boot0", 0); @@ -231,7 +234,7 @@ void stm32f4xx_init( for (i = 0; i < ARRAY_LENGTH(uart_desc); ++i) { assert(i < STM32F4XX_UART_COUNT); const stm32_periph_t periph = STM32_UART1 + i; - DeviceState *uart_dev = qdev_create(NULL, "stm32-uart"); + DeviceState *uart_dev = qdev_create(NULL, TYPE_STM32_UART); uart_dev->id = stm32f4xx_periph_name_arr[periph]; qdev_prop_set_int32(uart_dev, "periph", periph); qdev_prop_set_ptr(uart_dev, "stm32_rcc", rcc_dev); @@ -244,7 +247,7 @@ void stm32f4xx_init( irq = qdev_get_gpio_in(nvic, uart_desc[i].irq_idx); } stm32_init_periph(uart_dev, periph, uart_desc[i].addr, irq); - stm32_uart[i] = (Stm32Uart *)uart_dev; + stm32_uart[i] = (Stm32Uart *) uart_dev; } // TODO: Should we use these instead? // stm32_uart[STM32_UART1_INDEX] = stm32_create_uart_dev(STM32_UART1, rcc_dev, gpio_dev, afio_dev, 0x40011000, pic[STM32_UART1_IRQ]); @@ -270,7 +273,7 @@ void stm32f4xx_init( for (i = 0; i < ARRAY_LENGTH(spi_desc); ++i) { assert(i < STM32F4XX_SPI_COUNT); const stm32_periph_t periph = STM32_SPI1 + i; - stm->spi_dev[i] = qdev_create(NULL, "stm32f2xx_spi"); + stm->spi_dev[i] = qdev_create(NULL, TYPE_STM32F2XX_SPI); stm->spi_dev[i]->id = stm32f4xx_periph_name_arr[periph]; qdev_prop_set_int32(stm->spi_dev[i], "periph", periph); stm32_init_periph(stm->spi_dev[i], periph, spi_desc[i].addr, @@ -278,16 +281,16 @@ void stm32f4xx_init( } /* QSPI */ - stm->qspi_dev = qdev_create(NULL, "stm32f412_qspi"); + stm->qspi_dev = qdev_create(NULL, TYPE_STM32F412_QSPI); stm->qspi_dev->id = stm32f4xx_periph_name_arr[STM32_QSPI]; stm32_init_periph(stm->qspi_dev, STM32_QSPI, 0xA0001000, qdev_get_gpio_in(nvic, STM32_QSPI_IRQ)); /* ADC */ - DeviceState *adc_dev = qdev_create(NULL, "stm32f2xx_adc"); + DeviceState *adc_dev = qdev_create(NULL, TYPE_STM32_ADC); stm32_init_periph(adc_dev, STM32_ADC1, 0x40012000, NULL); /* RTC real time clock */ - DeviceState *rtc_dev = qdev_create(NULL, "f2xx_rtc"); + DeviceState *rtc_dev = qdev_create(NULL, TYPE_STM32F2XX_RTC); *stm32_rtc = rtc_dev; stm32_init_periph(rtc_dev, STM32_RTC, 0x40002800, NULL); // Alarm A @@ -298,12 +301,12 @@ void stm32f4xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 2, qdev_get_gpio_in(exti_dev, 22)); /* Power management */ - DeviceState *pwr_dev = qdev_create(NULL, "f2xx_pwr"); + DeviceState *pwr_dev = qdev_create(NULL, TYPE_STM32F2XX_PWR); stm32_init_periph(pwr_dev, STM32_RTC, 0x40007000, NULL); - qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); +//NVIC qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); #define dummy_dev(name, start, size) do {\ - DeviceState *dummy = qdev_create(NULL, "f2xx_dummy"); \ + DeviceState *dummy = qdev_create(NULL, TYPE_STM32F2XX_DUMMY); \ qdev_prop_set_ptr(dummy, "name", (void *)name); \ qdev_prop_set_int32(dummy, "size", size); \ qdev_init_nofail(dummy); \ @@ -336,27 +339,27 @@ void stm32f4xx_init( assert(i < STM32F4XX_TIM_COUNT); const stm32_periph_t periph = STM32_TIM1 + timer_desc[i].timer_num - 1; - DeviceState *timer = qdev_create(NULL, "f2xx_tim"); + DeviceState *timer = qdev_create(NULL, TYPE_STM32F2XX_TIM); timer->id = stm32f4xx_periph_name_arr[periph]; stm32_init_periph(timer, periph, timer_desc[i].addr, qdev_get_gpio_in(nvic, timer_desc[i].irq_idx)); - stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *)timer; + stm32_timer[timer_desc[i].timer_num - 1] = (Stm32Timer *) timer; } - dummy_dev("Reserved", 0x40002400, 0x400); + dummy_dev("Reserved", 0x40002400, 0x400); // 0x40002800 - dummy_dev("WWDG", 0x40002C00, 0x400); - dummy_dev("IWDG", 0x40003000, 0x400); - dummy_dev("Reserved", 0x40003400, 0x400); + dummy_dev("WWDG", 0x40002C00, 0x400); + dummy_dev("IWDG", 0x40003000, 0x400); + dummy_dev("Reserved", 0x40003400, 0x400); // 0x40003800 // 0x40003C00 - dummy_dev("Reserved", 0x40004000, 0x400); + dummy_dev("Reserved", 0x40004000, 0x400); // 0x40004400 // 0x40004800 // 0x40004C00 // 0x40005000 - DeviceState *i2c1 = qdev_create(NULL, "f2xx_i2c"); + DeviceState *i2c1 = qdev_create(NULL, TYPE_STM32F2XX_I2C); i2c1->id = stm32f4xx_periph_name_arr[STM32_I2C1]; qdev_prop_set_int32(i2c1, "periph", STM32_I2C1); stm32_init_periph(i2c1, STM32_I2C1, 0x40005400, @@ -364,7 +367,7 @@ void stm32f4xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(i2c1), 1, qdev_get_gpio_in(nvic, STM32_I2C1_ER_IRQ)); - DeviceState *i2c2 = qdev_create(NULL, "f2xx_i2c"); + DeviceState *i2c2 = qdev_create(NULL, TYPE_STM32F2XX_I2C); i2c2->id = stm32f4xx_periph_name_arr[STM32_I2C2]; qdev_prop_set_int32(i2c2, "periph", STM32_I2C2); stm32_init_periph(i2c2, STM32_I2C2, 0x40005800, @@ -372,7 +375,7 @@ void stm32f4xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(i2c2), 1, qdev_get_gpio_in(nvic, STM32_I2C2_ER_IRQ)); - DeviceState *i2c3 = qdev_create(NULL, "f2xx_i2c"); + DeviceState *i2c3 = qdev_create(NULL, TYPE_STM32F2XX_I2C); i2c3->id = stm32f4xx_periph_name_arr[STM32_I2C3]; qdev_prop_set_int32(i2c3, "periph", STM32_I2C3); stm32_init_periph(i2c3, STM32_I2C2, 0x40005C00, @@ -380,27 +383,27 @@ void stm32f4xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(i2c3), 1, qdev_get_gpio_in(nvic, STM32_I2C3_ER_IRQ)); - dummy_dev("Reserved", 0x40006000, 0x400); - dummy_dev("BxCAN1", 0x40006400, 0x400); - dummy_dev("BxCAN2", 0x40006800, 0x400); - dummy_dev("Reserved", 0x40006C00, 0x400); + dummy_dev("Reserved", 0x40006000, 0x400); + dummy_dev("BxCAN1", 0x40006400, 0x400); + dummy_dev("BxCAN2", 0x40006800, 0x400); + dummy_dev("Reserved", 0x40006C00, 0x400); // 0x40007000 PWR probably common dummy_dev("DAC1/DAC2", 0x40007400, 0x400); - dummy_dev("Reserved", 0x40007800, 0x400); - dummy_dev("Reserved", 0x40008000, 0x8000); + dummy_dev("Reserved", 0x40007800, 0x400); + dummy_dev("Reserved", 0x40008000, 0x8000); // USART1 // USART6 - dummy_dev("Reserved", 0x40011800, 0x800); + dummy_dev("Reserved", 0x40011800, 0x800); // ADC1 - ADC2 - ADC3 // skipped reserved from here on - dummy_dev("SDIO", 0x40012C00, 0x400); + dummy_dev("SDIO", 0x40012C00, 0x400); // SPI1 // SYSCFG needed - DeviceState *crc = qdev_create(NULL, "f2xx_crc"); + DeviceState *crc = qdev_create(NULL, TYPE_STM32F2XX_CRC); stm32_init_periph(crc, STM32_CRC, 0x40023000, NULL); - - DeviceState *dma1 = qdev_create(NULL, "f2xx_dma"); + + DeviceState *dma1 = qdev_create(NULL, TYPE_STM32F2XX_DMA); stm32_init_periph(dma1, STM32_DMA1, 0x40026000, NULL); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 0, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM0_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 1, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM1_IRQ)); @@ -411,7 +414,7 @@ void stm32f4xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 6, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM6_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 7, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM7_IRQ)); - DeviceState *dma2 = qdev_create(NULL, "f2xx_dma"); + DeviceState *dma2 = qdev_create(NULL, TYPE_STM32F2XX_DMA); stm32_init_periph(dma2, STM32_DMA2, 0x40026400, NULL); sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 0, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM0_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 1, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM1_IRQ)); diff --git a/hw/arm/stm32f7xx.c b/hw/arm/stm32f7xx.c index 5e5ccc8fbf8da..88f1fea3bcb4b 100644 --- a/hw/arm/stm32f7xx.c +++ b/hw/arm/stm32f7xx.c @@ -21,13 +21,18 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" +#include "sysemu/runstate.h" #include "hw/arm/stm32.h" #include "stm32f7xx.h" #include "exec/address-spaces.h" #include "exec/memory.h" -#include "hw/ssi.h" +#include "hw/ssi/ssi.h" +#include "hw/irq.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" // drive_get +#include "hw/qdev-properties.h" +#include "../../target/arm/cpu.h" static const char *stm32f7xx_periph_name_arr[] = { ENUM_STRING(STM32_UART1), @@ -95,7 +100,7 @@ static void do_sys_reset(void *opaque, int n, int level) { if (level) { - qemu_system_reset_request(); + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); } } @@ -126,11 +131,11 @@ void stm32f7xx_init( address_space_mem, /* address space memory */ flash_size * 1024, /* flash size in bytes */ ram_size * 1024, /* sram size in bytes */ - 0, /* default number of irqs */ + 128, /* default number of irqs */ kernel_filename, /* kernel filename */ kernel_load_translate_fn, /* kernel translate address function */ NULL, /* translate function opaque argument */ - "cortex-m4", /* cpu model */ + ARM_CPU_TYPE_NAME("cortex-m4"), /* cpu model */ cpu); /* Returned cpu instance */ qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, @@ -160,7 +165,7 @@ void stm32f7xx_init( /* Setup the RCC */ - DeviceState *rcc_dev = qdev_create(NULL, "stm32f2xx_rcc"); + DeviceState *rcc_dev = qdev_create(NULL, TYPE_STM32F2XX_RCC); qdev_prop_set_uint32(rcc_dev, "osc_freq", osc_freq); qdev_prop_set_uint32(rcc_dev, "osc32_freq", osc32_freq); object_property_add_child(stm32_container, "rcc", OBJECT(rcc_dev), NULL); @@ -174,7 +179,7 @@ void stm32f7xx_init( * STM32F7XX_GPIO_COUNT); for(i = 0; i < STM32F7XX_GPIO_COUNT; i++) { stm32_periph_t periph = STM32_GPIOA + i; - gpio_dev[i] = qdev_create(NULL, "stm32f2xx_gpio"); + gpio_dev[i] = qdev_create(NULL, TYPE_STM32F2XX_GPIO); gpio_dev[i]->id = stm32f7xx_periph_name_arr[periph]; qdev_prop_set_int32(gpio_dev[i], "periph", periph); qdev_prop_set_uint32(gpio_dev[i], "idr-mask", gpio_idr_masks[i]); @@ -184,12 +189,12 @@ void stm32f7xx_init( } /* Connect the WKUP pin (GPIO A, pin 0) to the NVIC's WKUP handler */ - qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); - f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); +//NVIC qemu_irq nvic_wake_irq = qdev_get_gpio_in_named(DEVICE((*cpu)->env.nvic), "wakeup_in", 0); +//NVIC f2xx_gpio_wake_set((stm32f2xx_gpio *)(stm32_gpio[STM32_GPIOA_INDEX]), 0, nvic_wake_irq); /* EXTI */ - DeviceState *exti_dev = qdev_create(NULL, "stm32_exti"); + DeviceState *exti_dev = qdev_create(NULL, TYPE_STM32_EXTI); qdev_prop_set_ptr(exti_dev, "stm32_gpio", gpio_dev); stm32_init_periph(exti_dev, STM32_EXTI_PERIPH, 0x40013C00, NULL); SysBusDevice *exti_busdev = SYS_BUS_DEVICE(exti_dev); @@ -212,7 +217,7 @@ void stm32f7xx_init( /* System configuration controller */ - DeviceState *syscfg_dev = qdev_create(NULL, "stm32f2xx_syscfg"); + DeviceState *syscfg_dev = qdev_create(NULL, TYPE_STM32F2XX_SYSCFG); qdev_prop_set_ptr(syscfg_dev, "stm32_rcc", rcc_dev); qdev_prop_set_ptr(syscfg_dev, "stm32_exti", exti_dev); qdev_prop_set_bit(syscfg_dev, "boot0", 0); @@ -263,7 +268,7 @@ void stm32f7xx_init( for (i = 0; i < ARRAY_LENGTH(spi_desc); ++i) { assert(i < STM32F7XX_SPI_COUNT); const stm32_periph_t periph = STM32_SPI1 + i; - stm->spi_dev[i] = qdev_create(NULL, "stm32f2xx_spi"); + stm->spi_dev[i] = qdev_create(NULL, TYPE_STM32F2XX_SPI); stm->spi_dev[i]->id = stm32f7xx_periph_name_arr[periph]; qdev_prop_set_int32(stm->spi_dev[i], "periph", periph); stm32_init_periph(stm->spi_dev[i], periph, spi_desc[i].addr, @@ -271,16 +276,16 @@ void stm32f7xx_init( } /* QSPI */ - stm->qspi_dev = qdev_create(NULL, "stm32f412_qspi"); + stm->qspi_dev = qdev_create(NULL, TYPE_STM32F412_QSPI); stm->qspi_dev->id = stm32f7xx_periph_name_arr[STM32_QSPI]; stm32_init_periph(stm->qspi_dev, STM32_QSPI, 0xA0001000, qdev_get_gpio_in(nvic, STM32_QSPI_IRQ)); /* ADC */ - DeviceState *adc_dev = qdev_create(NULL, "stm32f2xx_adc"); + DeviceState *adc_dev = qdev_create(NULL, TYPE_STM32_ADC); stm32_init_periph(adc_dev, STM32_ADC1, 0x40012000, NULL); /* RTC real time clock */ - DeviceState *rtc_dev = qdev_create(NULL, "f2xx_rtc"); + DeviceState *rtc_dev = qdev_create(NULL, TYPE_STM32F2XX_RTC); *stm32_rtc = rtc_dev; stm32_init_periph(rtc_dev, STM32_RTC, 0x40002800, NULL); // Alarm A @@ -291,12 +296,12 @@ void stm32f7xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(rtc_dev), 2, qdev_get_gpio_in(exti_dev, 22)); /* Power management */ - DeviceState *pwr_dev = qdev_create(NULL, "f2xx_pwr"); + DeviceState *pwr_dev = qdev_create(NULL, TYPE_STM32F2XX_PWR); stm32_init_periph(pwr_dev, STM32_RTC, 0x40007000, NULL); - qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); +//NVIC qdev_prop_set_ptr((*cpu)->env.nvic, "stm32_pwr", pwr_dev); #define dummy_dev(name, start, size) do {\ - DeviceState *dummy = qdev_create(NULL, "f2xx_dummy"); \ + DeviceState *dummy = qdev_create(NULL, TYPE_STM32F2XX_DUMMY); \ qdev_prop_set_ptr(dummy, "name", (void *)name); \ qdev_prop_set_int32(dummy, "size", size); \ qdev_init_nofail(dummy); \ @@ -329,7 +334,7 @@ void stm32f7xx_init( assert(i < STM32F7XX_TIM_COUNT); const stm32_periph_t periph = STM32_TIM1 + timer_desc[i].timer_num - 1; - DeviceState *timer = qdev_create(NULL, "f2xx_tim"); + DeviceState *timer = qdev_create(NULL, TYPE_STM32F2XX_TIM); timer->id = stm32f7xx_periph_name_arr[periph]; stm32_init_periph(timer, periph, timer_desc[i].addr, qdev_get_gpio_in(nvic, timer_desc[i].irq_idx)); @@ -337,7 +342,7 @@ void stm32f7xx_init( } /* Low-Power Timer */ - DeviceState *lptimer = qdev_create(NULL, "f7xx_lptim"); + DeviceState *lptimer = qdev_create(NULL, TYPE_STM32F7XX_LPTIM); lptimer->id = stm32f7xx_periph_name_arr[STM32_LPTIM1]; stm32_init_periph(lptimer, STM32_LPTIM1, 0x40002400, qdev_get_gpio_in(nvic, STM32_LPTIM1_IRQ)); *stm32_lptimer = (Stm32F7xxLPTimer *)lptimer; @@ -354,25 +359,25 @@ void stm32f7xx_init( // 0x40004C00 // 0x40005000 - DeviceState *i2c1 = qdev_create(NULL, "stm32f7xx_i2c"); + DeviceState *i2c1 = qdev_create(NULL, TYPE_STM32F7XX_I2C); i2c1->id = stm32f7xx_periph_name_arr[STM32_I2C1]; qdev_prop_set_int32(i2c1, "periph", STM32_I2C1); stm32_init_periph(i2c1, STM32_I2C1, 0x40005400, qdev_get_gpio_in(nvic, STM32_I2C1_EV_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(i2c1), 1, qdev_get_gpio_in(nvic, STM32_I2C1_ER_IRQ)); - DeviceState *i2c2 = qdev_create(NULL, "stm32f7xx_i2c"); + DeviceState *i2c2 = qdev_create(NULL, TYPE_STM32F7XX_I2C); i2c2->id = stm32f7xx_periph_name_arr[STM32_I2C2]; qdev_prop_set_int32(i2c2, "periph", STM32_I2C2); stm32_init_periph(i2c2, STM32_I2C2, 0x40005800, qdev_get_gpio_in(nvic, STM32_I2C2_EV_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(i2c2), 1, qdev_get_gpio_in(nvic, STM32_I2C2_ER_IRQ)); - DeviceState *i2c3 = qdev_create(NULL, "stm32f7xx_i2c"); + DeviceState *i2c3 = qdev_create(NULL, TYPE_STM32F7XX_I2C); i2c3->id = stm32f7xx_periph_name_arr[STM32_I2C3]; qdev_prop_set_int32(i2c3, "periph", STM32_I2C3); stm32_init_periph(i2c3, STM32_I2C3, 0x40005C00, qdev_get_gpio_in(nvic, STM32_I2C3_EV_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(i2c3), 1, qdev_get_gpio_in(nvic, STM32_I2C3_ER_IRQ)); - DeviceState *i2c4 = qdev_create(NULL, "stm32f7xx_i2c"); + DeviceState *i2c4 = qdev_create(NULL, TYPE_STM32F7XX_I2C); i2c4->id = stm32f7xx_periph_name_arr[STM32_I2C4]; qdev_prop_set_int32(i2c4, "periph", STM32_I2C4); stm32_init_periph(i2c4, STM32_I2C4, 0x40006000, qdev_get_gpio_in(nvic, STM32_I2C4_EV_IRQ)); @@ -394,10 +399,10 @@ void stm32f7xx_init( // SPI1 // SYSCFG needed - DeviceState *crc = qdev_create(NULL, "f2xx_crc"); + DeviceState *crc = qdev_create(NULL, TYPE_STM32F2XX_CRC); stm32_init_periph(crc, STM32_CRC, 0x40023000, NULL); - DeviceState *dma1 = qdev_create(NULL, "f2xx_dma"); + DeviceState *dma1 = qdev_create(NULL, TYPE_STM32F2XX_DMA); stm32_init_periph(dma1, STM32_DMA1, 0x40026000, NULL); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 0, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM0_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 1, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM1_IRQ)); @@ -408,7 +413,7 @@ void stm32f7xx_init( sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 6, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM6_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma1), 7, qdev_get_gpio_in(nvic, STM32_DMA1_STREAM7_IRQ)); - DeviceState *dma2 = qdev_create(NULL, "f2xx_dma"); + DeviceState *dma2 = qdev_create(NULL, TYPE_STM32F2XX_DMA); stm32_init_periph(dma2, STM32_DMA2, 0x40026400, NULL); sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 0, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM0_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(dma2), 1, qdev_get_gpio_in(nvic, STM32_DMA2_STREAM1_IRQ)); diff --git a/hw/arm/stm32f7xx_i2c.c b/hw/arm/stm32f7xx_i2c.c index f417bdfb55917..a5cb938e3155f 100644 --- a/hw/arm/stm32f7xx_i2c.c +++ b/hw/arm/stm32f7xx_i2c.c @@ -24,9 +24,13 @@ * QEMU model of the stm32f7xx I2C controller. */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" #include "hw/i2c/i2c.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" #define R_I2C_CR1 (0x00 / 4) #define R_I2C_CR2 (0x04 / 4) @@ -207,9 +211,10 @@ static void stm32f7xx_i2c_reset(DeviceState *dev) { } -static int stm32f7xx_i2c_init(SysBusDevice *dev) +static void stm32f7xx_i2c_init(Object *obj) { - struct stm32f7xx_i2c *s = FROM_SYSBUS(struct stm32f7xx_i2c, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + struct stm32f7xx_i2c *s = STM32F7XX_I2C(obj); memory_region_init_io(&s->iomem, OBJECT(s), &stm32f7xx_i2c_ops, s, "i2c", 0x3ff); sysbus_init_mmio(dev, &s->iomem); @@ -218,7 +223,6 @@ static int stm32f7xx_i2c_init(SysBusDevice *dev) s->bus = i2c_init_bus(DEVICE(dev), "i2c"); DPRINTF("%s %s: INITIALIZED\n", __func__, s->busdev.parent_obj.id); - return 0; } @@ -232,15 +236,15 @@ static void stm32f7xx_i2c_class_init(ObjectClass *c, void *data) DeviceClass *dc = DEVICE_CLASS(c); SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); - sc->init = stm32f7xx_i2c_init; dc->reset = stm32f7xx_i2c_reset; - dc->props = stm32f7xx_i2c_properties; + device_class_set_props(dc, stm32f7xx_i2c_properties); } static const TypeInfo stm32f7xx_i2c_info = { - .name = "stm32f7xx_i2c", + .name = TYPE_STM32F7XX_I2C, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(struct stm32f7xx_i2c), + .instance_init = stm32f7xx_i2c_init, .class_init = stm32f7xx_i2c_class_init }; diff --git a/hw/arm/stm32f7xx_lptim.c b/hw/arm/stm32f7xx_lptim.c index cc4583c498bf3..9e9a767eb688f 100644 --- a/hw/arm/stm32f7xx_lptim.c +++ b/hw/arm/stm32f7xx_lptim.c @@ -22,9 +22,13 @@ /* * QEMU stm32f7xx LPTIM emulation */ + +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" #include "qemu/timer.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" //#define DEBUG_STM32F7XX_LPTIM #ifdef DEBUG_STM32F7XX_LPTIM @@ -193,15 +197,16 @@ static const MemoryRegionOps f7xx_lptim_ops = { }; static void f7xx_lptim_reset(DeviceState *dev) { - f7xx_lptim *s = FROM_SYSBUS(f7xx_lptim, SYS_BUS_DEVICE(dev)); + f7xx_lptim *s = STM32F7XX_LPTIM(dev); timer_del(s->timer); memset(&s->regs, 0, sizeof(s->regs)); } -static int f7xx_lptim_init(SysBusDevice *dev) { - f7xx_lptim *s = FROM_SYSBUS(f7xx_lptim, dev); +static void f7xx_lptim_init(Object *obj) { + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + f7xx_lptim *s = STM32F7XX_LPTIM(obj); memory_region_init_io(&s->iomem, OBJECT(s), &f7xx_lptim_ops, s, "lptim", 0xa0); sysbus_init_mmio(dev, &s->iomem); @@ -210,8 +215,6 @@ static int f7xx_lptim_init(SysBusDevice *dev) { qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_ratio_changed, "pwm_ratio_changed", 1); qdev_init_gpio_out_named(DEVICE(dev), &s->pwm_enable, "pwm_enable", 1); - - return 0; } static Property f7xx_lptim_properties[] = { @@ -221,16 +224,17 @@ static Property f7xx_lptim_properties[] = { static void f7xx_lptim_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); - sc->init = f7xx_lptim_init; //TODO: fix this: dc->no_user = 1; - dc->props = f7xx_lptim_properties; dc->reset = f7xx_lptim_reset; + + device_class_set_props(dc, f7xx_lptim_properties); } static const TypeInfo f7xx_lptim_info = { - .name = "f7xx_lptim", + .name = TYPE_STM32F7XX_LPTIM, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(f7xx_lptim), + .instance_init = f7xx_lptim_init, .class_init = f7xx_lptim_class_init, }; diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index 10bb6772bc17c..c3f834d4ac178 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -5,12 +5,8 @@ common-obj-$(CONFIG_SSI_M25P80) += m25p80.o common-obj-$(CONFIG_NAND) += nand.o common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o -<<<<<<< HEAD +common-obj-y += pflash_jedec_424.o common-obj-$(CONFIG_XEN) += xen-block.o -======= -common-obj-$(CONFIG_PFLASH_JEDEC_424) += pflash_jedec_424.o -common-obj-$(CONFIG_XEN_BACKEND) += xen_disk.o ->>>>>>> 919b29ba7d... Pebble Qemu common-obj-$(CONFIG_ECC) += ecc.o common-obj-$(CONFIG_ONENAND) += onenand.o common-obj-$(CONFIG_NVME_PCI) += nvme.o diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index c035d872a9a07..3999cf1d87bb6 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -362,7 +362,6 @@ typedef enum { ERASE_32K = 0x52, ERASE4_32K = 0x5c, ERASE_SECTOR = 0xd8, -<<<<<<< HEAD ERASE4_SECTOR = 0xdc, EN_4BYTE_ADDR = 0xB7, @@ -391,11 +390,9 @@ typedef enum { WEVCR = 0x61, DIE_ERASE = 0xC4, -======= SLEEP = 0xb9, WAKE = 0xab, ->>>>>>> 919b29ba7d... Pebble Qemu } FlashCMD; typedef enum { @@ -1076,7 +1073,7 @@ static void decode_new_cmd(Flash *s, uint32_t value) break; case NOP: case SLEEP: - case WAKE: +// case WAKE: break; case EN_4BYTE_ADDR: s->four_bytes_address_mode = true; diff --git a/hw/block/mt25q.c b/hw/block/mt25q.c index b00265ef20f6a..0964e5a83a993 100644 --- a/hw/block/mt25q.c +++ b/hw/block/mt25q.c @@ -3,10 +3,15 @@ * Modelled after the m25p80 emulation found in hw/block/m25p80.c */ +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" #include "hw/hw.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" -#include "hw/ssi.h" +#include "hw/qdev-properties.h" +#include "hw/ssi/ssi.h" +#include "migration/vmstate.h" // TODO: These should be made configurable to support different flash parts @@ -141,8 +146,8 @@ static void mt25q_flash_sync_page(Flash *s, int page) qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE, nb_sectors * BDRV_SECTOR_SIZE); - blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete, - NULL); + blk_aio_pwritev(s->blk, page * s->page_size, &iov, 0, + blk_sync_complete, NULL); } static inline void mt25q_flash_sync_area(Flash *s, int64_t off, int64_t len) @@ -161,7 +166,7 @@ static inline void mt25q_flash_sync_area(Flash *s, int64_t off, int64_t len) qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), nb_sectors * BDRV_SECTOR_SIZE); - blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL); + blk_aio_pwritev(s->blk, off, &iov, 0, blk_sync_complete, NULL); } static inline void flash_sync_dirty(Flash *s, int64_t newpage) @@ -412,7 +417,7 @@ static uint32_t mt25q_transfer8(SSISlave *ss, uint32_t tx) return r; } -static int mt25q_init(SSISlave *ss) +static void mt25q_realize(SSISlave *ss, Error **errp) { DriveInfo *dinfo; Flash *s = MT25Q(ss); @@ -423,27 +428,20 @@ static int mt25q_init(SSISlave *ss) s->dirty_page = -1; s->STATUS_REG = 0; - /* FIXME use a qdev drive property instead of drive_get() */ - dinfo = drive_get(IF_PFLASH, 0, 1); /* Use the 2nd -pflash drive */ - - if (dinfo) { + if (s->blk) { DB_PRINT_L(0, "Binding to IF_MTD drive"); - s->blk = blk_by_legacy_dinfo(dinfo); - blk_attach_dev_nofail(s->blk, s); - s->storage = blk_blockalign(s->blk, s->size); - int r = blk_read(s->blk, 0, s->storage, DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE)); - if (r < 0) { - fprintf(stderr, "Failed to initialize SPI flash (%d)!\n", r); - return 1; + + if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) { + error_setg(errp, "Failed to initialize SPI flash!"); + return; } } else { DB_PRINT_L(-1, "No BDRV - binding to RAM"); s->storage = blk_blockalign(NULL, s->size); memset(s->storage, 0xFF, s->size); } - return 0; } static int mt25q_cs(SSISlave *ss, bool select) @@ -462,9 +460,11 @@ static int mt25q_cs(SSISlave *ss, bool select) return 0; } -static void mt25q_pre_save(void *opaque) +static int mt25q_pre_save(void *opaque) { flash_sync_dirty((Flash *)opaque, -1); + + return 0; } static const VMStateDescription vmstate_mt25q = { @@ -477,16 +477,22 @@ static const VMStateDescription vmstate_mt25q = { } }; +static Property mx251_properties[] = { + DEFINE_PROP_DRIVE("drive", Flash, blk), + DEFINE_PROP_END_OF_LIST(), +}; + static void mt25q_class_init(ObjectClass *class, void *data) { DeviceClass *dc = DEVICE_CLASS(class); SSISlaveClass *c = SSI_SLAVE_CLASS(class); - c->init = mt25q_init; + c->realize = mt25q_realize; c->transfer = mt25q_transfer8; c->set_cs = mt25q_cs; c->cs_polarity = SSI_CS_LOW; dc->vmsd = &vmstate_mt25q; + device_class_set_props(dc, mx251_properties); } static const TypeInfo mt25q_info = { diff --git a/hw/block/mx25u.c b/hw/block/mx25u.c index d27c498bd1b3d..c2d0b985ec8b2 100644 --- a/hw/block/mx25u.c +++ b/hw/block/mx25u.c @@ -3,10 +3,15 @@ * Modelled after the m25p80 emulation found in hw/block/m25p80.c */ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" #include "hw/hw.h" +#include "migration/vmstate.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" -#include "hw/ssi.h" +#include "hw/qdev-properties.h" +#include "hw/ssi/ssi.h" // TODO: These should be made configurable to support different flash parts @@ -152,7 +157,7 @@ mx25u_flash_sync_page(Flash *s, int page) qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE, nb_sectors * BDRV_SECTOR_SIZE); - blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete, + blk_aio_pwritev(s->blk, (page * s->page_size), &iov, 0, blk_sync_complete, NULL); } @@ -173,7 +178,7 @@ mx25u_flash_sync_area(Flash *s, int64_t off, int64_t len) qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), nb_sectors * BDRV_SECTOR_SIZE); - blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL); + blk_aio_pwritev(s->blk, off, &iov, 0, blk_sync_complete, NULL); } static inline void @@ -414,8 +419,8 @@ mx25u_transfer8(SSISlave *ss, uint32_t tx) return r; } -static int -mx25u_init(SSISlave *ss) +static void +mx25u_realize(SSISlave *ss, Error **errp) { DriveInfo *dinfo; Flash *s = MX25U(ss); @@ -426,28 +431,19 @@ mx25u_init(SSISlave *ss) s->dirty_page = -1; s->SR = 0; - /* FIXME use a qdev drive property instead of drive_get_next() */ - dinfo = drive_get_next(IF_MTD); - - if (dinfo) { + if (s->blk) { DB_PRINT_L(0, "Binding to IF_MTD drive"); - s->blk = blk_by_legacy_dinfo(dinfo); - blk_attach_dev_nofail(s->blk, s); - s->storage = blk_blockalign(s->blk, s->size); - /* FIXME: Move to late init */ - if (blk_read(s->blk, 0, s->storage, - DIV_ROUND_UP(s->size, BDRV_SECTOR_SIZE))) { - fprintf(stderr, "Failed to initialize SPI flash!\n"); - return 1; + if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) { + error_setg(errp, "Failed to initialize SPI flash!"); + return; } } else { DB_PRINT_L(0, "No BDRV - binding to RAM"); s->storage = blk_blockalign(NULL, s->size); memset(s->storage, 0xFF, s->size); } - return 0; } static int @@ -467,10 +463,12 @@ mx25u_cs(SSISlave *ss, bool select) return 0; } -static void +static int mx25u_pre_save(void *opaque) { flash_sync_dirty((Flash *)opaque, -1); + + return 0; } static const VMStateDescription vmstate_mx25u = { @@ -494,17 +492,23 @@ static const VMStateDescription vmstate_mx25u = { } }; +static Property mx25u_properties[] = { + DEFINE_PROP_DRIVE("drive", Flash, blk), + DEFINE_PROP_END_OF_LIST(), +}; + static void mx25u_class_init(ObjectClass *class, void *data) { DeviceClass *dc = DEVICE_CLASS(class); SSISlaveClass *c = SSI_SLAVE_CLASS(class); - c->init = mx25u_init; + c->realize = mx25u_realize; c->transfer = mx25u_transfer8; c->set_cs = mx25u_cs; c->cs_polarity = SSI_CS_LOW; dc->vmsd = &vmstate_mx25u; + device_class_set_props(dc, mx25u_properties); //mc->pi = data; } diff --git a/hw/block/pflash_jedec_424.c b/hw/block/pflash_jedec_424.c index 8313e84570b9d..0375c0bd89fef 100644 --- a/hw/block/pflash_jedec_424.c +++ b/hw/block/pflash_jedec_424.c @@ -36,6 +36,7 @@ * It does not implement much more ... */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/block/flash.h" #include "block/block.h" @@ -45,6 +46,9 @@ #include "exec/address-spaces.h" #include "qemu/host-utils.h" #include "hw/sysbus.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "migration/vmstate.h" #define PFLASH_BUG(fmt, ...) \ do { \ @@ -64,12 +68,9 @@ do { \ #define DPRINTF(fmt, ...) do { } while (0) #endif -#define TYPE_CFI_PFLASH_JEDEC_424 "cfi.pflash.jedec-42.4" -#define CFI_PFLASH_JEDEC(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH_JEDEC_424) - #define PFLASH_MAX_BANKS 8 -struct pflash_t { +struct PFlashJedec424 { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ @@ -106,16 +107,16 @@ static const VMStateDescription vmstate_pflash = { .version_id = 2, .minimum_version_id = 2, .fields = (VMStateField[]) { - VMSTATE_UINT8_ARRAY(wcycle, pflash_t, PFLASH_MAX_BANKS), - VMSTATE_UINT8_ARRAY(cmd, pflash_t, PFLASH_MAX_BANKS), - VMSTATE_UINT8(global_cmd, pflash_t), - VMSTATE_UINT8(status, pflash_t), - VMSTATE_UINT64(counter, pflash_t), + VMSTATE_UINT8_ARRAY(wcycle, PFlashJedec424, PFLASH_MAX_BANKS), + VMSTATE_UINT8_ARRAY(cmd, PFlashJedec424, PFLASH_MAX_BANKS), + VMSTATE_UINT8(global_cmd, PFlashJedec424), + VMSTATE_UINT8(status, PFlashJedec424), + VMSTATE_UINT64(counter, PFlashJedec424), VMSTATE_END_OF_LIST() } }; -static void pflash_reset_state(struct pflash_t* pfl) +static void pflash_reset_state(PFlashJedec424* pfl) { memset(pfl->wcycle, 0, sizeof(pfl->wcycle)); memset(pfl->cmd, 0, sizeof(pfl->cmd)); @@ -126,7 +127,7 @@ static void pflash_reset_state(struct pflash_t* pfl) * If this code is called we know we have a device_width set for * this flash. */ -static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) +static uint32_t pflash_cfi_query(PFlashJedec424 *pfl, hwaddr offset) { int i; uint32_t resp = 0; @@ -186,7 +187,7 @@ static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset) /* Perform a device id query based on the bank width of the flash. */ -static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) +static uint32_t pflash_devid_query(PFlashJedec424 *pfl, hwaddr offset) { int i; uint32_t resp; @@ -235,13 +236,14 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) return resp; } -static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, - int width, int be) +static uint64_t pflash_read (void *opaque, hwaddr offset, + unsigned int width) { hwaddr boff; uint32_t ret; uint8_t *p; + PFlashJedec424 *pfl = CFI_PFLASH_JEDEC(opaque); ret = -1; uint8_t bank = offset / pfl->bank_size; @@ -267,28 +269,28 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, // __func__, offset, ret); break; case 2: - if (be) { - ret = p[offset] << 8; - ret |= p[offset + 1]; - } else { +// if (be) { +// ret = p[offset] << 8; +// ret |= p[offset + 1]; +// } else { ret = p[offset]; ret |= p[offset + 1] << 8; - } +// } //DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n", // __func__, offset, ret); break; case 4: - if (be) { +// if (be) { ret = p[offset] << 24; ret |= p[offset + 1] << 16; ret |= p[offset + 2] << 8; ret |= p[offset + 3]; - } else { - ret = p[offset]; - ret |= p[offset + 1] << 8; - ret |= p[offset + 2] << 16; - ret |= p[offset + 3] << 24; - } +// } else { +// ret = p[offset]; +// ret |= p[offset + 1] << 8; +// ret |= p[offset + 2] << 16; +// ret |= p[offset + 3] << 24; +// } //DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n", // __func__, offset, ret); break; @@ -393,21 +395,18 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, } /* update flash content on disk */ -static void pflash_update(pflash_t *pfl, int offset, +static void pflash_update(PFlashJedec424 *pfl, int offset, int size) { int offset_end; if (pfl->blk) { offset_end = offset + size; - /* round to sectors */ - offset = offset >> 9; - offset_end = (offset_end + 511) >> 9; - blk_write(pfl->blk, offset, pfl->storage + (offset << 9), - offset_end - offset); + blk_pwrite(pfl->blk, offset, pfl->storage + offset, + offset_end - offset, 0); } } -static inline void pflash_data_write(pflash_t *pfl, hwaddr offset, +static inline void pflash_data_write(PFlashJedec424 *pfl, hwaddr offset, uint32_t value, int width, int be) { uint8_t *p = pfl->storage; @@ -449,13 +448,14 @@ static inline void pflash_data_write(pflash_t *pfl, hwaddr offset, } -static void pflash_write(pflash_t *pfl, hwaddr offset, - uint32_t value, int width, int be) +static void pflash_write(void *opaque, hwaddr offset, + uint64_t value, unsigned int width) { uint8_t cmd; int i; uint8_t *p; + PFlashJedec424 *pfl = CFI_PFLASH_JEDEC(opaque); cmd = value; uint8_t bank = pfl->global_cmd ? 0 : offset / pfl->bank_size; @@ -628,7 +628,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, if (!pfl->ro) { DPRINTF("%s: Programming %d bytes at " TARGET_FMT_plx " to 0x%x\n", __func__, width, offset, value); - pflash_data_write(pfl, offset, value, width, be); + pflash_data_write(pfl, offset, value, width, 0); } else { pfl->status |= 0x10; /* Programming error */ } @@ -730,107 +730,17 @@ static void pflash_write(pflash_t *pfl, hwaddr offset, } -static uint32_t pflash_readb_be(void *opaque, hwaddr addr) -{ - return pflash_read(opaque, addr, 1, 1); -} - -static uint32_t pflash_readb_le(void *opaque, hwaddr addr) -{ - return pflash_read(opaque, addr, 1, 0); -} - -static uint32_t pflash_readw_be(void *opaque, hwaddr addr) -{ - pflash_t *pfl = opaque; - - return pflash_read(pfl, addr, 2, 1); -} - -static uint32_t pflash_readw_le(void *opaque, hwaddr addr) -{ - pflash_t *pfl = opaque; - - return pflash_read(pfl, addr, 2, 0); -} - -static uint32_t pflash_readl_be(void *opaque, hwaddr addr) -{ - pflash_t *pfl = opaque; - - return pflash_read(pfl, addr, 4, 1); -} - -static uint32_t pflash_readl_le(void *opaque, hwaddr addr) -{ - pflash_t *pfl = opaque; - - return pflash_read(pfl, addr, 4, 0); -} - -static void pflash_writeb_be(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_write(opaque, addr, value, 1, 1); -} - -static void pflash_writeb_le(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_write(opaque, addr, value, 1, 0); -} - -static void pflash_writew_be(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl = opaque; - - pflash_write(pfl, addr, value, 2, 1); -} - -static void pflash_writew_le(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl = opaque; - - pflash_write(pfl, addr, value, 2, 0); -} - -static void pflash_writel_be(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl = opaque; - - pflash_write(pfl, addr, value, 4, 1); -} - -static void pflash_writel_le(void *opaque, hwaddr addr, - uint32_t value) -{ - pflash_t *pfl = opaque; - - pflash_write(pfl, addr, value, 4, 0); -} - -static const MemoryRegionOps pflash_jedec_ops_be = { - .old_mmio = { - .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, - .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static const MemoryRegionOps pflash_jedec_ops_le = { - .old_mmio = { - .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, - .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, }, - }, +static const MemoryRegionOps pflash_jedec_ops = { + .read = pflash_read, + .write = pflash_write, + .valid.min_access_size = 1, + .valid.max_access_size = 4, .endianness = DEVICE_NATIVE_ENDIAN, }; static void pflash_jedec_realize(DeviceState *dev, Error **errp) { - pflash_t *pfl = CFI_PFLASH_JEDEC(dev); + PFlashJedec424 *pfl = CFI_PFLASH_JEDEC(dev); uint64_t total_len; int ret; uint64_t blocks_per_device, device_len; @@ -847,7 +757,7 @@ static void pflash_jedec_realize(DeviceState *dev, Error **errp) memory_region_init_rom_device( &pfl->mem, OBJECT(dev), - pfl->be ? &pflash_jedec_ops_be : &pflash_jedec_ops_le, pfl, + &pflash_jedec_ops, pfl, pfl->name, total_len, errp); vmstate_register_ram(&pfl->mem, DEVICE(pfl)); pfl->storage = memory_region_get_ram_ptr(&pfl->mem); @@ -855,7 +765,7 @@ static void pflash_jedec_realize(DeviceState *dev, Error **errp) if (pfl->blk) { /* read the initial flash content */ - ret = blk_read(pfl->blk, 0, pfl->storage, total_len >> 9); + ret = blk_pread(pfl->blk, 0, pfl->storage, total_len); if (ret < 0) { vmstate_unregister_ram(&pfl->mem, DEVICE(pfl)); @@ -976,14 +886,14 @@ static void pflash_jedec_realize(DeviceState *dev, Error **errp) } static Property pflash_jedec_properties[] = { - DEFINE_PROP_DRIVE("drive", struct pflash_t, blk), + DEFINE_PROP_DRIVE("drive", PFlashJedec424, blk), /* num-blocks is the number of blocks actually visible to the guest, * ie the total size of the device divided by the sector length. * If we're emulating flash devices wired in parallel the actual * number of blocks per indvidual device will differ. */ - DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0), - DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0), + DEFINE_PROP_UINT32("num-blocks", PFlashJedec424, nb_blocs, 0), + DEFINE_PROP_UINT64("sector-length", PFlashJedec424, sector_len, 0), /* width here is the overall width of this QEMU device in bytes. * The QEMU device may be emulating a number of flash devices * wired up in parallel; the width of each individual flash @@ -1000,16 +910,16 @@ static Property pflash_jedec_properties[] = { * 16 bit devices making up a 32 bit wide QEMU device. This * is deprecated for new uses of this device. */ - DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0), - DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0), - DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0), - DEFINE_PROP_UINT32("bank-size", struct pflash_t, bank_size, 0), - DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0), - DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0), - DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0), - DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0), - DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0), - DEFINE_PROP_STRING("name", struct pflash_t, name), + DEFINE_PROP_UINT8("width", PFlashJedec424, bank_width, 0), + DEFINE_PROP_UINT8("device-width", PFlashJedec424, device_width, 0), + DEFINE_PROP_UINT8("max-device-width", PFlashJedec424, max_device_width, 0), + DEFINE_PROP_UINT32("bank-size", PFlashJedec424, bank_size, 0), + DEFINE_PROP_UINT8("big-endian", PFlashJedec424, be, 0), + DEFINE_PROP_UINT16("id0", PFlashJedec424, ident0, 0), + DEFINE_PROP_UINT16("id1", PFlashJedec424, ident1, 0), + DEFINE_PROP_UINT16("id2", PFlashJedec424, ident2, 0), + DEFINE_PROP_UINT16("id3", PFlashJedec424, ident3, 0), + DEFINE_PROP_STRING("name", PFlashJedec424, name), DEFINE_PROP_END_OF_LIST(), }; @@ -1017,17 +927,17 @@ static void pflash_jedec_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->realize = pflash_jedec_realize; - dc->props = pflash_jedec_properties; + dc->realize = pflash_jedec_realize;; dc->vmsd = &vmstate_pflash; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + device_class_set_props(dc, pflash_jedec_properties); } static const TypeInfo pflash_jedec_info = { .name = TYPE_CFI_PFLASH_JEDEC_424, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(struct pflash_t), + .instance_size = sizeof(PFlashJedec424), .class_init = pflash_jedec_class_init, }; @@ -1038,7 +948,7 @@ static void pflash_jedec_register_types(void) type_init(pflash_jedec_register_types) -pflash_t *pflash_jedec_424_register(hwaddr base, +PFlashJedec424 *pflash_jedec_424_register(hwaddr base, DeviceState *qdev, const char *name, hwaddr size, BlockBackend *blk, @@ -1049,7 +959,7 @@ pflash_t *pflash_jedec_424_register(hwaddr base, DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH_JEDEC_424); if (blk) { - qdev_prop_set_drive_nofail(dev, "drive", blk); + qdev_prop_set_drive(dev, "drive", blk, &error_fatal); } qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); qdev_prop_set_uint64(dev, "sector-length", sector_len); @@ -1067,7 +977,7 @@ pflash_t *pflash_jedec_424_register(hwaddr base, return CFI_PFLASH_JEDEC(dev); } -MemoryRegion *pflash_jedec_424_get_memory(pflash_t *fl) +static MemoryRegion *pflash_jedec_424_get_memory(PFlashJedec424 *fl) { return &fl->mem; } diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs index 1e5cb30e65b06..ce66bfb6457a2 100644 --- a/hw/char/Makefile.objs +++ b/hw/char/Makefile.objs @@ -32,11 +32,7 @@ common-obj-$(CONFIG_MILKYMIST) += milkymist-uart.o common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o sclpconsole-lm.o obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o -<<<<<<< HEAD obj-$(CONFIG_PSERIES) += spapr_vty.o obj-$(CONFIG_TERMINAL3270) += terminal3270.o -======= - -obj-$(CONFIG_STM32) += stm32_uart.o -obj-$(CONFIG_STM32) += stm32f7xx_uart.o ->>>>>>> 919b29ba7d... Pebble Qemu +obj-y += stm32_uart.o +obj-y += stm32f7xx_uart.o diff --git a/hw/char/stm32_uart.c b/hw/char/stm32_uart.c index 5915bf0e1fd0d..afdca4f3137e0 100644 --- a/hw/char/stm32_uart.c +++ b/hw/char/stm32_uart.c @@ -20,18 +20,21 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" -#include "hw/arm/stm32f1xx.h" -#include "sysemu/char.h" #include "qemu/bitops.h" +#include "hw/qdev-properties.h" +#include "hw/arm/stm32f1xx.h" +#include "hw/irq.h" +#include "hw/hw.h" /* DEFINITIONS*/ /* See the README file for details on these settings. */ -//#define DEBUG_STM32_UART +#define DEBUG_STM32_UART //#define STM32_UART_NO_BAUD_DELAY //#define STM32_UART_ENABLE_OVERRUN @@ -434,7 +437,7 @@ static int stm32_uart_can_receive(void *opaque) return (USART_RCV_BUF_LEN - s->rcv_char_bytes); } -static void stm32_uart_event(void *opaque, int event) +static void stm32_uart_event(void *opaque, QEMUChrEvent event) { /* Do nothing */ } @@ -758,12 +761,12 @@ void stm32_uart_get_rcv_handlers(Stm32Uart *s, IOCanReadHandler **can_read, // qemu_chr write handler. static int stm32_uart_chr_fe_write_stub(void *s, const uint8_t *buf, int len) { - return qemu_chr_fe_write((CharDriverState *)s, buf, len); + return qemu_chr_fe_write((Chardev *)s, buf, len); } // Helper method that connects this UART device's receive handlers to a qemu_chr instance. -void stm32_uart_connect(Stm32Uart *s, CharDriverState *chr, uint32_t afio_board_map) +void stm32_uart_connect(Stm32Uart *s, Chardev *chr, uint32_t afio_board_map) { s->chr_write_obj = chr; if (chr) { @@ -772,7 +775,7 @@ void stm32_uart_connect(Stm32Uart *s, CharDriverState *chr, uint32_t afio_board_ IOReadHandler *read_cb; IOEventHandler *event_cb; stm32_uart_get_rcv_handlers(s, &can_read_cb, &read_cb, &event_cb); - qemu_chr_add_handlers(chr, can_read_cb, read_cb, event_cb, s); + qemu_chr_fe_set_handlers(&chr, can_read_cb, read_cb, event_cb, NULL, s, NULL, true); } s->afio_board_map = afio_board_map; @@ -783,10 +786,11 @@ void stm32_uart_connect(Stm32Uart *s, CharDriverState *chr, uint32_t afio_board_ /* DEVICE INITIALIZATION */ -static int stm32_uart_init(SysBusDevice *dev) +static void stm32_uart_realize(DeviceState *obj, Error **pError) { qemu_irq *clk_irq; - Stm32Uart *s = STM32_UART(dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + Stm32Uart *s = STM32_UART(obj); s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; s->stm32_gpio = (Stm32Gpio **)s->stm32_gpio_prop; @@ -813,8 +817,6 @@ static int stm32_uart_init(SysBusDevice *dev) s->rcv_char_bytes = 0; stm32_uart_reset((DeviceState *)s); - - return 0; } static Property stm32_uart_properties[] = { @@ -829,15 +831,14 @@ static Property stm32_uart_properties[] = { static void stm32_uart_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_uart_init; + dc->realize = stm32_uart_realize; dc->reset = stm32_uart_reset; - dc->props = stm32_uart_properties; + device_class_set_props(dc, stm32_uart_properties); } static TypeInfo stm32_uart_info = { - .name = "stm32-uart", + .name = TYPE_STM32_UART, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Uart), .class_init = stm32_uart_class_init diff --git a/hw/char/stm32f7xx_uart.c b/hw/char/stm32f7xx_uart.c index 024d22ed54b32..72ad6bfb5859e 100644 --- a/hw/char/stm32f7xx_uart.c +++ b/hw/char/stm32f7xx_uart.c @@ -20,10 +20,13 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" -#include "sysemu/char.h" #include "qemu/bitops.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" +#include "hw/hw.h" @@ -648,12 +651,12 @@ void stm32f7xx_uart_get_rcv_handlers(Stm32F7xxUart *s, IOCanReadHandler **can_re // Stub used to typecast the generic write handler prototype to a qemu_chr write handler. static int stm32f7xx_uart_chr_fe_write_stub(void *s, const uint8_t *buf, int len) { - return qemu_chr_fe_write((CharDriverState *)s, buf, len); + return qemu_chr_fe_write((Chardev *)s, buf, len); } // Helper method that connects this UART device's receive handlers to a qemu_chr instance. -void stm32f7xx_uart_connect(Stm32F7xxUart *s, CharDriverState *chr, uint32_t afio_board_map) +void stm32f7xx_uart_connect(Stm32F7xxUart *s, Chardev *chr, uint32_t afio_board_map) { s->chr_write_obj = chr; if (chr) { @@ -662,7 +665,7 @@ void stm32f7xx_uart_connect(Stm32F7xxUart *s, CharDriverState *chr, uint32_t afi IOReadHandler *read_cb; IOEventHandler *event_cb; stm32f7xx_uart_get_rcv_handlers(s, &can_read_cb, &read_cb, &event_cb); - qemu_chr_add_handlers(chr, can_read_cb, read_cb, event_cb, s); + qemu_chr_fe_set_handlers(&chr, can_read_cb, read_cb, event_cb, NULL, s, NULL, true); } s->afio_board_map = afio_board_map; @@ -673,10 +676,11 @@ void stm32f7xx_uart_connect(Stm32F7xxUart *s, CharDriverState *chr, uint32_t afi /* DEVICE INITIALIZATION */ -static int stm32f7xx_uart_init(SysBusDevice *dev) +static void stm32f7xx_uart_init(Object *obj) { qemu_irq *clk_irq; - Stm32F7xxUart *s = STM32F7XX_UART(dev); + Stm32F7xxUart *s = STM32F7XX_UART(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; s->stm32_gpio = (Stm32Gpio **)s->stm32_gpio_prop; @@ -699,8 +703,6 @@ static int stm32f7xx_uart_init(SysBusDevice *dev) s->rcv_char_bytes = 0; stm32f7xx_uart_reset((DeviceState *)s); - - return 0; } static Property stm32f7xx_uart_properties[] = { @@ -715,17 +717,16 @@ static Property stm32f7xx_uart_properties[] = { static void stm32f7xx_uart_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32f7xx_uart_init; dc->reset = stm32f7xx_uart_reset; - dc->props = stm32f7xx_uart_properties; + device_class_set_props(dc, stm32f7xx_uart_properties); } static TypeInfo stm32f7xx_uart_info = { .name = "stm32f7xx-uart", .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32F7xxUart), + .instance_init = stm32f7xx_uart_init, .class_init = stm32f7xx_uart_class_init }; diff --git a/hw/core/irq.c b/hw/core/irq.c index cdb02f95a82a4..fb3045b912e9b 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -120,50 +120,17 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2) return qemu_allocate_irq(qemu_splitirq, s, 0); } -<<<<<<< HEAD void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) -======= -static void proxy_irq_handler(void *opaque, int n, int level) -{ - qemu_irq **target = opaque; - - if (*target) { - qemu_set_irq((*target)[n], level); - } -} - -qemu_irq *qemu_irq_proxy(qemu_irq **target, int n) -{ - return qemu_allocate_irqs(proxy_irq_handler, target, n); -} - - -void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, - int id, int n) ->>>>>>> 919b29ba7d... Pebble Qemu { int i; - IRQInterceptData *intercept_data = g_malloc0(sizeof(IRQInterceptData)); qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n); - intercept_data->id = id; - intercept_data->old_irqs = old_irqs; for (i = 0; i < n; i++) { *old_irqs[i] = *gpio_in[i]; gpio_in[i]->handler = handler; - gpio_in[i]->opaque = intercept_data; + gpio_in[i]->opaque = &old_irqs[i]; } } -void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, - int id, int n) -{ - IRQInterceptData *intercept_data = g_malloc0(sizeof(IRQInterceptData)); - qemu_irq *old_irqs = *gpio_out; - intercept_data->id = id; - intercept_data->old_irqs = old_irqs; - *gpio_out = qemu_allocate_irqs(handler, intercept_data, n); -} - static const TypeInfo irq_type_info = { .name = TYPE_IRQ, .parent = TYPE_OBJECT, diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 414521a3f28ff..44b0b9eef2349 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -505,7 +505,7 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, int old = gpio_list->num_out; gpio_list->out = old ? g_renew(qemu_irq, gpio_list->out, old + n) : g_new(qemu_irq, n); for (i = 0; i < n; ++i) { - gpio_list->out[old + i] = pins[i]; + gpio_list->out[old + i] = pins[i]; } if (!name) { @@ -513,7 +513,6 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, } memset(pins, 0, sizeof(*pins) * n); for (i = 0; i < n; ++i) { - memset(&pins[i], 0, sizeof(*pins)); gchar *propname = g_strdup_printf("%s[%u]", name, gpio_list->num_out + i); diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index 7c38300b1917d..cef9f80ef052b 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -13,13 +13,9 @@ common-obj-$(CONFIG_PL110) += pl110.o common-obj-$(CONFIG_SII9022) += sii9022.o common-obj-$(CONFIG_SSD0303) += ssd0303.o common-obj-$(CONFIG_SSD0323) += ssd0323.o -<<<<<<< HEAD common-obj-$(CONFIG_XEN) += xenfb.o -======= -common-obj-$(CONFIG_XEN_BACKEND) += xenfb.o -common-obj-$(CONFIG_LS013B7DH01) += ls013b7dh01.o +common-obj-y += ls013b7dh01.o common-obj-$(CONFIG_PEBBLE_SNOWY_DISPLAY) += pebble_snowy_display.o ->>>>>>> 919b29ba7d... Pebble Qemu common-obj-$(CONFIG_VGA_PCI) += vga-pci.o common-obj-$(CONFIG_VGA_ISA) += vga-isa.o diff --git a/hw/display/ls013b7dh01.c b/hw/display/ls013b7dh01.c index 7799bb9286bf1..f1289bba9d74b 100644 --- a/hw/display/ls013b7dh01.c +++ b/hw/display/ls013b7dh01.c @@ -32,10 +32,14 @@ * Handle 24bpp host displays. */ -#include "qemu-common.h" + +#include "qemu/osdep.h" #include "ui/console.h" #include "ui/pixel_ops.h" -#include "hw/ssi.h" +#include "hw/ssi/ssi.h" +#include "hw/qdev-properties.h" +#include "hw/ssi/ssi.h" +#include "qemu/log.h" #define NUM_ROWS 168 #define NUM_COLS 144 // 18 bytes @@ -319,7 +323,7 @@ static const GraphicHwOps sm_lcd_ops = { .invalidate = sm_lcd_invalidate_display, }; -static int sm_lcd_init(SSISlave *dev) +static void sm_lcd_init(SSISlave *dev, Error **pError) { lcd_state *s = FROM_SSI_SLAVE(lcd_state, dev); @@ -343,8 +347,6 @@ static int sm_lcd_init(SSISlave *dev) /* This callback informs us that power is on/off */ qdev_init_gpio_in_named(DEVICE(dev), sm_lcd_power_ctl, "power_ctl", 1); - - return 0; } static Property sm_lcd_init_properties[] = { @@ -357,11 +359,11 @@ static void sm_lcd_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SSISlaveClass *k = SSI_SLAVE_CLASS(klass); - k->init = sm_lcd_init; + k->realize = sm_lcd_init; k->transfer = sm_lcd_transfer; k->cs_polarity = SSI_CS_LOW; k->parent_class.reset = sm_lcd_reset; - dc->props = sm_lcd_init_properties; + device_class_set_props(dc, sm_lcd_init_properties); } static const TypeInfo sm_lcd_info = { diff --git a/hw/display/pebble_snowy_display.c b/hw/display/pebble_snowy_display.c index 80baecf153fbf..10d8e783c0d2f 100644 --- a/hw/display/pebble_snowy_display.c +++ b/hw/display/pebble_snowy_display.c @@ -54,6 +54,7 @@ #include +#include "qemu/osdep.h" #include "qemu-common.h" #include "ui/console.h" #include "ui/pixel_ops.h" diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs index 7665c0fba3a9f..ba9adae836352 100644 --- a/hw/gpio/Makefile.objs +++ b/hw/gpio/Makefile.objs @@ -5,14 +5,9 @@ common-obj-$(CONFIG_ZAURUS) += zaurus.o common-obj-$(CONFIG_E500) += mpc8xxx.o common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o -<<<<<<< HEAD common-obj-$(CONFIG_OMAP) += omap_gpio.o common-obj-$(CONFIG_IMX) += imx_gpio.o common-obj-$(CONFIG_RASPI) += bcm2835_gpio.o common-obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o common-obj-$(CONFIG_ASPEED_SOC) += aspeed_gpio.o -======= -obj-$(CONFIG_OMAP) += omap_gpio.o -obj-$(CONFIG_IMX) += imx_gpio.o -obj-$(CONFIG_STM32) += stm32_gpio.o stm32_afio.o stm32_exti.o ->>>>>>> 919b29ba7d... Pebble Qemu +common-obj-$(CONFIG_STM32) += stm32_gpio.o stm32_afio.o stm32_exti.o diff --git a/hw/gpio/stm32_afio.c b/hw/gpio/stm32_afio.c index f4e9b373829ec..6f2cc309a5450 100644 --- a/hw/gpio/stm32_afio.c +++ b/hw/gpio/stm32_afio.c @@ -19,8 +19,12 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/arm/stm32.h" #include "qemu/bitops.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" @@ -68,7 +72,7 @@ struct Stm32Afio { AFIO_EXTICR[AFIO_EXTICR_COUNT]; }; - +static void stm32_afio_instance_init(Object *obj); @@ -234,9 +238,10 @@ uint32_t stm32_afio_get_periph_map(Stm32Afio *s, stm32_periph_t periph) /* DEVICE INITIALIZATION */ -static int stm32_afio_init(SysBusDevice *dev) +static void stm32_afio_init(Object *obj) { - Stm32Afio *s = STM32_AFIO(dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + Stm32Afio *s = STM32_AFIO(obj); s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; @@ -244,7 +249,7 @@ static int stm32_afio_init(SysBusDevice *dev) "afio", 0x03ff); sysbus_init_mmio(dev, &s->iomem); - return 0; + stm32_afio_instance_init(obj); } static Property stm32_afio_properties[] = { @@ -257,11 +262,10 @@ static void add_gpio_link(Stm32Afio *s, int gpio_index, const char *link_name) object_property_add_link(OBJECT(s), link_name, TYPE_STM32_GPIO, (Object **)&s->gpio[gpio_index], object_property_allow_set_link, - OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); + OBJ_PROP_LINK_STRONG, &error_abort); } -static void stm32_afio_instance_init(Object *obj) -{ +void stm32_afio_instance_init(Object *obj) { Stm32Afio *s = STM32_AFIO(obj); add_gpio_link(s, 0, "gpio[a]"); @@ -273,9 +277,9 @@ static void stm32_afio_instance_init(Object *obj) add_gpio_link(s, 6, "gpio[g]"); object_property_add_link(obj, "exti", TYPE_STM32_EXTI, - (Object **)&s->exti, - object_property_allow_set_link, - OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); + (Object **)&s->exti, + object_property_allow_set_link, + OBJ_PROP_LINK_STRONG, &error_abort); } @@ -284,16 +288,15 @@ static void stm32_afio_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_afio_init; dc->reset = stm32_afio_reset; - dc->props = stm32_afio_properties; + device_class_set_props(dc, stm32_afio_properties); } static TypeInfo stm32_afio_info = { .name = TYPE_STM32_AFIO, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Afio), - .instance_init = stm32_afio_instance_init, + .instance_init = stm32_afio_init, .class_init = stm32_afio_class_init }; diff --git a/hw/gpio/stm32_exti.c b/hw/gpio/stm32_exti.c index a8c0665a88139..3ca752db16f12 100644 --- a/hw/gpio/stm32_exti.c +++ b/hw/gpio/stm32_exti.c @@ -19,9 +19,12 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/arm/stm32.h" #include "hw/arm/stm32f4xx.h" #include "qemu/bitops.h" +#include "hw/irq.h" +#include "hw/hw.h" @@ -287,10 +290,11 @@ static void stm32_exti_reset(DeviceState *dev) /* DEVICE INITIALIZATION */ -static int stm32_exti_init(SysBusDevice *dev) +static void stm32_exti_init(Object *obj) { int i; + SysBusDevice *dev = SYS_BUS_DEVICE(obj); Stm32Exti *s = STM32_EXTI(dev); memory_region_init_io(&s->iomem, OBJECT(s), &stm32_exti_ops, s, @@ -303,8 +307,6 @@ static int stm32_exti_init(SysBusDevice *dev) /* Create the handlers to handle GPIO input pin changes. */ qdev_init_gpio_in(DEVICE(dev), stm32_exti_gpio_in_handler, STM32_GPIO_PIN_COUNT); - - return 0; } static void stm32_exti_class_init(ObjectClass *klass, void *data) @@ -312,14 +314,14 @@ static void stm32_exti_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_exti_init; dc->reset = stm32_exti_reset; } static TypeInfo stm32_exti_info = { - .name = TYPE_STM32_EXTI, + .name = TYPE_STM32_EXTI_ALT, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Exti), + .instance_init = stm32_exti_init, .class_init = stm32_exti_class_init }; diff --git a/hw/gpio/stm32_gpio.c b/hw/gpio/stm32_gpio.c index 11ebbe7bb902d..e20e73af3a87b 100644 --- a/hw/gpio/stm32_gpio.c +++ b/hw/gpio/stm32_gpio.c @@ -20,9 +20,13 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" #include "qemu/bitops.h" +#include "hw/qdev-properties.h" +#include "hw/irq.h" +#include "hw/hw.h" @@ -306,10 +310,11 @@ uint8_t stm32_gpio_get_mode_bits(Stm32Gpio *s, unsigned pin) { /* DEVICE INITIALIZATION */ -static int stm32_gpio_init(SysBusDevice *dev) +static void stm32_gpio_init(Object *obj) { unsigned pin; - Stm32Gpio *s = STM32_GPIO(dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + Stm32Gpio *s = STM32_GPIO(obj); s->stm32_rcc = (Stm32Rcc *)s->stm32_rcc_prop; @@ -323,8 +328,6 @@ static int stm32_gpio_init(SysBusDevice *dev) for(pin = 0; pin < STM32_GPIO_PIN_COUNT; pin++) { sysbus_init_irq(dev, &s->in_irq[pin]); } - - return 0; } static Property stm32_gpio_properties[] = { @@ -338,15 +341,15 @@ static void stm32_gpio_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stm32_gpio_init; dc->reset = stm32_gpio_reset; - dc->props = stm32_gpio_properties; + device_class_set_props(dc, stm32_gpio_properties); } static TypeInfo stm32_gpio_info = { .name = TYPE_STM32_GPIO, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Stm32Gpio), + .instance_init = stm32_gpio_init, .class_init = stm32_gpio_class_init }; diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c deleted file mode 100644 index 07d36ca169df5..0000000000000 --- a/hw/i386/kvm/pci-assign.c +++ /dev/null @@ -1,1901 +0,0 @@ -/* - * Copyright (c) 2007, Neocleus Corporation. - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - * - * Assign a PCI device from the host to a guest VM. - * - * This implementation uses the classic device assignment interface of KVM - * and is only available on x86 hosts. It is expected to be obsoleted by VFIO - * based device assignment. - * - * Adapted for KVM (qemu-kvm) by Qumranet. QEMU version was based on qemu-kvm - * revision 4144fe9d48. See its repository for the history. - * - * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) - * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) - * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) - * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) - * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) - */ -#include -#include -#include -#include -#include -#include "hw/hw.h" -#include "hw/i386/pc.h" -#include "qemu/error-report.h" -#include "ui/console.h" -#include "hw/loader.h" -#include "monitor/monitor.h" -#include "qemu/range.h" -#include "sysemu/sysemu.h" -#include "hw/pci/pci.h" -#include "hw/pci/msi.h" -#include "kvm_i386.h" -#include "hw/pci/pci-assign.h" - -#define MSIX_PAGE_SIZE 0x1000 - -/* From linux/ioport.h */ -#define IORESOURCE_IO 0x00000100 /* Resource type */ -#define IORESOURCE_MEM 0x00000200 -#define IORESOURCE_IRQ 0x00000400 -#define IORESOURCE_DMA 0x00000800 -#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */ -#define IORESOURCE_MEM_64 0x00100000 - -typedef struct PCIRegion { - int type; /* Memory or port I/O */ - int valid; - uint64_t base_addr; - uint64_t size; /* size of the region */ - int resource_fd; -} PCIRegion; - -typedef struct PCIDevRegions { - uint8_t bus, dev, func; /* Bus inside domain, device and function */ - int irq; /* IRQ number */ - uint16_t region_number; /* number of active regions */ - - /* Port I/O or MMIO Regions */ - PCIRegion regions[PCI_NUM_REGIONS - 1]; - int config_fd; -} PCIDevRegions; - -typedef struct AssignedDevRegion { - MemoryRegion container; - MemoryRegion real_iomem; - union { - uint8_t *r_virtbase; /* mmapped access address for memory regions */ - uint32_t r_baseport; /* the base guest port for I/O regions */ - } u; - pcibus_t e_size; /* emulated size of region in bytes */ - pcibus_t r_size; /* real size of region in bytes */ - PCIRegion *region; -} AssignedDevRegion; - -#define ASSIGNED_DEVICE_PREFER_MSI_BIT 0 -#define ASSIGNED_DEVICE_SHARE_INTX_BIT 1 - -#define ASSIGNED_DEVICE_PREFER_MSI_MASK (1 << ASSIGNED_DEVICE_PREFER_MSI_BIT) -#define ASSIGNED_DEVICE_SHARE_INTX_MASK (1 << ASSIGNED_DEVICE_SHARE_INTX_BIT) - -typedef struct MSIXTableEntry { - uint32_t addr_lo; - uint32_t addr_hi; - uint32_t data; - uint32_t ctrl; -} MSIXTableEntry; - -typedef enum AssignedIRQType { - ASSIGNED_IRQ_NONE = 0, - ASSIGNED_IRQ_INTX_HOST_INTX, - ASSIGNED_IRQ_INTX_HOST_MSI, - ASSIGNED_IRQ_MSI, - ASSIGNED_IRQ_MSIX -} AssignedIRQType; - -typedef struct AssignedDevice { - PCIDevice dev; - PCIHostDeviceAddress host; - uint32_t dev_id; - uint32_t features; - int intpin; - AssignedDevRegion v_addrs[PCI_NUM_REGIONS - 1]; - PCIDevRegions real_device; - PCIINTxRoute intx_route; - AssignedIRQType assigned_irq_type; - struct { -#define ASSIGNED_DEVICE_CAP_MSI (1 << 0) -#define ASSIGNED_DEVICE_CAP_MSIX (1 << 1) - uint32_t available; -#define ASSIGNED_DEVICE_MSI_ENABLED (1 << 0) -#define ASSIGNED_DEVICE_MSIX_ENABLED (1 << 1) -#define ASSIGNED_DEVICE_MSIX_MASKED (1 << 2) - uint32_t state; - } cap; - uint8_t emulate_config_read[PCI_CONFIG_SPACE_SIZE]; - uint8_t emulate_config_write[PCI_CONFIG_SPACE_SIZE]; - int msi_virq_nr; - int *msi_virq; - MSIXTableEntry *msix_table; - hwaddr msix_table_addr; - uint16_t msix_max; - MemoryRegion mmio; - char *configfd_name; - int32_t bootindex; -} AssignedDevice; - -#define TYPE_PCI_ASSIGN "kvm-pci-assign" -#define PCI_ASSIGN(obj) OBJECT_CHECK(AssignedDevice, (obj), TYPE_PCI_ASSIGN) - -static void assigned_dev_update_irq_routing(PCIDevice *dev); - -static void assigned_dev_load_option_rom(AssignedDevice *dev); - -static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev); - -static uint64_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region, - hwaddr addr, int size, - uint64_t *data) -{ - uint64_t val = 0; - int fd = dev_region->region->resource_fd; - - if (data) { - DEBUG("pwrite data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx - ", addr="TARGET_FMT_plx"\n", *data, size, addr, addr); - if (pwrite(fd, data, size, addr) != size) { - error_report("%s - pwrite failed %s", __func__, strerror(errno)); - } - } else { - if (pread(fd, &val, size, addr) != size) { - error_report("%s - pread failed %s", __func__, strerror(errno)); - val = (1UL << (size * 8)) - 1; - } - DEBUG("pread val=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx - ", addr=" TARGET_FMT_plx "\n", val, size, addr, addr); - } - return val; -} - -static void assigned_dev_ioport_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size) -{ - assigned_dev_ioport_rw(opaque, addr, size, &data); -} - -static uint64_t assigned_dev_ioport_read(void *opaque, - hwaddr addr, unsigned size) -{ - return assigned_dev_ioport_rw(opaque, addr, size, NULL); -} - -static uint32_t slow_bar_readb(void *opaque, hwaddr addr) -{ - AssignedDevRegion *d = opaque; - uint8_t *in = d->u.r_virtbase + addr; - uint32_t r; - - r = *in; - DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r); - - return r; -} - -static uint32_t slow_bar_readw(void *opaque, hwaddr addr) -{ - AssignedDevRegion *d = opaque; - uint16_t *in = (uint16_t *)(d->u.r_virtbase + addr); - uint32_t r; - - r = *in; - DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r); - - return r; -} - -static uint32_t slow_bar_readl(void *opaque, hwaddr addr) -{ - AssignedDevRegion *d = opaque; - uint32_t *in = (uint32_t *)(d->u.r_virtbase + addr); - uint32_t r; - - r = *in; - DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r); - - return r; -} - -static void slow_bar_writeb(void *opaque, hwaddr addr, uint32_t val) -{ - AssignedDevRegion *d = opaque; - uint8_t *out = d->u.r_virtbase + addr; - - DEBUG("addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr, val); - *out = val; -} - -static void slow_bar_writew(void *opaque, hwaddr addr, uint32_t val) -{ - AssignedDevRegion *d = opaque; - uint16_t *out = (uint16_t *)(d->u.r_virtbase + addr); - - DEBUG("addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr, val); - *out = val; -} - -static void slow_bar_writel(void *opaque, hwaddr addr, uint32_t val) -{ - AssignedDevRegion *d = opaque; - uint32_t *out = (uint32_t *)(d->u.r_virtbase + addr); - - DEBUG("addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, val); - *out = val; -} - -static const MemoryRegionOps slow_bar_ops = { - .old_mmio = { - .read = { slow_bar_readb, slow_bar_readw, slow_bar_readl, }, - .write = { slow_bar_writeb, slow_bar_writew, slow_bar_writel, }, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num, - pcibus_t e_size) -{ - AssignedDevice *r_dev = PCI_ASSIGN(pci_dev); - AssignedDevRegion *region = &r_dev->v_addrs[region_num]; - PCIRegion *real_region = &r_dev->real_device.regions[region_num]; - - if (e_size > 0) { - memory_region_init(®ion->container, OBJECT(pci_dev), - "assigned-dev-container", e_size); - memory_region_add_subregion(®ion->container, 0, ®ion->real_iomem); - - /* deal with MSI-X MMIO page */ - if (real_region->base_addr <= r_dev->msix_table_addr && - real_region->base_addr + real_region->size > - r_dev->msix_table_addr) { - uint64_t offset = r_dev->msix_table_addr - real_region->base_addr; - - memory_region_add_subregion_overlap(®ion->container, - offset, - &r_dev->mmio, - 1); - } - } -} - -static const MemoryRegionOps assigned_dev_ioport_ops = { - .read = assigned_dev_ioport_read, - .write = assigned_dev_ioport_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void assigned_dev_ioport_setup(PCIDevice *pci_dev, int region_num, - pcibus_t size) -{ - AssignedDevice *r_dev = PCI_ASSIGN(pci_dev); - AssignedDevRegion *region = &r_dev->v_addrs[region_num]; - - region->e_size = size; - memory_region_init(®ion->container, OBJECT(pci_dev), - "assigned-dev-container", size); - memory_region_init_io(®ion->real_iomem, OBJECT(pci_dev), - &assigned_dev_ioport_ops, r_dev->v_addrs + region_num, - "assigned-dev-iomem", size); - memory_region_add_subregion(®ion->container, 0, ®ion->real_iomem); -} - -static uint32_t assigned_dev_pci_read(PCIDevice *d, int pos, int len) -{ - AssignedDevice *pci_dev = PCI_ASSIGN(d); - uint32_t val; - ssize_t ret; - int fd = pci_dev->real_device.config_fd; - -again: - ret = pread(fd, &val, len, pos); - if (ret != len) { - if ((ret < 0) && (errno == EINTR || errno == EAGAIN)) { - goto again; - } - - hw_error("pci read failed, ret = %zd errno = %d\n", ret, errno); - } - - return val; -} - -static uint8_t assigned_dev_pci_read_byte(PCIDevice *d, int pos) -{ - return (uint8_t)assigned_dev_pci_read(d, pos, 1); -} - -static void assigned_dev_pci_write(PCIDevice *d, int pos, uint32_t val, int len) -{ - AssignedDevice *pci_dev = PCI_ASSIGN(d); - ssize_t ret; - int fd = pci_dev->real_device.config_fd; - -again: - ret = pwrite(fd, &val, len, pos); - if (ret != len) { - if ((ret < 0) && (errno == EINTR || errno == EAGAIN)) { - goto again; - } - - hw_error("pci write failed, ret = %zd errno = %d\n", ret, errno); - } -} - -static void assigned_dev_emulate_config_read(AssignedDevice *dev, - uint32_t offset, uint32_t len) -{ - memset(dev->emulate_config_read + offset, 0xff, len); -} - -static void assigned_dev_direct_config_read(AssignedDevice *dev, - uint32_t offset, uint32_t len) -{ - memset(dev->emulate_config_read + offset, 0, len); -} - -static void assigned_dev_direct_config_write(AssignedDevice *dev, - uint32_t offset, uint32_t len) -{ - memset(dev->emulate_config_write + offset, 0, len); -} - -static uint8_t pci_find_cap_offset(PCIDevice *d, uint8_t cap, uint8_t start) -{ - int id; - int max_cap = 48; - int pos = start ? start : PCI_CAPABILITY_LIST; - int status; - - status = assigned_dev_pci_read_byte(d, PCI_STATUS); - if ((status & PCI_STATUS_CAP_LIST) == 0) { - return 0; - } - - while (max_cap--) { - pos = assigned_dev_pci_read_byte(d, pos); - if (pos < 0x40) { - break; - } - - pos &= ~3; - id = assigned_dev_pci_read_byte(d, pos + PCI_CAP_LIST_ID); - - if (id == 0xff) { - break; - } - if (id == cap) { - return pos; - } - - pos += PCI_CAP_LIST_NEXT; - } - return 0; -} - -static void assigned_dev_register_regions(PCIRegion *io_regions, - unsigned long regions_num, - AssignedDevice *pci_dev, - Error **errp) -{ - uint32_t i; - PCIRegion *cur_region = io_regions; - - for (i = 0; i < regions_num; i++, cur_region++) { - if (!cur_region->valid) { - continue; - } - - /* handle memory io regions */ - if (cur_region->type & IORESOURCE_MEM) { - int t = PCI_BASE_ADDRESS_SPACE_MEMORY; - if (cur_region->type & IORESOURCE_PREFETCH) { - t |= PCI_BASE_ADDRESS_MEM_PREFETCH; - } - if (cur_region->type & IORESOURCE_MEM_64) { - t |= PCI_BASE_ADDRESS_MEM_TYPE_64; - } - - /* map physical memory */ - pci_dev->v_addrs[i].u.r_virtbase = mmap(NULL, cur_region->size, - PROT_WRITE | PROT_READ, - MAP_SHARED, - cur_region->resource_fd, - (off_t)0); - - if (pci_dev->v_addrs[i].u.r_virtbase == MAP_FAILED) { - pci_dev->v_addrs[i].u.r_virtbase = NULL; - error_setg_errno(errp, errno, "Couldn't mmap 0x%" PRIx64 "!", - cur_region->base_addr); - return; - } - - pci_dev->v_addrs[i].r_size = cur_region->size; - pci_dev->v_addrs[i].e_size = 0; - - /* add offset */ - pci_dev->v_addrs[i].u.r_virtbase += - (cur_region->base_addr & 0xFFF); - - if (cur_region->size & 0xFFF) { - error_report("PCI region %d at address 0x%" PRIx64 " has " - "size 0x%" PRIx64 ", which is not a multiple of " - "4K. You might experience some performance hit " - "due to that.", - i, cur_region->base_addr, cur_region->size); - memory_region_init_io(&pci_dev->v_addrs[i].real_iomem, - OBJECT(pci_dev), &slow_bar_ops, - &pci_dev->v_addrs[i], - "assigned-dev-slow-bar", - cur_region->size); - } else { - void *virtbase = pci_dev->v_addrs[i].u.r_virtbase; - char name[32]; - snprintf(name, sizeof(name), "%s.bar%d", - object_get_typename(OBJECT(pci_dev)), i); - memory_region_init_ram_ptr(&pci_dev->v_addrs[i].real_iomem, - OBJECT(pci_dev), name, - cur_region->size, virtbase); - vmstate_register_ram(&pci_dev->v_addrs[i].real_iomem, - &pci_dev->dev.qdev); - } - - assigned_dev_iomem_setup(&pci_dev->dev, i, cur_region->size); - pci_register_bar((PCIDevice *) pci_dev, i, t, - &pci_dev->v_addrs[i].container); - continue; - } else { - /* handle port io regions */ - uint32_t val; - int ret; - - /* Test kernel support for ioport resource read/write. Old - * kernels return EIO. New kernels only allow 1/2/4 byte reads - * so should return EINVAL for a 3 byte read */ - ret = pread(pci_dev->v_addrs[i].region->resource_fd, &val, 3, 0); - if (ret >= 0) { - error_report("Unexpected return from I/O port read: %d", ret); - abort(); - } else if (errno != EINVAL) { - error_report("Kernel doesn't support ioport resource " - "access, hiding this region."); - close(pci_dev->v_addrs[i].region->resource_fd); - cur_region->valid = 0; - continue; - } - - pci_dev->v_addrs[i].u.r_baseport = cur_region->base_addr; - pci_dev->v_addrs[i].r_size = cur_region->size; - pci_dev->v_addrs[i].e_size = 0; - - assigned_dev_ioport_setup(&pci_dev->dev, i, cur_region->size); - pci_register_bar((PCIDevice *) pci_dev, i, - PCI_BASE_ADDRESS_SPACE_IO, - &pci_dev->v_addrs[i].container); - } - } - - /* success */ -} - -static void get_real_id(const char *devpath, const char *idname, uint16_t *val, - Error **errp) -{ - FILE *f; - char name[128]; - long id; - - snprintf(name, sizeof(name), "%s%s", devpath, idname); - f = fopen(name, "r"); - if (f == NULL) { - error_setg_file_open(errp, errno, name); - return; - } - if (fscanf(f, "%li\n", &id) == 1) { - *val = id; - } else { - error_setg(errp, "Failed to parse contents of '%s'", name); - } - fclose(f); -} - -static void get_real_vendor_id(const char *devpath, uint16_t *val, - Error **errp) -{ - get_real_id(devpath, "vendor", val, errp); -} - -static void get_real_device_id(const char *devpath, uint16_t *val, - Error **errp) -{ - get_real_id(devpath, "device", val, errp); -} - -static void get_real_device(AssignedDevice *pci_dev, Error **errp) -{ - char dir[128], name[128]; - int fd, r = 0; - FILE *f; - uint64_t start, end, size, flags; - uint16_t id; - PCIRegion *rp; - PCIDevRegions *dev = &pci_dev->real_device; - Error *local_err = NULL; - - dev->region_number = 0; - - snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/", - pci_dev->host.domain, pci_dev->host.bus, - pci_dev->host.slot, pci_dev->host.function); - - snprintf(name, sizeof(name), "%sconfig", dir); - - if (pci_dev->configfd_name && *pci_dev->configfd_name) { - dev->config_fd = monitor_fd_param(cur_mon, pci_dev->configfd_name, - &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - } else { - dev->config_fd = open(name, O_RDWR); - - if (dev->config_fd == -1) { - error_setg_file_open(errp, errno, name); - return; - } - } -again: - r = read(dev->config_fd, pci_dev->dev.config, - pci_config_size(&pci_dev->dev)); - if (r < 0) { - if (errno == EINTR || errno == EAGAIN) { - goto again; - } - error_setg_errno(errp, errno, "read(\"%s\")", - (pci_dev->configfd_name && *pci_dev->configfd_name) ? - pci_dev->configfd_name : name); - return; - } - - /* Restore or clear multifunction, this is always controlled by qemu */ - if (pci_dev->dev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) { - pci_dev->dev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION; - } else { - pci_dev->dev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION; - } - - /* Clear host resource mapping info. If we choose not to register a - * BAR, such as might be the case with the option ROM, we can get - * confusing, unwritable, residual addresses from the host here. */ - memset(&pci_dev->dev.config[PCI_BASE_ADDRESS_0], 0, 24); - memset(&pci_dev->dev.config[PCI_ROM_ADDRESS], 0, 4); - - snprintf(name, sizeof(name), "%sresource", dir); - - f = fopen(name, "r"); - if (f == NULL) { - error_setg_file_open(errp, errno, name); - return; - } - - for (r = 0; r < PCI_ROM_SLOT; r++) { - if (fscanf(f, "%" SCNi64 " %" SCNi64 " %" SCNi64 "\n", - &start, &end, &flags) != 3) { - break; - } - - rp = dev->regions + r; - rp->valid = 0; - rp->resource_fd = -1; - size = end - start + 1; - flags &= IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH - | IORESOURCE_MEM_64; - if (size == 0 || (flags & ~IORESOURCE_PREFETCH) == 0) { - continue; - } - if (flags & IORESOURCE_MEM) { - flags &= ~IORESOURCE_IO; - } else { - flags &= ~IORESOURCE_PREFETCH; - } - snprintf(name, sizeof(name), "%sresource%d", dir, r); - fd = open(name, O_RDWR); - if (fd == -1) { - continue; - } - rp->resource_fd = fd; - - rp->type = flags; - rp->valid = 1; - rp->base_addr = start; - rp->size = size; - pci_dev->v_addrs[r].region = rp; - DEBUG("region %d size %" PRIu64 " start 0x%" PRIx64 - " type %d resource_fd %d\n", - r, rp->size, start, rp->type, rp->resource_fd); - } - - fclose(f); - - /* read and fill vendor ID */ - get_real_vendor_id(dir, &id, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - pci_dev->dev.config[0] = id & 0xff; - pci_dev->dev.config[1] = (id & 0xff00) >> 8; - - /* read and fill device ID */ - get_real_device_id(dir, &id, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - pci_dev->dev.config[2] = id & 0xff; - pci_dev->dev.config[3] = (id & 0xff00) >> 8; - - pci_word_test_and_clear_mask(pci_dev->emulate_config_write + PCI_COMMAND, - PCI_COMMAND_MASTER | PCI_COMMAND_INTX_DISABLE); - - dev->region_number = r; -} - -static void free_msi_virqs(AssignedDevice *dev) -{ - int i; - - for (i = 0; i < dev->msi_virq_nr; i++) { - if (dev->msi_virq[i] >= 0) { - kvm_irqchip_release_virq(kvm_state, dev->msi_virq[i]); - dev->msi_virq[i] = -1; - } - } - g_free(dev->msi_virq); - dev->msi_virq = NULL; - dev->msi_virq_nr = 0; -} - -static void free_assigned_device(AssignedDevice *dev) -{ - int i; - - if (dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) { - assigned_dev_unregister_msix_mmio(dev); - } - for (i = 0; i < dev->real_device.region_number; i++) { - PCIRegion *pci_region = &dev->real_device.regions[i]; - AssignedDevRegion *region = &dev->v_addrs[i]; - - if (!pci_region->valid) { - continue; - } - if (pci_region->type & IORESOURCE_IO) { - if (region->u.r_baseport) { - memory_region_del_subregion(®ion->container, - ®ion->real_iomem); - } - } else if (pci_region->type & IORESOURCE_MEM) { - if (region->u.r_virtbase) { - memory_region_del_subregion(®ion->container, - ®ion->real_iomem); - - /* Remove MSI-X table subregion */ - if (pci_region->base_addr <= dev->msix_table_addr && - pci_region->base_addr + pci_region->size > - dev->msix_table_addr) { - memory_region_del_subregion(®ion->container, - &dev->mmio); - } - if (munmap(region->u.r_virtbase, - (pci_region->size + 0xFFF) & 0xFFFFF000)) { - error_report("Failed to unmap assigned device region: %s", - strerror(errno)); - } - } - } - if (pci_region->resource_fd >= 0) { - close(pci_region->resource_fd); - } - } - - if (dev->real_device.config_fd >= 0) { - close(dev->real_device.config_fd); - } - - free_msi_virqs(dev); -} - -/* This function tries to determine the cause of the PCI assignment failure. It - * always returns the cause as a dynamically allocated, human readable string. - * If the function fails to determine the cause for any internal reason, then - * the returned string will state that fact. - */ -static char *assign_failed_examine(const AssignedDevice *dev) -{ - char name[PATH_MAX], dir[PATH_MAX], driver[PATH_MAX] = {}, *ns; - uint16_t vendor_id, device_id; - int r; - Error *local_err = NULL; - - snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/", - dev->host.domain, dev->host.bus, dev->host.slot, - dev->host.function); - - snprintf(name, sizeof(name), "%sdriver", dir); - - r = readlink(name, driver, sizeof(driver)); - if ((r <= 0) || r >= sizeof(driver)) { - goto fail; - } - - driver[r] = 0; - ns = strrchr(driver, '/'); - if (!ns) { - goto fail; - } - - ns++; - - if ((get_real_vendor_id(dir, &vendor_id, &local_err), local_err) || - (get_real_device_id(dir, &device_id, &local_err), local_err)) { - /* We're already analyzing an assignment error, so we suppress this - * one just like the others above. - */ - error_free(local_err); - goto fail; - } - - return g_strdup_printf( - "*** The driver '%s' is occupying your device %04x:%02x:%02x.%x.\n" - "***\n" - "*** You can try the following commands to free it:\n" - "***\n" - "*** $ echo \"%04x %04x\" > /sys/bus/pci/drivers/pci-stub/new_id\n" - "*** $ echo \"%04x:%02x:%02x.%x\" > /sys/bus/pci/drivers/%s/unbind\n" - "*** $ echo \"%04x:%02x:%02x.%x\" > /sys/bus/pci/drivers/" - "pci-stub/bind\n" - "*** $ echo \"%04x %04x\" > /sys/bus/pci/drivers/pci-stub/remove_id\n" - "***", - ns, dev->host.domain, dev->host.bus, dev->host.slot, - dev->host.function, vendor_id, device_id, - dev->host.domain, dev->host.bus, dev->host.slot, dev->host.function, - ns, dev->host.domain, dev->host.bus, dev->host.slot, - dev->host.function, vendor_id, device_id); - -fail: - return g_strdup("Couldn't find out why."); -} - -static void assign_device(AssignedDevice *dev, Error **errp) -{ - uint32_t flags = KVM_DEV_ASSIGN_ENABLE_IOMMU; - int r; - - /* Only pass non-zero PCI segment to capable module */ - if (!kvm_check_extension(kvm_state, KVM_CAP_PCI_SEGMENT) && - dev->host.domain) { - error_setg(errp, "Can't assign device inside non-zero PCI segment " - "as this KVM module doesn't support it."); - return; - } - - if (!kvm_check_extension(kvm_state, KVM_CAP_IOMMU)) { - error_setg(errp, "No IOMMU found. Unable to assign device \"%s\"", - dev->dev.qdev.id); - return; - } - - if (dev->features & ASSIGNED_DEVICE_SHARE_INTX_MASK && - kvm_has_intx_set_mask()) { - flags |= KVM_DEV_ASSIGN_PCI_2_3; - } - - r = kvm_device_pci_assign(kvm_state, &dev->host, flags, &dev->dev_id); - if (r < 0) { - switch (r) { - case -EBUSY: { - char *cause; - - cause = assign_failed_examine(dev); - error_setg_errno(errp, -r, "Failed to assign device \"%s\"\n%s", - dev->dev.qdev.id, cause); - g_free(cause); - break; - } - default: - error_setg_errno(errp, -r, "Failed to assign device \"%s\"", - dev->dev.qdev.id); - break; - } - } -} - -static void verify_irqchip_in_kernel(Error **errp) -{ - if (kvm_irqchip_in_kernel()) { - return; - } - error_setg(errp, "pci-assign requires KVM with in-kernel irqchip enabled"); -} - -static int assign_intx(AssignedDevice *dev, Error **errp) -{ - AssignedIRQType new_type; - PCIINTxRoute intx_route; - bool intx_host_msi; - int r; - Error *local_err = NULL; - - /* Interrupt PIN 0 means don't use INTx */ - if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) { - pci_device_set_intx_routing_notifier(&dev->dev, NULL); - return 0; - } - - verify_irqchip_in_kernel(&local_err); - if (local_err) { - error_propagate(errp, local_err); - return -ENOTSUP; - } - - pci_device_set_intx_routing_notifier(&dev->dev, - assigned_dev_update_irq_routing); - - intx_route = pci_device_route_intx_to_irq(&dev->dev, dev->intpin); - assert(intx_route.mode != PCI_INTX_INVERTED); - - if (!pci_intx_route_changed(&dev->intx_route, &intx_route)) { - return 0; - } - - switch (dev->assigned_irq_type) { - case ASSIGNED_IRQ_INTX_HOST_INTX: - case ASSIGNED_IRQ_INTX_HOST_MSI: - intx_host_msi = dev->assigned_irq_type == ASSIGNED_IRQ_INTX_HOST_MSI; - r = kvm_device_intx_deassign(kvm_state, dev->dev_id, intx_host_msi); - break; - case ASSIGNED_IRQ_MSI: - r = kvm_device_msi_deassign(kvm_state, dev->dev_id); - break; - case ASSIGNED_IRQ_MSIX: - r = kvm_device_msix_deassign(kvm_state, dev->dev_id); - break; - default: - r = 0; - break; - } - if (r) { - perror("assign_intx: deassignment of previous interrupt failed"); - } - dev->assigned_irq_type = ASSIGNED_IRQ_NONE; - - if (intx_route.mode == PCI_INTX_DISABLED) { - dev->intx_route = intx_route; - return 0; - } - -retry: - if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK && - dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) { - intx_host_msi = true; - new_type = ASSIGNED_IRQ_INTX_HOST_MSI; - } else { - intx_host_msi = false; - new_type = ASSIGNED_IRQ_INTX_HOST_INTX; - } - - r = kvm_device_intx_assign(kvm_state, dev->dev_id, intx_host_msi, - intx_route.irq); - if (r < 0) { - if (r == -EIO && !(dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK) && - dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) { - /* Retry with host-side MSI. There might be an IRQ conflict and - * either the kernel or the device doesn't support sharing. */ - error_report("Host-side INTx sharing not supported, " - "using MSI instead"); - error_printf("Some devices do not work properly in this mode.\n"); - dev->features |= ASSIGNED_DEVICE_PREFER_MSI_MASK; - goto retry; - } - error_setg_errno(errp, -r, - "Failed to assign irq for \"%s\"\n" - "Perhaps you are assigning a device " - "that shares an IRQ with another device?", - dev->dev.qdev.id); - return r; - } - - dev->intx_route = intx_route; - dev->assigned_irq_type = new_type; - return r; -} - -static void deassign_device(AssignedDevice *dev) -{ - int r; - - r = kvm_device_pci_deassign(kvm_state, dev->dev_id); - assert(r == 0); -} - -/* The pci config space got updated. Check if irq numbers have changed - * for our devices - */ -static void assigned_dev_update_irq_routing(PCIDevice *dev) -{ - AssignedDevice *assigned_dev = PCI_ASSIGN(dev); - Error *err = NULL; - int r; - - r = assign_intx(assigned_dev, &err); - if (r < 0) { - error_report_err(err); - err = NULL; - qdev_unplug(&dev->qdev, &err); - assert(!err); - } -} - -static void assigned_dev_update_msi(PCIDevice *pci_dev) -{ - AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); - uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + - PCI_MSI_FLAGS); - int r; - - /* Some guests gratuitously disable MSI even if they're not using it, - * try to catch this by only deassigning irqs if the guest is using - * MSI or intends to start. */ - if (assigned_dev->assigned_irq_type == ASSIGNED_IRQ_MSI || - (ctrl_byte & PCI_MSI_FLAGS_ENABLE)) { - r = kvm_device_msi_deassign(kvm_state, assigned_dev->dev_id); - /* -ENXIO means no assigned irq */ - if (r && r != -ENXIO) { - perror("assigned_dev_update_msi: deassign irq"); - } - - free_msi_virqs(assigned_dev); - - assigned_dev->assigned_irq_type = ASSIGNED_IRQ_NONE; - pci_device_set_intx_routing_notifier(pci_dev, NULL); - } - - if (ctrl_byte & PCI_MSI_FLAGS_ENABLE) { - MSIMessage msg = msi_get_message(pci_dev, 0); - int virq; - - virq = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev); - if (virq < 0) { - perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route"); - return; - } - - assigned_dev->msi_virq = g_malloc(sizeof(*assigned_dev->msi_virq)); - assigned_dev->msi_virq_nr = 1; - assigned_dev->msi_virq[0] = virq; - if (kvm_device_msi_assign(kvm_state, assigned_dev->dev_id, virq) < 0) { - perror("assigned_dev_update_msi: kvm_device_msi_assign"); - } - - assigned_dev->intx_route.mode = PCI_INTX_DISABLED; - assigned_dev->intx_route.irq = -1; - assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSI; - } else { - Error *local_err = NULL; - - assign_intx(assigned_dev, &local_err); - if (local_err) { - error_report_err(local_err); - } - } -} - -static void assigned_dev_update_msi_msg(PCIDevice *pci_dev) -{ - AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); - uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + - PCI_MSI_FLAGS); - - if (assigned_dev->assigned_irq_type != ASSIGNED_IRQ_MSI || - !(ctrl_byte & PCI_MSI_FLAGS_ENABLE)) { - return; - } - - kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0], - msi_get_message(pci_dev, 0), pci_dev); -} - -static bool assigned_dev_msix_masked(MSIXTableEntry *entry) -{ - return (entry->ctrl & cpu_to_le32(0x1)) != 0; -} - -/* - * When MSI-X is first enabled the vector table typically has all the - * vectors masked, so we can't use that as the obvious test to figure out - * how many vectors to initially enable. Instead we look at the data field - * because this is what worked for pci-assign for a long time. This makes - * sure the physical MSI-X state tracks the guest's view, which is important - * for some VF/PF and PF/fw communication channels. - */ -static bool assigned_dev_msix_skipped(MSIXTableEntry *entry) -{ - return !entry->data; -} - -static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) -{ - AssignedDevice *adev = PCI_ASSIGN(pci_dev); - uint16_t entries_nr = 0; - int i, r = 0; - MSIXTableEntry *entry = adev->msix_table; - MSIMessage msg; - - /* Get the usable entry number for allocating */ - for (i = 0; i < adev->msix_max; i++, entry++) { - if (assigned_dev_msix_skipped(entry)) { - continue; - } - entries_nr++; - } - - DEBUG("MSI-X entries: %d\n", entries_nr); - - /* It's valid to enable MSI-X with all entries masked */ - if (!entries_nr) { - return 0; - } - - r = kvm_device_msix_init_vectors(kvm_state, adev->dev_id, entries_nr); - if (r != 0) { - error_report("fail to set MSI-X entry number for MSIX! %s", - strerror(-r)); - return r; - } - - free_msi_virqs(adev); - - adev->msi_virq_nr = adev->msix_max; - adev->msi_virq = g_malloc(adev->msix_max * sizeof(*adev->msi_virq)); - - entry = adev->msix_table; - for (i = 0; i < adev->msix_max; i++, entry++) { - adev->msi_virq[i] = -1; - - if (assigned_dev_msix_skipped(entry)) { - continue; - } - - msg.address = entry->addr_lo | ((uint64_t)entry->addr_hi << 32); - msg.data = entry->data; - r = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev); - if (r < 0) { - return r; - } - adev->msi_virq[i] = r; - - DEBUG("MSI-X vector %d, gsi %d, addr %08x_%08x, data %08x\n", i, - r, entry->addr_hi, entry->addr_lo, entry->data); - - r = kvm_device_msix_set_vector(kvm_state, adev->dev_id, i, - adev->msi_virq[i]); - if (r) { - error_report("fail to set MSI-X entry! %s", strerror(-r)); - break; - } - } - - return r; -} - -static void assigned_dev_update_msix(PCIDevice *pci_dev) -{ - AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); - uint16_t ctrl_word = pci_get_word(pci_dev->config + pci_dev->msix_cap + - PCI_MSIX_FLAGS); - int r; - - /* Some guests gratuitously disable MSIX even if they're not using it, - * try to catch this by only deassigning irqs if the guest is using - * MSIX or intends to start. */ - if ((assigned_dev->assigned_irq_type == ASSIGNED_IRQ_MSIX) || - (ctrl_word & PCI_MSIX_FLAGS_ENABLE)) { - r = kvm_device_msix_deassign(kvm_state, assigned_dev->dev_id); - /* -ENXIO means no assigned irq */ - if (r && r != -ENXIO) { - perror("assigned_dev_update_msix: deassign irq"); - } - - free_msi_virqs(assigned_dev); - - assigned_dev->assigned_irq_type = ASSIGNED_IRQ_NONE; - pci_device_set_intx_routing_notifier(pci_dev, NULL); - } - - if (ctrl_word & PCI_MSIX_FLAGS_ENABLE) { - if (assigned_dev_update_msix_mmio(pci_dev) < 0) { - perror("assigned_dev_update_msix_mmio"); - return; - } - - if (assigned_dev->msi_virq_nr > 0) { - if (kvm_device_msix_assign(kvm_state, assigned_dev->dev_id) < 0) { - perror("assigned_dev_enable_msix: assign irq"); - return; - } - } - assigned_dev->intx_route.mode = PCI_INTX_DISABLED; - assigned_dev->intx_route.irq = -1; - assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSIX; - } else { - Error *local_err = NULL; - - assign_intx(assigned_dev, &local_err); - if (local_err) { - error_report_err(local_err); - } - } -} - -static uint32_t assigned_dev_pci_read_config(PCIDevice *pci_dev, - uint32_t address, int len) -{ - AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); - uint32_t virt_val = pci_default_read_config(pci_dev, address, len); - uint32_t real_val, emulate_mask, full_emulation_mask; - - emulate_mask = 0; - memcpy(&emulate_mask, assigned_dev->emulate_config_read + address, len); - emulate_mask = le32_to_cpu(emulate_mask); - - full_emulation_mask = 0xffffffff >> (32 - len * 8); - - if (emulate_mask != full_emulation_mask) { - real_val = assigned_dev_pci_read(pci_dev, address, len); - return (virt_val & emulate_mask) | (real_val & ~emulate_mask); - } else { - return virt_val; - } -} - -static void assigned_dev_pci_write_config(PCIDevice *pci_dev, uint32_t address, - uint32_t val, int len) -{ - AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); - uint16_t old_cmd = pci_get_word(pci_dev->config + PCI_COMMAND); - uint32_t emulate_mask, full_emulation_mask; - int ret; - - pci_default_write_config(pci_dev, address, val, len); - - if (kvm_has_intx_set_mask() && - range_covers_byte(address, len, PCI_COMMAND + 1)) { - bool intx_masked = (pci_get_word(pci_dev->config + PCI_COMMAND) & - PCI_COMMAND_INTX_DISABLE); - - if (intx_masked != !!(old_cmd & PCI_COMMAND_INTX_DISABLE)) { - ret = kvm_device_intx_set_mask(kvm_state, assigned_dev->dev_id, - intx_masked); - if (ret) { - perror("assigned_dev_pci_write_config: set intx mask"); - } - } - } - if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) { - if (range_covers_byte(address, len, - pci_dev->msi_cap + PCI_MSI_FLAGS)) { - assigned_dev_update_msi(pci_dev); - } else if (ranges_overlap(address, len, /* 32bit MSI only */ - pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, 6)) { - assigned_dev_update_msi_msg(pci_dev); - } - } - if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) { - if (range_covers_byte(address, len, - pci_dev->msix_cap + PCI_MSIX_FLAGS + 1)) { - assigned_dev_update_msix(pci_dev); - } - } - - emulate_mask = 0; - memcpy(&emulate_mask, assigned_dev->emulate_config_write + address, len); - emulate_mask = le32_to_cpu(emulate_mask); - - full_emulation_mask = 0xffffffff >> (32 - len * 8); - - if (emulate_mask != full_emulation_mask) { - if (emulate_mask) { - val &= ~emulate_mask; - val |= assigned_dev_pci_read(pci_dev, address, len) & emulate_mask; - } - assigned_dev_pci_write(pci_dev, address, val, len); - } -} - -static void assigned_dev_setup_cap_read(AssignedDevice *dev, uint32_t offset, - uint32_t len) -{ - assigned_dev_direct_config_read(dev, offset, len); - assigned_dev_emulate_config_read(dev, offset + PCI_CAP_LIST_NEXT, 1); -} - -static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp) -{ - AssignedDevice *dev = PCI_ASSIGN(pci_dev); - PCIRegion *pci_region = dev->real_device.regions; - int ret, pos; - Error *local_err = NULL; - - /* Clear initial capabilities pointer and status copied from hw */ - pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0); - pci_set_word(pci_dev->config + PCI_STATUS, - pci_get_word(pci_dev->config + PCI_STATUS) & - ~PCI_STATUS_CAP_LIST); - - /* Expose MSI capability - * MSI capability is the 1st capability in capability config */ - pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0); - if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) { - verify_irqchip_in_kernel(&local_err); - if (local_err) { - error_propagate(errp, local_err); - return -ENOTSUP; - } - dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI; - /* Only 32-bit/no-mask currently supported */ - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSI, pos, 10, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - pci_dev->msi_cap = pos; - - pci_set_word(pci_dev->config + pos + PCI_MSI_FLAGS, - pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS) & - PCI_MSI_FLAGS_QMASK); - pci_set_long(pci_dev->config + pos + PCI_MSI_ADDRESS_LO, 0); - pci_set_word(pci_dev->config + pos + PCI_MSI_DATA_32, 0); - - /* Set writable fields */ - pci_set_word(pci_dev->wmask + pos + PCI_MSI_FLAGS, - PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); - pci_set_long(pci_dev->wmask + pos + PCI_MSI_ADDRESS_LO, 0xfffffffc); - pci_set_word(pci_dev->wmask + pos + PCI_MSI_DATA_32, 0xffff); - } - /* Expose MSI-X capability */ - pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX, 0); - if (pos != 0 && kvm_device_msix_supported(kvm_state)) { - int bar_nr; - uint32_t msix_table_entry; - uint16_t msix_max; - - verify_irqchip_in_kernel(&local_err); - if (local_err) { - error_propagate(errp, local_err); - return -ENOTSUP; - } - dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX; - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSIX, pos, 12, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - pci_dev->msix_cap = pos; - - msix_max = (pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & - PCI_MSIX_FLAGS_QSIZE) + 1; - msix_max = MIN(msix_max, KVM_MAX_MSIX_PER_DEV); - pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, msix_max - 1); - - /* Only enable and function mask bits are writable */ - pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS, - PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); - - msix_table_entry = pci_get_long(pci_dev->config + pos + PCI_MSIX_TABLE); - bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK; - msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK; - dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry; - dev->msix_max = msix_max; - } - - /* Minimal PM support, nothing writable, device appears to NAK changes */ - pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PM, 0); - if (pos) { - uint16_t pmc; - - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - - assigned_dev_setup_cap_read(dev, pos, PCI_PM_SIZEOF); - - pmc = pci_get_word(pci_dev->config + pos + PCI_CAP_FLAGS); - pmc &= (PCI_PM_CAP_VER_MASK | PCI_PM_CAP_DSI); - pci_set_word(pci_dev->config + pos + PCI_CAP_FLAGS, pmc); - - /* assign_device will bring the device up to D0, so we don't need - * to worry about doing that ourselves here. */ - pci_set_word(pci_dev->config + pos + PCI_PM_CTRL, - PCI_PM_CTRL_NO_SOFT_RESET); - - pci_set_byte(pci_dev->config + pos + PCI_PM_PPB_EXTENSIONS, 0); - pci_set_byte(pci_dev->config + pos + PCI_PM_DATA_REGISTER, 0); - } - - pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_EXP, 0); - if (pos) { - uint8_t version, size = 0; - uint16_t type, devctl, lnksta; - uint32_t devcap, lnkcap; - - version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS); - version &= PCI_EXP_FLAGS_VERS; - if (version == 1) { - size = 0x14; - } else if (version == 2) { - /* - * Check for non-std size, accept reduced size to 0x34, - * which is what bcm5761 implemented, violating the - * PCIe v3.0 spec that regs should exist and be read as 0, - * not optionally provided and shorten the struct size. - */ - size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - pos); - if (size < 0x34) { - error_setg(errp, "Invalid size PCIe cap-id 0x%x", - PCI_CAP_ID_EXP); - return -EINVAL; - } else if (size != 0x3c) { - error_report("WARNING, %s: PCIe cap-id 0x%x has " - "non-standard size 0x%x; std size should be 0x3c", - __func__, PCI_CAP_ID_EXP, size); - } - } else if (version == 0) { - uint16_t vid, did; - vid = pci_get_word(pci_dev->config + PCI_VENDOR_ID); - did = pci_get_word(pci_dev->config + PCI_DEVICE_ID); - if (vid == PCI_VENDOR_ID_INTEL && did == 0x10ed) { - /* - * quirk for Intel 82599 VF with invalid PCIe capability - * version, should really be version 2 (same as PF) - */ - size = 0x3c; - } - } - - if (size == 0) { - error_setg(errp, "Unsupported PCI express capability version %d", - version); - return -EINVAL; - } - - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_EXP, pos, size, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - - assigned_dev_setup_cap_read(dev, pos, size); - - type = pci_get_word(pci_dev->config + pos + PCI_EXP_FLAGS); - type = (type & PCI_EXP_FLAGS_TYPE) >> 4; - if (type != PCI_EXP_TYPE_ENDPOINT && - type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) { - error_setg(errp, "Device assignment only supports endpoint " - "assignment, device type %d", type); - return -EINVAL; - } - - /* capabilities, pass existing read-only copy - * PCI_EXP_FLAGS_IRQ: updated by hardware, should be direct read */ - - /* device capabilities: hide FLR */ - devcap = pci_get_long(pci_dev->config + pos + PCI_EXP_DEVCAP); - devcap &= ~PCI_EXP_DEVCAP_FLR; - pci_set_long(pci_dev->config + pos + PCI_EXP_DEVCAP, devcap); - - /* device control: clear all error reporting enable bits, leaving - * only a few host values. Note, these are - * all writable, but not passed to hw. - */ - devctl = pci_get_word(pci_dev->config + pos + PCI_EXP_DEVCTL); - devctl = (devctl & (PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_PAYLOAD)) | - PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN; - pci_set_word(pci_dev->config + pos + PCI_EXP_DEVCTL, devctl); - devctl = PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_AUX_PME; - pci_set_word(pci_dev->wmask + pos + PCI_EXP_DEVCTL, ~devctl); - - /* Clear device status */ - pci_set_word(pci_dev->config + pos + PCI_EXP_DEVSTA, 0); - - /* Link capabilities, expose links and latencues, clear reporting */ - lnkcap = pci_get_long(pci_dev->config + pos + PCI_EXP_LNKCAP); - lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW | - PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL | - PCI_EXP_LNKCAP_L1EL); - pci_set_long(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap); - - /* Link control, pass existing read-only copy. Should be writable? */ - - /* Link status, only expose current speed and width */ - lnksta = pci_get_word(pci_dev->config + pos + PCI_EXP_LNKSTA); - lnksta &= (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW); - pci_set_word(pci_dev->config + pos + PCI_EXP_LNKSTA, lnksta); - - if (version >= 2) { - /* Slot capabilities, control, status - not needed for endpoints */ - pci_set_long(pci_dev->config + pos + PCI_EXP_SLTCAP, 0); - pci_set_word(pci_dev->config + pos + PCI_EXP_SLTCTL, 0); - pci_set_word(pci_dev->config + pos + PCI_EXP_SLTSTA, 0); - - /* Root control, capabilities, status - not needed for endpoints */ - pci_set_word(pci_dev->config + pos + PCI_EXP_RTCTL, 0); - pci_set_word(pci_dev->config + pos + PCI_EXP_RTCAP, 0); - pci_set_long(pci_dev->config + pos + PCI_EXP_RTSTA, 0); - - /* Device capabilities/control 2, pass existing read-only copy */ - /* Link control 2, pass existing read-only copy */ - } - } - - pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PCIX, 0); - if (pos) { - uint16_t cmd; - uint32_t status; - - /* Only expose the minimum, 8 byte capability */ - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PCIX, pos, 8, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - - assigned_dev_setup_cap_read(dev, pos, 8); - - /* Command register, clear upper bits, including extended modes */ - cmd = pci_get_word(pci_dev->config + pos + PCI_X_CMD); - cmd &= (PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO | PCI_X_CMD_MAX_READ | - PCI_X_CMD_MAX_SPLIT); - pci_set_word(pci_dev->config + pos + PCI_X_CMD, cmd); - - /* Status register, update with emulated PCI bus location, clear - * error bits, leave the rest. */ - status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS); - status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN); - status |= pci_requester_id(pci_dev); - status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL | - PCI_X_STATUS_SPL_ERR); - pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status); - } - - pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0); - if (pos) { - /* Direct R/W passthrough */ - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VPD, pos, 8, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - - assigned_dev_setup_cap_read(dev, pos, 8); - - /* direct write for cap content */ - assigned_dev_direct_config_write(dev, pos + 2, 6); - } - - /* Devices can have multiple vendor capabilities, get them all */ - for (pos = 0; (pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VNDR, pos)); - pos += PCI_CAP_LIST_NEXT) { - uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS); - /* Direct R/W passthrough */ - ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VNDR, pos, len, - &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - - assigned_dev_setup_cap_read(dev, pos, len); - - /* direct write for cap content */ - assigned_dev_direct_config_write(dev, pos + 2, len - 2); - } - - /* If real and virtual capability list status bits differ, virtualize the - * access. */ - if ((pci_get_word(pci_dev->config + PCI_STATUS) & PCI_STATUS_CAP_LIST) != - (assigned_dev_pci_read_byte(pci_dev, PCI_STATUS) & - PCI_STATUS_CAP_LIST)) { - dev->emulate_config_read[PCI_STATUS] |= PCI_STATUS_CAP_LIST; - } - - return 0; -} - -static uint64_t -assigned_dev_msix_mmio_read(void *opaque, hwaddr addr, - unsigned size) -{ - AssignedDevice *adev = opaque; - uint64_t val; - - memcpy(&val, (void *)((uint8_t *)adev->msix_table + addr), size); - - return val; -} - -static void assigned_dev_msix_mmio_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) -{ - AssignedDevice *adev = opaque; - PCIDevice *pdev = &adev->dev; - uint16_t ctrl; - MSIXTableEntry orig; - int i = addr >> 4; - - if (i >= adev->msix_max) { - return; /* Drop write */ - } - - ctrl = pci_get_word(pdev->config + pdev->msix_cap + PCI_MSIX_FLAGS); - - DEBUG("write to MSI-X table offset 0x%lx, val 0x%lx\n", addr, val); - - if (ctrl & PCI_MSIX_FLAGS_ENABLE) { - orig = adev->msix_table[i]; - } - - memcpy((uint8_t *)adev->msix_table + addr, &val, size); - - if (ctrl & PCI_MSIX_FLAGS_ENABLE) { - MSIXTableEntry *entry = &adev->msix_table[i]; - - if (!assigned_dev_msix_masked(&orig) && - assigned_dev_msix_masked(entry)) { - /* - * Vector masked, disable it - * - * XXX It's not clear if we can or should actually attempt - * to mask or disable the interrupt. KVM doesn't have - * support for pending bits and kvm_assign_set_msix_entry - * doesn't modify the device hardware mask. Interrupts - * while masked are simply not injected to the guest, so - * are lost. Can we get away with always injecting an - * interrupt on unmask? - */ - } else if (assigned_dev_msix_masked(&orig) && - !assigned_dev_msix_masked(entry)) { - /* Vector unmasked */ - if (i >= adev->msi_virq_nr || adev->msi_virq[i] < 0) { - /* Previously unassigned vector, start from scratch */ - assigned_dev_update_msix(pdev); - return; - } else { - /* Update an existing, previously masked vector */ - MSIMessage msg; - int ret; - - msg.address = entry->addr_lo | - ((uint64_t)entry->addr_hi << 32); - msg.data = entry->data; - - ret = kvm_irqchip_update_msi_route(kvm_state, - adev->msi_virq[i], msg, - pdev); - if (ret) { - error_report("Error updating irq routing entry (%d)", ret); - } - } - } - } -} - -static const MemoryRegionOps assigned_dev_msix_mmio_ops = { - .read = assigned_dev_msix_mmio_read, - .write = assigned_dev_msix_mmio_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 8, - }, - .impl = { - .min_access_size = 4, - .max_access_size = 8, - }, -}; - -static void assigned_dev_msix_reset(AssignedDevice *dev) -{ - MSIXTableEntry *entry; - int i; - - if (!dev->msix_table) { - return; - } - - memset(dev->msix_table, 0, MSIX_PAGE_SIZE); - - for (i = 0, entry = dev->msix_table; i < dev->msix_max; i++, entry++) { - entry->ctrl = cpu_to_le32(0x1); /* Masked */ - } -} - -static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp) -{ - dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); - if (dev->msix_table == MAP_FAILED) { - error_setg_errno(errp, errno, "failed to allocate msix_table"); - dev->msix_table = NULL; - return; - } - - assigned_dev_msix_reset(dev); - - memory_region_init_io(&dev->mmio, OBJECT(dev), &assigned_dev_msix_mmio_ops, - dev, "assigned-dev-msix", MSIX_PAGE_SIZE); -} - -static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev) -{ - if (!dev->msix_table) { - return; - } - - if (munmap(dev->msix_table, MSIX_PAGE_SIZE) == -1) { - error_report("error unmapping msix_table! %s", strerror(errno)); - } - dev->msix_table = NULL; -} - -static const VMStateDescription vmstate_assigned_device = { - .name = "pci-assign", - .unmigratable = 1, -}; - -static void reset_assigned_device(DeviceState *dev) -{ - PCIDevice *pci_dev = PCI_DEVICE(dev); - AssignedDevice *adev = PCI_ASSIGN(pci_dev); - char reset_file[64]; - const char reset[] = "1"; - int fd, ret; - - /* - * If a guest is reset without being shutdown, MSI/MSI-X can still - * be running. We want to return the device to a known state on - * reset, so disable those here. We especially do not want MSI-X - * enabled since it lives in MMIO space, which is about to get - * disabled. - */ - if (adev->assigned_irq_type == ASSIGNED_IRQ_MSIX) { - uint16_t ctrl = pci_get_word(pci_dev->config + - pci_dev->msix_cap + PCI_MSIX_FLAGS); - - pci_set_word(pci_dev->config + pci_dev->msix_cap + PCI_MSIX_FLAGS, - ctrl & ~PCI_MSIX_FLAGS_ENABLE); - assigned_dev_update_msix(pci_dev); - } else if (adev->assigned_irq_type == ASSIGNED_IRQ_MSI) { - uint8_t ctrl = pci_get_byte(pci_dev->config + - pci_dev->msi_cap + PCI_MSI_FLAGS); - - pci_set_byte(pci_dev->config + pci_dev->msi_cap + PCI_MSI_FLAGS, - ctrl & ~PCI_MSI_FLAGS_ENABLE); - assigned_dev_update_msi(pci_dev); - } - - snprintf(reset_file, sizeof(reset_file), - "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/reset", - adev->host.domain, adev->host.bus, adev->host.slot, - adev->host.function); - - /* - * Issue a device reset via pci-sysfs. Note that we use write(2) here - * and ignore the return value because some kernels have a bug that - * returns 0 rather than bytes written on success, sending us into an - * infinite retry loop using other write mechanisms. - */ - fd = open(reset_file, O_WRONLY); - if (fd != -1) { - ret = write(fd, reset, strlen(reset)); - (void)ret; - close(fd); - } - - /* - * When a 0 is written to the bus master register, the device is logically - * disconnected from the PCI bus. This avoids further DMA transfers. - */ - assigned_dev_pci_write_config(pci_dev, PCI_COMMAND, 0, 1); -} - -static void assigned_realize(struct PCIDevice *pci_dev, Error **errp) -{ - AssignedDevice *dev = PCI_ASSIGN(pci_dev); - uint8_t e_intx; - int r; - Error *local_err = NULL; - - if (!kvm_enabled()) { - error_setg(&local_err, "pci-assign requires KVM support"); - goto exit_with_error; - } - - if (!dev->host.domain && !dev->host.bus && !dev->host.slot && - !dev->host.function) { - error_setg(&local_err, "no host device specified"); - goto exit_with_error; - } - - /* - * Set up basic config space access control. Will be further refined during - * device initialization. - */ - assigned_dev_emulate_config_read(dev, 0, PCI_CONFIG_SPACE_SIZE); - assigned_dev_direct_config_read(dev, PCI_STATUS, 2); - assigned_dev_direct_config_read(dev, PCI_REVISION_ID, 1); - assigned_dev_direct_config_read(dev, PCI_CLASS_PROG, 3); - assigned_dev_direct_config_read(dev, PCI_CACHE_LINE_SIZE, 1); - assigned_dev_direct_config_read(dev, PCI_LATENCY_TIMER, 1); - assigned_dev_direct_config_read(dev, PCI_BIST, 1); - assigned_dev_direct_config_read(dev, PCI_CARDBUS_CIS, 4); - assigned_dev_direct_config_read(dev, PCI_SUBSYSTEM_VENDOR_ID, 2); - assigned_dev_direct_config_read(dev, PCI_SUBSYSTEM_ID, 2); - assigned_dev_direct_config_read(dev, PCI_CAPABILITY_LIST + 1, 7); - assigned_dev_direct_config_read(dev, PCI_MIN_GNT, 1); - assigned_dev_direct_config_read(dev, PCI_MAX_LAT, 1); - memcpy(dev->emulate_config_write, dev->emulate_config_read, - sizeof(dev->emulate_config_read)); - - get_real_device(dev, &local_err); - if (local_err) { - goto out; - } - - if (assigned_device_pci_cap_init(pci_dev, &local_err) < 0) { - goto out; - } - - /* intercept MSI-X entry page in the MMIO */ - if (dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) { - assigned_dev_register_msix_mmio(dev, &local_err); - if (local_err) { - goto out; - } - } - - /* handle real device's MMIO/PIO BARs */ - assigned_dev_register_regions(dev->real_device.regions, - dev->real_device.region_number, dev, - &local_err); - if (local_err) { - goto out; - } - - /* handle interrupt routing */ - e_intx = dev->dev.config[PCI_INTERRUPT_PIN] - 1; - dev->intpin = e_intx; - dev->intx_route.mode = PCI_INTX_DISABLED; - dev->intx_route.irq = -1; - - /* assign device to guest */ - assign_device(dev, &local_err); - if (local_err) { - goto out; - } - - /* assign legacy INTx to the device */ - r = assign_intx(dev, &local_err); - if (r < 0) { - goto assigned_out; - } - - assigned_dev_load_option_rom(dev); - - return; - -assigned_out: - deassign_device(dev); - -out: - free_assigned_device(dev); - -exit_with_error: - assert(local_err); - error_propagate(errp, local_err); -} - -static void assigned_exitfn(struct PCIDevice *pci_dev) -{ - AssignedDevice *dev = PCI_ASSIGN(pci_dev); - - deassign_device(dev); - free_assigned_device(dev); -} - -static void assigned_dev_instance_init(Object *obj) -{ - PCIDevice *pci_dev = PCI_DEVICE(obj); - AssignedDevice *d = PCI_ASSIGN(pci_dev); - - device_add_bootindex_property(obj, &d->bootindex, - "bootindex", NULL, - &pci_dev->qdev, NULL); -} - -static Property assigned_dev_properties[] = { - DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host), - DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features, - ASSIGNED_DEVICE_PREFER_MSI_BIT, false), - DEFINE_PROP_BIT("share_intx", AssignedDevice, features, - ASSIGNED_DEVICE_SHARE_INTX_BIT, true), - DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name), - DEFINE_PROP_END_OF_LIST(), -}; - -static void assign_class_init(ObjectClass *klass, void *data) -{ - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); - - k->realize = assigned_realize; - k->exit = assigned_exitfn; - k->config_read = assigned_dev_pci_read_config; - k->config_write = assigned_dev_pci_write_config; - dc->props = assigned_dev_properties; - dc->vmsd = &vmstate_assigned_device; - dc->reset = reset_assigned_device; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); - dc->desc = "KVM-based PCI passthrough"; -} - -static const TypeInfo assign_info = { - .name = TYPE_PCI_ASSIGN, - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(AssignedDevice), - .class_init = assign_class_init, - .instance_init = assigned_dev_instance_init, -}; - -static void assign_register_types(void) -{ - type_register_static(&assign_info); -} - -type_init(assign_register_types) - -static void assigned_dev_load_option_rom(AssignedDevice *dev) -{ - int size = 0; - &error_abort); - - pci_assign_dev_load_option_rom(&dev->dev, OBJECT(dev), &size, - dev->host.domain, dev->host.bus, - dev->host.slot, dev->host.function); - - if (!size) { - error_report("pci-assign: Invalid ROM."); - } -} diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e190ca281d215..5143c516531ec 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -662,13 +662,7 @@ void pc_cmos_init(PCMachineState *pcms, object_property_set_link(OBJECT(pcms), OBJECT(s), "rtc_state", &error_abort); -<<<<<<< HEAD set_boot_dev(s, MACHINE(pcms)->boot_order, &error_fatal); -======= - set_boot_dev(s, MACHINE(pcms)->boot_order, &local_err); - if (local_err) { - error_report_err(local_err); ->>>>>>> 919b29ba7d... Pebble Qemu val = 0; val |= 0x02; /* FPU is there */ diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index a25dcdad8e53b..22dee0e76c628 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -71,7 +71,7 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; #endif /* PC hardware initialisation */ -static void pc_init1(MachineState *machine) +static void pc_init1(MachineState *machine, const char *host_type, const char *pci_type) { PCMachineState *pcms = PC_MACHINE(machine); @@ -808,196 +808,6 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2, pc_i440fx_1_0_machine_options); -<<<<<<< HEAD -======= -#define PC_COMPAT_0_15 \ - PC_COMPAT_1_0 - -static void pc_i440fx_0_15_machine_options(MachineClass *m) -{ - pc_i440fx_1_0_machine_options(m); - m->hw_version = "0.15"; - SET_MACHINE_COMPAT(m, PC_COMPAT_0_15); -} - -DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2, - pc_i440fx_0_15_machine_options); - - -#define PC_COMPAT_0_14 \ - PC_COMPAT_0_15 \ - {\ - .driver = "virtio-blk-pci",\ - .property = "event_idx",\ - .value = "off",\ - },{\ - .driver = "virtio-serial-pci",\ - .property = "event_idx",\ - .value = "off",\ - },{\ - .driver = "virtio-net-pci",\ - .property = "event_idx",\ - .value = "off",\ - },{\ - .driver = "virtio-balloon-pci",\ - .property = "event_idx",\ - .value = "off",\ - },{\ - .driver = "qxl",\ - .property = "revision",\ - .value = stringify(2),\ - },{\ - .driver = "qxl-vga",\ - .property = "revision",\ - .value = stringify(2),\ - }, - -static void pc_i440fx_0_14_machine_options(MachineClass *m) -{ - pc_i440fx_0_15_machine_options(m); - m->hw_version = "0.14"; - SET_MACHINE_COMPAT(m, PC_COMPAT_0_14); -} - -DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2, - pc_i440fx_0_14_machine_options); - - -#define PC_COMPAT_0_13 \ - PC_COMPAT_0_14 \ - {\ - .driver = TYPE_PCI_DEVICE,\ - .property = "command_serr_enable",\ - .value = "off",\ - },{\ - .driver = "AC97",\ - .property = "use_broken_id",\ - .value = stringify(1),\ - },{\ - .driver = "virtio-9p-pci",\ - .property = "vectors",\ - .value = stringify(0),\ - },{\ - .driver = "VGA",\ - .property = "rombar",\ - .value = stringify(0),\ - },{\ - .driver = "vmware-svga",\ - .property = "rombar",\ - .value = stringify(0),\ - }, - -static void pc_i440fx_0_13_machine_options(MachineClass *m) -{ - pc_i440fx_0_14_machine_options(m); - m->hw_version = "0.13"; - SET_MACHINE_COMPAT(m, PC_COMPAT_0_13); -} - -DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13, - pc_i440fx_0_13_machine_options); - - -#define PC_COMPAT_0_12 \ - PC_COMPAT_0_13 \ - {\ - .driver = "virtio-serial-pci",\ - .property = "max_ports",\ - .value = stringify(1),\ - },{\ - .driver = "virtio-serial-pci",\ - .property = "vectors",\ - .value = stringify(0),\ - },{\ - .driver = "usb-mouse",\ - .property = "serial",\ - .value = "1",\ - },{\ - .driver = "usb-tablet",\ - .property = "serial",\ - .value = "1",\ - },{\ - .driver = "usb-kbd",\ - .property = "serial",\ - .value = "1",\ - }, - -static void pc_i440fx_0_12_machine_options(MachineClass *m) -{ - pc_i440fx_0_13_machine_options(m); - m->hw_version = "0.12"; - SET_MACHINE_COMPAT(m, PC_COMPAT_0_12); -} - -DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13, - pc_i440fx_0_12_machine_options); - - -#define PC_COMPAT_0_11 \ - PC_COMPAT_0_12 \ - {\ - .driver = "virtio-blk-pci",\ - .property = "vectors",\ - .value = stringify(0),\ - },{\ - .driver = TYPE_PCI_DEVICE,\ - .property = "rombar",\ - .value = stringify(0),\ - },{\ - .driver = "ide-drive",\ - .property = "ver",\ - .value = "0.11",\ - },{\ - .driver = "scsi-disk",\ - .property = "ver",\ - .value = "0.11",\ - }, -static void pc_i440fx_0_11_machine_options(MachineClass *m) -{ - pc_i440fx_0_12_machine_options(m); - m->hw_version = "0.11"; - SET_MACHINE_COMPAT(m, PC_COMPAT_0_11); -} - -DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13, - pc_i440fx_0_11_machine_options); - - -#define PC_COMPAT_0_10 \ - PC_COMPAT_0_11 \ - {\ - .driver = "virtio-blk-pci",\ - .property = "class",\ - .value = stringify(PCI_CLASS_STORAGE_OTHER),\ - },{\ - .driver = "virtio-serial-pci",\ - .property = "class",\ - .value = stringify(PCI_CLASS_DISPLAY_OTHER),\ - },{\ - .driver = "virtio-net-pci",\ - .property = "vectors",\ - .value = stringify(0),\ - },{\ - .driver = "ide-drive",\ - .property = "ver",\ - .value = "0.10",\ - },{\ - .driver = "scsi-disk",\ - .property = "ver",\ - .value = "0.10",\ - }, - -static void pc_i440fx_0_10_machine_options(MachineClass *m) -{ - pc_i440fx_0_11_machine_options(m); - m->hw_version = "0.10"; - SET_MACHINE_COMPAT(m, PC_COMPAT_0_10); -} - -DEFINE_I440FX_MACHINE(v0_10, "pc-0.10", pc_compat_0_13, - pc_i440fx_0_10_machine_options); - ->>>>>>> 919b29ba7d... Pebble Qemu typedef struct { uint16_t gpu_device_id; uint16_t pch_device_id; @@ -1052,6 +862,7 @@ static const IGDDeviceIDInfo igd_combo_id_infos[] = { {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */ {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */ {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */ +}; static void isa_bridge_class_init(ObjectClass *klass, void *data) { @@ -1062,6 +873,7 @@ static void isa_bridge_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); k->vendor_id = PCI_VENDOR_ID_INTEL; k->class_id = PCI_CLASS_BRIDGE_ISA; +}; static TypeInfo isa_bridge_info = { .name = "igd-passthrough-isa-bridge", @@ -1081,10 +893,6 @@ static void pt_graphics_register_types(void) type_init(pt_graphics_register_types) void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id) - pc_i440fx_0_10_machine_options); - - -static void isapc_machine_options(MachineClass *m) { struct PCIDevice *bridge_dev; int i, num; diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 7e22fca99b0eb..13d91e109ab3e 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -1308,41 +1308,11 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot) trace_handle_cmd_badmap(s, port, cmd_len); goto out; } -<<<<<<< HEAD if (trace_event_get_state_backends(TRACE_HANDLE_CMD_FIS_DUMP)) { char *pretty_fis = ahci_pretty_buffer_fis(cmd_fis, 0x80); trace_handle_cmd_fis_dump(s, port, pretty_fis); g_free(pretty_fis); } -======= - cmd = get_cmd_header(s, port, slot); - /* remember current slot handle for later */ - s->dev[port].cur_cmd = cmd; - - /* The device we are working for */ - ide_state = &s->dev[port].port.ifs[0]; - if (!ide_state->blk) { - DPRINTF(port, "error: guest accessed unused port"); - return -1; - } - - tbl_addr = le64_to_cpu(cmd->tbl_addr); - cmd_len = 0x80; - cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len, - DMA_DIRECTION_FROM_DEVICE); - if (!cmd_fis) { - DPRINTF(port, "error: guest passed us an invalid cmd fis\n"); - return -1; - } else if (cmd_len != 0x80) { - ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR); - DPRINTF(port, "error: dma_memory_map failed: " - "(len(%02"PRIx64") != 0x80)\n", - cmd_len); - goto out; - } - debug_print_fis(cmd_fis, 0x80); - ->>>>>>> 919b29ba7d... Pebble Qemu switch (cmd_fis[0]) { case SATA_FIS_TYPE_REGISTER_H2D: handle_reg_h2d_fis(s, port, slot, cmd_fis); diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 4edc3f71ecf2e..c60dc6b5e6e51 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -32,12 +32,7 @@ /* #define DEBUG_GIC */ #ifdef DEBUG_GIC -<<<<<<< HEAD #define DEBUG_GIC_GATE 1 -======= -#define DPRINTF(fmt, ...) \ -do { printf("DEBUG_GIC: " fmt , ## __VA_ARGS__); usleep(100);} while (0) ->>>>>>> 919b29ba7d... Pebble Qemu #else #define DEBUG_GIC_GATE 0 #endif @@ -464,7 +459,6 @@ static int gic_get_group_priority(GICState *s, int cpu, int irq) assert(bpr >= 0); } else { bpr = s->bpr[cpu]; - return GIC_GET_PRIORITY(irq, cpu); } /* a BPR of 0 means the group priority bits are [7:1]; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 84945fd0424bf..1ad35e55292b7 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -16,7 +16,6 @@ #include "hw/sysbus.h" #include "migration/vmstate.h" #include "qemu/timer.h" -<<<<<<< HEAD #include "hw/intc/armv7m_nvic.h" #include "hw/irq.h" #include "hw/qdev-properties.h" @@ -36,57 +35,6 @@ * and one for the unused exception number 0). * * NVIC_MAX_IRQ is the highest permitted number of external IRQ lines. -======= -#include "hw/arm/arm.h" -#include "exec/address-spaces.h" -#include "gic_internal.h" -#include "sysemu/sysemu.h" - -//#define DEBUG_ARMV7M_NVIC -#ifdef DEBUG_ARMV7M_NVIC - -// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out -#define DPRINTF(fmt, ...) \ - do { printf("ARMV7M_NVIC: " fmt , ## __VA_ARGS__); \ - /* usleep(1000); */ /* the usleep causes watchdogs :( */ \ - } while (0) -#else -#define DPRINTF(fmt, ...) -#endif - - -typedef struct { - GICState gic; - struct { - uint32_t control; - uint32_t reload; - int64_t tick; - QEMUTimer *timer; - } systick; - uint16_t aircr_reg; /* low word of Application Interrupt and Reset Control Register */ - MemoryRegion sysregmem; - MemoryRegion gic_iomem_alias; - MemoryRegion container; - uint32_t num_irq; - qemu_irq sysresetreq; - uint32_t scr_reg; /* contents of SCR register */ - /* set true if we executed a WFI instruction with the SLEEPDEEP bit set in the SCR */ - bool in_deep_sleep; - // Set true if we execute a WFI instruction with both SLEEPDEEP bit set in the SCR - // and PDDS (Power Down Deep Sleep) bit is set in the PWR_CR register - bool in_standby; - // Properties - void *stm32_pwr_prop; - // output IRQs - qemu_irq cpu_wakeup_out; - qemu_irq power_out; -} nvic_state; - -#define TYPE_NVIC "armv7m_nvic" -/** - * NVICClass: - * @parent_reset: the parent class' reset handler. ->>>>>>> 919b29ba7d... Pebble Qemu * * NVIC_MAX_VECTORS is the highest permitted number of exceptions. * @@ -116,7 +64,6 @@ static const uint8_t nvic_id[] = { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 }; -<<<<<<< HEAD static int nvic_pending_prio(NVICState *s) { /* return the group priority of the current pending interrupt, @@ -196,13 +143,6 @@ static bool exc_is_banked(int exc) exc == ARMV7M_EXCP_PENDSV || exc == ARMV7M_EXCP_SYSTICK; } -======= -/* SCR register definitions */ -#define SCR_REG_SLEEPDEEP 0x00000004 - -/* qemu timers run at 1GHz. We want something closer to 1MHz. */ -#define SYSTICK_SCALE 1000ULL ->>>>>>> 919b29ba7d... Pebble Qemu /* Return a mask word which clears the subpriority bits from * a priority value for an M-profile exception, leaving only @@ -438,7 +378,6 @@ static inline int nvic_exec_prio(NVICState *s) bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure) { -<<<<<<< HEAD /* Return true if the requested execution priority is negative * for the specified security state, ie that security state * has an active NMI or HardFault or has set its FAULTMASK. @@ -451,18 +390,6 @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure) if (s->cpu->env.v7m.faultmask[secure]) { return true; -======= - nvic_state *s = (nvic_state *)opaque; - s->systick.control |= SYSTICK_COUNTFLAG; - if (s->systick.control & SYSTICK_TICKINT) { - if (!s->in_deep_sleep) { - /* NOTE: In deep sleep mode, all peripherals are off (no clocks), so - * no IRQs should be made pending. Eventually, we should gate all - * peripherals according to deep sleep mode, but SysTick is a good - * important start. */ - armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK); - } ->>>>>>> 919b29ba7d... Pebble Qemu } if (secure ? s->sec_vectors[ARMV7M_EXCP_HARD].active : @@ -995,34 +922,8 @@ bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure) vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; -<<<<<<< HEAD return vec->enabled && exc_group_prio(s, vec->prio, secure) < running; -======= -/* Set the base priority */ -void armv7m_nvic_set_base_priority(void *opaque, unsigned int priority) -{ - nvic_state *s = (nvic_state *)opaque; - if (priority == 0) { - s->gic.priority_mask[0] = 0x100; - } else { - /* Pay only attention to the priority group when masking interrupts */ - uint32_t group_setting = (s->aircr_reg >> 8) & 0x03; - uint32_t group_mask = (0x0FF << (group_setting + 1)) & 0x0FF; - s->gic.priority_mask[0] = priority & group_mask; /* TODO: Make this more general */ - } - gic_update(&s->gic); -} - -/* The external routines use the hardware vector numbering, ie. the first - IRQ is #16. The internal GIC routines use #32 as the first IRQ. */ -void armv7m_nvic_set_pending(void *opaque, int irq) -{ - nvic_state *s = (nvic_state *)opaque; - if (irq >= 16) - irq += 16; - gic_set_pending_private(&s->gic, 0, irq); ->>>>>>> 919b29ba7d... Pebble Qemu } /* callback when external interrupt line is changed */ @@ -1037,7 +938,6 @@ static void set_irq_level(void *opaque, int n, int level) trace_nvic_set_irq_level(n, level); -<<<<<<< HEAD /* The pending status of an external interrupt is * latched on rising edge and exception handler return. * @@ -1052,28 +952,6 @@ static void set_irq_level(void *opaque, int n, int level) armv7m_nvic_set_pending(s, n, false); } } -======= - /* We can't be in deep sleep mode anymore because we received an interrupt - * Actually, the correct way to do this to match the hardware exactly would be to fall - * out of deep sleep even if an interrupt is pending - regardless if it is active or - * not or masked due to BASEPRI. This would involved moving this reset of deep sleep - * mode higher up the call chain, perhaps in arm_gic.c, where we get notification of - * interrupts that change to pending state. */ - s->in_deep_sleep = false; - if (s->in_standby) { - qemu_set_irq(s->power_out, true); - s->in_standby = false; - } - - irq = gic_acknowledge_irq(&s->gic, 0, MEMTXATTRS_UNSPECIFIED); - if (irq == 1023) { - hw_error("Interrupt but no vector\n"); - } - if (irq >= 32) { - irq -= 16; - } - return irq; ->>>>>>> 919b29ba7d... Pebble Qemu } /* callback when external NMI line is changed */ @@ -1094,46 +972,7 @@ static void nvic_nmi_trigger(void *opaque, int n, int level) } } -<<<<<<< HEAD static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) -======= -void armv7m_nvic_cpu_executed_wfi(void *opaque) -{ - nvic_state *s = (nvic_state *)opaque; - if ((s->scr_reg & SCR_REG_SLEEPDEEP) != 0) { - s->in_deep_sleep = true; - if (s->stm32_pwr_prop && f2xx_pwr_powerdown_deepsleep(s->stm32_pwr_prop)) { - s->in_standby = true; - // For now, this is an easy way to disable nearly all interrupts from waking up - // the CPU. Technically, this is not correct and we should allow specific ones - // through (some RTC interrupts, etc.). - armv7m_nvic_set_base_priority(opaque, 0x01); - - // Inform peripherals that the power is off - qemu_set_irq(s->power_out, false); - } - } -} - -// ----------------------------------------------------------------------------- -// Called when the WKUP pin changes state (GPIO A0) -static void nvic_wakeup_in_cb(void *opaque, int n, int level) -{ - nvic_state *s = (nvic_state *)opaque; - - // If we are in standby mode, wake up the CPU - if (level && s->in_standby) { - s->in_standby = false; - s->in_deep_sleep = false; - qemu_set_irq(s->power_out, true); - qemu_set_irq(s->cpu_wakeup_out, level); - } else if (!level) { - qemu_set_irq(s->cpu_wakeup_out, level); - } -} - -static uint32_t nvic_readl(nvic_state *s, uint32_t offset) ->>>>>>> 919b29ba7d... Pebble Qemu { ARMCPU *cpu = s->cpu; uint32_t val; @@ -1214,7 +1053,6 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) /* STTNS: RES0 for the Main Extension */ return val; case 0xd08: /* Vector Table Offset. */ -<<<<<<< HEAD return cpu->env.v7m.vecbase[attrs.secure]; case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */ val = 0xfa050000 | (s->prigroup[attrs.secure] << 8); @@ -1247,19 +1085,6 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { goto bad_offset; } -======= - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.vecbase; - case 0xd0c: /* Application Interrupt/Reset Control. */ - return 0xfa050000 | s->aircr_reg; - case 0xd10: /* System Control. */ - return s->scr_reg; - break; - case 0xd14: /* Configuration Control. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.ccr; - case 0xd24: /* System Handler Status. */ ->>>>>>> 919b29ba7d... Pebble Qemu val = 0; if (attrs.secure) { if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { @@ -1371,7 +1196,6 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) val |= (1 << 8); } return val; -<<<<<<< HEAD case 0xd2c: /* Hard Fault Status. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; @@ -1397,26 +1221,6 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) /* TODO: Implement fault status registers. */ qemu_log_mask(LOG_UNIMP, "Aux Fault status registers unimplemented\n"); -======= - case 0xd28: /* Configurable Fault Status. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.cfsr; - case 0xd2c: /* Hard Fault Status. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.hfsr; - case 0xd30: /* Debug Fault Status. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.dfsr; - case 0xd34: /* MemManage Address. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.mmfar; - case 0xd38: /* Bus Fault Address. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.bfar; - case 0xd3c: /* Aux Fault Status. */ - /* TODO: Implement fault status registers. */ - qemu_log_mask(LOG_UNIMP, "AUX fault status registers unimplemented\n"); ->>>>>>> 919b29ba7d... Pebble Qemu return 0; case 0xd40: /* PFR0. */ return cpu->id_pfr0; @@ -1443,7 +1247,6 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) case 0xd6c: /* ISAR3. */ return cpu->isar.id_isar3; case 0xd70: /* ISAR4. */ -<<<<<<< HEAD return cpu->isar.id_isar4; case 0xd74: /* ISAR5. */ return cpu->isar.id_isar5; @@ -1656,42 +1459,6 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) return cpu->isar.mvfr1; case 0xf48: /* MVFR2 */ return cpu->isar.mvfr2; -======= - return 0x01310102; - case 0xd90: /* MPU type register. */ - cpu = ARM_CPU(current_cpu); - return cpu->pmsav7_dregion << 8; - case 0xd94: /* MPU control register. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.v7m.mpu_ctrl; - case 0xd98: /* MPU_RNR. */ - cpu = ARM_CPU(current_cpu); - return cpu->env.cp15.c6_rgnr; - case 0xd9c: /* MPU_RBAR: MPU region base address register. */ - case 0xda4: /* MPU_RBAR_A1. */ - case 0xdac: /* MPU_RBAR_A2. */ - case 0xdb4: /* MPU_RBAR_A3. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - return 0; - } - val = cpu->env.pmsav7.drbar[cpu->env.cp15.c6_rgnr]; - val |= (cpu->env.cp15.c6_rgnr ) & 0xf; - return val; - case 0xda0: /* MPU_RASR: MPU region attribute and size register. */ - case 0xda8: /* MPU_RASR_A1. */ - case 0xdb0: /* MPU_RASR_A2. */ - case 0xdb8: /* MPU_RASR_A3. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - return 0; - } - val = cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr]; - val <<= 16; - val |= cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]; - return val; - /* TODO: Implement debug registers. */ ->>>>>>> 919b29ba7d... Pebble Qemu default: bad_offset: qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); @@ -2118,7 +1885,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, cpu->env.sau.rnr = value; } break; -<<<<<<< HEAD case 0xddc: /* SAU_RBAR */ { int region = cpu->env.sau.rnr; @@ -2128,24 +1894,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } if (!attrs.secure) { return; -======= - case 0xd08: /* Vector Table Offset. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.vecbase = value & 0xffffff80; - break; - case 0xd0c: /* Application Interrupt/Reset Control. */ - if ((value >> 16) == 0x05fa) { - if (value & 4) { - qemu_irq_pulse(s->sysresetreq); - } - if (value & 2) { - qemu_log_mask(LOG_UNIMP, "VECTCLRACTIVE unimplemented\n"); - } - if (value & 1) { - qemu_system_reset_request(); - } - s->aircr_reg = value & 0x00700; /* keep only the bits we suport */ ->>>>>>> 919b29ba7d... Pebble Qemu } if (region >= cpu->sau_sregion) { return; @@ -2153,7 +1901,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, cpu->env.sau.rbar[region] = value & ~0x1f; tlb_flush(CPU(cpu)); break; -<<<<<<< HEAD } case 0xde0: /* SAU_RLAR */ { @@ -2170,14 +1917,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } cpu->env.sau.rlar[region] = value & ~0x1c; tlb_flush(CPU(cpu)); -======= - case 0xd10: /* System Control. */ - s->scr_reg = value; - break; - case 0xd14: /* Configuration Control. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.ccr = value & CCR_STKALIGN; ->>>>>>> 919b29ba7d... Pebble Qemu break; } case 0xde4: /* SFSR */ @@ -2189,7 +1928,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } cpu->env.v7m.sfsr &= ~value; /* W1C */ break; -<<<<<<< HEAD case 0xde8: /* SFAR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; @@ -2198,104 +1936,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, return; } cpu->env.v7m.sfsr = value; -======= - case 0xd28: /* Configurable Fault Status. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.cfsr &= ~value; - DPRINTF("writel:cfsr now: %08X\n", cpu->env.v7m.cfsr); - break; - case 0xd2c: /* Hard Fault Status. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.hfsr &= ~value; - DPRINTF("writel:hfsr now: %08X\n", cpu->env.v7m.hfsr); - break; - case 0xd30: /* Debug Fault Status. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.dfsr &= ~value; - DPRINTF("writel:dfsr now: %08X\n", cpu->env.v7m.dfsr); - break; - case 0xd34: /* Mem Manage Address. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.mmfar = value; - DPRINTF("writel:mmfar now: %08X\n", cpu->env.v7m.mmfar); - break; - case 0xd38: /* Bus Fault Address. */ - cpu = ARM_CPU(current_cpu); - cpu->env.v7m.bfar = value; - DPRINTF("writel:bfar now: %08X\n", cpu->env.v7m.bfar); - break; - case 0xd3c: /* Aux Fault Status. */ - qemu_log_mask(LOG_UNIMP, - "NVIC: AUX fault status registers unimplemented\n"); - break; - case 0xd94: /* MPU control register. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - DPRINTF("writel:mpu_ctrl -- no regions!\n"); - break; - } - cpu->env.v7m.mpu_ctrl = value & 0x7; - if (cpu->env.v7m.mpu_ctrl & MPU_CTRL_ENABLE) { - cpu->env.cp15.sctlr_ns |= SCTLR_M; - } else { - cpu->env.cp15.sctlr_ns &= ~SCTLR_M; - } - /* TODO: mimic MPU_CTRL_HFNMIENA */ - if (cpu->env.v7m.mpu_ctrl & MPU_CTRL_PRIVDEFENA) { - cpu->env.cp15.sctlr_ns |= SCTLR_BR; - } else { - cpu->env.cp15.sctlr_ns &= ~SCTLR_BR; - } - /* This may enable/disable the MMU, so do a TLB flush. */ - DPRINTF("writel:mpu_ctrl now: %08X\n", cpu->env.v7m.mpu_ctrl); - DPRINTF("writel:sctlr_ns now: %016llX\n", cpu->env.cp15.sctlr_ns); - tlb_flush(CPU(cpu), 1); - break; - case 0xd98: /* MPU_RNR. */ - cpu = ARM_CPU(current_cpu); - value &= 0xff; - if (value < cpu->pmsav7_dregion) { - cpu->env.cp15.c6_rgnr = value; - } - DPRINTF("writel:mpu_rnr, region now: %u\n", cpu->env.cp15.c6_rgnr); - break; - case 0xd9c: /* MPU_RBAR: MPU region base address register. */ - case 0xda4: /* MPU_RBAR_A1. */ - case 0xdac: /* MPU_RBAR_A2. */ - case 0xdb4: /* MPU_RBAR_A3. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - DPRINTF("writel:mpu_rbar (%02X) -- no regions!\n", offset); - break; - } - if (value & 0x10) { - /* region update */ - uint32_t region = value & 0x0f; - if (region < cpu->pmsav7_dregion) { - cpu->env.cp15.c6_rgnr = region; - } - DPRINTF("writel:mpu_rbar (%04X), region now: %u\n", offset, cpu->env.cp15.c6_rgnr); - } - value &= ~0x1f; - cpu->env.pmsav7.drbar[cpu->env.cp15.c6_rgnr] = value; - DPRINTF("writel:mpu_rbar (%04X), region(%u) now %08X\n", offset, cpu->env.cp15.c6_rgnr, cpu->env.pmsav7.drbar[cpu->env.cp15.c6_rgnr]); - tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ - break; - case 0xda0: /* MPU_RSAR: MPU region attribute and size register. */ - case 0xda8: /* MPU_RSAR_A1. */ - case 0xdb0: /* MPU_RSAR_A2. */ - case 0xdb8: /* MPU_RSAR_A3. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - DPRINTF("writel:mpu_rsar (%02X) -- no regions!\n", offset); - break; - } - cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr] = value >> 16; - cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr] = value & 0xffff; - DPRINTF("writel:mpu_rsar (%04X), region(%u), dracr now %04X\n", offset, cpu->env.cp15.c6_rgnr, cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr]); - DPRINTF("writel:mpu_rsar (%04X), region(%u), drsr now %04X\n", offset, cpu->env.cp15.c6_rgnr, cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]); - tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ ->>>>>>> 919b29ba7d... Pebble Qemu break; case 0xf00: /* Software Triggered Interrupt Register */ { @@ -2459,7 +2099,6 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, uint32_t offset = addr; unsigned i, startvec, end; uint32_t val; - ARMCPU *cpu; if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) { /* Generate BusFault for unprivileged accesses */ @@ -2538,7 +2177,6 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, } val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank)); } -<<<<<<< HEAD break; case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */ if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) { @@ -2558,25 +2196,6 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK; } val = extract32(val, (offset - 0xd28) * 8, size * 8); -======= - return val; - case 0xd28 ... 0xd2b: /* Configurable Fault Status. */ - cpu = ARM_CPU(current_cpu); - return extract32(cpu->env.v7m.cfsr, (offset - 0xd28) * 8, size * 8); - case 0xda0 ... 0xdb7: /* MPU_RSAR and aliases. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - break; - } - if ((size == 2) && (offset & 7) == 0) { - val = cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]; - return val & 0xffff; - } - if ((size == 2) && (offset & 7) == 2) { - val = cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr]; - return val & 0xffff; - } ->>>>>>> 919b29ba7d... Pebble Qemu break; case 0xfe0 ... 0xfff: /* ID. */ if (offset & 3) { @@ -2607,7 +2226,6 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, { NVICState *s = (NVICState *)opaque; uint32_t offset = addr; -<<<<<<< HEAD unsigned i, startvec, end; unsigned setval = 0; @@ -2617,10 +2235,6 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, /* Generate BusFault for unprivileged accesses */ return MEMTX_ERROR; } -======= - int i; - ARMCPU *cpu; ->>>>>>> 919b29ba7d... Pebble Qemu switch (offset) { case 0x100 ... 0x13f: /* NVIC Set enable */ @@ -2684,7 +2298,6 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, } set_prio(s, hdlidx, sbank, newprio); } -<<<<<<< HEAD nvic_irq_update(s); goto exit_ok; case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */ @@ -2710,43 +2323,6 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK); } goto exit_ok; -======= - gic_update(&s->gic); - return; - case 0xd28 ... 0xd2b: /* Configurable Fault Status. */ - if (size == 1) { - value <<= (offset - 0xd28) * 8; - offset &= ~3; - size = 4; - break; - } - if ((size == 2) && ((offset & 1) == 0)) { - value <<= (offset - 0xd28) * 8; - offset &= ~3; - size = 4; - break; - } - break; - case 0xda0 ... 0xdb7: /* MPU_RSAR and aliases. */ - cpu = ARM_CPU(current_cpu); - if (cpu->pmsav7_dregion == 0) { - break; - } - if ((size == 2) && (offset & 7) == 0) { - value |= cpu->env.pmsav7.dracr[cpu->env.cp15.c6_rgnr] << 16; - offset &= ~2; - size = 4; - break; - } - if ((size == 2) && (offset & 7) == 2) { - value <<= 16; - value |= cpu->env.pmsav7.drsr[cpu->env.cp15.c6_rgnr]; - offset &= ~2; - size = 4; - break; - } - break; ->>>>>>> 919b29ba7d... Pebble Qemu } if (size == 4) { nvic_writel(s, offset, value, attrs); @@ -3022,7 +2598,6 @@ static void armv7m_nvic_reset(DeviceState *dev) * We updated state that affects the CPU's MMUidx and thus its hflags; * and we can't guarantee that we run before the CPU reset function. */ -<<<<<<< HEAD arm_rebuild_hflags(&s->cpu->env); } @@ -3039,18 +2614,6 @@ static void nvic_systick_trigger(void *opaque, int n, int level) */ armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, n); } -======= - s->gic.cpu_ctlr[0] = GICC_CTLR_EN_GRP0; - s->gic.priority_mask[0] = 0x100; - /* The NVIC as a whole is always enabled. */ - s->gic.ctlr = 1; - systick_reset(s); - - s->scr_reg = 0; - s->in_deep_sleep = false; - s->in_standby = false; - qemu_set_irq(s->power_out, true); ->>>>>>> 919b29ba7d... Pebble Qemu } static void armv7m_nvic_realize(DeviceState *dev, Error **errp) @@ -3139,7 +2702,6 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s, "nvic_sysregs", 0x1000); memory_region_add_subregion(&s->container, 0, &s->sysregmem); -<<<<<<< HEAD memory_region_init_io(&s->systickmem, OBJECT(s), &nvic_systick_ops, s, @@ -3161,30 +2723,6 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) } sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container); -======= - /* Alias the GIC region so we can get only the section of it - * we need, and layer it on top of the system register region. - */ - memory_region_init_alias(&s->gic_iomem_alias, OBJECT(s), - "nvic-gic", &s->gic.iomem, - 0x100, 0xc00); - memory_region_add_subregion_overlap(&s->container, 0x100, - &s->gic_iomem_alias, 1); - /* Map the whole thing into system memory at the location required - * by the v7M architecture. - */ - memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container); - s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s); - - // Create the input handler to be notified when the WKUP pin gets asserted - qdev_init_gpio_in_named(dev, nvic_wakeup_in_cb, "wakeup_in", 1); - - // This is the handler that will wakeup the CPU - qdev_init_gpio_out_named(dev, &s->cpu_wakeup_out, "wakeup_out", 1); - - // This is the handler that informs peripherals that the power is on/off - qdev_init_gpio_out_named(dev, &s->power_out, "power_out", 1); ->>>>>>> 919b29ba7d... Pebble Qemu } static void armv7m_nvic_instance_init(Object *obj) @@ -3212,11 +2750,6 @@ static void armv7m_nvic_instance_init(Object *obj) qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1); } -static Property armv7m_nvic_properties[] = { - DEFINE_PROP_PTR("stm32_pwr", nvic_state, stm32_pwr_prop), - DEFINE_PROP_END_OF_LIST(), -}; - static void armv7m_nvic_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -3225,7 +2758,6 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, props_nvic); dc->reset = armv7m_nvic_reset; dc->realize = armv7m_nvic_realize; - dc->props = armv7m_nvic_properties; } static const TypeInfo armv7m_nvic_info = { diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 8589ebe8a04d3..6d91cd8309d5d 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -1958,14 +1958,6 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size) return -1; } - /* Pad to minimum Ethernet frame length */ - if (size < sizeof(min_buf)) { - memcpy(min_buf, buf, size); - memset(&min_buf[size], 0, sizeof(min_buf) - size); - buf = min_buf; - size = sizeof(min_buf); - } - if (s->peer_has_vhdr) { net_rx_pkt_set_vhdr(s->rx_pkt, (struct virtio_net_hdr *)buf); buf += sizeof(struct virtio_net_hdr); diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs index 9b1637f2b2102..49480ed662242 100644 --- a/hw/ssi/Makefile.objs +++ b/hw/ssi/Makefile.objs @@ -6,12 +6,8 @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o common-obj-$(CONFIG_MSF2) += mss-spi.o -<<<<<<< HEAD common-obj-$(CONFIG_OMAP) += omap_spi.o common-obj-$(CONFIG_IMX) += imx_spi.o -======= -obj-$(CONFIG_OMAP) += omap_spi.o -obj-y += stm32f2xx_spi.o -obj-y += stm32f412_qspi.o ->>>>>>> 919b29ba7d... Pebble Qemu +common-obj-y += stm32f2xx_spi_pbl.o +common-obj-y += stm32f412_qspi.o diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c index 58fe4780c3a7f..cd6e8443db300 100644 --- a/hw/ssi/stm32f2xx_spi.c +++ b/hw/ssi/stm32f2xx_spi.c @@ -1,12 +1,7 @@ -<<<<<<< HEAD /* * STM32F405 SPI * * Copyright (c) 2014 Alistair Francis -======= -/*- - * Copyright (c) 2013 ->>>>>>> 919b29ba7d... Pebble Qemu * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,7 +15,6 @@ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -<<<<<<< HEAD * 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, @@ -167,145 +161,12 @@ static void stm32f2xx_spi_write(void *opaque, hwaddr addr, default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr); -======= - * 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. - */ -/* - * QEMU model of the stm32f2xx SPI controller. - */ - -#include "hw/sysbus.h" -#include "hw/arm/stm32.h" -#include "hw/ssi.h" - -#define R_CR1 (0x00 / 4) -#define R_CR1_DFF (1 << 11) -#define R_CR1_LSBFIRST (1 << 7) -#define R_CR1_SPE (1 << 6) -#define R_CR2 (0x04 / 4) - -#define R_SR (0x08 / 4) -#define R_SR_RESET 0x0002 -#define R_SR_MASK 0x01FF -#define R_SR_OVR (1 << 6) -#define R_SR_TXE (1 << 1) -#define R_SR_RXNE (1 << 0) - -#define R_DR (0x0C / 4) -#define R_CRCPR (0x10 / 4) -#define R_CRCPR_RESET 0x0007 -#define R_RXCRCR (0x14 / 4) -#define R_TXCRCR (0x18 / 4) -#define R_I2SCFGR (0x1C / 4) -#define R_I2SPR (0x20 / 4) -#define R_I2SPR_RESET 0x0002 -#define R_MAX (0x24 / 4) - -typedef struct stm32f2xx_spi_s { - SysBusDevice busdev; - MemoryRegion iomem; - qemu_irq irq; - - SSIBus *spi; - - stm32_periph_t periph; - - int32_t rx; - int rx_full; - uint16_t regs[R_MAX]; -} Stm32Spi; - -static uint64_t -stm32f2xx_spi_read(void *arg, hwaddr offset, unsigned size) -{ - Stm32Spi *s = arg; - uint16_t r = UINT16_MAX; - - if (!(size == 1 || size == 2 || size == 4 || (offset & 0x3) != 0)) { - STM32_BAD_REG(offset, size); - } - offset >>= 2; - if (offset < R_MAX) { - r = s->regs[offset]; - } else { - stm32_hw_warn("Out of range SPI write, offset 0x%x", (unsigned)offset<<2); - } - switch (offset) { - case R_DR: - s->regs[R_SR] &= ~R_SR_RXNE; - } - return r; -} - -static uint8_t -bitswap(uint8_t val) -{ - return ((val * 0x0802LU & 0x22110LU) | (val * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; -} - -static void -stm32f2xx_spi_write(void *arg, hwaddr addr, uint64_t data, unsigned size) -{ - struct stm32f2xx_spi_s *s = (struct stm32f2xx_spi_s *)arg; - int offset = addr & 0x3; - - /* SPI registers are all at most 16 bits wide */ - data &= 0xFFFFF; - addr >>= 2; - - switch (size) { - case 1: - data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); - break; - case 2: - data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); - break; - case 4: - break; - default: - abort(); - } - - switch (addr) { - case R_CR1: - if ((data & R_CR1_DFF) != s->regs[R_CR1] && (s->regs[R_CR1] & R_CR1_SPE) != 0) - qemu_log_mask(LOG_GUEST_ERROR, "cannot change DFF with SPE set\n"); - if (data & R_CR1_DFF) - qemu_log_mask(LOG_UNIMP, "f2xx DFF 16-bit mode not implemented\n"); - s->regs[R_CR1] = data; - break; - case R_DR: - s->regs[R_SR] &= ~R_SR_TXE; - if (s->regs[R_SR] & R_SR_RXNE) { - s->regs[R_SR] |= R_SR_OVR; - } - if (s->regs[R_CR1] & R_CR1_LSBFIRST) { - s->regs[R_DR] = bitswap(ssi_transfer(s->spi, bitswap(data))); - } else { - s->regs[R_DR] = ssi_transfer(s->spi, data); - } - - s->regs[R_SR] |= R_SR_RXNE; - s->regs[R_SR] |= R_SR_TXE; - break; - default: - if (addr < ARRAY_SIZE(s->regs)) { - s->regs[addr] = data; - } else { - STM32_BAD_REG(addr, size); - } ->>>>>>> 919b29ba7d... Pebble Qemu } } static const MemoryRegionOps stm32f2xx_spi_ops = { .read = stm32f2xx_spi_read, .write = stm32f2xx_spi_write, -<<<<<<< HEAD .endianness = DEVICE_NATIVE_ENDIAN, }; @@ -358,80 +219,8 @@ static const TypeInfo stm32f2xx_spi_info = { }; static void stm32f2xx_spi_register_types(void) -======= - .endianness = DEVICE_NATIVE_ENDIAN -}; - -static void -stm32f2xx_spi_reset(DeviceState *dev) -{ - struct stm32f2xx_spi_s *s = FROM_SYSBUS(struct stm32f2xx_spi_s, - SYS_BUS_DEVICE(dev)); - - s->regs[R_SR] = R_SR_RESET; - switch (s->periph) { - case 0: - break; - case 1: - break; - default: - break; - } -} - -static int -stm32f2xx_spi_init(SysBusDevice *dev) -{ - struct stm32f2xx_spi_s *s = FROM_SYSBUS(struct stm32f2xx_spi_s, dev); - - memory_region_init_io(&s->iomem, NULL, &stm32f2xx_spi_ops, s, "spi", 0x3ff); - sysbus_init_mmio(dev, &s->iomem); - sysbus_init_irq(dev, &s->irq); - s->spi = ssi_create_bus(DEVICE(dev), "ssi"); - - return 0; -} - - -static Property stm32f2xx_spi_properties[] = { - DEFINE_PROP_INT32("periph", struct stm32f2xx_spi_s, periph, -1), - DEFINE_PROP_END_OF_LIST() -}; - -static void -stm32f2xx_spi_class_init(ObjectClass *c, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(c); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); - - sc->init = stm32f2xx_spi_init; - dc->reset = stm32f2xx_spi_reset; - dc->props = stm32f2xx_spi_properties; -} - -static const TypeInfo stm32f2xx_spi_info = { - .name = "stm32f2xx_spi", - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(struct stm32f2xx_spi_s), - .class_init = stm32f2xx_spi_class_init -}; - -static void -stm32f2xx_spi_register_types(void) ->>>>>>> 919b29ba7d... Pebble Qemu { type_register_static(&stm32f2xx_spi_info); } type_init(stm32f2xx_spi_register_types) -<<<<<<< HEAD -======= - -/* - * - */ -/* - * Serial peripheral interface (SPI) RM0033 section 25 - */ - ->>>>>>> 919b29ba7d... Pebble Qemu diff --git a/hw/ssi/stm32f2xx_spi_pbl.c b/hw/ssi/stm32f2xx_spi_pbl.c new file mode 100644 index 0000000000000..24aa3af63caeb --- /dev/null +++ b/hw/ssi/stm32f2xx_spi_pbl.c @@ -0,0 +1,224 @@ +/*- + * Copyright (c) 2013 + * + * 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. + */ +/* + * QEMU model of the stm32f2xx SPI controller. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/sysbus.h" +#include "hw/arm/stm32.h" +#include "hw/ssi/ssi.h" +#include "hw/qdev-properties.h" +#include "hw/hw.h" + +#define R_CR1 (0x00 / 4) +#define R_CR1_DFF (1 << 11) +#define R_CR1_LSBFIRST (1 << 7) +#define R_CR1_SPE (1 << 6) +#define R_CR2 (0x04 / 4) + +#define R_SR (0x08 / 4) +#define R_SR_RESET 0x0002 +#define R_SR_MASK 0x01FF +#define R_SR_OVR (1 << 6) +#define R_SR_TXE (1 << 1) +#define R_SR_RXNE (1 << 0) + +#define R_DR (0x0C / 4) +#define R_CRCPR (0x10 / 4) +#define R_CRCPR_RESET 0x0007 +#define R_RXCRCR (0x14 / 4) +#define R_TXCRCR (0x18 / 4) +#define R_I2SCFGR (0x1C / 4) +#define R_I2SPR (0x20 / 4) +#define R_I2SPR_RESET 0x0002 +#define R_MAX (0x24 / 4) + +typedef struct stm32f2xx_spi_s { + SysBusDevice busdev; + MemoryRegion iomem; + qemu_irq irq; + + SSIBus *spi; + + stm32_periph_t periph; + + int32_t rx; + int rx_full; + uint16_t regs[R_MAX]; +} Stm32Spi; + +static uint64_t +stm32f2xx_spi_read(void *arg, hwaddr offset, unsigned size) +{ + Stm32Spi *s = arg; + uint16_t r = UINT16_MAX; + + if (!(size == 1 || size == 2 || size == 4 || (offset & 0x3) != 0)) { + STM32_BAD_REG(offset, size); + } + offset >>= 2; + if (offset < R_MAX) { + r = s->regs[offset]; + } else { + stm32_hw_warn("Out of range SPI write, offset 0x%x", (unsigned)offset<<2); + } + switch (offset) { + case R_DR: + s->regs[R_SR] &= ~R_SR_RXNE; + } + return r; +} + +static uint8_t +bitswap(uint8_t val) +{ + return ((val * 0x0802LU & 0x22110LU) | (val * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; +} + +static void +stm32f2xx_spi_write(void *arg, hwaddr addr, uint64_t data, unsigned size) +{ + struct stm32f2xx_spi_s *s = (struct stm32f2xx_spi_s *)arg; + int offset = addr & 0x3; + + /* SPI registers are all at most 16 bits wide */ + data &= 0xFFFFF; + addr >>= 2; + + switch (size) { + case 1: + data = (s->regs[addr] & ~(0xff << (offset * 8))) | data << (offset * 8); + break; + case 2: + data = (s->regs[addr] & ~(0xffff << (offset * 8))) | data << (offset * 8); + break; + case 4: + break; + default: + abort(); + } + + switch (addr) { + case R_CR1: + if ((data & R_CR1_DFF) != s->regs[R_CR1] && (s->regs[R_CR1] & R_CR1_SPE) != 0) + qemu_log_mask(LOG_GUEST_ERROR, "cannot change DFF with SPE set\n"); + if (data & R_CR1_DFF) + qemu_log_mask(LOG_UNIMP, "f2xx DFF 16-bit mode not implemented\n"); + s->regs[R_CR1] = data; + break; + case R_DR: + s->regs[R_SR] &= ~R_SR_TXE; + if (s->regs[R_SR] & R_SR_RXNE) { + s->regs[R_SR] |= R_SR_OVR; + } + if (s->regs[R_CR1] & R_CR1_LSBFIRST) { + s->regs[R_DR] = bitswap(ssi_transfer(s->spi, bitswap(data))); + } else { + s->regs[R_DR] = ssi_transfer(s->spi, data); + } + + s->regs[R_SR] |= R_SR_RXNE; + s->regs[R_SR] |= R_SR_TXE; + break; + default: + if (addr < ARRAY_SIZE(s->regs)) { + s->regs[addr] = data; + } else { + STM32_BAD_REG(addr, size); + } + } +} + +static const MemoryRegionOps stm32f2xx_spi_ops = { + .read = stm32f2xx_spi_read, + .write = stm32f2xx_spi_write, + .endianness = DEVICE_NATIVE_ENDIAN +}; + +static void +stm32f2xx_spi_reset(DeviceState *dev) +{ + struct stm32f2xx_spi_s *s = STM32F2XX_SPI(dev); + + s->regs[R_SR] = R_SR_RESET; + switch (s->periph) { + case 0: + break; + case 1: + break; + default: + break; + } +} + +static void +stm32f2xx_spi_init(Object *obj) +{ + struct stm32f2xx_spi_s *s = STM32F2XX_SPI(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->iomem, NULL, &stm32f2xx_spi_ops, s, "spi", 0x3ff); + sysbus_init_mmio(dev, &s->iomem); + sysbus_init_irq(dev, &s->irq); + s->spi = ssi_create_bus(DEVICE(dev), "ssi"); +} + + +static Property stm32f2xx_spi_properties[] = { + DEFINE_PROP_INT32("periph", struct stm32f2xx_spi_s, periph, -1), + DEFINE_PROP_END_OF_LIST() +}; + +static void +stm32f2xx_spi_class_init(ObjectClass *c, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(c); + + dc->reset = stm32f2xx_spi_reset; + + device_class_set_props(dc, stm32f2xx_spi_properties); +} + +static const TypeInfo stm32f2xx_spi_info = { + .name = TYPE_STM32F2XX_SPI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(struct stm32f2xx_spi_s), + .instance_init = stm32f2xx_spi_init, + .class_init = stm32f2xx_spi_class_init +}; + +static void +stm32f2xx_spi_register_types(void) +{ + type_register_static(&stm32f2xx_spi_info); +} + +type_init(stm32f2xx_spi_register_types) + +/* + * + */ +/* + * Serial peripheral interface (SPI) RM0033 section 25 + */ diff --git a/hw/ssi/stm32f412_qspi.c b/hw/ssi/stm32f412_qspi.c index 7ded2c0ce7528..de86a1d4144eb 100644 --- a/hw/ssi/stm32f412_qspi.c +++ b/hw/ssi/stm32f412_qspi.c @@ -1,6 +1,9 @@ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/arm/stm32.h" -#include "hw/ssi.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/ssi/ssi.h" #ifndef STM32F412_QSPI_ERR_DEBUG #define STM32F412_QSPI_ERR_DEBUG 0 @@ -290,18 +293,18 @@ static const MemoryRegionOps stm32f412_qspi_ops = { static void stm32f412_qspi_reset(DeviceState *dev) { - struct stm32f412_qspi_s *s = FROM_SYSBUS(struct stm32f412_qspi_s, - SYS_BUS_DEVICE(dev)); + struct stm32f412_qspi_s *s = STM32F412_QSPI(dev); //s->regs[R_SR] = R_SR_RESET; s->cs_state = CS_STATE_HIGH; s->tx_remaining = 0; } -static int -stm32f412_qspi_init(SysBusDevice *dev) +static void +stm32f412_qspi_init(Object *obj) { - struct stm32f412_qspi_s *s = FROM_SYSBUS(struct stm32f412_qspi_s, dev); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + struct stm32f412_qspi_s *s = STM32F412_QSPI(dev); memory_region_init_io(&s->iomem, NULL, &stm32f412_qspi_ops, s, "qspi", 0x3ff); sysbus_init_mmio(dev, &s->iomem); @@ -312,8 +315,6 @@ stm32f412_qspi_init(SysBusDevice *dev) s->tx_remaining = 0; qdev_init_gpio_out_named(DEVICE(dev), &s->cs_irq, "qspi-gpio-cs", 1); - - return 0; } static Property stm32f412_qspi_properties[] = { @@ -324,17 +325,16 @@ static void stm32f412_qspi_class_init(ObjectClass *c, void *data) { DeviceClass *dc = DEVICE_CLASS(c); - SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(c); - sc->init = stm32f412_qspi_init; dc->reset = stm32f412_qspi_reset; - dc->props = stm32f412_qspi_properties; + device_class_set_props(dc, stm32f412_qspi_properties); } static const TypeInfo stm32f412_qspi_info = { - .name = "stm32f412_qspi", + .name = TYPE_STM32F412_QSPI, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(struct stm32f412_qspi_s), + .instance_init = stm32f412_qspi_init, .class_init = stm32f412_qspi_class_init }; diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 65f21d7b75e7a..ce2b48b88bca5 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -14,7 +14,6 @@ #include "target/arm/cpu-qom.h" #include "qemu/notify.h" -<<<<<<< HEAD:include/hw/arm/boot.h typedef enum { ARM_ENDIANNESS_UNKNOWN = 0, ARM_ENDIANNESS_LE, @@ -31,24 +30,6 @@ typedef enum { * Load the guest image for an ARMv7M system. This must be called by * any ARMv7M board. (This is necessary to ensure that the CPU resets * correctly on system reset, as well as for kernel loading.) -======= -/* armv7m.c */ -DeviceState *armv7m_init(Object *parent, MemoryRegion *system_memory, - int flash_size, int sram_size, int num_irq, - const char *kernel_filename, const char *cpu_model); - -DeviceState *armv7m_translated_init(Object *parent, MemoryRegion *system_memory, - int flash_size, int sram_size, int num_irq, - const char *kernel_filename, - uint64_t (*translate_fn)(void *, uint64_t), - void *translate_opaque, - const char *cpu_model, - ARMCPU **cpu_device); - -/* - * struct used as a parameter of the arm_load_kernel machine init - * done notifier ->>>>>>> 919b29ba7d... Pebble Qemu:include/hw/arm/arm.h */ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size); diff --git a/include/hw/arm/stm32.h b/include/hw/arm/stm32.h index 0ad9a8e044163..ebcd1da546f7a 100644 --- a/include/hw/arm/stm32.h +++ b/include/hw/arm/stm32.h @@ -23,12 +23,94 @@ #define STM32_H #include "qemu/timer.h" -#include "hw/arm/arm.h" #include "qemu-common.h" #include "hw/sysbus.h" +#include "hw/arm/boot.h" #include "qemu/log.h" -#include "sysemu/char.h" +#include "chardev/char-fe.h" +#include "hw/qdev-properties.h" +#include "hw/core/cpu.h" +#include "qapi/error.h" +#define qdev_prop_set_ptr(a, b, c) qdev_prop_set_uint64((a), (b), (uint64_t)(c)) +#define DEFINE_PROP_PTR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_uint64, void*) + +#define TYPE_STM32_FLASH "stm32_flash" +#define STM32_FLASH(obj) \ + OBJECT_CHECK(Stm32Flash, (obj), TYPE_STM32_FLASH) + +#define TYPE_STM32_ADC "stm32f2xx_adc" +#define STM32_ADC(obj) \ + OBJECT_CHECK(stm32_adc, (obj), TYPE_STM32_ADC) + +#define TYPE_STM32F2XX_CRC "f2xx_crc" +#define STM32F2XX_CRC(obj) \ + OBJECT_CHECK(f2xx_crc, (obj), TYPE_STM32F2XX_CRC) + +#define TYPE_STM32F2XX_DMA "f2xx_dma" +#define STM32F2XX_DMA(obj) \ + OBJECT_CHECK(f2xx_dma, (obj), TYPE_STM32F2XX_DMA) + +#define TYPE_STM32F412_QSPI "stm32f412_qspi" +#define STM32F412_QSPI(obj) \ + OBJECT_CHECK(struct stm32f412_qspi_s, (obj), TYPE_STM32F412_QSPI) + +#define TYPE_STM32F2XX_SPI "stm32f2xx_spi" +#define STM32F2XX_SPI(obj) \ + OBJECT_CHECK(struct stm32f2xx_spi_s, (obj), TYPE_STM32F2XX_SPI) + +#define TYPE_STM32F7XX_LPTIM "f7xx_lptim" +#define STM32F7XX_LPTIM(obj) \ + OBJECT_CHECK(f7xx_lptim, (obj), TYPE_STM32F7XX_LPTIM) + +#define TYPE_STM32F2XX_FLASH "f2xx.flash" +#define STM32F2XX_FLASH(obj) \ + OBJECT_CHECK(f2xx_flash_t, (obj), TYPE_STM32F2XX_FLASH) + +#define TYPE_STM32F2XX_GPIO "stm32f2xx_gpio" +#define STM32F2XX_GPIO(obj) \ + OBJECT_CHECK(stm32f2xx_gpio, (obj), TYPE_STM32F2XX_GPIO) + +#define TYPE_STM32F2XX_RCC "stm32f2xx_rcc" +#define STM32F2XX_RCC(obj) \ + OBJECT_CHECK(Stm32f2xxRcc, (obj), TYPE_STM32F2XX_RCC) + +#define TYPE_STM32F2XX_TIM "f2xx_tim" +#define STM32F2XX_TIM(obj) \ + OBJECT_CHECK(f2xx_tim, (obj), TYPE_STM32F2XX_TIM) + +#define TYPE_STM32F1XX_RCC "stm32f1xx_rcc" +#define STM32F1XX_RCC(obj) \ + OBJECT_CHECK(Stm32f1xxRcc, (obj), TYPE_STM32F1XX_RCC) + +#define TYPE_STM32F2XX_SYSCFG "stm32f2xx_syscfg" +#define STM32F2XX_SYSCFG(obj) \ + OBJECT_CHECK(Stm32Syscfg, (obj), TYPE_STM32F2XX_SYSCFG) + +#define TYPE_STM32F2XX_SPI_PBL "stm32f2xx_spi_pbl" +#define STM32F2XX_SPI_PBL(obj) \ + OBJECT_CHECK(stm32f2xx_spi_s, (obj), TYPE_STM32F2XX_SPI_PBL) + +#define TYPE_STM32F2XX_RTC "f2xx_rtc" +#define STM32F2XX_RTC(obj) \ + OBJECT_CHECK(f2xx_rtc, (obj), TYPE_STM32F2XX_RTC) + +#define TYPE_STM32F2XX_DUMMY "f2xx_dummy" +#define STM32F2XX_DUMMY(obj) \ + OBJECT_CHECK(f2xx_dummy, (obj), TYPE_STM32F2XX_DUMMY) + +#define TYPE_STM32F2XX_PWR "f2xx_pwr" +#define STM32F2XX_PWR(obj) \ + OBJECT_CHECK(f2xx_pwr, (obj), TYPE_STM32F2XX_PWR) + +#define TYPE_STM32F2XX_I2C "f2xx_i2c" +#define STM32F2XX_I2C(obj) \ + OBJECT_CHECK(f2xx_i2c, (obj), TYPE_STM32F2XX_I2C) + +#define TYPE_STM32F7XX_I2C "stm32f7xx_i2c" +#define STM32F7XX_I2C(obj) \ + OBJECT_CHECK(stm32f7xx_i2c, (obj), TYPE_STM32F7XX_I2C) #define ENUM_STRING(x) [x] = #x #define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0])) @@ -97,36 +179,36 @@ typedef int32_t stm32_periph_t; enum { STM32_PERIPH_UNDEFINED = -1, - STM32_RCC_PERIPH = 0, - STM32_GPIOA, - STM32_GPIOB, - STM32_GPIOC, - STM32_GPIOD, - STM32_GPIOE, - STM32_GPIOF, - STM32_GPIOG, - STM32_GPIOH, - STM32_GPIOI, - STM32_GPIOJ, - STM32_GPIOK, - STM32_SYSCFG, - STM32_AFIO_PERIPH, - STM32_UART1, - STM32_UART2, - STM32_UART3, - STM32_UART4, - STM32_UART5, - STM32_UART6, - STM32_UART7, - STM32_UART8, - STM32_ADC1, - STM32_ADC2, - STM32_ADC3, - STM32_DAC, - STM32_TIM1, - STM32_TIM2, - STM32_TIM3, - STM32_TIM4, + STM32_RCC_PERIPH = 0, // 0 + STM32_GPIOA, // 1 + STM32_GPIOB, // 2 + STM32_GPIOC, // 3 + STM32_GPIOD, // 4 + STM32_GPIOE, // 5 + STM32_GPIOF, // 6 + STM32_GPIOG, // 7 + STM32_GPIOH, // 8 + STM32_GPIOI, // 9 + STM32_GPIOJ, // 10 + STM32_GPIOK, // 11 + STM32_SYSCFG, // 12 + STM32_AFIO_PERIPH, // 13 + STM32_UART1, // 14 + STM32_UART2, // 15 + STM32_UART3, // 16 + STM32_UART4, // 17 + STM32_UART5, // 18 + STM32_UART6, // 19 + STM32_UART7, // 20 + STM32_UART8, // 21 + STM32_ADC1, // 22 + STM32_ADC2, // 23 + STM32_ADC3, // 24 + STM32_DAC, // 25 + STM32_TIM1, // 26 + STM32_TIM2, // 27 + STM32_TIM3, // 28 + STM32_TIM4, // 29 STM32_TIM5, STM32_TIM6, STM32_TIM7, @@ -302,6 +384,9 @@ typedef struct Stm32Exti Stm32Exti; #define TYPE_STM32_EXTI "stm32-exti" #define STM32_EXTI(obj) OBJECT_CHECK(Stm32Exti, (obj), TYPE_STM32_EXTI) +#define TYPE_STM32_EXTI_ALT "stm32-exti-alt" +#define STM32_EXTI_ALT(obj) OBJECT_CHECK(Stm32Exti, (obj), TYPE_STM32_EXTI_ALT) + /* Assigns the specified EXTI line to the specified GPIO. */ void stm32_exti_set_gpio(Stm32Exti *s, unsigned exti_line, const uint8_t gpio_index); @@ -405,12 +490,12 @@ typedef struct Stm32Uart Stm32Uart; * board's pin mapping should be passed in. This will be used to * verify the correct mapping is configured by the software. */ -void stm32_uart_connect(Stm32Uart *s, CharDriverState *chr, +void stm32_uart_connect(Stm32Uart *s, Chardev *chr, uint32_t afio_board_map); /* Low level methods that let you connect a UART device to any other instance * that has read/write handlers. These can be used in place of stm32_uart_connect - * if not connecting to a CharDriverState instance. */ + * if not connecting to a Chardev instance. */ void stm32_uart_set_write_handler(Stm32Uart *s, void *obj, int (*chr_write_handler)(void *chr_write_obj, const uint8_t *buf, int len)); void stm32_uart_get_rcv_handlers(Stm32Uart *s, IOCanReadHandler **can_read, @@ -439,12 +524,12 @@ typedef struct Stm32F7xxUart Stm32F7xxUart; * board's pin mapping should be passed in. This will be used to * verify the correct mapping is configured by the software. */ -void stm32f7xx_uart_connect(Stm32F7xxUart *s, CharDriverState *chr, +void stm32f7xx_uart_connect(Stm32F7xxUart *s, Chardev *chr, uint32_t afio_board_map); /* Low level methods that let you connect a UART device to any other instance * that has read/write handlers. These can be used in place of stm32_uart_connect - * if not connecting to a CharDriverState instance. */ + * if not connecting to a Chardev instance. */ void stm32f7xx_uart_set_write_handler(Stm32F7xxUart *s, void *obj, int (*chr_write_handler)(void *chr_write_obj, const uint8_t *buf, int len)); void stm32f7xx_uart_get_rcv_handlers(Stm32F7xxUart *s, IOCanReadHandler **can_read, @@ -551,4 +636,47 @@ void stm32f7xx_init( struct stm32f7xx *stm, ARMCPU **cpu); +static inline DeviceState * +armv7m_translated_init(Object *parent, MemoryRegion *system_memory, + int flash_size, int sram_size, int num_irq, + const char *kernel_filename, + uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, + const char *cpu_model, + ARMCPU **cpu_device) { + + if (sram_size) { + + MemoryRegion *sram = g_new(MemoryRegion, 1); + memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size, &error_fatal); + memory_region_add_subregion(system_memory, 0x20000000, sram); + } + + DeviceState *armv7m = qdev_create(NULL, "armv7m"); + qdev_prop_set_string(DEVICE(armv7m), "cpu-type", cpu_model); + qdev_prop_set_uint32(DEVICE(armv7m), "num-irq", num_irq); + qdev_prop_set_bit(DEVICE(armv7m), "enable-bitband", true); + object_property_set_link(OBJECT(armv7m), OBJECT(system_memory), + "memory", NULL); + qdev_init_nofail(DEVICE(armv7m)); + + + armv7m_load_kernel(ARM_CPU(first_cpu), kernel_filename, flash_size); + cpu_device = armv7m; + return armv7m; +} + +static inline DeviceState * +armv7m_init(Object *parent, MemoryRegion *system_memory, + int flash_size, int sram_size, int num_irq, + const char *kernel_filename, const char *cpu_model) +{ + ARMCPU *cpu; + return armv7m_translated_init(parent, system_memory, flash_size, sram_size, num_irq, + kernel_filename, NULL, NULL, cpu_model, &cpu); +} + +typedef struct f2xx_flash f2xx_flash_t; +f2xx_flash_t *f2xx_flash_register(BlockBackend *blk, hwaddr base, + hwaddr size); #endif /* STM32_H */ diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h index 2cbf0ed41ecd4..ddfb9fcbb9012 100644 --- a/include/hw/block/flash.h +++ b/include/hw/block/flash.h @@ -27,7 +27,6 @@ MemoryRegion *pflash_cfi01_get_memory(PFlashCFI01 *fl); void pflash_cfi01_legacy_drive(PFlashCFI01 *dev, DriveInfo *dinfo); /* pflash_cfi02.c */ -<<<<<<< HEAD #define TYPE_PFLASH_CFI02 "cfi.pflash02" #define PFLASH_CFI02(obj) \ @@ -47,29 +46,23 @@ PFlashCFI02 *pflash_cfi02_register(hwaddr base, uint16_t unlock_addr0, uint16_t unlock_addr1, int be); -======= -pflash_t *pflash_cfi02_register(hwaddr base, - DeviceState *qdev, const char *name, - hwaddr size, - BlockBackend *blk, uint32_t sector_len, - int nb_blocs, int nb_mappings, int width, - uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3, - uint16_t unlock_addr0, uint16_t unlock_addr1, - int be); + /* pflash_jedec_424.c */ -pflash_t *pflash_jedec_424_register(hwaddr base, - DeviceState *qdev, const char *name, - hwaddr size, - BlockBackend *blk, - uint32_t sector_len, int nb_blocs, uint32_t bank_size, - int bank_width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3, int be); - -MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl); -MemoryRegion *pflash_jedec_424_get_memory(pflash_t *fl); ->>>>>>> 919b29ba7d... Pebble Qemu + +#define TYPE_CFI_PFLASH_JEDEC_424 "cfi.pflash.jedec-42.4" +#define CFI_PFLASH_JEDEC(obj) \ + OBJECT_CHECK(PFlashJedec424, (obj), TYPE_CFI_PFLASH_JEDEC_424) + +typedef struct PFlashJedec424 PFlashJedec424; + +PFlashJedec424 *pflash_jedec_424_register(hwaddr base, + DeviceState *qdev, const char *name, + hwaddr size, + BlockBackend *blk, + uint32_t sector_len, int nb_blocs, uint32_t bank_size, + int bank_width, uint16_t id0, uint16_t id1, + uint16_t id2, uint16_t id3, int be); /* nand.c */ DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id); @@ -103,7 +96,4 @@ uint8_t ecc_digest(ECCState *s, uint8_t sample); void ecc_reset(ECCState *s); extern VMStateDescription vmstate_ecc_state; -typedef struct f2xx_flash f2xx_flash_t; -f2xx_flash_t *f2xx_flash_register(BlockBackend *blk, hwaddr base, - hwaddr size); #endif diff --git a/include/hw/irq.h b/include/hw/irq.h index d4d97f5f5a714..24ba0ece11664 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -53,14 +53,6 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); /* For internal use in qtest. Similar to qemu_irq_split, but operating on an existing vector of qemu_irq. */ -typedef struct IRQInterceptData { - qemu_irq *old_irqs; - int id; -} IRQInterceptData; - -void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, - int id, int n); -void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, - int id, int n); +void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); #endif diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index 44693fb306986..c4a1c0adfa5a1 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -68,14 +68,7 @@ struct SysBusDevice { uint32_t pio[QDEV_MAX_PIO]; }; -<<<<<<< HEAD typedef void FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque); -======= -/* Macros to compensate for lack of type inheritance in C. */ -#define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev) - -typedef int FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque); ->>>>>>> 919b29ba7d... Pebble Qemu void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory); MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n); diff --git a/monitor.c b/monitor.c deleted file mode 100644 index 4e62100805d27..0000000000000 --- a/monitor.c +++ /dev/null @@ -1,4244 +0,0 @@ -/* - * QEMU monitor - * - * Copyright (c) 2003-2004 Fabrice Bellard - * - * 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 -#include "hw/hw.h" -#include "monitor/qdev.h" -#include "hw/usb.h" -#include "hw/i386/pc.h" -#include "hw/pci/pci.h" -#include "sysemu/watchdog.h" -#include "hw/loader.h" -#include "exec/gdbstub.h" -#include "net/net.h" -#include "net/slirp.h" -#include "sysemu/char.h" -#include "ui/qemu-spice.h" -#include "sysemu/sysemu.h" -#include "sysemu/numa.h" -#include "monitor/monitor.h" -#include "qemu/readline.h" -#include "ui/console.h" -#include "ui/input.h" -#include "sysemu/blockdev.h" -#include "audio/audio.h" -#include "disas/disas.h" -#include "sysemu/balloon.h" -#include "qemu/timer.h" -#include "migration/migration.h" -#include "sysemu/kvm.h" -#include "qemu/acl.h" -#include "sysemu/tpm.h" -#include "qapi/qmp/qerror.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qjson.h" -#include "qapi/qmp/json-streamer.h" -#include "qapi/qmp/json-parser.h" -#include -#include "qemu/osdep.h" -#include "cpu.h" -#include "trace.h" -#include "trace/control.h" -#include "monitor/hmp-target.h" -#ifdef CONFIG_TRACE_SIMPLE -#include "trace/simple.h" -#endif -#include "exec/memory.h" -#include "qmp-commands.h" -#include "hmp.h" -#include "qemu/thread.h" -#include "block/qapi.h" -#include "qapi/qmp-event.h" -#include "qapi-event.h" -#include "qmp-introspect.h" -#include "sysemu/block-backend.h" - -/* for hmp_info_irq/pic */ -#if defined(TARGET_SPARC) -#include "hw/sparc/sun4m.h" -#endif -#include "hw/lm32/lm32_pic.h" - -#if defined(TARGET_S390X) -#include "hw/s390x/storage-keys.h" -#endif - -/* - * Supported types: - * - * 'F' filename - * 'B' block device name - * 's' string (accept optional quote) - * 'S' it just appends the rest of the string (accept optional quote) - * 'O' option string of the form NAME=VALUE,... - * parsed according to QemuOptsList given by its name - * Example: 'device:O' uses qemu_device_opts. - * Restriction: only lists with empty desc are supported - * TODO lift the restriction - * 'i' 32 bit integer - * 'l' target long (32 or 64 bit) - * 'M' Non-negative target long (32 or 64 bit), in user mode the - * value is multiplied by 2^20 (think Mebibyte) - * 'o' octets (aka bytes) - * user mode accepts an optional E, e, P, p, T, t, G, g, M, m, - * K, k suffix, which multiplies the value by 2^60 for suffixes E - * and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t, - * 2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k - * 'T' double - * user mode accepts an optional ms, us, ns suffix, - * which divides the value by 1e3, 1e6, 1e9, respectively - * '/' optional gdb-like print format (like "/10x") - * - * '?' optional type (for all types, except '/') - * '.' other form of optional type (for 'i' and 'l') - * 'b' boolean - * user mode accepts "on" or "off" - * '-' optional parameter (eg. '-f') - * - */ - -typedef struct mon_cmd_t { - const char *name; - const char *args_type; - const char *params; - const char *help; - union { - void (*cmd)(Monitor *mon, const QDict *qdict); - void (*cmd_new)(QDict *params, QObject **ret_data, Error **errp); - } mhandler; - /* @sub_table is a list of 2nd level of commands. If it do not exist, - * mhandler should be used. If it exist, sub_table[?].mhandler should be - * used, and mhandler of 1st level plays the role of help function. - */ - struct mon_cmd_t *sub_table; - void (*command_completion)(ReadLineState *rs, int nb_args, const char *str); -} mon_cmd_t; - -/* file descriptors passed via SCM_RIGHTS */ -typedef struct mon_fd_t mon_fd_t; -struct mon_fd_t { - char *name; - int fd; - QLIST_ENTRY(mon_fd_t) next; -}; - -/* file descriptor associated with a file descriptor set */ -typedef struct MonFdsetFd MonFdsetFd; -struct MonFdsetFd { - int fd; - bool removed; - char *opaque; - QLIST_ENTRY(MonFdsetFd) next; -}; - -/* file descriptor set containing fds passed via SCM_RIGHTS */ -typedef struct MonFdset MonFdset; -struct MonFdset { - int64_t id; - QLIST_HEAD(, MonFdsetFd) fds; - QLIST_HEAD(, MonFdsetFd) dup_fds; - QLIST_ENTRY(MonFdset) next; -}; - -typedef struct { - QObject *id; - JSONMessageParser parser; - /* - * When a client connects, we're in capabilities negotiation mode. - * When command qmp_capabilities succeeds, we go into command - * mode. - */ - bool in_command_mode; /* are we in command mode? */ -} MonitorQMP; - -/* - * To prevent flooding clients, events can be throttled. The - * throttling is calculated globally, rather than per-Monitor - * instance. - */ -typedef struct MonitorQAPIEventState { - QAPIEvent event; /* Throttling state for this event type and... */ - QDict *data; /* ... data, see qapi_event_throttle_equal() */ - QEMUTimer *timer; /* Timer for handling delayed events */ - QDict *qdict; /* Delayed event (if any) */ -} MonitorQAPIEventState; - -typedef struct { - int64_t rate; /* Minimum time (in ns) between two events */ -} MonitorQAPIEventConf; - -struct Monitor { - CharDriverState *chr; - int reset_seen; - int flags; - int suspend_cnt; - bool skip_flush; - - QemuMutex out_lock; - QString *outbuf; - guint out_watch; - - /* Read under either BQL or out_lock, written with BQL+out_lock. */ - int mux_out; - - ReadLineState *rs; - MonitorQMP qmp; - CPUState *mon_cpu; - BlockCompletionFunc *password_completion_cb; - void *password_opaque; - mon_cmd_t *cmd_table; - QLIST_HEAD(,mon_fd_t) fds; - QLIST_ENTRY(Monitor) entry; -}; - -/* QMP checker flags */ -#define QMP_ACCEPT_UNKNOWNS 1 - -/* Protects mon_list, monitor_event_state. */ -static QemuMutex monitor_lock; - -static QLIST_HEAD(mon_list, Monitor) mon_list; -static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets; -static int mon_refcount; - -static mon_cmd_t mon_cmds[]; -static mon_cmd_t info_cmds[]; - -static const mon_cmd_t qmp_cmds[]; - -Monitor *cur_mon; - -static void monitor_command_cb(void *opaque, const char *cmdline, - void *readline_opaque); - -/** - * Is @mon a QMP monitor? - */ -static inline bool monitor_is_qmp(const Monitor *mon) -{ - return (mon->flags & MONITOR_USE_CONTROL); -} - -/** - * Is the current monitor, if any, a QMP monitor? - */ -bool monitor_cur_is_qmp(void) -{ - return cur_mon && monitor_is_qmp(cur_mon); -} - -void monitor_read_command(Monitor *mon, int show_prompt) -{ - if (!mon->rs) - return; - - readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL); - if (show_prompt) - readline_show_prompt(mon->rs); -} - -int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, - void *opaque) -{ - if (mon->rs) { - readline_start(mon->rs, "Password: ", 1, readline_func, opaque); - /* prompt is printed on return from the command handler */ - return 0; - } else { - monitor_printf(mon, "terminal does not support password prompting\n"); - return -ENOTTY; - } -} - -static void monitor_flush_locked(Monitor *mon); - -static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond, - void *opaque) -{ - Monitor *mon = opaque; - - qemu_mutex_lock(&mon->out_lock); - mon->out_watch = 0; - monitor_flush_locked(mon); - qemu_mutex_unlock(&mon->out_lock); - return FALSE; -} - -/* Called with mon->out_lock held. */ -static void monitor_flush_locked(Monitor *mon) -{ - int rc; - size_t len; - const char *buf; - - if (mon->skip_flush) { - return; - } - - buf = qstring_get_str(mon->outbuf); - len = qstring_get_length(mon->outbuf); - - if (len && !mon->mux_out) { - rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len); - if ((rc < 0 && errno != EAGAIN) || (rc == len)) { - /* all flushed or error */ - QDECREF(mon->outbuf); - mon->outbuf = qstring_new(); - return; - } - if (rc > 0) { - /* partinal write */ - QString *tmp = qstring_from_str(buf + rc); - QDECREF(mon->outbuf); - mon->outbuf = tmp; - } - if (mon->out_watch == 0) { - mon->out_watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT|G_IO_HUP, - monitor_unblocked, mon); - } - } -} - -void monitor_flush(Monitor *mon) -{ - qemu_mutex_lock(&mon->out_lock); - monitor_flush_locked(mon); - qemu_mutex_unlock(&mon->out_lock); -} - -/* flush at every end of line */ -static void monitor_puts(Monitor *mon, const char *str) -{ - char c; - - qemu_mutex_lock(&mon->out_lock); - for(;;) { - c = *str++; - if (c == '\0') - break; - if (c == '\n') { - qstring_append_chr(mon->outbuf, '\r'); - } - qstring_append_chr(mon->outbuf, c); - if (c == '\n') { - monitor_flush_locked(mon); - } - } - qemu_mutex_unlock(&mon->out_lock); -} - -void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) -{ - char *buf; - - if (!mon) - return; - - if (monitor_is_qmp(mon)) { - return; - } - - buf = g_strdup_vprintf(fmt, ap); - monitor_puts(mon, buf); - g_free(buf); -} - -void monitor_printf(Monitor *mon, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - monitor_vprintf(mon, fmt, ap); - va_end(ap); -} - -int monitor_fprintf(FILE *stream, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - monitor_vprintf((Monitor *)stream, fmt, ap); - va_end(ap); - return 0; -} - -static void monitor_json_emitter(Monitor *mon, const QObject *data) -{ - QString *json; - - json = mon->flags & MONITOR_USE_PRETTY ? qobject_to_json_pretty(data) : - qobject_to_json(data); - assert(json != NULL); - - qstring_append_chr(json, '\n'); - monitor_puts(mon, qstring_get_str(json)); - - QDECREF(json); -} - -static QDict *build_qmp_error_dict(Error *err) -{ - QObject *obj; - - obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }", - ErrorClass_lookup[error_get_class(err)], - error_get_pretty(err)); - - return qobject_to_qdict(obj); -} - -static void monitor_protocol_emitter(Monitor *mon, QObject *data, - Error *err) -{ - QDict *qmp; - - trace_monitor_protocol_emitter(mon); - - if (!err) { - /* success response */ - qmp = qdict_new(); - if (data) { - qobject_incref(data); - qdict_put_obj(qmp, "return", data); - } else { - /* return an empty QDict by default */ - qdict_put(qmp, "return", qdict_new()); - } - } else { - /* error response */ - qmp = build_qmp_error_dict(err); - } - - if (mon->qmp.id) { - qdict_put_obj(qmp, "id", mon->qmp.id); - mon->qmp.id = NULL; - } - - monitor_json_emitter(mon, QOBJECT(qmp)); - QDECREF(qmp); -} - - -static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT_MAX] = { - /* Limit guest-triggerable events to 1 per second */ - [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_WATCHDOG] = { 1000 * SCALE_MS }, - [QAPI_EVENT_BALLOON_CHANGE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS }, - [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS }, -}; - -GHashTable *monitor_qapi_event_state; - -/* - * Emits the event to every monitor instance, @event is only used for trace - * Called with monitor_lock held. - */ -static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) -{ - Monitor *mon; - - trace_monitor_protocol_event_emit(event, qdict); - QLIST_FOREACH(mon, &mon_list, entry) { - if (monitor_is_qmp(mon) && mon->qmp.in_command_mode) { - monitor_json_emitter(mon, QOBJECT(qdict)); - } - } -} - -static void monitor_qapi_event_handler(void *opaque); - -/* - * Queue a new event for emission to Monitor instances, - * applying any rate limiting if required. - */ -static void -monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp) -{ - MonitorQAPIEventConf *evconf; - MonitorQAPIEventState *evstate; - - assert(event < QAPI_EVENT_MAX); - evconf = &monitor_qapi_event_conf[event]; - trace_monitor_protocol_event_queue(event, qdict, evconf->rate); - - qemu_mutex_lock(&monitor_lock); - - if (!evconf->rate) { - /* Unthrottled event */ - monitor_qapi_event_emit(event, qdict); - } else { - QDict *data = qobject_to_qdict(qdict_get(qdict, "data")); - MonitorQAPIEventState key = { .event = event, .data = data }; - - evstate = g_hash_table_lookup(monitor_qapi_event_state, &key); - assert(!evstate || timer_pending(evstate->timer)); - - if (evstate) { - /* - * Timer is pending for (at least) evconf->rate ns after - * last send. Store event for sending when timer fires, - * replacing a prior stored event if any. - */ - QDECREF(evstate->qdict); - evstate->qdict = qdict; - QINCREF(evstate->qdict); - } else { - /* - * Last send was (at least) evconf->rate ns ago. - * Send immediately, and arm the timer to call - * monitor_qapi_event_handler() in evconf->rate ns. Any - * events arriving before then will be delayed until then. - */ - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); - - monitor_qapi_event_emit(event, qdict); - - evstate = g_new(MonitorQAPIEventState, 1); - evstate->event = event; - evstate->data = data; - QINCREF(evstate->data); - evstate->qdict = NULL; - evstate->timer = timer_new_ns(QEMU_CLOCK_REALTIME, - monitor_qapi_event_handler, - evstate); - g_hash_table_add(monitor_qapi_event_state, evstate); - timer_mod_ns(evstate->timer, now + evconf->rate); - } - } - - qemu_mutex_unlock(&monitor_lock); -} - -/* - * This function runs evconf->rate ns after sending a throttled - * event. - * If another event has since been stored, send it. - */ -static void monitor_qapi_event_handler(void *opaque) -{ - MonitorQAPIEventState *evstate = opaque; - MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event]; - - trace_monitor_protocol_event_handler(evstate->event, evstate->qdict); - qemu_mutex_lock(&monitor_lock); - - if (evstate->qdict) { - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); - - monitor_qapi_event_emit(evstate->event, evstate->qdict); - QDECREF(evstate->qdict); - evstate->qdict = NULL; - timer_mod_ns(evstate->timer, now + evconf->rate); - } else { - g_hash_table_remove(monitor_qapi_event_state, evstate); - QDECREF(evstate->data); - timer_free(evstate->timer); - g_free(evstate); - } - - qemu_mutex_unlock(&monitor_lock); -} - -static unsigned int qapi_event_throttle_hash(const void *key) -{ - const MonitorQAPIEventState *evstate = key; - unsigned int hash = evstate->event * 255; - - if (evstate->event == QAPI_EVENT_VSERPORT_CHANGE) { - hash += g_str_hash(qdict_get_str(evstate->data, "id")); - } - - return hash; -} - -static gboolean qapi_event_throttle_equal(const void *a, const void *b) -{ - const MonitorQAPIEventState *eva = a; - const MonitorQAPIEventState *evb = b; - - if (eva->event != evb->event) { - return FALSE; - } - - if (eva->event == QAPI_EVENT_VSERPORT_CHANGE) { - return !strcmp(qdict_get_str(eva->data, "id"), - qdict_get_str(evb->data, "id")); - } - - return TRUE; -} - -static void monitor_qapi_event_init(void) -{ - monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash, - qapi_event_throttle_equal); - qmp_event_set_func_emit(monitor_qapi_event_queue); -} - -static void qmp_capabilities(QDict *params, QObject **ret_data, Error **errp) -{ - cur_mon->qmp.in_command_mode = true; -} - -static void handle_hmp_command(Monitor *mon, const char *cmdline); - -static void monitor_data_init(Monitor *mon) -{ - memset(mon, 0, sizeof(Monitor)); - qemu_mutex_init(&mon->out_lock); - mon->outbuf = qstring_new(); - /* Use *mon_cmds by default. */ - mon->cmd_table = mon_cmds; -} - -static void monitor_data_destroy(Monitor *mon) -{ - QDECREF(mon->outbuf); - qemu_mutex_destroy(&mon->out_lock); -} - -char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, - int64_t cpu_index, Error **errp) -{ - char *output = NULL; - Monitor *old_mon, hmp; - - monitor_data_init(&hmp); - hmp.skip_flush = true; - - old_mon = cur_mon; - cur_mon = &hmp; - - if (has_cpu_index) { - int ret = monitor_set_cpu(cpu_index); - if (ret < 0) { - cur_mon = old_mon; - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", - "a CPU number"); - goto out; - } - } - - handle_hmp_command(&hmp, command_line); - cur_mon = old_mon; - - qemu_mutex_lock(&hmp.out_lock); - if (qstring_get_length(hmp.outbuf) > 0) { - output = g_strdup(qstring_get_str(hmp.outbuf)); - } else { - output = g_strdup(""); - } - qemu_mutex_unlock(&hmp.out_lock); - -out: - monitor_data_destroy(&hmp); - return output; -} - -static int compare_cmd(const char *name, const char *list) -{ - const char *p, *pstart; - int len; - len = strlen(name); - p = list; - for(;;) { - pstart = p; - p = strchr(p, '|'); - if (!p) - p = pstart + strlen(pstart); - if ((p - pstart) == len && !memcmp(pstart, name, len)) - return 1; - if (*p == '\0') - break; - p++; - } - return 0; -} - -static int get_str(char *buf, int buf_size, const char **pp) -{ - const char *p; - char *q; - int c; - - q = buf; - p = *pp; - while (qemu_isspace(*p)) { - p++; - } - if (*p == '\0') { - fail: - *q = '\0'; - *pp = p; - return -1; - } - if (*p == '\"') { - p++; - while (*p != '\0' && *p != '\"') { - if (*p == '\\') { - p++; - c = *p++; - switch (c) { - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case '\\': - case '\'': - case '\"': - break; - default: - printf("unsupported escape code: '\\%c'\n", c); - goto fail; - } - if ((q - buf) < buf_size - 1) { - *q++ = c; - } - } else { - if ((q - buf) < buf_size - 1) { - *q++ = *p; - } - p++; - } - } - if (*p != '\"') { - printf("unterminated string\n"); - goto fail; - } - p++; - } else { - while (*p != '\0' && !qemu_isspace(*p)) { - if ((q - buf) < buf_size - 1) { - *q++ = *p; - } - p++; - } - } - *q = '\0'; - *pp = p; - return 0; -} - -#define MAX_ARGS 16 - -static void free_cmdline_args(char **args, int nb_args) -{ - int i; - - assert(nb_args <= MAX_ARGS); - - for (i = 0; i < nb_args; i++) { - g_free(args[i]); - } - -} - -/* - * Parse the command line to get valid args. - * @cmdline: command line to be parsed. - * @pnb_args: location to store the number of args, must NOT be NULL. - * @args: location to store the args, which should be freed by caller, must - * NOT be NULL. - * - * Returns 0 on success, negative on failure. - * - * NOTE: this parser is an approximate form of the real command parser. Number - * of args have a limit of MAX_ARGS. If cmdline contains more, it will - * return with failure. - */ -static int parse_cmdline(const char *cmdline, - int *pnb_args, char **args) -{ - const char *p; - int nb_args, ret; - char buf[1024]; - - p = cmdline; - nb_args = 0; - for (;;) { - while (qemu_isspace(*p)) { - p++; - } - if (*p == '\0') { - break; - } - if (nb_args >= MAX_ARGS) { - goto fail; - } - ret = get_str(buf, sizeof(buf), &p); - if (ret < 0) { - goto fail; - } - args[nb_args] = g_strdup(buf); - nb_args++; - } - *pnb_args = nb_args; - return 0; - - fail: - free_cmdline_args(args, nb_args); - return -1; -} - -static void help_cmd_dump_one(Monitor *mon, - const mon_cmd_t *cmd, - char **prefix_args, - int prefix_args_nb) -{ - int i; - - for (i = 0; i < prefix_args_nb; i++) { - monitor_printf(mon, "%s ", prefix_args[i]); - } - monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help); -} - -/* @args[@arg_index] is the valid command need to find in @cmds */ -static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds, - char **args, int nb_args, int arg_index) -{ - const mon_cmd_t *cmd; - - /* No valid arg need to compare with, dump all in *cmds */ - if (arg_index >= nb_args) { - for (cmd = cmds; cmd->name != NULL; cmd++) { - help_cmd_dump_one(mon, cmd, args, arg_index); - } - return; - } - - /* Find one entry to dump */ - for (cmd = cmds; cmd->name != NULL; cmd++) { - if (compare_cmd(args[arg_index], cmd->name)) { - if (cmd->sub_table) { - /* continue with next arg */ - help_cmd_dump(mon, cmd->sub_table, - args, nb_args, arg_index + 1); - } else { - help_cmd_dump_one(mon, cmd, args, arg_index); - } - break; - } - } -} - -static void help_cmd(Monitor *mon, const char *name) -{ - char *args[MAX_ARGS]; - int nb_args = 0; - - /* 1. parse user input */ - if (name) { - /* special case for log, directly dump and return */ - if (!strcmp(name, "log")) { - const QEMULogItem *item; - monitor_printf(mon, "Log items (comma separated):\n"); - monitor_printf(mon, "%-10s %s\n", "none", "remove all logs"); - for (item = qemu_log_items; item->mask != 0; item++) { - monitor_printf(mon, "%-10s %s\n", item->name, item->help); - } - return; - } - - if (parse_cmdline(name, &nb_args, args) < 0) { - return; - } - } - - /* 2. dump the contents according to parsed args */ - help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0); - - free_cmdline_args(args, nb_args); -} - -static void do_help_cmd(Monitor *mon, const QDict *qdict) -{ - help_cmd(mon, qdict_get_try_str(qdict, "name")); -} - -static void hmp_trace_event(Monitor *mon, const QDict *qdict) -{ - const char *tp_name = qdict_get_str(qdict, "name"); - bool new_state = qdict_get_bool(qdict, "option"); - Error *local_err = NULL; - - qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err); - if (local_err) { - error_report_err(local_err); - } -} - -#ifdef CONFIG_TRACE_SIMPLE -static void hmp_trace_file(Monitor *mon, const QDict *qdict) -{ - const char *op = qdict_get_try_str(qdict, "op"); - const char *arg = qdict_get_try_str(qdict, "arg"); - - if (!op) { - st_print_trace_file_status((FILE *)mon, &monitor_fprintf); - } else if (!strcmp(op, "on")) { - st_set_trace_file_enabled(true); - } else if (!strcmp(op, "off")) { - st_set_trace_file_enabled(false); - } else if (!strcmp(op, "flush")) { - st_flush_trace_buffer(); - } else if (!strcmp(op, "set")) { - if (arg) { - st_set_trace_file(arg); - } - } else { - monitor_printf(mon, "unexpected argument \"%s\"\n", op); - help_cmd(mon, "trace-file"); - } -} -#endif - -static void hmp_info_help(Monitor *mon, const QDict *qdict) -{ - help_cmd(mon, "info"); -} - -CommandInfoList *qmp_query_commands(Error **errp) -{ - CommandInfoList *info, *cmd_list = NULL; - const mon_cmd_t *cmd; - - for (cmd = qmp_cmds; cmd->name != NULL; cmd++) { - info = g_malloc0(sizeof(*info)); - info->value = g_malloc0(sizeof(*info->value)); - info->value->name = g_strdup(cmd->name); - - info->next = cmd_list; - cmd_list = info; - } - - return cmd_list; -} - -EventInfoList *qmp_query_events(Error **errp) -{ - EventInfoList *info, *ev_list = NULL; - QAPIEvent e; - - for (e = 0 ; e < QAPI_EVENT_MAX ; e++) { - const char *event_name = QAPIEvent_lookup[e]; - assert(event_name != NULL); - info = g_malloc0(sizeof(*info)); - info->value = g_malloc0(sizeof(*info->value)); - info->value->name = g_strdup(event_name); - - info->next = ev_list; - ev_list = info; - } - - return ev_list; -} - -/* - * Minor hack: generated marshalling suppressed for this command - * ('gen': false in the schema) so we can parse the JSON string - * directly into QObject instead of first parsing it with - * visit_type_SchemaInfoList() into a SchemaInfoList, then marshal it - * to QObject with generated output marshallers, every time. Instead, - * we do it in test-qmp-input-visitor.c, just to make sure - * qapi-introspect.py's output actually conforms to the schema. - */ -static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data, - Error **errp) -{ - *ret_data = qobject_from_json(qmp_schema_json); -} - -/* set the current CPU defined by the user */ -int monitor_set_cpu(int cpu_index) -{ - CPUState *cpu; - - cpu = qemu_get_cpu(cpu_index); - if (cpu == NULL) { - return -1; - } - cur_mon->mon_cpu = cpu; - return 0; -} - -CPUState *mon_get_cpu(void) -{ - if (!cur_mon->mon_cpu) { - monitor_set_cpu(0); - } - cpu_synchronize_state(cur_mon->mon_cpu); - return cur_mon->mon_cpu; -} - -CPUArchState *mon_get_cpu_env(void) -{ - return mon_get_cpu()->env_ptr; -} - -int monitor_get_cpu_index(void) -{ - return mon_get_cpu()->cpu_index; -} - -static void hmp_info_registers(Monitor *mon, const QDict *qdict) -{ - cpu_dump_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU); -} - -static void hmp_info_jit(Monitor *mon, const QDict *qdict) -{ - dump_exec_info((FILE *)mon, monitor_fprintf); - dump_drift_info((FILE *)mon, monitor_fprintf); -} - -static void hmp_info_opcount(Monitor *mon, const QDict *qdict) -{ - dump_opcount_info((FILE *)mon, monitor_fprintf); -} - -static void hmp_info_history(Monitor *mon, const QDict *qdict) -{ - int i; - const char *str; - - if (!mon->rs) - return; - i = 0; - for(;;) { - str = readline_get_history(mon->rs, i); - if (!str) - break; - monitor_printf(mon, "%d: '%s'\n", i, str); - i++; - } -} - -static void hmp_info_cpustats(Monitor *mon, const QDict *qdict) -{ - cpu_dump_statistics(mon_get_cpu(), (FILE *)mon, &monitor_fprintf, 0); -} - -static void hmp_info_trace_events(Monitor *mon, const QDict *qdict) -{ - TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL); - TraceEventInfoList *elem; - - for (elem = events; elem != NULL; elem = elem->next) { - monitor_printf(mon, "%s : state %u\n", - elem->value->name, - elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0); - } - qapi_free_TraceEventInfoList(events); -} - -void qmp_client_migrate_info(const char *protocol, const char *hostname, - bool has_port, int64_t port, - bool has_tls_port, int64_t tls_port, - bool has_cert_subject, const char *cert_subject, - Error **errp) -{ - if (strcmp(protocol, "spice") == 0) { - if (!qemu_using_spice(errp)) { - return; - } - - if (!has_port && !has_tls_port) { - error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port"); - return; - } - - if (qemu_spice_migrate_info(hostname, - has_port ? port : -1, - has_tls_port ? tls_port : -1, - cert_subject)) { - error_setg(errp, QERR_UNDEFINED_ERROR); - return; - } - return; - } - - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice"); -} - -static void hmp_logfile(Monitor *mon, const QDict *qdict) -{ - qemu_set_log_filename(qdict_get_str(qdict, "filename")); -} - -static void hmp_log(Monitor *mon, const QDict *qdict) -{ - int mask; - const char *items = qdict_get_str(qdict, "items"); - - if (!strcmp(items, "none")) { - mask = 0; - } else { - mask = qemu_str_to_log_mask(items); - if (!mask) { - help_cmd(mon, "log"); - return; - } - } - qemu_set_log(mask); -} - -static void hmp_singlestep(Monitor *mon, const QDict *qdict) -{ - const char *option = qdict_get_try_str(qdict, "option"); - if (!option || !strcmp(option, "on")) { - singlestep = 1; - } else if (!strcmp(option, "off")) { - singlestep = 0; - } else { - monitor_printf(mon, "unexpected option %s\n", option); - } -} - -static void hmp_gdbserver(Monitor *mon, const QDict *qdict) -{ - const char *device = qdict_get_try_str(qdict, "device"); - if (!device) - device = "tcp::" DEFAULT_GDBSTUB_PORT; - if (gdbserver_start(device) < 0) { - monitor_printf(mon, "Could not open gdbserver on device '%s'\n", - device); - } else if (strcmp(device, "none") == 0) { - monitor_printf(mon, "Disabled gdbserver\n"); - } else { - monitor_printf(mon, "Waiting for gdb connection on device '%s'\n", - device); - } -} - -static void hmp_watchdog_action(Monitor *mon, const QDict *qdict) -{ - const char *action = qdict_get_str(qdict, "action"); - if (select_watchdog_action(action) == -1) { - monitor_printf(mon, "Unknown watchdog action '%s'\n", action); - } -} - -static void monitor_printc(Monitor *mon, int c) -{ - monitor_printf(mon, "'"); - switch(c) { - case '\'': - monitor_printf(mon, "\\'"); - break; - case '\\': - monitor_printf(mon, "\\\\"); - break; - case '\n': - monitor_printf(mon, "\\n"); - break; - case '\r': - monitor_printf(mon, "\\r"); - break; - default: - if (c >= 32 && c <= 126) { - monitor_printf(mon, "%c", c); - } else { - monitor_printf(mon, "\\x%02x", c); - } - break; - } - monitor_printf(mon, "'"); -} - -static void memory_dump(Monitor *mon, int count, int format, int wsize, - hwaddr addr, int is_physical) -{ - int l, line_size, i, max_digits, len; - uint8_t buf[16]; - uint64_t v; - - if (format == 'i') { - int flags = 0; -#ifdef TARGET_I386 - CPUArchState *env = mon_get_cpu_env(); - if (wsize == 2) { - flags = 1; - } else if (wsize == 4) { - flags = 0; - } else { - /* as default we use the current CS size */ - flags = 0; - if (env) { -#ifdef TARGET_X86_64 - if ((env->efer & MSR_EFER_LMA) && - (env->segs[R_CS].flags & DESC_L_MASK)) - flags = 2; - else -#endif - if (!(env->segs[R_CS].flags & DESC_B_MASK)) - flags = 1; - } - } -#endif -#ifdef TARGET_PPC - CPUArchState *env = mon_get_cpu_env(); - flags = msr_le << 16; - flags |= env->bfd_mach; -#endif - monitor_disas(mon, mon_get_cpu(), addr, count, is_physical, flags); - return; - } - - len = wsize * count; - if (wsize == 1) - line_size = 8; - else - line_size = 16; - max_digits = 0; - - switch(format) { - case 'o': - max_digits = (wsize * 8 + 2) / 3; - break; - default: - case 'x': - max_digits = (wsize * 8) / 4; - break; - case 'u': - case 'd': - max_digits = (wsize * 8 * 10 + 32) / 33; - break; - case 'c': - wsize = 1; - break; - } - - while (len > 0) { - if (is_physical) - monitor_printf(mon, TARGET_FMT_plx ":", addr); - else - monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr); - l = len; - if (l > line_size) - l = line_size; - if (is_physical) { - cpu_physical_memory_read(addr, buf, l); - } else { - if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) { - monitor_printf(mon, " Cannot access memory\n"); - break; - } - } - i = 0; - while (i < l) { - switch(wsize) { - default: - case 1: - v = ldub_p(buf + i); - break; - case 2: - v = lduw_p(buf + i); - break; - case 4: - v = (uint32_t)ldl_p(buf + i); - break; - case 8: - v = ldq_p(buf + i); - break; - } - monitor_printf(mon, " "); - switch(format) { - case 'o': - monitor_printf(mon, "%#*" PRIo64, max_digits, v); - break; - case 'x': - monitor_printf(mon, "0x%0*" PRIx64, max_digits, v); - break; - case 'u': - monitor_printf(mon, "%*" PRIu64, max_digits, v); - break; - case 'd': - monitor_printf(mon, "%*" PRId64, max_digits, v); - break; - case 'c': - monitor_printc(mon, v); - break; - } - i += wsize; - } - monitor_printf(mon, "\n"); - addr += l; - len -= l; - } -} - -static void hmp_memory_dump(Monitor *mon, const QDict *qdict) -{ - int count = qdict_get_int(qdict, "count"); - int format = qdict_get_int(qdict, "format"); - int size = qdict_get_int(qdict, "size"); - target_long addr = qdict_get_int(qdict, "addr"); - - memory_dump(mon, count, format, size, addr, 0); -} - -static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict) -{ - int count = qdict_get_int(qdict, "count"); - int format = qdict_get_int(qdict, "format"); - int size = qdict_get_int(qdict, "size"); - hwaddr addr = qdict_get_int(qdict, "addr"); - - memory_dump(mon, count, format, size, addr, 1); -} - -static void do_print(Monitor *mon, const QDict *qdict) -{ - int format = qdict_get_int(qdict, "format"); - hwaddr val = qdict_get_int(qdict, "val"); - - switch(format) { - case 'o': - monitor_printf(mon, "%#" HWADDR_PRIo, val); - break; - case 'x': - monitor_printf(mon, "%#" HWADDR_PRIx, val); - break; - case 'u': - monitor_printf(mon, "%" HWADDR_PRIu, val); - break; - default: - case 'd': - monitor_printf(mon, "%" HWADDR_PRId, val); - break; - case 'c': - monitor_printc(mon, val); - break; - } - monitor_printf(mon, "\n"); -} - -static void hmp_sum(Monitor *mon, const QDict *qdict) -{ - uint32_t addr; - uint16_t sum; - uint32_t start = qdict_get_int(qdict, "start"); - uint32_t size = qdict_get_int(qdict, "size"); - - sum = 0; - for(addr = start; addr < (start + size); addr++) { - uint8_t val = address_space_ldub(&address_space_memory, addr, - MEMTXATTRS_UNSPECIFIED, NULL); - /* BSD sum algorithm ('sum' Unix command) */ - sum = (sum >> 1) | (sum << 15); - sum += val; - } - monitor_printf(mon, "%05d\n", sum); -} - -static int mouse_button_state; - -static void hmp_mouse_move(Monitor *mon, const QDict *qdict) -{ - int dx, dy, dz, button; - const char *dx_str = qdict_get_str(qdict, "dx_str"); - const char *dy_str = qdict_get_str(qdict, "dy_str"); - const char *dz_str = qdict_get_try_str(qdict, "dz_str"); - - dx = strtol(dx_str, NULL, 0); - dy = strtol(dy_str, NULL, 0); - qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx); - qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy); - - if (dz_str) { - dz = strtol(dz_str, NULL, 0); - if (dz != 0) { - button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; - qemu_input_queue_btn(NULL, button, true); - qemu_input_event_sync(); - qemu_input_queue_btn(NULL, button, false); - } - } - qemu_input_event_sync(); -} - -static void hmp_mouse_button(Monitor *mon, const QDict *qdict) -{ - static uint32_t bmap[INPUT_BUTTON_MAX] = { - [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, - [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, - [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, - }; - int button_state = qdict_get_int(qdict, "button_state"); - - if (mouse_button_state == button_state) { - return; - } - qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state); - qemu_input_event_sync(); - mouse_button_state = button_state; -} - -static void hmp_ioport_read(Monitor *mon, const QDict *qdict) -{ - int size = qdict_get_int(qdict, "size"); - int addr = qdict_get_int(qdict, "addr"); - int has_index = qdict_haskey(qdict, "index"); - uint32_t val; - int suffix; - - if (has_index) { - int index = qdict_get_int(qdict, "index"); - cpu_outb(addr & IOPORTS_MASK, index & 0xff); - addr++; - } - addr &= 0xffff; - - switch(size) { - default: - case 1: - val = cpu_inb(addr); - suffix = 'b'; - break; - case 2: - val = cpu_inw(addr); - suffix = 'w'; - break; - case 4: - val = cpu_inl(addr); - suffix = 'l'; - break; - } - monitor_printf(mon, "port%c[0x%04x] = %#0*x\n", - suffix, addr, size * 2, val); -} - -static void hmp_ioport_write(Monitor *mon, const QDict *qdict) -{ - int size = qdict_get_int(qdict, "size"); - int addr = qdict_get_int(qdict, "addr"); - int val = qdict_get_int(qdict, "val"); - - addr &= IOPORTS_MASK; - - switch (size) { - default: - case 1: - cpu_outb(addr, val); - break; - case 2: - cpu_outw(addr, val); - break; - case 4: - cpu_outl(addr, val); - break; - } -} - -static void hmp_boot_set(Monitor *mon, const QDict *qdict) -{ - Error *local_err = NULL; - const char *bootdevice = qdict_get_str(qdict, "bootdevice"); - - qemu_boot_set(bootdevice, &local_err); - if (local_err) { - monitor_printf(mon, "%s\n", error_get_pretty(local_err)); - error_free(local_err); - } else { - monitor_printf(mon, "boot device list now set to %s\n", bootdevice); - } -} - -static void hmp_info_mtree(Monitor *mon, const QDict *qdict) -{ - mtree_info((fprintf_function)monitor_printf, mon); -} - -static void hmp_info_numa(Monitor *mon, const QDict *qdict) -{ - int i; - CPUState *cpu; - uint64_t *node_mem; - - node_mem = g_new0(uint64_t, nb_numa_nodes); - query_numa_node_mem(node_mem); - monitor_printf(mon, "%d nodes\n", nb_numa_nodes); - for (i = 0; i < nb_numa_nodes; i++) { - monitor_printf(mon, "node %d cpus:", i); - CPU_FOREACH(cpu) { - if (cpu->numa_node == i) { - monitor_printf(mon, " %d", cpu->cpu_index); - } - } - monitor_printf(mon, "\n"); - monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i, - node_mem[i] >> 20); - } - g_free(node_mem); -} - -#ifdef CONFIG_PROFILER - -int64_t tcg_time; -int64_t dev_time; - -static void hmp_info_profile(Monitor *mon, const QDict *qdict) -{ - monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n", - dev_time, dev_time / (double)get_ticks_per_sec()); - monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n", - tcg_time, tcg_time / (double)get_ticks_per_sec()); - tcg_time = 0; - dev_time = 0; -} -#else -static void hmp_info_profile(Monitor *mon, const QDict *qdict) -{ - monitor_printf(mon, "Internal profiler not compiled\n"); -} -#endif - -/* Capture support */ -static QLIST_HEAD (capture_list_head, CaptureState) capture_head; - -static void hmp_info_capture(Monitor *mon, const QDict *qdict) -{ - int i; - CaptureState *s; - - for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { - monitor_printf(mon, "[%d]: ", i); - s->ops.info (s->opaque); - } -} - -static void hmp_stopcapture(Monitor *mon, const QDict *qdict) -{ - int i; - int n = qdict_get_int(qdict, "n"); - CaptureState *s; - - for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { - if (i == n) { - s->ops.destroy (s->opaque); - QLIST_REMOVE (s, entries); - g_free (s); - return; - } - } -} - -static void hmp_wavcapture(Monitor *mon, const QDict *qdict) -{ - const char *path = qdict_get_str(qdict, "path"); - int has_freq = qdict_haskey(qdict, "freq"); - int freq = qdict_get_try_int(qdict, "freq", -1); - int has_bits = qdict_haskey(qdict, "bits"); - int bits = qdict_get_try_int(qdict, "bits", -1); - int has_channels = qdict_haskey(qdict, "nchannels"); - int nchannels = qdict_get_try_int(qdict, "nchannels", -1); - CaptureState *s; - - s = g_malloc0 (sizeof (*s)); - - freq = has_freq ? freq : 44100; - bits = has_bits ? bits : 16; - nchannels = has_channels ? nchannels : 2; - - if (wav_start_capture (s, path, freq, bits, nchannels)) { - monitor_printf(mon, "Failed to add wave capture\n"); - g_free (s); - return; - } - QLIST_INSERT_HEAD (&capture_head, s, entries); -} - -static qemu_acl *find_acl(Monitor *mon, const char *name) -{ - qemu_acl *acl = qemu_acl_find(name); - - if (!acl) { - monitor_printf(mon, "acl: unknown list '%s'\n", name); - } - return acl; -} - -static void hmp_acl_show(Monitor *mon, const QDict *qdict) -{ - const char *aclname = qdict_get_str(qdict, "aclname"); - qemu_acl *acl = find_acl(mon, aclname); - qemu_acl_entry *entry; - int i = 0; - - if (acl) { - monitor_printf(mon, "policy: %s\n", - acl->defaultDeny ? "deny" : "allow"); - QTAILQ_FOREACH(entry, &acl->entries, next) { - i++; - monitor_printf(mon, "%d: %s %s\n", i, - entry->deny ? "deny" : "allow", entry->match); - } - } -} - -static void hmp_acl_reset(Monitor *mon, const QDict *qdict) -{ - const char *aclname = qdict_get_str(qdict, "aclname"); - qemu_acl *acl = find_acl(mon, aclname); - - if (acl) { - qemu_acl_reset(acl); - monitor_printf(mon, "acl: removed all rules\n"); - } -} - -static void hmp_acl_policy(Monitor *mon, const QDict *qdict) -{ - const char *aclname = qdict_get_str(qdict, "aclname"); - const char *policy = qdict_get_str(qdict, "policy"); - qemu_acl *acl = find_acl(mon, aclname); - - if (acl) { - if (strcmp(policy, "allow") == 0) { - acl->defaultDeny = 0; - monitor_printf(mon, "acl: policy set to 'allow'\n"); - } else if (strcmp(policy, "deny") == 0) { - acl->defaultDeny = 1; - monitor_printf(mon, "acl: policy set to 'deny'\n"); - } else { - monitor_printf(mon, "acl: unknown policy '%s', " - "expected 'deny' or 'allow'\n", policy); - } - } -} - -static void hmp_acl_add(Monitor *mon, const QDict *qdict) -{ - const char *aclname = qdict_get_str(qdict, "aclname"); - const char *match = qdict_get_str(qdict, "match"); - const char *policy = qdict_get_str(qdict, "policy"); - int has_index = qdict_haskey(qdict, "index"); - int index = qdict_get_try_int(qdict, "index", -1); - qemu_acl *acl = find_acl(mon, aclname); - int deny, ret; - - if (acl) { - if (strcmp(policy, "allow") == 0) { - deny = 0; - } else if (strcmp(policy, "deny") == 0) { - deny = 1; - } else { - monitor_printf(mon, "acl: unknown policy '%s', " - "expected 'deny' or 'allow'\n", policy); - return; - } - if (has_index) - ret = qemu_acl_insert(acl, deny, match, index); - else - ret = qemu_acl_append(acl, deny, match); - if (ret < 0) - monitor_printf(mon, "acl: unable to add acl entry\n"); - else - monitor_printf(mon, "acl: added rule at position %d\n", ret); - } -} - -static void hmp_acl_remove(Monitor *mon, const QDict *qdict) -{ - const char *aclname = qdict_get_str(qdict, "aclname"); - const char *match = qdict_get_str(qdict, "match"); - qemu_acl *acl = find_acl(mon, aclname); - int ret; - - if (acl) { - ret = qemu_acl_remove(acl, match); - if (ret < 0) - monitor_printf(mon, "acl: no matching acl entry\n"); - else - monitor_printf(mon, "acl: removed rule at position %d\n", ret); - } -} - -void qmp_getfd(const char *fdname, Error **errp) -{ - mon_fd_t *monfd; - int fd; - - fd = qemu_chr_fe_get_msgfd(cur_mon->chr); - if (fd == -1) { - error_setg(errp, QERR_FD_NOT_SUPPLIED); - return; - } - - if (qemu_isdigit(fdname[0])) { - close(fd); - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname", - "a name not starting with a digit"); - return; - } - - QLIST_FOREACH(monfd, &cur_mon->fds, next) { - if (strcmp(monfd->name, fdname) != 0) { - continue; - } - - close(monfd->fd); - monfd->fd = fd; - return; - } - - monfd = g_malloc0(sizeof(mon_fd_t)); - monfd->name = g_strdup(fdname); - monfd->fd = fd; - - QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next); -} - -void qmp_closefd(const char *fdname, Error **errp) -{ - mon_fd_t *monfd; - - QLIST_FOREACH(monfd, &cur_mon->fds, next) { - if (strcmp(monfd->name, fdname) != 0) { - continue; - } - - QLIST_REMOVE(monfd, next); - close(monfd->fd); - g_free(monfd->name); - g_free(monfd); - return; - } - - error_setg(errp, QERR_FD_NOT_FOUND, fdname); -} - -static void hmp_loadvm(Monitor *mon, const QDict *qdict) -{ - int saved_vm_running = runstate_is_running(); - const char *name = qdict_get_str(qdict, "name"); - - vm_stop(RUN_STATE_RESTORE_VM); - - if (load_vmstate(name) == 0 && saved_vm_running) { - vm_start(); - } -} - -int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) -{ - mon_fd_t *monfd; - - QLIST_FOREACH(monfd, &mon->fds, next) { - int fd; - - if (strcmp(monfd->name, fdname) != 0) { - continue; - } - - fd = monfd->fd; - - /* caller takes ownership of fd */ - QLIST_REMOVE(monfd, next); - g_free(monfd->name); - g_free(monfd); - - return fd; - } - - error_setg(errp, "File descriptor named '%s' has not been found", fdname); - return -1; -} - -static void monitor_fdset_cleanup(MonFdset *mon_fdset) -{ - MonFdsetFd *mon_fdset_fd; - MonFdsetFd *mon_fdset_fd_next; - - QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) { - if ((mon_fdset_fd->removed || - (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) && - runstate_is_running()) { - close(mon_fdset_fd->fd); - g_free(mon_fdset_fd->opaque); - QLIST_REMOVE(mon_fdset_fd, next); - g_free(mon_fdset_fd); - } - } - - if (QLIST_EMPTY(&mon_fdset->fds) && QLIST_EMPTY(&mon_fdset->dup_fds)) { - QLIST_REMOVE(mon_fdset, next); - g_free(mon_fdset); - } -} - -static void monitor_fdsets_cleanup(void) -{ - MonFdset *mon_fdset; - MonFdset *mon_fdset_next; - - QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) { - monitor_fdset_cleanup(mon_fdset); - } -} - -AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, - const char *opaque, Error **errp) -{ - int fd; - Monitor *mon = cur_mon; - AddfdInfo *fdinfo; - - fd = qemu_chr_fe_get_msgfd(mon->chr); - if (fd == -1) { - error_setg(errp, QERR_FD_NOT_SUPPLIED); - goto error; - } - - fdinfo = monitor_fdset_add_fd(fd, has_fdset_id, fdset_id, - has_opaque, opaque, errp); - if (fdinfo) { - return fdinfo; - } - -error: - if (fd != -1) { - close(fd); - } - return NULL; -} - -void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) -{ - MonFdset *mon_fdset; - MonFdsetFd *mon_fdset_fd; - char fd_str[60]; - - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - if (mon_fdset->id != fdset_id) { - continue; - } - QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { - if (has_fd) { - if (mon_fdset_fd->fd != fd) { - continue; - } - mon_fdset_fd->removed = true; - break; - } else { - mon_fdset_fd->removed = true; - } - } - if (has_fd && !mon_fdset_fd) { - goto error; - } - monitor_fdset_cleanup(mon_fdset); - return; - } - -error: - if (has_fd) { - snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64, - fdset_id, fd); - } else { - snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64, fdset_id); - } - error_setg(errp, QERR_FD_NOT_FOUND, fd_str); -} - -FdsetInfoList *qmp_query_fdsets(Error **errp) -{ - MonFdset *mon_fdset; - MonFdsetFd *mon_fdset_fd; - FdsetInfoList *fdset_list = NULL; - - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info)); - FdsetFdInfoList *fdsetfd_list = NULL; - - fdset_info->value = g_malloc0(sizeof(*fdset_info->value)); - fdset_info->value->fdset_id = mon_fdset->id; - - QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { - FdsetFdInfoList *fdsetfd_info; - - fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info)); - fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value)); - fdsetfd_info->value->fd = mon_fdset_fd->fd; - if (mon_fdset_fd->opaque) { - fdsetfd_info->value->has_opaque = true; - fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque); - } else { - fdsetfd_info->value->has_opaque = false; - } - - fdsetfd_info->next = fdsetfd_list; - fdsetfd_list = fdsetfd_info; - } - - fdset_info->value->fds = fdsetfd_list; - - fdset_info->next = fdset_list; - fdset_list = fdset_info; - } - - return fdset_list; -} - -AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id, - bool has_opaque, const char *opaque, - Error **errp) -{ - MonFdset *mon_fdset = NULL; - MonFdsetFd *mon_fdset_fd; - AddfdInfo *fdinfo; - - if (has_fdset_id) { - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - /* Break if match found or match impossible due to ordering by ID */ - if (fdset_id <= mon_fdset->id) { - if (fdset_id < mon_fdset->id) { - mon_fdset = NULL; - } - break; - } - } - } - - if (mon_fdset == NULL) { - int64_t fdset_id_prev = -1; - MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets); - - if (has_fdset_id) { - if (fdset_id < 0) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id", - "a non-negative value"); - return NULL; - } - /* Use specified fdset ID */ - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - mon_fdset_cur = mon_fdset; - if (fdset_id < mon_fdset_cur->id) { - break; - } - } - } else { - /* Use first available fdset ID */ - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - mon_fdset_cur = mon_fdset; - if (fdset_id_prev == mon_fdset_cur->id - 1) { - fdset_id_prev = mon_fdset_cur->id; - continue; - } - break; - } - } - - mon_fdset = g_malloc0(sizeof(*mon_fdset)); - if (has_fdset_id) { - mon_fdset->id = fdset_id; - } else { - mon_fdset->id = fdset_id_prev + 1; - } - - /* The fdset list is ordered by fdset ID */ - if (!mon_fdset_cur) { - QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next); - } else if (mon_fdset->id < mon_fdset_cur->id) { - QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next); - } else { - QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next); - } - } - - mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd)); - mon_fdset_fd->fd = fd; - mon_fdset_fd->removed = false; - if (has_opaque) { - mon_fdset_fd->opaque = g_strdup(opaque); - } - QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next); - - fdinfo = g_malloc0(sizeof(*fdinfo)); - fdinfo->fdset_id = mon_fdset->id; - fdinfo->fd = mon_fdset_fd->fd; - - return fdinfo; -} - -int monitor_fdset_get_fd(int64_t fdset_id, int flags) -{ -#ifndef _WIN32 - MonFdset *mon_fdset; - MonFdsetFd *mon_fdset_fd; - int mon_fd_flags; - - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - if (mon_fdset->id != fdset_id) { - continue; - } - QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { - mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL); - if (mon_fd_flags == -1) { - return -1; - } - - if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) { - return mon_fdset_fd->fd; - } - } - errno = EACCES; - return -1; - } -#endif - - errno = ENOENT; - return -1; -} - -int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd) -{ - MonFdset *mon_fdset; - MonFdsetFd *mon_fdset_fd_dup; - - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - if (mon_fdset->id != fdset_id) { - continue; - } - QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { - if (mon_fdset_fd_dup->fd == dup_fd) { - return -1; - } - } - mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup)); - mon_fdset_fd_dup->fd = dup_fd; - QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next); - return 0; - } - return -1; -} - -static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove) -{ - MonFdset *mon_fdset; - MonFdsetFd *mon_fdset_fd_dup; - - QLIST_FOREACH(mon_fdset, &mon_fdsets, next) { - QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) { - if (mon_fdset_fd_dup->fd == dup_fd) { - if (remove) { - QLIST_REMOVE(mon_fdset_fd_dup, next); - if (QLIST_EMPTY(&mon_fdset->dup_fds)) { - monitor_fdset_cleanup(mon_fdset); - } - return -1; - } else { - return mon_fdset->id; - } - } - } - } - return -1; -} - -int monitor_fdset_dup_fd_find(int dup_fd) -{ - return monitor_fdset_dup_fd_find_remove(dup_fd, false); -} - -void monitor_fdset_dup_fd_remove(int dup_fd) -{ - monitor_fdset_dup_fd_find_remove(dup_fd, true); -} - -int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp) -{ - int fd; - Error *local_err = NULL; - - if (!qemu_isdigit(fdname[0]) && mon) { - fd = monitor_get_fd(mon, fdname, &local_err); - } else { - fd = qemu_parse_fd(fdname); - if (fd == -1) { - error_setg(&local_err, "Invalid file descriptor number '%s'", - fdname); - } - } - if (local_err) { - error_propagate(errp, local_err); - assert(fd == -1); - } else { - assert(fd != -1); - } - - return fd; -} - -/* Please update hmp-commands.hx when adding or changing commands */ -static mon_cmd_t info_cmds[] = { -#include "hmp-commands-info.h" - { NULL, NULL, }, -}; - -/* mon_cmds and info_cmds would be sorted at runtime */ -static mon_cmd_t mon_cmds[] = { -#include "hmp-commands.h" - { NULL, NULL, }, -}; - -static const mon_cmd_t qmp_cmds[] = { -#include "qmp-commands-old.h" - { /* NULL */ }, -}; - -/*******************************************************************/ - -static const char *pch; -static sigjmp_buf expr_env; - -static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN -expr_error(Monitor *mon, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - monitor_vprintf(mon, fmt, ap); - monitor_printf(mon, "\n"); - va_end(ap); - siglongjmp(expr_env, 1); -} - -/* return 0 if OK, -1 if not found */ -static int get_monitor_def(target_long *pval, const char *name) -{ - const MonitorDef *md = target_monitor_defs(); - void *ptr; - uint64_t tmp = 0; - int ret; - - if (md == NULL) { - return -1; - } - - for(; md->name != NULL; md++) { - if (compare_cmd(name, md->name)) { - if (md->get_value) { - *pval = md->get_value(md, md->offset); - } else { - CPUArchState *env = mon_get_cpu_env(); - ptr = (uint8_t *)env + md->offset; - switch(md->type) { - case MD_I32: - *pval = *(int32_t *)ptr; - break; - case MD_TLONG: - *pval = *(target_long *)ptr; - break; - default: - *pval = 0; - break; - } - } - return 0; - } - } - - ret = target_get_monitor_def(mon_get_cpu(), name, &tmp); - if (!ret) { - *pval = (target_long) tmp; - } - - return ret; -} - -static void next(void) -{ - if (*pch != '\0') { - pch++; - while (qemu_isspace(*pch)) - pch++; - } -} - -static int64_t expr_sum(Monitor *mon); - -static int64_t expr_unary(Monitor *mon) -{ - int64_t n; - char *p; - int ret; - - switch(*pch) { - case '+': - next(); - n = expr_unary(mon); - break; - case '-': - next(); - n = -expr_unary(mon); - break; - case '~': - next(); - n = ~expr_unary(mon); - break; - case '(': - next(); - n = expr_sum(mon); - if (*pch != ')') { - expr_error(mon, "')' expected"); - } - next(); - break; - case '\'': - pch++; - if (*pch == '\0') - expr_error(mon, "character constant expected"); - n = *pch; - pch++; - if (*pch != '\'') - expr_error(mon, "missing terminating \' character"); - next(); - break; - case '$': - { - char buf[128], *q; - target_long reg=0; - - pch++; - q = buf; - while ((*pch >= 'a' && *pch <= 'z') || - (*pch >= 'A' && *pch <= 'Z') || - (*pch >= '0' && *pch <= '9') || - *pch == '_' || *pch == '.') { - if ((q - buf) < sizeof(buf) - 1) - *q++ = *pch; - pch++; - } - while (qemu_isspace(*pch)) - pch++; - *q = 0; - ret = get_monitor_def(®, buf); - if (ret < 0) - expr_error(mon, "unknown register"); - n = reg; - } - break; - case '\0': - expr_error(mon, "unexpected end of expression"); - n = 0; - break; - default: - errno = 0; - n = strtoull(pch, &p, 0); - if (errno == ERANGE) { - expr_error(mon, "number too large"); - } - if (pch == p) { - expr_error(mon, "invalid char '%c' in expression", *p); - } - pch = p; - while (qemu_isspace(*pch)) - pch++; - break; - } - return n; -} - - -static int64_t expr_prod(Monitor *mon) -{ - int64_t val, val2; - int op; - - val = expr_unary(mon); - for(;;) { - op = *pch; - if (op != '*' && op != '/' && op != '%') - break; - next(); - val2 = expr_unary(mon); - switch(op) { - default: - case '*': - val *= val2; - break; - case '/': - case '%': - if (val2 == 0) - expr_error(mon, "division by zero"); - if (op == '/') - val /= val2; - else - val %= val2; - break; - } - } - return val; -} - -static int64_t expr_logic(Monitor *mon) -{ - int64_t val, val2; - int op; - - val = expr_prod(mon); - for(;;) { - op = *pch; - if (op != '&' && op != '|' && op != '^') - break; - next(); - val2 = expr_prod(mon); - switch(op) { - default: - case '&': - val &= val2; - break; - case '|': - val |= val2; - break; - case '^': - val ^= val2; - break; - } - } - return val; -} - -static int64_t expr_sum(Monitor *mon) -{ - int64_t val, val2; - int op; - - val = expr_logic(mon); - for(;;) { - op = *pch; - if (op != '+' && op != '-') - break; - next(); - val2 = expr_logic(mon); - if (op == '+') - val += val2; - else - val -= val2; - } - return val; -} - -static int get_expr(Monitor *mon, int64_t *pval, const char **pp) -{ - pch = *pp; - if (sigsetjmp(expr_env, 0)) { - *pp = pch; - return -1; - } - while (qemu_isspace(*pch)) - pch++; - *pval = expr_sum(mon); - *pp = pch; - return 0; -} - -static int get_double(Monitor *mon, double *pval, const char **pp) -{ - const char *p = *pp; - char *tailp; - double d; - - d = strtod(p, &tailp); - if (tailp == p) { - monitor_printf(mon, "Number expected\n"); - return -1; - } - if (d != d || d - d != 0) { - /* NaN or infinity */ - monitor_printf(mon, "Bad number\n"); - return -1; - } - *pval = d; - *pp = tailp; - return 0; -} - -/* - * Store the command-name in cmdname, and return a pointer to - * the remaining of the command string. - */ -static const char *get_command_name(const char *cmdline, - char *cmdname, size_t nlen) -{ - size_t len; - const char *p, *pstart; - - p = cmdline; - while (qemu_isspace(*p)) - p++; - if (*p == '\0') - return NULL; - pstart = p; - while (*p != '\0' && *p != '/' && !qemu_isspace(*p)) - p++; - len = p - pstart; - if (len > nlen - 1) - len = nlen - 1; - memcpy(cmdname, pstart, len); - cmdname[len] = '\0'; - return p; -} - -/** - * Read key of 'type' into 'key' and return the current - * 'type' pointer. - */ -static char *key_get_info(const char *type, char **key) -{ - size_t len; - char *p, *str; - - if (*type == ',') - type++; - - p = strchr(type, ':'); - if (!p) { - *key = NULL; - return NULL; - } - len = p - type; - - str = g_malloc(len + 1); - memcpy(str, type, len); - str[len] = '\0'; - - *key = str; - return ++p; -} - -static int default_fmt_format = 'x'; -static int default_fmt_size = 4; - -static int is_valid_option(const char *c, const char *typestr) -{ - char option[3]; - - option[0] = '-'; - option[1] = *c; - option[2] = '\0'; - - typestr = strstr(typestr, option); - return (typestr != NULL); -} - -static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table, - const char *cmdname) -{ - const mon_cmd_t *cmd; - - for (cmd = disp_table; cmd->name != NULL; cmd++) { - if (compare_cmd(cmdname, cmd->name)) { - return cmd; - } - } - - return NULL; -} - -static const mon_cmd_t *qmp_find_cmd(const char *cmdname) -{ - return search_dispatch_table(qmp_cmds, cmdname); -} - -/* - * Parse command name from @cmdp according to command table @table. - * If blank, return NULL. - * Else, if no valid command can be found, report to @mon, and return - * NULL. - * Else, change @cmdp to point right behind the name, and return its - * command table entry. - * Do not assume the return value points into @table! It doesn't when - * the command is found in a sub-command table. - */ -static const mon_cmd_t *monitor_parse_command(Monitor *mon, - const char **cmdp, - mon_cmd_t *table) -{ - const char *p; - const mon_cmd_t *cmd; - char cmdname[256]; - - /* extract the command name */ - p = get_command_name(*cmdp, cmdname, sizeof(cmdname)); - if (!p) - return NULL; - - cmd = search_dispatch_table(table, cmdname); - if (!cmd) { - monitor_printf(mon, "unknown command: '%.*s'\n", - (int)(p - *cmdp), *cmdp); - return NULL; - } - - /* filter out following useless space */ - while (qemu_isspace(*p)) { - p++; - } - - *cmdp = p; - /* search sub command */ - if (cmd->sub_table != NULL && *p != '\0') { - return monitor_parse_command(mon, cmdp, cmd->sub_table); - } - - return cmd; -} - -/* - * Parse arguments for @cmd. - * If it can't be parsed, report to @mon, and return NULL. - * Else, insert command arguments into a QDict, and return it. - * Note: On success, caller has to free the QDict structure. - */ - -static QDict *monitor_parse_arguments(Monitor *mon, - const char **endp, - const mon_cmd_t *cmd) -{ - const char *typestr; - char *key; - int c; - const char *p = *endp; - char buf[1024]; - QDict *qdict = qdict_new(); - - /* parse the parameters */ - typestr = cmd->args_type; - for(;;) { - typestr = key_get_info(typestr, &key); - if (!typestr) - break; - c = *typestr; - typestr++; - switch(c) { - case 'F': - case 'B': - case 's': - { - int ret; - - while (qemu_isspace(*p)) - p++; - if (*typestr == '?') { - typestr++; - if (*p == '\0') { - /* no optional string: NULL argument */ - break; - } - } - ret = get_str(buf, sizeof(buf), &p); - if (ret < 0) { - switch(c) { - case 'F': - monitor_printf(mon, "%s: filename expected\n", - cmd->name); - break; - case 'B': - monitor_printf(mon, "%s: block device name expected\n", - cmd->name); - break; - default: - monitor_printf(mon, "%s: string expected\n", cmd->name); - break; - } - goto fail; - } - qdict_put(qdict, key, qstring_from_str(buf)); - } - break; - case 'O': - { - QemuOptsList *opts_list; - QemuOpts *opts; - - opts_list = qemu_find_opts(key); - if (!opts_list || opts_list->desc->name) { - goto bad_type; - } - while (qemu_isspace(*p)) { - p++; - } - if (!*p) - break; - if (get_str(buf, sizeof(buf), &p) < 0) { - goto fail; - } - opts = qemu_opts_parse_noisily(opts_list, buf, true); - if (!opts) { - goto fail; - } - qemu_opts_to_qdict(opts, qdict); - qemu_opts_del(opts); - } - break; - case '/': - { - int count, format, size; - - while (qemu_isspace(*p)) - p++; - if (*p == '/') { - /* format found */ - p++; - count = 1; - if (qemu_isdigit(*p)) { - count = 0; - while (qemu_isdigit(*p)) { - count = count * 10 + (*p - '0'); - p++; - } - } - size = -1; - format = -1; - for(;;) { - switch(*p) { - case 'o': - case 'd': - case 'u': - case 'x': - case 'i': - case 'c': - format = *p++; - break; - case 'b': - size = 1; - p++; - break; - case 'h': - size = 2; - p++; - break; - case 'w': - size = 4; - p++; - break; - case 'g': - case 'L': - size = 8; - p++; - break; - default: - goto next; - } - } - next: - if (*p != '\0' && !qemu_isspace(*p)) { - monitor_printf(mon, "invalid char in format: '%c'\n", - *p); - goto fail; - } - if (format < 0) - format = default_fmt_format; - if (format != 'i') { - /* for 'i', not specifying a size gives -1 as size */ - if (size < 0) - size = default_fmt_size; - default_fmt_size = size; - } - default_fmt_format = format; - } else { - count = 1; - format = default_fmt_format; - if (format != 'i') { - size = default_fmt_size; - } else { - size = -1; - } - } - qdict_put(qdict, "count", qint_from_int(count)); - qdict_put(qdict, "format", qint_from_int(format)); - qdict_put(qdict, "size", qint_from_int(size)); - } - break; - case 'i': - case 'l': - case 'M': - { - int64_t val; - - while (qemu_isspace(*p)) - p++; - if (*typestr == '?' || *typestr == '.') { - if (*typestr == '?') { - if (*p == '\0') { - typestr++; - break; - } - } else { - if (*p == '.') { - p++; - while (qemu_isspace(*p)) - p++; - } else { - typestr++; - break; - } - } - typestr++; - } - if (get_expr(mon, &val, &p)) - goto fail; - /* Check if 'i' is greater than 32-bit */ - if ((c == 'i') && ((val >> 32) & 0xffffffff)) { - monitor_printf(mon, "\'%s\' has failed: ", cmd->name); - monitor_printf(mon, "integer is for 32-bit values\n"); - goto fail; - } else if (c == 'M') { - if (val < 0) { - monitor_printf(mon, "enter a positive value\n"); - goto fail; - } - val <<= 20; - } - qdict_put(qdict, key, qint_from_int(val)); - } - break; - case 'o': - { - int64_t val; - char *end; - - while (qemu_isspace(*p)) { - p++; - } - if (*typestr == '?') { - typestr++; - if (*p == '\0') { - break; - } - } - val = qemu_strtosz(p, &end); - if (val < 0) { - monitor_printf(mon, "invalid size\n"); - goto fail; - } - qdict_put(qdict, key, qint_from_int(val)); - p = end; - } - break; - case 'T': - { - double val; - - while (qemu_isspace(*p)) - p++; - if (*typestr == '?') { - typestr++; - if (*p == '\0') { - break; - } - } - if (get_double(mon, &val, &p) < 0) { - goto fail; - } - if (p[0] && p[1] == 's') { - switch (*p) { - case 'm': - val /= 1e3; p += 2; break; - case 'u': - val /= 1e6; p += 2; break; - case 'n': - val /= 1e9; p += 2; break; - } - } - if (*p && !qemu_isspace(*p)) { - monitor_printf(mon, "Unknown unit suffix\n"); - goto fail; - } - qdict_put(qdict, key, qfloat_from_double(val)); - } - break; - case 'b': - { - const char *beg; - bool val; - - while (qemu_isspace(*p)) { - p++; - } - beg = p; - while (qemu_isgraph(*p)) { - p++; - } - if (p - beg == 2 && !memcmp(beg, "on", p - beg)) { - val = true; - } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) { - val = false; - } else { - monitor_printf(mon, "Expected 'on' or 'off'\n"); - goto fail; - } - qdict_put(qdict, key, qbool_from_bool(val)); - } - break; - case '-': - { - const char *tmp = p; - int skip_key = 0; - /* option */ - - c = *typestr++; - if (c == '\0') - goto bad_type; - while (qemu_isspace(*p)) - p++; - if (*p == '-') { - p++; - if(c != *p) { - if(!is_valid_option(p, typestr)) { - - monitor_printf(mon, "%s: unsupported option -%c\n", - cmd->name, *p); - goto fail; - } else { - skip_key = 1; - } - } - if(skip_key) { - p = tmp; - } else { - /* has option */ - p++; - qdict_put(qdict, key, qbool_from_bool(true)); - } - } - } - break; - case 'S': - { - /* package all remaining string */ - int len; - - while (qemu_isspace(*p)) { - p++; - } - if (*typestr == '?') { - typestr++; - if (*p == '\0') { - /* no remaining string: NULL argument */ - break; - } - } - len = strlen(p); - if (len <= 0) { - monitor_printf(mon, "%s: string expected\n", - cmd->name); - goto fail; - } - qdict_put(qdict, key, qstring_from_str(p)); - p += len; - } - break; - default: - bad_type: - monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c); - goto fail; - } - g_free(key); - key = NULL; - } - /* check that all arguments were parsed */ - while (qemu_isspace(*p)) - p++; - if (*p != '\0') { - monitor_printf(mon, "%s: extraneous characters at the end of line\n", - cmd->name); - goto fail; - } - - return qdict; - -fail: - QDECREF(qdict); - g_free(key); - return NULL; -} - -static void handle_hmp_command(Monitor *mon, const char *cmdline) -{ - QDict *qdict; - const mon_cmd_t *cmd; - - cmd = monitor_parse_command(mon, &cmdline, mon->cmd_table); - if (!cmd) { - return; - } - - qdict = monitor_parse_arguments(mon, &cmdline, cmd); - if (!qdict) { - monitor_printf(mon, "Try \"help %s\" for more information\n", - cmd->name); - return; - } - - cmd->mhandler.cmd(mon, qdict); - QDECREF(qdict); -} - -static void cmd_completion(Monitor *mon, const char *name, const char *list) -{ - const char *p, *pstart; - char cmd[128]; - int len; - - p = list; - for(;;) { - pstart = p; - p = strchr(p, '|'); - if (!p) - p = pstart + strlen(pstart); - len = p - pstart; - if (len > sizeof(cmd) - 2) - len = sizeof(cmd) - 2; - memcpy(cmd, pstart, len); - cmd[len] = '\0'; - if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { - readline_add_completion(mon->rs, cmd); - } - if (*p == '\0') - break; - p++; - } -} - -static void file_completion(Monitor *mon, const char *input) -{ - DIR *ffs; - struct dirent *d; - char path[1024]; - char file[1024], file_prefix[1024]; - int input_path_len; - const char *p; - - p = strrchr(input, '/'); - if (!p) { - input_path_len = 0; - pstrcpy(file_prefix, sizeof(file_prefix), input); - pstrcpy(path, sizeof(path), "."); - } else { - input_path_len = p - input + 1; - memcpy(path, input, input_path_len); - if (input_path_len > sizeof(path) - 1) - input_path_len = sizeof(path) - 1; - path[input_path_len] = '\0'; - pstrcpy(file_prefix, sizeof(file_prefix), p + 1); - } - - ffs = opendir(path); - if (!ffs) - return; - for(;;) { - struct stat sb; - d = readdir(ffs); - if (!d) - break; - - if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) { - continue; - } - - if (strstart(d->d_name, file_prefix, NULL)) { - memcpy(file, input, input_path_len); - if (input_path_len < sizeof(file)) - pstrcpy(file + input_path_len, sizeof(file) - input_path_len, - d->d_name); - /* stat the file to find out if it's a directory. - * In that case add a slash to speed up typing long paths - */ - if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) { - pstrcat(file, sizeof(file), "/"); - } - readline_add_completion(mon->rs, file); - } - } - closedir(ffs); -} - -static const char *next_arg_type(const char *typestr) -{ - const char *p = strchr(typestr, ':'); - return (p != NULL ? ++p : typestr); -} - -static void add_completion_option(ReadLineState *rs, const char *str, - const char *option) -{ - if (!str || !option) { - return; - } - if (!strncmp(option, str, strlen(str))) { - readline_add_completion(rs, option); - } -} - -void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str) -{ - size_t len; - ChardevBackendInfoList *list, *start; - - if (nb_args != 2) { - return; - } - len = strlen(str); - readline_set_completion_index(rs, len); - - start = list = qmp_query_chardev_backends(NULL); - while (list) { - const char *chr_name = list->value->name; - - if (!strncmp(chr_name, str, len)) { - readline_add_completion(rs, chr_name); - } - list = list->next; - } - qapi_free_ChardevBackendInfoList(start); -} - -void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) -{ - size_t len; - int i; - - if (nb_args != 2) { - return; - } - len = strlen(str); - readline_set_completion_index(rs, len); - for (i = 0; NetClientOptionsKind_lookup[i]; i++) { - add_completion_option(rs, str, NetClientOptionsKind_lookup[i]); - } -} - -void device_add_completion(ReadLineState *rs, int nb_args, const char *str) -{ - GSList *list, *elt; - size_t len; - - if (nb_args != 2) { - return; - } - - len = strlen(str); - readline_set_completion_index(rs, len); - list = elt = object_class_get_list(TYPE_DEVICE, false); - while (elt) { - const char *name; - DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data, - TYPE_DEVICE); - name = object_class_get_name(OBJECT_CLASS(dc)); - - if (!dc->cannot_instantiate_with_device_add_yet - && !strncmp(name, str, len)) { - readline_add_completion(rs, name); - } - elt = elt->next; - } - g_slist_free(list); -} - -void object_add_completion(ReadLineState *rs, int nb_args, const char *str) -{ - GSList *list, *elt; - size_t len; - - if (nb_args != 2) { - return; - } - - len = strlen(str); - readline_set_completion_index(rs, len); - list = elt = object_class_get_list(TYPE_USER_CREATABLE, false); - while (elt) { - const char *name; - - name = object_class_get_name(OBJECT_CLASS(elt->data)); - if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) { - readline_add_completion(rs, name); - } - elt = elt->next; - } - g_slist_free(list); -} - -static void peripheral_device_del_completion(ReadLineState *rs, - const char *str, size_t len) -{ - Object *peripheral = container_get(qdev_get_machine(), "/peripheral"); - GSList *list, *item; - - list = qdev_build_hotpluggable_device_list(peripheral); - if (!list) { - return; - } - - for (item = list; item; item = g_slist_next(item)) { - DeviceState *dev = item->data; - - if (dev->id && !strncmp(str, dev->id, len)) { - readline_add_completion(rs, dev->id); - } - } - - g_slist_free(list); -} - -void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) -{ - size_t len; - ChardevInfoList *list, *start; - - if (nb_args != 2) { - return; - } - len = strlen(str); - readline_set_completion_index(rs, len); - - start = list = qmp_query_chardev(NULL); - while (list) { - ChardevInfo *chr = list->value; - - if (!strncmp(chr->label, str, len)) { - readline_add_completion(rs, chr->label); - } - list = list->next; - } - qapi_free_ChardevInfoList(start); -} - -static void ringbuf_completion(ReadLineState *rs, const char *str) -{ - size_t len; - ChardevInfoList *list, *start; - - len = strlen(str); - readline_set_completion_index(rs, len); - - start = list = qmp_query_chardev(NULL); - while (list) { - ChardevInfo *chr_info = list->value; - - if (!strncmp(chr_info->label, str, len)) { - CharDriverState *chr = qemu_chr_find(chr_info->label); - if (chr && chr_is_ringbuf(chr)) { - readline_add_completion(rs, chr_info->label); - } - } - list = list->next; - } - qapi_free_ChardevInfoList(start); -} - -void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str) -{ - if (nb_args != 2) { - return; - } - ringbuf_completion(rs, str); -} - -void device_del_completion(ReadLineState *rs, int nb_args, const char *str) -{ - size_t len; - - if (nb_args != 2) { - return; - } - - len = strlen(str); - readline_set_completion_index(rs, len); - peripheral_device_del_completion(rs, str, len); -} - -void object_del_completion(ReadLineState *rs, int nb_args, const char *str) -{ - ObjectPropertyInfoList *list, *start; - size_t len; - - if (nb_args != 2) { - return; - } - len = strlen(str); - readline_set_completion_index(rs, len); - - start = list = qmp_qom_list("/objects", NULL); - while (list) { - ObjectPropertyInfo *info = list->value; - - if (!strncmp(info->type, "child<", 5) - && !strncmp(info->name, str, len)) { - readline_add_completion(rs, info->name); - } - list = list->next; - } - qapi_free_ObjectPropertyInfoList(start); -} - -void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) -{ - int i; - char *sep; - size_t len; - - if (nb_args != 2) { - return; - } - sep = strrchr(str, '-'); - if (sep) { - str = sep + 1; - } - len = strlen(str); - readline_set_completion_index(rs, len); - for (i = 0; i < Q_KEY_CODE_MAX; i++) { - if (!strncmp(str, QKeyCode_lookup[i], len)) { - readline_add_completion(rs, QKeyCode_lookup[i]); - } - } -} - -void set_link_completion(ReadLineState *rs, int nb_args, const char *str) -{ - size_t len; - - len = strlen(str); - readline_set_completion_index(rs, len); - if (nb_args == 2) { - NetClientState *ncs[MAX_QUEUE_NUM]; - int count, i; - count = qemu_find_net_clients_except(NULL, ncs, - NET_CLIENT_OPTIONS_KIND_NONE, - MAX_QUEUE_NUM); - for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { - const char *name = ncs[i]->name; - if (!strncmp(str, name, len)) { - readline_add_completion(rs, name); - } - } - } else if (nb_args == 3) { - add_completion_option(rs, str, "on"); - add_completion_option(rs, str, "off"); - } -} - -void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str) -{ - int len, count, i; - NetClientState *ncs[MAX_QUEUE_NUM]; - - if (nb_args != 2) { - return; - } - - len = strlen(str); - readline_set_completion_index(rs, len); - count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC, - MAX_QUEUE_NUM); - for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { - QemuOpts *opts; - const char *name = ncs[i]->name; - if (strncmp(str, name, len)) { - continue; - } - opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name); - if (opts) { - readline_add_completion(rs, name); - } - } -} - -void trace_event_completion(ReadLineState *rs, int nb_args, const char *str) -{ - size_t len; - - len = strlen(str); - readline_set_completion_index(rs, len); - if (nb_args == 2) { - TraceEventID id; - for (id = 0; id < trace_event_count(); id++) { - const char *event_name = trace_event_get_name(trace_event_id(id)); - if (!strncmp(str, event_name, len)) { - readline_add_completion(rs, event_name); - } - } - } else if (nb_args == 3) { - add_completion_option(rs, str, "on"); - add_completion_option(rs, str, "off"); - } -} - -void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) -{ - int i; - - if (nb_args != 2) { - return; - } - readline_set_completion_index(rs, strlen(str)); - for (i = 0; WatchdogExpirationAction_lookup[i]; i++) { - add_completion_option(rs, str, WatchdogExpirationAction_lookup[i]); - } -} - -void migrate_set_capability_completion(ReadLineState *rs, int nb_args, - const char *str) -{ - size_t len; - - len = strlen(str); - readline_set_completion_index(rs, len); - if (nb_args == 2) { - int i; - for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { - const char *name = MigrationCapability_lookup[i]; - if (!strncmp(str, name, len)) { - readline_add_completion(rs, name); - } - } - } else if (nb_args == 3) { - add_completion_option(rs, str, "on"); - add_completion_option(rs, str, "off"); - } -} - -void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, - const char *str) -{ - size_t len; - - len = strlen(str); - readline_set_completion_index(rs, len); - if (nb_args == 2) { - int i; - for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) { - const char *name = MigrationParameter_lookup[i]; - if (!strncmp(str, name, len)) { - readline_add_completion(rs, name); - } - } - } -} - -void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str) -{ - int i; - size_t len; - if (nb_args != 2) { - return; - } - len = strlen(str); - readline_set_completion_index(rs, len); - for (i = 0; host_net_devices[i]; i++) { - if (!strncmp(host_net_devices[i], str, len)) { - readline_add_completion(rs, host_net_devices[i]); - } - } -} - -void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str) -{ - NetClientState *ncs[MAX_QUEUE_NUM]; - int count, i, len; - - len = strlen(str); - readline_set_completion_index(rs, len); - if (nb_args == 2) { - count = qemu_find_net_clients_except(NULL, ncs, - NET_CLIENT_OPTIONS_KIND_NONE, - MAX_QUEUE_NUM); - for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { - int id; - char name[16]; - - if (net_hub_id_for_client(ncs[i], &id)) { - continue; - } - snprintf(name, sizeof(name), "%d", id); - if (!strncmp(str, name, len)) { - readline_add_completion(rs, name); - } - } - return; - } else if (nb_args == 3) { - count = qemu_find_net_clients_except(NULL, ncs, - NET_CLIENT_OPTIONS_KIND_NIC, - MAX_QUEUE_NUM); - for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) { - int id; - const char *name; - - if (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT || - net_hub_id_for_client(ncs[i], &id)) { - continue; - } - name = ncs[i]->name; - if (!strncmp(str, name, len)) { - readline_add_completion(rs, name); - } - } - return; - } -} - -static void vm_completion(ReadLineState *rs, const char *str) -{ - size_t len; - BlockDriverState *bs = NULL; - - len = strlen(str); - readline_set_completion_index(rs, len); - while ((bs = bdrv_next(bs))) { - SnapshotInfoList *snapshots, *snapshot; - AioContext *ctx = bdrv_get_aio_context(bs); - bool ok = false; - - aio_context_acquire(ctx); - if (bdrv_can_snapshot(bs)) { - ok = bdrv_query_snapshot_info_list(bs, &snapshots, NULL) == 0; - } - aio_context_release(ctx); - if (!ok) { - continue; - } - - snapshot = snapshots; - while (snapshot) { - char *completion = snapshot->value->name; - if (!strncmp(str, completion, len)) { - readline_add_completion(rs, completion); - } - completion = snapshot->value->id; - if (!strncmp(str, completion, len)) { - readline_add_completion(rs, completion); - } - snapshot = snapshot->next; - } - qapi_free_SnapshotInfoList(snapshots); - } - -} - -void delvm_completion(ReadLineState *rs, int nb_args, const char *str) -{ - if (nb_args == 2) { - vm_completion(rs, str); - } -} - -void loadvm_completion(ReadLineState *rs, int nb_args, const char *str) -{ - if (nb_args == 2) { - vm_completion(rs, str); - } -} - -static void monitor_find_completion_by_table(Monitor *mon, - const mon_cmd_t *cmd_table, - char **args, - int nb_args) -{ - const char *cmdname; - int i; - const char *ptype, *str, *name; - const mon_cmd_t *cmd; - BlockDriverState *bs; - - if (nb_args <= 1) { - /* command completion */ - if (nb_args == 0) - cmdname = ""; - else - cmdname = args[0]; - readline_set_completion_index(mon->rs, strlen(cmdname)); - for (cmd = cmd_table; cmd->name != NULL; cmd++) { - cmd_completion(mon, cmdname, cmd->name); - } - } else { - /* find the command */ - for (cmd = cmd_table; cmd->name != NULL; cmd++) { - if (compare_cmd(args[0], cmd->name)) { - break; - } - } - if (!cmd->name) { - return; - } - - if (cmd->sub_table) { - /* do the job again */ - monitor_find_completion_by_table(mon, cmd->sub_table, - &args[1], nb_args - 1); - return; - } - if (cmd->command_completion) { - cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]); - return; - } - - ptype = next_arg_type(cmd->args_type); - for(i = 0; i < nb_args - 2; i++) { - if (*ptype != '\0') { - ptype = next_arg_type(ptype); - while (*ptype == '?') - ptype = next_arg_type(ptype); - } - } - str = args[nb_args - 1]; - while (*ptype == '-' && ptype[1] != '\0') { - ptype = next_arg_type(ptype); - } - switch(*ptype) { - case 'F': - /* file completion */ - readline_set_completion_index(mon->rs, strlen(str)); - file_completion(mon, str); - break; - case 'B': - /* block device name completion */ - readline_set_completion_index(mon->rs, strlen(str)); - for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) { - name = bdrv_get_device_name(bs); - if (str[0] == '\0' || - !strncmp(name, str, strlen(str))) { - readline_add_completion(mon->rs, name); - } - } - break; - case 's': - case 'S': - if (!strcmp(cmd->name, "help|?")) { - monitor_find_completion_by_table(mon, cmd_table, - &args[1], nb_args - 1); - } - break; - default: - break; - } - } -} - -static void monitor_find_completion(void *opaque, - const char *cmdline) -{ - Monitor *mon = opaque; - char *args[MAX_ARGS]; - int nb_args, len; - - /* 1. parse the cmdline */ - if (parse_cmdline(cmdline, &nb_args, args) < 0) { - return; - } - - /* if the line ends with a space, it means we want to complete the - next arg */ - len = strlen(cmdline); - if (len > 0 && qemu_isspace(cmdline[len - 1])) { - if (nb_args >= MAX_ARGS) { - goto cleanup; - } - args[nb_args++] = g_strdup(""); - } - - /* 2. auto complete according to args */ - monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args); - -cleanup: - free_cmdline_args(args, nb_args); -} - -static int monitor_can_read(void *opaque) -{ - Monitor *mon = opaque; - - return (mon->suspend_cnt == 0) ? 1 : 0; -} - -static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd, - Error **errp) -{ - bool is_cap = cmd->mhandler.cmd_new == qmp_capabilities; - - if (is_cap && mon->qmp.in_command_mode) { - error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, - "Capabilities negotiation is already complete, command " - "'%s' ignored", cmd->name); - return true; - } - if (!is_cap && !mon->qmp.in_command_mode) { - error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, - "Expecting capabilities negotiation with " - "'qmp_capabilities' before command '%s'", cmd->name); - return true; - } - return false; -} - -/* - * Argument validation rules: - * - * 1. The argument must exist in cmd_args qdict - * 2. The argument type must be the expected one - * - * Special case: If the argument doesn't exist in cmd_args and - * the QMP_ACCEPT_UNKNOWNS flag is set, then the - * checking is skipped for it. - */ -static void check_client_args_type(const QDict *client_args, - const QDict *cmd_args, int flags, - Error **errp) -{ - const QDictEntry *ent; - - for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){ - QObject *obj; - QString *arg_type; - const QObject *client_arg = qdict_entry_value(ent); - const char *client_arg_name = qdict_entry_key(ent); - - obj = qdict_get(cmd_args, client_arg_name); - if (!obj) { - if (flags & QMP_ACCEPT_UNKNOWNS) { - /* handler accepts unknowns */ - continue; - } - /* client arg doesn't exist */ - error_setg(errp, QERR_INVALID_PARAMETER, client_arg_name); - return; - } - - arg_type = qobject_to_qstring(obj); - assert(arg_type != NULL); - - /* check if argument's type is correct */ - switch (qstring_get_str(arg_type)[0]) { - case 'F': - case 'B': - case 's': - if (qobject_type(client_arg) != QTYPE_QSTRING) { - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, - client_arg_name, "string"); - return; - } - break; - case 'i': - case 'l': - case 'M': - case 'o': - if (qobject_type(client_arg) != QTYPE_QINT) { - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, - client_arg_name, "int"); - return; - } - break; - case 'T': - if (qobject_type(client_arg) != QTYPE_QINT && - qobject_type(client_arg) != QTYPE_QFLOAT) { - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, - client_arg_name, "number"); - return; - } - break; - case 'b': - case '-': - if (qobject_type(client_arg) != QTYPE_QBOOL) { - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, - client_arg_name, "bool"); - return; - } - break; - case 'O': - assert(flags & QMP_ACCEPT_UNKNOWNS); - break; - case 'q': - /* Any QObject can be passed. */ - break; - case '/': - case '.': - /* - * These types are not supported by QMP and thus are not - * handled here. Fall through. - */ - default: - abort(); - } - } -} - -/* - * - Check if the client has passed all mandatory args - * - Set special flags for argument validation - */ -static void check_mandatory_args(const QDict *cmd_args, - const QDict *client_args, int *flags, - Error **errp) -{ - const QDictEntry *ent; - - for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) { - const char *cmd_arg_name = qdict_entry_key(ent); - QString *type = qobject_to_qstring(qdict_entry_value(ent)); - assert(type != NULL); - - if (qstring_get_str(type)[0] == 'O') { - assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0); - *flags |= QMP_ACCEPT_UNKNOWNS; - } else if (qstring_get_str(type)[0] != '-' && - qstring_get_str(type)[1] != '?' && - !qdict_haskey(client_args, cmd_arg_name)) { - error_setg(errp, QERR_MISSING_PARAMETER, cmd_arg_name); - return; - } - } -} - -static QDict *qdict_from_args_type(const char *args_type) -{ - int i; - QDict *qdict; - QString *key, *type, *cur_qs; - - assert(args_type != NULL); - - qdict = qdict_new(); - - if (args_type == NULL || args_type[0] == '\0') { - /* no args, empty qdict */ - goto out; - } - - key = qstring_new(); - type = qstring_new(); - - cur_qs = key; - - for (i = 0;; i++) { - switch (args_type[i]) { - case ',': - case '\0': - qdict_put(qdict, qstring_get_str(key), type); - QDECREF(key); - if (args_type[i] == '\0') { - goto out; - } - type = qstring_new(); /* qdict has ref */ - cur_qs = key = qstring_new(); - break; - case ':': - cur_qs = type; - break; - default: - qstring_append_chr(cur_qs, args_type[i]); - break; - } - } - -out: - return qdict; -} - -/* - * Client argument checking rules: - * - * 1. Client must provide all mandatory arguments - * 2. Each argument provided by the client must be expected - * 3. Each argument provided by the client must have the type expected - * by the command - */ -static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args, - Error **errp) -{ - Error *err = NULL; - int flags; - QDict *cmd_args; - - cmd_args = qdict_from_args_type(cmd->args_type); - - flags = 0; - check_mandatory_args(cmd_args, client_args, &flags, &err); - if (err) { - goto out; - } - - check_client_args_type(client_args, cmd_args, flags, &err); - -out: - error_propagate(errp, err); - QDECREF(cmd_args); -} - -/* - * Input object checking rules - * - * 1. Input object must be a dict - * 2. The "execute" key must exist - * 3. The "execute" key must be a string - * 4. If the "arguments" key exists, it must be a dict - * 5. If the "id" key exists, it can be anything (ie. json-value) - * 6. Any argument not listed above is considered invalid - */ -static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp) -{ - const QDictEntry *ent; - int has_exec_key = 0; - QDict *input_dict; - - if (qobject_type(input_obj) != QTYPE_QDICT) { - error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "object"); - return NULL; - } - - input_dict = qobject_to_qdict(input_obj); - - for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){ - const char *arg_name = qdict_entry_key(ent); - const QObject *arg_obj = qdict_entry_value(ent); - - if (!strcmp(arg_name, "execute")) { - if (qobject_type(arg_obj) != QTYPE_QSTRING) { - error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, - "execute", "string"); - return NULL; - } - has_exec_key = 1; - } else if (!strcmp(arg_name, "arguments")) { - if (qobject_type(arg_obj) != QTYPE_QDICT) { - error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, - "arguments", "object"); - return NULL; - } - } else if (!strcmp(arg_name, "id")) { - /* Any string is acceptable as "id", so nothing to check */ - } else { - error_setg(errp, QERR_QMP_EXTRA_MEMBER, arg_name); - return NULL; - } - } - - if (!has_exec_key) { - error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute"); - return NULL; - } - - return input_dict; -} - -static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens) -{ - Error *local_err = NULL; - QObject *obj, *data; - QDict *input, *args; - const mon_cmd_t *cmd; - const char *cmd_name; - Monitor *mon = cur_mon; - - args = input = NULL; - data = NULL; - - obj = json_parser_parse(tokens, NULL); - if (!obj) { - // FIXME: should be triggered in json_parser_parse() - error_setg(&local_err, QERR_JSON_PARSING); - goto err_out; - } - - input = qmp_check_input_obj(obj, &local_err); - if (!input) { - qobject_decref(obj); - goto err_out; - } - - mon->qmp.id = qdict_get(input, "id"); - qobject_incref(mon->qmp.id); - - cmd_name = qdict_get_str(input, "execute"); - trace_handle_qmp_command(mon, cmd_name); - cmd = qmp_find_cmd(cmd_name); - if (!cmd) { - error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND, - "The command %s has not been found", cmd_name); - goto err_out; - } - if (invalid_qmp_mode(mon, cmd, &local_err)) { - goto err_out; - } - - obj = qdict_get(input, "arguments"); - if (!obj) { - args = qdict_new(); - } else { - args = qobject_to_qdict(obj); - QINCREF(args); - } - - qmp_check_client_args(cmd, args, &local_err); - if (local_err) { - goto err_out; - } - - cmd->mhandler.cmd_new(args, &data, &local_err); - -err_out: - monitor_protocol_emitter(mon, data, local_err); - qobject_decref(data); - error_free(local_err); - QDECREF(input); - QDECREF(args); -} - -static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size) -{ - Monitor *old_mon = cur_mon; - - cur_mon = opaque; - - json_message_parser_feed(&cur_mon->qmp.parser, (const char *) buf, size); - - cur_mon = old_mon; -} - -static void monitor_read(void *opaque, const uint8_t *buf, int size) -{ - Monitor *old_mon = cur_mon; - int i; - - cur_mon = opaque; - - if (cur_mon->rs) { - for (i = 0; i < size; i++) - readline_handle_byte(cur_mon->rs, buf[i]); - } else { - if (size == 0 || buf[size - 1] != 0) - monitor_printf(cur_mon, "corrupted command\n"); - else - handle_hmp_command(cur_mon, (char *)buf); - } - - cur_mon = old_mon; -} - -static void monitor_command_cb(void *opaque, const char *cmdline, - void *readline_opaque) -{ - Monitor *mon = opaque; - - monitor_suspend(mon); - handle_hmp_command(mon, cmdline); - monitor_resume(mon); -} - -int monitor_suspend(Monitor *mon) -{ - if (!mon->rs) - return -ENOTTY; - mon->suspend_cnt++; - return 0; -} - -void monitor_resume(Monitor *mon) -{ - if (!mon->rs) - return; - if (--mon->suspend_cnt == 0) - readline_show_prompt(mon->rs); -} - -static QObject *get_qmp_greeting(void) -{ - QObject *ver = NULL; - - qmp_marshal_query_version(NULL, &ver, NULL); - return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver); -} - -static void monitor_qmp_event(void *opaque, int event) -{ - QObject *data; - Monitor *mon = opaque; - - switch (event) { - case CHR_EVENT_OPENED: - mon->qmp.in_command_mode = false; - data = get_qmp_greeting(); - monitor_json_emitter(mon, data); - qobject_decref(data); - mon_refcount++; - break; - case CHR_EVENT_CLOSED: - json_message_parser_destroy(&mon->qmp.parser); - json_message_parser_init(&mon->qmp.parser, handle_qmp_command); - mon_refcount--; - monitor_fdsets_cleanup(); - break; - } -} - -static void monitor_event(void *opaque, int event) -{ - Monitor *mon = opaque; - - switch (event) { - case CHR_EVENT_MUX_IN: - qemu_mutex_lock(&mon->out_lock); - mon->mux_out = 0; - qemu_mutex_unlock(&mon->out_lock); - if (mon->reset_seen) { - readline_restart(mon->rs); - monitor_resume(mon); - monitor_flush(mon); - } else { - mon->suspend_cnt = 0; - } - break; - - case CHR_EVENT_MUX_OUT: - if (mon->reset_seen) { - if (mon->suspend_cnt == 0) { - monitor_printf(mon, "\n"); - } - monitor_flush(mon); - monitor_suspend(mon); - } else { - mon->suspend_cnt++; - } - qemu_mutex_lock(&mon->out_lock); - mon->mux_out = 1; - qemu_mutex_unlock(&mon->out_lock); - break; - - case CHR_EVENT_OPENED: - monitor_printf(mon, "QEMU %s monitor - type 'help' for more " - "information\n", QEMU_VERSION); - if (!mon->mux_out) { - readline_restart(mon->rs); - readline_show_prompt(mon->rs); - } - mon->reset_seen = 1; - mon_refcount++; - break; - - case CHR_EVENT_CLOSED: - mon_refcount--; - monitor_fdsets_cleanup(); - break; - } -} - -static int -compare_mon_cmd(const void *a, const void *b) -{ - return strcmp(((const mon_cmd_t *)a)->name, - ((const mon_cmd_t *)b)->name); -} - -static void sortcmdlist(void) -{ - int array_num; - int elem_size = sizeof(mon_cmd_t); - - array_num = sizeof(mon_cmds)/elem_size-1; - qsort((void *)mon_cmds, array_num, elem_size, compare_mon_cmd); - - array_num = sizeof(info_cmds)/elem_size-1; - qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd); -} - - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 8 - * End: - */ - -/* These functions just adapt the readline interface in a typesafe way. We - * could cast function pointers but that discards compiler checks. - */ -static void GCC_FMT_ATTR(2, 3) monitor_readline_printf(void *opaque, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - monitor_vprintf(opaque, fmt, ap); - va_end(ap); -} - -static void monitor_readline_flush(void *opaque) -{ - monitor_flush(opaque); -} - -static void __attribute__((constructor)) monitor_lock_init(void) -{ - qemu_mutex_init(&monitor_lock); -} - -void monitor_init(CharDriverState *chr, int flags) -{ - static int is_first_init = 1; - Monitor *mon; - - if (is_first_init) { - monitor_qapi_event_init(); - sortcmdlist(); - is_first_init = 0; - } - - mon = g_malloc(sizeof(*mon)); - monitor_data_init(mon); - - mon->chr = chr; - mon->flags = flags; - if (flags & MONITOR_USE_READLINE) { - mon->rs = readline_init(monitor_readline_printf, - monitor_readline_flush, - mon, - monitor_find_completion); - monitor_read_command(mon, 0); - } - - if (monitor_is_qmp(mon)) { - qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read, - monitor_qmp_event, mon); - qemu_chr_fe_set_echo(chr, true); - json_message_parser_init(&mon->qmp.parser, handle_qmp_command); - } else { - qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, - monitor_event, mon); - } - - qemu_mutex_lock(&monitor_lock); - QLIST_INSERT_HEAD(&mon_list, mon, entry); - qemu_mutex_unlock(&monitor_lock); -} - -static void bdrv_password_cb(void *opaque, const char *password, - void *readline_opaque) -{ - Monitor *mon = opaque; - BlockDriverState *bs = readline_opaque; - int ret = 0; - Error *local_err = NULL; - - bdrv_add_key(bs, password, &local_err); - if (local_err) { - monitor_printf(mon, "%s\n", error_get_pretty(local_err)); - error_free(local_err); - ret = -EPERM; - } - if (mon->password_completion_cb) - mon->password_completion_cb(mon->password_opaque, ret); - - monitor_read_command(mon, 1); -} - -int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, - BlockCompletionFunc *completion_cb, - void *opaque) -{ - int err; - - monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs), - bdrv_get_encrypted_filename(bs)); - - mon->password_completion_cb = completion_cb; - mon->password_opaque = opaque; - - err = monitor_read_password(mon, bdrv_password_cb, bs); - - if (err && completion_cb) - completion_cb(opaque, err); - - return err; -} - -int monitor_read_block_device_key(Monitor *mon, const char *device, - BlockCompletionFunc *completion_cb, - void *opaque) -{ - Error *err = NULL; - BlockBackend *blk; - - blk = blk_by_name(device); - if (!blk) { - monitor_printf(mon, "Device not found %s\n", device); - return -1; - } - if (!blk_bs(blk)) { - monitor_printf(mon, "Device '%s' has no medium\n", device); - return -1; - } - - bdrv_add_key(blk_bs(blk), NULL, &err); - if (err) { - error_free(err); - return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque); - } - - if (completion_cb) { - completion_cb(opaque, 0); - } - return 0; -} - -QemuOptsList qemu_mon_opts = { - .name = "mon", - .implied_opt_name = "chardev", - .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head), - .desc = { - { - .name = "mode", - .type = QEMU_OPT_STRING, - },{ - .name = "chardev", - .type = QEMU_OPT_STRING, - },{ - .name = "default", - .type = QEMU_OPT_BOOL, - },{ - .name = "pretty", - .type = QEMU_OPT_BOOL, - }, - { /* end of list */ } - }, -}; - -#ifndef TARGET_I386 -void qmp_rtc_reset_reinjection(Error **errp) -{ - error_setg(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection"); -} -#endif - -#ifndef TARGET_S390X -void qmp_dump_skeys(const char *filename, Error **errp) -{ - error_setg(errp, QERR_FEATURE_DISABLED, "dump-skeys"); -} -#endif diff --git a/qemu-char.c b/qemu-char.c deleted file mode 100644 index b7822865ae8ac..0000000000000 --- a/qemu-char.c +++ /dev/null @@ -1,4393 +0,0 @@ -/* - * QEMU System Emulator - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * 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-common.h" -#include "monitor/monitor.h" -#include "sysemu/sysemu.h" -#include "qemu/error-report.h" -#include "qemu/timer.h" -#include "sysemu/char.h" -#include "hw/usb.h" -#include "qmp-commands.h" -#include "qapi/qmp-input-visitor.h" -#include "qapi/qmp-output-visitor.h" -#include "qapi-visit.h" - -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_BSD -#include -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#elif defined(__DragonFly__) -#include -#include -#endif -#else -#ifdef __linux__ -#include -#include -#endif -#ifdef __sun__ -#include -#include -#include -#include -#include -#include -#include -#include // must come after ip.h -#include -#include -#endif -#endif -#endif - -#include "qemu/sockets.h" -#include "ui/qemu-spice.h" - -#define READ_BUF_LEN 4096 -#define READ_RETRIES 10 -#define CHR_MAX_FILENAME_SIZE 256 -#define TCP_MAX_FDS 16 - -/***********************************************************/ -/* Socket address helpers */ - -static int SocketAddress_to_str(char *dest, int max_len, - const char *prefix, SocketAddress *addr, - bool is_listen, bool is_telnet) -{ - switch (addr->type) { - case SOCKET_ADDRESS_KIND_INET: - return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix, - is_telnet ? "telnet" : "tcp", addr->u.inet->host, - addr->u.inet->port, is_listen ? ",server" : ""); - break; - case SOCKET_ADDRESS_KIND_UNIX: - return snprintf(dest, max_len, "%sunix:%s%s", prefix, - addr->u.q_unix->path, is_listen ? ",server" : ""); - break; - case SOCKET_ADDRESS_KIND_FD: - return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->u.fd->str, - is_listen ? ",server" : ""); - break; - default: - abort(); - } -} - -static int sockaddr_to_str(char *dest, int max_len, - struct sockaddr_storage *ss, socklen_t ss_len, - struct sockaddr_storage *ps, socklen_t ps_len, - bool is_listen, bool is_telnet) -{ - char shost[NI_MAXHOST], sserv[NI_MAXSERV]; - char phost[NI_MAXHOST], pserv[NI_MAXSERV]; - const char *left = "", *right = ""; - - switch (ss->ss_family) { -#ifndef _WIN32 - case AF_UNIX: - return snprintf(dest, max_len, "unix:%s%s", - ((struct sockaddr_un *)(ss))->sun_path, - is_listen ? ",server" : ""); -#endif - case AF_INET6: - left = "["; - right = "]"; - /* fall through */ - case AF_INET: - getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost), - sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV); - getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost), - pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV); - return snprintf(dest, max_len, "%s:%s%s%s:%s%s <-> %s%s%s:%s", - is_telnet ? "telnet" : "tcp", - left, shost, right, sserv, - is_listen ? ",server" : "", - left, phost, right, pserv); - - default: - return snprintf(dest, max_len, "unknown"); - } -} - -/***********************************************************/ -/* character device */ - -static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = - QTAILQ_HEAD_INITIALIZER(chardevs); - -CharDriverState *qemu_chr_alloc(void) -{ - CharDriverState *chr = g_malloc0(sizeof(CharDriverState)); - qemu_mutex_init(&chr->chr_write_lock); - return chr; -} - -void qemu_chr_be_event(CharDriverState *s, int event) -{ - /* Keep track if the char device is open */ - switch (event) { - case CHR_EVENT_OPENED: - s->be_open = 1; - break; - case CHR_EVENT_CLOSED: - s->be_open = 0; - break; - } - - if (!s->chr_event) - return; - s->chr_event(s->handler_opaque, event); -} - -void qemu_chr_be_generic_open(CharDriverState *s) -{ - qemu_chr_be_event(s, CHR_EVENT_OPENED); -} - -int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) -{ - int ret; - - qemu_mutex_lock(&s->chr_write_lock); - ret = s->chr_write(s, buf, len); - qemu_mutex_unlock(&s->chr_write_lock); - return ret; -} - -int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) -{ - int offset = 0; - int res = 0; - - qemu_mutex_lock(&s->chr_write_lock); - while (offset < len) { - do { - res = s->chr_write(s, buf + offset, len - offset); - if (res == -1 && errno == EAGAIN) { - g_usleep(100); - } - } while (res == -1 && errno == EAGAIN); - - if (res <= 0) { - break; - } - - offset += res; - } - qemu_mutex_unlock(&s->chr_write_lock); - - if (res < 0) { - return res; - } - return offset; -} - -int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len) -{ - int offset = 0, counter = 10; - int res; - - if (!s->chr_sync_read) { - return 0; - } - - while (offset < len) { - do { - res = s->chr_sync_read(s, buf + offset, len - offset); - if (res == -1 && errno == EAGAIN) { - g_usleep(100); - } - } while (res == -1 && errno == EAGAIN); - - if (res == 0) { - break; - } - - if (res < 0) { - return res; - } - - offset += res; - - if (!counter--) { - break; - } - } - - return offset; -} - -int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg) -{ - if (!s->chr_ioctl) - return -ENOTSUP; - return s->chr_ioctl(s, cmd, arg); -} - -int qemu_chr_be_can_write(CharDriverState *s) -{ - if (!s->chr_can_read) - return 0; - return s->chr_can_read(s->handler_opaque); -} - -void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len) -{ - if (s->chr_read) { - s->chr_read(s->handler_opaque, buf, len); - } -} - -int qemu_chr_fe_get_msgfd(CharDriverState *s) -{ - int fd; - return (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1; -} - -int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len) -{ - return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1; -} - -int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num) -{ - return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1; -} - -int qemu_chr_add_client(CharDriverState *s, int fd) -{ - return s->chr_add_client ? s->chr_add_client(s, fd) : -1; -} - -void qemu_chr_accept_input(CharDriverState *s) -{ - if (s->chr_accept_input) - s->chr_accept_input(s); - qemu_notify_event(); -} - -void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) -{ - char buf[READ_BUF_LEN]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf)); - va_end(ap); -} - -static void remove_fd_in_watch(CharDriverState *chr); - -void qemu_chr_add_handlers(CharDriverState *s, - IOCanReadHandler *fd_can_read, - IOReadHandler *fd_read, - IOEventHandler *fd_event, - void *opaque) -{ - int fe_open; - - if (!opaque && !fd_can_read && !fd_read && !fd_event) { - fe_open = 0; - remove_fd_in_watch(s); - } else { - fe_open = 1; - } - s->chr_can_read = fd_can_read; - s->chr_read = fd_read; - s->chr_event = fd_event; - s->handler_opaque = opaque; - if (fe_open && s->chr_update_read_handler) - s->chr_update_read_handler(s); - - if (!s->explicit_fe_open) { - qemu_chr_fe_set_open(s, fe_open); - } - - /* We're connecting to an already opened device, so let's make sure we - also get the open event */ - if (fe_open && s->be_open) { - qemu_chr_be_generic_open(s); - } -} - -static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - return len; -} - -static CharDriverState *qemu_chr_open_null(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - CharDriverState *chr; - - chr = qemu_chr_alloc(); - chr->chr_write = null_chr_write; - chr->explicit_be_open = true; - return chr; -} - -/* MUX driver for serial I/O splitting */ -#define MAX_MUX 4 -#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */ -#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1) -typedef struct { - IOCanReadHandler *chr_can_read[MAX_MUX]; - IOReadHandler *chr_read[MAX_MUX]; - IOEventHandler *chr_event[MAX_MUX]; - void *ext_opaque[MAX_MUX]; - CharDriverState *drv; - int focus; - int mux_cnt; - int term_got_escape; - int max_size; - /* Intermediate input buffer allows to catch escape sequences even if the - currently active device is not accepting any input - but only until it - is full as well. */ - unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE]; - int prod[MAX_MUX]; - int cons[MAX_MUX]; - int timestamps; - - /* Protected by the CharDriverState chr_write_lock. */ - int linestart; - int64_t timestamps_start; -} MuxDriver; - - -/* Called with chr_write_lock held. */ -static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - MuxDriver *d = chr->opaque; - int ret; - if (!d->timestamps) { - ret = qemu_chr_fe_write(d->drv, buf, len); - } else { - int i; - - ret = 0; - for (i = 0; i < len; i++) { - if (d->linestart) { - char buf1[64]; - int64_t ti; - int secs; - - ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); - if (d->timestamps_start == -1) - d->timestamps_start = ti; - ti -= d->timestamps_start; - secs = ti / 1000; - snprintf(buf1, sizeof(buf1), - "[%02d:%02d:%02d.%03d] ", - secs / 3600, - (secs / 60) % 60, - secs % 60, - (int)(ti % 1000)); - qemu_chr_fe_write(d->drv, (uint8_t *)buf1, strlen(buf1)); - d->linestart = 0; - } - ret += qemu_chr_fe_write(d->drv, buf+i, 1); - if (buf[i] == '\n') { - d->linestart = 1; - } - } - } - return ret; -} - -static const char * const mux_help[] = { - "% h print this help\n\r", - "% x exit emulator\n\r", - "% s save disk data back to file (if -snapshot)\n\r", - "% t toggle console timestamps\n\r", - "% b send break (magic sysrq)\n\r", - "% c switch between console and monitor\n\r", - "% % sends %\n\r", - NULL -}; - -int term_escape_char = 0x01; /* ctrl-a is used for escape */ -static void mux_print_help(CharDriverState *chr) -{ - int i, j; - char ebuf[15] = "Escape-Char"; - char cbuf[50] = "\n\r"; - - if (term_escape_char > 0 && term_escape_char < 26) { - snprintf(cbuf, sizeof(cbuf), "\n\r"); - snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a'); - } else { - snprintf(cbuf, sizeof(cbuf), - "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", - term_escape_char); - } - qemu_chr_fe_write(chr, (uint8_t *)cbuf, strlen(cbuf)); - for (i = 0; mux_help[i] != NULL; i++) { - for (j=0; mux_help[i][j] != '\0'; j++) { - if (mux_help[i][j] == '%') - qemu_chr_fe_write(chr, (uint8_t *)ebuf, strlen(ebuf)); - else - qemu_chr_fe_write(chr, (uint8_t *)&mux_help[i][j], 1); - } - } -} - -static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event) -{ - if (d->chr_event[mux_nr]) - d->chr_event[mux_nr](d->ext_opaque[mux_nr], event); -} - -static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) -{ - if (d->term_got_escape) { - d->term_got_escape = 0; - if (ch == term_escape_char) - goto send_char; - switch(ch) { - case '?': - case 'h': - mux_print_help(chr); - break; - case 'x': - { - const char *term = "QEMU: Terminated\n\r"; - qemu_chr_fe_write(chr, (uint8_t *)term, strlen(term)); - exit(0); - break; - } - case 's': - bdrv_commit_all(); - break; - case 'b': - qemu_chr_be_event(chr, CHR_EVENT_BREAK); - break; - case 'c': - /* Switch to the next registered device */ - mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); - d->focus++; - if (d->focus >= d->mux_cnt) - d->focus = 0; - mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); - break; - case 't': - d->timestamps = !d->timestamps; - d->timestamps_start = -1; - d->linestart = 0; - break; - } - } else if (ch == term_escape_char) { - d->term_got_escape = 1; - } else { - send_char: - return 1; - } - return 0; -} - -static void mux_chr_accept_input(CharDriverState *chr) -{ - MuxDriver *d = chr->opaque; - int m = d->focus; - - while (d->prod[m] != d->cons[m] && - d->chr_can_read[m] && - d->chr_can_read[m](d->ext_opaque[m])) { - d->chr_read[m](d->ext_opaque[m], - &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1); - } -} - -static int mux_chr_can_read(void *opaque) -{ - CharDriverState *chr = opaque; - MuxDriver *d = chr->opaque; - int m = d->focus; - - if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) - return 1; - if (d->chr_can_read[m]) - return d->chr_can_read[m](d->ext_opaque[m]); - return 0; -} - -static void mux_chr_read(void *opaque, const uint8_t *buf, int size) -{ - CharDriverState *chr = opaque; - MuxDriver *d = chr->opaque; - int m = d->focus; - int i; - - mux_chr_accept_input (opaque); - - for(i = 0; i < size; i++) - if (mux_proc_byte(chr, d, buf[i])) { - if (d->prod[m] == d->cons[m] && - d->chr_can_read[m] && - d->chr_can_read[m](d->ext_opaque[m])) - d->chr_read[m](d->ext_opaque[m], &buf[i], 1); - else - d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i]; - } -} - -static void mux_chr_event(void *opaque, int event) -{ - CharDriverState *chr = opaque; - MuxDriver *d = chr->opaque; - int i; - - /* Send the event to all registered listeners */ - for (i = 0; i < d->mux_cnt; i++) - mux_chr_send_event(d, i, event); -} - -static void mux_chr_update_read_handler(CharDriverState *chr) -{ - MuxDriver *d = chr->opaque; - - if (d->mux_cnt >= MAX_MUX) { - fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n"); - return; - } - d->ext_opaque[d->mux_cnt] = chr->handler_opaque; - d->chr_can_read[d->mux_cnt] = chr->chr_can_read; - d->chr_read[d->mux_cnt] = chr->chr_read; - d->chr_event[d->mux_cnt] = chr->chr_event; - /* Fix up the real driver with mux routines */ - if (d->mux_cnt == 0) { - qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read, - mux_chr_event, chr); - } - if (d->focus != -1) { - mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); - } - d->focus = d->mux_cnt; - d->mux_cnt++; - mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); -} - -static bool muxes_realized; - -/** - * Called after processing of default and command-line-specified - * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached - * to a mux chardev. This is done here to ensure that - * output/prompts/banners are only displayed for the FE that has - * focus when initial command-line processing/machine init is - * completed. - * - * After this point, any new FE attached to any new or existing - * mux will receive CHR_EVENT_OPENED notifications for the BE - * immediately. - */ -static void muxes_realize_done(Notifier *notifier, void *unused) -{ - CharDriverState *chr; - - QTAILQ_FOREACH(chr, &chardevs, next) { - if (chr->is_mux) { - MuxDriver *d = chr->opaque; - int i; - - /* send OPENED to all already-attached FEs */ - for (i = 0; i < d->mux_cnt; i++) { - mux_chr_send_event(d, i, CHR_EVENT_OPENED); - } - /* mark mux as OPENED so any new FEs will immediately receive - * OPENED event - */ - qemu_chr_be_generic_open(chr); - } - } - muxes_realized = true; -} - -static Notifier muxes_realize_notify = { - .notify = muxes_realize_done, -}; - -static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) -{ - MuxDriver *d = s->opaque; - return d->drv->chr_add_watch(d->drv, cond); -} - -static CharDriverState *qemu_chr_open_mux(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, Error **errp) -{ - ChardevMux *mux = backend->u.mux; - CharDriverState *chr, *drv; - MuxDriver *d; - - drv = qemu_chr_find(mux->chardev); - if (drv == NULL) { - error_setg(errp, "mux: base chardev %s not found", mux->chardev); - return NULL; - } - - chr = qemu_chr_alloc(); - d = g_new0(MuxDriver, 1); - - chr->opaque = d; - d->drv = drv; - d->focus = -1; - chr->chr_write = mux_chr_write; - chr->chr_update_read_handler = mux_chr_update_read_handler; - chr->chr_accept_input = mux_chr_accept_input; - /* Frontend guest-open / -close notification is not support with muxes */ - chr->chr_set_fe_open = NULL; - if (drv->chr_add_watch) { - chr->chr_add_watch = mux_chr_add_watch; - } - /* only default to opened state if we've realized the initial - * set of muxes - */ - chr->explicit_be_open = muxes_realized ? 0 : 1; - chr->is_mux = 1; - - return chr; -} - - -#ifdef _WIN32 -int send_all(int fd, const void *buf, int len1) -{ - int ret, len; - - len = len1; - while (len > 0) { - ret = send(fd, buf, len, 0); - if (ret < 0) { - errno = WSAGetLastError(); - if (errno != WSAEWOULDBLOCK) { - return -1; - } - } else if (ret == 0) { - break; - } else { - buf += ret; - len -= ret; - } - } - return len1 - len; -} - -#else - -int send_all(int fd, const void *_buf, int len1) -{ - int ret, len; - const uint8_t *buf = _buf; - - len = len1; - while (len > 0) { - ret = write(fd, buf, len); - if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) - return -1; - } else if (ret == 0) { - break; - } else { - buf += ret; - len -= ret; - } - } - return len1 - len; -} - -int recv_all(int fd, void *_buf, int len1, bool single_read) -{ - int ret, len; - uint8_t *buf = _buf; - - len = len1; - while ((len > 0) && (ret = read(fd, buf, len)) != 0) { - if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) { - return -1; - } - continue; - } else { - if (single_read) { - return ret; - } - buf += ret; - len -= ret; - } - } - return len1 - len; -} - -#endif /* !_WIN32 */ - -typedef struct IOWatchPoll -{ - GSource parent; - - GIOChannel *channel; - GSource *src; - - IOCanReadHandler *fd_can_read; - GSourceFunc fd_read; - void *opaque; -} IOWatchPoll; - -static IOWatchPoll *io_watch_poll_from_source(GSource *source) -{ - return container_of(source, IOWatchPoll, parent); -} - -static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_) -{ - IOWatchPoll *iwp = io_watch_poll_from_source(source); - bool now_active = iwp->fd_can_read(iwp->opaque) > 0; - bool was_active = iwp->src != NULL; - if (was_active == now_active) { - return FALSE; - } - - if (now_active) { - iwp->src = g_io_create_watch(iwp->channel, - G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); - g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL); - g_source_attach(iwp->src, NULL); - } else { - g_source_destroy(iwp->src); - g_source_unref(iwp->src); - iwp->src = NULL; - } - return FALSE; -} - -static gboolean io_watch_poll_check(GSource *source) -{ - return FALSE; -} - -static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback, - gpointer user_data) -{ - abort(); -} - -static void io_watch_poll_finalize(GSource *source) -{ - /* Due to a glib bug, removing the last reference to a source - * inside a finalize callback causes recursive locking (and a - * deadlock). This is not a problem inside other callbacks, - * including dispatch callbacks, so we call io_remove_watch_poll - * to remove this source. At this point, iwp->src must - * be NULL, or we would leak it. - * - * This would be solved much more elegantly by child sources, - * but we support older glib versions that do not have them. - */ - IOWatchPoll *iwp = io_watch_poll_from_source(source); - assert(iwp->src == NULL); -} - -static GSourceFuncs io_watch_poll_funcs = { - .prepare = io_watch_poll_prepare, - .check = io_watch_poll_check, - .dispatch = io_watch_poll_dispatch, - .finalize = io_watch_poll_finalize, -}; - -/* Can only be used for read */ -static guint io_add_watch_poll(GIOChannel *channel, - IOCanReadHandler *fd_can_read, - GIOFunc fd_read, - gpointer user_data) -{ - IOWatchPoll *iwp; - int tag; - - iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll)); - iwp->fd_can_read = fd_can_read; - iwp->opaque = user_data; - iwp->channel = channel; - iwp->fd_read = (GSourceFunc) fd_read; - iwp->src = NULL; - - tag = g_source_attach(&iwp->parent, NULL); - g_source_unref(&iwp->parent); - return tag; -} - -static void io_remove_watch_poll(guint tag) -{ - GSource *source; - IOWatchPoll *iwp; - - g_return_if_fail (tag > 0); - - source = g_main_context_find_source_by_id(NULL, tag); - g_return_if_fail (source != NULL); - - iwp = io_watch_poll_from_source(source); - if (iwp->src) { - g_source_destroy(iwp->src); - g_source_unref(iwp->src); - iwp->src = NULL; - } - g_source_destroy(&iwp->parent); -} - -static void remove_fd_in_watch(CharDriverState *chr) -{ - if (chr->fd_in_tag) { - io_remove_watch_poll(chr->fd_in_tag); - chr->fd_in_tag = 0; - } -} - -#ifndef _WIN32 -static GIOChannel *io_channel_from_fd(int fd) -{ - GIOChannel *chan; - - if (fd == -1) { - return NULL; - } - - chan = g_io_channel_unix_new(fd); - - g_io_channel_set_encoding(chan, NULL, NULL); - g_io_channel_set_buffered(chan, FALSE); - - return chan; -} -#endif - -static GIOChannel *io_channel_from_socket(int fd) -{ - GIOChannel *chan; - - if (fd == -1) { - return NULL; - } - -#ifdef _WIN32 - chan = g_io_channel_win32_new_socket(fd); -#else - chan = g_io_channel_unix_new(fd); -#endif - - g_io_channel_set_encoding(chan, NULL, NULL); - g_io_channel_set_buffered(chan, FALSE); - - return chan; -} - -static int io_channel_send(GIOChannel *fd, const void *buf, size_t len) -{ - size_t offset = 0; - GIOStatus status = G_IO_STATUS_NORMAL; - - while (offset < len && status == G_IO_STATUS_NORMAL) { - gsize bytes_written = 0; - - status = g_io_channel_write_chars(fd, buf + offset, len - offset, - &bytes_written, NULL); - offset += bytes_written; - } - - if (offset > 0) { - return offset; - } - switch (status) { - case G_IO_STATUS_NORMAL: - g_assert(len == 0); - return 0; - case G_IO_STATUS_AGAIN: - errno = EAGAIN; - return -1; - default: - break; - } - errno = EINVAL; - return -1; -} - -#ifndef _WIN32 - -typedef struct FDCharDriver { - CharDriverState *chr; - GIOChannel *fd_in, *fd_out; - int max_size; -} FDCharDriver; - -/* Called with chr_write_lock held. */ -static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - FDCharDriver *s = chr->opaque; - - return io_channel_send(s->fd_out, buf, len); -} - -static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) -{ - CharDriverState *chr = opaque; - FDCharDriver *s = chr->opaque; - int len; - uint8_t buf[READ_BUF_LEN]; - GIOStatus status; - gsize bytes_read; - - len = sizeof(buf); - if (len > s->max_size) { - len = s->max_size; - } - if (len == 0) { - return TRUE; - } - - status = g_io_channel_read_chars(chan, (gchar *)buf, - len, &bytes_read, NULL); - if (status == G_IO_STATUS_EOF) { - remove_fd_in_watch(chr); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); - return FALSE; - } - if (status == G_IO_STATUS_NORMAL) { - qemu_chr_be_write(chr, buf, bytes_read); - } - - return TRUE; -} - -static int fd_chr_read_poll(void *opaque) -{ - CharDriverState *chr = opaque; - FDCharDriver *s = chr->opaque; - - s->max_size = qemu_chr_be_can_write(chr); - return s->max_size; -} - -static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond) -{ - FDCharDriver *s = chr->opaque; - return g_io_create_watch(s->fd_out, cond); -} - -static void fd_chr_update_read_handler(CharDriverState *chr) -{ - FDCharDriver *s = chr->opaque; - - remove_fd_in_watch(chr); - if (s->fd_in) { - chr->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll, - fd_chr_read, chr); - } -} - -static void fd_chr_close(struct CharDriverState *chr) -{ - FDCharDriver *s = chr->opaque; - - remove_fd_in_watch(chr); - if (s->fd_in) { - g_io_channel_unref(s->fd_in); - } - if (s->fd_out) { - g_io_channel_unref(s->fd_out); - } - - g_free(s); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -} - -/* open a character device to a unix fd */ -static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) -{ - CharDriverState *chr; - FDCharDriver *s; - - chr = qemu_chr_alloc(); - s = g_new0(FDCharDriver, 1); - s->fd_in = io_channel_from_fd(fd_in); - s->fd_out = io_channel_from_fd(fd_out); - qemu_set_nonblock(fd_out); - s->chr = chr; - chr->opaque = s; - chr->chr_add_watch = fd_chr_add_watch; - chr->chr_write = fd_chr_write; - chr->chr_update_read_handler = fd_chr_update_read_handler; - chr->chr_close = fd_chr_close; - - return chr; -} - -static CharDriverState *qemu_chr_open_pipe(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevHostdev *opts = backend->u.pipe; - int fd_in, fd_out; - char filename_in[CHR_MAX_FILENAME_SIZE]; - char filename_out[CHR_MAX_FILENAME_SIZE]; - const char *filename = opts->device; - - snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename); - snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename); - TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY)); - TFR(fd_out = qemu_open(filename_out, O_RDWR | O_BINARY)); - if (fd_in < 0 || fd_out < 0) { - if (fd_in >= 0) - close(fd_in); - if (fd_out >= 0) - close(fd_out); - TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY)); - if (fd_in < 0) { - error_setg_file_open(errp, errno, filename); - return NULL; - } - } - return qemu_chr_open_fd(fd_in, fd_out); -} - -/* init terminal so that we can grab keys */ -static struct termios oldtty; -static int old_fd0_flags; -static bool stdio_in_use; -static bool stdio_allow_signal; -static bool stdio_echo_state; - -static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo); - -static void term_exit(void) -{ - tcsetattr (0, TCSANOW, &oldtty); - fcntl(0, F_SETFL, old_fd0_flags); -} - -static void term_stdio_handler(int sig) -{ - /* restore echo after resume from suspend. */ - qemu_chr_set_echo_stdio(NULL, stdio_echo_state); -} - -static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo) -{ - struct termios tty; - - stdio_echo_state = echo; - tty = oldtty; - if (!echo) { - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - } - if (!stdio_allow_signal) - tty.c_lflag &= ~ISIG; - - tcsetattr (0, TCSANOW, &tty); -} - -static void qemu_chr_close_stdio(struct CharDriverState *chr) -{ - term_exit(); - fd_chr_close(chr); -} - -static CharDriverState *qemu_chr_open_stdio(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevStdio *opts = backend->u.stdio; - CharDriverState *chr; - struct sigaction act; - - if (is_daemonized()) { - error_setg(errp, "cannot use stdio with -daemonize"); - return NULL; - } - - if (stdio_in_use) { - error_setg(errp, "cannot use stdio by multiple character devices"); - return NULL; - } - - stdio_in_use = true; - old_fd0_flags = fcntl(0, F_GETFL); - tcgetattr(0, &oldtty); - qemu_set_nonblock(0); - atexit(term_exit); - - memset(&act, 0, sizeof(act)); - act.sa_handler = term_stdio_handler; - sigaction(SIGCONT, &act, NULL); - - /* NOTE: on Mac OS (noticed on 10.9.5), we get buffer overruns if the stdout stream is - * line buffered and the underlying stdout file has O_NONBLOCK set. When the stream reaches - * the end of the buffer allocated to it by setvbuf, instead of wrapping to the beginning of - * the buffer again, it just starts trashing memory after the buffer. We can avoid this issue - * by changing the stream to be non-buffered. - */ - setvbuf(stdout, NULL, _IONBF, 0); - - chr = qemu_chr_open_fd(0, 1); - chr->chr_close = qemu_chr_close_stdio; - chr->chr_set_echo = qemu_chr_set_echo_stdio; - if (opts->has_signal) { - stdio_allow_signal = opts->signal; - } - qemu_chr_fe_set_echo(chr, false); - - return chr; -} - -#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ - || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \ - || defined(__GLIBC__) - -#define HAVE_CHARDEV_SERIAL 1 -#define HAVE_CHARDEV_PTY 1 - -typedef struct { - GIOChannel *fd; - int read_bytes; - - /* Protected by the CharDriverState chr_write_lock. */ - int connected; - guint timer_tag; - guint open_tag; -} PtyCharDriver; - -static void pty_chr_update_read_handler_locked(CharDriverState *chr); -static void pty_chr_state(CharDriverState *chr, int connected); - -static gboolean pty_chr_timer(gpointer opaque) -{ - struct CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; - - qemu_mutex_lock(&chr->chr_write_lock); - s->timer_tag = 0; - s->open_tag = 0; - if (!s->connected) { - /* Next poll ... */ - pty_chr_update_read_handler_locked(chr); - } - qemu_mutex_unlock(&chr->chr_write_lock); - return FALSE; -} - -/* Called with chr_write_lock held. */ -static void pty_chr_rearm_timer(CharDriverState *chr, int ms) -{ - PtyCharDriver *s = chr->opaque; - - if (s->timer_tag) { - g_source_remove(s->timer_tag); - s->timer_tag = 0; - } - - if (ms == 1000) { - s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr); - } else { - s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr); - } -} - -/* Called with chr_write_lock held. */ -static void pty_chr_update_read_handler_locked(CharDriverState *chr) -{ - PtyCharDriver *s = chr->opaque; - GPollFD pfd; - int rc; - - pfd.fd = g_io_channel_unix_get_fd(s->fd); - pfd.events = G_IO_OUT; - pfd.revents = 0; - do { - rc = g_poll(&pfd, 1, 0); - } while (rc == -1 && errno == EINTR); - assert(rc >= 0); - - if (pfd.revents & G_IO_HUP) { - pty_chr_state(chr, 0); - } else { - pty_chr_state(chr, 1); - } -} - -static void pty_chr_update_read_handler(CharDriverState *chr) -{ - qemu_mutex_lock(&chr->chr_write_lock); - pty_chr_update_read_handler_locked(chr); - qemu_mutex_unlock(&chr->chr_write_lock); -} - -/* Called with chr_write_lock held. */ -static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - PtyCharDriver *s = chr->opaque; - - if (!s->connected) { - /* guest sends data, check for (re-)connect */ - pty_chr_update_read_handler_locked(chr); - if (!s->connected) { - return 0; - } - } - return io_channel_send(s->fd, buf, len); -} - -static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond) -{ - PtyCharDriver *s = chr->opaque; - if (!s->connected) { - return NULL; - } - return g_io_create_watch(s->fd, cond); -} - -static int pty_chr_read_poll(void *opaque) -{ - CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; - - s->read_bytes = qemu_chr_be_can_write(chr); - return s->read_bytes; -} - -static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) -{ - CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; - gsize size, len; - uint8_t buf[READ_BUF_LEN]; - GIOStatus status; - - len = sizeof(buf); - if (len > s->read_bytes) - len = s->read_bytes; - if (len == 0) { - return TRUE; - } - status = g_io_channel_read_chars(s->fd, (gchar *)buf, len, &size, NULL); - if (status != G_IO_STATUS_NORMAL) { - pty_chr_state(chr, 0); - return FALSE; - } else { - pty_chr_state(chr, 1); - qemu_chr_be_write(chr, buf, size); - } - return TRUE; -} - -static gboolean qemu_chr_be_generic_open_func(gpointer opaque) -{ - CharDriverState *chr = opaque; - PtyCharDriver *s = chr->opaque; - - s->open_tag = 0; - qemu_chr_be_generic_open(chr); - return FALSE; -} - -/* Called with chr_write_lock held. */ -static void pty_chr_state(CharDriverState *chr, int connected) -{ - PtyCharDriver *s = chr->opaque; - - if (!connected) { - if (s->open_tag) { - g_source_remove(s->open_tag); - s->open_tag = 0; - } - remove_fd_in_watch(chr); - s->connected = 0; - /* (re-)connect poll interval for idle guests: once per second. - * We check more frequently in case the guests sends data to - * the virtual device linked to our pty. */ - pty_chr_rearm_timer(chr, 1000); - } else { - if (s->timer_tag) { - g_source_remove(s->timer_tag); - s->timer_tag = 0; - } - if (!s->connected) { - g_assert(s->open_tag == 0); - s->connected = 1; - s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr); - } - if (!chr->fd_in_tag) { - chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, - pty_chr_read, chr); - } - } -} - -static void pty_chr_close(struct CharDriverState *chr) -{ - PtyCharDriver *s = chr->opaque; - int fd; - - qemu_mutex_lock(&chr->chr_write_lock); - pty_chr_state(chr, 0); - fd = g_io_channel_unix_get_fd(s->fd); - g_io_channel_unref(s->fd); - close(fd); - if (s->timer_tag) { - g_source_remove(s->timer_tag); - s->timer_tag = 0; - } - qemu_mutex_unlock(&chr->chr_write_lock); - g_free(s); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -} - -static CharDriverState *qemu_chr_open_pty(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - CharDriverState *chr; - PtyCharDriver *s; - int master_fd, slave_fd; - char pty_name[PATH_MAX]; - - master_fd = qemu_openpty_raw(&slave_fd, pty_name); - if (master_fd < 0) { - error_setg_errno(errp, errno, "Failed to create PTY"); - return NULL; - } - - close(slave_fd); - qemu_set_nonblock(master_fd); - - chr = qemu_chr_alloc(); - - chr->filename = g_strdup_printf("pty:%s", pty_name); - ret->pty = g_strdup(pty_name); - ret->has_pty = true; - - fprintf(stderr, "char device redirected to %s (label %s)\n", - pty_name, id); - - s = g_new0(PtyCharDriver, 1); - chr->opaque = s; - chr->chr_write = pty_chr_write; - chr->chr_update_read_handler = pty_chr_update_read_handler; - chr->chr_close = pty_chr_close; - chr->chr_add_watch = pty_chr_add_watch; - chr->explicit_be_open = true; - - s->fd = io_channel_from_fd(master_fd); - s->timer_tag = 0; - - return chr; -} - -static void tty_serial_init(int fd, int speed, - int parity, int data_bits, int stop_bits) -{ - struct termios tty; - speed_t spd; - -#if 0 - printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n", - speed, parity, data_bits, stop_bits); -#endif - tcgetattr (fd, &tty); - -#define check_speed(val) if (speed <= val) { spd = B##val; break; } - speed = speed * 10 / 11; - do { - check_speed(50); - check_speed(75); - check_speed(110); - check_speed(134); - check_speed(150); - check_speed(200); - check_speed(300); - check_speed(600); - check_speed(1200); - check_speed(1800); - check_speed(2400); - check_speed(4800); - check_speed(9600); - check_speed(19200); - check_speed(38400); - /* Non-Posix values follow. They may be unsupported on some systems. */ - check_speed(57600); - check_speed(115200); -#ifdef B230400 - check_speed(230400); -#endif -#ifdef B460800 - check_speed(460800); -#endif -#ifdef B500000 - check_speed(500000); -#endif -#ifdef B576000 - check_speed(576000); -#endif -#ifdef B921600 - check_speed(921600); -#endif -#ifdef B1000000 - check_speed(1000000); -#endif -#ifdef B1152000 - check_speed(1152000); -#endif -#ifdef B1500000 - check_speed(1500000); -#endif -#ifdef B2000000 - check_speed(2000000); -#endif -#ifdef B2500000 - check_speed(2500000); -#endif -#ifdef B3000000 - check_speed(3000000); -#endif -#ifdef B3500000 - check_speed(3500000); -#endif -#ifdef B4000000 - check_speed(4000000); -#endif - spd = B115200; - } while (0); - - cfsetispeed(&tty, spd); - cfsetospeed(&tty, spd); - - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); - tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB); - switch(data_bits) { - default: - case 8: - tty.c_cflag |= CS8; - break; - case 7: - tty.c_cflag |= CS7; - break; - case 6: - tty.c_cflag |= CS6; - break; - case 5: - tty.c_cflag |= CS5; - break; - } - switch(parity) { - default: - case 'N': - break; - case 'E': - tty.c_cflag |= PARENB; - break; - case 'O': - tty.c_cflag |= PARENB | PARODD; - break; - } - if (stop_bits == 2) - tty.c_cflag |= CSTOPB; - - tcsetattr (fd, TCSANOW, &tty); -} - -static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) -{ - FDCharDriver *s = chr->opaque; - - switch(cmd) { - case CHR_IOCTL_SERIAL_SET_PARAMS: - { - QEMUSerialSetParams *ssp = arg; - tty_serial_init(g_io_channel_unix_get_fd(s->fd_in), - ssp->speed, ssp->parity, - ssp->data_bits, ssp->stop_bits); - } - break; - case CHR_IOCTL_SERIAL_SET_BREAK: - { - int enable = *(int *)arg; - if (enable) { - tcsendbreak(g_io_channel_unix_get_fd(s->fd_in), 1); - } - } - break; - case CHR_IOCTL_SERIAL_GET_TIOCM: - { - int sarg = 0; - int *targ = (int *)arg; - ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &sarg); - *targ = 0; - if (sarg & TIOCM_CTS) - *targ |= CHR_TIOCM_CTS; - if (sarg & TIOCM_CAR) - *targ |= CHR_TIOCM_CAR; - if (sarg & TIOCM_DSR) - *targ |= CHR_TIOCM_DSR; - if (sarg & TIOCM_RI) - *targ |= CHR_TIOCM_RI; - if (sarg & TIOCM_DTR) - *targ |= CHR_TIOCM_DTR; - if (sarg & TIOCM_RTS) - *targ |= CHR_TIOCM_RTS; - } - break; - case CHR_IOCTL_SERIAL_SET_TIOCM: - { - int sarg = *(int *)arg; - int targ = 0; - ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &targ); - targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR - | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS); - if (sarg & CHR_TIOCM_CTS) - targ |= TIOCM_CTS; - if (sarg & CHR_TIOCM_CAR) - targ |= TIOCM_CAR; - if (sarg & CHR_TIOCM_DSR) - targ |= TIOCM_DSR; - if (sarg & CHR_TIOCM_RI) - targ |= TIOCM_RI; - if (sarg & CHR_TIOCM_DTR) - targ |= TIOCM_DTR; - if (sarg & CHR_TIOCM_RTS) - targ |= TIOCM_RTS; - ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); - } - break; - default: - return -ENOTSUP; - } - return 0; -} - -static void qemu_chr_close_tty(CharDriverState *chr) -{ - FDCharDriver *s = chr->opaque; - int fd = -1; - - if (s) { - fd = g_io_channel_unix_get_fd(s->fd_in); - } - - fd_chr_close(chr); - - if (fd >= 0) { - close(fd); - } -} - -static CharDriverState *qemu_chr_open_tty_fd(int fd) -{ - CharDriverState *chr; - - tty_serial_init(fd, 115200, 'N', 8, 1); - chr = qemu_chr_open_fd(fd, fd); - chr->chr_ioctl = tty_serial_ioctl; - chr->chr_close = qemu_chr_close_tty; - return chr; -} -#endif /* __linux__ || __sun__ */ - -#if defined(__linux__) - -#define HAVE_CHARDEV_PARPORT 1 - -typedef struct { - int fd; - int mode; -} ParallelCharDriver; - -static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode) -{ - if (s->mode != mode) { - int m = mode; - if (ioctl(s->fd, PPSETMODE, &m) < 0) - return 0; - s->mode = mode; - } - return 1; -} - -static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) -{ - ParallelCharDriver *drv = chr->opaque; - int fd = drv->fd; - uint8_t b; - - switch(cmd) { - case CHR_IOCTL_PP_READ_DATA: - if (ioctl(fd, PPRDATA, &b) < 0) - return -ENOTSUP; - *(uint8_t *)arg = b; - break; - case CHR_IOCTL_PP_WRITE_DATA: - b = *(uint8_t *)arg; - if (ioctl(fd, PPWDATA, &b) < 0) - return -ENOTSUP; - break; - case CHR_IOCTL_PP_READ_CONTROL: - if (ioctl(fd, PPRCONTROL, &b) < 0) - return -ENOTSUP; - /* Linux gives only the lowest bits, and no way to know data - direction! For better compatibility set the fixed upper - bits. */ - *(uint8_t *)arg = b | 0xc0; - break; - case CHR_IOCTL_PP_WRITE_CONTROL: - b = *(uint8_t *)arg; - if (ioctl(fd, PPWCONTROL, &b) < 0) - return -ENOTSUP; - break; - case CHR_IOCTL_PP_READ_STATUS: - if (ioctl(fd, PPRSTATUS, &b) < 0) - return -ENOTSUP; - *(uint8_t *)arg = b; - break; - case CHR_IOCTL_PP_DATA_DIR: - if (ioctl(fd, PPDATADIR, (int *)arg) < 0) - return -ENOTSUP; - break; - case CHR_IOCTL_PP_EPP_READ_ADDR: - if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) { - struct ParallelIOArg *parg = arg; - int n = read(fd, parg->buffer, parg->count); - if (n != parg->count) { - return -EIO; - } - } - break; - case CHR_IOCTL_PP_EPP_READ: - if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) { - struct ParallelIOArg *parg = arg; - int n = read(fd, parg->buffer, parg->count); - if (n != parg->count) { - return -EIO; - } - } - break; - case CHR_IOCTL_PP_EPP_WRITE_ADDR: - if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) { - struct ParallelIOArg *parg = arg; - int n = write(fd, parg->buffer, parg->count); - if (n != parg->count) { - return -EIO; - } - } - break; - case CHR_IOCTL_PP_EPP_WRITE: - if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) { - struct ParallelIOArg *parg = arg; - int n = write(fd, parg->buffer, parg->count); - if (n != parg->count) { - return -EIO; - } - } - break; - default: - return -ENOTSUP; - } - return 0; -} - -static void pp_close(CharDriverState *chr) -{ - ParallelCharDriver *drv = chr->opaque; - int fd = drv->fd; - - pp_hw_mode(drv, IEEE1284_MODE_COMPAT); - ioctl(fd, PPRELEASE); - close(fd); - g_free(drv); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -} - -static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) -{ - CharDriverState *chr; - ParallelCharDriver *drv; - - if (ioctl(fd, PPCLAIM) < 0) { - error_setg_errno(errp, errno, "not a parallel port"); - close(fd); - return NULL; - } - - drv = g_new0(ParallelCharDriver, 1); - drv->fd = fd; - drv->mode = IEEE1284_MODE_COMPAT; - - chr = qemu_chr_alloc(); - chr->chr_write = null_chr_write; - chr->chr_ioctl = pp_ioctl; - chr->chr_close = pp_close; - chr->opaque = drv; - - return chr; -} -#endif /* __linux__ */ - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) - -#define HAVE_CHARDEV_PARPORT 1 - -static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) -{ - int fd = (int)(intptr_t)chr->opaque; - uint8_t b; - - switch(cmd) { - case CHR_IOCTL_PP_READ_DATA: - if (ioctl(fd, PPIGDATA, &b) < 0) - return -ENOTSUP; - *(uint8_t *)arg = b; - break; - case CHR_IOCTL_PP_WRITE_DATA: - b = *(uint8_t *)arg; - if (ioctl(fd, PPISDATA, &b) < 0) - return -ENOTSUP; - break; - case CHR_IOCTL_PP_READ_CONTROL: - if (ioctl(fd, PPIGCTRL, &b) < 0) - return -ENOTSUP; - *(uint8_t *)arg = b; - break; - case CHR_IOCTL_PP_WRITE_CONTROL: - b = *(uint8_t *)arg; - if (ioctl(fd, PPISCTRL, &b) < 0) - return -ENOTSUP; - break; - case CHR_IOCTL_PP_READ_STATUS: - if (ioctl(fd, PPIGSTATUS, &b) < 0) - return -ENOTSUP; - *(uint8_t *)arg = b; - break; - default: - return -ENOTSUP; - } - return 0; -} - -static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) -{ - CharDriverState *chr; - - chr = qemu_chr_alloc(); - chr->opaque = (void *)(intptr_t)fd; - chr->chr_write = null_chr_write; - chr->chr_ioctl = pp_ioctl; - chr->explicit_be_open = true; - return chr; -} -#endif - -#else /* _WIN32 */ - -#define HAVE_CHARDEV_SERIAL 1 - -typedef struct { - int max_size; - HANDLE hcom, hrecv, hsend; - OVERLAPPED orecv; - BOOL fpipe; - DWORD len; - - /* Protected by the CharDriverState chr_write_lock. */ - OVERLAPPED osend; -} WinCharState; - -typedef struct { - HANDLE hStdIn; - HANDLE hInputReadyEvent; - HANDLE hInputDoneEvent; - HANDLE hInputThread; - uint8_t win_stdio_buf; -} WinStdioCharState; - -#define NSENDBUF 2048 -#define NRECVBUF 2048 -#define MAXCONNECT 1 -#define NTIMEOUT 5000 - -static int win_chr_poll(void *opaque); -static int win_chr_pipe_poll(void *opaque); - -static void win_chr_close(CharDriverState *chr) -{ - WinCharState *s = chr->opaque; - - if (s->hsend) { - CloseHandle(s->hsend); - s->hsend = NULL; - } - if (s->hrecv) { - CloseHandle(s->hrecv); - s->hrecv = NULL; - } - if (s->hcom) { - CloseHandle(s->hcom); - s->hcom = NULL; - } - if (s->fpipe) - qemu_del_polling_cb(win_chr_pipe_poll, chr); - else - qemu_del_polling_cb(win_chr_poll, chr); - - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -} - -static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp) -{ - WinCharState *s = chr->opaque; - COMMCONFIG comcfg; - COMMTIMEOUTS cto = { 0, 0, 0, 0, 0}; - COMSTAT comstat; - DWORD size; - DWORD err; - - s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!s->hsend) { - error_setg(errp, "Failed CreateEvent"); - goto fail; - } - s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!s->hrecv) { - error_setg(errp, "Failed CreateEvent"); - goto fail; - } - - s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - if (s->hcom == INVALID_HANDLE_VALUE) { - error_setg(errp, "Failed CreateFile (%lu)", GetLastError()); - s->hcom = NULL; - goto fail; - } - - if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) { - error_setg(errp, "Failed SetupComm"); - goto fail; - } - - ZeroMemory(&comcfg, sizeof(COMMCONFIG)); - size = sizeof(COMMCONFIG); - GetDefaultCommConfig(filename, &comcfg, &size); - comcfg.dcb.DCBlength = sizeof(DCB); - CommConfigDialog(filename, NULL, &comcfg); - - if (!SetCommState(s->hcom, &comcfg.dcb)) { - error_setg(errp, "Failed SetCommState"); - goto fail; - } - - if (!SetCommMask(s->hcom, EV_ERR)) { - error_setg(errp, "Failed SetCommMask"); - goto fail; - } - - cto.ReadIntervalTimeout = MAXDWORD; - if (!SetCommTimeouts(s->hcom, &cto)) { - error_setg(errp, "Failed SetCommTimeouts"); - goto fail; - } - - if (!ClearCommError(s->hcom, &err, &comstat)) { - error_setg(errp, "Failed ClearCommError"); - goto fail; - } - qemu_add_polling_cb(win_chr_poll, chr); - return 0; - - fail: - win_chr_close(chr); - return -1; -} - -/* Called with chr_write_lock held. */ -static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1) -{ - WinCharState *s = chr->opaque; - DWORD len, ret, size, err; - - len = len1; - ZeroMemory(&s->osend, sizeof(s->osend)); - s->osend.hEvent = s->hsend; - while (len > 0) { - if (s->hsend) - ret = WriteFile(s->hcom, buf, len, &size, &s->osend); - else - ret = WriteFile(s->hcom, buf, len, &size, NULL); - if (!ret) { - err = GetLastError(); - if (err == ERROR_IO_PENDING) { - ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE); - if (ret) { - buf += size; - len -= size; - } else { - break; - } - } else { - break; - } - } else { - buf += size; - len -= size; - } - } - return len1 - len; -} - -static int win_chr_read_poll(CharDriverState *chr) -{ - WinCharState *s = chr->opaque; - - s->max_size = qemu_chr_be_can_write(chr); - return s->max_size; -} - -static void win_chr_readfile(CharDriverState *chr) -{ - WinCharState *s = chr->opaque; - int ret, err; - uint8_t buf[READ_BUF_LEN]; - DWORD size; - - ZeroMemory(&s->orecv, sizeof(s->orecv)); - s->orecv.hEvent = s->hrecv; - ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv); - if (!ret) { - err = GetLastError(); - if (err == ERROR_IO_PENDING) { - ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE); - } - } - - if (size > 0) { - qemu_chr_be_write(chr, buf, size); - } -} - -static void win_chr_read(CharDriverState *chr) -{ - WinCharState *s = chr->opaque; - - if (s->len > s->max_size) - s->len = s->max_size; - if (s->len == 0) - return; - - win_chr_readfile(chr); -} - -static int win_chr_poll(void *opaque) -{ - CharDriverState *chr = opaque; - WinCharState *s = chr->opaque; - COMSTAT status; - DWORD comerr; - - ClearCommError(s->hcom, &comerr, &status); - if (status.cbInQue > 0) { - s->len = status.cbInQue; - win_chr_read_poll(chr); - win_chr_read(chr); - return 1; - } - return 0; -} - -static CharDriverState *qemu_chr_open_win_path(const char *filename, - Error **errp) -{ - CharDriverState *chr; - WinCharState *s; - - chr = qemu_chr_alloc(); - s = g_new0(WinCharState, 1); - chr->opaque = s; - chr->chr_write = win_chr_write; - chr->chr_close = win_chr_close; - - if (win_chr_init(chr, filename, errp) < 0) { - g_free(s); - g_free(chr); - return NULL; - } - return chr; -} - -static int win_chr_pipe_poll(void *opaque) -{ - CharDriverState *chr = opaque; - WinCharState *s = chr->opaque; - DWORD size; - - PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL); - if (size > 0) { - s->len = size; - win_chr_read_poll(chr); - win_chr_read(chr); - return 1; - } - return 0; -} - -static int win_chr_pipe_init(CharDriverState *chr, const char *filename, - Error **errp) -{ - WinCharState *s = chr->opaque; - OVERLAPPED ov; - int ret; - DWORD size; - char openname[CHR_MAX_FILENAME_SIZE]; - - s->fpipe = TRUE; - - s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!s->hsend) { - error_setg(errp, "Failed CreateEvent"); - goto fail; - } - s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!s->hrecv) { - error_setg(errp, "Failed CreateEvent"); - goto fail; - } - - snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename); - s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | - PIPE_WAIT, - MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL); - if (s->hcom == INVALID_HANDLE_VALUE) { - error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError()); - s->hcom = NULL; - goto fail; - } - - ZeroMemory(&ov, sizeof(ov)); - ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - ret = ConnectNamedPipe(s->hcom, &ov); - if (ret) { - error_setg(errp, "Failed ConnectNamedPipe"); - goto fail; - } - - ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE); - if (!ret) { - error_setg(errp, "Failed GetOverlappedResult"); - if (ov.hEvent) { - CloseHandle(ov.hEvent); - ov.hEvent = NULL; - } - goto fail; - } - - if (ov.hEvent) { - CloseHandle(ov.hEvent); - ov.hEvent = NULL; - } - qemu_add_polling_cb(win_chr_pipe_poll, chr); - return 0; - - fail: - win_chr_close(chr); - return -1; -} - - -static CharDriverState *qemu_chr_open_pipe(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevHostdev *opts = backend->u.pipe; - const char *filename = opts->device; - CharDriverState *chr; - WinCharState *s; - - chr = qemu_chr_alloc(); - s = g_new0(WinCharState, 1); - chr->opaque = s; - chr->chr_write = win_chr_write; - chr->chr_close = win_chr_close; - - if (win_chr_pipe_init(chr, filename, errp) < 0) { - g_free(s); - g_free(chr); - return NULL; - } - return chr; -} - -static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) -{ - CharDriverState *chr; - WinCharState *s; - - chr = qemu_chr_alloc(); - s = g_new0(WinCharState, 1); - s->hcom = fd_out; - chr->opaque = s; - chr->chr_write = win_chr_write; - return chr; -} - -static CharDriverState *qemu_chr_open_win_con(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE)); -} - -static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD dwSize; - int len1; - - len1 = len; - - while (len1 > 0) { - if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) { - break; - } - buf += dwSize; - len1 -= dwSize; - } - - return len - len1; -} - -static void win_stdio_wait_func(void *opaque) -{ - CharDriverState *chr = opaque; - WinStdioCharState *stdio = chr->opaque; - INPUT_RECORD buf[4]; - int ret; - DWORD dwSize; - int i; - - ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize); - - if (!ret) { - /* Avoid error storm */ - qemu_del_wait_object(stdio->hStdIn, NULL, NULL); - return; - } - - for (i = 0; i < dwSize; i++) { - KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent; - - if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) { - int j; - if (kev->uChar.AsciiChar != 0) { - for (j = 0; j < kev->wRepeatCount; j++) { - if (qemu_chr_be_can_write(chr)) { - uint8_t c = kev->uChar.AsciiChar; - qemu_chr_be_write(chr, &c, 1); - } - } - } - } - } -} - -static DWORD WINAPI win_stdio_thread(LPVOID param) -{ - CharDriverState *chr = param; - WinStdioCharState *stdio = chr->opaque; - int ret; - DWORD dwSize; - - while (1) { - - /* Wait for one byte */ - ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL); - - /* Exit in case of error, continue if nothing read */ - if (!ret) { - break; - } - if (!dwSize) { - continue; - } - - /* Some terminal emulator returns \r\n for Enter, just pass \n */ - if (stdio->win_stdio_buf == '\r') { - continue; - } - - /* Signal the main thread and wait until the byte was eaten */ - if (!SetEvent(stdio->hInputReadyEvent)) { - break; - } - if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE) - != WAIT_OBJECT_0) { - break; - } - } - - qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); - return 0; -} - -static void win_stdio_thread_wait_func(void *opaque) -{ - CharDriverState *chr = opaque; - WinStdioCharState *stdio = chr->opaque; - - if (qemu_chr_be_can_write(chr)) { - qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1); - } - - SetEvent(stdio->hInputDoneEvent); -} - -static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo) -{ - WinStdioCharState *stdio = chr->opaque; - DWORD dwMode = 0; - - GetConsoleMode(stdio->hStdIn, &dwMode); - - if (echo) { - SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT); - } else { - SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT); - } -} - -static void win_stdio_close(CharDriverState *chr) -{ - WinStdioCharState *stdio = chr->opaque; - - if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) { - CloseHandle(stdio->hInputReadyEvent); - } - if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) { - CloseHandle(stdio->hInputDoneEvent); - } - if (stdio->hInputThread != INVALID_HANDLE_VALUE) { - TerminateThread(stdio->hInputThread, 0); - } - - g_free(chr->opaque); - g_free(chr); -} - -static CharDriverState *qemu_chr_open_stdio(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - CharDriverState *chr; - WinStdioCharState *stdio; - DWORD dwMode; - int is_console = 0; - - chr = qemu_chr_alloc(); - stdio = g_new0(WinStdioCharState, 1); - - stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); - if (stdio->hStdIn == INVALID_HANDLE_VALUE) { - error_setg(errp, "cannot open stdio: invalid handle"); - return NULL; - } - - is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; - - chr->opaque = stdio; - chr->chr_write = win_stdio_write; - chr->chr_close = win_stdio_close; - - if (is_console) { - if (qemu_add_wait_object(stdio->hStdIn, - win_stdio_wait_func, chr)) { - error_setg(errp, "qemu_add_wait_object: failed"); - goto err1; - } - } else { - DWORD dwId; - - stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE - || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { - error_setg(errp, "cannot create event"); - goto err2; - } - if (qemu_add_wait_object(stdio->hInputReadyEvent, - win_stdio_thread_wait_func, chr)) { - error_setg(errp, "qemu_add_wait_object: failed"); - goto err2; - } - stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, - chr, 0, &dwId); - - if (stdio->hInputThread == INVALID_HANDLE_VALUE) { - error_setg(errp, "cannot create stdio thread"); - goto err3; - } - } - - dwMode |= ENABLE_LINE_INPUT; - - if (is_console) { - /* set the terminal in raw mode */ - /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */ - dwMode |= ENABLE_PROCESSED_INPUT; - } - - SetConsoleMode(stdio->hStdIn, dwMode); - - chr->chr_set_echo = qemu_chr_set_echo_win_stdio; - qemu_chr_fe_set_echo(chr, false); - - return chr; - -err3: - qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); -err2: - CloseHandle(stdio->hInputReadyEvent); - CloseHandle(stdio->hInputDoneEvent); -err1: - qemu_del_wait_object(stdio->hStdIn, NULL, NULL); - return NULL; -} -#endif /* !_WIN32 */ - - -/***********************************************************/ -/* UDP Net console */ - -typedef struct { - int fd; - GIOChannel *chan; - uint8_t buf[READ_BUF_LEN]; - int bufcnt; - int bufptr; - int max_size; -} NetCharDriver; - -/* Called with chr_write_lock held. */ -static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - NetCharDriver *s = chr->opaque; - gsize bytes_written; - GIOStatus status; - - status = g_io_channel_write_chars(s->chan, (const gchar *)buf, len, &bytes_written, NULL); - if (status == G_IO_STATUS_EOF) { - return 0; - } else if (status != G_IO_STATUS_NORMAL) { - return -1; - } - - return bytes_written; -} - -static int udp_chr_read_poll(void *opaque) -{ - CharDriverState *chr = opaque; - NetCharDriver *s = chr->opaque; - - s->max_size = qemu_chr_be_can_write(chr); - - /* If there were any stray characters in the queue process them - * first - */ - while (s->max_size > 0 && s->bufptr < s->bufcnt) { - qemu_chr_be_write(chr, &s->buf[s->bufptr], 1); - s->bufptr++; - s->max_size = qemu_chr_be_can_write(chr); - } - return s->max_size; -} - -static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) -{ - CharDriverState *chr = opaque; - NetCharDriver *s = chr->opaque; - gsize bytes_read = 0; - GIOStatus status; - - if (s->max_size == 0) { - return TRUE; - } - status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf), - &bytes_read, NULL); - s->bufcnt = bytes_read; - s->bufptr = s->bufcnt; - if (status != G_IO_STATUS_NORMAL) { - remove_fd_in_watch(chr); - return FALSE; - } - - s->bufptr = 0; - while (s->max_size > 0 && s->bufptr < s->bufcnt) { - qemu_chr_be_write(chr, &s->buf[s->bufptr], 1); - s->bufptr++; - s->max_size = qemu_chr_be_can_write(chr); - } - - return TRUE; -} - -static void udp_chr_update_read_handler(CharDriverState *chr) -{ - NetCharDriver *s = chr->opaque; - - remove_fd_in_watch(chr); - if (s->chan) { - chr->fd_in_tag = io_add_watch_poll(s->chan, udp_chr_read_poll, - udp_chr_read, chr); - } -} - -static void udp_chr_close(CharDriverState *chr) -{ - NetCharDriver *s = chr->opaque; - - remove_fd_in_watch(chr); - if (s->chan) { - g_io_channel_unref(s->chan); - closesocket(s->fd); - } - g_free(s); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -} - -static CharDriverState *qemu_chr_open_udp_fd(int fd) -{ - CharDriverState *chr = NULL; - NetCharDriver *s = NULL; - - chr = qemu_chr_alloc(); - s = g_new0(NetCharDriver, 1); - - s->fd = fd; - s->chan = io_channel_from_socket(s->fd); - s->bufcnt = 0; - s->bufptr = 0; - chr->opaque = s; - chr->chr_write = udp_chr_write; - chr->chr_update_read_handler = udp_chr_update_read_handler; - chr->chr_close = udp_chr_close; - /* be isn't opened until we get a connection */ - chr->explicit_be_open = true; - return chr; -} - -/***********************************************************/ -/* TCP Net console */ - -typedef struct { - - GIOChannel *chan, *listen_chan; - guint listen_tag; - int fd, listen_fd; - int connected; - int max_size; - int do_telnetopt; - int do_nodelay; - int is_unix; - int *read_msgfds; - int read_msgfds_num; - int *write_msgfds; - int write_msgfds_num; - - SocketAddress *addr; - bool is_listen; - bool is_telnet; - - guint reconnect_timer; - int64_t reconnect_time; - bool connect_err_reported; -} TCPCharDriver; - -static gboolean socket_reconnect_timeout(gpointer opaque); - -static void qemu_chr_socket_restart_timer(CharDriverState *chr) -{ - TCPCharDriver *s = chr->opaque; - assert(s->connected == 0); - s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time, - socket_reconnect_timeout, chr); -} - -static void check_report_connect_error(CharDriverState *chr, - Error *err) -{ - TCPCharDriver *s = chr->opaque; - - if (!s->connect_err_reported) { - error_report("Unable to connect character device %s: %s", - chr->label, error_get_pretty(err)); - s->connect_err_reported = true; - } - qemu_chr_socket_restart_timer(chr); -} - -static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque); - -#ifndef _WIN32 -static int unix_send_msgfds(CharDriverState *chr, const uint8_t *buf, int len) -{ - TCPCharDriver *s = chr->opaque; - struct msghdr msgh; - struct iovec iov; - int r; - - size_t fd_size = s->write_msgfds_num * sizeof(int); - char control[CMSG_SPACE(fd_size)]; - struct cmsghdr *cmsg; - - memset(&msgh, 0, sizeof(msgh)); - memset(control, 0, sizeof(control)); - - /* set the payload */ - iov.iov_base = (uint8_t *) buf; - iov.iov_len = len; - - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - - msgh.msg_control = control; - msgh.msg_controllen = sizeof(control); - - cmsg = CMSG_FIRSTHDR(&msgh); - - cmsg->cmsg_len = CMSG_LEN(fd_size); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - memcpy(CMSG_DATA(cmsg), s->write_msgfds, fd_size); - - do { - r = sendmsg(s->fd, &msgh, 0); - } while (r < 0 && errno == EINTR); - - /* free the written msgfds, no matter what */ - if (s->write_msgfds_num) { - g_free(s->write_msgfds); - s->write_msgfds = 0; - s->write_msgfds_num = 0; - } - - return r; -} -#endif - -/* Called with chr_write_lock held. */ -static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - TCPCharDriver *s = chr->opaque; - if (s->connected) { -#ifndef _WIN32 - if (s->is_unix && s->write_msgfds_num) { - return unix_send_msgfds(chr, buf, len); - } else -#endif - { - return io_channel_send(s->chan, buf, len); - } - } else { - /* XXX: indicate an error ? */ - return len; - } -} - -static int tcp_chr_read_poll(void *opaque) -{ - CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; - if (!s->connected) - return 0; - s->max_size = qemu_chr_be_can_write(chr); - return s->max_size; -} - -#define IAC 255 -#define IAC_BREAK 243 -static void tcp_chr_process_IAC_bytes(CharDriverState *chr, - TCPCharDriver *s, - uint8_t *buf, int *size) -{ - /* Handle any telnet client's basic IAC options to satisfy char by - * char mode with no echo. All IAC options will be removed from - * the buf and the do_telnetopt variable will be used to track the - * state of the width of the IAC information. - * - * IAC commands come in sets of 3 bytes with the exception of the - * "IAC BREAK" command and the double IAC. - */ - - int i; - int j = 0; - - for (i = 0; i < *size; i++) { - if (s->do_telnetopt > 1) { - if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) { - /* Double IAC means send an IAC */ - if (j != i) - buf[j] = buf[i]; - j++; - s->do_telnetopt = 1; - } else { - if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) { - /* Handle IAC break commands by sending a serial break */ - qemu_chr_be_event(chr, CHR_EVENT_BREAK); - s->do_telnetopt++; - } - s->do_telnetopt++; - } - if (s->do_telnetopt >= 4) { - s->do_telnetopt = 1; - } - } else { - if ((unsigned char)buf[i] == IAC) { - s->do_telnetopt = 2; - } else { - if (j != i) - buf[j] = buf[i]; - j++; - } - } - } - *size = j; -} - -static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num) -{ - TCPCharDriver *s = chr->opaque; - int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; - - assert(num <= TCP_MAX_FDS); - - if (to_copy) { - int i; - - memcpy(fds, s->read_msgfds, to_copy * sizeof(int)); - - /* Close unused fds */ - for (i = to_copy; i < s->read_msgfds_num; i++) { - close(s->read_msgfds[i]); - } - - g_free(s->read_msgfds); - s->read_msgfds = 0; - s->read_msgfds_num = 0; - } - - return to_copy; -} - -static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) -{ - TCPCharDriver *s = chr->opaque; - - /* clear old pending fd array */ - g_free(s->write_msgfds); - - if (num) { - s->write_msgfds = g_new(int, num); - memcpy(s->write_msgfds, fds, num * sizeof(int)); - } - - s->write_msgfds_num = num; - - return 0; -} - -#ifndef _WIN32 -static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg) -{ - TCPCharDriver *s = chr->opaque; - struct cmsghdr *cmsg; - - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { - int fd_size, i; - - if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { - continue; - } - - fd_size = cmsg->cmsg_len - CMSG_LEN(0); - - if (!fd_size) { - continue; - } - - /* close and clean read_msgfds */ - for (i = 0; i < s->read_msgfds_num; i++) { - close(s->read_msgfds[i]); - } - - if (s->read_msgfds_num) { - g_free(s->read_msgfds); - } - - s->read_msgfds_num = fd_size / sizeof(int); - s->read_msgfds = g_malloc(fd_size); - memcpy(s->read_msgfds, CMSG_DATA(cmsg), fd_size); - - for (i = 0; i < s->read_msgfds_num; i++) { - int fd = s->read_msgfds[i]; - if (fd < 0) { - continue; - } - - /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ - qemu_set_block(fd); - - #ifndef MSG_CMSG_CLOEXEC - qemu_set_cloexec(fd); - #endif - } - } -} - -static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) -{ - TCPCharDriver *s = chr->opaque; - struct msghdr msg = { NULL, }; - struct iovec iov[1]; - union { - struct cmsghdr cmsg; - char control[CMSG_SPACE(sizeof(int) * TCP_MAX_FDS)]; - } msg_control; - int flags = 0; - ssize_t ret; - - iov[0].iov_base = buf; - iov[0].iov_len = len; - - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = &msg_control; - msg.msg_controllen = sizeof(msg_control); - -#ifdef MSG_CMSG_CLOEXEC - flags |= MSG_CMSG_CLOEXEC; -#endif - do { - ret = recvmsg(s->fd, &msg, flags); - } while (ret == -1 && errno == EINTR); - - if (ret > 0 && s->is_unix) { - unix_process_msgfd(chr, &msg); - } - - return ret; -} -#else -static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) -{ - TCPCharDriver *s = chr->opaque; - ssize_t ret; - - do { - ret = qemu_recv(s->fd, buf, len, 0); - } while (ret == -1 && socket_error() == EINTR); - - return ret; -} -#endif - -static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond) -{ - TCPCharDriver *s = chr->opaque; - return g_io_create_watch(s->chan, cond); -} - -static void tcp_chr_disconnect(CharDriverState *chr) -{ - TCPCharDriver *s = chr->opaque; - - s->connected = 0; - if (s->listen_chan) { - s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, - tcp_chr_accept, chr); - } - remove_fd_in_watch(chr); - g_io_channel_unref(s->chan); - s->chan = NULL; - closesocket(s->fd); - s->fd = -1; - SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, - "disconnected:", s->addr, s->is_listen, s->is_telnet); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); - if (s->reconnect_time) { - qemu_chr_socket_restart_timer(chr); - } -} - -static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) -{ - CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; - uint8_t buf[READ_BUF_LEN]; - int len, size; - - if (!s->connected || s->max_size <= 0) { - return TRUE; - } - len = sizeof(buf); - if (len > s->max_size) - len = s->max_size; - size = tcp_chr_recv(chr, (void *)buf, len); - if (size == 0 || - (size < 0 && - socket_error() != EAGAIN && socket_error() != EWOULDBLOCK)) { - /* connection closed */ - tcp_chr_disconnect(chr); - } else if (size > 0) { - if (s->do_telnetopt) - tcp_chr_process_IAC_bytes(chr, s, buf, &size); - if (size > 0) - qemu_chr_be_write(chr, buf, size); - } - - return TRUE; -} - -static int tcp_chr_sync_read(CharDriverState *chr, const uint8_t *buf, int len) -{ - TCPCharDriver *s = chr->opaque; - int size; - - if (!s->connected) { - return 0; - } - - size = tcp_chr_recv(chr, (void *) buf, len); - if (size == 0) { - /* connection closed */ - tcp_chr_disconnect(chr); - } - - return size; -} - -#ifndef _WIN32 -CharDriverState *qemu_chr_open_eventfd(int eventfd) -{ - CharDriverState *chr = qemu_chr_open_fd(eventfd, eventfd); - - if (chr) { - chr->avail_connections = 1; - } - - return chr; -} -#endif - -static void tcp_chr_connect(void *opaque) -{ - CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; - struct sockaddr_storage ss, ps; - socklen_t ss_len = sizeof(ss), ps_len = sizeof(ps); - - memset(&ss, 0, ss_len); - if (getsockname(s->fd, (struct sockaddr *) &ss, &ss_len) != 0) { - snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, - "Error in getsockname: %s\n", strerror(errno)); - } else if (getpeername(s->fd, (struct sockaddr *) &ps, &ps_len) != 0) { - snprintf(chr->filename, CHR_MAX_FILENAME_SIZE, - "Error in getpeername: %s\n", strerror(errno)); - } else { - sockaddr_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, - &ss, ss_len, &ps, ps_len, - s->is_listen, s->is_telnet); - } - - s->connected = 1; - if (s->chan) { - chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, - tcp_chr_read, chr); - } - qemu_chr_be_generic_open(chr); -} - -static void tcp_chr_update_read_handler(CharDriverState *chr) -{ - TCPCharDriver *s = chr->opaque; - - remove_fd_in_watch(chr); - if (s->chan) { - chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, - tcp_chr_read, chr); - } -} - -#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c; -static void tcp_chr_telnet_init(int fd) -{ - char buf[3]; - /* Send the telnet negotion to put telnet in binary, no echo, single char mode */ - IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */ - send(fd, (char *)buf, 3, 0); - IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */ - send(fd, (char *)buf, 3, 0); - IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */ - send(fd, (char *)buf, 3, 0); - IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */ - send(fd, (char *)buf, 3, 0); -} - -static int tcp_chr_add_client(CharDriverState *chr, int fd) -{ - TCPCharDriver *s = chr->opaque; - if (s->fd != -1) - return -1; - - qemu_set_nonblock(fd); - if (s->do_nodelay) - socket_set_nodelay(fd); - s->fd = fd; - s->chan = io_channel_from_socket(fd); - if (s->listen_tag) { - g_source_remove(s->listen_tag); - s->listen_tag = 0; - } - tcp_chr_connect(chr); - - return 0; -} - -static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque) -{ - CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; - struct sockaddr_in saddr; -#ifndef _WIN32 - struct sockaddr_un uaddr; -#endif - struct sockaddr *addr; - socklen_t len; - int fd; - - for(;;) { -#ifndef _WIN32 - if (s->is_unix) { - len = sizeof(uaddr); - addr = (struct sockaddr *)&uaddr; - } else -#endif - { - len = sizeof(saddr); - addr = (struct sockaddr *)&saddr; - } - fd = qemu_accept(s->listen_fd, addr, &len); - if (fd < 0 && errno != EINTR) { - s->listen_tag = 0; - return FALSE; - } else if (fd >= 0) { - if (s->do_telnetopt) - tcp_chr_telnet_init(fd); - break; - } - } - if (tcp_chr_add_client(chr, fd) < 0) - close(fd); - - return TRUE; -} - -static void tcp_chr_close(CharDriverState *chr) -{ - TCPCharDriver *s = chr->opaque; - int i; - - if (s->reconnect_timer) { - g_source_remove(s->reconnect_timer); - s->reconnect_timer = 0; - } - qapi_free_SocketAddress(s->addr); - if (s->fd >= 0) { - remove_fd_in_watch(chr); - if (s->chan) { - g_io_channel_unref(s->chan); - } - closesocket(s->fd); - } - if (s->listen_fd >= 0) { - if (s->listen_tag) { - g_source_remove(s->listen_tag); - s->listen_tag = 0; - } - if (s->listen_chan) { - g_io_channel_unref(s->listen_chan); - } - closesocket(s->listen_fd); - } - if (s->read_msgfds_num) { - for (i = 0; i < s->read_msgfds_num; i++) { - close(s->read_msgfds[i]); - } - g_free(s->read_msgfds); - } - if (s->write_msgfds_num) { - g_free(s->write_msgfds); - } - g_free(s); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); -} - -static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd) -{ - TCPCharDriver *s = chr->opaque; - - if (s->is_listen) { - s->listen_fd = fd; - s->listen_chan = io_channel_from_socket(s->listen_fd); - s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, - tcp_chr_accept, chr); - } else { - s->connected = 1; - s->fd = fd; - socket_set_nodelay(fd); - s->chan = io_channel_from_socket(s->fd); - tcp_chr_connect(chr); - } -} - -static void qemu_chr_socket_connected(int fd, Error *err, void *opaque) -{ - CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; - - if (fd < 0) { - check_report_connect_error(chr, err); - return; - } - - s->connect_err_reported = false; - qemu_chr_finish_socket_connection(chr, fd); -} - -static bool qemu_chr_open_socket_fd(CharDriverState *chr, Error **errp) -{ - TCPCharDriver *s = chr->opaque; - int fd; - - if (s->is_listen) { - fd = socket_listen(s->addr, errp); - } else if (s->reconnect_time) { - fd = socket_connect(s->addr, errp, qemu_chr_socket_connected, chr); - return fd >= 0; - } else { - fd = socket_connect(s->addr, errp, NULL, NULL); - } - if (fd < 0) { - return false; - } - - qemu_chr_finish_socket_connection(chr, fd); - return true; -} - -/*********************************************************/ -/* Ring buffer chardev */ - -typedef struct { - size_t size; - size_t prod; - size_t cons; - uint8_t *cbuf; -} RingBufCharDriver; - -static size_t ringbuf_count(const CharDriverState *chr) -{ - const RingBufCharDriver *d = chr->opaque; - - return d->prod - d->cons; -} - -/* Called with chr_write_lock held. */ -static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - RingBufCharDriver *d = chr->opaque; - int i; - - if (!buf || (len < 0)) { - return -1; - } - - for (i = 0; i < len; i++ ) { - d->cbuf[d->prod++ & (d->size - 1)] = buf[i]; - if (d->prod - d->cons > d->size) { - d->cons = d->prod - d->size; - } - } - - return 0; -} - -static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len) -{ - RingBufCharDriver *d = chr->opaque; - int i; - - qemu_mutex_lock(&chr->chr_write_lock); - for (i = 0; i < len && d->cons != d->prod; i++) { - buf[i] = d->cbuf[d->cons++ & (d->size - 1)]; - } - qemu_mutex_unlock(&chr->chr_write_lock); - - return i; -} - -static void ringbuf_chr_close(struct CharDriverState *chr) -{ - RingBufCharDriver *d = chr->opaque; - - g_free(d->cbuf); - g_free(d); - chr->opaque = NULL; -} - -static CharDriverState *qemu_chr_open_ringbuf(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevRingbuf *opts = backend->u.ringbuf; - CharDriverState *chr; - RingBufCharDriver *d; - - chr = qemu_chr_alloc(); - d = g_malloc(sizeof(*d)); - - d->size = opts->has_size ? opts->size : 65536; - - /* The size must be power of 2 */ - if (d->size & (d->size - 1)) { - error_setg(errp, "size of ringbuf chardev must be power of two"); - goto fail; - } - - d->prod = 0; - d->cons = 0; - d->cbuf = g_malloc0(d->size); - - chr->opaque = d; - chr->chr_write = ringbuf_chr_write; - chr->chr_close = ringbuf_chr_close; - - return chr; - -fail: - g_free(d); - g_free(chr); - return NULL; -} - -bool chr_is_ringbuf(const CharDriverState *chr) -{ - return chr->chr_write == ringbuf_chr_write; -} - -void qmp_ringbuf_write(const char *device, const char *data, - bool has_format, enum DataFormat format, - Error **errp) -{ - CharDriverState *chr; - const uint8_t *write_data; - int ret; - gsize write_count; - - chr = qemu_chr_find(device); - if (!chr) { - error_setg(errp, "Device '%s' not found", device); - return; - } - - if (!chr_is_ringbuf(chr)) { - error_setg(errp,"%s is not a ringbuf device", device); - return; - } - - if (has_format && (format == DATA_FORMAT_BASE64)) { - write_data = g_base64_decode(data, &write_count); - } else { - write_data = (uint8_t *)data; - write_count = strlen(data); - } - - ret = ringbuf_chr_write(chr, write_data, write_count); - - if (write_data != (uint8_t *)data) { - g_free((void *)write_data); - } - - if (ret < 0) { - error_setg(errp, "Failed to write to device %s", device); - return; - } -} - -char *qmp_ringbuf_read(const char *device, int64_t size, - bool has_format, enum DataFormat format, - Error **errp) -{ - CharDriverState *chr; - uint8_t *read_data; - size_t count; - char *data; - - chr = qemu_chr_find(device); - if (!chr) { - error_setg(errp, "Device '%s' not found", device); - return NULL; - } - - if (!chr_is_ringbuf(chr)) { - error_setg(errp,"%s is not a ringbuf device", device); - return NULL; - } - - if (size <= 0) { - error_setg(errp, "size must be greater than zero"); - return NULL; - } - - count = ringbuf_count(chr); - size = size > count ? count : size; - read_data = g_malloc(size + 1); - - ringbuf_chr_read(chr, read_data, size); - - if (has_format && (format == DATA_FORMAT_BASE64)) { - data = g_base64_encode(read_data, size); - g_free(read_data); - } else { - /* - * FIXME should read only complete, valid UTF-8 characters up - * to @size bytes. Invalid sequences should be replaced by a - * suitable replacement character. Except when (and only - * when) ring buffer lost characters since last read, initial - * continuation characters should be dropped. - */ - read_data[size] = 0; - data = (char *)read_data; - } - - return data; -} - -QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) -{ - char host[65], port[33], width[8], height[8]; - int pos; - const char *p; - QemuOpts *opts; - Error *local_err = NULL; - - opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err); - if (local_err) { - error_report_err(local_err); - return NULL; - } - - if (strstart(filename, "mon:", &p)) { - filename = p; - qemu_opt_set(opts, "mux", "on", &error_abort); - if (strcmp(filename, "stdio") == 0) { - /* Monitor is muxed to stdio: do not exit on Ctrl+C by default - * but pass it to the guest. Handle this only for compat syntax, - * for -chardev syntax we have special option for this. - * This is what -nographic did, redirecting+muxing serial+monitor - * to stdio causing Ctrl+C to be passed to guest. */ - qemu_opt_set(opts, "signal", "off", &error_abort); - } - } - - if (strcmp(filename, "null") == 0 || - strcmp(filename, "pty") == 0 || - strcmp(filename, "msmouse") == 0 || - strcmp(filename, "braille") == 0 || - strcmp(filename, "testdev") == 0 || - strcmp(filename, "stdio") == 0) { - qemu_opt_set(opts, "backend", filename, &error_abort); - return opts; - } - if (strstart(filename, "vc", &p)) { - qemu_opt_set(opts, "backend", "vc", &error_abort); - if (*p == ':') { - if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) { - /* pixels */ - qemu_opt_set(opts, "width", width, &error_abort); - qemu_opt_set(opts, "height", height, &error_abort); - } else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) { - /* chars */ - qemu_opt_set(opts, "cols", width, &error_abort); - qemu_opt_set(opts, "rows", height, &error_abort); - } else { - goto fail; - } - } - return opts; - } - if (strcmp(filename, "con:") == 0) { - qemu_opt_set(opts, "backend", "console", &error_abort); - return opts; - } - if (strstart(filename, "COM", NULL)) { - qemu_opt_set(opts, "backend", "serial", &error_abort); - qemu_opt_set(opts, "path", filename, &error_abort); - return opts; - } - if (strstart(filename, "file:", &p)) { - qemu_opt_set(opts, "backend", "file", &error_abort); - qemu_opt_set(opts, "path", p, &error_abort); - return opts; - } - if (strstart(filename, "pipe:", &p)) { - qemu_opt_set(opts, "backend", "pipe", &error_abort); - qemu_opt_set(opts, "path", p, &error_abort); - return opts; - } - if (strstart(filename, "tcp:", &p) || - strstart(filename, "telnet:", &p)) { - if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) { - host[0] = 0; - if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) - goto fail; - } - qemu_opt_set(opts, "backend", "socket", &error_abort); - qemu_opt_set(opts, "host", host, &error_abort); - qemu_opt_set(opts, "port", port, &error_abort); - if (p[pos] == ',') { - qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err); - if (local_err) { - error_report_err(local_err); - goto fail; - } - } - if (strstart(filename, "telnet:", &p)) - qemu_opt_set(opts, "telnet", "on", &error_abort); - return opts; - } - if (strstart(filename, "udp:", &p)) { - qemu_opt_set(opts, "backend", "udp", &error_abort); - if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) { - host[0] = 0; - if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) { - goto fail; - } - } - qemu_opt_set(opts, "host", host, &error_abort); - qemu_opt_set(opts, "port", port, &error_abort); - if (p[pos] == '@') { - p += pos + 1; - if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) { - host[0] = 0; - if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) { - goto fail; - } - } - qemu_opt_set(opts, "localaddr", host, &error_abort); - qemu_opt_set(opts, "localport", port, &error_abort); - } - return opts; - } - if (strstart(filename, "unix:", &p)) { - qemu_opt_set(opts, "backend", "socket", &error_abort); - qemu_opts_do_parse(opts, p, "path", &local_err); - if (local_err) { - error_report_err(local_err); - goto fail; - } - return opts; - } - if (strstart(filename, "/dev/parport", NULL) || - strstart(filename, "/dev/ppi", NULL)) { - qemu_opt_set(opts, "backend", "parport", &error_abort); - qemu_opt_set(opts, "path", filename, &error_abort); - return opts; - } - if (strstart(filename, "/dev/", NULL)) { - qemu_opt_set(opts, "backend", "tty", &error_abort); - qemu_opt_set(opts, "path", filename, &error_abort); - return opts; - } - -fail: - qemu_opts_del(opts); - return NULL; -} - -static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - const char *path = qemu_opt_get(opts, "path"); - - if (path == NULL) { - error_setg(errp, "chardev: file: no filename given"); - return; - } - backend->u.file = g_new0(ChardevFile, 1); - backend->u.file->out = g_strdup(path); -} - -static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - backend->u.stdio = g_new0(ChardevStdio, 1); - backend->u.stdio->has_signal = true; - backend->u.stdio->signal = qemu_opt_get_bool(opts, "signal", true); -} - -#ifdef HAVE_CHARDEV_SERIAL -static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - const char *device = qemu_opt_get(opts, "path"); - - if (device == NULL) { - error_setg(errp, "chardev: serial/tty: no device path given"); - return; - } - backend->u.serial = g_new0(ChardevHostdev, 1); - backend->u.serial->device = g_strdup(device); -} -#endif - -#ifdef HAVE_CHARDEV_PARPORT -static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - const char *device = qemu_opt_get(opts, "path"); - - if (device == NULL) { - error_setg(errp, "chardev: parallel: no device path given"); - return; - } - backend->u.parallel = g_new0(ChardevHostdev, 1); - backend->u.parallel->device = g_strdup(device); -} -#endif - -static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - const char *device = qemu_opt_get(opts, "path"); - - if (device == NULL) { - error_setg(errp, "chardev: pipe: no device path given"); - return; - } - backend->u.pipe = g_new0(ChardevHostdev, 1); - backend->u.pipe->device = g_strdup(device); -} - -static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - int val; - - backend->u.ringbuf = g_new0(ChardevRingbuf, 1); - - val = qemu_opt_get_size(opts, "size", 0); - if (val != 0) { - backend->u.ringbuf->has_size = true; - backend->u.ringbuf->size = val; - } -} - -static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - const char *chardev = qemu_opt_get(opts, "chardev"); - - if (chardev == NULL) { - error_setg(errp, "chardev: mux: no chardev given"); - return; - } - backend->u.mux = g_new0(ChardevMux, 1); - backend->u.mux->chardev = g_strdup(chardev); -} - -static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - bool is_listen = qemu_opt_get_bool(opts, "server", false); - bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); - bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); - bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); - int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0); - const char *path = qemu_opt_get(opts, "path"); - const char *host = qemu_opt_get(opts, "host"); - const char *port = qemu_opt_get(opts, "port"); - SocketAddress *addr; - - if (!path) { - if (!host) { - error_setg(errp, "chardev: socket: no host given"); - return; - } - if (!port) { - error_setg(errp, "chardev: socket: no port given"); - return; - } - } - - backend->u.socket = g_new0(ChardevSocket, 1); - - backend->u.socket->has_nodelay = true; - backend->u.socket->nodelay = do_nodelay; - backend->u.socket->has_server = true; - backend->u.socket->server = is_listen; - backend->u.socket->has_telnet = true; - backend->u.socket->telnet = is_telnet; - backend->u.socket->has_wait = true; - backend->u.socket->wait = is_waitconnect; - backend->u.socket->has_reconnect = true; - backend->u.socket->reconnect = reconnect; - - addr = g_new0(SocketAddress, 1); - if (path) { - addr->type = SOCKET_ADDRESS_KIND_UNIX; - addr->u.q_unix = g_new0(UnixSocketAddress, 1); - addr->u.q_unix->path = g_strdup(path); - } else { - addr->type = SOCKET_ADDRESS_KIND_INET; - addr->u.inet = g_new0(InetSocketAddress, 1); - addr->u.inet->host = g_strdup(host); - addr->u.inet->port = g_strdup(port); - addr->u.inet->has_to = qemu_opt_get(opts, "to"); - addr->u.inet->to = qemu_opt_get_number(opts, "to", 0); - addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4"); - addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0); - addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6"); - addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0); - } - backend->u.socket->addr = addr; -} - -static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, - Error **errp) -{ - const char *host = qemu_opt_get(opts, "host"); - const char *port = qemu_opt_get(opts, "port"); - const char *localaddr = qemu_opt_get(opts, "localaddr"); - const char *localport = qemu_opt_get(opts, "localport"); - bool has_local = false; - SocketAddress *addr; - - if (host == NULL || strlen(host) == 0) { - host = "localhost"; - } - if (port == NULL || strlen(port) == 0) { - error_setg(errp, "chardev: udp: remote port not specified"); - return; - } - if (localport == NULL || strlen(localport) == 0) { - localport = "0"; - } else { - has_local = true; - } - if (localaddr == NULL || strlen(localaddr) == 0) { - localaddr = ""; - } else { - has_local = true; - } - - backend->u.udp = g_new0(ChardevUdp, 1); - - addr = g_new0(SocketAddress, 1); - addr->type = SOCKET_ADDRESS_KIND_INET; - addr->u.inet = g_new0(InetSocketAddress, 1); - addr->u.inet->host = g_strdup(host); - addr->u.inet->port = g_strdup(port); - addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4"); - addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0); - addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6"); - addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0); - backend->u.udp->remote = addr; - - if (has_local) { - backend->u.udp->has_local = true; - addr = g_new0(SocketAddress, 1); - addr->type = SOCKET_ADDRESS_KIND_INET; - addr->u.inet = g_new0(InetSocketAddress, 1); - addr->u.inet->host = g_strdup(localaddr); - addr->u.inet->port = g_strdup(localport); - backend->u.udp->local = addr; - } -} - -typedef struct CharDriver { - const char *name; - ChardevBackendKind kind; - void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); - CharDriverState *(*create)(const char *id, ChardevBackend *backend, - ChardevReturn *ret, Error **errp); -} CharDriver; - -static GSList *backends; - -void register_char_driver(const char *name, ChardevBackendKind kind, - void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp), - CharDriverState *(*create)(const char *id, ChardevBackend *backend, - ChardevReturn *ret, Error **errp)) -{ - CharDriver *s; - - s = g_malloc0(sizeof(*s)); - s->name = g_strdup(name); - s->kind = kind; - s->parse = parse; - s->create = create; - - backends = g_slist_append(backends, s); -} - -CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, - void (*init)(struct CharDriverState *s), - Error **errp) -{ - Error *local_err = NULL; - CharDriver *cd; - CharDriverState *chr; - GSList *i; - ChardevReturn *ret = NULL; - ChardevBackend *backend; - const char *id = qemu_opts_id(opts); - char *bid = NULL; - - if (id == NULL) { - error_setg(errp, "chardev: no id specified"); - goto err; - } - - if (qemu_opt_get(opts, "backend") == NULL) { - error_setg(errp, "chardev: \"%s\" missing backend", - qemu_opts_id(opts)); - goto err; - } - for (i = backends; i; i = i->next) { - cd = i->data; - - if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) { - break; - } - } - if (i == NULL) { - error_setg(errp, "chardev: backend \"%s\" not found", - qemu_opt_get(opts, "backend")); - goto err; - } - - backend = g_new0(ChardevBackend, 1); - - if (qemu_opt_get_bool(opts, "mux", 0)) { - bid = g_strdup_printf("%s-base", id); - } - - chr = NULL; - backend->type = cd->kind; - if (cd->parse) { - cd->parse(opts, backend, &local_err); - if (local_err) { - error_propagate(errp, local_err); - goto qapi_out; - } - } - ret = qmp_chardev_add(bid ? bid : id, backend, errp); - if (!ret) { - goto qapi_out; - } - - if (bid) { - qapi_free_ChardevBackend(backend); - qapi_free_ChardevReturn(ret); - backend = g_new0(ChardevBackend, 1); - backend->u.mux = g_new0(ChardevMux, 1); - backend->type = CHARDEV_BACKEND_KIND_MUX; - backend->u.mux->chardev = g_strdup(bid); - ret = qmp_chardev_add(id, backend, errp); - if (!ret) { - chr = qemu_chr_find(bid); - qemu_chr_delete(chr); - chr = NULL; - goto qapi_out; - } - } - - chr = qemu_chr_find(id); - chr->opts = opts; - -qapi_out: - qapi_free_ChardevBackend(backend); - qapi_free_ChardevReturn(ret); - g_free(bid); - return chr; - -err: - qemu_opts_del(opts); - return NULL; -} - -CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) -{ - const char *p; - CharDriverState *chr; - QemuOpts *opts; - Error *err = NULL; - - if (strstart(filename, "chardev:", &p)) { - return qemu_chr_find(p); - } - - opts = qemu_chr_parse_compat(label, filename); - if (!opts) - return NULL; - - chr = qemu_chr_new_from_opts(opts, init, &err); - if (err) { - error_report_err(err); - } - if (chr && qemu_opt_get_bool(opts, "mux", 0)) { - qemu_chr_fe_claim_no_fail(chr); - monitor_init(chr, MONITOR_USE_READLINE); - } - return chr; -} - -void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo) -{ - if (chr->chr_set_echo) { - chr->chr_set_echo(chr, echo); - } -} - -void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open) -{ - if (chr->fe_open == fe_open) { - return; - } - chr->fe_open = fe_open; - if (chr->chr_set_fe_open) { - chr->chr_set_fe_open(chr, fe_open); - } -} - -void qemu_chr_fe_event(struct CharDriverState *chr, int event) -{ - if (chr->chr_fe_event) { - chr->chr_fe_event(chr, event); - } -} - -int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, - GIOFunc func, void *user_data) -{ - GSource *src; - guint tag; - - if (s->chr_add_watch == NULL) { - return -ENOSYS; - } - - src = s->chr_add_watch(s, cond); - if (!src) { - return -EINVAL; - } - - g_source_set_callback(src, (GSourceFunc)func, user_data, NULL); - tag = g_source_attach(src, NULL); - g_source_unref(src); - - return tag; -} - -int qemu_chr_fe_claim(CharDriverState *s) -{ - if (s->avail_connections < 1) { - return -1; - } - s->avail_connections--; - return 0; -} - -void qemu_chr_fe_claim_no_fail(CharDriverState *s) -{ - if (qemu_chr_fe_claim(s) != 0) { - fprintf(stderr, "%s: error chardev \"%s\" already used\n", - __func__, s->label); - exit(1); - } -} - -void qemu_chr_fe_release(CharDriverState *s) -{ - s->avail_connections++; -} - -void qemu_chr_free(CharDriverState *chr) -{ - if (chr->chr_close) { - chr->chr_close(chr); - } - g_free(chr->filename); - g_free(chr->label); - qemu_opts_del(chr->opts); - g_free(chr); -} - -void qemu_chr_delete(CharDriverState *chr) -{ - QTAILQ_REMOVE(&chardevs, chr, next); - qemu_chr_free(chr); -} - -ChardevInfoList *qmp_query_chardev(Error **errp) -{ - ChardevInfoList *chr_list = NULL; - CharDriverState *chr; - - QTAILQ_FOREACH(chr, &chardevs, next) { - ChardevInfoList *info = g_malloc0(sizeof(*info)); - info->value = g_malloc0(sizeof(*info->value)); - info->value->label = g_strdup(chr->label); - info->value->filename = g_strdup(chr->filename); - info->value->frontend_open = chr->fe_open; - - info->next = chr_list; - chr_list = info; - } - - return chr_list; -} - -ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp) -{ - ChardevBackendInfoList *backend_list = NULL; - CharDriver *c = NULL; - GSList *i = NULL; - - for (i = backends; i; i = i->next) { - ChardevBackendInfoList *info = g_malloc0(sizeof(*info)); - c = i->data; - info->value = g_malloc0(sizeof(*info->value)); - info->value->name = g_strdup(c->name); - - info->next = backend_list; - backend_list = info; - } - - return backend_list; -} - -CharDriverState *qemu_chr_find(const char *name) -{ - CharDriverState *chr; - - QTAILQ_FOREACH(chr, &chardevs, next) { - if (strcmp(chr->label, name) != 0) - continue; - return chr; - } - return NULL; -} - -/* Get a character (serial) device interface. */ -CharDriverState *qemu_char_get_next_serial(void) -{ - static int next_serial; - CharDriverState *chr; - - /* FIXME: This function needs to go away: use chardev properties! */ - - while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) { - chr = serial_hds[next_serial++]; - qemu_chr_fe_claim_no_fail(chr); - return chr; - } - return NULL; -} - -QemuOptsList qemu_chardev_opts = { - .name = "chardev", - .implied_opt_name = "backend", - .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head), - .desc = { - { - .name = "backend", - .type = QEMU_OPT_STRING, - },{ - .name = "path", - .type = QEMU_OPT_STRING, - },{ - .name = "host", - .type = QEMU_OPT_STRING, - },{ - .name = "port", - .type = QEMU_OPT_STRING, - },{ - .name = "localaddr", - .type = QEMU_OPT_STRING, - },{ - .name = "localport", - .type = QEMU_OPT_STRING, - },{ - .name = "to", - .type = QEMU_OPT_NUMBER, - },{ - .name = "ipv4", - .type = QEMU_OPT_BOOL, - },{ - .name = "ipv6", - .type = QEMU_OPT_BOOL, - },{ - .name = "wait", - .type = QEMU_OPT_BOOL, - },{ - .name = "server", - .type = QEMU_OPT_BOOL, - },{ - .name = "delay", - .type = QEMU_OPT_BOOL, - },{ - .name = "reconnect", - .type = QEMU_OPT_NUMBER, - },{ - .name = "telnet", - .type = QEMU_OPT_BOOL, - },{ - .name = "width", - .type = QEMU_OPT_NUMBER, - },{ - .name = "height", - .type = QEMU_OPT_NUMBER, - },{ - .name = "cols", - .type = QEMU_OPT_NUMBER, - },{ - .name = "rows", - .type = QEMU_OPT_NUMBER, - },{ - .name = "mux", - .type = QEMU_OPT_BOOL, - },{ - .name = "signal", - .type = QEMU_OPT_BOOL, - },{ - .name = "name", - .type = QEMU_OPT_STRING, - },{ - .name = "debug", - .type = QEMU_OPT_NUMBER, - },{ - .name = "size", - .type = QEMU_OPT_SIZE, - },{ - .name = "chardev", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - -#ifdef _WIN32 - -static CharDriverState *qmp_chardev_open_file(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevFile *file = backend->u.file; - HANDLE out; - - if (file->has_in) { - error_setg(errp, "input file not supported"); - return NULL; - } - - out = CreateFile(file->out, GENERIC_WRITE, FILE_SHARE_READ, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (out == INVALID_HANDLE_VALUE) { - error_setg(errp, "open %s failed", file->out); - return NULL; - } - return qemu_chr_open_win_file(out); -} - -static CharDriverState *qmp_chardev_open_serial(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevHostdev *serial = backend->u.serial; - return qemu_chr_open_win_path(serial->device, errp); -} - -#else /* WIN32 */ - -static int qmp_chardev_open_file_source(char *src, int flags, - Error **errp) -{ - int fd = -1; - - TFR(fd = qemu_open(src, flags, 0666)); - if (fd == -1) { - error_setg_file_open(errp, errno, src); - } - return fd; -} - -static CharDriverState *qmp_chardev_open_file(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevFile *file = backend->u.file; - int flags, in = -1, out; - - flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY; - out = qmp_chardev_open_file_source(file->out, flags, errp); - if (out < 0) { - return NULL; - } - - if (file->has_in) { - flags = O_RDONLY; - in = qmp_chardev_open_file_source(file->in, flags, errp); - if (in < 0) { - qemu_close(out); - return NULL; - } - } - - return qemu_chr_open_fd(in, out); -} - -#ifdef HAVE_CHARDEV_SERIAL -static CharDriverState *qmp_chardev_open_serial(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevHostdev *serial = backend->u.serial; - int fd; - - fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); - if (fd < 0) { - return NULL; - } - qemu_set_nonblock(fd); - return qemu_chr_open_tty_fd(fd); -} -#endif - -#ifdef HAVE_CHARDEV_PARPORT -static CharDriverState *qmp_chardev_open_parallel(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevHostdev *parallel = backend->u.parallel; - int fd; - - fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); - if (fd < 0) { - return NULL; - } - return qemu_chr_open_pp_fd(fd, errp); -} -#endif - -#endif /* WIN32 */ - -static void socket_try_connect(CharDriverState *chr) -{ - Error *err = NULL; - - if (!qemu_chr_open_socket_fd(chr, &err)) { - check_report_connect_error(chr, err); - } -} - -static gboolean socket_reconnect_timeout(gpointer opaque) -{ - CharDriverState *chr = opaque; - TCPCharDriver *s = chr->opaque; - - s->reconnect_timer = 0; - - if (chr->be_open) { - return false; - } - - socket_try_connect(chr); - - return false; -} - -static CharDriverState *qmp_chardev_open_socket(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - CharDriverState *chr; - TCPCharDriver *s; - ChardevSocket *sock = backend->u.socket; - SocketAddress *addr = sock->addr; - bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; - bool is_listen = sock->has_server ? sock->server : true; - bool is_telnet = sock->has_telnet ? sock->telnet : false; - bool is_waitconnect = sock->has_wait ? sock->wait : false; - int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; - - chr = qemu_chr_alloc(); - s = g_new0(TCPCharDriver, 1); - - s->fd = -1; - s->listen_fd = -1; - s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX; - s->is_listen = is_listen; - s->is_telnet = is_telnet; - s->do_nodelay = do_nodelay; - qapi_copy_SocketAddress(&s->addr, sock->addr); - - chr->opaque = s; - chr->chr_write = tcp_chr_write; - chr->chr_sync_read = tcp_chr_sync_read; - chr->chr_close = tcp_chr_close; - chr->get_msgfds = tcp_get_msgfds; - chr->set_msgfds = tcp_set_msgfds; - chr->chr_add_client = tcp_chr_add_client; - chr->chr_add_watch = tcp_chr_add_watch; - chr->chr_update_read_handler = tcp_chr_update_read_handler; - /* be isn't opened until we get a connection */ - chr->explicit_be_open = true; - - chr->filename = g_malloc(CHR_MAX_FILENAME_SIZE); - SocketAddress_to_str(chr->filename, CHR_MAX_FILENAME_SIZE, "disconnected:", - addr, is_listen, is_telnet); - - if (is_listen) { - if (is_telnet) { - s->do_telnetopt = 1; - } - } else if (reconnect > 0) { - s->reconnect_time = reconnect; - } - - if (s->reconnect_time) { - socket_try_connect(chr); - } else if (!qemu_chr_open_socket_fd(chr, errp)) { - g_free(s); - g_free(chr->filename); - g_free(chr); - return NULL; - } - - if (is_listen && is_waitconnect) { - fprintf(stderr, "QEMU waiting for connection on: %s\n", - chr->filename); - tcp_chr_accept(s->listen_chan, G_IO_IN, chr); - qemu_set_nonblock(s->listen_fd); - } - - return chr; -} - -static CharDriverState *qmp_chardev_open_udp(const char *id, - ChardevBackend *backend, - ChardevReturn *ret, - Error **errp) -{ - ChardevUdp *udp = backend->u.udp; - int fd; - - fd = socket_dgram(udp->remote, udp->local, errp); - if (fd < 0) { - return NULL; - } - return qemu_chr_open_udp_fd(fd); -} - -ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, - Error **errp) -{ - ChardevReturn *ret = g_new0(ChardevReturn, 1); - CharDriverState *chr = NULL; - Error *local_err = NULL; - GSList *i; - CharDriver *cd; - - chr = qemu_chr_find(id); - if (chr) { - error_setg(errp, "Chardev '%s' already exists", id); - g_free(ret); - return NULL; - } - - for (i = backends; i; i = i->next) { - cd = i->data; - - if (cd->kind == backend->type) { - chr = cd->create(id, backend, ret, &local_err); - if (local_err) { - error_propagate(errp, local_err); - goto out_error; - } - break; - } - } - - if (chr == NULL) { - assert(!i); - error_setg(errp, "chardev backend not available"); - goto out_error; - } - - chr->label = g_strdup(id); - chr->avail_connections = - (backend->type == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; - if (!chr->filename) { - chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]); - } - if (!chr->explicit_be_open) { - qemu_chr_be_event(chr, CHR_EVENT_OPENED); - } - QTAILQ_INSERT_TAIL(&chardevs, chr, next); - return ret; - -out_error: - g_free(ret); - return NULL; -} - -void qmp_chardev_remove(const char *id, Error **errp) -{ - CharDriverState *chr; - - chr = qemu_chr_find(id); - if (chr == NULL) { - error_setg(errp, "Chardev '%s' not found", id); - return; - } - if (chr->chr_can_read || chr->chr_read || - chr->chr_event || chr->handler_opaque) { - error_setg(errp, "Chardev '%s' is busy", id); - return; - } - qemu_chr_delete(chr); -} - -static void register_types(void) -{ - register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, - qemu_chr_open_null); - register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, - qemu_chr_parse_socket, qmp_chardev_open_socket); - register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, - qmp_chardev_open_udp); - register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, - qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); - register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, - qemu_chr_parse_file_out, qmp_chardev_open_file); - register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, - qemu_chr_parse_stdio, qemu_chr_open_stdio); -#if defined HAVE_CHARDEV_SERIAL - register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial, qmp_chardev_open_serial); - register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial, qmp_chardev_open_serial); -#endif -#ifdef HAVE_CHARDEV_PARPORT - register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel, qmp_chardev_open_parallel); - register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel, qmp_chardev_open_parallel); -#endif -#ifdef HAVE_CHARDEV_PTY - register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, - qemu_chr_open_pty); -#endif -#ifdef _WIN32 - register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, - qemu_chr_open_win_con); -#endif - register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, - qemu_chr_parse_pipe, qemu_chr_open_pipe); - register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, - qemu_chr_open_mux); - /* Bug-compatibility: */ - register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, - qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); - /* this must be done after machine init, since we register FEs with muxes - * as part of realize functions like serial_isa_realizefn when -nographic - * is specified - */ - qemu_add_machine_init_done_notifier(&muxes_realize_notify); -} - -type_init(register_types); diff --git a/qtest.c b/qtest.c index 483b5a170bee7..5672b75c354b6 100644 --- a/qtest.c +++ b/qtest.c @@ -36,10 +36,11 @@ bool qtest_allowed; -static DeviceState *irq_intercept_dev = NULL; +static DeviceState *irq_intercept_dev; static FILE *qtest_log_fp; static CharBackend qtest_chr; static GString *inbuf; +static int irq_levels[MAX_IRQ]; static qemu_timeval start_time; static bool qtest_opened; static void (*qtest_server_send)(void*, const char*); @@ -149,24 +150,23 @@ static void *qtest_server_send_opaque; * * IRQ management: * - * > irq_intercept_in QOM-PATH ID-NUM + * > irq_intercept_in QOM-PATH * < OK * - * > irq_intercept_out QOM-PATH ID-NUM + * > irq_intercept_out QOM-PATH * < OK * * Attach to the gpio-in (resp. gpio-out) pins exported by the device at * QOM-PATH. When the pin is triggered, one of the following async messages * will be printed to the qtest stream: * - * IRQ raise GPIO-ID NUM - * IRQ lower GPIO-ID NUM + * IRQ raise NUM + * IRQ lower NUM * * where NUM is an IRQ number. For the PC, interrupts can be intercepted * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with * NUM=0 even though it is remapped to GSI 2). * -<<<<<<< HEAD * Setting interrupt level: * * > set_irq_in QOM-PATH NAME NUM LEVEL @@ -176,15 +176,6 @@ static void *qtest_server_send_opaque; * LEVEL is an signed integer IRQ level. * * Forcibly set the given interrupt pin to the given level. -======= - * A gpio-in IRQ mon an arbitrary device may be changed as follows: - * - * > set_irq_in QOM-PATH raise - * < OK - * - * > set_irq_in QOM-PATH lower - * < OK ->>>>>>> 919b29ba7d... Pebble Qemu * */ @@ -270,7 +261,6 @@ static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr, static void qtest_irq_handler(void *opaque, int n, int level) { -<<<<<<< HEAD qemu_irq old_irq = *(qemu_irq *)opaque; qemu_set_irq(old_irq, level); @@ -281,15 +271,6 @@ static void qtest_irq_handler(void *opaque, int n, int level) qtest_sendf(chr, "IRQ %s %d\n", level ? "raise" : "lower", n); } -======= - IRQInterceptData *intercept_data = opaque; - qemu_irq *old_irqs = intercept_data->old_irqs; - qemu_set_irq(old_irqs[n], level); - CharDriverState *chr = qtest_chr; - qtest_send_prefix(chr); - qtest_sendf(chr, "IRQ %s %d %d\n", - level ? "raise" : "lower", intercept_data->id, n); ->>>>>>> 919b29ba7d... Pebble Qemu } static void qtest_process_command(CharBackend *chr, gchar **words) @@ -318,7 +299,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) || strcmp(words[0], "irq_intercept_in") == 0) { DeviceState *dev; NamedGPIOList *ngl; - int id; g_assert(words[1]); dev = DEVICE(object_resolve_path(words[1], NULL)); @@ -328,35 +308,19 @@ static void qtest_process_command(CharBackend *chr, gchar **words) return; } - g_assert(words[2]); - id = strtoul(words[2], NULL, 0); - - if (irq_intercept_dev == dev) { + if (irq_intercept_dev) { qtest_send_prefix(chr); - qtest_send(chr, "OK\n"); - return; - } - QLIST_FOREACH(ngl, &dev->gpios, node) { - /* We don't support intercept of named GPIOs yet */ - if (ngl->name && (strcmp(ngl->name, "sysbus-irq") != 0)) { - continue; - } - if (words[0][14] == 'o') { - qemu_irq_intercept_out(&ngl->out, qtest_irq_handler, - id, ngl->num_out); + if (irq_intercept_dev != dev) { + qtest_send(chr, "FAIL IRQ intercept already enabled\n"); } else { - qemu_irq_intercept_in(ngl->in, qtest_irq_handler, - id, ngl->num_in); + qtest_send(chr, "OK\n"); } -<<<<<<< HEAD return; -======= ->>>>>>> 919b29ba7d... Pebble Qemu } -#if 0 + QLIST_FOREACH(ngl, &dev->gpios, node) { /* We don't support intercept of named GPIOs yet */ - if (ngl->name && (strcmp(ngl->name, "sysbus-irq") != 0)) { + if (ngl->name) { continue; } if (words[0][14] == 'o') { @@ -371,10 +335,9 @@ static void qtest_process_command(CharBackend *chr, gchar **words) } } else { qemu_irq_intercept_in(ngl->in, qtest_irq_handler, - id, ngl->num_in); + ngl->num_in); } } -#endif irq_intercept_dev = dev; qtest_send_prefix(chr); qtest_send(chr, "OK\n"); @@ -388,15 +351,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) g_assert(words[1] && words[2] && words[3] && words[4]); -<<<<<<< HEAD -======= - } else if (strcmp(words[0], "set_irq_in") == 0) { - DeviceState *dev; - qemu_irq irq; - unsigned n, level; - - g_assert(words[1]); ->>>>>>> 919b29ba7d... Pebble Qemu dev = DEVICE(object_resolve_path(words[1], NULL)); if (!dev) { qtest_send_prefix(chr); @@ -404,7 +358,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) return; } -<<<<<<< HEAD if (strcmp(words[2], "unnamed-gpio-in") == 0) { name = NULL; } else { @@ -420,20 +373,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words) qemu_set_irq(irq, level); qtest_send_prefix(chr); -======= - g_assert(words[2]); - n = strtoul(words[2], NULL, 0); - irq = qdev_get_gpio_in(dev, n); - - g_assert(words[3]); - if (strcmp(words[3], "raise") == 0) { - level = 1; - } else { - level = 0; - } - qemu_set_irq(irq, level); - ->>>>>>> 919b29ba7d... Pebble Qemu qtest_send(chr, "OK\n"); } else if (strcmp(words[0], "outb") == 0 || strcmp(words[0], "outw") == 0 || @@ -790,6 +729,8 @@ static int qtest_can_read(void *opaque) static void qtest_event(void *opaque, QEMUChrEvent event) { + int i; + switch (event) { case CHR_EVENT_OPENED: /* @@ -798,6 +739,9 @@ static void qtest_event(void *opaque, QEMUChrEvent event) * used. Injects an extra reset even when it's not used, and * that can mess up tests, e.g. -boot once. */ + for (i = 0; i < ARRAY_SIZE(irq_levels); i++) { + irq_levels[i] = 0; + } qemu_gettimeofday(&start_time); qtest_opened = true; if (qtest_log_fp) { diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c deleted file mode 100644 index 41f47f309c63e..0000000000000 --- a/target-arm/arm-semi.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Arm "Angel" semihosting syscalls - * - * Copyright (c) 2005, 2007 CodeSourcery. - * Written by Paul Brook. - * - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "cpu.h" -#include "exec/semihost.h" -#ifdef CONFIG_USER_ONLY -#include "qemu.h" - -#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) -#else -#include "qemu-common.h" -#include "exec/gdbstub.h" -#include "hw/arm/arm.h" -#endif - -#define TARGET_SYS_OPEN 0x01 -#define TARGET_SYS_CLOSE 0x02 -#define TARGET_SYS_WRITEC 0x03 -#define TARGET_SYS_WRITE0 0x04 -#define TARGET_SYS_WRITE 0x05 -#define TARGET_SYS_READ 0x06 -#define TARGET_SYS_READC 0x07 -#define TARGET_SYS_ISTTY 0x09 -#define TARGET_SYS_SEEK 0x0a -#define TARGET_SYS_FLEN 0x0c -#define TARGET_SYS_TMPNAM 0x0d -#define TARGET_SYS_REMOVE 0x0e -#define TARGET_SYS_RENAME 0x0f -#define TARGET_SYS_CLOCK 0x10 -#define TARGET_SYS_TIME 0x11 -#define TARGET_SYS_SYSTEM 0x12 -#define TARGET_SYS_ERRNO 0x13 -#define TARGET_SYS_GET_CMDLINE 0x15 -#define TARGET_SYS_HEAPINFO 0x16 -#define TARGET_SYS_EXIT 0x18 -#define TARGET_SYS_SYNCCACHE 0x19 - -/* ADP_Stopped_ApplicationExit is used for exit(0), - * anything else is implemented as exit(1) */ -#define ADP_Stopped_ApplicationExit (0x20026) - -/* ADP_Stopped_ApplicationExit is used for exit(0), - * anything else is implemented as exit(1) */ -#define ADP_Stopped_ApplicationExit (0x20026) - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#define GDB_O_RDONLY 0x000 -#define GDB_O_WRONLY 0x001 -#define GDB_O_RDWR 0x002 -#define GDB_O_APPEND 0x008 -#define GDB_O_CREAT 0x200 -#define GDB_O_TRUNC 0x400 -#define GDB_O_BINARY 0 - -static int gdb_open_modeflags[12] = { - GDB_O_RDONLY, - GDB_O_RDONLY | GDB_O_BINARY, - GDB_O_RDWR, - GDB_O_RDWR | GDB_O_BINARY, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY -}; - -static int open_modeflags[12] = { - O_RDONLY, - O_RDONLY | O_BINARY, - O_RDWR, - O_RDWR | O_BINARY, - O_WRONLY | O_CREAT | O_TRUNC, - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - O_RDWR | O_CREAT | O_TRUNC, - O_RDWR | O_CREAT | O_TRUNC | O_BINARY, - O_WRONLY | O_CREAT | O_APPEND, - O_WRONLY | O_CREAT | O_APPEND | O_BINARY, - O_RDWR | O_CREAT | O_APPEND, - O_RDWR | O_CREAT | O_APPEND | O_BINARY -}; - -#ifdef CONFIG_USER_ONLY -static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) -{ - if (code == (uint32_t)-1) - ts->swi_errno = errno; - return code; -} -#else -static inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code) -{ - return code; -} - -#include "exec/softmmu-semi.h" -#endif - -static target_ulong arm_semi_syscall_len; - -#if !defined(CONFIG_USER_ONLY) -static target_ulong syscall_err; -#endif - -static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; -#ifdef CONFIG_USER_ONLY - TaskState *ts = cs->opaque; -#endif - target_ulong reg0 = is_a64(env) ? env->xregs[0] : env->regs[0]; - - if (ret == (target_ulong)-1) { -#ifdef CONFIG_USER_ONLY - ts->swi_errno = err; -#else - syscall_err = err; -#endif - reg0 = ret; - } else { - /* Fixup syscalls that use nonstardard return conventions. */ - switch (reg0) { - case TARGET_SYS_WRITE: - case TARGET_SYS_READ: - reg0 = arm_semi_syscall_len - ret; - break; - case TARGET_SYS_SEEK: - reg0 = 0; - break; - default: - reg0 = ret; - break; - } - } - if (is_a64(env)) { - env->xregs[0] = reg0; - } else { - env->regs[0] = reg0; - } -} - -static target_ulong arm_flen_buf(ARMCPU *cpu) -{ - /* Return an address in target memory of 64 bytes where the remote - * gdb should write its stat struct. (The format of this structure - * is defined by GDB's remote protocol and is not target-specific.) - * We put this on the guest's stack just below SP. - */ - CPUARMState *env = &cpu->env; - target_ulong sp; - - if (is_a64(env)) { - sp = env->xregs[31]; - } else { - sp = env->regs[13]; - } - - return sp - 64; -} - -static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - /* The size is always stored in big-endian order, extract - the value. We assume the size always fit in 32 bits. */ - uint32_t size; - cpu_memory_rw_debug(cs, arm_flen_buf(cpu) + 32, (uint8_t *)&size, 4, 0); - size = be32_to_cpu(size); - if (is_a64(env)) { - env->xregs[0] = size; - } else { - env->regs[0] = size; - } -#ifdef CONFIG_USER_ONLY - ((TaskState *)cs->opaque)->swi_errno = err; -#else - syscall_err = err; -#endif -} - -static target_ulong arm_gdb_syscall(ARMCPU *cpu, gdb_syscall_complete_cb cb, - const char *fmt, ...) -{ - va_list va; - CPUARMState *env = &cpu->env; - - va_start(va, fmt); - gdb_do_syscallv(cb, fmt, va); - va_end(va); - - /* FIXME: we are implicitly relying on the syscall completing - * before this point, which is not guaranteed. We should - * put in an explicit synchronization between this and - * the callback function. - */ - - return is_a64(env) ? env->xregs[0] : env->regs[0]; -} - -/* Read the input value from the argument block; fail the semihosting - * call if the memory read fails. - */ -#define GET_ARG(n) do { \ - if (is_a64(env)) { \ - if (get_user_u64(arg ## n, args + (n) * 8)) { \ - return -1; \ - } \ - } else { \ - if (get_user_u32(arg ## n, args + (n) * 4)) { \ - return -1; \ - } \ - } \ -} while (0) - -#define SET_ARG(n, val) \ - (is_a64(env) ? \ - put_user_u64(val, args + (n) * 8) : \ - put_user_u32(val, args + (n) * 4)) - -target_ulong do_arm_semihosting(CPUARMState *env) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - target_ulong args; - target_ulong arg0, arg1, arg2, arg3; - char * s; - int nr; - uint32_t ret; - uint32_t len; -#ifdef CONFIG_USER_ONLY - TaskState *ts = cs->opaque; -#else - CPUARMState *ts = env; -#endif - - if (is_a64(env)) { - /* Note that the syscall number is in W0, not X0 */ - nr = env->xregs[0] & 0xffffffffU; - args = env->xregs[1]; - } else { - nr = env->regs[0]; - args = env->regs[1]; - } - - switch (nr) { - case TARGET_SYS_OPEN: - GET_ARG(0); - GET_ARG(1); - GET_ARG(2); - s = lock_user_string(arg0); - if (!s) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - if (arg1 >= 12) { - unlock_user(s, arg0, 0); - return (uint32_t)-1; - } - if (strcmp(s, ":tt") == 0) { - int result_fileno = arg1 < 4 ? STDIN_FILENO : STDOUT_FILENO; - unlock_user(s, arg0, 0); - return result_fileno; - } - if (use_gdb_syscalls()) { - ret = arm_gdb_syscall(cpu, arm_semi_cb, "open,%s,%x,1a4", arg0, - (int)arg2+1, gdb_open_modeflags[arg1]); - } else { - ret = set_swi_errno(ts, open(s, open_modeflags[arg1], 0644)); - } - unlock_user(s, arg0, 0); - return ret; - case TARGET_SYS_CLOSE: - GET_ARG(0); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "close,%x", arg0); - } else { - return set_swi_errno(ts, close(arg0)); - } - case TARGET_SYS_WRITEC: - { - char c; - - if (get_user_u8(c, args)) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - /* Write to debug console. stderr is near enough. */ - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "write,2,%x,1", args); - } else { - return write(STDERR_FILENO, &c, 1); - } - } - case TARGET_SYS_WRITE0: - if (!(s = lock_user_string(args))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - len = strlen(s); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "write,2,%x,%x", - args, len); - } else { - ret = write(STDERR_FILENO, s, len); - } - unlock_user(s, args, 0); - return ret; - case TARGET_SYS_WRITE: - GET_ARG(0); - GET_ARG(1); - GET_ARG(2); - len = arg2; - if (use_gdb_syscalls()) { - arm_semi_syscall_len = len; - return arm_gdb_syscall(cpu, arm_semi_cb, "write,%x,%x,%x", - arg0, arg1, len); - } else { - s = lock_user(VERIFY_READ, arg1, len, 1); - if (!s) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - ret = set_swi_errno(ts, write(arg0, s, len)); - unlock_user(s, arg1, 0); - if (ret == (uint32_t)-1) - return -1; - return len - ret; - } - case TARGET_SYS_READ: - GET_ARG(0); - GET_ARG(1); - GET_ARG(2); - len = arg2; - if (use_gdb_syscalls()) { - arm_semi_syscall_len = len; - return arm_gdb_syscall(cpu, arm_semi_cb, "read,%x,%x,%x", - arg0, arg1, len); - } else { - s = lock_user(VERIFY_WRITE, arg1, len, 0); - if (!s) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - do { - ret = set_swi_errno(ts, read(arg0, s, len)); - } while (ret == -1 && errno == EINTR); - unlock_user(s, arg1, len); - if (ret == (uint32_t)-1) - return -1; - return len - ret; - } - case TARGET_SYS_READC: - /* XXX: Read from debug console. Not implemented. */ - return 0; - case TARGET_SYS_ISTTY: - GET_ARG(0); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "isatty,%x", arg0); - } else { - return isatty(arg0); - } - case TARGET_SYS_SEEK: - GET_ARG(0); - GET_ARG(1); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "lseek,%x,%x,0", - arg0, arg1); - } else { - ret = set_swi_errno(ts, lseek(arg0, arg1, SEEK_SET)); - if (ret == (uint32_t)-1) - return -1; - return 0; - } - case TARGET_SYS_FLEN: - GET_ARG(0); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_flen_cb, "fstat,%x,%x", - arg0, arm_flen_buf(cpu)); - } else { - struct stat buf; - ret = set_swi_errno(ts, fstat(arg0, &buf)); - if (ret == (uint32_t)-1) - return -1; - return buf.st_size; - } - case TARGET_SYS_TMPNAM: - /* XXX: Not implemented. */ - return -1; - case TARGET_SYS_REMOVE: - GET_ARG(0); - GET_ARG(1); - if (use_gdb_syscalls()) { - ret = arm_gdb_syscall(cpu, arm_semi_cb, "unlink,%s", - arg0, (int)arg1+1); - } else { - s = lock_user_string(arg0); - if (!s) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - ret = set_swi_errno(ts, remove(s)); - unlock_user(s, arg0, 0); - } - return ret; - case TARGET_SYS_RENAME: - GET_ARG(0); - GET_ARG(1); - GET_ARG(2); - GET_ARG(3); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "rename,%s,%s", - arg0, (int)arg1+1, arg2, (int)arg3+1); - } else { - char *s2; - s = lock_user_string(arg0); - s2 = lock_user_string(arg2); - if (!s || !s2) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - ret = (uint32_t)-1; - else - ret = set_swi_errno(ts, rename(s, s2)); - if (s2) - unlock_user(s2, arg2, 0); - if (s) - unlock_user(s, arg0, 0); - return ret; - } - case TARGET_SYS_CLOCK: - return clock() / (CLOCKS_PER_SEC / 100); - case TARGET_SYS_TIME: - return set_swi_errno(ts, time(NULL)); - case TARGET_SYS_SYSTEM: - GET_ARG(0); - GET_ARG(1); - if (use_gdb_syscalls()) { - return arm_gdb_syscall(cpu, arm_semi_cb, "system,%s", - arg0, (int)arg1+1); - } else { - s = lock_user_string(arg0); - if (!s) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - ret = set_swi_errno(ts, system(s)); - unlock_user(s, arg0, 0); - return ret; - } - case TARGET_SYS_ERRNO: -#ifdef CONFIG_USER_ONLY - return ts->swi_errno; -#else - return syscall_err; -#endif - case TARGET_SYS_GET_CMDLINE: - { - /* Build a command-line from the original argv. - * - * The inputs are: - * * arg0, pointer to a buffer of at least the size - * specified in arg1. - * * arg1, size of the buffer pointed to by arg0 in - * bytes. - * - * The outputs are: - * * arg0, pointer to null-terminated string of the - * command line. - * * arg1, length of the string pointed to by arg0. - */ - - char *output_buffer; - size_t input_size; - size_t output_size; - int status = 0; -#if !defined(CONFIG_USER_ONLY) - const char *cmdline; -#endif - GET_ARG(0); - GET_ARG(1); - input_size = arg1; - /* Compute the size of the output string. */ -#if !defined(CONFIG_USER_ONLY) - cmdline = semihosting_get_cmdline(); - if (cmdline == NULL) { - cmdline = ""; /* Default to an empty line. */ - } - output_size = strlen(cmdline) + 1; /* Count terminating 0. */ -#else - unsigned int i; - - output_size = ts->info->arg_end - ts->info->arg_start; - if (!output_size) { - /* We special-case the "empty command line" case (argc==0). - Just provide the terminating 0. */ - output_size = 1; - } -#endif - - if (output_size > input_size) { - /* Not enough space to store command-line arguments. */ - return -1; - } - - /* Adjust the command-line length. */ - if (SET_ARG(1, output_size - 1)) { - /* Couldn't write back to argument block */ - return -1; - } - - /* Lock the buffer on the ARM side. */ - output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0); - if (!output_buffer) { - return -1; - } - - /* Copy the command-line arguments. */ -#if !defined(CONFIG_USER_ONLY) - pstrcpy(output_buffer, output_size, cmdline); -#else - if (output_size == 1) { - /* Empty command-line. */ - output_buffer[0] = '\0'; - goto out; - } - - if (copy_from_user(output_buffer, ts->info->arg_start, - output_size)) { - status = -1; - goto out; - } - - /* Separate arguments by white spaces. */ - for (i = 0; i < output_size - 1; i++) { - if (output_buffer[i] == 0) { - output_buffer[i] = ' '; - } - } - out: -#endif - /* Unlock the buffer on the ARM side. */ - unlock_user(output_buffer, arg0, output_size); - - return status; - } - case TARGET_SYS_HEAPINFO: - { - uint32_t *ptr; - uint32_t limit; - GET_ARG(0); - -#ifdef CONFIG_USER_ONLY - /* Some C libraries assume the heap immediately follows .bss, so - allocate it using sbrk. */ - if (!ts->heap_limit) { - abi_ulong ret; - - ts->heap_base = do_brk(0); - limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; - /* Try a big heap, and reduce the size if that fails. */ - for (;;) { - ret = do_brk(limit); - if (ret >= limit) { - break; - } - limit = (ts->heap_base >> 1) + (limit >> 1); - } - ts->heap_limit = limit; - } - - ptr = lock_user(VERIFY_WRITE, arg0, 16, 0); - if (!ptr) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - ptr[0] = tswap32(ts->heap_base); - ptr[1] = tswap32(ts->heap_limit); - ptr[2] = tswap32(ts->stack_base); - ptr[3] = tswap32(0); /* Stack limit. */ - unlock_user(ptr, arg0, 16); -#else - limit = ram_size; - ptr = lock_user(VERIFY_WRITE, arg0, 16, 0); - if (!ptr) { - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - } - /* TODO: Make this use the limit of the loaded application. */ - ptr[0] = tswap32(limit / 2); - ptr[1] = tswap32(limit); - ptr[2] = tswap32(limit); /* Stack base */ - ptr[3] = tswap32(0); /* Stack limit. */ - unlock_user(ptr, arg0, 16); -#endif - return 0; - } - case TARGET_SYS_EXIT: - if (is_a64(env)) { - /* The A64 version of this call takes a parameter block, - * so the application-exit type can return a subcode which - * is the exit status code from the application. - */ - GET_ARG(0); - GET_ARG(1); - - if (arg0 == ADP_Stopped_ApplicationExit) { - ret = arg1; - } else { - ret = 1; - } - } else { - /* ARM specifies only Stopped_ApplicationExit as normal - * exit, everything else is considered an error */ - ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1; - } - gdb_exit(env, ret); - exit(ret); - case TARGET_SYS_SYNCCACHE: - /* Clean the D-cache and invalidate the I-cache for the specified - * virtual address range. This is a nop for us since we don't - * implement caches. This is only present on A64. - */ - if (is_a64(env)) { - return 0; - } - /* fall through -- invalid for A32/T32 */ - default: - fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr); - cpu_dump_state(cs, stderr, fprintf, 0); - abort(); - } -} diff --git a/target-arm/cpu.c b/target-arm/cpu.c deleted file mode 100644 index 35932c656d422..0000000000000 --- a/target-arm/cpu.c +++ /dev/null @@ -1,1509 +0,0 @@ -/* - * QEMU ARM CPU - * - * Copyright (c) 2012 SUSE LINUX Products GmbH - * - * 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 - * - */ - -#include "cpu.h" -#include "internals.h" -#include "qemu-common.h" -#include "hw/qdev-properties.h" -#if !defined(CONFIG_USER_ONLY) -#include "hw/loader.h" -#endif -#include "hw/arm/arm.h" -#include "sysemu/sysemu.h" -#include "sysemu/kvm.h" -#include "kvm_arm.h" - -static void arm_cpu_set_pc(CPUState *cs, vaddr value) -{ - ARMCPU *cpu = ARM_CPU(cs); - - cpu->env.regs[15] = value; -} - -static bool arm_cpu_has_work(CPUState *cs) -{ - ARMCPU *cpu = ARM_CPU(cs); - - return !cpu->powered_off - && cs->interrupt_request & - (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD - | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ - | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_WKUP); -} - -static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) -{ - /* Reset a single ARMCPRegInfo register */ - ARMCPRegInfo *ri = value; - ARMCPU *cpu = opaque; - - if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) { - return; - } - - if (ri->resetfn) { - ri->resetfn(&cpu->env, ri); - return; - } - - /* A zero offset is never possible as it would be regs[0] - * so we use it to indicate that reset is being handled elsewhere. - * This is basically only used for fields in non-core coprocessors - * (like the pxa2xx ones). - */ - if (!ri->fieldoffset) { - return; - } - - if (cpreg_field_is_64bit(ri)) { - CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue; - } else { - CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue; - } -} - -static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque) -{ - /* Purely an assertion check: we've already done reset once, - * so now check that running the reset for the cpreg doesn't - * change its value. This traps bugs where two different cpregs - * both try to reset the same state field but to different values. - */ - ARMCPRegInfo *ri = value; - ARMCPU *cpu = opaque; - uint64_t oldvalue, newvalue; - - if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) { - return; - } - - oldvalue = read_raw_cp_reg(&cpu->env, ri); - cp_reg_reset(key, value, opaque); - newvalue = read_raw_cp_reg(&cpu->env, ri); - assert(oldvalue == newvalue); -} - -/* CPUClass::reset() */ -static void arm_cpu_reset(CPUState *s) -{ - ARMCPU *cpu = ARM_CPU(s); - ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); - CPUARMState *env = &cpu->env; - - acc->parent_reset(s); - - memset(env, 0, offsetof(CPUARMState, features)); - g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); - g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu); - - env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; - env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; - env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; - env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2; - - cpu->powered_off = cpu->start_powered_off; - s->halted = cpu->start_powered_off; - - if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; - } - - if (arm_feature(env, ARM_FEATURE_AARCH64)) { - /* 64 bit CPUs always start in 64 bit mode */ - env->aarch64 = 1; -#if defined(CONFIG_USER_ONLY) - env->pstate = PSTATE_MODE_EL0t; - /* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */ - env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE; - /* and to the FP/Neon instructions */ - env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3); -#else - /* Reset into the highest available EL */ - if (arm_feature(env, ARM_FEATURE_EL3)) { - env->pstate = PSTATE_MODE_EL3h; - } else if (arm_feature(env, ARM_FEATURE_EL2)) { - env->pstate = PSTATE_MODE_EL2h; - } else { - env->pstate = PSTATE_MODE_EL1h; - } - env->pc = cpu->rvbar; -#endif - } else { -#if defined(CONFIG_USER_ONLY) - /* Userspace expects access to cp10 and cp11 for FP/Neon */ - env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 4, 0xf); -#endif - } - -#if defined(CONFIG_USER_ONLY) - env->uncached_cpsr = ARM_CPU_MODE_USR; - /* For user mode we must enable access to coprocessors */ - env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; - if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - env->cp15.c15_cpar = 3; - } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { - env->cp15.c15_cpar = 1; - } -#else - /* SVC mode with interrupts disabled. */ - env->uncached_cpsr = ARM_CPU_MODE_SVC; - env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; - /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is - * clear at reset. Initial SP and PC are loaded from ROM. - */ - if (IS_M(env)) { - uint32_t initial_msp; /* Loaded from 0x0 */ - uint32_t initial_pc; /* Loaded from 0x4 */ - uint8_t *rom; - - env->daif &= ~PSTATE_I; - rom = rom_ptr(0); - if (rom) { - /* Address zero is covered by ROM which hasn't yet been - * copied into physical memory. - */ - initial_msp = ldl_p(rom); - initial_pc = ldl_p(rom + 4); - } else { - /* Address zero not covered by a ROM blob, or the ROM blob - * is in non-modifiable memory and this is a second reset after - * it got copied into memory. In the latter case, rom_ptr - * will return a NULL pointer and we should use ldl_phys instead. - */ - initial_msp = ldl_phys(s->as, 0); - initial_pc = ldl_phys(s->as, 4); - } - - env->regs[13] = initial_msp & 0xFFFFFFFC; - env->regs[15] = initial_pc & ~1; - env->thumb = initial_pc & 1; - } - - /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently - * executing as AArch32 then check if highvecs are enabled and - * adjust the PC accordingly. - */ - if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) { - env->regs[15] = 0xFFFF0000; - } - - env->vfp.xregs[ARM_VFP_FPEXC] = 0; -#endif - set_flush_to_zero(1, &env->vfp.standard_fp_status); - set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); - set_default_nan_mode(1, &env->vfp.standard_fp_status); - set_float_detect_tininess(float_tininess_before_rounding, - &env->vfp.fp_status); - set_float_detect_tininess(float_tininess_before_rounding, - &env->vfp.standard_fp_status); - tlb_flush(s, 1); - /* Reset is a state change for some CPUARMState fields which we - * bake assumptions about into translated code, so we need to - * tb_flush(). - */ - tb_flush(&(cpu->parent_obj)); - -#ifndef CONFIG_USER_ONLY - if (kvm_enabled()) { - kvm_arm_reset_vcpu(cpu); - } -#endif - - hw_breakpoint_update_all(cpu); - hw_watchpoint_update_all(cpu); -} - -bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -{ - CPUClass *cc = CPU_GET_CLASS(cs); - CPUARMState *env = cs->env_ptr; - uint32_t cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - uint32_t target_el; - uint32_t excp_idx; - bool ret = false; - - if (interrupt_request & CPU_INTERRUPT_FIQ) { - excp_idx = EXCP_FIQ; - target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); - if (arm_excp_unmasked(cs, excp_idx, target_el)) { - cs->exception_index = excp_idx; - env->exception.target_el = target_el; - cc->do_interrupt(cs); - ret = true; - } - } - if (interrupt_request & CPU_INTERRUPT_HARD) { - excp_idx = EXCP_IRQ; - target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); - if (arm_excp_unmasked(cs, excp_idx, target_el)) { - cs->exception_index = excp_idx; - env->exception.target_el = target_el; - cc->do_interrupt(cs); - ret = true; - } - } - if (interrupt_request & CPU_INTERRUPT_VIRQ) { - excp_idx = EXCP_VIRQ; - target_el = 1; - if (arm_excp_unmasked(cs, excp_idx, target_el)) { - cs->exception_index = excp_idx; - env->exception.target_el = target_el; - cc->do_interrupt(cs); - ret = true; - } - } - if (interrupt_request & CPU_INTERRUPT_VFIQ) { - excp_idx = EXCP_VFIQ; - target_el = 1; - if (arm_excp_unmasked(cs, excp_idx, target_el)) { - cs->exception_index = excp_idx; - env->exception.target_el = target_el; - cc->do_interrupt(cs); - ret = true; - } - } - if (interrupt_request & CPU_INTERRUPT_WKUP) { - excp_idx = EXCP_WKUP; - target_el = 1; - if (arm_excp_unmasked(cs, excp_idx, target_el)) { - cs->exception_index = excp_idx; - env->exception.target_el = target_el; - cc->do_interrupt(cs); - ret = true; - } - } - return ret; -} - -#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) -static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -{ - CPUClass *cc = CPU_GET_CLASS(cs); - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - bool ret = false; - - - if (interrupt_request & CPU_INTERRUPT_FIQ - && !(env->daif & PSTATE_F)) { - cs->exception_index = EXCP_FIQ; - cc->do_interrupt(cs); - ret = true; - } - /* ARMv7-M interrupt return works by loading a magic value - * into the PC. On real hardware the load causes the - * return to occur. The qemu implementation performs the - * jump normally, then does the exception return when the - * CPU tries to execute code at the magic address. - * This will cause the magic PC value to be pushed to - * the stack if an interrupt occurred at the wrong time. - * We avoid this by disabling interrupts when - * pc contains a magic address. - */ - if (interrupt_request & CPU_INTERRUPT_HARD - && !(env->daif & PSTATE_I) - && (env->regs[15] < 0xfffffff0)) { - cs->exception_index = EXCP_IRQ; - cc->do_interrupt(cs); - ret = true; - } - - /* This gets sent if the WKUP pin got asserted while we were in - * standby. Simply wake up without taking an interrupt */ - if (interrupt_request & CPU_INTERRUPT_WKUP) { - cs->interrupt_request &= ~CPU_INTERRUPT_WKUP; - cs->exception_index = EXCP_WKUP; - cc->do_interrupt(cs); - } - - return ret; -} -#endif - -#ifndef CONFIG_USER_ONLY -static void arm_cpu_set_irq(void *opaque, int irq, int level) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - CPUState *cs = CPU(cpu); - static const int mask[] = { - [ARM_CPU_IRQ] = CPU_INTERRUPT_HARD, - [ARM_CPU_FIQ] = CPU_INTERRUPT_FIQ, - [ARM_CPU_VIRQ] = CPU_INTERRUPT_VIRQ, - [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ, - [ARM_CPU_WKUP] = CPU_INTERRUPT_WKUP - }; - - switch (irq) { - case ARM_CPU_VIRQ: - case ARM_CPU_VFIQ: - assert(arm_feature(env, ARM_FEATURE_EL2)); - /* fall through */ - case ARM_CPU_IRQ: - case ARM_CPU_FIQ: - case ARM_CPU_WKUP: - if (level) { - cpu_interrupt(cs, mask[irq]); - } else { - cpu_reset_interrupt(cs, mask[irq]); - } - break; - default: - g_assert_not_reached(); - } -} - -static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level) -{ -#ifdef CONFIG_KVM - ARMCPU *cpu = opaque; - CPUState *cs = CPU(cpu); - int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT; - - switch (irq) { - case ARM_CPU_IRQ: - kvm_irq |= KVM_ARM_IRQ_CPU_IRQ; - break; - case ARM_CPU_FIQ: - kvm_irq |= KVM_ARM_IRQ_CPU_FIQ; - break; - default: - g_assert_not_reached(); - } - kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT; - kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0); -#endif -} - -static bool arm_cpu_is_big_endian(CPUState *cs) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - int cur_el; - - cpu_synchronize_state(cs); - - /* In 32bit guest endianness is determined by looking at CPSR's E bit */ - if (!is_a64(env)) { - return (env->uncached_cpsr & CPSR_E) ? 1 : 0; - } - - cur_el = arm_current_el(env); - - if (cur_el == 0) { - return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0; - } - - return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0; -} - -#endif - -static inline void set_feature(CPUARMState *env, int feature) -{ - env->features |= 1ULL << feature; -} - -static inline void unset_feature(CPUARMState *env, int feature) -{ - env->features &= ~(1ULL << feature); -} - -static int -print_insn_thumb1(bfd_vma pc, disassemble_info *info) -{ - return print_insn_arm(pc | 1, info); -} - -static void arm_disas_set_info(CPUState *cpu, disassemble_info *info) -{ - ARMCPU *ac = ARM_CPU(cpu); - CPUARMState *env = &ac->env; - - if (is_a64(env)) { - /* We might not be compiled with the A64 disassembler - * because it needs a C++ compiler. Leave print_insn - * unset in this case to use the caller default behaviour. - */ -#if defined(CONFIG_ARM_A64_DIS) - info->print_insn = print_insn_arm_a64; -#endif - } else if (env->thumb) { - info->print_insn = print_insn_thumb1; - } else { - info->print_insn = print_insn_arm; - } - if (env->bswap_code) { -#ifdef TARGET_WORDS_BIGENDIAN - info->endian = BFD_ENDIAN_LITTLE; -#else - info->endian = BFD_ENDIAN_BIG; -#endif - } -} - -#define ARM_CPUS_PER_CLUSTER 8 - -static void arm_cpu_initfn(Object *obj) -{ - CPUState *cs = CPU(obj); - ARMCPU *cpu = ARM_CPU(obj); - static bool inited; - uint32_t Aff1, Aff0; - - cs->env_ptr = &cpu->env; - cpu_exec_init(cs, &error_abort); - cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, - g_free, g_free); - - /* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it. - * We don't support setting cluster ID ([16..23]) (known as Aff2 - * in later ARM ARM versions), or any of the higher affinity level fields, - * so these bits always RAZ. - */ - Aff1 = cs->cpu_index / ARM_CPUS_PER_CLUSTER; - Aff0 = cs->cpu_index % ARM_CPUS_PER_CLUSTER; - cpu->mp_affinity = (Aff1 << ARM_AFF1_SHIFT) | Aff0; - -#ifndef CONFIG_USER_ONLY - /* Our inbound IRQ and FIQ lines */ - if (kvm_enabled()) { - /* VIRQ and VFIQ are unused with KVM but we add them to maintain - * the same interface as non-KVM CPUs. - */ - qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 5); - } else { - qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 5); - } - - cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, - arm_gt_ptimer_cb, cpu); - cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, - arm_gt_vtimer_cb, cpu); - cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, - arm_gt_htimer_cb, cpu); - cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, - arm_gt_stimer_cb, cpu); - qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs, - ARRAY_SIZE(cpu->gt_timer_outputs)); -#endif - - /* DTB consumers generally don't in fact care what the 'compatible' - * string is, so always provide some string and trust that a hypothetical - * picky DTB consumer will also provide a helpful error message. - */ - cpu->dtb_compatible = "qemu,unknown"; - cpu->psci_version = 1; /* By default assume PSCI v0.1 */ - cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; - - if (tcg_enabled()) { - cpu->psci_version = 2; /* TCG implements PSCI 0.2 */ - if (!inited) { - inited = true; - arm_translate_init(); - } - } -} - -static Property arm_cpu_reset_cbar_property = - DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0); - -static Property arm_cpu_reset_hivecs_property = - DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false); - -static Property arm_cpu_rvbar_property = - DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0); - -static Property arm_cpu_has_el3_property = - DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true); - -static Property arm_cpu_has_mpu_property = - DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); - -static Property arm_cpu_pmsav7_dregion_property = - DEFINE_PROP_UINT32("pmsav7-dregion", ARMCPU, pmsav7_dregion, 16); - -static void arm_cpu_post_init(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) || - arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) { - qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property, - &error_abort); - } - - if (!arm_feature(&cpu->env, ARM_FEATURE_M)) { - qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property, - &error_abort); - } - - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property, - &error_abort); - } - - if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { - /* Add the has_el3 state CPU property only if EL3 is allowed. This will - * prevent "has_el3" from existing on CPUs which cannot support EL3. - */ - qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el3_property, - &error_abort); - } - - if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) { - qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, - &error_abort); - if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { - qdev_property_add_static(DEVICE(obj), - &arm_cpu_pmsav7_dregion_property, - &error_abort); - } - } - -} - -static void arm_cpu_finalizefn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - g_hash_table_destroy(cpu->cp_regs); -} - -static void arm_cpu_realizefn(DeviceState *dev, Error **errp) -{ - CPUState *cs = CPU(dev); - ARMCPU *cpu = ARM_CPU(dev); - ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev); - CPUARMState *env = &cpu->env; - - /* Some features automatically imply others: */ - if (arm_feature(env, ARM_FEATURE_V8)) { - set_feature(env, ARM_FEATURE_V7); - set_feature(env, ARM_FEATURE_ARM_DIV); - set_feature(env, ARM_FEATURE_LPAE); - } - if (arm_feature(env, ARM_FEATURE_V7)) { - set_feature(env, ARM_FEATURE_VAPA); - set_feature(env, ARM_FEATURE_THUMB2); - set_feature(env, ARM_FEATURE_MPIDR); - if (!arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_V6K); - } else { - set_feature(env, ARM_FEATURE_V6); - } - } - if (arm_feature(env, ARM_FEATURE_V6K)) { - set_feature(env, ARM_FEATURE_V6); - set_feature(env, ARM_FEATURE_MVFR); - } - if (arm_feature(env, ARM_FEATURE_V6)) { - set_feature(env, ARM_FEATURE_V5); - if (!arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_AUXCR); - } - } - if (arm_feature(env, ARM_FEATURE_V5)) { - set_feature(env, ARM_FEATURE_V4T); - } - if (arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_THUMB_DIV); - } - if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { - set_feature(env, ARM_FEATURE_THUMB_DIV); - } - if (arm_feature(env, ARM_FEATURE_VFP4)) { - set_feature(env, ARM_FEATURE_VFP3); - set_feature(env, ARM_FEATURE_VFP_FP16); - } - if (arm_feature(env, ARM_FEATURE_VFP3)) { - set_feature(env, ARM_FEATURE_VFP); - } - if (arm_feature(env, ARM_FEATURE_LPAE)) { - set_feature(env, ARM_FEATURE_V7MP); - set_feature(env, ARM_FEATURE_PXN); - } - if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { - set_feature(env, ARM_FEATURE_CBAR); - } - if (arm_feature(env, ARM_FEATURE_THUMB2) && - !arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_THUMB_DSP); - } - - if (cpu->reset_hivecs) { - cpu->reset_sctlr |= (1 << 13); - } - - if (!cpu->has_el3) { - /* If the has_el3 CPU property is disabled then we need to disable the - * feature. - */ - unset_feature(env, ARM_FEATURE_EL3); - - /* Disable the security extension feature bits in the processor feature - * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12]. - */ - cpu->id_pfr1 &= ~0xf0; - cpu->id_aa64pfr0 &= ~0xf000; - } - - if (!cpu->has_mpu) { - unset_feature(env, ARM_FEATURE_MPU); - } - - if (arm_feature(env, ARM_FEATURE_MPU) && - arm_feature(env, ARM_FEATURE_V7)) { - uint32_t nr = cpu->pmsav7_dregion; - - if (nr > 0xff) { - error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32 "\n", nr); - return; - } - - if (nr) { - env->pmsav7.drbar = g_new0(uint32_t, nr); - env->pmsav7.drsr = g_new0(uint32_t, nr); - env->pmsav7.dracr = g_new0(uint32_t, nr); - } - } - - register_cp_regs_for_features(cpu); - arm_cpu_register_gdb_regs_for_features(cpu); - - init_cpreg_list(cpu); - - qemu_init_vcpu(cs); - cpu_reset(cs); - - acc->parent_realize(dev, errp); -} - -static ObjectClass *arm_cpu_class_by_name(const char *cpu_model) -{ - ObjectClass *oc; - char *typename; - char **cpuname; - - if (!cpu_model) { - return NULL; - } - - cpuname = g_strsplit(cpu_model, ",", 1); - typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpuname[0]); - oc = object_class_by_name(typename); - g_strfreev(cpuname); - g_free(typename); - if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) || - object_class_is_abstract(oc)) { - return NULL; - } - return oc; -} - -/* CPU models. These are not needed for the AArch64 linux-user build. */ -#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) - -static void arm926_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,arm926"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_VFP); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); - cpu->midr = 0x41069265; - cpu->reset_fpsid = 0x41011090; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00090078; -} - -static void arm946_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,arm946"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_MPU); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - cpu->midr = 0x41059461; - cpu->ctr = 0x0f004006; - cpu->reset_sctlr = 0x00000078; -} - -static void arm1026_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,arm1026"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_VFP); - set_feature(&cpu->env, ARM_FEATURE_AUXCR); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); - cpu->midr = 0x4106a262; - cpu->reset_fpsid = 0x410110a0; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00090078; - cpu->reset_auxcr = 1; - { - /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */ - ARMCPRegInfo ifar = { - .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns), - .resetvalue = 0 - }; - define_one_arm_cp_reg(cpu, &ifar); - } -} - -static void arm1136_r2_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an - * older core than plain "arm1136". In particular this does not - * have the v6K features. - * These ID register values are correct for 1136 but may be wrong - * for 1136_r2 (in particular r0p2 does not actually implement most - * of the ID registers). - */ - - cpu->dtb_compatible = "arm,arm1136"; - set_feature(&cpu->env, ARM_FEATURE_V6); - set_feature(&cpu->env, ARM_FEATURE_VFP); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); - set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); - cpu->midr = 0x4107b362; - cpu->reset_fpsid = 0x410120b4; - cpu->mvfr0 = 0x11111111; - cpu->mvfr1 = 0x00000000; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00050078; - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x1; - cpu->id_dfr0 = 0x2; - cpu->id_afr0 = 0x3; - cpu->id_mmfr0 = 0x01130003; - cpu->id_mmfr1 = 0x10030302; - cpu->id_mmfr2 = 0x01222110; - cpu->id_isar0 = 0x00140011; - cpu->id_isar1 = 0x12002111; - cpu->id_isar2 = 0x11231111; - cpu->id_isar3 = 0x01102131; - cpu->id_isar4 = 0x141; - cpu->reset_auxcr = 7; -} - -static void arm1136_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,arm1136"; - set_feature(&cpu->env, ARM_FEATURE_V6K); - set_feature(&cpu->env, ARM_FEATURE_V6); - set_feature(&cpu->env, ARM_FEATURE_VFP); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); - set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); - cpu->midr = 0x4117b363; - cpu->reset_fpsid = 0x410120b4; - cpu->mvfr0 = 0x11111111; - cpu->mvfr1 = 0x00000000; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00050078; - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x1; - cpu->id_dfr0 = 0x2; - cpu->id_afr0 = 0x3; - cpu->id_mmfr0 = 0x01130003; - cpu->id_mmfr1 = 0x10030302; - cpu->id_mmfr2 = 0x01222110; - cpu->id_isar0 = 0x00140011; - cpu->id_isar1 = 0x12002111; - cpu->id_isar2 = 0x11231111; - cpu->id_isar3 = 0x01102131; - cpu->id_isar4 = 0x141; - cpu->reset_auxcr = 7; -} - -static void arm1176_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,arm1176"; - set_feature(&cpu->env, ARM_FEATURE_V6K); - set_feature(&cpu->env, ARM_FEATURE_VFP); - set_feature(&cpu->env, ARM_FEATURE_VAPA); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); - set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); - set_feature(&cpu->env, ARM_FEATURE_EL3); - cpu->midr = 0x410fb767; - cpu->reset_fpsid = 0x410120b5; - cpu->mvfr0 = 0x11111111; - cpu->mvfr1 = 0x00000000; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00050078; - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x11; - cpu->id_dfr0 = 0x33; - cpu->id_afr0 = 0; - cpu->id_mmfr0 = 0x01130003; - cpu->id_mmfr1 = 0x10030302; - cpu->id_mmfr2 = 0x01222100; - cpu->id_isar0 = 0x0140011; - cpu->id_isar1 = 0x12002111; - cpu->id_isar2 = 0x11231121; - cpu->id_isar3 = 0x01102131; - cpu->id_isar4 = 0x01141; - cpu->reset_auxcr = 7; -} - -static void arm11mpcore_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,arm11mpcore"; - set_feature(&cpu->env, ARM_FEATURE_V6K); - set_feature(&cpu->env, ARM_FEATURE_VFP); - set_feature(&cpu->env, ARM_FEATURE_VAPA); - set_feature(&cpu->env, ARM_FEATURE_MPIDR); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - cpu->midr = 0x410fb022; - cpu->reset_fpsid = 0x410120b4; - cpu->mvfr0 = 0x11111111; - cpu->mvfr1 = 0x00000000; - cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x1; - cpu->id_dfr0 = 0; - cpu->id_afr0 = 0x2; - cpu->id_mmfr0 = 0x01100103; - cpu->id_mmfr1 = 0x10020302; - cpu->id_mmfr2 = 0x01222000; - cpu->id_isar0 = 0x00100011; - cpu->id_isar1 = 0x12002111; - cpu->id_isar2 = 0x11221011; - cpu->id_isar3 = 0x01102131; - cpu->id_isar4 = 0x141; - cpu->reset_auxcr = 1; -} - -static void cortex_m3_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - set_feature(&cpu->env, ARM_FEATURE_V7); - set_feature(&cpu->env, ARM_FEATURE_M); - set_feature(&cpu->env, ARM_FEATURE_MPU); - cpu->midr = 0x410fc231; -} - -static void cortex_m4_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - set_feature(&cpu->env, ARM_FEATURE_V7); - set_feature(&cpu->env, ARM_FEATURE_M); - set_feature(&cpu->env, ARM_FEATURE_MPU); - set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); - cpu->midr = 0x410fc240; /* r0p0 */ -} -static void arm_v7m_class_init(ObjectClass *oc, void *data) -{ - CPUClass *cc = CPU_CLASS(oc); - -#ifndef CONFIG_USER_ONLY - cc->do_interrupt = arm_v7m_cpu_do_interrupt; -#endif - - cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; -} - -static const ARMCPRegInfo cortexr5_cp_reginfo[] = { - /* Dummy the TCM region regs for the moment */ - { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_CONST }, - { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, - .access = PL1_RW, .type = ARM_CP_CONST }, - REGINFO_SENTINEL -}; - -static void cortex_r5_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - set_feature(&cpu->env, ARM_FEATURE_V7); - set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV); - set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); - set_feature(&cpu->env, ARM_FEATURE_V7MP); - set_feature(&cpu->env, ARM_FEATURE_MPU); - cpu->midr = 0x411fc153; /* r1p3 */ - cpu->id_pfr0 = 0x0131; - cpu->id_pfr1 = 0x001; - cpu->id_dfr0 = 0x010400; - cpu->id_afr0 = 0x0; - cpu->id_mmfr0 = 0x0210030; - cpu->id_mmfr1 = 0x00000000; - cpu->id_mmfr2 = 0x01200000; - cpu->id_mmfr3 = 0x0211; - cpu->id_isar0 = 0x2101111; - cpu->id_isar1 = 0x13112111; - cpu->id_isar2 = 0x21232141; - cpu->id_isar3 = 0x01112131; - cpu->id_isar4 = 0x0010142; - cpu->id_isar5 = 0x0; - cpu->mp_is_up = true; - define_arm_cp_regs(cpu, cortexr5_cp_reginfo); -} - -static const ARMCPRegInfo cortexa8_cp_reginfo[] = { - { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, - .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static void cortex_a8_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,cortex-a8"; - set_feature(&cpu->env, ARM_FEATURE_V7); - set_feature(&cpu->env, ARM_FEATURE_VFP3); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_EL3); - cpu->midr = 0x410fc080; - cpu->reset_fpsid = 0x410330c0; - cpu->mvfr0 = 0x11110222; - cpu->mvfr1 = 0x00011100; - cpu->ctr = 0x82048004; - cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x1031; - cpu->id_pfr1 = 0x11; - cpu->id_dfr0 = 0x400; - cpu->id_afr0 = 0; - cpu->id_mmfr0 = 0x31100003; - cpu->id_mmfr1 = 0x20000000; - cpu->id_mmfr2 = 0x01202000; - cpu->id_mmfr3 = 0x11; - cpu->id_isar0 = 0x00101111; - cpu->id_isar1 = 0x12112111; - cpu->id_isar2 = 0x21232031; - cpu->id_isar3 = 0x11112131; - cpu->id_isar4 = 0x00111142; - cpu->dbgdidr = 0x15141000; - cpu->clidr = (1 << 27) | (2 << 24) | 3; - cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ - cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ - cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ - cpu->reset_auxcr = 2; - define_arm_cp_regs(cpu, cortexa8_cp_reginfo); -} - -static const ARMCPRegInfo cortexa9_cp_reginfo[] = { - /* power_control should be set to maximum latency. Again, - * default to 0 and set by private hook - */ - { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) }, - { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) }, - { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) }, - { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, - /* TLB lockdown control */ - { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2, - .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, - { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4, - .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, - { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2, - .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, - { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2, - .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, - { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2, - .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, - REGINFO_SENTINEL -}; - -static void cortex_a9_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,cortex-a9"; - set_feature(&cpu->env, ARM_FEATURE_V7); - set_feature(&cpu->env, ARM_FEATURE_VFP3); - set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); - set_feature(&cpu->env, ARM_FEATURE_EL3); - /* Note that A9 supports the MP extensions even for - * A9UP and single-core A9MP (which are both different - * and valid configurations; we don't model A9UP). - */ - set_feature(&cpu->env, ARM_FEATURE_V7MP); - set_feature(&cpu->env, ARM_FEATURE_CBAR); - cpu->midr = 0x410fc090; - cpu->reset_fpsid = 0x41033090; - cpu->mvfr0 = 0x11110222; - cpu->mvfr1 = 0x01111111; - cpu->ctr = 0x80038003; - cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x1031; - cpu->id_pfr1 = 0x11; - cpu->id_dfr0 = 0x000; - cpu->id_afr0 = 0; - cpu->id_mmfr0 = 0x00100103; - cpu->id_mmfr1 = 0x20000000; - cpu->id_mmfr2 = 0x01230000; - cpu->id_mmfr3 = 0x00002111; - cpu->id_isar0 = 0x00101111; - cpu->id_isar1 = 0x13112111; - cpu->id_isar2 = 0x21232041; - cpu->id_isar3 = 0x11112131; - cpu->id_isar4 = 0x00111142; - cpu->dbgdidr = 0x35141000; - cpu->clidr = (1 << 27) | (1 << 24) | 3; - cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ - cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ - define_arm_cp_regs(cpu, cortexa9_cp_reginfo); -} - -#ifndef CONFIG_USER_ONLY -static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* Linux wants the number of processors from here. - * Might as well set the interrupt-controller bit too. - */ - return ((smp_cpus - 1) << 24) | (1 << 23); -} -#endif - -static const ARMCPRegInfo cortexa15_cp_reginfo[] = { -#ifndef CONFIG_USER_ONLY - { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, - .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read, - .writefn = arm_cp_write_ignore, }, -#endif - { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3, - .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static void cortex_a15_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,cortex-a15"; - set_feature(&cpu->env, ARM_FEATURE_V7); - set_feature(&cpu->env, ARM_FEATURE_VFP4); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); - set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); - set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); - set_feature(&cpu->env, ARM_FEATURE_LPAE); - set_feature(&cpu->env, ARM_FEATURE_EL3); - cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15; - cpu->midr = 0x412fc0f1; - cpu->reset_fpsid = 0x410430f0; - cpu->mvfr0 = 0x10110222; - cpu->mvfr1 = 0x11111111; - cpu->ctr = 0x8444c004; - cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x00001131; - cpu->id_pfr1 = 0x00011011; - cpu->id_dfr0 = 0x02010555; - cpu->id_afr0 = 0x00000000; - cpu->id_mmfr0 = 0x10201105; - cpu->id_mmfr1 = 0x20000000; - cpu->id_mmfr2 = 0x01240000; - cpu->id_mmfr3 = 0x02102211; - cpu->id_isar0 = 0x02101110; - cpu->id_isar1 = 0x13112111; - cpu->id_isar2 = 0x21232041; - cpu->id_isar3 = 0x11112131; - cpu->id_isar4 = 0x10011142; - cpu->dbgdidr = 0x3515f021; - cpu->clidr = 0x0a200023; - cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ - cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ - cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ - define_arm_cp_regs(cpu, cortexa15_cp_reginfo); -} - -static void ti925t_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - set_feature(&cpu->env, ARM_FEATURE_V4T); - set_feature(&cpu->env, ARM_FEATURE_OMAPCP); - cpu->midr = ARM_CPUID_TI925T; - cpu->ctr = 0x5109149; - cpu->reset_sctlr = 0x00000070; -} - -static void sa1100_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "intel,sa1100"; - set_feature(&cpu->env, ARM_FEATURE_STRONGARM); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - cpu->midr = 0x4401A11B; - cpu->reset_sctlr = 0x00000070; -} - -static void sa1110_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - set_feature(&cpu->env, ARM_FEATURE_STRONGARM); - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - cpu->midr = 0x6901B119; - cpu->reset_sctlr = 0x00000070; -} - -static void pxa250_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - cpu->midr = 0x69052100; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa255_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - cpu->midr = 0x69052d00; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa260_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - cpu->midr = 0x69052903; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa261_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - cpu->midr = 0x69052d05; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa262_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - cpu->midr = 0x69052d06; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa270a0_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - set_feature(&cpu->env, ARM_FEATURE_IWMMXT); - cpu->midr = 0x69054110; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa270a1_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - set_feature(&cpu->env, ARM_FEATURE_IWMMXT); - cpu->midr = 0x69054111; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa270b0_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - set_feature(&cpu->env, ARM_FEATURE_IWMMXT); - cpu->midr = 0x69054112; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa270b1_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - set_feature(&cpu->env, ARM_FEATURE_IWMMXT); - cpu->midr = 0x69054113; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa270c0_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - set_feature(&cpu->env, ARM_FEATURE_IWMMXT); - cpu->midr = 0x69054114; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -static void pxa270c5_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "marvell,xscale"; - set_feature(&cpu->env, ARM_FEATURE_V5); - set_feature(&cpu->env, ARM_FEATURE_XSCALE); - set_feature(&cpu->env, ARM_FEATURE_IWMMXT); - cpu->midr = 0x69054117; - cpu->ctr = 0xd172172; - cpu->reset_sctlr = 0x00000078; -} - -#ifdef CONFIG_USER_ONLY -static void arm_any_initfn(Object *obj) -{ - ARMCPU *cpu = ARM_CPU(obj); - set_feature(&cpu->env, ARM_FEATURE_V8); - set_feature(&cpu->env, ARM_FEATURE_VFP4); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); - set_feature(&cpu->env, ARM_FEATURE_V8_AES); - set_feature(&cpu->env, ARM_FEATURE_V8_SHA1); - set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); - set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); - set_feature(&cpu->env, ARM_FEATURE_CRC); - cpu->midr = 0xffffffff; -} -#endif - -#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */ - -typedef struct ARMCPUInfo { - const char *name; - void (*initfn)(Object *obj); - void (*class_init)(ObjectClass *oc, void *data); -} ARMCPUInfo; - -static const ARMCPUInfo arm_cpus[] = { -#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) - { .name = "arm926", .initfn = arm926_initfn }, - { .name = "arm946", .initfn = arm946_initfn }, - { .name = "arm1026", .initfn = arm1026_initfn }, - /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an - * older core than plain "arm1136". In particular this does not - * have the v6K features. - */ - { .name = "arm1136-r2", .initfn = arm1136_r2_initfn }, - { .name = "arm1136", .initfn = arm1136_initfn }, - { .name = "arm1176", .initfn = arm1176_initfn }, - { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, - { .name = "cortex-m3", .initfn = cortex_m3_initfn, - .class_init = arm_v7m_class_init }, - { .name = "cortex-m4", .initfn = cortex_m4_initfn, - .class_init = arm_v7m_class_init }, - { .name = "cortex-r5", .initfn = cortex_r5_initfn }, - { .name = "cortex-a8", .initfn = cortex_a8_initfn }, - { .name = "cortex-a9", .initfn = cortex_a9_initfn }, - { .name = "cortex-a15", .initfn = cortex_a15_initfn }, - { .name = "ti925t", .initfn = ti925t_initfn }, - { .name = "sa1100", .initfn = sa1100_initfn }, - { .name = "sa1110", .initfn = sa1110_initfn }, - { .name = "pxa250", .initfn = pxa250_initfn }, - { .name = "pxa255", .initfn = pxa255_initfn }, - { .name = "pxa260", .initfn = pxa260_initfn }, - { .name = "pxa261", .initfn = pxa261_initfn }, - { .name = "pxa262", .initfn = pxa262_initfn }, - /* "pxa270" is an alias for "pxa270-a0" */ - { .name = "pxa270", .initfn = pxa270a0_initfn }, - { .name = "pxa270-a0", .initfn = pxa270a0_initfn }, - { .name = "pxa270-a1", .initfn = pxa270a1_initfn }, - { .name = "pxa270-b0", .initfn = pxa270b0_initfn }, - { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, - { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, - { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, -#ifdef CONFIG_USER_ONLY - { .name = "any", .initfn = arm_any_initfn }, -#endif -#endif - { .name = NULL } -}; - -static Property arm_cpu_properties[] = { - DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false), - DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0), - DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0), - DEFINE_PROP_END_OF_LIST() -}; - -#ifdef CONFIG_USER_ONLY -static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, - int mmu_idx) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - - env->exception.vaddress = address; - if (rw == 2) { - cs->exception_index = EXCP_PREFETCH_ABORT; - } else { - cs->exception_index = EXCP_DATA_ABORT; - } - return 1; -} -#endif - -static void arm_cpu_class_init(ObjectClass *oc, void *data) -{ - ARMCPUClass *acc = ARM_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(acc); - DeviceClass *dc = DEVICE_CLASS(oc); - - acc->parent_realize = dc->realize; - dc->realize = arm_cpu_realizefn; - dc->props = arm_cpu_properties; - - acc->parent_reset = cc->reset; - cc->reset = arm_cpu_reset; - - cc->class_by_name = arm_cpu_class_by_name; - cc->has_work = arm_cpu_has_work; - cc->cpu_exec_interrupt = arm_cpu_exec_interrupt; - cc->dump_state = arm_cpu_dump_state; - cc->set_pc = arm_cpu_set_pc; - cc->gdb_read_register = arm_cpu_gdb_read_register; - cc->gdb_write_register = arm_cpu_gdb_write_register; -#ifdef CONFIG_USER_ONLY - cc->handle_mmu_fault = arm_cpu_handle_mmu_fault; -#else - cc->do_interrupt = arm_cpu_do_interrupt; - cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; - cc->vmsd = &vmstate_arm_cpu; - cc->virtio_is_big_endian = arm_cpu_is_big_endian; -#endif - cc->gdb_num_core_regs = 26; - cc->gdb_core_xml_file = "arm-core.xml"; - cc->gdb_stop_before_watchpoint = true; - cc->debug_excp_handler = arm_debug_excp_handler; - - cc->disas_set_info = arm_disas_set_info; - - /* - * Reason: arm_cpu_initfn() calls cpu_exec_init(), which saves - * the object in cpus -> dangling pointer after final - * object_unref(). - * - * Once this is fixed, the devices that create ARM CPUs should be - * updated not to set cannot_destroy_with_object_finalize_yet, - * unless they still screw up something else. - */ - dc->cannot_destroy_with_object_finalize_yet = true; -} - -static void cpu_register(const ARMCPUInfo *info) -{ - TypeInfo type_info = { - .parent = TYPE_ARM_CPU, - .instance_size = sizeof(ARMCPU), - .instance_init = info->initfn, - .class_size = sizeof(ARMCPUClass), - .class_init = info->class_init, - }; - - type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name); - type_register(&type_info); - g_free((void *)type_info.name); -} - -static const TypeInfo arm_cpu_type_info = { - .name = TYPE_ARM_CPU, - .parent = TYPE_CPU, - .instance_size = sizeof(ARMCPU), - .instance_init = arm_cpu_initfn, - .instance_post_init = arm_cpu_post_init, - .instance_finalize = arm_cpu_finalizefn, - .abstract = true, - .class_size = sizeof(ARMCPUClass), - .class_init = arm_cpu_class_init, -}; - -static void arm_cpu_register_types(void) -{ - const ARMCPUInfo *info = arm_cpus; - - type_register_static(&arm_cpu_type_info); - - while (info->name) { - cpu_register(info); - info++; - } -} - -type_init(arm_cpu_register_types) diff --git a/target-arm/cpu.h b/target-arm/cpu.h deleted file mode 100644 index ff9b81c5328df..0000000000000 --- a/target-arm/cpu.h +++ /dev/null @@ -1,2060 +0,0 @@ -/* - * ARM virtual CPU header - * - * Copyright (c) 2003 Fabrice Bellard - * - * 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 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 . - */ -#ifndef CPU_ARM_H -#define CPU_ARM_H - -#include "config.h" - -#include "kvm-consts.h" - -#if defined(TARGET_AARCH64) - /* AArch64 definitions */ -# define TARGET_LONG_BITS 64 -#else -# define TARGET_LONG_BITS 32 -#endif - -#define TARGET_IS_BIENDIAN 1 - -#define CPUArchState struct CPUARMState - -#include "qemu-common.h" -#include "exec/cpu-defs.h" - -#include "fpu/softfloat.h" - -#define EXCP_UDEF 1 /* undefined instruction */ -#define EXCP_SWI 2 /* software interrupt */ -#define EXCP_PREFETCH_ABORT 3 -#define EXCP_DATA_ABORT 4 -#define EXCP_IRQ 5 -#define EXCP_FIQ 6 -#define EXCP_BKPT 7 -#define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */ -#define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */ -#define EXCP_STREX 10 -#define EXCP_HVC 11 /* HyperVisor Call */ -#define EXCP_HYP_TRAP 12 -#define EXCP_SMC 13 /* Secure Monitor Call */ -#define EXCP_VIRQ 14 -#define EXCP_VFIQ 15 -#define EXCP_WKUP 16 /* Wakeup from standby mode */ -#define EXCP_SEMIHOST 17 /* semihosting call (A64 only) */ - -#define ARMV7M_EXCP_RESET 1 -#define ARMV7M_EXCP_NMI 2 -#define ARMV7M_EXCP_HARD 3 -#define ARMV7M_EXCP_MEM 4 -#define ARMV7M_EXCP_BUS 5 -#define ARMV7M_EXCP_USAGE 6 -#define ARMV7M_EXCP_SVC 11 -#define ARMV7M_EXCP_DEBUG 12 -#define ARMV7M_EXCP_PENDSV 14 -#define ARMV7M_EXCP_SYSTICK 15 - -/* ARM-specific interrupt pending bits. */ -#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1 -#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2 -#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3 -#define CPU_INTERRUPT_WKUP CPU_INTERRUPT_TGT_EXT_4 /* Wake up without any interrupt */ - - -/* The usual mapping for an AArch64 system register to its AArch32 - * counterpart is for the 32 bit world to have access to the lower - * half only (with writes leaving the upper half untouched). It's - * therefore useful to be able to pass TCG the offset of the least - * significant half of a uint64_t struct member. - */ -#ifdef HOST_WORDS_BIGENDIAN -#define offsetoflow32(S, M) (offsetof(S, M) + sizeof(uint32_t)) -#define offsetofhigh32(S, M) offsetof(S, M) -#else -#define offsetoflow32(S, M) offsetof(S, M) -#define offsetofhigh32(S, M) (offsetof(S, M) + sizeof(uint32_t)) -#endif - -/* Meanings of the ARMCPU object's five inbound GPIO lines */ -#define ARM_CPU_IRQ 0 -#define ARM_CPU_FIQ 1 -#define ARM_CPU_VIRQ 2 -#define ARM_CPU_VFIQ 3 -#define ARM_CPU_WKUP 4 - -struct arm_boot_info; - -#define NB_MMU_MODES 7 -#define TARGET_INSN_START_EXTRA_WORDS 1 - -/* We currently assume float and double are IEEE single and double - precision respectively. - Doing runtime conversions is tricky because VFP registers may contain - integer values (eg. as the result of a FTOSI instruction). - s<2n> maps to the least significant half of d - s<2n+1> maps to the most significant half of d - */ - -/* CPU state for each instance of a generic timer (in cp15 c14) */ -typedef struct ARMGenericTimer { - uint64_t cval; /* Timer CompareValue register */ - uint64_t ctl; /* Timer Control register */ -} ARMGenericTimer; - -#define GTIMER_PHYS 0 -#define GTIMER_VIRT 1 -#define GTIMER_HYP 2 -#define GTIMER_SEC 3 -#define NUM_GTIMERS 4 - -typedef struct { - uint64_t raw_tcr; - uint32_t mask; - uint32_t base_mask; -} TCR; - -typedef struct CPUARMState { - /* Regs for current mode. */ - uint32_t regs[16]; - - /* 32/64 switch only happens when taking and returning from - * exceptions so the overlap semantics are taken care of then - * instead of having a complicated union. - */ - /* Regs for A64 mode. */ - uint64_t xregs[32]; - uint64_t pc; - /* PSTATE isn't an architectural register for ARMv8. However, it is - * convenient for us to assemble the underlying state into a 32 bit format - * identical to the architectural format used for the SPSR. (This is also - * what the Linux kernel's 'pstate' field in signal handlers and KVM's - * 'pstate' register are.) Of the PSTATE bits: - * NZCV are kept in the split out env->CF/VF/NF/ZF, (which have the same - * semantics as for AArch32, as described in the comments on each field) - * nRW (also known as M[4]) is kept, inverted, in env->aarch64 - * DAIF (exception masks) are kept in env->daif - * all other bits are stored in their correct places in env->pstate - */ - uint32_t pstate; - uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */ - - /* Frequently accessed CPSR bits are stored separately for efficiency. - This contains all the other bits. Use cpsr_{read,write} to access - the whole CPSR. */ - uint32_t uncached_cpsr; - uint32_t spsr; - - /* Banked registers. */ - uint64_t banked_spsr[8]; - uint32_t banked_r13[8]; - uint32_t banked_r14[8]; - - /* These hold r8-r12. */ - uint32_t usr_regs[5]; - uint32_t fiq_regs[5]; - - /* cpsr flag cache for faster execution */ - uint32_t CF; /* 0 or 1 */ - uint32_t VF; /* V is the bit 31. All other bits are undefined */ - uint32_t NF; /* N is bit 31. All other bits are undefined. */ - uint32_t ZF; /* Z set if zero. */ - uint32_t QF; /* 0 or 1 */ - uint32_t GE; /* cpsr[19:16] */ - uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */ - uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */ - uint64_t daif; /* exception masks, in the bits they are in PSTATE */ - - uint64_t elr_el[4]; /* AArch64 exception link regs */ - uint64_t sp_el[4]; /* AArch64 banked stack pointers */ - - /* System control coprocessor (cp15) */ - struct { - uint32_t c0_cpuid; - union { /* Cache size selection */ - struct { - uint64_t _unused_csselr0; - uint64_t csselr_ns; - uint64_t _unused_csselr1; - uint64_t csselr_s; - }; - uint64_t csselr_el[4]; - }; - union { /* System control register. */ - struct { - uint64_t _unused_sctlr; - uint64_t sctlr_ns; - uint64_t hsctlr; - uint64_t sctlr_s; - }; - uint64_t sctlr_el[4]; - }; - uint64_t cpacr_el1; /* Architectural feature access control register */ - uint64_t cptr_el[4]; /* ARMv8 feature trap registers */ - uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */ - uint64_t sder; /* Secure debug enable register. */ - uint32_t nsacr; /* Non-secure access control register. */ - union { /* MMU translation table base 0. */ - struct { - uint64_t _unused_ttbr0_0; - uint64_t ttbr0_ns; - uint64_t _unused_ttbr0_1; - uint64_t ttbr0_s; - }; - uint64_t ttbr0_el[4]; - }; - union { /* MMU translation table base 1. */ - struct { - uint64_t _unused_ttbr1_0; - uint64_t ttbr1_ns; - uint64_t _unused_ttbr1_1; - uint64_t ttbr1_s; - }; - uint64_t ttbr1_el[4]; - }; - uint64_t vttbr_el2; /* Virtualization Translation Table Base. */ - /* MMU translation table base control. */ - TCR tcr_el[4]; - TCR vtcr_el2; /* Virtualization Translation Control. */ - uint32_t c2_data; /* MPU data cacheable bits. */ - uint32_t c2_insn; /* MPU instruction cacheable bits. */ - union { /* MMU domain access control register - * MPU write buffer control. - */ - struct { - uint64_t dacr_ns; - uint64_t dacr_s; - }; - struct { - uint64_t dacr32_el2; - }; - }; - uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */ - uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */ - uint64_t hcr_el2; /* Hypervisor configuration register */ - uint64_t scr_el3; /* Secure configuration register. */ - union { /* Fault status registers. */ - struct { - uint64_t ifsr_ns; - uint64_t ifsr_s; - }; - struct { - uint64_t ifsr32_el2; - }; - }; - union { - struct { - uint64_t _unused_dfsr; - uint64_t dfsr_ns; - uint64_t hsr; - uint64_t dfsr_s; - }; - uint64_t esr_el[4]; - }; - uint32_t c6_region[8]; /* MPU base/size registers. */ - union { /* Fault address registers. */ - struct { - uint64_t _unused_far0; -#ifdef HOST_WORDS_BIGENDIAN - uint32_t ifar_ns; - uint32_t dfar_ns; - uint32_t ifar_s; - uint32_t dfar_s; -#else - uint32_t dfar_ns; - uint32_t ifar_ns; - uint32_t dfar_s; - uint32_t ifar_s; -#endif - uint64_t _unused_far3; - }; - uint64_t far_el[4]; - }; - uint64_t hpfar_el2; - union { /* Translation result. */ - struct { - uint64_t _unused_par_0; - uint64_t par_ns; - uint64_t _unused_par_1; - uint64_t par_s; - }; - uint64_t par_el[4]; - }; - - uint32_t c6_rgnr; - - uint32_t c9_insn; /* Cache lockdown registers. */ - uint32_t c9_data; - uint64_t c9_pmcr; /* performance monitor control register */ - uint64_t c9_pmcnten; /* perf monitor counter enables */ - uint32_t c9_pmovsr; /* perf monitor overflow status */ - uint32_t c9_pmxevtyper; /* perf monitor event type */ - uint32_t c9_pmuserenr; /* perf monitor user enable */ - uint32_t c9_pminten; /* perf monitor interrupt enables */ - union { /* Memory attribute redirection */ - struct { -#ifdef HOST_WORDS_BIGENDIAN - uint64_t _unused_mair_0; - uint32_t mair1_ns; - uint32_t mair0_ns; - uint64_t _unused_mair_1; - uint32_t mair1_s; - uint32_t mair0_s; -#else - uint64_t _unused_mair_0; - uint32_t mair0_ns; - uint32_t mair1_ns; - uint64_t _unused_mair_1; - uint32_t mair0_s; - uint32_t mair1_s; -#endif - }; - uint64_t mair_el[4]; - }; - union { /* vector base address register */ - struct { - uint64_t _unused_vbar; - uint64_t vbar_ns; - uint64_t hvbar; - uint64_t vbar_s; - }; - uint64_t vbar_el[4]; - }; - uint32_t mvbar; /* (monitor) vector base address register */ - struct { /* FCSE PID. */ - uint32_t fcseidr_ns; - uint32_t fcseidr_s; - }; - union { /* Context ID. */ - struct { - uint64_t _unused_contextidr_0; - uint64_t contextidr_ns; - uint64_t _unused_contextidr_1; - uint64_t contextidr_s; - }; - uint64_t contextidr_el[4]; - }; - union { /* User RW Thread register. */ - struct { - uint64_t tpidrurw_ns; - uint64_t tpidrprw_ns; - uint64_t htpidr; - uint64_t _tpidr_el3; - }; - uint64_t tpidr_el[4]; - }; - /* The secure banks of these registers don't map anywhere */ - uint64_t tpidrurw_s; - uint64_t tpidrprw_s; - uint64_t tpidruro_s; - - union { /* User RO Thread register. */ - uint64_t tpidruro_ns; - uint64_t tpidrro_el[1]; - }; - uint64_t c14_cntfrq; /* Counter Frequency register */ - uint64_t c14_cntkctl; /* Timer Control register */ - uint32_t cnthctl_el2; /* Counter/Timer Hyp Control register */ - uint64_t cntvoff_el2; /* Counter Virtual Offset register */ - ARMGenericTimer c14_timer[NUM_GTIMERS]; - uint32_t c15_cpar; /* XScale Coprocessor Access Register */ - uint32_t c15_ticonfig; /* TI925T configuration byte. */ - uint32_t c15_i_max; /* Maximum D-cache dirty line index. */ - uint32_t c15_i_min; /* Minimum D-cache dirty line index. */ - uint32_t c15_threadid; /* TI debugger thread-ID. */ - uint32_t c15_config_base_address; /* SCU base address. */ - uint32_t c15_diagnostic; /* diagnostic register */ - uint32_t c15_power_diagnostic; - uint32_t c15_power_control; /* power control */ - uint64_t dbgbvr[16]; /* breakpoint value registers */ - uint64_t dbgbcr[16]; /* breakpoint control registers */ - uint64_t dbgwvr[16]; /* watchpoint value registers */ - uint64_t dbgwcr[16]; /* watchpoint control registers */ - uint64_t mdscr_el1; - uint64_t oslsr_el1; /* OS Lock Status */ - uint64_t mdcr_el2; - /* If the counter is enabled, this stores the last time the counter - * was reset. Otherwise it stores the counter value - */ - uint64_t c15_ccnt; - uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ - uint64_t vpidr_el2; /* Virtualization Processor ID Register */ - uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ - } cp15; - - struct { - uint32_t other_sp; - uint32_t vecbase; - uint32_t basepri; - uint32_t control; - int current_sp; - int exception; - uint32_t ccr; - uint32_t cfsr; - uint32_t hfsr; - uint32_t dfsr; - uint32_t mmfar; - uint32_t bfar; - uint32_t mpu_ctrl; - } v7m; - - /* Information associated with an exception about to be taken: - * code which raises an exception must set cs->exception_index and - * the relevant parts of this structure; the cpu_do_interrupt function - * will then set the guest-visible registers as part of the exception - * entry process. - */ - struct { - uint32_t syndrome; /* AArch64 format syndrome register */ - uint32_t fsr; /* AArch32 format fault status register info */ - uint64_t vaddress; /* virtual addr associated with exception, if any */ - uint32_t target_el; /* EL the exception should be targeted for */ - /* If we implement EL2 we will also need to store information - * about the intermediate physical address for stage 2 faults. - */ - } exception; - - /* Thumb-2 EE state. */ - uint32_t teecr; - uint32_t teehbr; - - /* VFP coprocessor state. */ - struct { - /* VFP/Neon register state. Note that the mapping between S, D and Q - * views of the register bank differs between AArch64 and AArch32: - * In AArch32: - * Qn = regs[2n+1]:regs[2n] - * Dn = regs[n] - * Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n - * (and regs[32] to regs[63] are inaccessible) - * In AArch64: - * Qn = regs[2n+1]:regs[2n] - * Dn = regs[2n] - * Sn = regs[2n] bits 31..0 - * This corresponds to the architecturally defined mapping between - * the two execution states, and means we do not need to explicitly - * map these registers when changing states. - */ - float64 regs[64]; - - uint32_t xregs[16]; - /* We store these fpcsr fields separately for convenience. */ - int vec_len; - int vec_stride; - - /* scratch space when Tn are not sufficient. */ - uint32_t scratch[8]; - - /* fp_status is the "normal" fp status. standard_fp_status retains - * values corresponding to the ARM "Standard FPSCR Value", ie - * default-NaN, flush-to-zero, round-to-nearest and is used by - * any operations (generally Neon) which the architecture defines - * as controlled by the standard FPSCR value rather than the FPSCR. - * - * To avoid having to transfer exception bits around, we simply - * say that the FPSCR cumulative exception flags are the logical - * OR of the flags in the two fp statuses. This relies on the - * only thing which needs to read the exception flags being - * an explicit FPSCR read. - */ - float_status fp_status; - float_status standard_fp_status; - } vfp; - uint64_t exclusive_addr; - uint64_t exclusive_val; - uint64_t exclusive_high; -#if defined(CONFIG_USER_ONLY) - uint64_t exclusive_test; - uint32_t exclusive_info; -#endif - - /* iwMMXt coprocessor state. */ - struct { - uint64_t regs[16]; - uint64_t val; - - uint32_t cregs[16]; - } iwmmxt; - - /* For mixed endian mode. */ - bool bswap_code; - -#if defined(CONFIG_USER_ONLY) - /* For usermode syscall translation. */ - int eabi; -#endif - - struct CPUBreakpoint *cpu_breakpoint[16]; - struct CPUWatchpoint *cpu_watchpoint[16]; - - CPU_COMMON - - /* These fields after the common ones so they are preserved on reset. */ - - /* Internal CPU feature flags. */ - uint64_t features; - - /* PMSAv7 MPU */ - struct { - uint32_t *drbar; - uint32_t *drsr; - uint32_t *dracr; - } pmsav7; - - void *nvic; - const struct arm_boot_info *boot_info; -} CPUARMState; - -#include "cpu-qom.h" - -ARMCPU *cpu_arm_init(const char *cpu_model); -int cpu_arm_exec(CPUState *cpu); -target_ulong do_arm_semihosting(CPUARMState *env); -void aarch64_sync_32_to_64(CPUARMState *env); -void aarch64_sync_64_to_32(CPUARMState *env); - -static inline bool is_a64(CPUARMState *env) -{ - return env->aarch64; -} - -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_arm_signal_handler(int host_signum, void *pinfo, - void *puc); - -/** - * pmccntr_sync - * @env: CPUARMState - * - * Synchronises the counter in the PMCCNTR. This must always be called twice, - * once before any action that might affect the timer and again afterwards. - * The function is used to swap the state of the register if required. - * This only happens when not in user mode (!CONFIG_USER_ONLY) - */ -void pmccntr_sync(CPUARMState *env); - -/* SCTLR bit meanings. Several bits have been reused in newer - * versions of the architecture; in that case we define constants - * for both old and new bit meanings. Code which tests against those - * bits should probably check or otherwise arrange that the CPU - * is the architectural version it expects. - */ -#define SCTLR_M (1U << 0) -#define SCTLR_A (1U << 1) -#define SCTLR_C (1U << 2) -#define SCTLR_W (1U << 3) /* up to v6; RAO in v7 */ -#define SCTLR_SA (1U << 3) -#define SCTLR_P (1U << 4) /* up to v5; RAO in v6 and v7 */ -#define SCTLR_SA0 (1U << 4) /* v8 onward, AArch64 only */ -#define SCTLR_D (1U << 5) /* up to v5; RAO in v6 */ -#define SCTLR_CP15BEN (1U << 5) /* v7 onward */ -#define SCTLR_L (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */ -#define SCTLR_B (1U << 7) /* up to v6; RAZ in v7 */ -#define SCTLR_ITD (1U << 7) /* v8 onward */ -#define SCTLR_S (1U << 8) /* up to v6; RAZ in v7 */ -#define SCTLR_SED (1U << 8) /* v8 onward */ -#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */ -#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */ -#define SCTLR_F (1U << 10) /* up to v6 */ -#define SCTLR_SW (1U << 10) /* v7 onward */ -#define SCTLR_Z (1U << 11) -#define SCTLR_I (1U << 12) -#define SCTLR_V (1U << 13) -#define SCTLR_RR (1U << 14) /* up to v7 */ -#define SCTLR_DZE (1U << 14) /* v8 onward, AArch64 only */ -#define SCTLR_L4 (1U << 15) /* up to v6; RAZ in v7 */ -#define SCTLR_UCT (1U << 15) /* v8 onward, AArch64 only */ -#define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */ -#define SCTLR_nTWI (1U << 16) /* v8 onward */ -#define SCTLR_HA (1U << 17) -#define SCTLR_BR (1U << 17) /* PMSA only */ -#define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */ -#define SCTLR_nTWE (1U << 18) /* v8 onward */ -#define SCTLR_WXN (1U << 19) -#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */ -#define SCTLR_UWXN (1U << 20) /* v7 onward */ -#define SCTLR_FI (1U << 21) -#define SCTLR_U (1U << 22) -#define SCTLR_XP (1U << 23) /* up to v6; v7 onward RAO */ -#define SCTLR_VE (1U << 24) /* up to v7 */ -#define SCTLR_E0E (1U << 24) /* v8 onward, AArch64 only */ -#define SCTLR_EE (1U << 25) -#define SCTLR_L2 (1U << 26) /* up to v6, RAZ in v7 */ -#define SCTLR_UCI (1U << 26) /* v8 onward, AArch64 only */ -#define SCTLR_NMFI (1U << 27) -#define SCTLR_TRE (1U << 28) -#define SCTLR_AFE (1U << 29) -#define SCTLR_TE (1U << 30) - -#define CPTR_TCPAC (1U << 31) -#define CPTR_TTA (1U << 20) -#define CPTR_TFP (1U << 10) - -#define CPSR_M (0x1fU) -#define CPSR_T (1U << 5) -#define CPSR_F (1U << 6) -#define CPSR_I (1U << 7) -#define CPSR_A (1U << 8) -#define CPSR_E (1U << 9) -#define CPSR_IT_2_7 (0xfc00U) -#define CPSR_GE (0xfU << 16) -#define CPSR_IL (1U << 20) -/* Note that the RESERVED bits include bit 21, which is PSTATE_SS in - * an AArch64 SPSR but RES0 in AArch32 SPSR and CPSR. In QEMU we use - * env->uncached_cpsr bit 21 to store PSTATE.SS when executing in AArch32, - * where it is live state but not accessible to the AArch32 code. - */ -#define CPSR_RESERVED (0x7U << 21) -#define CPSR_J (1U << 24) -#define CPSR_IT_0_1 (3U << 25) -#define CPSR_Q (1U << 27) -#define CPSR_V (1U << 28) -#define CPSR_C (1U << 29) -#define CPSR_Z (1U << 30) -#define CPSR_N (1U << 31) -#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) -#define CPSR_AIF (CPSR_A | CPSR_I | CPSR_F) - -#define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7) -#define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | CPSR_Q \ - | CPSR_NZCV) -/* Bits writable in user mode. */ -#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE) -/* Execution state bits. MRS read as zero, MSR writes ignored. */ -#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL) -/* Mask of bits which may be set by exception return copying them from SPSR */ -#define CPSR_ERET_MASK (~CPSR_RESERVED) - -#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */ -#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */ -#define TTBCR_PD0 (1U << 4) -#define TTBCR_PD1 (1U << 5) -#define TTBCR_EPD0 (1U << 7) -#define TTBCR_IRGN0 (3U << 8) -#define TTBCR_ORGN0 (3U << 10) -#define TTBCR_SH0 (3U << 12) -#define TTBCR_T1SZ (3U << 16) -#define TTBCR_A1 (1U << 22) -#define TTBCR_EPD1 (1U << 23) -#define TTBCR_IRGN1 (3U << 24) -#define TTBCR_ORGN1 (3U << 26) -#define TTBCR_SH1 (1U << 28) -#define TTBCR_EAE (1U << 31) - -/* Bit definitions for ARMv8 SPSR (PSTATE) format. - * Only these are valid when in AArch64 mode; in - * AArch32 mode SPSRs are basically CPSR-format. - */ -#define PSTATE_SP (1U) -#define PSTATE_M (0xFU) -#define PSTATE_nRW (1U << 4) -#define PSTATE_F (1U << 6) -#define PSTATE_I (1U << 7) -#define PSTATE_A (1U << 8) -#define PSTATE_D (1U << 9) -#define PSTATE_IL (1U << 20) -#define PSTATE_SS (1U << 21) -#define PSTATE_V (1U << 28) -#define PSTATE_C (1U << 29) -#define PSTATE_Z (1U << 30) -#define PSTATE_N (1U << 31) -#define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V) -#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F) -#define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF) -/* Mode values for AArch64 */ -#define PSTATE_MODE_EL3h 13 -#define PSTATE_MODE_EL3t 12 -#define PSTATE_MODE_EL2h 9 -#define PSTATE_MODE_EL2t 8 -#define PSTATE_MODE_EL1h 5 -#define PSTATE_MODE_EL1t 4 -#define PSTATE_MODE_EL0t 0 - -/* Map EL and handler into a PSTATE_MODE. */ -static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handler) -{ - return (el << 2) | handler; -} - -/* Return the current PSTATE value. For the moment we don't support 32<->64 bit - * interprocessing, so we don't attempt to sync with the cpsr state used by - * the 32 bit decoder. - */ -static inline uint32_t pstate_read(CPUARMState *env) -{ - int ZF; - - ZF = (env->ZF == 0); - return (env->NF & 0x80000000) | (ZF << 30) - | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) - | env->pstate | env->daif; -} - -static inline void pstate_write(CPUARMState *env, uint32_t val) -{ - env->ZF = (~val) & PSTATE_Z; - env->NF = val; - env->CF = (val >> 29) & 1; - env->VF = (val << 3) & 0x80000000; - env->daif = val & PSTATE_DAIF; - env->pstate = val & ~CACHED_PSTATE_BITS; -} - -/* Return the current CPSR value. */ -uint32_t cpsr_read(CPUARMState *env); -/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */ -void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask); - -/* Return the current xPSR value. */ -static inline uint32_t xpsr_read(CPUARMState *env) -{ - int ZF; - ZF = (env->ZF == 0); - return (env->NF & 0x80000000) | (ZF << 30) - | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) - | (env->thumb << 24) | ((env->condexec_bits & 3) << 25) - | ((env->condexec_bits & 0xfc) << 8) - | env->v7m.exception; -} - -/* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */ -static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) -{ - if (mask & CPSR_NZCV) { - env->ZF = (~val) & CPSR_Z; - env->NF = val; - env->CF = (val >> 29) & 1; - env->VF = (val << 3) & 0x80000000; - } - if (mask & CPSR_Q) - env->QF = ((val & CPSR_Q) != 0); - if (mask & (1 << 24)) - env->thumb = ((val & (1 << 24)) != 0); - if (mask & CPSR_IT_0_1) { - env->condexec_bits &= ~3; - env->condexec_bits |= (val >> 25) & 3; - } - if (mask & CPSR_IT_2_7) { - env->condexec_bits &= 3; - env->condexec_bits |= (val >> 8) & 0xfc; - } - if (mask & 0x1ff) { - env->v7m.exception = val & 0x1ff; - } -} - -#define HCR_VM (1ULL << 0) -#define HCR_SWIO (1ULL << 1) -#define HCR_PTW (1ULL << 2) -#define HCR_FMO (1ULL << 3) -#define HCR_IMO (1ULL << 4) -#define HCR_AMO (1ULL << 5) -#define HCR_VF (1ULL << 6) -#define HCR_VI (1ULL << 7) -#define HCR_VSE (1ULL << 8) -#define HCR_FB (1ULL << 9) -#define HCR_BSU_MASK (3ULL << 10) -#define HCR_DC (1ULL << 12) -#define HCR_TWI (1ULL << 13) -#define HCR_TWE (1ULL << 14) -#define HCR_TID0 (1ULL << 15) -#define HCR_TID1 (1ULL << 16) -#define HCR_TID2 (1ULL << 17) -#define HCR_TID3 (1ULL << 18) -#define HCR_TSC (1ULL << 19) -#define HCR_TIDCP (1ULL << 20) -#define HCR_TACR (1ULL << 21) -#define HCR_TSW (1ULL << 22) -#define HCR_TPC (1ULL << 23) -#define HCR_TPU (1ULL << 24) -#define HCR_TTLB (1ULL << 25) -#define HCR_TVM (1ULL << 26) -#define HCR_TGE (1ULL << 27) -#define HCR_TDZ (1ULL << 28) -#define HCR_HCD (1ULL << 29) -#define HCR_TRVM (1ULL << 30) -#define HCR_RW (1ULL << 31) -#define HCR_CD (1ULL << 32) -#define HCR_ID (1ULL << 33) -#define HCR_MASK ((1ULL << 34) - 1) - -#define SCR_NS (1U << 0) -#define SCR_IRQ (1U << 1) -#define SCR_FIQ (1U << 2) -#define SCR_EA (1U << 3) -#define SCR_FW (1U << 4) -#define SCR_AW (1U << 5) -#define SCR_NET (1U << 6) -#define SCR_SMD (1U << 7) -#define SCR_HCE (1U << 8) -#define SCR_SIF (1U << 9) -#define SCR_RW (1U << 10) -#define SCR_ST (1U << 11) -#define SCR_TWI (1U << 12) -#define SCR_TWE (1U << 13) -#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST)) -#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET) - -/* Return the current FPSCR value. */ -uint32_t vfp_get_fpscr(CPUARMState *env); -void vfp_set_fpscr(CPUARMState *env, uint32_t val); - -/* For A64 the FPSCR is split into two logically distinct registers, - * FPCR and FPSR. However since they still use non-overlapping bits - * we store the underlying state in fpscr and just mask on read/write. - */ -#define FPSR_MASK 0xf800009f -#define FPCR_MASK 0x07f79f00 -static inline uint32_t vfp_get_fpsr(CPUARMState *env) -{ - return vfp_get_fpscr(env) & FPSR_MASK; -} - -static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val) -{ - uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val & FPSR_MASK); - vfp_set_fpscr(env, new_fpscr); -} - -static inline uint32_t vfp_get_fpcr(CPUARMState *env) -{ - return vfp_get_fpscr(env) & FPCR_MASK; -} - -static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val) -{ - uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val & FPCR_MASK); - vfp_set_fpscr(env, new_fpscr); -} - -enum arm_cpu_mode { - ARM_CPU_MODE_USR = 0x10, - ARM_CPU_MODE_FIQ = 0x11, - ARM_CPU_MODE_IRQ = 0x12, - ARM_CPU_MODE_SVC = 0x13, - ARM_CPU_MODE_MON = 0x16, - ARM_CPU_MODE_ABT = 0x17, - ARM_CPU_MODE_HYP = 0x1a, - ARM_CPU_MODE_UND = 0x1b, - ARM_CPU_MODE_SYS = 0x1f -}; - -/* VFP system registers. */ -#define ARM_VFP_FPSID 0 -#define ARM_VFP_FPSCR 1 -#define ARM_VFP_MVFR2 5 -#define ARM_VFP_MVFR1 6 -#define ARM_VFP_MVFR0 7 -#define ARM_VFP_FPEXC 8 -#define ARM_VFP_FPINST 9 -#define ARM_VFP_FPINST2 10 - -/* iwMMXt coprocessor control registers. */ -#define ARM_IWMMXT_wCID 0 -#define ARM_IWMMXT_wCon 1 -#define ARM_IWMMXT_wCSSF 2 -#define ARM_IWMMXT_wCASF 3 -#define ARM_IWMMXT_wCGR0 8 -#define ARM_IWMMXT_wCGR1 9 -#define ARM_IWMMXT_wCGR2 10 -#define ARM_IWMMXT_wCGR3 11 - -/* V7M CCSR bits */ -#define CCR_STKALIGN 0x00000200 -#define CCR_BFHFNMIGN 0x00000100 -#define CCR_DIV_0_TRP 0x00000010 -#define CCR_UNALIGN_TRP 0x00000008 -#define CCR_USERSETMPEND 0x00000002 -#define CCR_NONBASETHRDENA 0x00000001 - -/* V7M CFSR bits for UFSR */ -#define CFSR_DIVBYZERO 0x02000000 -#define CFSR_UNALIGNED 0x01000000 -#define CFSR_NOCP 0x00080000 -#define CFSR_INVPC 0x00040000 -#define CFSR_INVSTATE 0x00020000 -#define CFSR_UNDEFINSTR 0x00010000 - -/* V7M CFSR bits for BFSR */ -#define CFSR_BFARVALID 0x00008000 -#define CFSR_LSPERR 0x00002000 -#define CFSR_STKERR 0x00001000 -#define CFSR_UNSTKERR 0x00000800 -#define CFSR_IMPRECISERR 0x00000400 -#define CFSR_PRECISERR 0x00000200 -#define CFSR_IBUSERR 0x00000100 - -/* V7M CFSR bits for MMFSR */ -#define CFSR_MMARVALID 0x00000080 -#define CFSR_MLSPERR 0x00000020 -#define CFSR_MSTKERR 0x00000010 -#define CFSR_MUNSTKERR 0x00000008 -#define CFSR_DACCVIOL 0x00000002 -#define CFSR_IACCVIOL 0x00000001 - -/* V7M HFSR bits */ -#define HFSR_DEBUG_VT 0x80000000 -#define HFSR_FORCED 0x40000000 -#define HFSR_VECTTBL 0x00000002 - -/* V7M DFSR bits */ -#define DFSR_EXTERNAL 0x00000010 -#define DFSR_VCATCH 0x00000008 -#define DFSR_DWTTRAP 0x00000004 -#define DFSR_BKPT 0x00000002 -#define DFSR_HALTED 0x00000001 - -/* V7M MPU_CTRL bits */ -#define MPU_CTRL_PRIVDEFENA 0x00000004 -#define MPU_CTRL_HFNMIENA 0x00000002 -#define MPU_CTRL_ENABLE 0x00000001 - -/* If adding a feature bit which corresponds to a Linux ELF - * HWCAP bit, remember to update the feature-bit-to-hwcap - * mapping in linux-user/elfload.c:get_elf_hwcap(). - */ -enum arm_features { - ARM_FEATURE_VFP, - ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */ - ARM_FEATURE_XSCALE, /* Intel XScale extensions. */ - ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */ - ARM_FEATURE_V6, - ARM_FEATURE_V6K, - ARM_FEATURE_V7, - ARM_FEATURE_THUMB2, - ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */ - ARM_FEATURE_VFP3, - ARM_FEATURE_VFP_FP16, - ARM_FEATURE_NEON, - ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */ - ARM_FEATURE_M, /* Microcontroller profile. */ - ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */ - ARM_FEATURE_THUMB2EE, - ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */ - ARM_FEATURE_V4T, - ARM_FEATURE_V5, - ARM_FEATURE_STRONGARM, - ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */ - ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */ - ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */ - ARM_FEATURE_GENERIC_TIMER, - ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */ - ARM_FEATURE_DUMMY_C15_REGS, /* RAZ/WI all of cp15 crn=15 */ - ARM_FEATURE_CACHE_TEST_CLEAN, /* 926/1026 style test-and-clean ops */ - ARM_FEATURE_CACHE_DIRTY_REG, /* 1136/1176 cache dirty status register */ - ARM_FEATURE_CACHE_BLOCK_OPS, /* v6 optional cache block operations */ - ARM_FEATURE_MPIDR, /* has cp15 MPIDR */ - ARM_FEATURE_PXN, /* has Privileged Execute Never bit */ - ARM_FEATURE_LPAE, /* has Large Physical Address Extension */ - ARM_FEATURE_V8, - ARM_FEATURE_AARCH64, /* supports 64 bit mode */ - ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */ - ARM_FEATURE_CBAR, /* has cp15 CBAR */ - ARM_FEATURE_CRC, /* ARMv8 CRC instructions */ - ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */ - ARM_FEATURE_EL2, /* has EL2 Virtualization support */ - ARM_FEATURE_EL3, /* has EL3 Secure monitor support */ - ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */ - ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */ - ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */ - ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */ -}; - -static inline int arm_feature(CPUARMState *env, int feature) -{ - return (env->features & (1ULL << feature)) != 0; -} - -#if !defined(CONFIG_USER_ONLY) -/* Return true if exception levels below EL3 are in secure state, - * or would be following an exception return to that level. - * Unlike arm_is_secure() (which is always a question about the - * _current_ state of the CPU) this doesn't care about the current - * EL or mode. - */ -static inline bool arm_is_secure_below_el3(CPUARMState *env) -{ - if (arm_feature(env, ARM_FEATURE_EL3)) { - return !(env->cp15.scr_el3 & SCR_NS); - } else { - /* If EL2 is not supported then the secure state is implementation - * defined, in which case QEMU defaults to non-secure. - */ - return false; - } -} - -/* Return true if the processor is in secure state */ -static inline bool arm_is_secure(CPUARMState *env) -{ - if (arm_feature(env, ARM_FEATURE_EL3)) { - if (is_a64(env) && extract32(env->pstate, 2, 2) == 3) { - /* CPU currently in AArch64 state and EL3 */ - return true; - } else if (!is_a64(env) && - (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) { - /* CPU currently in AArch32 state and monitor mode */ - return true; - } - } - return arm_is_secure_below_el3(env); -} - -#else -static inline bool arm_is_secure_below_el3(CPUARMState *env) -{ - return false; -} - -static inline bool arm_is_secure(CPUARMState *env) -{ - return false; -} -#endif - -/* Return true if the specified exception level is running in AArch64 state. */ -static inline bool arm_el_is_aa64(CPUARMState *env, int el) -{ - /* We don't currently support EL2, and this isn't valid for EL0 - * (if we're in EL0, is_a64() is what you want, and if we're not in EL0 - * then the state of EL0 isn't well defined.) - */ - assert(el == 1 || el == 3); - - /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This - * is a QEMU-imposed simplification which we may wish to change later. - * If we in future support EL2 and/or EL3, then the state of lower - * exception levels is controlled by the HCR.RW and SCR.RW bits. - */ - return arm_feature(env, ARM_FEATURE_AARCH64); -} - -/* Function for determing whether guest cp register reads and writes should - * access the secure or non-secure bank of a cp register. When EL3 is - * operating in AArch32 state, the NS-bit determines whether the secure - * instance of a cp register should be used. When EL3 is AArch64 (or if - * it doesn't exist at all) then there is no register banking, and all - * accesses are to the non-secure version. - */ -static inline bool access_secure_reg(CPUARMState *env) -{ - bool ret = (arm_feature(env, ARM_FEATURE_EL3) && - !arm_el_is_aa64(env, 3) && - !(env->cp15.scr_el3 & SCR_NS)); - - return ret; -} - -/* Macros for accessing a specified CP register bank */ -#define A32_BANKED_REG_GET(_env, _regname, _secure) \ - ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns) - -#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \ - do { \ - if (_secure) { \ - (_env)->cp15._regname##_s = (_val); \ - } else { \ - (_env)->cp15._regname##_ns = (_val); \ - } \ - } while (0) - -/* Macros for automatically accessing a specific CP register bank depending on - * the current secure state of the system. These macros are not intended for - * supporting instruction translation reads/writes as these are dependent - * solely on the SCR.NS bit and not the mode. - */ -#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \ - A32_BANKED_REG_GET((_env), _regname, \ - (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3))) - -#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \ - A32_BANKED_REG_SET((_env), _regname, \ - (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \ - (_val)) - -void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf); -uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, - uint32_t cur_el, bool secure); - -/* Interface between CPU and Interrupt controller. */ -void armv7m_nvic_set_pending(void *opaque, int irq); -int armv7m_nvic_acknowledge_irq(void *opaque); -void armv7m_nvic_complete_irq(void *opaque, int irq); -void armv7m_nvic_set_base_priority(void *opaque, unsigned int priority); -void armv7m_nvic_cpu_executed_wfi(void *opaque); - -/* Interface between interrupt controller and power controller */ -bool f2xx_pwr_powerdown_deepsleep(void *opaqe); - -/* Interface for defining coprocessor registers. - * Registers are defined in tables of arm_cp_reginfo structs - * which are passed to define_arm_cp_regs(). - */ - -/* When looking up a coprocessor register we look for it - * via an integer which encodes all of: - * coprocessor number - * Crn, Crm, opc1, opc2 fields - * 32 or 64 bit register (ie is it accessed via MRC/MCR - * or via MRRC/MCRR?) - * non-secure/secure bank (AArch32 only) - * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field. - * (In this case crn and opc2 should be zero.) - * For AArch64, there is no 32/64 bit size distinction; - * instead all registers have a 2 bit op0, 3 bit op1 and op2, - * and 4 bit CRn and CRm. The encoding patterns are chosen - * to be easy to convert to and from the KVM encodings, and also - * so that the hashtable can contain both AArch32 and AArch64 - * registers (to allow for interprocessing where we might run - * 32 bit code on a 64 bit core). - */ -/* This bit is private to our hashtable cpreg; in KVM register - * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64 - * in the upper bits of the 64 bit ID. - */ -#define CP_REG_AA64_SHIFT 28 -#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT) - -/* To enable banking of coprocessor registers depending on ns-bit we - * add a bit to distinguish between secure and non-secure cpregs in the - * hashtable. - */ -#define CP_REG_NS_SHIFT 29 -#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT) - -#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \ - ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \ - ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2)) - -#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \ - (CP_REG_AA64_MASK | \ - ((cp) << CP_REG_ARM_COPROC_SHIFT) | \ - ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \ - ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \ - ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \ - ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \ - ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT)) - -/* Convert a full 64 bit KVM register ID to the truncated 32 bit - * version used as a key for the coprocessor register hashtable - */ -static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid) -{ - uint32_t cpregid = kvmid; - if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) { - cpregid |= CP_REG_AA64_MASK; - } else { - if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) { - cpregid |= (1 << 15); - } - - /* KVM is always non-secure so add the NS flag on AArch32 register - * entries. - */ - cpregid |= 1 << CP_REG_NS_SHIFT; - } - return cpregid; -} - -/* Convert a truncated 32 bit hashtable key into the full - * 64 bit KVM register ID. - */ -static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) -{ - uint64_t kvmid; - - if (cpregid & CP_REG_AA64_MASK) { - kvmid = cpregid & ~CP_REG_AA64_MASK; - kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64; - } else { - kvmid = cpregid & ~(1 << 15); - if (cpregid & (1 << 15)) { - kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM; - } else { - kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM; - } - } - return kvmid; -} - -/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a - * special-behaviour cp reg and bits [15..8] indicate what behaviour - * it has. Otherwise it is a simple cp reg, where CONST indicates that - * TCG can assume the value to be constant (ie load at translate time) - * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END - * indicates that the TB should not be ended after a write to this register - * (the default is that the TB ends after cp writes). OVERRIDE permits - * a register definition to override a previous definition for the - * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the - * old must have the OVERRIDE bit set. - * ALIAS indicates that this register is an alias view of some underlying - * state which is also visible via another register, and that the other - * register is handling migration and reset; registers marked ALIAS will not be - * migrated but may have their state set by syncing of register state from KVM. - * NO_RAW indicates that this register has no underlying state and does not - * support raw access for state saving/loading; it will not be used for either - * migration or KVM state synchronization. (Typically this is for "registers" - * which are actually used as instructions for cache maintenance and so on.) - * IO indicates that this register does I/O and therefore its accesses - * need to be surrounded by gen_io_start()/gen_io_end(). In particular, - * registers which implement clocks or timers require this. - */ -#define ARM_CP_SPECIAL 1 -#define ARM_CP_CONST 2 -#define ARM_CP_64BIT 4 -#define ARM_CP_SUPPRESS_TB_END 8 -#define ARM_CP_OVERRIDE 16 -#define ARM_CP_ALIAS 32 -#define ARM_CP_IO 64 -#define ARM_CP_NO_RAW 128 -#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8)) -#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8)) -#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8)) -#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8)) -#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8)) -#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA -/* Used only as a terminator for ARMCPRegInfo lists */ -#define ARM_CP_SENTINEL 0xffff -/* Mask of only the flag bits in a type field */ -#define ARM_CP_FLAG_MASK 0xff - -/* Valid values for ARMCPRegInfo state field, indicating which of - * the AArch32 and AArch64 execution states this register is visible in. - * If the reginfo doesn't explicitly specify then it is AArch32 only. - * If the reginfo is declared to be visible in both states then a second - * reginfo is synthesised for the AArch32 view of the AArch64 register, - * such that the AArch32 view is the lower 32 bits of the AArch64 one. - * Note that we rely on the values of these enums as we iterate through - * the various states in some places. - */ -enum { - ARM_CP_STATE_AA32 = 0, - ARM_CP_STATE_AA64 = 1, - ARM_CP_STATE_BOTH = 2, -}; - -/* ARM CP register secure state flags. These flags identify security state - * attributes for a given CP register entry. - * The existence of both or neither secure and non-secure flags indicates that - * the register has both a secure and non-secure hash entry. A single one of - * these flags causes the register to only be hashed for the specified - * security state. - * Although definitions may have any combination of the S/NS bits, each - * registered entry will only have one to identify whether the entry is secure - * or non-secure. - */ -enum { - ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */ - ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */ -}; - -/* Return true if cptype is a valid type field. This is used to try to - * catch errors where the sentinel has been accidentally left off the end - * of a list of registers. - */ -static inline bool cptype_valid(int cptype) -{ - return ((cptype & ~ARM_CP_FLAG_MASK) == 0) - || ((cptype & ARM_CP_SPECIAL) && - ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL)); -} - -/* Access rights: - * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM - * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and - * PL2 (hyp). The other level which has Read and Write bits is Secure PL1 - * (ie any of the privileged modes in Secure state, or Monitor mode). - * If a register is accessible in one privilege level it's always accessible - * in higher privilege levels too. Since "Secure PL1" also follows this rule - * (ie anything visible in PL2 is visible in S-PL1, some things are only - * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the - * terminology a little and call this PL3. - * In AArch64 things are somewhat simpler as the PLx bits line up exactly - * with the ELx exception levels. - * - * If access permissions for a register are more complex than can be - * described with these bits, then use a laxer set of restrictions, and - * do the more restrictive/complex check inside a helper function. - */ -#define PL3_R 0x80 -#define PL3_W 0x40 -#define PL2_R (0x20 | PL3_R) -#define PL2_W (0x10 | PL3_W) -#define PL1_R (0x08 | PL2_R) -#define PL1_W (0x04 | PL2_W) -#define PL0_R (0x02 | PL1_R) -#define PL0_W (0x01 | PL1_W) - -#define PL3_RW (PL3_R | PL3_W) -#define PL2_RW (PL2_R | PL2_W) -#define PL1_RW (PL1_R | PL1_W) -#define PL0_RW (PL0_R | PL0_W) - -/* Return the current Exception Level (as per ARMv8; note that this differs - * from the ARMv7 Privilege Level). - */ -static inline int arm_current_el(CPUARMState *env) -{ - if (arm_feature(env, ARM_FEATURE_M)) { - return !((env->v7m.exception == 0) && (env->v7m.control & 1)); - } - - if (is_a64(env)) { - return extract32(env->pstate, 2, 2); - } - - switch (env->uncached_cpsr & 0x1f) { - case ARM_CPU_MODE_USR: - return 0; - case ARM_CPU_MODE_HYP: - return 2; - case ARM_CPU_MODE_MON: - return 3; - default: - if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) { - /* If EL3 is 32-bit then all secure privileged modes run in - * EL3 - */ - return 3; - } - - return 1; - } -} - -typedef struct ARMCPRegInfo ARMCPRegInfo; - -typedef enum CPAccessResult { - /* Access is permitted */ - CP_ACCESS_OK = 0, - /* Access fails due to a configurable trap or enable which would - * result in a categorized exception syndrome giving information about - * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6, - * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or - * PL1 if in EL0, otherwise to the current EL). - */ - CP_ACCESS_TRAP = 1, - /* Access fails and results in an exception syndrome 0x0 ("uncategorized"). - * Note that this is not a catch-all case -- the set of cases which may - * result in this failure is specifically defined by the architecture. - */ - CP_ACCESS_TRAP_UNCATEGORIZED = 2, - /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */ - CP_ACCESS_TRAP_EL2 = 3, - CP_ACCESS_TRAP_EL3 = 4, - /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */ - CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5, - CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6, -} CPAccessResult; - -/* Access functions for coprocessor registers. These cannot fail and - * may not raise exceptions. - */ -typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque); -typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque, - uint64_t value); -/* Access permission check functions for coprocessor registers. */ -typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque); -/* Hook function for register reset */ -typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque); - -#define CP_ANY 0xff - -/* Definition of an ARM coprocessor register */ -struct ARMCPRegInfo { - /* Name of register (useful mainly for debugging, need not be unique) */ - const char *name; - /* Location of register: coprocessor number and (crn,crm,opc1,opc2) - * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a - * 'wildcard' field -- any value of that field in the MRC/MCR insn - * will be decoded to this register. The register read and write - * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2 - * used by the program, so it is possible to register a wildcard and - * then behave differently on read/write if necessary. - * For 64 bit registers, only crm and opc1 are relevant; crn and opc2 - * must both be zero. - * For AArch64-visible registers, opc0 is also used. - * Since there are no "coprocessors" in AArch64, cp is purely used as a - * way to distinguish (for KVM's benefit) guest-visible system registers - * from demuxed ones provided to preserve the "no side effects on - * KVM register read/write from QEMU" semantics. cp==0x13 is guest - * visible (to match KVM's encoding); cp==0 will be converted to - * cp==0x13 when the ARMCPRegInfo is registered, for convenience. - */ - uint8_t cp; - uint8_t crn; - uint8_t crm; - uint8_t opc0; - uint8_t opc1; - uint8_t opc2; - /* Execution state in which this register is visible: ARM_CP_STATE_* */ - int state; - /* Register type: ARM_CP_* bits/values */ - int type; - /* Access rights: PL*_[RW] */ - int access; - /* Security state: ARM_CP_SECSTATE_* bits/values */ - int secure; - /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when - * this register was defined: can be used to hand data through to the - * register read/write functions, since they are passed the ARMCPRegInfo*. - */ - void *opaque; - /* Value of this register, if it is ARM_CP_CONST. Otherwise, if - * fieldoffset is non-zero, the reset value of the register. - */ - uint64_t resetvalue; - /* Offset of the field in CPUARMState for this register. - * - * This is not needed if either: - * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs - * 2. both readfn and writefn are specified - */ - ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */ - - /* Offsets of the secure and non-secure fields in CPUARMState for the - * register if it is banked. These fields are only used during the static - * registration of a register. During hashing the bank associated - * with a given security state is copied to fieldoffset which is used from - * there on out. - * - * It is expected that register definitions use either fieldoffset or - * bank_fieldoffsets in the definition but not both. It is also expected - * that both bank offsets are set when defining a banked register. This - * use indicates that a register is banked. - */ - ptrdiff_t bank_fieldoffsets[2]; - - /* Function for making any access checks for this register in addition to - * those specified by the 'access' permissions bits. If NULL, no extra - * checks required. The access check is performed at runtime, not at - * translate time. - */ - CPAccessFn *accessfn; - /* Function for handling reads of this register. If NULL, then reads - * will be done by loading from the offset into CPUARMState specified - * by fieldoffset. - */ - CPReadFn *readfn; - /* Function for handling writes of this register. If NULL, then writes - * will be done by writing to the offset into CPUARMState specified - * by fieldoffset. - */ - CPWriteFn *writefn; - /* Function for doing a "raw" read; used when we need to copy - * coprocessor state to the kernel for KVM or out for - * migration. This only needs to be provided if there is also a - * readfn and it has side effects (for instance clear-on-read bits). - */ - CPReadFn *raw_readfn; - /* Function for doing a "raw" write; used when we need to copy KVM - * kernel coprocessor state into userspace, or for inbound - * migration. This only needs to be provided if there is also a - * writefn and it masks out "unwritable" bits or has write-one-to-clear - * or similar behaviour. - */ - CPWriteFn *raw_writefn; - /* Function for resetting the register. If NULL, then reset will be done - * by writing resetvalue to the field specified in fieldoffset. If - * fieldoffset is 0 then no reset will be done. - */ - CPResetFn *resetfn; -}; - -/* Macros which are lvalues for the field in CPUARMState for the - * ARMCPRegInfo *ri. - */ -#define CPREG_FIELD32(env, ri) \ - (*(uint32_t *)((char *)(env) + (ri)->fieldoffset)) -#define CPREG_FIELD64(env, ri) \ - (*(uint64_t *)((char *)(env) + (ri)->fieldoffset)) - -#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL } - -void define_arm_cp_regs_with_opaque(ARMCPU *cpu, - const ARMCPRegInfo *regs, void *opaque); -void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, - const ARMCPRegInfo *regs, void *opaque); -static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs) -{ - define_arm_cp_regs_with_opaque(cpu, regs, 0); -} -static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs) -{ - define_one_arm_cp_reg_with_opaque(cpu, regs, 0); -} -const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp); - -/* CPWriteFn that can be used to implement writes-ignored behaviour */ -void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value); -/* CPReadFn that can be used for read-as-zero behaviour */ -uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri); - -/* CPResetFn that does nothing, for use if no reset is required even - * if fieldoffset is non zero. - */ -void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque); - -/* Return true if this reginfo struct's field in the cpu state struct - * is 64 bits wide. - */ -static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri) -{ - return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT); -} - -static inline bool cp_access_ok(int current_el, - const ARMCPRegInfo *ri, int isread) -{ - return (ri->access >> ((current_el * 2) + isread)) & 1; -} - -/* Raw read of a coprocessor register (as needed for migration, etc) */ -uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri); - -/** - * write_list_to_cpustate - * @cpu: ARMCPU - * - * For each register listed in the ARMCPU cpreg_indexes list, write - * its value from the cpreg_values list into the ARMCPUState structure. - * This updates TCG's working data structures from KVM data or - * from incoming migration state. - * - * Returns: true if all register values were updated correctly, - * false if some register was unknown or could not be written. - * Note that we do not stop early on failure -- we will attempt - * writing all registers in the list. - */ -bool write_list_to_cpustate(ARMCPU *cpu); - -/** - * write_cpustate_to_list: - * @cpu: ARMCPU - * - * For each register listed in the ARMCPU cpreg_indexes list, write - * its value from the ARMCPUState structure into the cpreg_values list. - * This is used to copy info from TCG's working data structures into - * KVM or for outbound migration. - * - * Returns: true if all register values were read correctly, - * false if some register was unknown or could not be read. - * Note that we do not stop early on failure -- we will attempt - * reading all registers in the list. - */ -bool write_cpustate_to_list(ARMCPU *cpu); - -/* Does the core conform to the "MicroController" profile. e.g. Cortex-M3. - Note the M in older cores (eg. ARM7TDMI) stands for Multiply. These are - conventional cores (ie. Application or Realtime profile). */ - -#define IS_M(env) arm_feature(env, ARM_FEATURE_M) - -#define ARM_CPUID_TI915T 0x54029152 -#define ARM_CPUID_TI925T 0x54029252 - -#if defined(CONFIG_USER_ONLY) -#define TARGET_PAGE_BITS 12 -#else -/* The ARM MMU allows 1k pages. */ -/* ??? Linux doesn't actually use these, and they're deprecated in recent - architecture revisions. Maybe a configure option to disable them. */ -#define TARGET_PAGE_BITS 10 -#endif - -#if defined(TARGET_AARCH64) -# define TARGET_PHYS_ADDR_SPACE_BITS 48 -# define TARGET_VIRT_ADDR_SPACE_BITS 64 -#else -# define TARGET_PHYS_ADDR_SPACE_BITS 40 -# define TARGET_VIRT_ADDR_SPACE_BITS 32 -#endif - -static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, - unsigned int target_el) -{ - CPUARMState *env = cs->env_ptr; - unsigned int cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - bool pstate_unmasked; - int8_t unmasked = 0; - - /* Don't take exceptions if they target a lower EL. - * This check should catch any exceptions that would not be taken but left - * pending. - */ - if (cur_el > target_el) { - return false; - } - - switch (excp_idx) { - case EXCP_FIQ: - pstate_unmasked = !(env->daif & PSTATE_F); - break; - - case EXCP_IRQ: - pstate_unmasked = !(env->daif & PSTATE_I); - break; - - case EXCP_VFIQ: - if (secure || !(env->cp15.hcr_el2 & HCR_FMO)) { - /* VFIQs are only taken when hypervized and non-secure. */ - return false; - } - return !(env->daif & PSTATE_F); - case EXCP_VIRQ: - if (secure || !(env->cp15.hcr_el2 & HCR_IMO)) { - /* VIRQs are only taken when hypervized and non-secure. */ - return false; - } - return !(env->daif & PSTATE_I); - default: - g_assert_not_reached(); - } - - /* Use the target EL, current execution state and SCR/HCR settings to - * determine whether the corresponding CPSR bit is used to mask the - * interrupt. - */ - if ((target_el > cur_el) && (target_el != 1)) { - /* Exceptions targeting a higher EL may not be maskable */ - if (arm_feature(env, ARM_FEATURE_AARCH64)) { - /* 64-bit masking rules are simple: exceptions to EL3 - * can't be masked, and exceptions to EL2 can only be - * masked from Secure state. The HCR and SCR settings - * don't affect the masking logic, only the interrupt routing. - */ - if (target_el == 3 || !secure) { - unmasked = 1; - } - } else { - /* The old 32-bit-only environment has a more complicated - * masking setup. HCR and SCR bits not only affect interrupt - * routing but also change the behaviour of masking. - */ - bool hcr, scr; - - switch (excp_idx) { - case EXCP_FIQ: - /* If FIQs are routed to EL3 or EL2 then there are cases where - * we override the CPSR.F in determining if the exception is - * masked or not. If neither of these are set then we fall back - * to the CPSR.F setting otherwise we further assess the state - * below. - */ - hcr = (env->cp15.hcr_el2 & HCR_FMO); - scr = (env->cp15.scr_el3 & SCR_FIQ); - - /* When EL3 is 32-bit, the SCR.FW bit controls whether the - * CPSR.F bit masks FIQ interrupts when taken in non-secure - * state. If SCR.FW is set then FIQs can be masked by CPSR.F - * when non-secure but only when FIQs are only routed to EL3. - */ - scr = scr && !((env->cp15.scr_el3 & SCR_FW) && !hcr); - break; - case EXCP_IRQ: - /* When EL3 execution state is 32-bit, if HCR.IMO is set then - * we may override the CPSR.I masking when in non-secure state. - * The SCR.IRQ setting has already been taken into consideration - * when setting the target EL, so it does not have a further - * affect here. - */ - hcr = (env->cp15.hcr_el2 & HCR_IMO); - scr = false; - break; - default: - g_assert_not_reached(); - } - - if ((scr || hcr) && !secure) { - unmasked = 1; - } - } - } - - /* The PSTATE bits only mask the interrupt if we have not overriden the - * ability above. - */ - return unmasked || pstate_unmasked; -} - -#define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model)) - -#define cpu_exec cpu_arm_exec -#define cpu_signal_handler cpu_arm_signal_handler -#define cpu_list arm_cpu_list - -/* ARM has the following "translation regimes" (as the ARM ARM calls them): - * - * If EL3 is 64-bit: - * + NonSecure EL1 & 0 stage 1 - * + NonSecure EL1 & 0 stage 2 - * + NonSecure EL2 - * + Secure EL1 & EL0 - * + Secure EL3 - * If EL3 is 32-bit: - * + NonSecure PL1 & 0 stage 1 - * + NonSecure PL1 & 0 stage 2 - * + NonSecure PL2 - * + Secure PL0 & PL1 - * (reminder: for 32 bit EL3, Secure PL1 is *EL3*, not EL1.) - * - * For QEMU, an mmu_idx is not quite the same as a translation regime because: - * 1. we need to split the "EL1 & 0" regimes into two mmu_idxes, because they - * may differ in access permissions even if the VA->PA map is the same - * 2. we want to cache in our TLB the full VA->IPA->PA lookup for a stage 1+2 - * translation, which means that we have one mmu_idx that deals with two - * concatenated translation regimes [this sort of combined s1+2 TLB is - * architecturally permitted] - * 3. we don't need to allocate an mmu_idx to translations that we won't be - * handling via the TLB. The only way to do a stage 1 translation without - * the immediate stage 2 translation is via the ATS or AT system insns, - * which can be slow-pathed and always do a page table walk. - * 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3" - * translation regimes, because they map reasonably well to each other - * and they can't both be active at the same time. - * This gives us the following list of mmu_idx values: - * - * NS EL0 (aka NS PL0) stage 1+2 - * NS EL1 (aka NS PL1) stage 1+2 - * NS EL2 (aka NS PL2) - * S EL3 (aka S PL1) - * S EL0 (aka S PL0) - * S EL1 (not used if EL3 is 32 bit) - * NS EL0+1 stage 2 - * - * (The last of these is an mmu_idx because we want to be able to use the TLB - * for the accesses done as part of a stage 1 page table walk, rather than - * having to walk the stage 2 page table over and over.) - * - * Our enumeration includes at the end some entries which are not "true" - * mmu_idx values in that they don't have corresponding TLBs and are only - * valid for doing slow path page table walks. - * - * The constant names here are patterned after the general style of the names - * of the AT/ATS operations. - * The values used are carefully arranged to make mmu_idx => EL lookup easy. - */ -typedef enum ARMMMUIdx { - ARMMMUIdx_S12NSE0 = 0, - ARMMMUIdx_S12NSE1 = 1, - ARMMMUIdx_S1E2 = 2, - ARMMMUIdx_S1E3 = 3, - ARMMMUIdx_S1SE0 = 4, - ARMMMUIdx_S1SE1 = 5, - ARMMMUIdx_S2NS = 6, - /* Indexes below here don't have TLBs and are used only for AT system - * instructions or for the first stage of an S12 page table walk. - */ - ARMMMUIdx_S1NSE0 = 7, - ARMMMUIdx_S1NSE1 = 8, -} ARMMMUIdx; - -#define MMU_USER_IDX 0 - -/* Return the exception level we're running at if this is our mmu_idx */ -static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx) -{ - assert(mmu_idx < ARMMMUIdx_S2NS); - return mmu_idx & 3; -} - -/* Determine the current mmu_idx to use for normal loads/stores */ -static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) -{ - int el = arm_current_el(env); - - if (el < 2 && arm_is_secure_below_el3(env)) { - return ARMMMUIdx_S1SE0 + el; - } - return el; -} - -/* Return the Exception Level targeted by debug exceptions; - * currently always EL1 since we don't implement EL2 or EL3. - */ -static inline int arm_debug_target_el(CPUARMState *env) -{ - bool secure = arm_is_secure(env); - bool route_to_el2 = false; - - if (arm_feature(env, ARM_FEATURE_EL2) && !secure) { - route_to_el2 = env->cp15.hcr_el2 & HCR_TGE || - env->cp15.mdcr_el2 & (1 << 8); - } - - if (route_to_el2) { - return 2; - } else if (arm_feature(env, ARM_FEATURE_EL3) && - !arm_el_is_aa64(env, 3) && secure) { - return 3; - } else { - return 1; - } -} - -static inline bool aa64_generate_debug_exceptions(CPUARMState *env) -{ - if (arm_current_el(env) == arm_debug_target_el(env)) { - if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0) - || (env->daif & PSTATE_D)) { - return false; - } - } - return true; -} - -static inline bool aa32_generate_debug_exceptions(CPUARMState *env) -{ - if (arm_current_el(env) == 0 && arm_el_is_aa64(env, 1)) { - return aa64_generate_debug_exceptions(env); - } - return arm_current_el(env) != 2; -} - -/* Return true if debugging exceptions are currently enabled. - * This corresponds to what in ARM ARM pseudocode would be - * if UsingAArch32() then - * return AArch32.GenerateDebugExceptions() - * else - * return AArch64.GenerateDebugExceptions() - * We choose to push the if() down into this function for clarity, - * since the pseudocode has it at all callsites except for the one in - * CheckSoftwareStep(), where it is elided because both branches would - * always return the same value. - * - * Parts of the pseudocode relating to EL2 and EL3 are omitted because we - * don't yet implement those exception levels or their associated trap bits. - */ -static inline bool arm_generate_debug_exceptions(CPUARMState *env) -{ - if (env->aarch64) { - return aa64_generate_debug_exceptions(env); - } else { - return aa32_generate_debug_exceptions(env); - } -} - -/* Is single-stepping active? (Note that the "is EL_D AArch64?" check - * implicitly means this always returns false in pre-v8 CPUs.) - */ -static inline bool arm_singlestep_active(CPUARMState *env) -{ - return extract32(env->cp15.mdscr_el1, 0, 1) - && arm_el_is_aa64(env, arm_debug_target_el(env)) - && arm_generate_debug_exceptions(env); -} - -#include "exec/cpu-all.h" - -/* Bit usage in the TB flags field: bit 31 indicates whether we are - * in 32 or 64 bit mode. The meaning of the other bits depends on that. - * We put flags which are shared between 32 and 64 bit mode at the top - * of the word, and flags which apply to only one mode at the bottom. - */ -#define ARM_TBFLAG_AARCH64_STATE_SHIFT 31 -#define ARM_TBFLAG_AARCH64_STATE_MASK (1U << ARM_TBFLAG_AARCH64_STATE_SHIFT) -#define ARM_TBFLAG_MMUIDX_SHIFT 28 -#define ARM_TBFLAG_MMUIDX_MASK (0x7 << ARM_TBFLAG_MMUIDX_SHIFT) -#define ARM_TBFLAG_SS_ACTIVE_SHIFT 27 -#define ARM_TBFLAG_SS_ACTIVE_MASK (1 << ARM_TBFLAG_SS_ACTIVE_SHIFT) -#define ARM_TBFLAG_PSTATE_SS_SHIFT 26 -#define ARM_TBFLAG_PSTATE_SS_MASK (1 << ARM_TBFLAG_PSTATE_SS_SHIFT) -/* Target EL if we take a floating-point-disabled exception */ -#define ARM_TBFLAG_FPEXC_EL_SHIFT 24 -#define ARM_TBFLAG_FPEXC_EL_MASK (0x3 << ARM_TBFLAG_FPEXC_EL_SHIFT) - -/* Bit usage when in AArch32 state: */ -#define ARM_TBFLAG_THUMB_SHIFT 0 -#define ARM_TBFLAG_THUMB_MASK (1 << ARM_TBFLAG_THUMB_SHIFT) -#define ARM_TBFLAG_VECLEN_SHIFT 1 -#define ARM_TBFLAG_VECLEN_MASK (0x7 << ARM_TBFLAG_VECLEN_SHIFT) -#define ARM_TBFLAG_VECSTRIDE_SHIFT 4 -#define ARM_TBFLAG_VECSTRIDE_MASK (0x3 << ARM_TBFLAG_VECSTRIDE_SHIFT) -#define ARM_TBFLAG_VFPEN_SHIFT 7 -#define ARM_TBFLAG_VFPEN_MASK (1 << ARM_TBFLAG_VFPEN_SHIFT) -#define ARM_TBFLAG_CONDEXEC_SHIFT 8 -#define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT) -#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16 -#define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT) -/* We store the bottom two bits of the CPAR as TB flags and handle - * checks on the other bits at runtime - */ -#define ARM_TBFLAG_XSCALE_CPAR_SHIFT 17 -#define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT) -/* Indicates whether cp register reads and writes by guest code should access - * the secure or nonsecure bank of banked registers; note that this is not - * the same thing as the current security state of the processor! - */ -#define ARM_TBFLAG_NS_SHIFT 19 -#define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT) - -/* Bit usage when in AArch64 state: currently we have no A64 specific bits */ - -/* some convenience accessor macros */ -#define ARM_TBFLAG_AARCH64_STATE(F) \ - (((F) & ARM_TBFLAG_AARCH64_STATE_MASK) >> ARM_TBFLAG_AARCH64_STATE_SHIFT) -#define ARM_TBFLAG_MMUIDX(F) \ - (((F) & ARM_TBFLAG_MMUIDX_MASK) >> ARM_TBFLAG_MMUIDX_SHIFT) -#define ARM_TBFLAG_SS_ACTIVE(F) \ - (((F) & ARM_TBFLAG_SS_ACTIVE_MASK) >> ARM_TBFLAG_SS_ACTIVE_SHIFT) -#define ARM_TBFLAG_PSTATE_SS(F) \ - (((F) & ARM_TBFLAG_PSTATE_SS_MASK) >> ARM_TBFLAG_PSTATE_SS_SHIFT) -#define ARM_TBFLAG_FPEXC_EL(F) \ - (((F) & ARM_TBFLAG_FPEXC_EL_MASK) >> ARM_TBFLAG_FPEXC_EL_SHIFT) -#define ARM_TBFLAG_THUMB(F) \ - (((F) & ARM_TBFLAG_THUMB_MASK) >> ARM_TBFLAG_THUMB_SHIFT) -#define ARM_TBFLAG_VECLEN(F) \ - (((F) & ARM_TBFLAG_VECLEN_MASK) >> ARM_TBFLAG_VECLEN_SHIFT) -#define ARM_TBFLAG_VECSTRIDE(F) \ - (((F) & ARM_TBFLAG_VECSTRIDE_MASK) >> ARM_TBFLAG_VECSTRIDE_SHIFT) -#define ARM_TBFLAG_VFPEN(F) \ - (((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT) -#define ARM_TBFLAG_CONDEXEC(F) \ - (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT) -#define ARM_TBFLAG_BSWAP_CODE(F) \ - (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT) -#define ARM_TBFLAG_XSCALE_CPAR(F) \ - (((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT) -#define ARM_TBFLAG_NS(F) \ - (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT) - -/* Return the exception level to which FP-disabled exceptions should - * be taken, or 0 if FP is enabled. - */ -static inline int fp_exception_el(CPUARMState *env) -{ - int fpen; - int cur_el = arm_current_el(env); - - /* CPACR and the CPTR registers don't exist before v6, so FP is - * always accessible - */ - if (!arm_feature(env, ARM_FEATURE_V6)) { - return 0; - } - - /* The CPACR controls traps to EL1, or PL1 if we're 32 bit: - * 0, 2 : trap EL0 and EL1/PL1 accesses - * 1 : trap only EL0 accesses - * 3 : trap no accesses - */ - fpen = extract32(env->cp15.cpacr_el1, 20, 2); - switch (fpen) { - case 0: - case 2: - if (cur_el == 0 || cur_el == 1) { - /* Trap to PL1, which might be EL1 or EL3 */ - if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) { - return 3; - } - return 1; - } - if (cur_el == 3 && !is_a64(env)) { - /* Secure PL1 running at EL3 */ - return 3; - } - break; - case 1: - if (cur_el == 0) { - return 1; - } - break; - case 3: - break; - } - - /* For the CPTR registers we don't need to guard with an ARM_FEATURE - * check because zero bits in the registers mean "don't trap". - */ - - /* CPTR_EL2 : present in v7VE or v8 */ - if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1) - && !arm_is_secure_below_el3(env)) { - /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */ - return 2; - } - - /* CPTR_EL3 : present in v8 */ - if (extract32(env->cp15.cptr_el[3], 10, 1)) { - /* Trap all FP ops to EL3 */ - return 3; - } - - return 0; -} - -static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, - target_ulong *cs_base, int *flags) -{ - if (is_a64(env)) { - *pc = env->pc; - *flags = ARM_TBFLAG_AARCH64_STATE_MASK; - } else { - *pc = env->regs[15]; - *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT) - | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT) - | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT) - | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT) - | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT); - if (!(access_secure_reg(env))) { - *flags |= ARM_TBFLAG_NS_MASK; - } - if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30) - || arm_el_is_aa64(env, 1)) { - *flags |= ARM_TBFLAG_VFPEN_MASK; - } - *flags |= (extract32(env->cp15.c15_cpar, 0, 2) - << ARM_TBFLAG_XSCALE_CPAR_SHIFT); - } - - *flags |= (cpu_mmu_index(env, false) << ARM_TBFLAG_MMUIDX_SHIFT); - /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine - * states defined in the ARM ARM for software singlestep: - * SS_ACTIVE PSTATE.SS State - * 0 x Inactive (the TB flag for SS is always 0) - * 1 0 Active-pending - * 1 1 Active-not-pending - */ - if (arm_singlestep_active(env)) { - *flags |= ARM_TBFLAG_SS_ACTIVE_MASK; - if (is_a64(env)) { - if (env->pstate & PSTATE_SS) { - *flags |= ARM_TBFLAG_PSTATE_SS_MASK; - } - } else { - if (env->uncached_cpsr & PSTATE_SS) { - *flags |= ARM_TBFLAG_PSTATE_SS_MASK; - } - } - } - *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT; - - *cs_base = 0; -} - -#include "exec/exec-all.h" - -enum { - QEMU_PSCI_CONDUIT_DISABLED = 0, - QEMU_PSCI_CONDUIT_SMC = 1, - QEMU_PSCI_CONDUIT_HVC = 2, -}; - -#endif diff --git a/target-arm/helper.c b/target-arm/helper.c deleted file mode 100644 index c615bd3f9874b..0000000000000 --- a/target-arm/helper.c +++ /dev/null @@ -1,8971 +0,0 @@ -#include "cpu.h" -#include "internals.h" -#include "exec/gdbstub.h" -#include "exec/helper-proto.h" -#include "qemu/host-utils.h" -#include "sysemu/arch_init.h" -#include "sysemu/sysemu.h" -#include "qemu/bitops.h" -#include "qemu/crc32c.h" -#include "exec/cpu_ldst.h" -#include "arm_ldst.h" -#include /* For crc32 */ -#include "exec/semihost.h" - -#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ - -//#define DEBUG_ARM_HELPER -#ifdef DEBUG_ARM_HELPER - -// NOTE: The usleep() helps the MacOS stdout from freezing when we have a lot of print out -#define DPRINTF(fmt, ...) \ - do { printf("ARM_HELPER: " fmt , ## __VA_ARGS__); \ - /* usleep(100); */ /* the usleep causes watchdogs :( */ \ - fflush(stdout); \ - } while (0) -#else -#define DPRINTF(fmt, ...) -#endif - -static CompatGMutex helper_mmu_lock; - -#ifndef CONFIG_USER_ONLY -static bool get_phys_addr(CPUARMState *env, target_ulong address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, - target_ulong *page_size, uint32_t *fsr, - ARMMMUFaultInfo *fi); - -static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot, - target_ulong *page_size_ptr, uint32_t *fsr, - ARMMMUFaultInfo *fi); - -/* Definitions for the PMCCNTR and PMCR registers */ -#define PMCRD 0x8 -#define PMCRC 0x4 -#define PMCRE 0x1 -#endif - -static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) -{ - int nregs; - - /* VFP data registers are always little-endian. */ - nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; - if (reg < nregs) { - stfq_le_p(buf, env->vfp.regs[reg]); - return 8; - } - if (arm_feature(env, ARM_FEATURE_NEON)) { - /* Aliases for Q regs. */ - nregs += 16; - if (reg < nregs) { - stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]); - stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]); - return 16; - } - } - switch (reg - nregs) { - case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4; - case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4; - case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4; - } - return 0; -} - -static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) -{ - int nregs; - - nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; - if (reg < nregs) { - env->vfp.regs[reg] = ldfq_le_p(buf); - return 8; - } - if (arm_feature(env, ARM_FEATURE_NEON)) { - nregs += 16; - if (reg < nregs) { - env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf); - env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8); - return 16; - } - } - switch (reg - nregs) { - case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4; - case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4; - case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4; - } - return 0; -} - -static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) -{ - switch (reg) { - case 0 ... 31: - /* 128 bit FP register */ - stfq_le_p(buf, env->vfp.regs[reg * 2]); - stfq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]); - return 16; - case 32: - /* FPSR */ - stl_p(buf, vfp_get_fpsr(env)); - return 4; - case 33: - /* FPCR */ - stl_p(buf, vfp_get_fpcr(env)); - return 4; - default: - return 0; - } -} - -static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) -{ - switch (reg) { - case 0 ... 31: - /* 128 bit FP register */ - env->vfp.regs[reg * 2] = ldfq_le_p(buf); - env->vfp.regs[reg * 2 + 1] = ldfq_le_p(buf + 8); - return 16; - case 32: - /* FPSR */ - vfp_set_fpsr(env, ldl_p(buf)); - return 4; - case 33: - /* FPCR */ - vfp_set_fpcr(env, ldl_p(buf)); - return 4; - default: - return 0; - } -} - -static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - assert(ri->fieldoffset); - if (cpreg_field_is_64bit(ri)) { - return CPREG_FIELD64(env, ri); - } else { - return CPREG_FIELD32(env, ri); - } -} - -static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - assert(ri->fieldoffset); - if (cpreg_field_is_64bit(ri)) { - CPREG_FIELD64(env, ri) = value; - } else { - CPREG_FIELD32(env, ri) = value; - } -} - -static void *raw_ptr(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return (char *)env + ri->fieldoffset; -} - -uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* Raw read of a coprocessor register (as needed for migration, etc). */ - if (ri->type & ARM_CP_CONST) { - return ri->resetvalue; - } else if (ri->raw_readfn) { - return ri->raw_readfn(env, ri); - } else if (ri->readfn) { - return ri->readfn(env, ri); - } else { - return raw_read(env, ri); - } -} - -static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t v) -{ - /* Raw write of a coprocessor register (as needed for migration, etc). - * Note that constant registers are treated as write-ignored; the - * caller should check for success by whether a readback gives the - * value written. - */ - if (ri->type & ARM_CP_CONST) { - return; - } else if (ri->raw_writefn) { - ri->raw_writefn(env, ri, v); - } else if (ri->writefn) { - ri->writefn(env, ri, v); - } else { - raw_write(env, ri, v); - } -} - -static bool raw_accessors_invalid(const ARMCPRegInfo *ri) -{ - /* Return true if the regdef would cause an assertion if you called - * read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a - * program bug for it not to have the NO_RAW flag). - * NB that returning false here doesn't necessarily mean that calling - * read/write_raw_cp_reg() is safe, because we can't distinguish "has - * read/write access functions which are safe for raw use" from "has - * read/write access functions which have side effects but has forgotten - * to provide raw access functions". - * The tests here line up with the conditions in read/write_raw_cp_reg() - * and assertions in raw_read()/raw_write(). - */ - if ((ri->type & ARM_CP_CONST) || - ri->fieldoffset || - ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) { - return false; - } - return true; -} - -bool write_cpustate_to_list(ARMCPU *cpu) -{ - /* Write the coprocessor state from cpu->env to the (index,value) list. */ - int i; - bool ok = true; - - for (i = 0; i < cpu->cpreg_array_len; i++) { - uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]); - const ARMCPRegInfo *ri; - - ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); - if (!ri) { - ok = false; - continue; - } - if (ri->type & ARM_CP_NO_RAW) { - continue; - } - cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri); - } - return ok; -} - -bool write_list_to_cpustate(ARMCPU *cpu) -{ - int i; - bool ok = true; - - for (i = 0; i < cpu->cpreg_array_len; i++) { - uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]); - uint64_t v = cpu->cpreg_values[i]; - const ARMCPRegInfo *ri; - - ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); - if (!ri) { - ok = false; - continue; - } - if (ri->type & ARM_CP_NO_RAW) { - continue; - } - /* Write value and confirm it reads back as written - * (to catch read-only registers and partially read-only - * registers where the incoming migration value doesn't match) - */ - write_raw_cp_reg(&cpu->env, ri, v); - if (read_raw_cp_reg(&cpu->env, ri) != v) { - ok = false; - } - } - return ok; -} - -static void add_cpreg_to_list(gpointer key, gpointer opaque) -{ - ARMCPU *cpu = opaque; - uint64_t regidx; - const ARMCPRegInfo *ri; - - regidx = *(uint32_t *)key; - ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); - - if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { - cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx); - /* The value array need not be initialized at this point */ - cpu->cpreg_array_len++; - } -} - -static void count_cpreg(gpointer key, gpointer opaque) -{ - ARMCPU *cpu = opaque; - uint64_t regidx; - const ARMCPRegInfo *ri; - - regidx = *(uint32_t *)key; - ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); - - if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { - cpu->cpreg_array_len++; - } -} - -static gint cpreg_key_compare(gconstpointer a, gconstpointer b) -{ - uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a); - uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b); - - if (aidx > bidx) { - return 1; - } - if (aidx < bidx) { - return -1; - } - return 0; -} - -void init_cpreg_list(ARMCPU *cpu) -{ - /* Initialise the cpreg_tuples[] array based on the cp_regs hash. - * Note that we require cpreg_tuples[] to be sorted by key ID. - */ - GList *keys; - int arraylen; - - keys = g_hash_table_get_keys(cpu->cp_regs); - keys = g_list_sort(keys, cpreg_key_compare); - - cpu->cpreg_array_len = 0; - - g_list_foreach(keys, count_cpreg, cpu); - - arraylen = cpu->cpreg_array_len; - cpu->cpreg_indexes = g_new(uint64_t, arraylen); - cpu->cpreg_values = g_new(uint64_t, arraylen); - cpu->cpreg_vmstate_indexes = g_new(uint64_t, arraylen); - cpu->cpreg_vmstate_values = g_new(uint64_t, arraylen); - cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; - cpu->cpreg_array_len = 0; - - g_list_foreach(keys, add_cpreg_to_list, cpu); - - assert(cpu->cpreg_array_len == arraylen); - - g_list_free(keys); -} - -/* - * Some registers are not accessible if EL3.NS=0 and EL3 is using AArch32 but - * they are accessible when EL3 is using AArch64 regardless of EL3.NS. - * - * access_el3_aa32ns: Used to check AArch32 register views. - * access_el3_aa32ns_aa64any: Used to check both AArch32/64 register views. - */ -static CPAccessResult access_el3_aa32ns(CPUARMState *env, - const ARMCPRegInfo *ri) -{ - bool secure = arm_is_secure_below_el3(env); - - assert(!arm_el_is_aa64(env, 3)); - if (secure) { - return CP_ACCESS_TRAP_UNCATEGORIZED; - } - return CP_ACCESS_OK; -} - -static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env, - const ARMCPRegInfo *ri) -{ - if (!arm_el_is_aa64(env, 3)) { - return access_el3_aa32ns(env, ri); - } - return CP_ACCESS_OK; -} - -static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - raw_write(env, ri, value); - tlb_flush(CPU(cpu), 1); /* Flush TLB as domain not tracked in TLB */ -} - -static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - if (raw_read(env, ri) != value) { - /* Unlike real hardware the qemu TLB uses virtual addresses, - * not modified virtual addresses, so this causes a TLB flush. - */ - tlb_flush(CPU(cpu), 1); - raw_write(env, ri, value); - } -} - -static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_MPU) - && !extended_addresses_enabled(env)) { - /* For VMSA (when not using the LPAE long descriptor page table - * format) this register includes the ASID, so do a TLB flush. - * For PMSA it is purely a process ID and no action is needed. - */ - tlb_flush(CPU(cpu), 1); - } - raw_write(env, ri, value); -} - -static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate all (TLBIALL) */ - ARMCPU *cpu = arm_env_get_cpu(env); - - tlb_flush(CPU(cpu), 1); -} - -static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */ - ARMCPU *cpu = arm_env_get_cpu(env); - - tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK); -} - -static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate by ASID (TLBIASID) */ - ARMCPU *cpu = arm_env_get_cpu(env); - - tlb_flush(CPU(cpu), value == 0); -} - -static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */ - ARMCPU *cpu = arm_env_get_cpu(env); - - tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK); -} - -/* IS variants of TLB operations must affect all cores */ -static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - tlb_flush(other_cs, 1); - } -} - -static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - tlb_flush(other_cs, value == 0); - } -} - -static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - tlb_flush_page(other_cs, value & TARGET_PAGE_MASK); - } -} - -static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - tlb_flush_page(other_cs, value & TARGET_PAGE_MASK); - } -} - -static const ARMCPRegInfo cp_reginfo[] = { - /* Define the secure and non-secure FCSE identifier CP registers - * separately because there is no secure bank in V8 (no _EL3). This allows - * the secure register to be properly reset and migrated. There is also no - * v8 EL1 version of the register so the non-secure instance stands alone. - */ - { .name = "FCSEIDR(NS)", - .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0, - .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS, - .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_ns), - .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, - { .name = "FCSEIDR(S)", - .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0, - .access = PL1_RW, .secure = ARM_CP_SECSTATE_S, - .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s), - .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, }, - /* Define the secure and non-secure context identifier CP registers - * separately because there is no secure bank in V8 (no _EL3). This allows - * the secure register to be properly reset and migrated. In the - * non-secure case, the 32-bit register will have reset and migration - * disabled during registration as it is handled by the 64-bit instance. - */ - { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, - .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS, - .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]), - .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, - { .name = "CONTEXTIDR(S)", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1, - .access = PL1_RW, .secure = ARM_CP_SECSTATE_S, - .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s), - .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo not_v8_cp_reginfo[] = { - /* NB: Some of these registers exist in v8 but with more precise - * definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]). - */ - /* MMU Domain access control / MPU write buffer control */ - { .name = "DACR", - .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY, - .access = PL1_RW, .resetvalue = 0, - .writefn = dacr_write, .raw_writefn = raw_write, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), - offsetoflow32(CPUARMState, cp15.dacr_ns) } }, - /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs. - * For v6 and v5, these mappings are overly broad. - */ - { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, - { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 1, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, - { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 4, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, - { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 8, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP }, - /* Cache maintenance ops; some of this space may be overridden later. */ - { .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, - .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, - .type = ARM_CP_NOP | ARM_CP_OVERRIDE }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo not_v6_cp_reginfo[] = { - /* Not all pre-v6 cores implemented this WFI, so this is slightly - * over-broad. - */ - { .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_WFI }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo not_v7_cp_reginfo[] = { - /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which - * is UNPREDICTABLE; we choose to NOP as most implementations do). - */ - { .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, - .access = PL1_W, .type = ARM_CP_WFI }, - /* L1 cache lockdown. Not architectural in v6 and earlier but in practice - * implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and - * OMAPCP will override this space. - */ - { .name = "DLOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_data), - .resetvalue = 0 }, - { .name = "ILOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_insn), - .resetvalue = 0 }, - /* v6 doesn't have the cache ID registers but Linux reads them anyway */ - { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY, - .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, - .resetvalue = 0 }, - /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR; - * implementing it as RAZ means the "debug architecture version" bits - * will read as a reserved value, which should cause Linux to not try - * to use the debug hardware. - */ - { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - /* MMU TLB control. Note that the wildcarding means we cover not just - * the unified TLB ops but also the dside/iside/inner-shareable variants. - */ - { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, - .type = ARM_CP_NO_RAW }, - { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, - .type = ARM_CP_NO_RAW }, - { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, - .type = ARM_CP_NO_RAW }, - { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, - .type = ARM_CP_NO_RAW }, - { .name = "PRRR", .cp = 15, .crn = 10, .crm = 2, - .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP }, - { .name = "NMRR", .cp = 15, .crn = 10, .crm = 2, - .opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP }, - REGINFO_SENTINEL -}; - -static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - uint32_t mask = 0; - - /* In ARMv8 most bits of CPACR_EL1 are RES0. */ - if (!arm_feature(env, ARM_FEATURE_V8)) { - /* ARMv7 defines bits for unimplemented coprocessors as RAZ/WI. - * ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP. - * TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell. - */ - if (arm_feature(env, ARM_FEATURE_VFP)) { - /* VFP coprocessor: cp10 & cp11 [23:20] */ - mask |= (1 << 31) | (1 << 30) | (0xf << 20); - - if (!arm_feature(env, ARM_FEATURE_NEON)) { - /* ASEDIS [31] bit is RAO/WI */ - value |= (1 << 31); - } - - /* VFPv3 and upwards with NEON implement 32 double precision - * registers (D0-D31). - */ - if (!arm_feature(env, ARM_FEATURE_NEON) || - !arm_feature(env, ARM_FEATURE_VFP3)) { - /* D32DIS [30] is RAO/WI if D16-31 are not implemented. */ - value |= (1 << 30); - } - } - value &= mask; - } - env->cp15.cpacr_el1 = value; -} - -static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - if (arm_feature(env, ARM_FEATURE_V8)) { - /* Check if CPACR accesses are to be trapped to EL2 */ - if (arm_current_el(env) == 1 && - (env->cp15.cptr_el[2] & CPTR_TCPAC) && !arm_is_secure(env)) { - return CP_ACCESS_TRAP_EL2; - /* Check if CPACR accesses are to be trapped to EL3 */ - } else if (arm_current_el(env) < 3 && - (env->cp15.cptr_el[3] & CPTR_TCPAC)) { - return CP_ACCESS_TRAP_EL3; - } - } - - return CP_ACCESS_OK; -} - -static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* Check if CPTR accesses are set to trap to EL3 */ - if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) { - return CP_ACCESS_TRAP_EL3; - } - - return CP_ACCESS_OK; -} - -static const ARMCPRegInfo v6_cp_reginfo[] = { - /* prefetch by MVA in v6, NOP in v7 */ - { .name = "MVA_prefetch", - .cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NOP }, - /* We need to break the TB after ISB to execute self-modifying code - * correctly and also to take any pending interrupts immediately. - * So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag. - */ - { .name = "ISB", .cp = 15, .crn = 7, .crm = 5, .opc1 = 0, .opc2 = 4, - .access = PL0_W, .type = ARM_CP_NO_RAW, .writefn = arm_cp_write_ignore }, - { .name = "DSB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 4, - .access = PL0_W, .type = ARM_CP_NOP }, - { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5, - .access = PL0_W, .type = ARM_CP_NOP }, - { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s), - offsetof(CPUARMState, cp15.ifar_ns) }, - .resetvalue = 0, }, - /* Watchpoint Fault Address Register : should actually only be present - * for 1136, 1176, 11MPCore. - */ - { .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, }, - { .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, - .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1), - .resetvalue = 0, .writefn = cpacr_write }, - REGINFO_SENTINEL -}; - -static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* Performance monitor registers user accessibility is controlled - * by PMUSERENR. - */ - if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -#ifndef CONFIG_USER_ONLY - -static inline bool arm_ccnt_enabled(CPUARMState *env) -{ - /* This does not support checking PMCCFILTR_EL0 register */ - - if (!(env->cp15.c9_pmcr & PMCRE)) { - return false; - } - - return true; -} - -void pmccntr_sync(CPUARMState *env) -{ - uint64_t temp_ticks; - - temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - temp_ticks /= 64; - } - - if (arm_ccnt_enabled(env)) { - env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt; - } -} - -static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - pmccntr_sync(env); - - if (value & PMCRC) { - /* The counter has been reset */ - env->cp15.c15_ccnt = 0; - } - - /* only the DP, X, D and E bits are writable */ - env->cp15.c9_pmcr &= ~0x39; - env->cp15.c9_pmcr |= (value & 0x39); - - pmccntr_sync(env); -} - -static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - uint64_t total_ticks; - - if (!arm_ccnt_enabled(env)) { - /* Counter is disabled, do not change value */ - return env->cp15.c15_ccnt; - } - - total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - total_ticks /= 64; - } - return total_ticks - env->cp15.c15_ccnt; -} - -static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - uint64_t total_ticks; - - if (!arm_ccnt_enabled(env)) { - /* Counter is disabled, set the absolute value */ - env->cp15.c15_ccnt = value; - return; - } - - total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - total_ticks /= 64; - } - env->cp15.c15_ccnt = total_ticks - value; -} - -static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - uint64_t cur_val = pmccntr_read(env, NULL); - - pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value)); -} - -#else /* CONFIG_USER_ONLY */ - -void pmccntr_sync(CPUARMState *env) -{ -} - -#endif - -static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - pmccntr_sync(env); - env->cp15.pmccfiltr_el0 = value & 0x7E000000; - pmccntr_sync(env); -} - -static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - value &= (1 << 31); - env->cp15.c9_pmcnten |= value; -} - -static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - value &= (1 << 31); - env->cp15.c9_pmcnten &= ~value; -} - -static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.c9_pmovsr &= ~value; -} - -static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.c9_pmxevtyper = value & 0xff; -} - -static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.c9_pmuserenr = value & 1; -} - -static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* We have no event counters so only the C bit can be changed */ - value &= (1 << 31); - env->cp15.c9_pminten |= value; -} - -static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - value &= (1 << 31); - env->cp15.c9_pminten &= ~value; -} - -static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Note that even though the AArch64 view of this register has bits - * [10:0] all RES0 we can only mask the bottom 5, to comply with the - * architectural requirements for bits which are RES0 only in some - * contexts. (ARMv8 would permit us to do no masking at all, but ARMv7 - * requires the bottom five bits to be RAZ/WI because they're UNK/SBZP.) - */ - raw_write(env, ri, value & ~0x1FULL); -} - -static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) -{ - /* We only mask off bits that are RES0 both for AArch64 and AArch32. - * For bits that vary between AArch32/64, code needs to check the - * current execution mode before directly using the feature bit. - */ - uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK; - - if (!arm_feature(env, ARM_FEATURE_EL2)) { - valid_mask &= ~SCR_HCE; - - /* On ARMv7, SMD (or SCD as it is called in v7) is only - * supported if EL2 exists. The bit is UNK/SBZP when - * EL2 is unavailable. In QEMU ARMv7, we force it to always zero - * when EL2 is unavailable. - * On ARMv8, this bit is always available. - */ - if (arm_feature(env, ARM_FEATURE_V7) && - !arm_feature(env, ARM_FEATURE_V8)) { - valid_mask &= ~SCR_SMD; - } - } - - /* Clear all-context RES0 bits. */ - value &= valid_mask; - raw_write(env, ri, value); -} - -static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - /* Acquire the CSSELR index from the bank corresponding to the CCSIDR - * bank - */ - uint32_t index = A32_BANKED_REG_GET(env, csselr, - ri->secure & ARM_CP_SECSTATE_S); - - return cpu->ccsidr[index]; -} - -static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - raw_write(env, ri, value & 0xf); -} - -static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - CPUState *cs = ENV_GET_CPU(env); - uint64_t ret = 0; - - if (cs->interrupt_request & CPU_INTERRUPT_HARD) { - ret |= CPSR_I; - } - if (cs->interrupt_request & CPU_INTERRUPT_FIQ) { - ret |= CPSR_F; - } - /* External aborts are not possible in QEMU so A bit is always clear */ - return ret; -} - -static const ARMCPRegInfo v7_cp_reginfo[] = { - /* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */ - { .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, - .access = PL1_W, .type = ARM_CP_NOP }, - /* Performance monitors are implementation defined in v7, - * but with an ARM recommended set of registers, which we - * follow (although we don't actually implement any counters) - * - * Performance registers fall into three categories: - * (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR) - * (b) RO in PL0 (ie UNDEF on write), RW in PL1 (PMUSERENR) - * (c) UNDEF in PL0 if PMUSERENR.EN==0, otherwise accessible (all others) - * For the cases controlled by PMUSERENR we must set .access to PL0_RW - * or PL0_RO as appropriate and then check PMUSERENR in the helper fn. - */ - { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1, - .access = PL0_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), - .writefn = pmcntenset_write, - .accessfn = pmreg_access, - .raw_writefn = raw_write }, - { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1, - .access = PL0_RW, .accessfn = pmreg_access, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0, - .writefn = pmcntenset_write, .raw_writefn = raw_write }, - { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2, - .access = PL0_RW, - .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), - .accessfn = pmreg_access, - .writefn = pmcntenclr_write, - .type = ARM_CP_ALIAS }, - { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2, - .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), - .writefn = pmcntenclr_write }, - { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3, - .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), - .accessfn = pmreg_access, - .writefn = pmovsr_write, - .raw_writefn = raw_write }, - /* Unimplemented so WI. */ - { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, - .access = PL0_W, .accessfn = pmreg_access, .type = ARM_CP_NOP }, - /* Since we don't implement any events, writing to PMSELR is UNPREDICTABLE. - * We choose to RAZ/WI. - */ - { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, - .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, - .accessfn = pmreg_access }, -#ifndef CONFIG_USER_ONLY - { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0, - .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO, - .readfn = pmccntr_read, .writefn = pmccntr_write32, - .accessfn = pmreg_access }, - { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0, - .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_IO, - .readfn = pmccntr_read, .writefn = pmccntr_write, }, -#endif - { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7, - .writefn = pmccfiltr_write, - .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_IO, - .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), - .resetvalue = 0, }, - { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, - .access = PL0_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper), - .accessfn = pmreg_access, .writefn = pmxevtyper_write, - .raw_writefn = raw_write }, - /* Unimplemented, RAZ/WI. */ - { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, - .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, - .accessfn = pmreg_access }, - { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0, - .access = PL0_R | PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr), - .resetvalue = 0, - .writefn = pmuserenr_write, .raw_writefn = raw_write }, - { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), - .resetvalue = 0, - .writefn = pmintenset_write, .raw_writefn = raw_write }, - { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), - .writefn = pmintenclr_write, }, - { .name = "VBAR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .writefn = vbar_write, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s), - offsetof(CPUARMState, cp15.vbar_ns) }, - .resetvalue = 0 }, - { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, - .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW }, - { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0, - .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s), - offsetof(CPUARMState, cp15.csselr_ns) } }, - /* Auxiliary ID register: this actually has an IMPDEF value but for now - * just RAZ for all cores: - */ - { .name = "AIDR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - /* Auxiliary fault status registers: these also are IMPDEF, and we - * choose to RAZ/WI for all cores. - */ - { .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1, - .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - /* MAIR can just read-as-written because we don't implement caches - * and so don't need to care about memory attributes. - */ - { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]), - .resetvalue = 0 }, - { .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0, - .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]), - .resetvalue = 0 }, - /* For non-long-descriptor page tables these are PRRR and NMRR; - * regardless they still act as reads-as-written for QEMU. - */ - /* MAIR0/1 are defined separately from their 64-bit counterpart which - * allows them to assign the correct fieldoffset based on the endianness - * handled in the field definitions. - */ - { .name = "MAIR0", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s), - offsetof(CPUARMState, cp15.mair0_ns) }, - .resetfn = arm_cp_reset_ignore }, - { .name = "MAIR1", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s), - offsetof(CPUARMState, cp15.mair1_ns) }, - .resetfn = arm_cp_reset_ignore }, - { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0, - .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read }, - /* 32 bit ITLB invalidates */ - { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, - { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, - { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, - /* 32 bit DTLB invalidates */ - { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, - { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, - { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, - /* 32 bit TLB invalidates */ - { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, - { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, - { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, - { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo v7mp_cp_reginfo[] = { - /* 32 bit TLB invalidates, Inner Shareable */ - { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write }, - { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write }, - { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, - .type = ARM_CP_NO_RAW, .access = PL1_W, - .writefn = tlbiasid_is_write }, - { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, - .type = ARM_CP_NO_RAW, .access = PL1_W, - .writefn = tlbimvaa_is_write }, - REGINFO_SENTINEL -}; - -static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - value &= 1; - env->teecr = value; -} - -static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - if (arm_current_el(env) == 0 && (env->teecr & 1)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -static const ARMCPRegInfo t2ee_cp_reginfo[] = { - { .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr), - .resetvalue = 0, - .writefn = teecr_write }, - { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0, - .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr), - .accessfn = teehbr_access, .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo v6k_cp_reginfo[] = { - { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0, - .access = PL0_RW, - .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 }, - { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL0_RW, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s), - offsetoflow32(CPUARMState, cp15.tpidrurw_ns) }, - .resetfn = arm_cp_reset_ignore }, - { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0, - .access = PL0_R|PL1_W, - .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]), - .resetvalue = 0}, - { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3, - .access = PL0_R|PL1_W, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s), - offsetoflow32(CPUARMState, cp15.tpidruro_ns) }, - .resetfn = arm_cp_reset_ignore }, - { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 }, - { .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4, - .access = PL1_RW, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s), - offsetoflow32(CPUARMState, cp15.tpidrprw_ns) }, - .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -#ifndef CONFIG_USER_ONLY - -static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */ - if (arm_current_el(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx) -{ - unsigned int cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - - /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */ - if (cur_el == 0 && - !extract32(env->cp15.c14_cntkctl, timeridx, 1)) { - return CP_ACCESS_TRAP; - } - - if (arm_feature(env, ARM_FEATURE_EL2) && - timeridx == GTIMER_PHYS && !secure && cur_el < 2 && - !extract32(env->cp15.cnthctl_el2, 0, 1)) { - return CP_ACCESS_TRAP_EL2; - } - return CP_ACCESS_OK; -} - -static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx) -{ - unsigned int cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - - /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if - * EL0[PV]TEN is zero. - */ - if (cur_el == 0 && - !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) { - return CP_ACCESS_TRAP; - } - - if (arm_feature(env, ARM_FEATURE_EL2) && - timeridx == GTIMER_PHYS && !secure && cur_el < 2 && - !extract32(env->cp15.cnthctl_el2, 1, 1)) { - return CP_ACCESS_TRAP_EL2; - } - return CP_ACCESS_OK; -} - -static CPAccessResult gt_pct_access(CPUARMState *env, - const ARMCPRegInfo *ri) -{ - return gt_counter_access(env, GTIMER_PHYS); -} - -static CPAccessResult gt_vct_access(CPUARMState *env, - const ARMCPRegInfo *ri) -{ - return gt_counter_access(env, GTIMER_VIRT); -} - -static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_timer_access(env, GTIMER_PHYS); -} - -static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_timer_access(env, GTIMER_VIRT); -} - -static CPAccessResult gt_stimer_access(CPUARMState *env, - const ARMCPRegInfo *ri) -{ - /* The AArch64 register view of the secure physical timer is - * always accessible from EL3, and configurably accessible from - * Secure EL1. - */ - switch (arm_current_el(env)) { - case 1: - if (!arm_is_secure(env)) { - return CP_ACCESS_TRAP; - } - if (!(env->cp15.scr_el3 & SCR_ST)) { - return CP_ACCESS_TRAP_EL3; - } - return CP_ACCESS_OK; - case 0: - case 2: - return CP_ACCESS_TRAP; - case 3: - return CP_ACCESS_OK; - default: - g_assert_not_reached(); - } -} - -static uint64_t gt_get_countervalue(CPUARMState *env) -{ - return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE; -} - -static void gt_recalc_timer(ARMCPU *cpu, int timeridx) -{ - ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx]; - - if (gt->ctl & 1) { - /* Timer enabled: calculate and set current ISTATUS, irq, and - * reset timer to when ISTATUS next has to change - */ - uint64_t offset = timeridx == GTIMER_VIRT ? - cpu->env.cp15.cntvoff_el2 : 0; - uint64_t count = gt_get_countervalue(&cpu->env); - /* Note that this must be unsigned 64 bit arithmetic: */ - int istatus = count - offset >= gt->cval; - uint64_t nexttick; - - gt->ctl = deposit32(gt->ctl, 2, 1, istatus); - qemu_set_irq(cpu->gt_timer_outputs[timeridx], - (istatus && !(gt->ctl & 2))); - if (istatus) { - /* Next transition is when count rolls back over to zero */ - nexttick = UINT64_MAX; - } else { - /* Next transition is when we hit cval */ - nexttick = gt->cval + offset; - } - /* Note that the desired next expiry time might be beyond the - * signed-64-bit range of a QEMUTimer -- in this case we just - * set the timer for as far in the future as possible. When the - * timer expires we will reset the timer for any remaining period. - */ - if (nexttick > INT64_MAX / GTIMER_SCALE) { - nexttick = INT64_MAX / GTIMER_SCALE; - } - timer_mod(cpu->gt_timer[timeridx], nexttick); - } else { - /* Timer disabled: ISTATUS and timer output always clear */ - gt->ctl &= ~4; - qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0); - timer_del(cpu->gt_timer[timeridx]); - } -} - -static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri, - int timeridx) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - timer_del(cpu->gt_timer[timeridx]); -} - -static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_get_countervalue(env); -} - -static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_get_countervalue(env) - env->cp15.cntvoff_el2; -} - -static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, - int timeridx, - uint64_t value) -{ - env->cp15.c14_timer[timeridx].cval = value; - gt_recalc_timer(arm_env_get_cpu(env), timeridx); -} - -static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri, - int timeridx) -{ - uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0; - - return (uint32_t)(env->cp15.c14_timer[timeridx].cval - - (gt_get_countervalue(env) - offset)); -} - -static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, - int timeridx, - uint64_t value) -{ - uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0; - - env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset + - sextract64(value, 0, 32); - gt_recalc_timer(arm_env_get_cpu(env), timeridx); -} - -static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, - int timeridx, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - uint32_t oldval = env->cp15.c14_timer[timeridx].ctl; - - env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value); - if ((oldval ^ value) & 1) { - /* Enable toggled */ - gt_recalc_timer(cpu, timeridx); - } else if ((oldval ^ value) & 2) { - /* IMASK toggled: don't need to recalculate, - * just set the interrupt line based on ISTATUS - */ - qemu_set_irq(cpu->gt_timer_outputs[timeridx], - (oldval & 4) && !(value & 2)); - } -} - -static void gt_phys_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) -{ - gt_timer_reset(env, ri, GTIMER_PHYS); -} - -static void gt_phys_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_cval_write(env, ri, GTIMER_PHYS, value); -} - -static uint64_t gt_phys_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_tval_read(env, ri, GTIMER_PHYS); -} - -static void gt_phys_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_tval_write(env, ri, GTIMER_PHYS, value); -} - -static void gt_phys_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_ctl_write(env, ri, GTIMER_PHYS, value); -} - -static void gt_virt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) -{ - gt_timer_reset(env, ri, GTIMER_VIRT); -} - -static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_cval_write(env, ri, GTIMER_VIRT, value); -} - -static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_tval_read(env, ri, GTIMER_VIRT); -} - -static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_tval_write(env, ri, GTIMER_VIRT, value); -} - -static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_ctl_write(env, ri, GTIMER_VIRT, value); -} - -static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - raw_write(env, ri, value); - gt_recalc_timer(cpu, GTIMER_VIRT); -} - -static void gt_hyp_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) -{ - gt_timer_reset(env, ri, GTIMER_HYP); -} - -static void gt_hyp_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_cval_write(env, ri, GTIMER_HYP, value); -} - -static uint64_t gt_hyp_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_tval_read(env, ri, GTIMER_HYP); -} - -static void gt_hyp_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_tval_write(env, ri, GTIMER_HYP, value); -} - -static void gt_hyp_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_ctl_write(env, ri, GTIMER_HYP, value); -} - -static void gt_sec_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri) -{ - gt_timer_reset(env, ri, GTIMER_SEC); -} - -static void gt_sec_cval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_cval_write(env, ri, GTIMER_SEC, value); -} - -static uint64_t gt_sec_tval_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return gt_tval_read(env, ri, GTIMER_SEC); -} - -static void gt_sec_tval_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_tval_write(env, ri, GTIMER_SEC, value); -} - -static void gt_sec_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - gt_ctl_write(env, ri, GTIMER_SEC, value); -} - -void arm_gt_ptimer_cb(void *opaque) -{ - ARMCPU *cpu = opaque; - - gt_recalc_timer(cpu, GTIMER_PHYS); -} - -void arm_gt_vtimer_cb(void *opaque) -{ - ARMCPU *cpu = opaque; - - gt_recalc_timer(cpu, GTIMER_VIRT); -} - -void arm_gt_htimer_cb(void *opaque) -{ - ARMCPU *cpu = opaque; - - gt_recalc_timer(cpu, GTIMER_HYP); -} - -void arm_gt_stimer_cb(void *opaque) -{ - ARMCPU *cpu = opaque; - - gt_recalc_timer(cpu, GTIMER_SEC); -} - -static const ARMCPRegInfo generic_timer_cp_reginfo[] = { - /* Note that CNTFRQ is purely reads-as-written for the benefit - * of software; writing it doesn't actually change the timer frequency. - * Our reset value matches the fixed frequency we implement the timer at. - */ - { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0, - .type = ARM_CP_ALIAS, - .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, - .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq), - }, - { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0, - .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, - .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq), - .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE, - }, - /* overall control: mostly access permissions */ - { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl), - .resetvalue = 0, - }, - /* per-timer control */ - { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1, - .secure = ARM_CP_SECSTATE_NS, - .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, - .accessfn = gt_ptimer_access, - .fieldoffset = offsetoflow32(CPUARMState, - cp15.c14_timer[GTIMER_PHYS].ctl), - .writefn = gt_phys_ctl_write, .raw_writefn = raw_write, - }, - { .name = "CNTP_CTL(S)", - .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1, - .secure = ARM_CP_SECSTATE_S, - .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, - .accessfn = gt_ptimer_access, - .fieldoffset = offsetoflow32(CPUARMState, - cp15.c14_timer[GTIMER_SEC].ctl), - .writefn = gt_sec_ctl_write, .raw_writefn = raw_write, - }, - { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1, - .type = ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_ptimer_access, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl), - .resetvalue = 0, - .writefn = gt_phys_ctl_write, .raw_writefn = raw_write, - }, - { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1, - .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, - .accessfn = gt_vtimer_access, - .fieldoffset = offsetoflow32(CPUARMState, - cp15.c14_timer[GTIMER_VIRT].ctl), - .writefn = gt_virt_ctl_write, .raw_writefn = raw_write, - }, - { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1, - .type = ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_vtimer_access, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl), - .resetvalue = 0, - .writefn = gt_virt_ctl_write, .raw_writefn = raw_write, - }, - /* TimerValue views: a 32 bit downcounting view of the underlying state */ - { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0, - .secure = ARM_CP_SECSTATE_NS, - .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_ptimer_access, - .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write, - }, - { .name = "CNTP_TVAL(S)", - .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0, - .secure = ARM_CP_SECSTATE_S, - .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_ptimer_access, - .readfn = gt_sec_tval_read, .writefn = gt_sec_tval_write, - }, - { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0, - .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_ptimer_access, .resetfn = gt_phys_timer_reset, - .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write, - }, - { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0, - .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_vtimer_access, - .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write, - }, - { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0, - .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, - .accessfn = gt_vtimer_access, .resetfn = gt_virt_timer_reset, - .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write, - }, - /* The counter itself */ - { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, - .accessfn = gt_pct_access, - .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore, - }, - { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1, - .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, - .accessfn = gt_pct_access, .readfn = gt_cnt_read, - }, - { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1, - .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, - .accessfn = gt_vct_access, - .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore, - }, - { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2, - .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, - .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read, - }, - /* Comparison value, indicating when the timer goes off */ - { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2, - .secure = ARM_CP_SECSTATE_NS, - .access = PL1_RW | PL0_R, - .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), - .accessfn = gt_ptimer_access, - .writefn = gt_phys_cval_write, .raw_writefn = raw_write, - }, - { .name = "CNTP_CVAL(S)", .cp = 15, .crm = 14, .opc1 = 2, - .secure = ARM_CP_SECSTATE_S, - .access = PL1_RW | PL0_R, - .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), - .accessfn = gt_ptimer_access, - .writefn = gt_sec_cval_write, .raw_writefn = raw_write, - }, - { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2, - .access = PL1_RW | PL0_R, - .type = ARM_CP_IO, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), - .resetvalue = 0, .accessfn = gt_ptimer_access, - .writefn = gt_phys_cval_write, .raw_writefn = raw_write, - }, - { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3, - .access = PL1_RW | PL0_R, - .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), - .accessfn = gt_vtimer_access, - .writefn = gt_virt_cval_write, .raw_writefn = raw_write, - }, - { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2, - .access = PL1_RW | PL0_R, - .type = ARM_CP_IO, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), - .resetvalue = 0, .accessfn = gt_vtimer_access, - .writefn = gt_virt_cval_write, .raw_writefn = raw_write, - }, - /* Secure timer -- this is actually restricted to only EL3 - * and configurably Secure-EL1 via the accessfn. - */ - { .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 0, - .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW, - .accessfn = gt_stimer_access, - .readfn = gt_sec_tval_read, - .writefn = gt_sec_tval_write, - .resetfn = gt_sec_timer_reset, - }, - { .name = "CNTPS_CTL_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 1, - .type = ARM_CP_IO, .access = PL1_RW, - .accessfn = gt_stimer_access, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl), - .resetvalue = 0, - .writefn = gt_sec_ctl_write, .raw_writefn = raw_write, - }, - { .name = "CNTPS_CVAL_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 2, - .type = ARM_CP_IO, .access = PL1_RW, - .accessfn = gt_stimer_access, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval), - .writefn = gt_sec_cval_write, .raw_writefn = raw_write, - }, - REGINFO_SENTINEL -}; - -#else -/* In user-mode none of the generic timer registers are accessible, - * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs, - * so instead just don't register any of them. - */ -static const ARMCPRegInfo generic_timer_cp_reginfo[] = { - REGINFO_SENTINEL -}; - -#endif - -static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) -{ - if (arm_feature(env, ARM_FEATURE_LPAE)) { - raw_write(env, ri, value); - } else if (arm_feature(env, ARM_FEATURE_V7)) { - raw_write(env, ri, value & 0xfffff6ff); - } else { - raw_write(env, ri, value & 0xfffff1ff); - } -} - -#ifndef CONFIG_USER_ONLY -/* get_phys_addr() isn't present for user-mode-only targets */ - -static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - if (ri->opc2 & 4) { - /* The ATS12NSO* operations must trap to EL3 if executed in - * Secure EL1 (which can only happen if EL3 is AArch64). - * They are simply UNDEF if executed from NS EL1. - * They function normally from EL2 or EL3. - */ - if (arm_current_el(env) == 1) { - if (arm_is_secure_below_el3(env)) { - return CP_ACCESS_TRAP_UNCATEGORIZED_EL3; - } - return CP_ACCESS_TRAP_UNCATEGORIZED; - } - } - return CP_ACCESS_OK; -} - -static uint64_t do_ats_write(CPUARMState *env, uint64_t value, - int access_type, ARMMMUIdx mmu_idx) -{ - hwaddr phys_addr; - target_ulong page_size; - int prot; - uint32_t fsr; - bool ret; - uint64_t par64; - MemTxAttrs attrs = {}; - ARMMMUFaultInfo fi = {}; - - ret = get_phys_addr(env, value, access_type, mmu_idx, - &phys_addr, &attrs, &prot, &page_size, &fsr, &fi); - if (extended_addresses_enabled(env)) { - /* fsr is a DFSR/IFSR value for the long descriptor - * translation table format, but with WnR always clear. - * Convert it to a 64-bit PAR. - */ - par64 = (1 << 11); /* LPAE bit always set */ - if (!ret) { - par64 |= phys_addr & ~0xfffULL; - if (!attrs.secure) { - par64 |= (1 << 9); /* NS */ - } - /* We don't set the ATTR or SH fields in the PAR. */ - } else { - par64 |= 1; /* F */ - par64 |= (fsr & 0x3f) << 1; /* FS */ - /* Note that S2WLK and FSTAGE are always zero, because we don't - * implement virtualization and therefore there can't be a stage 2 - * fault. - */ - } - } else { - /* fsr is a DFSR/IFSR value for the short descriptor - * translation table format (with WnR always clear). - * Convert it to a 32-bit PAR. - */ - if (!ret) { - /* We do not set any attribute bits in the PAR */ - if (page_size == (1 << 24) - && arm_feature(env, ARM_FEATURE_V7)) { - par64 = (phys_addr & 0xff000000) | (1 << 1); - } else { - par64 = phys_addr & 0xfffff000; - } - if (!attrs.secure) { - par64 |= (1 << 9); /* NS */ - } - } else { - par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) | - ((fsr & 0xf) << 1) | 1; - } - } - return par64; -} - -static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) -{ - int access_type = ri->opc2 & 1; - uint64_t par64; - ARMMMUIdx mmu_idx; - int el = arm_current_el(env); - bool secure = arm_is_secure_below_el3(env); - - switch (ri->opc2 & 6) { - case 0: - /* stage 1 current state PL1: ATS1CPR, ATS1CPW */ - switch (el) { - case 3: - mmu_idx = ARMMMUIdx_S1E3; - break; - case 2: - mmu_idx = ARMMMUIdx_S1NSE1; - break; - case 1: - mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S1NSE1; - break; - default: - g_assert_not_reached(); - } - break; - case 2: - /* stage 1 current state PL0: ATS1CUR, ATS1CUW */ - switch (el) { - case 3: - mmu_idx = ARMMMUIdx_S1SE0; - break; - case 2: - mmu_idx = ARMMMUIdx_S1NSE0; - break; - case 1: - mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S1NSE0; - break; - default: - g_assert_not_reached(); - } - break; - case 4: - /* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */ - mmu_idx = ARMMMUIdx_S12NSE1; - break; - case 6: - /* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */ - mmu_idx = ARMMMUIdx_S12NSE0; - break; - default: - g_assert_not_reached(); - } - - par64 = do_ats_write(env, value, access_type, mmu_idx); - - A32_BANKED_CURRENT_REG_SET(env, par, par64); -} - -static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - int access_type = ri->opc2 & 1; - uint64_t par64; - - par64 = do_ats_write(env, value, access_type, ARMMMUIdx_S2NS); - - A32_BANKED_CURRENT_REG_SET(env, par, par64); -} - -static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - int access_type = ri->opc2 & 1; - ARMMMUIdx mmu_idx; - int secure = arm_is_secure_below_el3(env); - - switch (ri->opc2 & 6) { - case 0: - switch (ri->opc1) { - case 0: /* AT S1E1R, AT S1E1W */ - mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S1NSE1; - break; - case 4: /* AT S1E2R, AT S1E2W */ - mmu_idx = ARMMMUIdx_S1E2; - break; - case 6: /* AT S1E3R, AT S1E3W */ - mmu_idx = ARMMMUIdx_S1E3; - break; - default: - g_assert_not_reached(); - } - break; - case 2: /* AT S1E0R, AT S1E0W */ - mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S1NSE0; - break; - case 4: /* AT S12E1R, AT S12E1W */ - mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S12NSE1; - break; - case 6: /* AT S12E0R, AT S12E0W */ - mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S12NSE0; - break; - default: - g_assert_not_reached(); - } - - env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx); -} -#endif - -static const ARMCPRegInfo vapa_cp_reginfo[] = { - { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s), - offsetoflow32(CPUARMState, cp15.par_ns) }, - .writefn = par_write }, -#ifndef CONFIG_USER_ONLY - /* This underdecoding is safe because the reginfo is NO_RAW. */ - { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_W, .accessfn = ats_access, - .writefn = ats_write, .type = ARM_CP_NO_RAW }, -#endif - REGINFO_SENTINEL -}; - -/* Return basic MPU access permission bits. */ -static uint32_t simple_mpu_ap_bits(uint32_t val) -{ - uint32_t ret; - uint32_t mask; - int i; - ret = 0; - mask = 3; - for (i = 0; i < 16; i += 2) { - ret |= (val >> i) & mask; - mask <<= 2; - } - return ret; -} - -/* Pad basic MPU access permission bits to extended format. */ -static uint32_t extended_mpu_ap_bits(uint32_t val) -{ - uint32_t ret; - uint32_t mask; - int i; - ret = 0; - mask = 3; - for (i = 0; i < 16; i += 2) { - ret |= (val & mask) << i; - mask <<= 2; - } - return ret; -} - -static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.pmsav5_data_ap = extended_mpu_ap_bits(value); -} - -static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return simple_mpu_ap_bits(env->cp15.pmsav5_data_ap); -} - -static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.pmsav5_insn_ap = extended_mpu_ap_bits(value); -} - -static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return simple_mpu_ap_bits(env->cp15.pmsav5_insn_ap); -} - -static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); - - if (!u32p) { - return 0; - } - - u32p += env->cp15.c6_rgnr; - return *u32p; -} - -static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); - - if (!u32p) { - return; - } - - u32p += env->cp15.c6_rgnr; - tlb_flush(CPU(cpu), 1); /* Mappings may have changed - purge! */ - *u32p = value; -} - -static void pmsav7_reset(CPUARMState *env, const ARMCPRegInfo *ri) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri); - - if (!u32p) { - return; - } - - memset(u32p, 0, sizeof(*u32p) * cpu->pmsav7_dregion); -} - -static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - uint32_t nrgs = cpu->pmsav7_dregion; - - if (value >= nrgs) { - qemu_log_mask(LOG_GUEST_ERROR, - "PMSAv7 RGNR write >= # supported regions, %" PRIu32 - " > %" PRIu32 "\n", (uint32_t)value, nrgs); - return; - } - - raw_write(env, ri, value); -} - -static const ARMCPRegInfo pmsav7_cp_reginfo[] = { - { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_NO_RAW, - .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, - { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2, - .access = PL1_RW, .type = ARM_CP_NO_RAW, - .fieldoffset = offsetof(CPUARMState, pmsav7.drsr), - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, - { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4, - .access = PL1_RW, .type = ARM_CP_NO_RAW, - .fieldoffset = offsetof(CPUARMState, pmsav7.dracr), - .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset }, - { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c6_rgnr), - .writefn = pmsav7_rgnr_write }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo pmsav5_cp_reginfo[] = { - { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), - .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, }, - { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), - .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, }, - { .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), - .resetvalue = 0, }, - { .name = "INSN_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 3, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), - .resetvalue = 0, }, - { .name = "DCACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c2_data), .resetvalue = 0, }, - { .name = "ICACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, }, - /* Protection region base and size registers */ - { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) }, - { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) }, - { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) }, - { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) }, - { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) }, - { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) }, - { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) }, - { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0, - .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) }, - REGINFO_SENTINEL -}; - -static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - TCR *tcr = raw_ptr(env, ri); - int maskshift = extract32(value, 0, 3); - - if (!arm_feature(env, ARM_FEATURE_V8)) { - if (arm_feature(env, ARM_FEATURE_LPAE) && (value & TTBCR_EAE)) { - /* Pre ARMv8 bits [21:19], [15:14] and [6:3] are UNK/SBZP when - * using Long-desciptor translation table format */ - value &= ~((7 << 19) | (3 << 14) | (0xf << 3)); - } else if (arm_feature(env, ARM_FEATURE_EL3)) { - /* In an implementation that includes the Security Extensions - * TTBCR has additional fields PD0 [4] and PD1 [5] for - * Short-descriptor translation table format. - */ - value &= TTBCR_PD1 | TTBCR_PD0 | TTBCR_N; - } else { - value &= TTBCR_N; - } - } - - /* Update the masks corresponding to the TCR bank being written - * Note that we always calculate mask and base_mask, but - * they are only used for short-descriptor tables (ie if EAE is 0); - * for long-descriptor tables the TCR fields are used differently - * and the mask and base_mask values are meaningless. - */ - tcr->raw_tcr = value; - tcr->mask = ~(((uint32_t)0xffffffffu) >> maskshift); - tcr->base_mask = ~((uint32_t)0x3fffu >> maskshift); -} - -static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - if (arm_feature(env, ARM_FEATURE_LPAE)) { - /* With LPAE the TTBCR could result in a change of ASID - * via the TTBCR.A1 bit, so do a TLB flush. - */ - tlb_flush(CPU(cpu), 1); - } - vmsa_ttbcr_raw_write(env, ri, value); -} - -static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri) -{ - TCR *tcr = raw_ptr(env, ri); - - /* Reset both the TCR as well as the masks corresponding to the bank of - * the TCR being reset. - */ - tcr->raw_tcr = 0; - tcr->mask = 0; - tcr->base_mask = 0xffffc000u; -} - -static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - TCR *tcr = raw_ptr(env, ri); - - /* For AArch64 the A1 bit could result in a change of ASID, so TLB flush. */ - tlb_flush(CPU(cpu), 1); - tcr->raw_tcr = value; -} - -static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* 64 bit accesses to the TTBRs can change the ASID and so we - * must flush the TLB. - */ - if (cpreg_field_is_64bit(ri)) { - ARMCPU *cpu = arm_env_get_cpu(env); - - tlb_flush(CPU(cpu), 1); - } - raw_write(env, ri, value); -} - -static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - - /* Accesses to VTTBR may change the VMID so we must flush the TLB. */ - if (raw_read(env, ri) != value) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, - ARMMMUIdx_S2NS, -1); - raw_write(env, ri, value); - } -} - -static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = { - { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_ALIAS, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s), - offsetoflow32(CPUARMState, cp15.dfsr_ns) }, }, - { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .resetvalue = 0, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s), - offsetoflow32(CPUARMState, cp15.ifsr_ns) } }, - { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s), - offsetof(CPUARMState, cp15.dfar_ns) } }, - { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]), - .resetvalue = 0, }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo vmsa_cp_reginfo[] = { - { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, }, - { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0, - .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), - offsetof(CPUARMState, cp15.ttbr0_ns) } }, - { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1, - .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), - offsetof(CPUARMState, cp15.ttbr1_ns) } }, - { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, .writefn = vmsa_tcr_el1_write, - .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, - .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) }, - { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write, - .raw_writefn = vmsa_ttbcr_raw_write, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]), - offsetoflow32(CPUARMState, cp15.tcr_el[1])} }, - REGINFO_SENTINEL -}; - -static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.c15_ticonfig = value & 0xe7; - /* The OS_TYPE bit in this register changes the reported CPUID! */ - env->cp15.c0_cpuid = (value & (1 << 5)) ? - ARM_CPUID_TI915T : ARM_CPUID_TI925T; -} - -static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.c15_threadid = value & 0xffff; -} - -static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Wait-for-interrupt (deprecated) */ - cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT); -} - -static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* On OMAP there are registers indicating the max/min index of dcache lines - * containing a dirty line; cache flush operations have to reset these. - */ - env->cp15.c15_i_max = 0x000; - env->cp15.c15_i_min = 0xff0; -} - -static const ARMCPRegInfo omap_cp_reginfo[] = { - { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE, - .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]), - .resetvalue = 0, }, - { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_NOP }, - { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0, - .writefn = omap_ticonfig_write }, - { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, }, - { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0xff0, - .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) }, - { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0, - .writefn = omap_threadid_write }, - { .name = "TI925T_STATUS", .cp = 15, .crn = 15, - .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW, - .type = ARM_CP_NO_RAW, - .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, }, - /* TODO: Peripheral port remap register: - * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller - * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff), - * when MMU is off. - */ - { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, - .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, - .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW, - .writefn = omap_cachemaint_write }, - { .name = "C9", .cp = 15, .crn = 9, - .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, - .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->cp15.c15_cpar = value & 0x3fff; -} - -static const ARMCPRegInfo xscale_cp_reginfo[] = { - { .name = "XSCALE_CPAR", - .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0, - .writefn = xscale_cpar_write, }, - { .name = "XSCALE_AUXCR", - .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr), - .resetvalue = 0, }, - /* XScale specific cache-lockdown: since we have no cache we NOP these - * and hope the guest does not really rely on cache behaviour. - */ - { .name = "XSCALE_LOCK_ICACHE_LINE", - .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "XSCALE_UNLOCK_ICACHE", - .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "XSCALE_DCACHE_LOCK", - .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_NOP }, - { .name = "XSCALE_UNLOCK_DCACHE", - .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NOP }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo dummy_c15_cp_reginfo[] = { - /* RAZ/WI the whole crn=15 space, when we don't have a more specific - * implementation of this implementation-defined space. - * Ideally this should eventually disappear in favour of actually - * implementing the correct behaviour for all cores. - */ - { .name = "C15_IMPDEF", .cp = 15, .crn = 15, - .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, - .access = PL1_RW, - .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE, - .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = { - /* Cache status: RAZ because we have no cache so it's always clean */ - { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6, - .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, - .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = { - /* We never have a a block transfer operation in progress */ - { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, - .resetvalue = 0 }, - /* The cache ops themselves: these all NOP for QEMU */ - { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0, - .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, - { .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0, - .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, - { .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0, - .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, - { .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1, - .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, - { .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2, - .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, - { .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0, - .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = { - /* The cache test-and-clean instructions always return (1 << 30) - * to indicate that there are no dirty cache lines. - */ - { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, - .resetvalue = (1 << 30) }, - { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3, - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, - .resetvalue = (1 << 30) }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo strongarm_cp_reginfo[] = { - /* Ignore ReadBuffer accesses */ - { .name = "C9_READBUFFER", .cp = 15, .crn = 9, - .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, - .access = PL1_RW, .resetvalue = 0, - .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW }, - REGINFO_SENTINEL -}; - -static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - unsigned int cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - - if (arm_feature(&cpu->env, ARM_FEATURE_EL2) && !secure && cur_el == 1) { - return env->cp15.vpidr_el2; - } - return raw_read(env, ri); -} - -static uint64_t mpidr_read_val(CPUARMState *env) -{ - ARMCPU *cpu = ARM_CPU(arm_env_get_cpu(env)); - uint64_t mpidr = cpu->mp_affinity; - - if (arm_feature(env, ARM_FEATURE_V7MP)) { - mpidr |= (1U << 31); - /* Cores which are uniprocessor (non-coherent) - * but still implement the MP extensions set - * bit 30. (For instance, Cortex-R5). - */ - if (cpu->mp_is_up) { - mpidr |= (1u << 30); - } - } - return mpidr; -} - -static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - unsigned int cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - - if (arm_feature(env, ARM_FEATURE_EL2) && !secure && cur_el == 1) { - return env->cp15.vmpidr_el2; - } - return mpidr_read_val(env); -} - -static const ARMCPRegInfo mpidr_cp_reginfo[] = { - { .name = "MPIDR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5, - .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo lpae_cp_reginfo[] = { - /* NOP AMAIR0/1 */ - { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - /* AMAIR1 is mapped to AMAIR_EL1[63:32] */ - { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1, - .access = PL1_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0, - .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s), - offsetof(CPUARMState, cp15.par_ns)} }, - { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0, - .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), - offsetof(CPUARMState, cp15.ttbr0_ns) }, - .writefn = vmsa_ttbr_write, }, - { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1, - .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), - offsetof(CPUARMState, cp15.ttbr1_ns) }, - .writefn = vmsa_ttbr_write, }, - REGINFO_SENTINEL -}; - -static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return vfp_get_fpcr(env); -} - -static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - vfp_set_fpcr(env, value); -} - -static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return vfp_get_fpsr(env); -} - -static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - vfp_set_fpsr(env, value); -} - -static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - env->daif = value & PSTATE_DAIF; -} - -static CPAccessResult aa64_cacheop_access(CPUARMState *env, - const ARMCPRegInfo *ri) -{ - /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless - * SCTLR_EL1.UCI is set. - */ - if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCI)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions - * Page D4-1736 (DDI0487A.b) - */ - -static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - - if (arm_is_secure_below_el3(env)) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); - } else { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); - } -} - -static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - bool sec = arm_is_secure_below_el3(env); - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - if (sec) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); - } else { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, - ARMMMUIdx_S12NSE0, -1); - } - } -} - -static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Note that the 'ALL' scope must invalidate both stage 1 and - * stage 2 translations, whereas most other scopes only invalidate - * stage 1 translations. - */ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - - if (arm_is_secure_below_el3(env)) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); - } else { - if (arm_feature(env, ARM_FEATURE_EL2)) { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, - ARMMMUIdx_S2NS, -1); - } else { - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, -1); - } - } -} - -static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E2, -1); -} - -static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - - tlb_flush_by_mmuidx(cs, ARMMMUIdx_S1E3, -1); -} - -static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Note that the 'ALL' scope must invalidate both stage 1 and - * stage 2 translations, whereas most other scopes only invalidate - * stage 1 translations. - */ - bool sec = arm_is_secure_below_el3(env); - bool has_el2 = arm_feature(env, ARM_FEATURE_EL2); - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - if (sec) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1SE1, ARMMMUIdx_S1SE0, -1); - } else if (has_el2) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, - ARMMMUIdx_S12NSE0, ARMMMUIdx_S2NS, -1); - } else { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S12NSE1, - ARMMMUIdx_S12NSE0, -1); - } - } -} - -static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E2, -1); - } -} - -static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - - CPU_FOREACH(other_cs) { - tlb_flush_by_mmuidx(other_cs, ARMMMUIdx_S1E3, -1); - } -} - -static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate by VA, EL1&0 (AArch64 version). - * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1, - * since we don't support flush-for-specific-ASID-only or - * flush-last-level-only. - */ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - uint64_t pageaddr = sextract64(value << 12, 0, 56); - - if (arm_is_secure_below_el3(env)) { - tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1SE1, - ARMMMUIdx_S1SE0, -1); - } else { - tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S12NSE1, - ARMMMUIdx_S12NSE0, -1); - } -} - -static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate by VA, EL2 - * Currently handles both VAE2 and VALE2, since we don't support - * flush-last-level-only. - */ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - uint64_t pageaddr = sextract64(value << 12, 0, 56); - - tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1E2, -1); -} - -static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate by VA, EL3 - * Currently handles both VAE3 and VALE3, since we don't support - * flush-last-level-only. - */ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - uint64_t pageaddr = sextract64(value << 12, 0, 56); - - tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S1E3, -1); -} - -static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - bool sec = arm_is_secure_below_el3(env); - CPUState *other_cs; - uint64_t pageaddr = sextract64(value << 12, 0, 56); - - CPU_FOREACH(other_cs) { - if (sec) { - tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1SE1, - ARMMMUIdx_S1SE0, -1); - } else { - tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S12NSE1, - ARMMMUIdx_S12NSE0, -1); - } - } -} - -static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - uint64_t pageaddr = sextract64(value << 12, 0, 56); - - CPU_FOREACH(other_cs) { - tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E2, -1); - } -} - -static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - uint64_t pageaddr = sextract64(value << 12, 0, 56); - - CPU_FOREACH(other_cs) { - tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S1E3, -1); - } -} - -static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Invalidate by IPA. This has to invalidate any structures that - * contain only stage 2 translation information, but does not need - * to apply to structures that contain combined stage 1 and stage 2 - * translation information. - * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero. - */ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - uint64_t pageaddr; - - if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { - return; - } - - pageaddr = sextract64(value << 12, 0, 48); - - tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdx_S2NS, -1); -} - -static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - CPUState *other_cs; - uint64_t pageaddr; - - if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) { - return; - } - - pageaddr = sextract64(value << 12, 0, 48); - - CPU_FOREACH(other_cs) { - tlb_flush_page_by_mmuidx(other_cs, pageaddr, ARMMMUIdx_S2NS, -1); - } -} - -static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* We don't implement EL2, so the only control on DC ZVA is the - * bit in the SCTLR which can prohibit access for EL0. - */ - if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_DZE)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int dzp_bit = 1 << 4; - - /* DZP indicates whether DC ZVA access is allowed */ - if (aa64_zva_access(env, NULL) == CP_ACCESS_OK) { - dzp_bit = 0; - } - return cpu->dcz_blocksize | dzp_bit; -} - -static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - if (!(env->pstate & PSTATE_SP)) { - /* Access to SP_EL0 is undefined if it's being used as - * the stack pointer. - */ - return CP_ACCESS_TRAP_UNCATEGORIZED; - } - return CP_ACCESS_OK; -} - -static uint64_t spsel_read(CPUARMState *env, const ARMCPRegInfo *ri) -{ - return env->pstate & PSTATE_SP; -} - -static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val) -{ - update_spsel(env, val); -} - -static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - if (raw_read(env, ri) == value) { - /* Skip the TLB flush if nothing actually changed; Linux likes - * to do a lot of pointless SCTLR writes. - */ - return; - } - - raw_write(env, ri, value); - /* ??? Lots of these bits are not implemented. */ - /* This may enable/disable the MMU, so do a TLB flush. */ - tlb_flush(CPU(cpu), 1); -} - -static const ARMCPRegInfo v8_cp_reginfo[] = { - /* Minimal set of EL0-visible registers. This will need to be expanded - * significantly for system emulation of AArch64 CPUs. - */ - { .name = "NZCV", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2, - .access = PL0_RW, .type = ARM_CP_NZCV }, - { .name = "DAIF", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2, - .type = ARM_CP_NO_RAW, - .access = PL0_RW, .accessfn = aa64_daif_access, - .fieldoffset = offsetof(CPUARMState, daif), - .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore }, - { .name = "FPCR", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4, - .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write }, - { .name = "FPSR", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4, - .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write }, - { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0, - .access = PL0_R, .type = ARM_CP_NO_RAW, - .readfn = aa64_dczid_read }, - { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1, - .access = PL0_W, .type = ARM_CP_DC_ZVA, -#ifndef CONFIG_USER_ONLY - /* Avoid overhead of an access check that always passes in user-mode */ - .accessfn = aa64_zva_access, -#endif - }, - { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2, - .access = PL1_R, .type = ARM_CP_CURRENTEL }, - /* Cache ops: all NOPs since we don't emulate caches */ - { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1, - .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_access }, - { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "DC_ISW", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1, - .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_access }, - { .name = "DC_CSW", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NOP }, - { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1, - .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_access }, - { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1, - .access = PL0_W, .type = ARM_CP_NOP, - .accessfn = aa64_cacheop_access }, - { .name = "DC_CISW", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NOP }, - /* TLBI operations */ - { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vmalle1is_write }, - { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1is_write }, - { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vmalle1is_write }, - { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1is_write }, - { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1is_write }, - { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1is_write }, - { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vmalle1_write }, - { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1_write }, - { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vmalle1_write }, - { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1_write }, - { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1_write }, - { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae1_write }, - { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_ipas2e1is_write }, - { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_ipas2e1is_write }, - { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle1is_write }, - { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle1is_write }, - { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_ipas2e1_write }, - { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_ipas2e1_write }, - { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle1_write }, - { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle1is_write }, -#ifndef CONFIG_USER_ONLY - /* 64 bit address translation operations */ - { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7, - .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - /* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */ - { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0, - .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1, - .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.par_el[1]), - .writefn = par_write }, -#endif - /* TLB invalidate last level of translation table walk */ - { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write }, - { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, - .type = ARM_CP_NO_RAW, .access = PL1_W, - .writefn = tlbimvaa_is_write }, - { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, - { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, - .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, - /* 32 bit cache operations */ - { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL1_W }, - { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2, - .type = ARM_CP_NOP, .access = PL1_W }, - /* MMU Domain access control / MPU write buffer control */ - { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0, - .access = PL1_RW, .resetvalue = 0, - .writefn = dacr_write, .raw_writefn = raw_write, - .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), - offsetoflow32(CPUARMState, cp15.dacr_ns) } }, - { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, elr_el[1]) }, - { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) }, - /* We rely on the access checks not allowing the guest to write to the - * state field when SPSel indicates that it's being used as the stack - * pointer. - */ - { .name = "SP_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0, - .access = PL1_RW, .accessfn = sp_el0_access, - .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, sp_el[0]) }, - { .name = "SP_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, sp_el[1]) }, - { .name = "SPSel", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0, - .type = ARM_CP_NO_RAW, - .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write }, - REGINFO_SENTINEL -}; - -/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */ -static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = { - { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, - .access = PL2_RW, - .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, - { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_NO_RAW, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, - .access = PL2_RW, - .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, - { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, - .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, - .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, - .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "VTTBR", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 6, .crm = 2, - .access = PL2_RW, .accessfn = access_el3_aa32ns, - .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, - { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, - .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14, - .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14, - .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, - .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, - .type = ARM_CP_CONST, .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - uint64_t valid_mask = HCR_MASK; - - if (arm_feature(env, ARM_FEATURE_EL3)) { - valid_mask &= ~HCR_HCD; - } else { - valid_mask &= ~HCR_TSC; - } - - /* Clear RES0 bits. */ - value &= valid_mask; - - /* These bits change the MMU setup: - * HCR_VM enables stage 2 translation - * HCR_PTW forbids certain page-table setups - * HCR_DC Disables stage1 and enables stage2 translation - */ - if ((raw_read(env, ri) ^ value) & (HCR_VM | HCR_PTW | HCR_DC)) { - tlb_flush(CPU(cpu), 1); - } - raw_write(env, ri, value); -} - -static const ARMCPRegInfo el2_cp_reginfo[] = { - { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, - .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2), - .writefn = hcr_write }, - { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0, - .access = PL2_RW, .resetvalue = 0, - .writefn = dacr_write, .raw_writefn = raw_write, - .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) }, - { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, elr_el[2]) }, - { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0, - .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) }, - { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1, - .access = PL2_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) }, - { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0, - .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) }, - { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) }, - { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) }, - { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) }, - { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) }, - { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) }, - { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, - .access = PL2_RW, .writefn = vbar_write, - .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]), - .resetvalue = 0 }, - { .name = "SP_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 1, .opc2 = 0, - .access = PL3_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, sp_el[2]) }, - { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2, - .access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]) }, - { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0, - .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]), - .resetvalue = 0 }, - { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, - .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) }, - { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - /* HAMAIR1 is mapped to AMAIR_EL2[63:32] */ - { .name = "HMAIR1", .state = ARM_CP_STATE_AA32, - .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2, - .access = PL2_RW, .writefn = vmsa_tcr_el1_write, - .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, - .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) }, - { .name = "VTCR", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, - .access = PL2_RW, .accessfn = access_el3_aa32ns, - .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, - { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, - .access = PL2_RW, .type = ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, - { .name = "VTTBR", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 6, .crm = 2, - .type = ARM_CP_64BIT | ARM_CP_ALIAS, - .access = PL2_RW, .accessfn = access_el3_aa32ns, - .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2), - .writefn = vttbr_write }, - { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, - .access = PL2_RW, .writefn = vttbr_write, - .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) }, - { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, - .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write, - .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) }, - { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2, - .access = PL2_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) }, - { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, - .access = PL2_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, - { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, - .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, - .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, - { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, - .type = ARM_CP_NO_RAW, .access = PL2_W, - .writefn = tlbi_aa64_alle2_write }, - { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, - .type = ARM_CP_NO_RAW, .access = PL2_W, - .writefn = tlbi_aa64_vae2_write }, - { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae2_write }, - { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle2is_write }, - { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, - .type = ARM_CP_NO_RAW, .access = PL2_W, - .writefn = tlbi_aa64_vae2is_write }, - { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae2is_write }, -#ifndef CONFIG_USER_ONLY - /* Unlike the other EL2-related AT operations, these must - * UNDEF from EL3 if EL2 is not implemented, which is why we - * define them here rather than with the rest of the AT ops. - */ - { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, - .access = PL2_W, .accessfn = at_s1e2_access, - .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, - .access = PL2_W, .accessfn = at_s1e2_access, - .type = ARM_CP_NO_RAW, .writefn = ats_write64 }, - /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE - * if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3 - * with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose - * to behave as if SCR.NS was 1. - */ - { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, - .access = PL2_W, - .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, - { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, - .access = PL2_W, - .writefn = ats1h_write, .type = ARM_CP_NO_RAW }, - { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0, - /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the - * reset values as IMPDEF. We choose to reset to 3 to comply with - * both ARMv7 and ARMv8. - */ - .access = PL2_RW, .resetvalue = 3, - .fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) }, - { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3, - .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0, - .writefn = gt_cntvoff_write, - .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) }, - { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14, - .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO, - .writefn = gt_cntvoff_write, - .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) }, - { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), - .type = ARM_CP_IO, .access = PL2_RW, - .writefn = gt_hyp_cval_write, .raw_writefn = raw_write }, - { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval), - .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_IO, - .writefn = gt_hyp_cval_write, .raw_writefn = raw_write }, - { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0, - .type = ARM_CP_IO, .access = PL2_RW, - .resetfn = gt_hyp_timer_reset, - .readfn = gt_hyp_tval_read, .writefn = gt_hyp_tval_write }, - { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH, - .type = ARM_CP_IO, - .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl), - .resetvalue = 0, - .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write }, -#endif - /* The only field of MDCR_EL2 that has a defined architectural reset value - * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we - * don't impelment any PMU event counters, so using zero as a reset - * value for MDCR_EL2 is okay - */ - { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, - .access = PL2_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), }, - { .name = "HPFAR", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, - .access = PL2_RW, .accessfn = access_el3_aa32ns, - .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) }, - { .name = "HPFAR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, - .access = PL2_RW, - .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo el3_cp_reginfo[] = { - { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0, - .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3), - .resetvalue = 0, .writefn = scr_write }, - { .name = "SCR", .type = ARM_CP_ALIAS, - .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0, - .access = PL3_RW, .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3), - .writefn = scr_write }, - { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1, - .access = PL3_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.sder) }, - { .name = "SDER", - .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1, - .access = PL3_RW, .resetvalue = 0, - .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) }, - /* TODO: Implement NSACR trapping of secure EL1 accesses to EL3 */ - { .name = "NSACR", .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2, - .access = PL3_W | PL1_R, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.nsacr) }, - { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, - .access = PL3_RW, .writefn = vbar_write, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.mvbar) }, - { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, /* reset handled by AArch32 view */ - .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0, - .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write, - .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]) }, - { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0, - .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) }, - { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2, - .access = PL3_RW, .writefn = vmsa_tcr_el1_write, - .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, - .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) }, - { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1, - .access = PL3_RW, - .fieldoffset = offsetof(CPUARMState, elr_el[3]) }, - { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0, - .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) }, - { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0, - .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) }, - { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_ALIAS, - .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0, - .access = PL3_RW, - .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) }, - { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0, - .access = PL3_RW, .writefn = vbar_write, - .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]), - .resetvalue = 0 }, - { .name = "CPTR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 2, - .access = PL3_RW, .accessfn = cptr_access, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[3]) }, - { .name = "TPIDR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 2, - .access = PL3_RW, .resetvalue = 0, - .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[3]) }, - { .name = "AMAIR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 3, .opc2 = 0, - .access = PL3_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "AFSR0_EL3", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 0, - .access = PL3_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "AFSR1_EL3", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 1, - .access = PL3_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle3is_write }, - { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae3is_write }, - { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae3is_write }, - { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle3_write }, - { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae3_write }, - { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vae3_write }, - REGINFO_SENTINEL -}; - -static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64, - * but the AArch32 CTR has its own reginfo struct) - */ - if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) { - return CP_ACCESS_TRAP; - } - return CP_ACCESS_OK; -} - -static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Writes to OSLAR_EL1 may update the OS lock status, which can be - * read via a bit in OSLSR_EL1. - */ - int oslock; - - if (ri->state == ARM_CP_STATE_AA32) { - oslock = (value == 0xC5ACCE55); - } else { - oslock = value & 1; - } - - env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock); -} - -static const ARMCPRegInfo debug_cp_reginfo[] = { - /* DBGDRAR, DBGDSAR: always RAZ since we don't implement memory mapped - * debug components. The AArch64 version of DBGDRAR is named MDRAR_EL1; - * unlike DBGDRAR it is never accessible from EL0. - * DBGDSAR is deprecated and must RAZ from v8 anyway, so it has no AArch64 - * accessor. - */ - { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - /* Monitor debug system control register; the 32-bit alias is DBGDSCRext. */ - { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), - .resetvalue = 0 }, - /* MDCCSR_EL0, aka DBGDSCRint. This is a read-only mirror of MDSCR_EL1. - * We don't implement the configurable EL0 access. - */ - { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, - .type = ARM_CP_ALIAS, - .access = PL1_R, - .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), }, - { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = oslar_write }, - { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4, - .access = PL1_R, .resetvalue = 10, - .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) }, - /* Dummy OSDLR_EL1: 32-bit Linux will read this */ - { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4, - .access = PL1_RW, .type = ARM_CP_NOP }, - /* Dummy DBGVCR: Linux wants to clear this on startup, but we don't - * implement vector catch debug events yet. - */ - { .name = "DBGVCR", - .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, - .access = PL1_RW, .type = ARM_CP_NOP }, - REGINFO_SENTINEL -}; - -static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { - /* 64 bit access versions of the (dummy) debug registers */ - { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, - { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0, - .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 }, - REGINFO_SENTINEL -}; - -void hw_watchpoint_update(ARMCPU *cpu, int n) -{ - CPUARMState *env = &cpu->env; - vaddr len = 0; - vaddr wvr = env->cp15.dbgwvr[n]; - uint64_t wcr = env->cp15.dbgwcr[n]; - int mask; - int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; - - if (env->cpu_watchpoint[n]) { - cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]); - env->cpu_watchpoint[n] = NULL; - } - - if (!extract64(wcr, 0, 1)) { - /* E bit clear : watchpoint disabled */ - return; - } - - switch (extract64(wcr, 3, 2)) { - case 0: - /* LSC 00 is reserved and must behave as if the wp is disabled */ - return; - case 1: - flags |= BP_MEM_READ; - break; - case 2: - flags |= BP_MEM_WRITE; - break; - case 3: - flags |= BP_MEM_ACCESS; - break; - } - - /* Attempts to use both MASK and BAS fields simultaneously are - * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, - * thus generating a watchpoint for every byte in the masked region. - */ - mask = extract64(wcr, 24, 4); - if (mask == 1 || mask == 2) { - /* Reserved values of MASK; we must act as if the mask value was - * some non-reserved value, or as if the watchpoint were disabled. - * We choose the latter. - */ - return; - } else if (mask) { - /* Watchpoint covers an aligned area up to 2GB in size */ - len = 1ULL << mask; - /* If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE - * whether the watchpoint fires when the unmasked bits match; we opt - * to generate the exceptions. - */ - wvr &= ~(len - 1); - } else { - /* Watchpoint covers bytes defined by the byte address select bits */ - int bas = extract64(wcr, 5, 8); - int basstart; - - if (bas == 0) { - /* This must act as if the watchpoint is disabled */ - return; - } - - if (extract64(wvr, 2, 1)) { - /* Deprecated case of an only 4-aligned address. BAS[7:4] are - * ignored, and BAS[3:0] define which bytes to watch. - */ - bas &= 0xf; - } - /* The BAS bits are supposed to be programmed to indicate a contiguous - * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether - * we fire for each byte in the word/doubleword addressed by the WVR. - * We choose to ignore any non-zero bits after the first range of 1s. - */ - basstart = ctz32(bas); - len = cto32(bas >> basstart); - wvr += basstart; - } - - cpu_watchpoint_insert(CPU(cpu), wvr, len, flags, - &env->cpu_watchpoint[n]); -} - -void hw_watchpoint_update_all(ARMCPU *cpu) -{ - int i; - CPUARMState *env = &cpu->env; - - /* Completely clear out existing QEMU watchpoints and our array, to - * avoid possible stale entries following migration load. - */ - cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); - memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint)); - - for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) { - hw_watchpoint_update(cpu, i); - } -} - -static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int i = ri->crm; - - /* Bits [63:49] are hardwired to the value of bit [48]; that is, the - * register reads and behaves as if values written are sign extended. - * Bits [1:0] are RES0. - */ - value = sextract64(value, 0, 49) & ~3ULL; - - raw_write(env, ri, value); - hw_watchpoint_update(cpu, i); -} - -static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int i = ri->crm; - - raw_write(env, ri, value); - hw_watchpoint_update(cpu, i); -} - -void hw_breakpoint_update(ARMCPU *cpu, int n) -{ - CPUARMState *env = &cpu->env; - uint64_t bvr = env->cp15.dbgbvr[n]; - uint64_t bcr = env->cp15.dbgbcr[n]; - vaddr addr; - int bt; - int flags = BP_CPU; - - if (env->cpu_breakpoint[n]) { - cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]); - env->cpu_breakpoint[n] = NULL; - } - - if (!extract64(bcr, 0, 1)) { - /* E bit clear : watchpoint disabled */ - return; - } - - bt = extract64(bcr, 20, 4); - - switch (bt) { - case 4: /* unlinked address mismatch (reserved if AArch64) */ - case 5: /* linked address mismatch (reserved if AArch64) */ - qemu_log_mask(LOG_UNIMP, - "arm: address mismatch breakpoint types not implemented"); - return; - case 0: /* unlinked address match */ - case 1: /* linked address match */ - { - /* Bits [63:49] are hardwired to the value of bit [48]; that is, - * we behave as if the register was sign extended. Bits [1:0] are - * RES0. The BAS field is used to allow setting breakpoints on 16 - * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether - * a bp will fire if the addresses covered by the bp and the addresses - * covered by the insn overlap but the insn doesn't start at the - * start of the bp address range. We choose to require the insn and - * the bp to have the same address. The constraints on writing to - * BAS enforced in dbgbcr_write mean we have only four cases: - * 0b0000 => no breakpoint - * 0b0011 => breakpoint on addr - * 0b1100 => breakpoint on addr + 2 - * 0b1111 => breakpoint on addr - * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). - */ - int bas = extract64(bcr, 5, 4); - addr = sextract64(bvr, 0, 49) & ~3ULL; - if (bas == 0) { - return; - } - if (bas == 0xc) { - addr += 2; - } - break; - } - case 2: /* unlinked context ID match */ - case 8: /* unlinked VMID match (reserved if no EL2) */ - case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ - qemu_log_mask(LOG_UNIMP, - "arm: unlinked context breakpoint types not implemented"); - return; - case 9: /* linked VMID match (reserved if no EL2) */ - case 11: /* linked context ID and VMID match (reserved if no EL2) */ - case 3: /* linked context ID match */ - default: - /* We must generate no events for Linked context matches (unless - * they are linked to by some other bp/wp, which is handled in - * updates for the linking bp/wp). We choose to also generate no events - * for reserved values. - */ - return; - } - - cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]); -} - -void hw_breakpoint_update_all(ARMCPU *cpu) -{ - int i; - CPUARMState *env = &cpu->env; - - /* Completely clear out existing QEMU breakpoints and our array, to - * avoid possible stale entries following migration load. - */ - cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); - memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint)); - - for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) { - hw_breakpoint_update(cpu, i); - } -} - -static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int i = ri->crm; - - raw_write(env, ri, value); - hw_breakpoint_update(cpu, i); -} - -static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int i = ri->crm; - - /* BAS[3] is a read-only copy of BAS[2], and BAS[1] a read-only - * copy of BAS[0]. - */ - value = deposit64(value, 6, 1, extract64(value, 5, 1)); - value = deposit64(value, 8, 1, extract64(value, 7, 1)); - - raw_write(env, ri, value); - hw_breakpoint_update(cpu, i); -} - -static void define_debug_regs(ARMCPU *cpu) -{ - /* Define v7 and v8 architectural debug registers. - * These are just dummy implementations for now. - */ - int i; - int wrps, brps, ctx_cmps; - ARMCPRegInfo dbgdidr = { - .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr, - }; - - /* Note that all these register fields hold "number of Xs minus 1". */ - brps = extract32(cpu->dbgdidr, 24, 4); - wrps = extract32(cpu->dbgdidr, 28, 4); - ctx_cmps = extract32(cpu->dbgdidr, 20, 4); - - assert(ctx_cmps <= brps); - - /* The DBGDIDR and ID_AA64DFR0_EL1 define various properties - * of the debug registers such as number of breakpoints; - * check that if they both exist then they agree. - */ - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps); - assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps); - assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps); - } - - define_one_arm_cp_reg(cpu, &dbgdidr); - define_arm_cp_regs(cpu, debug_cp_reginfo); - - if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) { - define_arm_cp_regs(cpu, debug_lpae_cp_reginfo); - } - - for (i = 0; i < brps + 1; i++) { - ARMCPRegInfo dbgregs[] = { - { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]), - .writefn = dbgbvr_write, .raw_writefn = raw_write - }, - { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]), - .writefn = dbgbcr_write, .raw_writefn = raw_write - }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, dbgregs); - } - - for (i = 0; i < wrps + 1; i++) { - ARMCPRegInfo dbgregs[] = { - { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]), - .writefn = dbgwvr_write, .raw_writefn = raw_write - }, - { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH, - .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7, - .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]), - .writefn = dbgwcr_write, .raw_writefn = raw_write - }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, dbgregs); - } -} - -void register_cp_regs_for_features(ARMCPU *cpu) -{ - /* Register all the coprocessor registers based on feature bits */ - CPUARMState *env = &cpu->env; - if (arm_feature(env, ARM_FEATURE_M)) { - /* M profile has no coprocessor registers */ - return; - } - - define_arm_cp_regs(cpu, cp_reginfo); - if (!arm_feature(env, ARM_FEATURE_V8)) { - /* Must go early as it is full of wildcards that may be - * overridden by later definitions. - */ - define_arm_cp_regs(cpu, not_v8_cp_reginfo); - } - - if (arm_feature(env, ARM_FEATURE_V6)) { - /* The ID registers all have impdef reset values */ - ARMCPRegInfo v6_idregs[] = { - { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_pfr0 }, - { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_pfr1 }, - { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_dfr0 }, - { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_afr0 }, - { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_mmfr0 }, - { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_mmfr1 }, - { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_mmfr2 }, - { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_mmfr3 }, - { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_isar0 }, - { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_isar1 }, - { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_isar2 }, - { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_isar3 }, - { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_isar4 }, - { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_isar5 }, - /* 6..7 are as yet unallocated and must RAZ */ - { .name = "ID_ISAR6", .cp = 15, .crn = 0, .crm = 2, - .opc1 = 0, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "ID_ISAR7", .cp = 15, .crn = 0, .crm = 2, - .opc1 = 0, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = 0 }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, v6_idregs); - define_arm_cp_regs(cpu, v6_cp_reginfo); - } else { - define_arm_cp_regs(cpu, not_v6_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_V6K)) { - define_arm_cp_regs(cpu, v6k_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_V7MP) && - !arm_feature(env, ARM_FEATURE_MPU)) { - define_arm_cp_regs(cpu, v7mp_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_V7)) { - /* v7 performance monitor control register: same implementor - * field as main ID register, and we implement only the cycle - * count register. - */ -#ifndef CONFIG_USER_ONLY - ARMCPRegInfo pmcr = { - .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, - .access = PL0_RW, - .type = ARM_CP_IO | ARM_CP_ALIAS, - .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr), - .accessfn = pmreg_access, .writefn = pmcr_write, - .raw_writefn = raw_write, - }; - ARMCPRegInfo pmcr64 = { - .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0, - .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_IO, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr), - .resetvalue = cpu->midr & 0xff000000, - .writefn = pmcr_write, .raw_writefn = raw_write, - }; - define_one_arm_cp_reg(cpu, &pmcr); - define_one_arm_cp_reg(cpu, &pmcr64); -#endif - ARMCPRegInfo clidr = { - .name = "CLIDR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr - }; - define_one_arm_cp_reg(cpu, &clidr); - define_arm_cp_regs(cpu, v7_cp_reginfo); - define_debug_regs(cpu); - } else { - define_arm_cp_regs(cpu, not_v7_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_V8)) { - /* AArch64 ID registers, which all have impdef reset values */ - ARMCPRegInfo v8_idregs[] = { - { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64pfr0 }, - { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64pfr1}, - { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - /* We mask out the PMUVer field, because we don't currently - * implement the PMU. Not advertising it prevents the guest - * from trying to use it and getting UNDEFs on registers we - * don't implement. - */ - .resetvalue = cpu->id_aa64dfr0 & ~0xf00 }, - { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64dfr1 }, - { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64afr0 }, - { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64afr1 }, - { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64isar0 }, - { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64isar1 }, - { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64mmfr0 }, - { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64mmfr1 }, - { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->mvfr0 }, - { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->mvfr1 }, - { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->mvfr2 }, - REGINFO_SENTINEL - }; - /* RVBAR_EL1 is only implemented if EL1 is the highest EL */ - if (!arm_feature(env, ARM_FEATURE_EL3) && - !arm_feature(env, ARM_FEATURE_EL2)) { - ARMCPRegInfo rvbar = { - .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, - .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar - }; - define_one_arm_cp_reg(cpu, &rvbar); - } - define_arm_cp_regs(cpu, v8_idregs); - define_arm_cp_regs(cpu, v8_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_EL2)) { - uint64_t vmpidr_def = mpidr_read_val(env); - ARMCPRegInfo vpidr_regs[] = { - { .name = "VPIDR", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, - .access = PL2_RW, .accessfn = access_el3_aa32ns, - .resetvalue = cpu->midr, - .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, - { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, - .access = PL2_RW, .resetvalue = cpu->midr, - .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, - { .name = "VMPIDR", .state = ARM_CP_STATE_AA32, - .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, - .access = PL2_RW, .accessfn = access_el3_aa32ns, - .resetvalue = vmpidr_def, - .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) }, - { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, - .access = PL2_RW, - .resetvalue = vmpidr_def, - .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, vpidr_regs); - define_arm_cp_regs(cpu, el2_cp_reginfo); - /* RVBAR_EL2 is only implemented if EL2 is the highest EL */ - if (!arm_feature(env, ARM_FEATURE_EL3)) { - ARMCPRegInfo rvbar = { - .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1, - .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar - }; - define_one_arm_cp_reg(cpu, &rvbar); - } - } else { - /* If EL2 is missing but higher ELs are enabled, we need to - * register the no_el2 reginfos. - */ - if (arm_feature(env, ARM_FEATURE_EL3)) { - /* When EL3 exists but not EL2, VPIDR and VMPIDR take the value - * of MIDR_EL1 and MPIDR_EL1. - */ - ARMCPRegInfo vpidr_regs[] = { - { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0, - .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, - .type = ARM_CP_CONST, .resetvalue = cpu->midr, - .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) }, - { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5, - .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, - .type = ARM_CP_NO_RAW, - .writefn = arm_cp_write_ignore, .readfn = mpidr_read }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, vpidr_regs); - define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo); - } - } - if (arm_feature(env, ARM_FEATURE_EL3)) { - define_arm_cp_regs(cpu, el3_cp_reginfo); - ARMCPRegInfo rvbar = { - .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1, - .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar - }; - define_one_arm_cp_reg(cpu, &rvbar); - } - if (arm_feature(env, ARM_FEATURE_MPU)) { - if (arm_feature(env, ARM_FEATURE_V6)) { - /* PMSAv6 not implemented */ - assert(arm_feature(env, ARM_FEATURE_V7)); - define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); - define_arm_cp_regs(cpu, pmsav7_cp_reginfo); - } else { - define_arm_cp_regs(cpu, pmsav5_cp_reginfo); - } - } else { - define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); - define_arm_cp_regs(cpu, vmsa_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { - define_arm_cp_regs(cpu, t2ee_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) { - define_arm_cp_regs(cpu, generic_timer_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_VAPA)) { - define_arm_cp_regs(cpu, vapa_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_CACHE_TEST_CLEAN)) { - define_arm_cp_regs(cpu, cache_test_clean_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_CACHE_DIRTY_REG)) { - define_arm_cp_regs(cpu, cache_dirty_status_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_CACHE_BLOCK_OPS)) { - define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_OMAPCP)) { - define_arm_cp_regs(cpu, omap_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_STRONGARM)) { - define_arm_cp_regs(cpu, strongarm_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_XSCALE)) { - define_arm_cp_regs(cpu, xscale_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) { - define_arm_cp_regs(cpu, dummy_c15_cp_reginfo); - } - if (arm_feature(env, ARM_FEATURE_LPAE)) { - define_arm_cp_regs(cpu, lpae_cp_reginfo); - } - /* Slightly awkwardly, the OMAP and StrongARM cores need all of - * cp15 crn=0 to be writes-ignored, whereas for other cores they should - * be read-only (ie write causes UNDEF exception). - */ - { - ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = { - /* Pre-v8 MIDR space. - * Note that the MIDR isn't a simple constant register because - * of the TI925 behaviour where writes to another register can - * cause the MIDR value to change. - * - * Unimplemented registers in the c15 0 0 0 space default to - * MIDR. Define MIDR first as this entire space, then CTR, TCMTR - * and friends override accordingly. - */ - { .name = "MIDR", - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_R, .resetvalue = cpu->midr, - .writefn = arm_cp_write_ignore, .raw_writefn = raw_write, - .readfn = midr_read, - .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), - .type = ARM_CP_OVERRIDE }, - /* crn = 0 op1 = 0 crm = 3..7 : currently unassigned; we RAZ. */ - { .name = "DUMMY", - .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "DUMMY", - .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "DUMMY", - .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "DUMMY", - .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "DUMMY", - .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - REGINFO_SENTINEL - }; - ARMCPRegInfo id_v8_midr_cp_reginfo[] = { - { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr, - .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), - .readfn = midr_read }, - /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */ - { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST, - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, - .access = PL1_R, .resetvalue = cpu->midr }, - { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST, - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7, - .access = PL1_R, .resetvalue = cpu->midr }, - { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr }, - REGINFO_SENTINEL - }; - ARMCPRegInfo id_cp_reginfo[] = { - /* These are common to v8 and pre-v8 */ - { .name = "CTR", - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr }, - { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0, - .access = PL0_R, .accessfn = ctr_el0_access, - .type = ARM_CP_CONST, .resetvalue = cpu->ctr }, - /* TCMTR and TLBTR exist in v8 but have no 64-bit versions */ - { .name = "TCMTR", - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, - REGINFO_SENTINEL - }; - /* TLBTR is specific to VMSA */ - ARMCPRegInfo id_tlbtr_reginfo = { - .name = "TLBTR", - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0, - }; - /* MPUIR is specific to PMSA V6+ */ - ARMCPRegInfo id_mpuir_reginfo = { - .name = "MPUIR", - .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->pmsav7_dregion << 8 - }; - ARMCPRegInfo crn0_wi_reginfo = { - .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, - .type = ARM_CP_NOP | ARM_CP_OVERRIDE - }; - if (arm_feature(env, ARM_FEATURE_OMAPCP) || - arm_feature(env, ARM_FEATURE_STRONGARM)) { - ARMCPRegInfo *r; - /* Register the blanket "writes ignored" value first to cover the - * whole space. Then update the specific ID registers to allow write - * access, so that they ignore writes rather than causing them to - * UNDEF. - */ - define_one_arm_cp_reg(cpu, &crn0_wi_reginfo); - for (r = id_pre_v8_midr_cp_reginfo; - r->type != ARM_CP_SENTINEL; r++) { - r->access = PL1_RW; - } - for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) { - r->access = PL1_RW; - } - id_tlbtr_reginfo.access = PL1_RW; - id_tlbtr_reginfo.access = PL1_RW; - } - if (arm_feature(env, ARM_FEATURE_V8)) { - define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo); - } else { - define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo); - } - define_arm_cp_regs(cpu, id_cp_reginfo); - if (!arm_feature(env, ARM_FEATURE_MPU)) { - define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); - } else if (arm_feature(env, ARM_FEATURE_V7)) { - define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); - } - } - - if (arm_feature(env, ARM_FEATURE_MPIDR)) { - define_arm_cp_regs(cpu, mpidr_cp_reginfo); - } - - if (arm_feature(env, ARM_FEATURE_AUXCR)) { - ARMCPRegInfo auxcr_reginfo[] = { - { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1, - .access = PL1_RW, .type = ARM_CP_CONST, - .resetvalue = cpu->reset_auxcr }, - { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1, - .access = PL2_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1, - .access = PL3_RW, .type = ARM_CP_CONST, - .resetvalue = 0 }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, auxcr_reginfo); - } - - if (arm_feature(env, ARM_FEATURE_CBAR)) { - if (arm_feature(env, ARM_FEATURE_AARCH64)) { - /* 32 bit view is [31:18] 0...0 [43:32]. */ - uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18) - | extract64(cpu->reset_cbar, 32, 12); - ARMCPRegInfo cbar_reginfo[] = { - { .name = "CBAR", - .type = ARM_CP_CONST, - .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0, - .access = PL1_R, .resetvalue = cpu->reset_cbar }, - { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64, - .type = ARM_CP_CONST, - .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0, - .access = PL1_R, .resetvalue = cbar32 }, - REGINFO_SENTINEL - }; - /* We don't implement a r/w 64 bit CBAR currently */ - assert(arm_feature(env, ARM_FEATURE_CBAR_RO)); - define_arm_cp_regs(cpu, cbar_reginfo); - } else { - ARMCPRegInfo cbar = { - .name = "CBAR", - .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0, - .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar, - .fieldoffset = offsetof(CPUARMState, - cp15.c15_config_base_address) - }; - if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { - cbar.access = PL1_R; - cbar.fieldoffset = 0; - cbar.type = ARM_CP_CONST; - } - define_one_arm_cp_reg(cpu, &cbar); - } - } - - /* Generic registers whose values depend on the implementation */ - { - ARMCPRegInfo sctlr = { - .name = "SCTLR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0, - .access = PL1_RW, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s), - offsetof(CPUARMState, cp15.sctlr_ns) }, - .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr, - .raw_writefn = raw_write, - }; - if (arm_feature(env, ARM_FEATURE_XSCALE)) { - /* Normally we would always end the TB on an SCTLR write, but Linux - * arch/arm/mach-pxa/sleep.S expects two instructions following - * an MMU enable to execute from cache. Imitate this behaviour. - */ - sctlr.type |= ARM_CP_SUPPRESS_TB_END; - } - define_one_arm_cp_reg(cpu, &sctlr); - } -} - -ARMCPU *cpu_arm_init(const char *cpu_model) -{ - return ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model)); -} - -void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) -{ - CPUState *cs = CPU(cpu); - CPUARMState *env = &cpu->env; - - if (arm_feature(env, ARM_FEATURE_AARCH64)) { - gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg, - aarch64_fpu_gdb_set_reg, - 34, "aarch64-fpu.xml", 0); - } else if (arm_feature(env, ARM_FEATURE_NEON)) { - gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, - 51, "arm-neon.xml", 0); - } else if (arm_feature(env, ARM_FEATURE_VFP3)) { - gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, - 35, "arm-vfp3.xml", 0); - } else if (arm_feature(env, ARM_FEATURE_VFP)) { - gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, - 19, "arm-vfp.xml", 0); - } -} - -/* Sort alphabetically by type name, except for "any". */ -static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b) -{ - ObjectClass *class_a = (ObjectClass *)a; - ObjectClass *class_b = (ObjectClass *)b; - const char *name_a, *name_b; - - name_a = object_class_get_name(class_a); - name_b = object_class_get_name(class_b); - if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) { - return 1; - } else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) { - return -1; - } else { - return strcmp(name_a, name_b); - } -} - -static void arm_cpu_list_entry(gpointer data, gpointer user_data) -{ - ObjectClass *oc = data; - CPUListState *s = user_data; - const char *typename; - char *name; - - typename = object_class_get_name(oc); - name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU)); - (*s->cpu_fprintf)(s->file, " %s\n", - name); - g_free(name); -} - -void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf) -{ - CPUListState s = { - .file = f, - .cpu_fprintf = cpu_fprintf, - }; - GSList *list; - - list = object_class_get_list(TYPE_ARM_CPU, false); - list = g_slist_sort(list, arm_cpu_list_compare); - (*cpu_fprintf)(f, "Available CPUs:\n"); - g_slist_foreach(list, arm_cpu_list_entry, &s); - g_slist_free(list); -#ifdef CONFIG_KVM - /* The 'host' CPU type is dynamically registered only if KVM is - * enabled, so we have to special-case it here: - */ - (*cpu_fprintf)(f, " host (only available in KVM mode)\n"); -#endif -} - -static void arm_cpu_add_definition(gpointer data, gpointer user_data) -{ - ObjectClass *oc = data; - CpuDefinitionInfoList **cpu_list = user_data; - CpuDefinitionInfoList *entry; - CpuDefinitionInfo *info; - const char *typename; - - typename = object_class_get_name(oc); - info = g_malloc0(sizeof(*info)); - info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_ARM_CPU)); - - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = *cpu_list; - *cpu_list = entry; -} - -CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) -{ - CpuDefinitionInfoList *cpu_list = NULL; - GSList *list; - - list = object_class_get_list(TYPE_ARM_CPU, false); - g_slist_foreach(list, arm_cpu_add_definition, &cpu_list); - g_slist_free(list); - - return cpu_list; -} - -static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, - void *opaque, int state, int secstate, - int crm, int opc1, int opc2) -{ - /* Private utility function for define_one_arm_cp_reg_with_opaque(): - * add a single reginfo struct to the hash table. - */ - uint32_t *key = g_new(uint32_t, 1); - ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); - int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0; - int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0; - - /* Reset the secure state to the specific incoming state. This is - * necessary as the register may have been defined with both states. - */ - r2->secure = secstate; - - if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) { - /* Register is banked (using both entries in array). - * Overwriting fieldoffset as the array is only used to define - * banked registers but later only fieldoffset is used. - */ - r2->fieldoffset = r->bank_fieldoffsets[ns]; - } - - if (state == ARM_CP_STATE_AA32) { - if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) { - /* If the register is banked then we don't need to migrate or - * reset the 32-bit instance in certain cases: - * - * 1) If the register has both 32-bit and 64-bit instances then we - * can count on the 64-bit instance taking care of the - * non-secure bank. - * 2) If ARMv8 is enabled then we can count on a 64-bit version - * taking care of the secure bank. This requires that separate - * 32 and 64-bit definitions are provided. - */ - if ((r->state == ARM_CP_STATE_BOTH && ns) || - (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) { - r2->type |= ARM_CP_ALIAS; - } - } else if ((secstate != r->secure) && !ns) { - /* The register is not banked so we only want to allow migration of - * the non-secure instance. - */ - r2->type |= ARM_CP_ALIAS; - } - - if (r->state == ARM_CP_STATE_BOTH) { - /* We assume it is a cp15 register if the .cp field is left unset. - */ - if (r2->cp == 0) { - r2->cp = 15; - } - -#ifdef HOST_WORDS_BIGENDIAN - if (r2->fieldoffset) { - r2->fieldoffset += sizeof(uint32_t); - } -#endif - } - } - if (state == ARM_CP_STATE_AA64) { - /* To allow abbreviation of ARMCPRegInfo - * definitions, we treat cp == 0 as equivalent to - * the value for "standard guest-visible sysreg". - * STATE_BOTH definitions are also always "standard - * sysreg" in their AArch64 view (the .cp value may - * be non-zero for the benefit of the AArch32 view). - */ - if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) { - r2->cp = CP_REG_ARM64_SYSREG_CP; - } - *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm, - r2->opc0, opc1, opc2); - } else { - *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2); - } - if (opaque) { - r2->opaque = opaque; - } - /* reginfo passed to helpers is correct for the actual access, - * and is never ARM_CP_STATE_BOTH: - */ - r2->state = state; - /* Make sure reginfo passed to helpers for wildcarded regs - * has the correct crm/opc1/opc2 for this reg, not CP_ANY: - */ - r2->crm = crm; - r2->opc1 = opc1; - r2->opc2 = opc2; - /* By convention, for wildcarded registers only the first - * entry is used for migration; the others are marked as - * ALIAS so we don't try to transfer the register - * multiple times. Special registers (ie NOP/WFI) are - * never migratable and not even raw-accessible. - */ - if ((r->type & ARM_CP_SPECIAL)) { - r2->type |= ARM_CP_NO_RAW; - } - if (((r->crm == CP_ANY) && crm != 0) || - ((r->opc1 == CP_ANY) && opc1 != 0) || - ((r->opc2 == CP_ANY) && opc2 != 0)) { - r2->type |= ARM_CP_ALIAS; - } - - /* Check that raw accesses are either forbidden or handled. Note that - * we can't assert this earlier because the setup of fieldoffset for - * banked registers has to be done first. - */ - if (!(r2->type & ARM_CP_NO_RAW)) { - assert(!raw_accessors_invalid(r2)); - } - - /* Overriding of an existing definition must be explicitly - * requested. - */ - if (!(r->type & ARM_CP_OVERRIDE)) { - ARMCPRegInfo *oldreg; - oldreg = g_hash_table_lookup(cpu->cp_regs, key); - if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) { - fprintf(stderr, "Register redefined: cp=%d %d bit " - "crn=%d crm=%d opc1=%d opc2=%d, " - "was %s, now %s\n", r2->cp, 32 + 32 * is64, - r2->crn, r2->crm, r2->opc1, r2->opc2, - oldreg->name, r2->name); - g_assert_not_reached(); - } - } - g_hash_table_insert(cpu->cp_regs, key, r2); -} - - -void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, - const ARMCPRegInfo *r, void *opaque) -{ - /* Define implementations of coprocessor registers. - * We store these in a hashtable because typically - * there are less than 150 registers in a space which - * is 16*16*16*8*8 = 262144 in size. - * Wildcarding is supported for the crm, opc1 and opc2 fields. - * If a register is defined twice then the second definition is - * used, so this can be used to define some generic registers and - * then override them with implementation specific variations. - * At least one of the original and the second definition should - * include ARM_CP_OVERRIDE in its type bits -- this is just a guard - * against accidental use. - * - * The state field defines whether the register is to be - * visible in the AArch32 or AArch64 execution state. If the - * state is set to ARM_CP_STATE_BOTH then we synthesise a - * reginfo structure for the AArch32 view, which sees the lower - * 32 bits of the 64 bit register. - * - * Only registers visible in AArch64 may set r->opc0; opc0 cannot - * be wildcarded. AArch64 registers are always considered to be 64 - * bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of - * the register, if any. - */ - int crm, opc1, opc2, state; - int crmmin = (r->crm == CP_ANY) ? 0 : r->crm; - int crmmax = (r->crm == CP_ANY) ? 15 : r->crm; - int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1; - int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1; - int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2; - int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2; - /* 64 bit registers have only CRm and Opc1 fields */ - assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn))); - /* op0 only exists in the AArch64 encodings */ - assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0)); - /* AArch64 regs are all 64 bit so ARM_CP_64BIT is meaningless */ - assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT)); - /* The AArch64 pseudocode CheckSystemAccess() specifies that op1 - * encodes a minimum access level for the register. We roll this - * runtime check into our general permission check code, so check - * here that the reginfo's specified permissions are strict enough - * to encompass the generic architectural permission check. - */ - if (r->state != ARM_CP_STATE_AA32) { - int mask = 0; - switch (r->opc1) { - case 0: case 1: case 2: - /* min_EL EL1 */ - mask = PL1_RW; - break; - case 3: - /* min_EL EL0 */ - mask = PL0_RW; - break; - case 4: - /* min_EL EL2 */ - mask = PL2_RW; - break; - case 5: - /* unallocated encoding, so not possible */ - assert(false); - break; - case 6: - /* min_EL EL3 */ - mask = PL3_RW; - break; - case 7: - /* min_EL EL1, secure mode only (we don't check the latter) */ - mask = PL1_RW; - break; - default: - /* broken reginfo with out-of-range opc1 */ - assert(false); - break; - } - /* assert our permissions are not too lax (stricter is fine) */ - assert((r->access & ~mask) == 0); - } - - /* Check that the register definition has enough info to handle - * reads and writes if they are permitted. - */ - if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) { - if (r->access & PL3_R) { - assert((r->fieldoffset || - (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) || - r->readfn); - } - if (r->access & PL3_W) { - assert((r->fieldoffset || - (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) || - r->writefn); - } - } - /* Bad type field probably means missing sentinel at end of reg list */ - assert(cptype_valid(r->type)); - for (crm = crmmin; crm <= crmmax; crm++) { - for (opc1 = opc1min; opc1 <= opc1max; opc1++) { - for (opc2 = opc2min; opc2 <= opc2max; opc2++) { - for (state = ARM_CP_STATE_AA32; - state <= ARM_CP_STATE_AA64; state++) { - if (r->state != state && r->state != ARM_CP_STATE_BOTH) { - continue; - } - if (state == ARM_CP_STATE_AA32) { - /* Under AArch32 CP registers can be common - * (same for secure and non-secure world) or banked. - */ - switch (r->secure) { - case ARM_CP_SECSTATE_S: - case ARM_CP_SECSTATE_NS: - add_cpreg_to_hashtable(cpu, r, opaque, state, - r->secure, crm, opc1, opc2); - break; - default: - add_cpreg_to_hashtable(cpu, r, opaque, state, - ARM_CP_SECSTATE_S, - crm, opc1, opc2); - add_cpreg_to_hashtable(cpu, r, opaque, state, - ARM_CP_SECSTATE_NS, - crm, opc1, opc2); - break; - } - } else { - /* AArch64 registers get mapped to non-secure instance - * of AArch32 */ - add_cpreg_to_hashtable(cpu, r, opaque, state, - ARM_CP_SECSTATE_NS, - crm, opc1, opc2); - } - } - } - } - } -} - -void define_arm_cp_regs_with_opaque(ARMCPU *cpu, - const ARMCPRegInfo *regs, void *opaque) -{ - /* Define a whole list of registers */ - const ARMCPRegInfo *r; - for (r = regs; r->type != ARM_CP_SENTINEL; r++) { - define_one_arm_cp_reg_with_opaque(cpu, r, opaque); - } -} - -const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp) -{ - return g_hash_table_lookup(cpregs, &encoded_cp); -} - -void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) -{ - /* Helper coprocessor write function for write-ignore registers */ -} - -uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri) -{ - /* Helper coprocessor write function for read-as-zero registers */ - return 0; -} - -void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque) -{ - /* Helper coprocessor reset function for do-nothing-on-reset registers */ -} - -static int bad_mode_switch(CPUARMState *env, int mode) -{ - /* Return true if it is not valid for us to switch to - * this CPU mode (ie all the UNPREDICTABLE cases in - * the ARM ARM CPSRWriteByInstr pseudocode). - */ - switch (mode) { - case ARM_CPU_MODE_USR: - case ARM_CPU_MODE_SYS: - case ARM_CPU_MODE_SVC: - case ARM_CPU_MODE_ABT: - case ARM_CPU_MODE_UND: - case ARM_CPU_MODE_IRQ: - case ARM_CPU_MODE_FIQ: - return 0; - case ARM_CPU_MODE_MON: - return !arm_is_secure(env); - default: - return 1; - } -} - -uint32_t cpsr_read(CPUARMState *env) -{ - int ZF; - ZF = (env->ZF == 0); - return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) | - (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) - | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) - | ((env->condexec_bits & 0xfc) << 8) - | (env->GE << 16) | (env->daif & CPSR_AIF); -} - -void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) -{ - uint32_t changed_daif; - - if (mask & CPSR_NZCV) { - env->ZF = (~val) & CPSR_Z; - env->NF = val; - env->CF = (val >> 29) & 1; - env->VF = (val << 3) & 0x80000000; - } - if (mask & CPSR_Q) - env->QF = ((val & CPSR_Q) != 0); - if (mask & CPSR_T) - env->thumb = ((val & CPSR_T) != 0); - if (mask & CPSR_IT_0_1) { - env->condexec_bits &= ~3; - env->condexec_bits |= (val >> 25) & 3; - } - if (mask & CPSR_IT_2_7) { - env->condexec_bits &= 3; - env->condexec_bits |= (val >> 8) & 0xfc; - } - if (mask & CPSR_GE) { - env->GE = (val >> 16) & 0xf; - } - - /* In a V7 implementation that includes the security extensions but does - * not include Virtualization Extensions the SCR.FW and SCR.AW bits control - * whether non-secure software is allowed to change the CPSR_F and CPSR_A - * bits respectively. - * - * In a V8 implementation, it is permitted for privileged software to - * change the CPSR A/F bits regardless of the SCR.AW/FW bits. - */ - if (!arm_feature(env, ARM_FEATURE_V8) && - arm_feature(env, ARM_FEATURE_EL3) && - !arm_feature(env, ARM_FEATURE_EL2) && - !arm_is_secure(env)) { - - changed_daif = (env->daif ^ val) & mask; - - if (changed_daif & CPSR_A) { - /* Check to see if we are allowed to change the masking of async - * abort exceptions from a non-secure state. - */ - if (!(env->cp15.scr_el3 & SCR_AW)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Ignoring attempt to switch CPSR_A flag from " - "non-secure world with SCR.AW bit clear\n"); - mask &= ~CPSR_A; - } - } - - if (changed_daif & CPSR_F) { - /* Check to see if we are allowed to change the masking of FIQ - * exceptions from a non-secure state. - */ - if (!(env->cp15.scr_el3 & SCR_FW)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Ignoring attempt to switch CPSR_F flag from " - "non-secure world with SCR.FW bit clear\n"); - mask &= ~CPSR_F; - } - - /* Check whether non-maskable FIQ (NMFI) support is enabled. - * If this bit is set software is not allowed to mask - * FIQs, but is allowed to set CPSR_F to 0. - */ - if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) && - (val & CPSR_F)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Ignoring attempt to enable CPSR_F flag " - "(non-maskable FIQ [NMFI] support enabled)\n"); - mask &= ~CPSR_F; - } - } - } - - env->daif &= ~(CPSR_AIF & mask); - env->daif |= val & CPSR_AIF & mask; - - if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { - if (bad_mode_switch(env, val & CPSR_M)) { - /* Attempt to switch to an invalid mode: this is UNPREDICTABLE. - * We choose to ignore the attempt and leave the CPSR M field - * untouched. - */ - mask &= ~CPSR_M; - } else { - switch_mode(env, val & CPSR_M); - } - } - mask &= ~CACHED_CPSR_BITS; - env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); -} - -/* Sign/zero extend */ -uint32_t HELPER(sxtb16)(uint32_t x) -{ - uint32_t res; - res = (uint16_t)(int8_t)x; - res |= (uint32_t)(int8_t)(x >> 16) << 16; - return res; -} - -uint32_t HELPER(uxtb16)(uint32_t x) -{ - uint32_t res; - res = (uint16_t)(uint8_t)x; - res |= (uint32_t)(uint8_t)(x >> 16) << 16; - return res; -} - -uint32_t HELPER(clz)(uint32_t x) -{ - return clz32(x); -} - -int32_t HELPER(sdiv)(int32_t num, int32_t den) -{ - if (den == 0) - return 0; - if (num == INT_MIN && den == -1) - return INT_MIN; - return num / den; -} - -uint32_t HELPER(udiv)(uint32_t num, uint32_t den) -{ - if (den == 0) - return 0; - return num / den; -} - -uint32_t HELPER(rbit)(uint32_t x) -{ - return revbit32(x); -} - -#if defined(CONFIG_USER_ONLY) - -/* These should probably raise undefined insn exceptions. */ -void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - cpu_abort(CPU(cpu), "v7m_msr %d\n", reg); -} - -uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - cpu_abort(CPU(cpu), "v7m_mrs %d\n", reg); - return 0; -} - -void switch_mode(CPUARMState *env, int mode) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - if (mode != ARM_CPU_MODE_USR) { - cpu_abort(CPU(cpu), "Tried to switch out of user mode\n"); - } -} - -void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - cpu_abort(CPU(cpu), "banked r13 write\n"); -} - -uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - cpu_abort(CPU(cpu), "banked r13 read\n"); - return 0; -} - -uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, - uint32_t cur_el, bool secure) -{ - return 1; -} - -void aarch64_sync_64_to_32(CPUARMState *env) -{ - g_assert_not_reached(); -} - -#else - -/* Map CPU modes onto saved register banks. */ -int bank_number(int mode) -{ - switch (mode) { - case ARM_CPU_MODE_USR: - case ARM_CPU_MODE_SYS: - return BANK_USRSYS; - case ARM_CPU_MODE_SVC: - return BANK_SVC; - case ARM_CPU_MODE_ABT: - return BANK_ABT; - case ARM_CPU_MODE_UND: - return BANK_UND; - case ARM_CPU_MODE_IRQ: - return BANK_IRQ; - case ARM_CPU_MODE_FIQ: - return BANK_FIQ; - case ARM_CPU_MODE_HYP: - return BANK_HYP; - case ARM_CPU_MODE_MON: - return BANK_MON; - } - g_assert_not_reached(); -} - -void switch_mode(CPUARMState *env, int mode) -{ - int old_mode; - int i; - - old_mode = env->uncached_cpsr & CPSR_M; - if (mode == old_mode) - return; - - if (old_mode == ARM_CPU_MODE_FIQ) { - memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t)); - memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t)); - } else if (mode == ARM_CPU_MODE_FIQ) { - memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t)); - memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t)); - } - - i = bank_number(old_mode); - env->banked_r13[i] = env->regs[13]; - env->banked_r14[i] = env->regs[14]; - env->banked_spsr[i] = env->spsr; - - i = bank_number(mode); - env->regs[13] = env->banked_r13[i]; - env->regs[14] = env->banked_r14[i]; - env->spsr = env->banked_spsr[i]; -} - -/* Physical Interrupt Target EL Lookup Table - * - * [ From ARM ARM section G1.13.4 (Table G1-15) ] - * - * The below multi-dimensional table is used for looking up the target - * exception level given numerous condition criteria. Specifically, the - * target EL is based on SCR and HCR routing controls as well as the - * currently executing EL and secure state. - * - * Dimensions: - * target_el_table[2][2][2][2][2][4] - * | | | | | +--- Current EL - * | | | | +------ Non-secure(0)/Secure(1) - * | | | +--------- HCR mask override - * | | +------------ SCR exec state control - * | +--------------- SCR mask override - * +------------------ 32-bit(0)/64-bit(1) EL3 - * - * The table values are as such: - * 0-3 = EL0-EL3 - * -1 = Cannot occur - * - * The ARM ARM target EL table includes entries indicating that an "exception - * is not taken". The two cases where this is applicable are: - * 1) An exception is taken from EL3 but the SCR does not have the exception - * routed to EL3. - * 2) An exception is taken from EL2 but the HCR does not have the exception - * routed to EL2. - * In these two cases, the below table contain a target of EL1. This value is - * returned as it is expected that the consumer of the table data will check - * for "target EL >= current EL" to ensure the exception is not taken. - * - * SCR HCR - * 64 EA AMO From - * BIT IRQ IMO Non-secure Secure - * EL3 FIQ RW FMO EL0 EL1 EL2 EL3 EL0 EL1 EL2 EL3 - */ -static const int8_t target_el_table[2][2][2][2][2][4] = { - {{{{/* 0 0 0 0 */{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },}, - {/* 0 0 0 1 */{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},}, - {{/* 0 0 1 0 */{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },}, - {/* 0 0 1 1 */{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},}, - {{{/* 0 1 0 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },}, - {/* 0 1 0 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},}, - {{/* 0 1 1 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },}, - {/* 0 1 1 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},}, - {{{{/* 1 0 0 0 */{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },}, - {/* 1 0 0 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},}, - {{/* 1 0 1 0 */{ 1, 1, 1, -1 },{ 1, 1, -1, 1 },}, - {/* 1 0 1 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},}, - {{{/* 1 1 0 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },}, - {/* 1 1 0 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},}, - {{/* 1 1 1 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },}, - {/* 1 1 1 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},},}, -}; - -/* - * Determine the target EL for physical exceptions - */ -uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, - uint32_t cur_el, bool secure) -{ - CPUARMState *env = cs->env_ptr; - int rw; - int scr; - int hcr; - int target_el; - /* Is the highest EL AArch64? */ - int is64 = arm_feature(env, ARM_FEATURE_AARCH64); - - if (arm_feature(env, ARM_FEATURE_EL3)) { - rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW); - } else { - /* Either EL2 is the highest EL (and so the EL2 register width - * is given by is64); or there is no EL2 or EL3, in which case - * the value of 'rw' does not affect the table lookup anyway. - */ - rw = is64; - } - - switch (excp_idx) { - case EXCP_IRQ: - scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ); - hcr = ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO); - break; - case EXCP_FIQ: - scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ); - hcr = ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO); - break; - default: - scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA); - hcr = ((env->cp15.hcr_el2 & HCR_AMO) == HCR_AMO); - break; - }; - - /* If HCR.TGE is set then HCR is treated as being 1 */ - hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE); - - /* Perform a table-lookup for the target EL given the current state */ - target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el]; - - assert(target_el > 0); - - return target_el; -} - -static void v7m_push(CPUARMState *env, uint32_t val) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - - env->regs[13] -= 4; - stl_phys(cs->as, env->regs[13], val); -} - -static uint32_t v7m_pop(CPUARMState *env) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - uint32_t val; - - val = ldl_phys(cs->as, env->regs[13]); - env->regs[13] += 4; - return val; -} - -/* Switch to V7M main or process stack pointer. */ -static void switch_v7m_sp(CPUARMState *env, int process) -{ - uint32_t tmp; - if (env->v7m.current_sp != process) { - tmp = env->v7m.other_sp; - env->v7m.other_sp = env->regs[13]; - env->regs[13] = tmp; - env->v7m.current_sp = process; - } -} - -static void do_v7m_exception_exit(CPUARMState *env) -{ - uint32_t type; - uint32_t xpsr; - - type = env->regs[15]; - if (env->v7m.exception != 0) - armv7m_nvic_complete_irq(env->nvic, env->v7m.exception); - - /* Switch to the target stack. */ - switch_v7m_sp(env, (type & 4) != 0); - /* Pop registers. */ - env->regs[0] = v7m_pop(env); - env->regs[1] = v7m_pop(env); - env->regs[2] = v7m_pop(env); - env->regs[3] = v7m_pop(env); - env->regs[12] = v7m_pop(env); - env->regs[14] = v7m_pop(env); - env->regs[15] = v7m_pop(env); - if (env->regs[15] & 1) { - qemu_log_mask(LOG_GUEST_ERROR, - "M profile return from interrupt with misaligned " - "PC is UNPREDICTABLE\n"); - /* Actual hardware seems to ignore the lsbit, and there are several - * RTOSes out there which incorrectly assume the r15 in the stack - * frame should be a Thumb-style "lsbit indicates ARM/Thumb" value. - */ - env->regs[15] &= ~1U; - } - xpsr = v7m_pop(env); - xpsr_write(env, xpsr, 0xfffffdff); - /* Undo stack alignment. */ - if (xpsr & 0x200) - env->regs[13] |= 4; - /* ??? The exception return type specifies Thread/Handler mode. However - this is also implied by the xPSR value. Not sure what to do - if there is a mismatch. */ - /* ??? Likewise for mismatches between the CONTROL register and the stack - pointer. */ -} - -void arm_v7m_cpu_do_interrupt(CPUState *cs) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - uint32_t xpsr = xpsr_read(env); - uint32_t lr; - uint32_t addr; - - arm_log_exception(cs->exception_index); - - lr = 0xfffffff1; - if (env->v7m.current_sp) - lr |= 4; - if (env->v7m.exception == 0) - lr |= 8; - - /* For exceptions we just mark as pending on the NVIC, and let that - handle it. */ - /* TODO: Need to escalate if the current priority is higher than the - one we're raising. */ - switch (cs->exception_index) { - case EXCP_UDEF: - env->v7m.cfsr |= CFSR_UNDEFINSTR; - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); - return; - case EXCP_SWI: - /* The PC already points to the next instruction. */ - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC); - return; - case EXCP_PREFETCH_ABORT: - case EXCP_DATA_ABORT: - env->v7m.mmfar = env->exception.vaddress; - env->v7m.cfsr |= CFSR_MMARVALID; - if (cs->exception_index == EXCP_PREFETCH_ABORT) - env->v7m.cfsr |= CFSR_IACCVIOL; - else - env->v7m.cfsr |= CFSR_DACCVIOL; - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); - return; - case EXCP_BKPT: - if (semihosting_enabled()) { - int nr; - nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff; - if (nr == 0xab) { - env->regs[15] += 2; - qemu_log_mask(CPU_LOG_INT, - "...handling as semihosting call 0x%x\n", - env->regs[0]); - env->regs[0] = do_arm_semihosting(env); - return; - } - } - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG); - return; - case EXCP_IRQ: - env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic); - break; - case EXCP_WKUP: - // Take a reset - qemu_devices_reset(); - return; - case EXCP_EXCEPTION_EXIT: - do_v7m_exception_exit(env); - return; - default: - cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); - return; /* Never happens. Keep compiler happy. */ - } - - /* Align stack pointer. */ - if ((env->v7m.ccr & CCR_STKALIGN) && (env->regs[13] & 4)) { - env->regs[13] -= 4; - xpsr |= 0x200; - } - /* Switch to the handler mode. */ - v7m_push(env, xpsr); - v7m_push(env, env->regs[15]); - v7m_push(env, env->regs[14]); - v7m_push(env, env->regs[12]); - v7m_push(env, env->regs[3]); - v7m_push(env, env->regs[2]); - v7m_push(env, env->regs[1]); - v7m_push(env, env->regs[0]); - switch_v7m_sp(env, 0); - /* Clear IT bits */ - env->condexec_bits = 0; - env->regs[14] = lr; - addr = ldl_phys(cs->as, env->v7m.vecbase + env->v7m.exception * 4); - env->regs[15] = addr & 0xfffffffe; - env->thumb = addr & 1; - if (env->v7m.exception == 1) { // reset? - env->v7m.exception = 0; - } -} - -/* Function used to synchronize QEMU's AArch64 register set with AArch32 - * register set. This is necessary when switching between AArch32 and AArch64 - * execution state. - */ -void aarch64_sync_32_to_64(CPUARMState *env) -{ - int i; - uint32_t mode = env->uncached_cpsr & CPSR_M; - - /* We can blanket copy R[0:7] to X[0:7] */ - for (i = 0; i < 8; i++) { - env->xregs[i] = env->regs[i]; - } - - /* Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12. - * Otherwise, they come from the banked user regs. - */ - if (mode == ARM_CPU_MODE_FIQ) { - for (i = 8; i < 13; i++) { - env->xregs[i] = env->usr_regs[i - 8]; - } - } else { - for (i = 8; i < 13; i++) { - env->xregs[i] = env->regs[i]; - } - } - - /* Registers x13-x23 are the various mode SP and FP registers. Registers - * r13 and r14 are only copied if we are in that mode, otherwise we copy - * from the mode banked register. - */ - if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) { - env->xregs[13] = env->regs[13]; - env->xregs[14] = env->regs[14]; - } else { - env->xregs[13] = env->banked_r13[bank_number(ARM_CPU_MODE_USR)]; - /* HYP is an exception in that it is copied from r14 */ - if (mode == ARM_CPU_MODE_HYP) { - env->xregs[14] = env->regs[14]; - } else { - env->xregs[14] = env->banked_r14[bank_number(ARM_CPU_MODE_USR)]; - } - } - - if (mode == ARM_CPU_MODE_HYP) { - env->xregs[15] = env->regs[13]; - } else { - env->xregs[15] = env->banked_r13[bank_number(ARM_CPU_MODE_HYP)]; - } - - if (mode == ARM_CPU_MODE_IRQ) { - env->xregs[16] = env->regs[14]; - env->xregs[17] = env->regs[13]; - } else { - env->xregs[16] = env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)]; - env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)]; - } - - if (mode == ARM_CPU_MODE_SVC) { - env->xregs[18] = env->regs[14]; - env->xregs[19] = env->regs[13]; - } else { - env->xregs[18] = env->banked_r14[bank_number(ARM_CPU_MODE_SVC)]; - env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)]; - } - - if (mode == ARM_CPU_MODE_ABT) { - env->xregs[20] = env->regs[14]; - env->xregs[21] = env->regs[13]; - } else { - env->xregs[20] = env->banked_r14[bank_number(ARM_CPU_MODE_ABT)]; - env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)]; - } - - if (mode == ARM_CPU_MODE_UND) { - env->xregs[22] = env->regs[14]; - env->xregs[23] = env->regs[13]; - } else { - env->xregs[22] = env->banked_r14[bank_number(ARM_CPU_MODE_UND)]; - env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)]; - } - - /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ - * mode, then we can copy from r8-r14. Otherwise, we copy from the - * FIQ bank for r8-r14. - */ - if (mode == ARM_CPU_MODE_FIQ) { - for (i = 24; i < 31; i++) { - env->xregs[i] = env->regs[i - 16]; /* X[24:30] <- R[8:14] */ - } - } else { - for (i = 24; i < 29; i++) { - env->xregs[i] = env->fiq_regs[i - 24]; - } - env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)]; - env->xregs[30] = env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)]; - } - - env->pc = env->regs[15]; -} - -/* Function used to synchronize QEMU's AArch32 register set with AArch64 - * register set. This is necessary when switching between AArch32 and AArch64 - * execution state. - */ -void aarch64_sync_64_to_32(CPUARMState *env) -{ - int i; - uint32_t mode = env->uncached_cpsr & CPSR_M; - - /* We can blanket copy X[0:7] to R[0:7] */ - for (i = 0; i < 8; i++) { - env->regs[i] = env->xregs[i]; - } - - /* Unless we are in FIQ mode, r8-r12 come from the user registers x8-x12. - * Otherwise, we copy x8-x12 into the banked user regs. - */ - if (mode == ARM_CPU_MODE_FIQ) { - for (i = 8; i < 13; i++) { - env->usr_regs[i - 8] = env->xregs[i]; - } - } else { - for (i = 8; i < 13; i++) { - env->regs[i] = env->xregs[i]; - } - } - - /* Registers r13 & r14 depend on the current mode. - * If we are in a given mode, we copy the corresponding x registers to r13 - * and r14. Otherwise, we copy the x register to the banked r13 and r14 - * for the mode. - */ - if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) { - env->regs[13] = env->xregs[13]; - env->regs[14] = env->xregs[14]; - } else { - env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13]; - - /* HYP is an exception in that it does not have its own banked r14 but - * shares the USR r14 - */ - if (mode == ARM_CPU_MODE_HYP) { - env->regs[14] = env->xregs[14]; - } else { - env->banked_r14[bank_number(ARM_CPU_MODE_USR)] = env->xregs[14]; - } - } - - if (mode == ARM_CPU_MODE_HYP) { - env->regs[13] = env->xregs[15]; - } else { - env->banked_r13[bank_number(ARM_CPU_MODE_HYP)] = env->xregs[15]; - } - - if (mode == ARM_CPU_MODE_IRQ) { - env->regs[14] = env->xregs[16]; - env->regs[13] = env->xregs[17]; - } else { - env->banked_r14[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16]; - env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17]; - } - - if (mode == ARM_CPU_MODE_SVC) { - env->regs[14] = env->xregs[18]; - env->regs[13] = env->xregs[19]; - } else { - env->banked_r14[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18]; - env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19]; - } - - if (mode == ARM_CPU_MODE_ABT) { - env->regs[14] = env->xregs[20]; - env->regs[13] = env->xregs[21]; - } else { - env->banked_r14[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20]; - env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21]; - } - - if (mode == ARM_CPU_MODE_UND) { - env->regs[14] = env->xregs[22]; - env->regs[13] = env->xregs[23]; - } else { - env->banked_r14[bank_number(ARM_CPU_MODE_UND)] = env->xregs[22]; - env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23]; - } - - /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ - * mode, then we can copy to r8-r14. Otherwise, we copy to the - * FIQ bank for r8-r14. - */ - if (mode == ARM_CPU_MODE_FIQ) { - for (i = 24; i < 31; i++) { - env->regs[i - 16] = env->xregs[i]; /* X[24:30] -> R[8:14] */ - } - } else { - for (i = 24; i < 29; i++) { - env->fiq_regs[i - 24] = env->xregs[i]; - } - env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29]; - env->banked_r14[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30]; - } - - env->regs[15] = env->pc; -} - -/* Handle a CPU exception. */ -void arm_cpu_do_interrupt(CPUState *cs) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - uint32_t addr; - uint32_t mask; - int new_mode; - uint32_t offset; - uint32_t moe; - - assert(!IS_M(env)); - - arm_log_exception(cs->exception_index); - - if (arm_is_psci_call(cpu, cs->exception_index)) { - arm_handle_psci_call(cpu); - qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n"); - return; - } - - /* If this is a debug exception we must update the DBGDSCR.MOE bits */ - switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) { - case EC_BREAKPOINT: - case EC_BREAKPOINT_SAME_EL: - moe = 1; - break; - case EC_WATCHPOINT: - case EC_WATCHPOINT_SAME_EL: - moe = 10; - break; - case EC_AA32_BKPT: - moe = 3; - break; - case EC_VECTORCATCH: - moe = 5; - break; - default: - moe = 0; - break; - } - - if (moe) { - env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe); - } - - /* TODO: Vectored interrupt controller. */ - switch (cs->exception_index) { - case EXCP_UDEF: - new_mode = ARM_CPU_MODE_UND; - addr = 0x04; - mask = CPSR_I; - if (env->thumb) - offset = 2; - else - offset = 4; - break; - case EXCP_SWI: - if (semihosting_enabled()) { - /* Check for semihosting interrupt. */ - if (env->thumb) { - mask = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code) - & 0xff; - } else { - mask = arm_ldl_code(env, env->regs[15] - 4, env->bswap_code) - & 0xffffff; - } - /* Only intercept calls from privileged modes, to provide some - semblance of security. */ - if (((mask == 0x123456 && !env->thumb) - || (mask == 0xab && env->thumb)) - && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { - qemu_log_mask(CPU_LOG_INT, - "...handling as semihosting call 0x%x\n", - env->regs[0]); - env->regs[0] = do_arm_semihosting(env); - return; - } - } - new_mode = ARM_CPU_MODE_SVC; - addr = 0x08; - mask = CPSR_I; - /* The PC already points to the next instruction. */ - offset = 0; - break; - case EXCP_BKPT: - /* See if this is a semihosting syscall. */ - if (env->thumb && semihosting_enabled()) { - mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff; - if (mask == 0xab - && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { - env->regs[15] += 2; - qemu_log_mask(CPU_LOG_INT, - "...handling as semihosting call 0x%x\n", - env->regs[0]); - env->regs[0] = do_arm_semihosting(env); - return; - } - } - env->exception.fsr = 2; - /* Fall through to prefetch abort. */ - case EXCP_PREFETCH_ABORT: - A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr); - A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress); - qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", - env->exception.fsr, (uint32_t)env->exception.vaddress); - new_mode = ARM_CPU_MODE_ABT; - addr = 0x0c; - mask = CPSR_A | CPSR_I; - offset = 4; - break; - case EXCP_DATA_ABORT: - A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr); - A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress); - qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", - env->exception.fsr, - (uint32_t)env->exception.vaddress); - new_mode = ARM_CPU_MODE_ABT; - addr = 0x10; - mask = CPSR_A | CPSR_I; - offset = 8; - break; - case EXCP_IRQ: - new_mode = ARM_CPU_MODE_IRQ; - addr = 0x18; - /* Disable IRQ and imprecise data aborts. */ - mask = CPSR_A | CPSR_I; - offset = 4; - if (env->cp15.scr_el3 & SCR_IRQ) { - /* IRQ routed to monitor mode */ - new_mode = ARM_CPU_MODE_MON; - mask |= CPSR_F; - } - break; - case EXCP_FIQ: - new_mode = ARM_CPU_MODE_FIQ; - addr = 0x1c; - /* Disable FIQ, IRQ and imprecise data aborts. */ - mask = CPSR_A | CPSR_I | CPSR_F; - if (env->cp15.scr_el3 & SCR_FIQ) { - /* FIQ routed to monitor mode */ - new_mode = ARM_CPU_MODE_MON; - } - offset = 4; - break; - case EXCP_SMC: - new_mode = ARM_CPU_MODE_MON; - addr = 0x08; - mask = CPSR_A | CPSR_I | CPSR_F; - offset = 0; - break; - default: - cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); - return; /* Never happens. Keep compiler happy. */ - } - - if (new_mode == ARM_CPU_MODE_MON) { - addr += env->cp15.mvbar; - } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) { - /* High vectors. When enabled, base address cannot be remapped. */ - addr += 0xffff0000; - } else { - /* ARM v7 architectures provide a vector base address register to remap - * the interrupt vector table. - * This register is only followed in non-monitor mode, and is banked. - * Note: only bits 31:5 are valid. - */ - addr += A32_BANKED_CURRENT_REG_GET(env, vbar); - } - - if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) { - env->cp15.scr_el3 &= ~SCR_NS; - } - - switch_mode (env, new_mode); - /* For exceptions taken to AArch32 we must clear the SS bit in both - * PSTATE and in the old-state value we save to SPSR_, so zero it now. - */ - env->uncached_cpsr &= ~PSTATE_SS; - env->spsr = cpsr_read(env); - /* Clear IT bits. */ - env->condexec_bits = 0; - /* Switch to the new mode, and to the correct instruction set. */ - env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; - env->daif |= mask; - /* this is a lie, as the was no c1_sys on V4T/V5, but who cares - * and we should just guard the thumb mode on V4 */ - if (arm_feature(env, ARM_FEATURE_V4T)) { - env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0; - } - env->regs[14] = env->regs[15] + offset; - env->regs[15] = addr; - cs->interrupt_request |= CPU_INTERRUPT_EXITTB; -} - - -/* Return the exception level which controls this address translation regime */ -static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - switch (mmu_idx) { - case ARMMMUIdx_S2NS: - case ARMMMUIdx_S1E2: - return 2; - case ARMMMUIdx_S1E3: - return 3; - case ARMMMUIdx_S1SE0: - return arm_el_is_aa64(env, 3) ? 1 : 3; - case ARMMMUIdx_S1SE1: - case ARMMMUIdx_S1NSE0: - case ARMMMUIdx_S1NSE1: - return 1; - default: - g_assert_not_reached(); - } -} - -/* Return true if this address translation regime is secure */ -static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - switch (mmu_idx) { - case ARMMMUIdx_S12NSE0: - case ARMMMUIdx_S12NSE1: - case ARMMMUIdx_S1NSE0: - case ARMMMUIdx_S1NSE1: - case ARMMMUIdx_S1E2: - case ARMMMUIdx_S2NS: - return false; - case ARMMMUIdx_S1E3: - case ARMMMUIdx_S1SE0: - case ARMMMUIdx_S1SE1: - return true; - default: - g_assert_not_reached(); - } -} - -/* Return the SCTLR value which controls this address translation regime */ -static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - return env->cp15.sctlr_el[regime_el(env, mmu_idx)]; -} - -/* Return true if the specified stage of address translation is disabled */ -static inline bool regime_translation_disabled(CPUARMState *env, - ARMMMUIdx mmu_idx) -{ - if (mmu_idx == ARMMMUIdx_S2NS) { - return (env->cp15.hcr_el2 & HCR_VM) == 0; - } - return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0; -} - -/* Return the TCR controlling this translation regime */ -static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - if (mmu_idx == ARMMMUIdx_S2NS) { - return &env->cp15.vtcr_el2; - } - return &env->cp15.tcr_el[regime_el(env, mmu_idx)]; -} - -/* Return the TTBR associated with this translation regime */ -static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, - int ttbrn) -{ - if (mmu_idx == ARMMMUIdx_S2NS) { - return env->cp15.vttbr_el2; - } - if (ttbrn == 0) { - return env->cp15.ttbr0_el[regime_el(env, mmu_idx)]; - } else { - return env->cp15.ttbr1_el[regime_el(env, mmu_idx)]; - } -} - -/* Return true if the translation regime is using LPAE format page tables */ -static inline bool regime_using_lpae_format(CPUARMState *env, - ARMMMUIdx mmu_idx) -{ - int el = regime_el(env, mmu_idx); - if (el == 2 || arm_el_is_aa64(env, el)) { - return true; - } - if (arm_feature(env, ARM_FEATURE_LPAE) - && (regime_tcr(env, mmu_idx)->raw_tcr & TTBCR_EAE)) { - return true; - } - return false; -} - -static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - switch (mmu_idx) { - case ARMMMUIdx_S1SE0: - case ARMMMUIdx_S1NSE0: - return true; - default: - return false; - case ARMMMUIdx_S12NSE0: - case ARMMMUIdx_S12NSE1: - g_assert_not_reached(); - } -} - -/* Translate section/page access permissions to page - * R/W protection flags - * - * @env: CPUARMState - * @mmu_idx: MMU index indicating required translation regime - * @ap: The 3-bit access permissions (AP[2:0]) - * @domain_prot: The 2-bit domain access permissions - */ -static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, - int ap, int domain_prot) -{ - bool is_user = regime_is_user(env, mmu_idx); - - if (domain_prot == 3) { - return PAGE_READ | PAGE_WRITE; - } - - switch (ap) { - case 0: - if (arm_feature(env, ARM_FEATURE_V7)) { - return 0; - } - switch (regime_sctlr(env, mmu_idx) & (SCTLR_S | SCTLR_R)) { - case SCTLR_S: - return is_user ? 0 : PAGE_READ; - case SCTLR_R: - return PAGE_READ; - default: - return 0; - } - case 1: - return is_user ? 0 : PAGE_READ | PAGE_WRITE; - case 2: - if (is_user) { - return PAGE_READ; - } else { - return PAGE_READ | PAGE_WRITE; - } - case 3: - return PAGE_READ | PAGE_WRITE; - case 4: /* Reserved. */ - return 0; - case 5: - return is_user ? 0 : PAGE_READ; - case 6: - return PAGE_READ; - case 7: - if (!arm_feature(env, ARM_FEATURE_V6K)) { - return 0; - } - return PAGE_READ; - default: - g_assert_not_reached(); - } -} - -/* Translate section/page access permissions to page - * R/W protection flags. - * - * @ap: The 2-bit simple AP (AP[2:1]) - * @is_user: TRUE if accessing from PL0 - */ -static inline int simple_ap_to_rw_prot_is_user(int ap, bool is_user) -{ - switch (ap) { - case 0: - return is_user ? 0 : PAGE_READ | PAGE_WRITE; - case 1: - return PAGE_READ | PAGE_WRITE; - case 2: - return is_user ? 0 : PAGE_READ; - case 3: - return PAGE_READ; - default: - g_assert_not_reached(); - } -} - -static inline int -simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap) -{ - return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx)); -} - -/* Translate S2 section/page access permissions to protection flags - * - * @env: CPUARMState - * @s2ap: The 2-bit stage2 access permissions (S2AP) - * @xn: XN (execute-never) bit - */ -static int get_S2prot(CPUARMState *env, int s2ap, int xn) -{ - int prot = 0; - - if (s2ap & 1) { - prot |= PAGE_READ; - } - if (s2ap & 2) { - prot |= PAGE_WRITE; - } - if (!xn) { - prot |= PAGE_EXEC; - } - return prot; -} - -/* Translate section/page access permissions to protection flags - * - * @env: CPUARMState - * @mmu_idx: MMU index indicating required translation regime - * @is_aa64: TRUE if AArch64 - * @ap: The 2-bit simple AP (AP[2:1]) - * @ns: NS (non-secure) bit - * @xn: XN (execute-never) bit - * @pxn: PXN (privileged execute-never) bit - */ -static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, - int ap, int ns, int xn, int pxn) -{ - bool is_user = regime_is_user(env, mmu_idx); - int prot_rw, user_rw; - bool have_wxn; - int wxn = 0; - - assert(mmu_idx != ARMMMUIdx_S2NS); - - user_rw = simple_ap_to_rw_prot_is_user(ap, true); - if (is_user) { - prot_rw = user_rw; - } else { - prot_rw = simple_ap_to_rw_prot_is_user(ap, false); - } - - if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) { - return prot_rw; - } - - /* TODO have_wxn should be replaced with - * ARM_FEATURE_V8 || (ARM_FEATURE_V7 && ARM_FEATURE_EL2) - * when ARM_FEATURE_EL2 starts getting set. For now we assume all LPAE - * compatible processors have EL2, which is required for [U]WXN. - */ - have_wxn = arm_feature(env, ARM_FEATURE_LPAE); - - if (have_wxn) { - wxn = regime_sctlr(env, mmu_idx) & SCTLR_WXN; - } - - if (is_aa64) { - switch (regime_el(env, mmu_idx)) { - case 1: - if (!is_user) { - xn = pxn || (user_rw & PAGE_WRITE); - } - break; - case 2: - case 3: - break; - } - } else if (arm_feature(env, ARM_FEATURE_V7)) { - switch (regime_el(env, mmu_idx)) { - case 1: - case 3: - if (is_user) { - xn = xn || !(user_rw & PAGE_READ); - } else { - int uwxn = 0; - if (have_wxn) { - uwxn = regime_sctlr(env, mmu_idx) & SCTLR_UWXN; - } - xn = xn || !(prot_rw & PAGE_READ) || pxn || - (uwxn && (user_rw & PAGE_WRITE)); - } - break; - case 2: - break; - } - } else { - xn = wxn = 0; - } - - if (xn || (wxn && (prot_rw & PAGE_WRITE))) { - return prot_rw; - } - return prot_rw | PAGE_EXEC; -} - -static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, - uint32_t *table, uint32_t address) -{ - /* Note that we can only get here for an AArch32 PL0/PL1 lookup */ - TCR *tcr = regime_tcr(env, mmu_idx); - - if (address & tcr->mask) { - if (tcr->raw_tcr & TTBCR_PD1) { - /* Translation table walk disabled for TTBR1 */ - return false; - } - *table = regime_ttbr(env, mmu_idx, 1) & 0xffffc000; - } else { - if (tcr->raw_tcr & TTBCR_PD0) { - /* Translation table walk disabled for TTBR0 */ - return false; - } - *table = regime_ttbr(env, mmu_idx, 0) & tcr->base_mask; - } - *table |= (address >> 18) & 0x3ffc; - return true; -} - -/* Translate a S1 pagetable walk through S2 if needed. */ -static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, - hwaddr addr, MemTxAttrs txattrs, - uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - if ((mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1) && - !regime_translation_disabled(env, ARMMMUIdx_S2NS)) { - target_ulong s2size; - hwaddr s2pa; - int s2prot; - int ret; - - ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa, - &txattrs, &s2prot, &s2size, fsr, fi); - if (ret) { - fi->s2addr = addr; - fi->stage2 = true; - fi->s1ptw = true; - return ~0; - } - addr = s2pa; - } - return addr; -} - -/* All loads done in the course of a page table walk go through here. - * TODO: rather than ignoring errors from physical memory reads (which - * are external aborts in ARM terminology) we should propagate this - * error out so that we can turn it into a Data Abort if this walk - * was being done for a CPU load/store or an address translation instruction - * (but not if it was for a debug access). - */ -static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure, - ARMMMUIdx mmu_idx, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - MemTxAttrs attrs = {}; - - attrs.secure = is_secure; - addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi); - if (fi->s1ptw) { - return 0; - } - return address_space_ldl(cs->as, addr, attrs, NULL); -} - -static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure, - ARMMMUIdx mmu_idx, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - MemTxAttrs attrs = {}; - - attrs.secure = is_secure; - addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi); - if (fi->s1ptw) { - return 0; - } - return address_space_ldq(cs->as, addr, attrs, NULL); -} - -static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, - target_ulong *page_size, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - int code; - uint32_t table; - uint32_t desc; - int type; - int ap; - int domain = 0; - int domain_prot; - hwaddr phys_addr; - uint32_t dacr; - - /* Pagetable walk. */ - /* Lookup l1 descriptor. */ - if (!get_level1_table_address(env, mmu_idx, &table, address)) { - /* Section translation fault if page walk is disabled by PD0 or PD1 */ - code = 5; - goto do_fault; - } - desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), - mmu_idx, fsr, fi); - type = (desc & 3); - domain = (desc >> 5) & 0x0f; - if (regime_el(env, mmu_idx) == 1) { - dacr = env->cp15.dacr_ns; - } else { - dacr = env->cp15.dacr_s; - } - domain_prot = (dacr >> (domain * 2)) & 3; - if (type == 0) { - /* Section translation fault. */ - code = 5; - goto do_fault; - } - if (domain_prot == 0 || domain_prot == 2) { - if (type == 2) - code = 9; /* Section domain fault. */ - else - code = 11; /* Page domain fault. */ - goto do_fault; - } - if (type == 2) { - /* 1Mb section. */ - phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); - ap = (desc >> 10) & 3; - code = 13; - *page_size = 1024 * 1024; - } else { - /* Lookup l2 entry. */ - if (type == 1) { - /* Coarse pagetable. */ - table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); - } else { - /* Fine pagetable. */ - table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); - } - desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), - mmu_idx, fsr, fi); - switch (desc & 3) { - case 0: /* Page translation fault. */ - code = 7; - goto do_fault; - case 1: /* 64k page. */ - phys_addr = (desc & 0xffff0000) | (address & 0xffff); - ap = (desc >> (4 + ((address >> 13) & 6))) & 3; - *page_size = 0x10000; - break; - case 2: /* 4k page. */ - phys_addr = (desc & 0xfffff000) | (address & 0xfff); - ap = (desc >> (4 + ((address >> 9) & 6))) & 3; - *page_size = 0x1000; - break; - case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */ - if (type == 1) { - /* ARMv6/XScale extended small page format */ - if (arm_feature(env, ARM_FEATURE_XSCALE) - || arm_feature(env, ARM_FEATURE_V6)) { - phys_addr = (desc & 0xfffff000) | (address & 0xfff); - *page_size = 0x1000; - } else { - /* UNPREDICTABLE in ARMv5; we choose to take a - * page translation fault. - */ - code = 7; - goto do_fault; - } - } else { - phys_addr = (desc & 0xfffffc00) | (address & 0x3ff); - *page_size = 0x400; - } - ap = (desc >> 4) & 3; - break; - default: - /* Never happens, but compiler isn't smart enough to tell. */ - abort(); - } - code = 15; - } - *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot); - *prot |= *prot ? PAGE_EXEC : 0; - if (!(*prot & (1 << access_type))) { - /* Access permission fault. */ - goto do_fault; - } - *phys_ptr = phys_addr; - return false; -do_fault: - *fsr = code | (domain << 4); - return true; -} - -static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, - target_ulong *page_size, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - int code; - uint32_t table; - uint32_t desc; - uint32_t xn; - uint32_t pxn = 0; - int type; - int ap; - int domain = 0; - int domain_prot; - hwaddr phys_addr; - uint32_t dacr; - bool ns; - - /* Pagetable walk. */ - /* Lookup l1 descriptor. */ - if (!get_level1_table_address(env, mmu_idx, &table, address)) { - /* Section translation fault if page walk is disabled by PD0 or PD1 */ - code = 5; - goto do_fault; - } - desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), - mmu_idx, fsr, fi); - type = (desc & 3); - if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) { - /* Section translation fault, or attempt to use the encoding - * which is Reserved on implementations without PXN. - */ - code = 5; - goto do_fault; - } - if ((type == 1) || !(desc & (1 << 18))) { - /* Page or Section. */ - domain = (desc >> 5) & 0x0f; - } - if (regime_el(env, mmu_idx) == 1) { - dacr = env->cp15.dacr_ns; - } else { - dacr = env->cp15.dacr_s; - } - domain_prot = (dacr >> (domain * 2)) & 3; - if (domain_prot == 0 || domain_prot == 2) { - if (type != 1) { - code = 9; /* Section domain fault. */ - } else { - code = 11; /* Page domain fault. */ - } - goto do_fault; - } - if (type != 1) { - if (desc & (1 << 18)) { - /* Supersection. */ - phys_addr = (desc & 0xff000000) | (address & 0x00ffffff); - phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32; - phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36; - *page_size = 0x1000000; - } else { - /* Section. */ - phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); - *page_size = 0x100000; - } - ap = ((desc >> 10) & 3) | ((desc >> 13) & 4); - xn = desc & (1 << 4); - pxn = desc & 1; - code = 13; - ns = extract32(desc, 19, 1); - } else { - if (arm_feature(env, ARM_FEATURE_PXN)) { - pxn = (desc >> 2) & 1; - } - ns = extract32(desc, 3, 1); - /* Lookup l2 entry. */ - table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); - desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx), - mmu_idx, fsr, fi); - ap = ((desc >> 4) & 3) | ((desc >> 7) & 4); - switch (desc & 3) { - case 0: /* Page translation fault. */ - code = 7; - goto do_fault; - case 1: /* 64k page. */ - phys_addr = (desc & 0xffff0000) | (address & 0xffff); - xn = desc & (1 << 15); - *page_size = 0x10000; - break; - case 2: case 3: /* 4k page. */ - phys_addr = (desc & 0xfffff000) | (address & 0xfff); - xn = desc & 1; - *page_size = 0x1000; - break; - default: - /* Never happens, but compiler isn't smart enough to tell. */ - abort(); - } - code = 15; - } - if (domain_prot == 3) { - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - } else { - if (pxn && !regime_is_user(env, mmu_idx)) { - xn = 1; - } - if (xn && access_type == 2) - goto do_fault; - - if (arm_feature(env, ARM_FEATURE_V6K) && - (regime_sctlr(env, mmu_idx) & SCTLR_AFE)) { - /* The simplified model uses AP[0] as an access control bit. */ - if ((ap & 1) == 0) { - /* Access flag fault. */ - code = (code == 15) ? 6 : 3; - goto do_fault; - } - *prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1); - } else { - *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot); - } - if (*prot && !xn) { - *prot |= PAGE_EXEC; - } - if (!(*prot & (1 << access_type))) { - /* Access permission fault. */ - goto do_fault; - } - } - if (ns) { - /* The NS bit will (as required by the architecture) have no effect if - * the CPU doesn't support TZ or this is a non-secure translation - * regime, because the attribute will already be non-secure. - */ - attrs->secure = false; - } - *phys_ptr = phys_addr; - return false; -do_fault: - *fsr = code | (domain << 4); - return true; -} - -/* Fault type for long-descriptor MMU fault reporting; this corresponds - * to bits [5..2] in the STATUS field in long-format DFSR/IFSR. - */ -typedef enum { - translation_fault = 1, - access_fault = 2, - permission_fault = 3, -} MMUFaultType; - -/* - * check_s2_startlevel - * @cpu: ARMCPU - * @is_aa64: True if the translation regime is in AArch64 state - * @startlevel: Suggested starting level - * @inputsize: Bitsize of IPAs - * @stride: Page-table stride (See the ARM ARM) - * - * Returns true if the suggested starting level is OK and false otherwise. - */ -static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level, - int inputsize, int stride) -{ - /* Negative levels are never allowed. */ - if (level < 0) { - return false; - } - - if (is_aa64) { - unsigned int pamax = arm_pamax(cpu); - - switch (stride) { - case 13: /* 64KB Pages. */ - if (level == 0 || (level == 1 && pamax <= 42)) { - return false; - } - break; - case 11: /* 16KB Pages. */ - if (level == 0 || (level == 1 && pamax <= 40)) { - return false; - } - break; - case 9: /* 4KB Pages. */ - if (level == 0 && pamax <= 42) { - return false; - } - break; - default: - g_assert_not_reached(); - } - } else { - const int grainsize = stride + 3; - int startsizecheck; - - /* AArch32 only supports 4KB pages. Assert on that. */ - assert(stride == 9); - - if (level == 0) { - return false; - } - - startsizecheck = inputsize - ((3 - level) * stride + grainsize); - if (startsizecheck < 1 || startsizecheck > stride + 4) { - return false; - } - } - return true; -} - -static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot, - target_ulong *page_size_ptr, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - /* Read an LPAE long-descriptor translation table. */ - MMUFaultType fault_type = translation_fault; - uint32_t level = 1; - uint32_t epd = 0; - int32_t t0sz, t1sz; - uint32_t tg; - uint64_t ttbr; - int ttbr_select; - hwaddr descaddr, descmask; - uint32_t tableattrs; - target_ulong page_size; - uint32_t attrs; - int32_t stride = 9; - int32_t va_size = 32; - int inputsize; - int32_t tbi = 0; - TCR *tcr = regime_tcr(env, mmu_idx); - int ap, ns, xn, pxn; - uint32_t el = regime_el(env, mmu_idx); - bool ttbr1_valid = true; - uint64_t descaddrmask; - - /* TODO: - * This code does not handle the different format TCR for VTCR_EL2. - * This code also does not support shareability levels. - * Attribute and permission bit handling should also be checked when adding - * support for those page table walks. - */ - if (arm_el_is_aa64(env, el)) { - va_size = 64; - if (el > 1) { - if (mmu_idx != ARMMMUIdx_S2NS) { - tbi = extract64(tcr->raw_tcr, 20, 1); - } - } else { - if (extract64(address, 55, 1)) { - tbi = extract64(tcr->raw_tcr, 38, 1); - } else { - tbi = extract64(tcr->raw_tcr, 37, 1); - } - } - tbi *= 8; - - /* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it - * invalid. - */ - if (el > 1) { - ttbr1_valid = false; - } - } else { - /* There is no TTBR1 for EL2 */ - if (el == 2) { - ttbr1_valid = false; - } - } - - /* Determine whether this address is in the region controlled by - * TTBR0 or TTBR1 (or if it is in neither region and should fault). - * This is a Non-secure PL0/1 stage 1 translation, so controlled by - * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32: - */ - if (va_size == 64) { - /* AArch64 translation. */ - t0sz = extract32(tcr->raw_tcr, 0, 6); - t0sz = MIN(t0sz, 39); - t0sz = MAX(t0sz, 16); - } else if (mmu_idx != ARMMMUIdx_S2NS) { - /* AArch32 stage 1 translation. */ - t0sz = extract32(tcr->raw_tcr, 0, 3); - } else { - /* AArch32 stage 2 translation. */ - bool sext = extract32(tcr->raw_tcr, 4, 1); - bool sign = extract32(tcr->raw_tcr, 3, 1); - t0sz = sextract32(tcr->raw_tcr, 0, 4); - - /* If the sign-extend bit is not the same as t0sz[3], the result - * is unpredictable. Flag this as a guest error. */ - if (sign != sext) { - qemu_log_mask(LOG_GUEST_ERROR, - "AArch32: VTCR.S / VTCR.T0SZ[3] missmatch\n"); - } - } - t1sz = extract32(tcr->raw_tcr, 16, 6); - if (va_size == 64) { - t1sz = MIN(t1sz, 39); - t1sz = MAX(t1sz, 16); - } - if (t0sz && !extract64(address, va_size - t0sz, t0sz - tbi)) { - /* there is a ttbr0 region and we are in it (high bits all zero) */ - ttbr_select = 0; - } else if (ttbr1_valid && t1sz && - !extract64(~address, va_size - t1sz, t1sz - tbi)) { - /* there is a ttbr1 region and we are in it (high bits all one) */ - ttbr_select = 1; - } else if (!t0sz) { - /* ttbr0 region is "everything not in the ttbr1 region" */ - ttbr_select = 0; - } else if (!t1sz && ttbr1_valid) { - /* ttbr1 region is "everything not in the ttbr0 region" */ - ttbr_select = 1; - } else { - /* in the gap between the two regions, this is a Translation fault */ - fault_type = translation_fault; - goto do_fault; - } - - /* Note that QEMU ignores shareability and cacheability attributes, - * so we don't need to do anything with the SH, ORGN, IRGN fields - * in the TTBCR. Similarly, TTBCR:A1 selects whether we get the - * ASID from TTBR0 or TTBR1, but QEMU's TLB doesn't currently - * implement any ASID-like capability so we can ignore it (instead - * we will always flush the TLB any time the ASID is changed). - */ - if (ttbr_select == 0) { - ttbr = regime_ttbr(env, mmu_idx, 0); - if (el < 2) { - epd = extract32(tcr->raw_tcr, 7, 1); - } - inputsize = va_size - t0sz; - - tg = extract32(tcr->raw_tcr, 14, 2); - if (tg == 1) { /* 64KB pages */ - stride = 13; - } - if (tg == 2) { /* 16KB pages */ - stride = 11; - } - } else { - /* We should only be here if TTBR1 is valid */ - assert(ttbr1_valid); - - ttbr = regime_ttbr(env, mmu_idx, 1); - epd = extract32(tcr->raw_tcr, 23, 1); - inputsize = va_size - t1sz; - - tg = extract32(tcr->raw_tcr, 30, 2); - if (tg == 3) { /* 64KB pages */ - stride = 13; - } - if (tg == 1) { /* 16KB pages */ - stride = 11; - } - } - - /* Here we should have set up all the parameters for the translation: - * va_size, inputsize, ttbr, epd, stride, tbi - */ - - if (epd) { - /* Translation table walk disabled => Translation fault on TLB miss - * Note: This is always 0 on 64-bit EL2 and EL3. - */ - goto do_fault; - } - - if (mmu_idx != ARMMMUIdx_S2NS) { - /* The starting level depends on the virtual address size (which can - * be up to 48 bits) and the translation granule size. It indicates - * the number of strides (stride bits at a time) needed to - * consume the bits of the input address. In the pseudocode this is: - * level = 4 - RoundUp((inputsize - grainsize) / stride) - * where their 'inputsize' is our 'inputsize', 'grainsize' is - * our 'stride + 3' and 'stride' is our 'stride'. - * Applying the usual "rounded up m/n is (m+n-1)/n" and simplifying: - * = 4 - (inputsize - stride - 3 + stride - 1) / stride - * = 4 - (inputsize - 4) / stride; - */ - level = 4 - (inputsize - 4) / stride; - } else { - /* For stage 2 translations the starting level is specified by the - * VTCR_EL2.SL0 field (whose interpretation depends on the page size) - */ - int startlevel = extract32(tcr->raw_tcr, 6, 2); - bool ok; - - if (va_size == 32 || stride == 9) { - /* AArch32 or 4KB pages */ - level = 2 - startlevel; - } else { - /* 16KB or 64KB pages */ - level = 3 - startlevel; - } - - /* Check that the starting level is valid. */ - ok = check_s2_startlevel(cpu, va_size == 64, level, - inputsize, stride); - if (!ok) { - /* AArch64 reports these as level 0 faults. - * AArch32 reports these as level 1 faults. - */ - level = va_size == 64 ? 0 : 1; - fault_type = translation_fault; - goto do_fault; - } - } - - /* Clear the vaddr bits which aren't part of the within-region address, - * so that we don't have to special case things when calculating the - * first descriptor address. - */ - if (va_size != inputsize) { - address &= (1ULL << inputsize) - 1; - } - - descmask = (1ULL << (stride + 3)) - 1; - - /* Now we can extract the actual base address from the TTBR */ - descaddr = extract64(ttbr, 0, 48); - descaddr &= ~((1ULL << (inputsize - (stride * (4 - level)))) - 1); - - /* The address field in the descriptor goes up to bit 39 for ARMv7 - * but up to bit 47 for ARMv8. - */ - if (arm_feature(env, ARM_FEATURE_V8)) { - descaddrmask = 0xfffffffff000ULL; - } else { - descaddrmask = 0xfffffff000ULL; - } - - /* Secure accesses start with the page table in secure memory and - * can be downgraded to non-secure at any step. Non-secure accesses - * remain non-secure. We implement this by just ORing in the NSTable/NS - * bits at each step. - */ - tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4); - for (;;) { - uint64_t descriptor; - bool nstable; - - descaddr |= (address >> (stride * (4 - level))) & descmask; - descaddr &= ~7ULL; - nstable = extract32(tableattrs, 4, 1); - descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi); - if (fi->s1ptw) { - goto do_fault; - } - - if (!(descriptor & 1) || - (!(descriptor & 2) && (level == 3))) { - /* Invalid, or the Reserved level 3 encoding */ - goto do_fault; - } - descaddr = descriptor & descaddrmask; - - if ((descriptor & 2) && (level < 3)) { - /* Table entry. The top five bits are attributes which may - * propagate down through lower levels of the table (and - * which are all arranged so that 0 means "no effect", so - * we can gather them up by ORing in the bits at each level). - */ - tableattrs |= extract64(descriptor, 59, 5); - level++; - continue; - } - /* Block entry at level 1 or 2, or page entry at level 3. - * These are basically the same thing, although the number - * of bits we pull in from the vaddr varies. - */ - page_size = (1ULL << ((stride * (4 - level)) + 3)); - descaddr |= (address & (page_size - 1)); - /* Extract attributes from the descriptor */ - attrs = extract64(descriptor, 2, 10) - | (extract64(descriptor, 52, 12) << 10); - - if (mmu_idx == ARMMMUIdx_S2NS) { - /* Stage 2 table descriptors do not include any attribute fields */ - break; - } - /* Merge in attributes from table descriptors */ - attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ - attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */ - /* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 - * means "force PL1 access only", which means forcing AP[1] to 0. - */ - if (extract32(tableattrs, 2, 1)) { - attrs &= ~(1 << 4); - } - attrs |= nstable << 3; /* NS */ - break; - } - /* Here descaddr is the final physical address, and attributes - * are all in attrs. - */ - fault_type = access_fault; - if ((attrs & (1 << 8)) == 0) { - /* Access flag */ - goto do_fault; - } - - ap = extract32(attrs, 4, 2); - xn = extract32(attrs, 12, 1); - - if (mmu_idx == ARMMMUIdx_S2NS) { - ns = true; - *prot = get_S2prot(env, ap, xn); - } else { - ns = extract32(attrs, 3, 1); - pxn = extract32(attrs, 11, 1); - *prot = get_S1prot(env, mmu_idx, va_size == 64, ap, ns, xn, pxn); - } - - fault_type = permission_fault; - if (!(*prot & (1 << access_type))) { - goto do_fault; - } - - if (ns) { - /* The NS bit will (as required by the architecture) have no effect if - * the CPU doesn't support TZ or this is a non-secure translation - * regime, because the attribute will already be non-secure. - */ - txattrs->secure = false; - } - *phys_ptr = descaddr; - *page_size_ptr = page_size; - return false; - -do_fault: - /* Long-descriptor format IFSR/DFSR value */ - *fsr = (1 << 9) | (fault_type << 2) | level; - /* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */ - fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS); - return true; -} - -static inline void get_phys_addr_pmsav7_default(CPUARMState *env, - ARMMMUIdx mmu_idx, - int32_t address, int *prot) -{ - *prot = PAGE_READ | PAGE_WRITE; - switch (address) { - case 0xF0000000 ... 0xFFFFFFFF: - if (regime_sctlr(env, mmu_idx) & SCTLR_V) { /* hivecs execing is ok */ - *prot |= PAGE_EXEC; - } - break; - case 0x00000000 ... 0x7FFFFFFF: - *prot |= PAGE_EXEC; - break; - } - -} - -static inline void get_phys_addr_v7m_default(CPUARMState *env, - ARMMMUIdx mmu_idx, - int32_t address, int *prot) -{ - *prot = PAGE_READ | PAGE_WRITE; - switch (address) { - case 0xFFFFF000 ... 0xFFFFFFFF: - /* the special exception return address memory region is EXEC only */ - *prot = PAGE_EXEC; - break; - - case 0x00000000 ... 0x1FFFFFFF: - case 0x20000000 ... 0x3FFFFFFF: - case 0x60000000 ... 0x7FFFFFFF: - case 0x80000000 ... 0x9FFFFFFF: - *prot |= PAGE_EXEC; - break; - } -} - -#if 1 -static bool get_phys_addr_pmsav7_regions(CPUARMState *env, uint32_t address, - ARMMMUIdx mmu_idx, int *prot) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - bool is_user = regime_is_user(env, mmu_idx); - int match = -1; - for (int n = 0; n < cpu->pmsav7_dregion; ++n) { - /* region search */ - uint32_t base = env->pmsav7.drbar[n]; - uint32_t rsizebits = extract32(env->pmsav7.drsr[n], 1, 5); - uint32_t rsize = 1 << (rsizebits + 1); - bool enabled = (env->pmsav7.drsr[n] & 0x1); - bool outside_range = (address < base) || (address >= (base + rsize)); - if (!enabled) { - continue; - } - if (outside_range) { - continue; - } - if (rsize >= 256) { /* subregions only if region is big enough */ - uint32_t region_size = rsize / 8; - uint32_t region = (address - base) / region_size; - uint8_t srdis = extract32(env->pmsav7.drsr[n], 8, 8); - if (srdis & (1 << region)) { /* disabled - not really a match */ - continue; - } else { - } - } - match = n; - } - if (match == -1) { - return false; /* we didn't match a region or subregion... */ - } - /* set the permissions while we're here... */ - uint32_t ap = extract32(env->pmsav7.dracr[match], 8, 3); - if ((ap == 7) && arm_feature(env, ARM_FEATURE_M)) - ap = 6; - - if (is_user) { /* User mode AP bit decoding */ - switch (ap) { - case 0: - case 1: - case 5: - break; /* no access */ - case 3: - *prot |= PAGE_WRITE; - /* fall through */ - case 2: - case 6: - *prot |= PAGE_READ | PAGE_EXEC; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "Bad value for AP bits in DRACR %" - PRIx32 "\n", ap); - } - } else { /* Priv. mode AP bits decoding */ - switch (ap) { - case 0: - break; /* no access */ - case 1: - case 2: - case 3: - *prot |= PAGE_WRITE; - /* fall through */ - case 5: - case 6: - *prot |= PAGE_READ | PAGE_EXEC; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "Bad value for AP bits in DRACR %" - PRIx32 "\n", ap); - } - } - /* execute never */ - if (env->pmsav7.dracr[match] & (1 << 12)) { - *prot &= ~PAGE_EXEC; - } - return true; -} - -static bool get_phys_addr_pmsav7_sub(CPUARMState *env, uint32_t address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, uint32_t *fsr) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - bool is_user = regime_is_user(env, mmu_idx); - - *phys_ptr = address; - *prot = 0; - - if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ - if (arm_feature(env, ARM_FEATURE_M)) { - get_phys_addr_v7m_default(env, mmu_idx, address, prot); - } else { - get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); - } - } else { /* MPU enabled */ - if (!get_phys_addr_pmsav7_regions(env, address, mmu_idx, prot)) { - if (cpu->pmsav7_dregion && (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR))) { - /* background fault */ - *fsr = 0; - return true; - } - if (arm_feature(env, ARM_FEATURE_M)) { - get_phys_addr_v7m_default(env, mmu_idx, address, prot); - } else { - get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); - } - } - } - - *fsr = 0x00d; /* Permission fault */ - return !(*prot & (1 << access_type)); -} - -#else - -static bool get_phys_addr_pmsav7_sub(CPUARMState *env, uint32_t address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, uint32_t *fsr) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int n; - bool is_user = regime_is_user(env, mmu_idx); - - *phys_ptr = address; - *prot = 0; - - if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ - if (arm_feature(env, ARM_FEATURE_M)) { - get_phys_addr_v7m_default(env, mmu_idx, address, prot); - } else { - get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); - } - } else { /* MPU enabled */ - for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { - /* region search */ - uint32_t base = env->pmsav7.drbar[n]; - uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5); - uint32_t rmask; - bool srdis = false; - - if (!(env->pmsav7.drsr[n] & 0x1)) { - continue; - } - - if (!rsize) { - qemu_log_mask(LOG_GUEST_ERROR, "DRSR.Rsize field can not be 0"); - continue; - } - rsize++; - rmask = (1ull << rsize) - 1; - - if (base & rmask) { - qemu_log_mask(LOG_GUEST_ERROR, "DRBAR %" PRIx32 " misaligned " - "to DRSR region size, mask = %" PRIx32, - base, rmask); - continue; - } - - if (address < base || address > base + rmask) { - continue; - } - - /* Region matched */ - - if (rsize >= 8) { /* no subregions for regions < 256 bytes */ - int i, snd; - uint32_t srdis_mask; - - rsize -= 3; /* sub region size (power of 2) */ - snd = ((address - base) >> rsize) & 0x7; - srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1); - - srdis_mask = srdis ? 0x3 : 0x0; - for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) { - /* This will check in groups of 2, 4 and then 8, whether - * the subregion bits are consistent. rsize is incremented - * back up to give the region size, considering consistent - * adjacent subregions as one region. Stop testing if rsize - * is already big enough for an entire QEMU page. - */ - int snd_rounded = snd & ~(i - 1); - uint32_t srdis_multi = extract32(env->pmsav7.drsr[n], - snd_rounded + 8, i); - if (srdis_mask ^ srdis_multi) { - break; - } - srdis_mask = (srdis_mask << i) | srdis_mask; - rsize++; - } - if (rsize < TARGET_PAGE_BITS) { - qemu_log_mask(LOG_UNIMP, "No support for MPU (sub)region" - "alignment of %" PRIu32 " bits. Minimum is %d\n", - rsize, TARGET_PAGE_BITS); - continue; - } - if (srdis) { - continue; - } - } - break; - } - - if (n == -1) { /* no hits */ - if (cpu->pmsav7_dregion && - (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR))) { - /* background fault */ - *fsr = 0; - return true; - } - if (arm_feature(env, ARM_FEATURE_M)) { - get_phys_addr_v7m_default(env, mmu_idx, address, prot); - } else { - get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); - } - } else { /* a MPU hit! */ - uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3); - if ((ap == 7) && arm_feature(env, ARM_FEATURE_M)) - ap = 6; - - if (is_user) { /* User mode AP bit decoding */ - switch (ap) { - case 0: - case 1: - case 5: - break; /* no access */ - case 3: - *prot |= PAGE_WRITE; - /* fall through */ - case 2: - case 6: - *prot |= PAGE_READ | PAGE_EXEC; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "Bad value for AP bits in DRACR %" - PRIx32 "\n", ap); - } - } else { /* Priv. mode AP bits decoding */ - switch (ap) { - case 0: - break; /* no access */ - case 1: - case 2: - case 3: - *prot |= PAGE_WRITE; - /* fall through */ - case 5: - case 6: - *prot |= PAGE_READ | PAGE_EXEC; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "Bad value for AP bits in DRACR %" - PRIx32 "\n", ap); - } - } - /* execute never */ - if (env->pmsav7.dracr[n] & (1 << 12)) { - *prot &= ~PAGE_EXEC; - } - - } - } - - *fsr = 0x00d; /* Permission fault */ - return !(*prot & (1 << access_type)); -} -#endif - -static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, uint32_t *fsr) -{ - g_mutex_lock(&helper_mmu_lock); - bool ret = get_phys_addr_pmsav7_sub(env, address, access_type, mmu_idx, phys_ptr, prot, fsr); - g_mutex_unlock(&helper_mmu_lock); - return ret; -} -static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, uint32_t *fsr) -{ - int n; - uint32_t mask; - uint32_t base; - bool is_user = regime_is_user(env, mmu_idx); - - *phys_ptr = address; - for (n = 7; n >= 0; n--) { - base = env->cp15.c6_region[n]; - if ((base & 1) == 0) { - continue; - } - mask = 1 << ((base >> 1) & 0x1f); - /* Keep this shift separate from the above to avoid an - (undefined) << 32. */ - mask = (mask << 1) - 1; - if (((base ^ address) & ~mask) == 0) { - break; - } - } - if (n < 0) { - *fsr = 2; - return true; - } - - if (access_type == 2) { - mask = env->cp15.pmsav5_insn_ap; - } else { - mask = env->cp15.pmsav5_data_ap; - } - mask = (mask >> (n * 4)) & 0xf; - switch (mask) { - case 0: - *fsr = 1; - return true; - case 1: - if (is_user) { - *fsr = 1; - return true; - } - *prot = PAGE_READ | PAGE_WRITE; - break; - case 2: - *prot = PAGE_READ; - if (!is_user) { - *prot |= PAGE_WRITE; - } - break; - case 3: - *prot = PAGE_READ | PAGE_WRITE; - break; - case 5: - if (is_user) { - *fsr = 1; - return true; - } - *prot = PAGE_READ; - break; - case 6: - *prot = PAGE_READ; - break; - default: - /* Bad permission. */ - *fsr = 1; - return true; - } - *prot |= PAGE_EXEC; - return false; -} - -/* get_phys_addr - get the physical address for this virtual address - * - * Find the physical address corresponding to the given virtual address, - * by doing a translation table walk on MMU based systems or using the - * MPU state on MPU based systems. - * - * Returns false if the translation was successful. Otherwise, phys_ptr, attrs, - * prot and page_size may not be filled in, and the populated fsr value provides - * information on why the translation aborted, in the format of a - * DFSR/IFSR fault register, with the following caveats: - * * we honour the short vs long DFSR format differences. - * * the WnR bit is never set (the caller must do this). - * * for PSMAv5 based systems we don't bother to return a full FSR format - * value. - * - * @env: CPUARMState - * @address: virtual address to get physical address for - * @access_type: 0 for read, 1 for write, 2 for execute - * @mmu_idx: MMU index indicating required translation regime - * @phys_ptr: set to the physical address corresponding to the virtual address - * @attrs: set to the memory transaction attributes to use - * @prot: set to the permissions for the page containing phys_ptr - * @page_size: set to the size of the page containing phys_ptr - * @fsr: set to the DFSR/IFSR value on failure - */ -static bool get_phys_addr(CPUARMState *env, target_ulong address, - int access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot, - target_ulong *page_size, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - - if ((address >= 0x20017F00) && (address < 0x20018020)) { - DPRINTF("get_phys_addr(%08X)\n", address); - } - - if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { - /* Call ourselves recursively to do the stage 1 and then stage 2 - * translations. - */ - if (arm_feature(env, ARM_FEATURE_EL2)) { - hwaddr ipa; - int s2_prot; - int ret; - - ret = get_phys_addr(env, address, access_type, - mmu_idx + ARMMMUIdx_S1NSE0, &ipa, attrs, - prot, page_size, fsr, fi); - - /* If S1 fails or S2 is disabled, return early. */ - if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) { - *phys_ptr = ipa; - return ret; - } - - /* S1 is done. Now do S2 translation. */ - ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS, - phys_ptr, attrs, &s2_prot, - page_size, fsr, fi); - fi->s2addr = ipa; - /* Combine the S1 and S2 perms. */ - *prot &= s2_prot; - return ret; - } else { - /* - * For non-EL2 CPUs a stage1+stage2 translation is just stage 1. - */ - mmu_idx += ARMMMUIdx_S1NSE0; - } - } - - /* The page table entries may downgrade secure to non-secure, but - * cannot upgrade an non-secure translation regime's attributes - * to secure. - */ - attrs->secure = regime_is_secure(env, mmu_idx); - attrs->user = regime_is_user(env, mmu_idx); - - /* Fast Context Switch Extension. This doesn't exist at all in v8. - * In v7 and earlier it affects all stage 1 translations. - */ - if (address < 0x02000000 && mmu_idx != ARMMMUIdx_S2NS - && !arm_feature(env, ARM_FEATURE_V8)) { - if (regime_el(env, mmu_idx) == 3) { - address += env->cp15.fcseidr_s; - } else { - address += env->cp15.fcseidr_ns; - } - } - - /* pmsav7 has special handling for when MPU is disabled so call it before - * the common MMU/MPU disabled check below. - */ - if (arm_feature(env, ARM_FEATURE_MPU) && - arm_feature(env, ARM_FEATURE_V7)) { - *page_size = TARGET_PAGE_SIZE; - return get_phys_addr_pmsav7(env, address, access_type, mmu_idx, - phys_ptr, prot, fsr); - } - - if (regime_translation_disabled(env, mmu_idx)) { - /* MMU/MPU disabled. */ - *phys_ptr = address; - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - *page_size = TARGET_PAGE_SIZE; - return 0; - } - - if (arm_feature(env, ARM_FEATURE_MPU)) { - /* Pre-v7 MPU */ - *page_size = TARGET_PAGE_SIZE; - return get_phys_addr_pmsav5(env, address, access_type, mmu_idx, - phys_ptr, prot, fsr); - } - - if (regime_using_lpae_format(env, mmu_idx)) { - return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr, - attrs, prot, page_size, fsr, fi); - } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { - return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr, - attrs, prot, page_size, fsr, fi); - } else { - return get_phys_addr_v5(env, address, access_type, mmu_idx, phys_ptr, - prot, page_size, fsr, fi); - } -} - -/* Walk the page table and (if the mapping exists) add the page - * to the TLB. Return false on success, or true on failure. Populate - * fsr with ARM DFSR/IFSR fault register format value on failure. - */ -bool arm_tlb_fill(CPUState *cs, vaddr address, - int access_type, int mmu_idx, uint32_t *fsr, - ARMMMUFaultInfo *fi) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - hwaddr phys_addr; - target_ulong page_size; - int prot; - int ret; - MemTxAttrs attrs = {}; - - ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr, - &attrs, &prot, &page_size, fsr, fi); - if (!ret) { - /* Map a single [sub]page. */ - phys_addr &= TARGET_PAGE_MASK; - address &= TARGET_PAGE_MASK; - tlb_set_page_with_attrs(cs, address, phys_addr, attrs, - prot, mmu_idx, page_size); - return 0; - } - - return ret; -} - -hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - hwaddr phys_addr; - target_ulong page_size; - int prot; - bool ret; - uint32_t fsr; - MemTxAttrs attrs = {}; - ARMMMUFaultInfo fi = {}; - - ret = get_phys_addr(env, addr, 0, cpu_mmu_index(env, false), &phys_addr, - &attrs, &prot, &page_size, &fsr, &fi); - - if (ret) { - return -1; - } - - return phys_addr; -} - -void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val) -{ - if ((env->uncached_cpsr & CPSR_M) == mode) { - env->regs[13] = val; - } else { - env->banked_r13[bank_number(mode)] = val; - } -} - -uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode) -{ - if ((env->uncached_cpsr & CPSR_M) == mode) { - return env->regs[13]; - } else { - return env->banked_r13[bank_number(mode)]; - } -} - -uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - switch (reg) { - case 0: /* APSR */ - return xpsr_read(env) & 0xf8000000; - case 1: /* IAPSR */ - return xpsr_read(env) & 0xf80001ff; - case 2: /* EAPSR */ - return xpsr_read(env) & 0xff00fc00; - case 3: /* xPSR */ - return xpsr_read(env) & 0xff00fdff; - case 5: /* IPSR */ - return xpsr_read(env) & 0x000001ff; - case 6: /* EPSR */ - return xpsr_read(env) & 0x0700fc00; - case 7: /* IEPSR */ - return xpsr_read(env) & 0x0700edff; - case 8: /* MSP */ - return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]; - case 9: /* PSP */ - return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp; - case 16: /* PRIMASK */ - return (env->daif & PSTATE_I) != 0; - case 17: /* BASEPRI */ - case 18: /* BASEPRI_MAX */ - return env->v7m.basepri; - case 19: /* FAULTMASK */ - return (env->daif & PSTATE_F) != 0; - case 20: /* CONTROL */ - return env->v7m.control; - default: - /* ??? For debugging only. */ - cpu_abort(CPU(cpu), "Unimplemented system register read (%d)\n", reg); - return 0; - } -} - -void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - switch (reg) { - case 0: /* APSR */ - xpsr_write(env, val, 0xf8000000); - break; - case 1: /* IAPSR */ - xpsr_write(env, val, 0xf8000000); - break; - case 2: /* EAPSR */ - xpsr_write(env, val, 0xfe00fc00); - break; - case 3: /* xPSR */ - xpsr_write(env, val, 0xfe00fc00); - break; - case 5: /* IPSR */ - /* IPSR bits are readonly. */ - break; - case 6: /* EPSR */ - xpsr_write(env, val, 0x0600fc00); - break; - case 7: /* IEPSR */ - xpsr_write(env, val, 0x0600fc00); - break; - case 8: /* MSP */ - if (env->v7m.current_sp) - env->v7m.other_sp = val; - else - env->regs[13] = val; - break; - case 9: /* PSP */ - if (env->v7m.current_sp) - env->regs[13] = val; - else - env->v7m.other_sp = val; - break; - case 16: /* PRIMASK */ - if (val & 1) { - env->daif |= PSTATE_I; - } else { - env->daif &= ~PSTATE_I; - } - break; - case 17: /* BASEPRI */ - env->v7m.basepri = val & 0xff; - armv7m_nvic_set_base_priority(env->nvic, env->v7m.basepri); - break; - case 18: /* BASEPRI_MAX */ - val &= 0xff; - if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) { - env->v7m.basepri = val; - armv7m_nvic_set_base_priority(env->nvic, env->v7m.basepri); - } - break; - case 19: /* FAULTMASK */ - if (val & 1) { - env->daif |= PSTATE_F; - } else { - env->daif &= ~PSTATE_F; - } - break; - case 20: /* CONTROL */ - env->v7m.control = val & 3; - switch_v7m_sp(env, (env->v7m.exception == 0) && ((val & 2) != 0)); - break; - default: - /* ??? For debugging only. */ - cpu_abort(CPU(cpu), "Unimplemented system register write (%d)\n", reg); - return; - } -} - -#endif - -void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) -{ - /* Implement DC ZVA, which zeroes a fixed-length block of memory. - * Note that we do not implement the (architecturally mandated) - * alignment fault for attempts to use this on Device memory - * (which matches the usual QEMU behaviour of not implementing either - * alignment faults or any memory attribute handling). - */ - - ARMCPU *cpu = arm_env_get_cpu(env); - uint64_t blocklen = 4 << cpu->dcz_blocksize; - uint64_t vaddr = vaddr_in & ~(blocklen - 1); - -#ifndef CONFIG_USER_ONLY - { - /* Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than - * the block size so we might have to do more than one TLB lookup. - * We know that in fact for any v8 CPU the page size is at least 4K - * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only - * 1K as an artefact of legacy v5 subpage support being present in the - * same QEMU executable. - */ - int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE); - void *hostaddr[maxidx]; - int try, i; - unsigned mmu_idx = cpu_mmu_index(env, false); - TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx); - - for (try = 0; try < 2; try++) { - - for (i = 0; i < maxidx; i++) { - hostaddr[i] = tlb_vaddr_to_host(env, - vaddr + TARGET_PAGE_SIZE * i, - 1, mmu_idx); - if (!hostaddr[i]) { - break; - } - } - if (i == maxidx) { - /* If it's all in the TLB it's fair game for just writing to; - * we know we don't need to update dirty status, etc. - */ - for (i = 0; i < maxidx - 1; i++) { - memset(hostaddr[i], 0, TARGET_PAGE_SIZE); - } - memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE)); - return; - } - /* OK, try a store and see if we can populate the tlb. This - * might cause an exception if the memory isn't writable, - * in which case we will longjmp out of here. We must for - * this purpose use the actual register value passed to us - * so that we get the fault address right. - */ - helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETRA()); - /* Now we can populate the other TLB entries, if any */ - for (i = 0; i < maxidx; i++) { - uint64_t va = vaddr + TARGET_PAGE_SIZE * i; - if (va != (vaddr_in & TARGET_PAGE_MASK)) { - helper_ret_stb_mmu(env, va, 0, oi, GETRA()); - } - } - } - - /* Slow path (probably attempt to do this to an I/O device or - * similar, or clearing of a block of code we have translations - * cached for). Just do a series of byte writes as the architecture - * demands. It's not worth trying to use a cpu_physical_memory_map(), - * memset(), unmap() sequence here because: - * + we'd need to account for the blocksize being larger than a page - * + the direct-RAM access case is almost always going to be dealt - * with in the fastpath code above, so there's no speed benefit - * + we would have to deal with the map returning NULL because the - * bounce buffer was in use - */ - for (i = 0; i < blocklen; i++) { - helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETRA()); - } - } -#else - memset(g2h(vaddr), 0, blocklen); -#endif -} - -/* Note that signed overflow is undefined in C. The following routines are - careful to use unsigned types where modulo arithmetic is required. - Failure to do so _will_ break on newer gcc. */ - -/* Signed saturating arithmetic. */ - -/* Perform 16-bit signed saturating addition. */ -static inline uint16_t add16_sat(uint16_t a, uint16_t b) -{ - uint16_t res; - - res = a + b; - if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) { - if (a & 0x8000) - res = 0x8000; - else - res = 0x7fff; - } - return res; -} - -/* Perform 8-bit signed saturating addition. */ -static inline uint8_t add8_sat(uint8_t a, uint8_t b) -{ - uint8_t res; - - res = a + b; - if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) { - if (a & 0x80) - res = 0x80; - else - res = 0x7f; - } - return res; -} - -/* Perform 16-bit signed saturating subtraction. */ -static inline uint16_t sub16_sat(uint16_t a, uint16_t b) -{ - uint16_t res; - - res = a - b; - if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) { - if (a & 0x8000) - res = 0x8000; - else - res = 0x7fff; - } - return res; -} - -/* Perform 8-bit signed saturating subtraction. */ -static inline uint8_t sub8_sat(uint8_t a, uint8_t b) -{ - uint8_t res; - - res = a - b; - if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) { - if (a & 0x80) - res = 0x80; - else - res = 0x7f; - } - return res; -} - -#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16); -#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16); -#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8); -#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8); -#define PFX q - -#include "op_addsub.h" - -/* Unsigned saturating arithmetic. */ -static inline uint16_t add16_usat(uint16_t a, uint16_t b) -{ - uint16_t res; - res = a + b; - if (res < a) - res = 0xffff; - return res; -} - -static inline uint16_t sub16_usat(uint16_t a, uint16_t b) -{ - if (a > b) - return a - b; - else - return 0; -} - -static inline uint8_t add8_usat(uint8_t a, uint8_t b) -{ - uint8_t res; - res = a + b; - if (res < a) - res = 0xff; - return res; -} - -static inline uint8_t sub8_usat(uint8_t a, uint8_t b) -{ - if (a > b) - return a - b; - else - return 0; -} - -#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16); -#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16); -#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8); -#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8); -#define PFX uq - -#include "op_addsub.h" - -/* Signed modulo arithmetic. */ -#define SARITH16(a, b, n, op) do { \ - int32_t sum; \ - sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \ - RESULT(sum, n, 16); \ - if (sum >= 0) \ - ge |= 3 << (n * 2); \ - } while(0) - -#define SARITH8(a, b, n, op) do { \ - int32_t sum; \ - sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \ - RESULT(sum, n, 8); \ - if (sum >= 0) \ - ge |= 1 << n; \ - } while(0) - - -#define ADD16(a, b, n) SARITH16(a, b, n, +) -#define SUB16(a, b, n) SARITH16(a, b, n, -) -#define ADD8(a, b, n) SARITH8(a, b, n, +) -#define SUB8(a, b, n) SARITH8(a, b, n, -) -#define PFX s -#define ARITH_GE - -#include "op_addsub.h" - -/* Unsigned modulo arithmetic. */ -#define ADD16(a, b, n) do { \ - uint32_t sum; \ - sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \ - RESULT(sum, n, 16); \ - if ((sum >> 16) == 1) \ - ge |= 3 << (n * 2); \ - } while(0) - -#define ADD8(a, b, n) do { \ - uint32_t sum; \ - sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \ - RESULT(sum, n, 8); \ - if ((sum >> 8) == 1) \ - ge |= 1 << n; \ - } while(0) - -#define SUB16(a, b, n) do { \ - uint32_t sum; \ - sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \ - RESULT(sum, n, 16); \ - if ((sum >> 16) == 0) \ - ge |= 3 << (n * 2); \ - } while(0) - -#define SUB8(a, b, n) do { \ - uint32_t sum; \ - sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \ - RESULT(sum, n, 8); \ - if ((sum >> 8) == 0) \ - ge |= 1 << n; \ - } while(0) - -#define PFX u -#define ARITH_GE - -#include "op_addsub.h" - -/* Halved signed arithmetic. */ -#define ADD16(a, b, n) \ - RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16) -#define SUB16(a, b, n) \ - RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16) -#define ADD8(a, b, n) \ - RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8) -#define SUB8(a, b, n) \ - RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8) -#define PFX sh - -#include "op_addsub.h" - -/* Halved unsigned arithmetic. */ -#define ADD16(a, b, n) \ - RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16) -#define SUB16(a, b, n) \ - RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16) -#define ADD8(a, b, n) \ - RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8) -#define SUB8(a, b, n) \ - RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8) -#define PFX uh - -#include "op_addsub.h" - -static inline uint8_t do_usad(uint8_t a, uint8_t b) -{ - if (a > b) - return a - b; - else - return b - a; -} - -/* Unsigned sum of absolute byte differences. */ -uint32_t HELPER(usad8)(uint32_t a, uint32_t b) -{ - uint32_t sum; - sum = do_usad(a, b); - sum += do_usad(a >> 8, b >> 8); - sum += do_usad(a >> 16, b >>16); - sum += do_usad(a >> 24, b >> 24); - return sum; -} - -/* For ARMv6 SEL instruction. */ -uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) -{ - uint32_t mask; - - mask = 0; - if (flags & 1) - mask |= 0xff; - if (flags & 2) - mask |= 0xff00; - if (flags & 4) - mask |= 0xff0000; - if (flags & 8) - mask |= 0xff000000; - return (a & mask) | (b & ~mask); -} - -/* VFP support. We follow the convention used for VFP instructions: - Single precision routines have a "s" suffix, double precision a - "d" suffix. */ - -/* Convert host exception flags to vfp form. */ -static inline int vfp_exceptbits_from_host(int host_bits) -{ - int target_bits = 0; - - if (host_bits & float_flag_invalid) - target_bits |= 1; - if (host_bits & float_flag_divbyzero) - target_bits |= 2; - if (host_bits & float_flag_overflow) - target_bits |= 4; - if (host_bits & (float_flag_underflow | float_flag_output_denormal)) - target_bits |= 8; - if (host_bits & float_flag_inexact) - target_bits |= 0x10; - if (host_bits & float_flag_input_denormal) - target_bits |= 0x80; - return target_bits; -} - -uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env) -{ - int i; - uint32_t fpscr; - - fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff) - | (env->vfp.vec_len << 16) - | (env->vfp.vec_stride << 20); - i = get_float_exception_flags(&env->vfp.fp_status); - i |= get_float_exception_flags(&env->vfp.standard_fp_status); - fpscr |= vfp_exceptbits_from_host(i); - return fpscr; -} - -uint32_t vfp_get_fpscr(CPUARMState *env) -{ - return HELPER(vfp_get_fpscr)(env); -} - -/* Convert vfp exception flags to target form. */ -static inline int vfp_exceptbits_to_host(int target_bits) -{ - int host_bits = 0; - - if (target_bits & 1) - host_bits |= float_flag_invalid; - if (target_bits & 2) - host_bits |= float_flag_divbyzero; - if (target_bits & 4) - host_bits |= float_flag_overflow; - if (target_bits & 8) - host_bits |= float_flag_underflow; - if (target_bits & 0x10) - host_bits |= float_flag_inexact; - if (target_bits & 0x80) - host_bits |= float_flag_input_denormal; - return host_bits; -} - -void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) -{ - int i; - uint32_t changed; - - changed = env->vfp.xregs[ARM_VFP_FPSCR]; - env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff); - env->vfp.vec_len = (val >> 16) & 7; - env->vfp.vec_stride = (val >> 20) & 3; - - changed ^= val; - if (changed & (3 << 22)) { - i = (val >> 22) & 3; - switch (i) { - case FPROUNDING_TIEEVEN: - i = float_round_nearest_even; - break; - case FPROUNDING_POSINF: - i = float_round_up; - break; - case FPROUNDING_NEGINF: - i = float_round_down; - break; - case FPROUNDING_ZERO: - i = float_round_to_zero; - break; - } - set_float_rounding_mode(i, &env->vfp.fp_status); - } - if (changed & (1 << 24)) { - set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status); - set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status); - } - if (changed & (1 << 25)) - set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status); - - i = vfp_exceptbits_to_host(val); - set_float_exception_flags(i, &env->vfp.fp_status); - set_float_exception_flags(0, &env->vfp.standard_fp_status); -} - -void vfp_set_fpscr(CPUARMState *env, uint32_t val) -{ - HELPER(vfp_set_fpscr)(env, val); -} - -#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p)) - -#define VFP_BINOP(name) \ -float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - return float32_ ## name(a, b, fpst); \ -} \ -float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - return float64_ ## name(a, b, fpst); \ -} -VFP_BINOP(add) -VFP_BINOP(sub) -VFP_BINOP(mul) -VFP_BINOP(div) -VFP_BINOP(min) -VFP_BINOP(max) -VFP_BINOP(minnum) -VFP_BINOP(maxnum) -#undef VFP_BINOP - -float32 VFP_HELPER(neg, s)(float32 a) -{ - return float32_chs(a); -} - -float64 VFP_HELPER(neg, d)(float64 a) -{ - return float64_chs(a); -} - -float32 VFP_HELPER(abs, s)(float32 a) -{ - return float32_abs(a); -} - -float64 VFP_HELPER(abs, d)(float64 a) -{ - return float64_abs(a); -} - -float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env) -{ - return float32_sqrt(a, &env->vfp.fp_status); -} - -float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env) -{ - return float64_sqrt(a, &env->vfp.fp_status); -} - -/* XXX: check quiet/signaling case */ -#define DO_VFP_cmp(p, type) \ -void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ -{ \ - uint32_t flags; \ - switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \ - case 0: flags = 0x6; break; \ - case -1: flags = 0x8; break; \ - case 1: flags = 0x2; break; \ - default: case 2: flags = 0x3; break; \ - } \ - env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ - | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ -} \ -void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ -{ \ - uint32_t flags; \ - switch(type ## _compare(a, b, &env->vfp.fp_status)) { \ - case 0: flags = 0x6; break; \ - case -1: flags = 0x8; break; \ - case 1: flags = 0x2; break; \ - default: case 2: flags = 0x3; break; \ - } \ - env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ - | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ -} -DO_VFP_cmp(s, float32) -DO_VFP_cmp(d, float64) -#undef DO_VFP_cmp - -/* Integer to float and float to integer conversions */ - -#define CONV_ITOF(name, fsz, sign) \ - float##fsz HELPER(name)(uint32_t x, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \ -} - -#define CONV_FTOI(name, fsz, sign, round) \ -uint32_t HELPER(name)(float##fsz x, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - if (float##fsz##_is_any_nan(x)) { \ - float_raise(float_flag_invalid, fpst); \ - return 0; \ - } \ - return float##fsz##_to_##sign##int32##round(x, fpst); \ -} - -#define FLOAT_CONVS(name, p, fsz, sign) \ -CONV_ITOF(vfp_##name##to##p, fsz, sign) \ -CONV_FTOI(vfp_to##name##p, fsz, sign, ) \ -CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero) - -FLOAT_CONVS(si, s, 32, ) -FLOAT_CONVS(si, d, 64, ) -FLOAT_CONVS(ui, s, 32, u) -FLOAT_CONVS(ui, d, 64, u) - -#undef CONV_ITOF -#undef CONV_FTOI -#undef FLOAT_CONVS - -/* floating point conversion */ -float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env) -{ - float64 r = float32_to_float64(x, &env->vfp.fp_status); - /* ARM requires that S<->D conversion of any kind of NaN generates - * a quiet NaN by forcing the most significant frac bit to 1. - */ - return float64_maybe_silence_nan(r); -} - -float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env) -{ - float32 r = float64_to_float32(x, &env->vfp.fp_status); - /* ARM requires that S<->D conversion of any kind of NaN generates - * a quiet NaN by forcing the most significant frac bit to 1. - */ - return float32_maybe_silence_nan(r); -} - -/* VFP3 fixed point conversion. */ -#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ - void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - float##fsz tmp; \ - tmp = itype##_to_##float##fsz(x, fpst); \ - return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ -} - -/* Notice that we want only input-denormal exception flags from the - * scalbn operation: the other possible flags (overflow+inexact if - * we overflow to infinity, output-denormal) aren't correct for the - * complete scale-and-convert operation. - */ -#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \ -uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \ - uint32_t shift, \ - void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - int old_exc_flags = get_float_exception_flags(fpst); \ - float##fsz tmp; \ - if (float##fsz##_is_any_nan(x)) { \ - float_raise(float_flag_invalid, fpst); \ - return 0; \ - } \ - tmp = float##fsz##_scalbn(x, shift, fpst); \ - old_exc_flags |= get_float_exception_flags(fpst) \ - & float_flag_input_denormal; \ - set_float_exception_flags(old_exc_flags, fpst); \ - return float##fsz##_to_##itype##round(tmp, fpst); \ -} - -#define VFP_CONV_FIX(name, p, fsz, isz, itype) \ -VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) - -#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \ -VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) - -VFP_CONV_FIX(sh, d, 64, 64, int16) -VFP_CONV_FIX(sl, d, 64, 64, int32) -VFP_CONV_FIX_A64(sq, d, 64, 64, int64) -VFP_CONV_FIX(uh, d, 64, 64, uint16) -VFP_CONV_FIX(ul, d, 64, 64, uint32) -VFP_CONV_FIX_A64(uq, d, 64, 64, uint64) -VFP_CONV_FIX(sh, s, 32, 32, int16) -VFP_CONV_FIX(sl, s, 32, 32, int32) -VFP_CONV_FIX_A64(sq, s, 32, 64, int64) -VFP_CONV_FIX(uh, s, 32, 32, uint16) -VFP_CONV_FIX(ul, s, 32, 32, uint32) -VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) -#undef VFP_CONV_FIX -#undef VFP_CONV_FIX_FLOAT -#undef VFP_CONV_FLOAT_FIX_ROUND - -/* Set the current fp rounding mode and return the old one. - * The argument is a softfloat float_round_ value. - */ -uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env) -{ - float_status *fp_status = &env->vfp.fp_status; - - uint32_t prev_rmode = get_float_rounding_mode(fp_status); - set_float_rounding_mode(rmode, fp_status); - - return prev_rmode; -} - -/* Set the current fp rounding mode in the standard fp status and return - * the old one. This is for NEON instructions that need to change the - * rounding mode but wish to use the standard FPSCR values for everything - * else. Always set the rounding mode back to the correct value after - * modifying it. - * The argument is a softfloat float_round_ value. - */ -uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env) -{ - float_status *fp_status = &env->vfp.standard_fp_status; - - uint32_t prev_rmode = get_float_rounding_mode(fp_status); - set_float_rounding_mode(rmode, fp_status); - - return prev_rmode; -} - -/* Half precision conversions. */ -static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s) -{ - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float32 r = float16_to_float32(make_float16(a), ieee, s); - if (ieee) { - return float32_maybe_silence_nan(r); - } - return r; -} - -static uint32_t do_fcvt_f32_to_f16(float32 a, CPUARMState *env, float_status *s) -{ - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float16 r = float32_to_float16(a, ieee, s); - if (ieee) { - r = float16_maybe_silence_nan(r); - } - return float16_val(r); -} - -float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env) -{ - return do_fcvt_f16_to_f32(a, env, &env->vfp.standard_fp_status); -} - -uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUARMState *env) -{ - return do_fcvt_f32_to_f16(a, env, &env->vfp.standard_fp_status); -} - -float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env) -{ - return do_fcvt_f16_to_f32(a, env, &env->vfp.fp_status); -} - -uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env) -{ - return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status); -} - -float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env) -{ - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float64 r = float16_to_float64(make_float16(a), ieee, &env->vfp.fp_status); - if (ieee) { - return float64_maybe_silence_nan(r); - } - return r; -} - -uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env) -{ - int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - float16 r = float64_to_float16(a, ieee, &env->vfp.fp_status); - if (ieee) { - r = float16_maybe_silence_nan(r); - } - return float16_val(r); -} - -#define float32_two make_float32(0x40000000) -#define float32_three make_float32(0x40400000) -#define float32_one_point_five make_float32(0x3fc00000) - -float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env) -{ - float_status *s = &env->vfp.standard_fp_status; - if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) || - (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) { - if (!(float32_is_zero(a) || float32_is_zero(b))) { - float_raise(float_flag_input_denormal, s); - } - return float32_two; - } - return float32_sub(float32_two, float32_mul(a, b, s), s); -} - -float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env) -{ - float_status *s = &env->vfp.standard_fp_status; - float32 product; - if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) || - (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) { - if (!(float32_is_zero(a) || float32_is_zero(b))) { - float_raise(float_flag_input_denormal, s); - } - return float32_one_point_five; - } - product = float32_mul(a, b, s); - return float32_div(float32_sub(float32_three, product, s), float32_two, s); -} - -/* NEON helpers. */ - -/* Constants 256 and 512 are used in some helpers; we avoid relying on - * int->float conversions at run-time. */ -#define float64_256 make_float64(0x4070000000000000LL) -#define float64_512 make_float64(0x4080000000000000LL) -#define float32_maxnorm make_float32(0x7f7fffff) -#define float64_maxnorm make_float64(0x7fefffffffffffffLL) - -/* Reciprocal functions - * - * The algorithm that must be used to calculate the estimate - * is specified by the ARM ARM, see FPRecipEstimate() - */ - -static float64 recip_estimate(float64 a, float_status *real_fp_status) -{ - /* These calculations mustn't set any fp exception flags, - * so we use a local copy of the fp_status. - */ - float_status dummy_status = *real_fp_status; - float_status *s = &dummy_status; - /* q = (int)(a * 512.0) */ - float64 q = float64_mul(float64_512, a, s); - int64_t q_int = float64_to_int64_round_to_zero(q, s); - - /* r = 1.0 / (((double)q + 0.5) / 512.0) */ - q = int64_to_float64(q_int, s); - q = float64_add(q, float64_half, s); - q = float64_div(q, float64_512, s); - q = float64_div(float64_one, q, s); - - /* s = (int)(256.0 * r + 0.5) */ - q = float64_mul(q, float64_256, s); - q = float64_add(q, float64_half, s); - q_int = float64_to_int64_round_to_zero(q, s); - - /* return (double)s / 256.0 */ - return float64_div(int64_to_float64(q_int, s), float64_256, s); -} - -/* Common wrapper to call recip_estimate */ -static float64 call_recip_estimate(float64 num, int off, float_status *fpst) -{ - uint64_t val64 = float64_val(num); - uint64_t frac = extract64(val64, 0, 52); - int64_t exp = extract64(val64, 52, 11); - uint64_t sbit; - float64 scaled, estimate; - - /* Generate the scaled number for the estimate function */ - if (exp == 0) { - if (extract64(frac, 51, 1) == 0) { - exp = -1; - frac = extract64(frac, 0, 50) << 2; - } else { - frac = extract64(frac, 0, 51) << 1; - } - } - - /* scaled = '0' : '01111111110' : fraction<51:44> : Zeros(44); */ - scaled = make_float64((0x3feULL << 52) - | extract64(frac, 44, 8) << 44); - - estimate = recip_estimate(scaled, fpst); - - /* Build new result */ - val64 = float64_val(estimate); - sbit = 0x8000000000000000ULL & val64; - exp = off - exp; - frac = extract64(val64, 0, 52); - - if (exp == 0) { - frac = 1ULL << 51 | extract64(frac, 1, 51); - } else if (exp == -1) { - frac = 1ULL << 50 | extract64(frac, 2, 50); - exp = 0; - } - - return make_float64(sbit | (exp << 52) | frac); -} - -static bool round_to_inf(float_status *fpst, bool sign_bit) -{ - switch (fpst->float_rounding_mode) { - case float_round_nearest_even: /* Round to Nearest */ - return true; - case float_round_up: /* Round to +Inf */ - return !sign_bit; - case float_round_down: /* Round to -Inf */ - return sign_bit; - case float_round_to_zero: /* Round to Zero */ - return false; - } - - g_assert_not_reached(); -} - -float32 HELPER(recpe_f32)(float32 input, void *fpstp) -{ - float_status *fpst = fpstp; - float32 f32 = float32_squash_input_denormal(input, fpst); - uint32_t f32_val = float32_val(f32); - uint32_t f32_sbit = 0x80000000ULL & f32_val; - int32_t f32_exp = extract32(f32_val, 23, 8); - uint32_t f32_frac = extract32(f32_val, 0, 23); - float64 f64, r64; - uint64_t r64_val; - int64_t r64_exp; - uint64_t r64_frac; - - if (float32_is_any_nan(f32)) { - float32 nan = f32; - if (float32_is_signaling_nan(f32)) { - float_raise(float_flag_invalid, fpst); - nan = float32_maybe_silence_nan(f32); - } - if (fpst->default_nan_mode) { - nan = float32_default_nan; - } - return nan; - } else if (float32_is_infinity(f32)) { - return float32_set_sign(float32_zero, float32_is_neg(f32)); - } else if (float32_is_zero(f32)) { - float_raise(float_flag_divbyzero, fpst); - return float32_set_sign(float32_infinity, float32_is_neg(f32)); - } else if ((f32_val & ~(1ULL << 31)) < (1ULL << 21)) { - /* Abs(value) < 2.0^-128 */ - float_raise(float_flag_overflow | float_flag_inexact, fpst); - if (round_to_inf(fpst, f32_sbit)) { - return float32_set_sign(float32_infinity, float32_is_neg(f32)); - } else { - return float32_set_sign(float32_maxnorm, float32_is_neg(f32)); - } - } else if (f32_exp >= 253 && fpst->flush_to_zero) { - float_raise(float_flag_underflow, fpst); - return float32_set_sign(float32_zero, float32_is_neg(f32)); - } - - - f64 = make_float64(((int64_t)(f32_exp) << 52) | (int64_t)(f32_frac) << 29); - r64 = call_recip_estimate(f64, 253, fpst); - r64_val = float64_val(r64); - r64_exp = extract64(r64_val, 52, 11); - r64_frac = extract64(r64_val, 0, 52); - - /* result = sign : result_exp<7:0> : fraction<51:29>; */ - return make_float32(f32_sbit | - (r64_exp & 0xff) << 23 | - extract64(r64_frac, 29, 24)); -} - -float64 HELPER(recpe_f64)(float64 input, void *fpstp) -{ - float_status *fpst = fpstp; - float64 f64 = float64_squash_input_denormal(input, fpst); - uint64_t f64_val = float64_val(f64); - uint64_t f64_sbit = 0x8000000000000000ULL & f64_val; - int64_t f64_exp = extract64(f64_val, 52, 11); - float64 r64; - uint64_t r64_val; - int64_t r64_exp; - uint64_t r64_frac; - - /* Deal with any special cases */ - if (float64_is_any_nan(f64)) { - float64 nan = f64; - if (float64_is_signaling_nan(f64)) { - float_raise(float_flag_invalid, fpst); - nan = float64_maybe_silence_nan(f64); - } - if (fpst->default_nan_mode) { - nan = float64_default_nan; - } - return nan; - } else if (float64_is_infinity(f64)) { - return float64_set_sign(float64_zero, float64_is_neg(f64)); - } else if (float64_is_zero(f64)) { - float_raise(float_flag_divbyzero, fpst); - return float64_set_sign(float64_infinity, float64_is_neg(f64)); - } else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) { - /* Abs(value) < 2.0^-1024 */ - float_raise(float_flag_overflow | float_flag_inexact, fpst); - if (round_to_inf(fpst, f64_sbit)) { - return float64_set_sign(float64_infinity, float64_is_neg(f64)); - } else { - return float64_set_sign(float64_maxnorm, float64_is_neg(f64)); - } - } else if (f64_exp >= 2045 && fpst->flush_to_zero) { - float_raise(float_flag_underflow, fpst); - return float64_set_sign(float64_zero, float64_is_neg(f64)); - } - - r64 = call_recip_estimate(f64, 2045, fpst); - r64_val = float64_val(r64); - r64_exp = extract64(r64_val, 52, 11); - r64_frac = extract64(r64_val, 0, 52); - - /* result = sign : result_exp<10:0> : fraction<51:0> */ - return make_float64(f64_sbit | - ((r64_exp & 0x7ff) << 52) | - r64_frac); -} - -/* The algorithm that must be used to calculate the estimate - * is specified by the ARM ARM. - */ -static float64 recip_sqrt_estimate(float64 a, float_status *real_fp_status) -{ - /* These calculations mustn't set any fp exception flags, - * so we use a local copy of the fp_status. - */ - float_status dummy_status = *real_fp_status; - float_status *s = &dummy_status; - float64 q; - int64_t q_int; - - if (float64_lt(a, float64_half, s)) { - /* range 0.25 <= a < 0.5 */ - - /* a in units of 1/512 rounded down */ - /* q0 = (int)(a * 512.0); */ - q = float64_mul(float64_512, a, s); - q_int = float64_to_int64_round_to_zero(q, s); - - /* reciprocal root r */ - /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */ - q = int64_to_float64(q_int, s); - q = float64_add(q, float64_half, s); - q = float64_div(q, float64_512, s); - q = float64_sqrt(q, s); - q = float64_div(float64_one, q, s); - } else { - /* range 0.5 <= a < 1.0 */ - - /* a in units of 1/256 rounded down */ - /* q1 = (int)(a * 256.0); */ - q = float64_mul(float64_256, a, s); - int64_t q_int = float64_to_int64_round_to_zero(q, s); - - /* reciprocal root r */ - /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */ - q = int64_to_float64(q_int, s); - q = float64_add(q, float64_half, s); - q = float64_div(q, float64_256, s); - q = float64_sqrt(q, s); - q = float64_div(float64_one, q, s); - } - /* r in units of 1/256 rounded to nearest */ - /* s = (int)(256.0 * r + 0.5); */ - - q = float64_mul(q, float64_256,s ); - q = float64_add(q, float64_half, s); - q_int = float64_to_int64_round_to_zero(q, s); - - /* return (double)s / 256.0;*/ - return float64_div(int64_to_float64(q_int, s), float64_256, s); -} - -float32 HELPER(rsqrte_f32)(float32 input, void *fpstp) -{ - float_status *s = fpstp; - float32 f32 = float32_squash_input_denormal(input, s); - uint32_t val = float32_val(f32); - uint32_t f32_sbit = 0x80000000 & val; - int32_t f32_exp = extract32(val, 23, 8); - uint32_t f32_frac = extract32(val, 0, 23); - uint64_t f64_frac; - uint64_t val64; - int result_exp; - float64 f64; - - if (float32_is_any_nan(f32)) { - float32 nan = f32; - if (float32_is_signaling_nan(f32)) { - float_raise(float_flag_invalid, s); - nan = float32_maybe_silence_nan(f32); - } - if (s->default_nan_mode) { - nan = float32_default_nan; - } - return nan; - } else if (float32_is_zero(f32)) { - float_raise(float_flag_divbyzero, s); - return float32_set_sign(float32_infinity, float32_is_neg(f32)); - } else if (float32_is_neg(f32)) { - float_raise(float_flag_invalid, s); - return float32_default_nan; - } else if (float32_is_infinity(f32)) { - return float32_zero; - } - - /* Scale and normalize to a double-precision value between 0.25 and 1.0, - * preserving the parity of the exponent. */ - - f64_frac = ((uint64_t) f32_frac) << 29; - if (f32_exp == 0) { - while (extract64(f64_frac, 51, 1) == 0) { - f64_frac = f64_frac << 1; - f32_exp = f32_exp-1; - } - f64_frac = extract64(f64_frac, 0, 51) << 1; - } - - if (extract64(f32_exp, 0, 1) == 0) { - f64 = make_float64(((uint64_t) f32_sbit) << 32 - | (0x3feULL << 52) - | f64_frac); - } else { - f64 = make_float64(((uint64_t) f32_sbit) << 32 - | (0x3fdULL << 52) - | f64_frac); - } - - result_exp = (380 - f32_exp) / 2; - - f64 = recip_sqrt_estimate(f64, s); - - val64 = float64_val(f64); - - val = ((result_exp & 0xff) << 23) - | ((val64 >> 29) & 0x7fffff); - return make_float32(val); -} - -float64 HELPER(rsqrte_f64)(float64 input, void *fpstp) -{ - float_status *s = fpstp; - float64 f64 = float64_squash_input_denormal(input, s); - uint64_t val = float64_val(f64); - uint64_t f64_sbit = 0x8000000000000000ULL & val; - int64_t f64_exp = extract64(val, 52, 11); - uint64_t f64_frac = extract64(val, 0, 52); - int64_t result_exp; - uint64_t result_frac; - - if (float64_is_any_nan(f64)) { - float64 nan = f64; - if (float64_is_signaling_nan(f64)) { - float_raise(float_flag_invalid, s); - nan = float64_maybe_silence_nan(f64); - } - if (s->default_nan_mode) { - nan = float64_default_nan; - } - return nan; - } else if (float64_is_zero(f64)) { - float_raise(float_flag_divbyzero, s); - return float64_set_sign(float64_infinity, float64_is_neg(f64)); - } else if (float64_is_neg(f64)) { - float_raise(float_flag_invalid, s); - return float64_default_nan; - } else if (float64_is_infinity(f64)) { - return float64_zero; - } - - /* Scale and normalize to a double-precision value between 0.25 and 1.0, - * preserving the parity of the exponent. */ - - if (f64_exp == 0) { - while (extract64(f64_frac, 51, 1) == 0) { - f64_frac = f64_frac << 1; - f64_exp = f64_exp - 1; - } - f64_frac = extract64(f64_frac, 0, 51) << 1; - } - - if (extract64(f64_exp, 0, 1) == 0) { - f64 = make_float64(f64_sbit - | (0x3feULL << 52) - | f64_frac); - } else { - f64 = make_float64(f64_sbit - | (0x3fdULL << 52) - | f64_frac); - } - - result_exp = (3068 - f64_exp) / 2; - - f64 = recip_sqrt_estimate(f64, s); - - result_frac = extract64(float64_val(f64), 0, 52); - - return make_float64(f64_sbit | - ((result_exp & 0x7ff) << 52) | - result_frac); -} - -uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp) -{ - float_status *s = fpstp; - float64 f64; - - if ((a & 0x80000000) == 0) { - return 0xffffffff; - } - - f64 = make_float64((0x3feULL << 52) - | ((int64_t)(a & 0x7fffffff) << 21)); - - f64 = recip_estimate(f64, s); - - return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff); -} - -uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp) -{ - float_status *fpst = fpstp; - float64 f64; - - if ((a & 0xc0000000) == 0) { - return 0xffffffff; - } - - if (a & 0x80000000) { - f64 = make_float64((0x3feULL << 52) - | ((uint64_t)(a & 0x7fffffff) << 21)); - } else { /* bits 31-30 == '01' */ - f64 = make_float64((0x3fdULL << 52) - | ((uint64_t)(a & 0x3fffffff) << 22)); - } - - f64 = recip_sqrt_estimate(f64, fpst); - - return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff); -} - -/* VFPv4 fused multiply-accumulate */ -float32 VFP_HELPER(muladd, s)(float32 a, float32 b, float32 c, void *fpstp) -{ - float_status *fpst = fpstp; - return float32_muladd(a, b, c, 0, fpst); -} - -float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp) -{ - float_status *fpst = fpstp; - return float64_muladd(a, b, c, 0, fpst); -} - -/* ARMv8 round to integral */ -float32 HELPER(rints_exact)(float32 x, void *fp_status) -{ - return float32_round_to_int(x, fp_status); -} - -float64 HELPER(rintd_exact)(float64 x, void *fp_status) -{ - return float64_round_to_int(x, fp_status); -} - -float32 HELPER(rints)(float32 x, void *fp_status) -{ - int old_flags = get_float_exception_flags(fp_status), new_flags; - float32 ret; - - ret = float32_round_to_int(x, fp_status); - - /* Suppress any inexact exceptions the conversion produced */ - if (!(old_flags & float_flag_inexact)) { - new_flags = get_float_exception_flags(fp_status); - set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status); - } - - return ret; -} - -float64 HELPER(rintd)(float64 x, void *fp_status) -{ - int old_flags = get_float_exception_flags(fp_status), new_flags; - float64 ret; - - ret = float64_round_to_int(x, fp_status); - - new_flags = get_float_exception_flags(fp_status); - - /* Suppress any inexact exceptions the conversion produced */ - if (!(old_flags & float_flag_inexact)) { - new_flags = get_float_exception_flags(fp_status); - set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status); - } - - return ret; -} - -/* Convert ARM rounding mode to softfloat */ -int arm_rmode_to_sf(int rmode) -{ - switch (rmode) { - case FPROUNDING_TIEAWAY: - rmode = float_round_ties_away; - break; - case FPROUNDING_ODD: - /* FIXME: add support for TIEAWAY and ODD */ - qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n", - rmode); - case FPROUNDING_TIEEVEN: - default: - rmode = float_round_nearest_even; - break; - case FPROUNDING_POSINF: - rmode = float_round_up; - break; - case FPROUNDING_NEGINF: - rmode = float_round_down; - break; - case FPROUNDING_ZERO: - rmode = float_round_to_zero; - break; - } - return rmode; -} - -/* CRC helpers. - * The upper bytes of val (above the number specified by 'bytes') must have - * been zeroed out by the caller. - */ -uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes) -{ - uint8_t buf[4]; - - stl_le_p(buf, val); - - /* zlib crc32 converts the accumulator and output to one's complement. */ - return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff; -} - -uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes) -{ - uint8_t buf[4]; - - stl_le_p(buf, val); - - /* Linux crc32c converts the output to one's complement. */ - return crc32c(acc, buf, bytes) ^ 0xffffffff; -} diff --git a/target-arm/internals.h b/target-arm/internals.h deleted file mode 100644 index 325c7ea6e6682..0000000000000 --- a/target-arm/internals.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - * QEMU ARM CPU -- internal functions and types - * - * Copyright (c) 2014 Linaro Ltd - * - * 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 - * - * - * This header defines functions, types, etc which need to be shared - * between different source files within target-arm/ but which are - * private to it and not required by the rest of QEMU. - */ - -#ifndef TARGET_ARM_INTERNALS_H -#define TARGET_ARM_INTERNALS_H - -/* register banks for CPU modes */ -#define BANK_USRSYS 0 -#define BANK_SVC 1 -#define BANK_ABT 2 -#define BANK_UND 3 -#define BANK_IRQ 4 -#define BANK_FIQ 5 -#define BANK_HYP 6 -#define BANK_MON 7 - -static inline bool excp_is_internal(int excp) -{ - /* Return true if this exception number represents a QEMU-internal - * exception that will not be passed to the guest. - */ - return excp == EXCP_INTERRUPT - || excp == EXCP_HLT - || excp == EXCP_DEBUG - || excp == EXCP_HALTED - || excp == EXCP_EXCEPTION_EXIT - || excp == EXCP_KERNEL_TRAP - || excp == EXCP_SEMIHOST - || excp == EXCP_STREX; -} - -/* Exception names for debug logging; note that not all of these - * precisely correspond to architectural exceptions. - */ -static const char * const excnames[] = { - [EXCP_UDEF] = "Undefined Instruction", - [EXCP_SWI] = "SVC", - [EXCP_PREFETCH_ABORT] = "Prefetch Abort", - [EXCP_DATA_ABORT] = "Data Abort", - [EXCP_IRQ] = "IRQ", - [EXCP_FIQ] = "FIQ", - [EXCP_BKPT] = "Breakpoint", - [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit", - [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage", - [EXCP_STREX] = "QEMU intercept of STREX", - [EXCP_HVC] = "Hypervisor Call", - [EXCP_HYP_TRAP] = "Hypervisor Trap", - [EXCP_SMC] = "Secure Monitor Call", - [EXCP_VIRQ] = "Virtual IRQ", - [EXCP_VFIQ] = "Virtual FIQ", - [EXCP_WKUP] = "Wakeup", - [EXCP_SEMIHOST] = "Semihosting call", -}; - -static inline void arm_log_exception(int idx) -{ - if (qemu_loglevel_mask(CPU_LOG_INT)) { - const char *exc = NULL; - - if (idx >= 0 && idx < ARRAY_SIZE(excnames)) { - exc = excnames[idx]; - } - if (!exc) { - exc = "unknown"; - } - qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc); - } -} - -/* Scale factor for generic timers, ie number of ns per tick. - * This gives a 62.5MHz timer. - */ -#define GTIMER_SCALE 16 - -/* - * For AArch64, map a given EL to an index in the banked_spsr array. - * Note that this mapping and the AArch32 mapping defined in bank_number() - * must agree such that the AArch64<->AArch32 SPSRs have the architecturally - * mandated mapping between each other. - */ -static inline unsigned int aarch64_banked_spsr_index(unsigned int el) -{ - static const unsigned int map[4] = { - [1] = BANK_SVC, /* EL1. */ - [2] = BANK_HYP, /* EL2. */ - [3] = BANK_MON, /* EL3. */ - }; - assert(el >= 1 && el <= 3); - return map[el]; -} - -int bank_number(int mode); -void switch_mode(CPUARMState *, int); -void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu); -void arm_translate_init(void); - -enum arm_fprounding { - FPROUNDING_TIEEVEN, - FPROUNDING_POSINF, - FPROUNDING_NEGINF, - FPROUNDING_ZERO, - FPROUNDING_TIEAWAY, - FPROUNDING_ODD -}; - -int arm_rmode_to_sf(int rmode); - -static inline void aarch64_save_sp(CPUARMState *env, int el) -{ - if (env->pstate & PSTATE_SP) { - env->sp_el[el] = env->xregs[31]; - } else { - env->sp_el[0] = env->xregs[31]; - } -} - -static inline void aarch64_restore_sp(CPUARMState *env, int el) -{ - if (env->pstate & PSTATE_SP) { - env->xregs[31] = env->sp_el[el]; - } else { - env->xregs[31] = env->sp_el[0]; - } -} - -static inline void update_spsel(CPUARMState *env, uint32_t imm) -{ - unsigned int cur_el = arm_current_el(env); - /* Update PSTATE SPSel bit; this requires us to update the - * working stack pointer in xregs[31]. - */ - if (!((imm ^ env->pstate) & PSTATE_SP)) { - return; - } - aarch64_save_sp(env, cur_el); - env->pstate = deposit32(env->pstate, 0, 1, imm); - - /* We rely on illegal updates to SPsel from EL0 to get trapped - * at translation time. - */ - assert(cur_el >= 1 && cur_el <= 3); - aarch64_restore_sp(env, cur_el); -} - -/* - * arm_pamax - * @cpu: ARMCPU - * - * Returns the implementation defined bit-width of physical addresses. - * The ARMv8 reference manuals refer to this as PAMax(). - */ -static inline unsigned int arm_pamax(ARMCPU *cpu) -{ - static const unsigned int pamax_map[] = { - [0] = 32, - [1] = 36, - [2] = 40, - [3] = 42, - [4] = 44, - [5] = 48, - }; - unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4); - - /* id_aa64mmfr0 is a read-only register so values outside of the - * supported mappings can be considered an implementation error. */ - assert(parange < ARRAY_SIZE(pamax_map)); - return pamax_map[parange]; -} - -/* Return true if extended addresses are enabled. - * This is always the case if our translation regime is 64 bit, - * but depends on TTBCR.EAE for 32 bit. - */ -static inline bool extended_addresses_enabled(CPUARMState *env) -{ - TCR *tcr = &env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1]; - return arm_el_is_aa64(env, 1) || - (arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE)); -} - -/* Valid Syndrome Register EC field values */ -enum arm_exception_class { - EC_UNCATEGORIZED = 0x00, - EC_WFX_TRAP = 0x01, - EC_CP15RTTRAP = 0x03, - EC_CP15RRTTRAP = 0x04, - EC_CP14RTTRAP = 0x05, - EC_CP14DTTRAP = 0x06, - EC_ADVSIMDFPACCESSTRAP = 0x07, - EC_FPIDTRAP = 0x08, - EC_CP14RRTTRAP = 0x0c, - EC_ILLEGALSTATE = 0x0e, - EC_AA32_SVC = 0x11, - EC_AA32_HVC = 0x12, - EC_AA32_SMC = 0x13, - EC_AA64_SVC = 0x15, - EC_AA64_HVC = 0x16, - EC_AA64_SMC = 0x17, - EC_SYSTEMREGISTERTRAP = 0x18, - EC_INSNABORT = 0x20, - EC_INSNABORT_SAME_EL = 0x21, - EC_PCALIGNMENT = 0x22, - EC_DATAABORT = 0x24, - EC_DATAABORT_SAME_EL = 0x25, - EC_SPALIGNMENT = 0x26, - EC_AA32_FPTRAP = 0x28, - EC_AA64_FPTRAP = 0x2c, - EC_SERROR = 0x2f, - EC_BREAKPOINT = 0x30, - EC_BREAKPOINT_SAME_EL = 0x31, - EC_SOFTWARESTEP = 0x32, - EC_SOFTWARESTEP_SAME_EL = 0x33, - EC_WATCHPOINT = 0x34, - EC_WATCHPOINT_SAME_EL = 0x35, - EC_AA32_BKPT = 0x38, - EC_VECTORCATCH = 0x3a, - EC_AA64_BKPT = 0x3c, -}; - -#define ARM_EL_EC_SHIFT 26 -#define ARM_EL_IL_SHIFT 25 -#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT) - -/* Utility functions for constructing various kinds of syndrome value. - * Note that in general we follow the AArch64 syndrome values; in a - * few cases the value in HSR for exceptions taken to AArch32 Hyp - * mode differs slightly, so if we ever implemented Hyp mode then the - * syndrome value would need some massaging on exception entry. - * (One example of this is that AArch64 defaults to IL bit set for - * exceptions which don't specifically indicate information about the - * trapping instruction, whereas AArch32 defaults to IL bit clear.) - */ -static inline uint32_t syn_uncategorized(void) -{ - return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL; -} - -static inline uint32_t syn_aa64_svc(uint32_t imm16) -{ - return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); -} - -static inline uint32_t syn_aa64_hvc(uint32_t imm16) -{ - return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); -} - -static inline uint32_t syn_aa64_smc(uint32_t imm16) -{ - return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); -} - -static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb) -{ - return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff) - | (is_thumb ? 0 : ARM_EL_IL); -} - -static inline uint32_t syn_aa32_hvc(uint32_t imm16) -{ - return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); -} - -static inline uint32_t syn_aa32_smc(void) -{ - return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL; -} - -static inline uint32_t syn_aa64_bkpt(uint32_t imm16) -{ - return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); -} - -static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_thumb) -{ - return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff) - | (is_thumb ? 0 : ARM_EL_IL); -} - -static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2, - int crn, int crm, int rt, - int isread) -{ - return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL - | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5) - | (crm << 1) | isread; -} - -static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2, - int crn, int crm, int rt, int isread, - bool is_thumb) -{ - return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT) - | (is_thumb ? 0 : ARM_EL_IL) - | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14) - | (crn << 10) | (rt << 5) | (crm << 1) | isread; -} - -static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2, - int crn, int crm, int rt, int isread, - bool is_thumb) -{ - return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT) - | (is_thumb ? 0 : ARM_EL_IL) - | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14) - | (crn << 10) | (rt << 5) | (crm << 1) | isread; -} - -static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm, - int rt, int rt2, int isread, - bool is_thumb) -{ - return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT) - | (is_thumb ? 0 : ARM_EL_IL) - | (cv << 24) | (cond << 20) | (opc1 << 16) - | (rt2 << 10) | (rt << 5) | (crm << 1) | isread; -} - -static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm, - int rt, int rt2, int isread, - bool is_thumb) -{ - return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT) - | (is_thumb ? 0 : ARM_EL_IL) - | (cv << 24) | (cond << 20) | (opc1 << 16) - | (rt2 << 10) | (rt << 5) | (crm << 1) | isread; -} - -static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_thumb) -{ - return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT) - | (is_thumb ? 0 : ARM_EL_IL) - | (cv << 24) | (cond << 20); -} - -static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc) -{ - return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) - | (ea << 9) | (s1ptw << 7) | fsc; -} - -static inline uint32_t syn_data_abort(int same_el, int ea, int cm, int s1ptw, - int wnr, int fsc) -{ - return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) - | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc; -} - -static inline uint32_t syn_swstep(int same_el, int isv, int ex) -{ - return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) - | (isv << 24) | (ex << 6) | 0x22; -} - -static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr) -{ - return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) - | (cm << 8) | (wnr << 6) | 0x22; -} - -static inline uint32_t syn_breakpoint(int same_el) -{ - return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT) - | ARM_EL_IL | 0x22; -} - -static inline uint32_t syn_wfx(int cv, int cond, int ti) -{ - return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) | - (cv << 24) | (cond << 20) | ti; -} - -/* Update a QEMU watchpoint based on the information the guest has set in the - * DBGWCR_EL1 and DBGWVR_EL1 registers. - */ -void hw_watchpoint_update(ARMCPU *cpu, int n); -/* Update the QEMU watchpoints for every guest watchpoint. This does a - * complete delete-and-reinstate of the QEMU watchpoint list and so is - * suitable for use after migration or on reset. - */ -void hw_watchpoint_update_all(ARMCPU *cpu); -/* Update a QEMU breakpoint based on the information the guest has set in the - * DBGBCR_EL1 and DBGBVR_EL1 registers. - */ -void hw_breakpoint_update(ARMCPU *cpu, int n); -/* Update the QEMU breakpoints for every guest breakpoint. This does a - * complete delete-and-reinstate of the QEMU breakpoint list and so is - * suitable for use after migration or on reset. - */ -void hw_breakpoint_update_all(ARMCPU *cpu); - -/* Callback function for when a watchpoint or breakpoint triggers. */ -void arm_debug_excp_handler(CPUState *cs); - -#ifdef CONFIG_USER_ONLY -static inline bool arm_is_psci_call(ARMCPU *cpu, int excp_type) -{ - return false; -} -#else -/* Return true if the r0/x0 value indicates that this SMC/HVC is a PSCI call. */ -bool arm_is_psci_call(ARMCPU *cpu, int excp_type); -/* Actually handle a PSCI call */ -void arm_handle_psci_call(ARMCPU *cpu); -#endif - -/** - * ARMMMUFaultInfo: Information describing an ARM MMU Fault - * @s2addr: Address that caused a fault at stage 2 - * @stage2: True if we faulted at stage 2 - * @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk - */ -typedef struct ARMMMUFaultInfo ARMMMUFaultInfo; -struct ARMMMUFaultInfo { - target_ulong s2addr; - bool stage2; - bool s1ptw; -}; - -/* Do a page table walk and add page to TLB if possible */ -bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx, - uint32_t *fsr, ARMMMUFaultInfo *fi); - -#endif diff --git a/target-arm/machine.c b/target-arm/machine.c deleted file mode 100644 index c2c5bb4db24f7..0000000000000 --- a/target-arm/machine.c +++ /dev/null @@ -1,355 +0,0 @@ -#include "hw/hw.h" -#include "hw/boards.h" -#include "qemu/error-report.h" -#include "sysemu/kvm.h" -#include "kvm_arm.h" -#include "internals.h" - -static bool vfp_needed(void *opaque) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - - return arm_feature(env, ARM_FEATURE_VFP); -} - -static int get_fpscr(QEMUFile *f, void *opaque, size_t size) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - uint32_t val = qemu_get_be32(f); - - vfp_set_fpscr(env, val); - return 0; -} - -static void put_fpscr(QEMUFile *f, void *opaque, size_t size) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - - qemu_put_be32(f, vfp_get_fpscr(env)); -} - -static const VMStateInfo vmstate_fpscr = { - .name = "fpscr", - .get = get_fpscr, - .put = put_fpscr, -}; - -static const VMStateDescription vmstate_vfp = { - .name = "cpu/vfp", - .version_id = 3, - .minimum_version_id = 3, - .needed = vfp_needed, - .fields = (VMStateField[]) { - VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 64), - /* The xregs array is a little awkward because element 1 (FPSCR) - * requires a specific accessor, so we have to split it up in - * the vmstate: - */ - VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU), - VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14), - { - .name = "fpscr", - .version_id = 0, - .size = sizeof(uint32_t), - .info = &vmstate_fpscr, - .flags = VMS_SINGLE, - .offset = 0, - }, - VMSTATE_END_OF_LIST() - } -}; - -static bool iwmmxt_needed(void *opaque) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - - return arm_feature(env, ARM_FEATURE_IWMMXT); -} - -static const VMStateDescription vmstate_iwmmxt = { - .name = "cpu/iwmmxt", - .version_id = 1, - .minimum_version_id = 1, - .needed = iwmmxt_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16), - VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16), - VMSTATE_END_OF_LIST() - } -}; - -static bool m_needed(void *opaque) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - - return arm_feature(env, ARM_FEATURE_M); -} - -static const VMStateDescription vmstate_m = { - .name = "cpu/m", - .version_id = 2, - .minimum_version_id = 2, - .needed = m_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), - VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), - VMSTATE_UINT32(env.v7m.basepri, ARMCPU), - VMSTATE_UINT32(env.v7m.control, ARMCPU), - VMSTATE_INT32(env.v7m.current_sp, ARMCPU), - VMSTATE_INT32(env.v7m.exception, ARMCPU), - VMSTATE_UINT32(env.v7m.ccr, ARMCPU), - VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), - VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), - VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), - VMSTATE_UINT32(env.v7m.mmfar, ARMCPU), - VMSTATE_UINT32(env.v7m.bfar, ARMCPU), - VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU), - VMSTATE_END_OF_LIST() - } -}; - -static bool thumb2ee_needed(void *opaque) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - - return arm_feature(env, ARM_FEATURE_THUMB2EE); -} - -static const VMStateDescription vmstate_thumb2ee = { - .name = "cpu/thumb2ee", - .version_id = 1, - .minimum_version_id = 1, - .needed = thumb2ee_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT32(env.teecr, ARMCPU), - VMSTATE_UINT32(env.teehbr, ARMCPU), - VMSTATE_END_OF_LIST() - } -}; - -static bool pmsav7_needed(void *opaque) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - - return arm_feature(env, ARM_FEATURE_MPU) && - arm_feature(env, ARM_FEATURE_V7); -} - -static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) -{ - ARMCPU *cpu = opaque; - - return cpu->env.cp15.c6_rgnr < cpu->pmsav7_dregion; -} - -static const VMStateDescription vmstate_pmsav7 = { - .name = "cpu/pmsav7", - .version_id = 1, - .minimum_version_id = 1, - .needed = pmsav7_needed, - .fields = (VMStateField[]) { - VMSTATE_VARRAY_UINT32(env.pmsav7.drbar, ARMCPU, pmsav7_dregion, 0, - vmstate_info_uint32, uint32_t), - VMSTATE_VARRAY_UINT32(env.pmsav7.drsr, ARMCPU, pmsav7_dregion, 0, - vmstate_info_uint32, uint32_t), - VMSTATE_VARRAY_UINT32(env.pmsav7.dracr, ARMCPU, pmsav7_dregion, 0, - vmstate_info_uint32, uint32_t), - VMSTATE_VALIDATE("rgnr is valid", pmsav7_rgnr_vmstate_validate), - VMSTATE_END_OF_LIST() - } -}; - -static int get_cpsr(QEMUFile *f, void *opaque, size_t size) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - uint32_t val = qemu_get_be32(f); - - env->aarch64 = ((val & PSTATE_nRW) == 0); - - if (is_a64(env)) { - pstate_write(env, val); - return 0; - } - - /* Avoid mode switch when restoring CPSR */ - env->uncached_cpsr = val & CPSR_M; - cpsr_write(env, val, 0xffffffff); - return 0; -} - -static void put_cpsr(QEMUFile *f, void *opaque, size_t size) -{ - ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; - uint32_t val; - - if (is_a64(env)) { - val = pstate_read(env); - } else { - val = cpsr_read(env); - } - - qemu_put_be32(f, val); -} - -static const VMStateInfo vmstate_cpsr = { - .name = "cpsr", - .get = get_cpsr, - .put = put_cpsr, -}; - -static void cpu_pre_save(void *opaque) -{ - ARMCPU *cpu = opaque; - - if (kvm_enabled()) { - if (!write_kvmstate_to_list(cpu)) { - /* This should never fail */ - abort(); - } - } else { - if (!write_cpustate_to_list(cpu)) { - /* This should never fail. */ - abort(); - } - } - - cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; - memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes, - cpu->cpreg_array_len * sizeof(uint64_t)); - memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values, - cpu->cpreg_array_len * sizeof(uint64_t)); -} - -static int cpu_post_load(void *opaque, int version_id) -{ - ARMCPU *cpu = opaque; - int i, v; - - /* Update the values list from the incoming migration data. - * Anything in the incoming data which we don't know about is - * a migration failure; anything we know about but the incoming - * data doesn't specify retains its current (reset) value. - * The indexes list remains untouched -- we only inspect the - * incoming migration index list so we can match the values array - * entries with the right slots in our own values array. - */ - - for (i = 0, v = 0; i < cpu->cpreg_array_len - && v < cpu->cpreg_vmstate_array_len; i++) { - if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) { - /* register in our list but not incoming : skip it */ - continue; - } - if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) { - /* register in their list but not ours: fail migration */ - return -1; - } - /* matching register, copy the value over */ - cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v]; - v++; - } - - if (kvm_enabled()) { - if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) { - return -1; - } - /* Note that it's OK for the TCG side not to know about - * every register in the list; KVM is authoritative if - * we're using it. - */ - write_list_to_cpustate(cpu); - } else { - if (!write_list_to_cpustate(cpu)) { - return -1; - } - } - - hw_breakpoint_update_all(cpu); - hw_watchpoint_update_all(cpu); - - return 0; -} - -const VMStateDescription vmstate_arm_cpu = { - .name = "cpu", - .version_id = 22, - .minimum_version_id = 22, - .pre_save = cpu_pre_save, - .post_load = cpu_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), - VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32), - VMSTATE_UINT64(env.pc, ARMCPU), - { - .name = "cpsr", - .version_id = 0, - .size = sizeof(uint32_t), - .info = &vmstate_cpsr, - .flags = VMS_SINGLE, - .offset = 0, - }, - VMSTATE_UINT32(env.spsr, ARMCPU), - VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8), - VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8), - VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8), - VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5), - VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5), - VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4), - VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 4), - /* The length-check must come before the arrays to avoid - * incoming data possibly overflowing the array. - */ - VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU), - VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU, - cpreg_vmstate_array_len, - 0, vmstate_info_uint64, uint64_t), - VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU, - cpreg_vmstate_array_len, - 0, vmstate_info_uint64, uint64_t), - VMSTATE_UINT64(env.exclusive_addr, ARMCPU), - VMSTATE_UINT64(env.exclusive_val, ARMCPU), - VMSTATE_UINT64(env.exclusive_high, ARMCPU), - VMSTATE_UINT64(env.features, ARMCPU), - VMSTATE_UINT32(env.exception.syndrome, ARMCPU), - VMSTATE_UINT32(env.exception.fsr, ARMCPU), - VMSTATE_UINT64(env.exception.vaddress, ARMCPU), - VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU), - VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU), - VMSTATE_BOOL(powered_off, ARMCPU), - VMSTATE_END_OF_LIST() - }, - .subsections = (const VMStateDescription*[]) { - &vmstate_vfp, - &vmstate_iwmmxt, - &vmstate_m, - &vmstate_thumb2ee, - &vmstate_pmsav7, - NULL - } -}; - -const char *gicv3_class_name(void) -{ - if (kvm_irqchip_in_kernel()) { -#ifdef TARGET_AARCH64 - return "kvm-arm-gicv3"; -#else - error_report("KVM GICv3 acceleration is not supported on this " - "platform\n"); -#endif - } else { - /* TODO: Software emulation is not implemented yet */ - error_report("KVM is currently required for GICv3 emulation\n"); - } - - exit(1); -} diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c deleted file mode 100644 index d3fccf17fbc05..0000000000000 --- a/target-arm/op_helper.c +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * ARM helper routines - * - * Copyright (c) 2005-2007 CodeSourcery, LLC - * - * 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 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 . - */ -#include "cpu.h" -#include "exec/helper-proto.h" -#include "internals.h" -#include "exec/cpu_ldst.h" - -#define SIGNBIT (uint32_t)0x80000000 -#define SIGNBIT64 ((uint64_t)1 << 63) - -static void raise_exception(CPUARMState *env, uint32_t excp, - uint32_t syndrome, uint32_t target_el) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - - assert(!excp_is_internal(excp)); - cs->exception_index = excp; - env->exception.syndrome = syndrome; - env->exception.target_el = target_el; - cpu_loop_exit(cs); -} - -static int exception_target_el(CPUARMState *env) -{ - int target_el = MAX(1, arm_current_el(env)); - - /* No such thing as secure EL1 if EL3 is aarch32, so update the target EL - * to EL3 in this case. - */ - if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) { - target_el = 3; - } - - return target_el; -} - -uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def, - uint32_t rn, uint32_t maxindex) -{ - uint32_t val; - uint32_t tmp; - int index; - int shift; - uint64_t *table; - table = (uint64_t *)&env->vfp.regs[rn]; - val = 0; - for (shift = 0; shift < 32; shift += 8) { - index = (ireg >> shift) & 0xff; - if (index < maxindex) { - tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff; - val |= tmp << shift; - } else { - val |= def & (0xff << shift); - } - } - return val; -} - -#if !defined(CONFIG_USER_ONLY) - -/* try to fill the TLB and return an exception if error. If retaddr is - * NULL, it means that the function was called in C code (i.e. not - * from generated code or from helper.c) - */ -void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, - uintptr_t retaddr) -{ - bool ret; - uint32_t fsr = 0; - ARMMMUFaultInfo fi = {}; - - ret = arm_tlb_fill(cs, addr, is_write, mmu_idx, &fsr, &fi); - if (unlikely(ret)) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - uint32_t syn, exc; - unsigned int target_el; - bool same_el; - - if (retaddr) { - /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr); - } - - target_el = exception_target_el(env); - if (fi.stage2) { - target_el = 2; - env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4; - } - same_el = arm_current_el(env) == target_el; - /* AArch64 syndrome does not have an LPAE bit */ - syn = fsr & ~(1 << 9); - - /* For insn and data aborts we assume there is no instruction syndrome - * information; this is always true for exceptions reported to EL1. - */ - if (is_write == 2) { - syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn); - exc = EXCP_PREFETCH_ABORT; - } else { - syn = syn_data_abort(same_el, 0, 0, fi.s1ptw, is_write == 1, syn); - if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) { - fsr |= (1 << 11); - } - exc = EXCP_DATA_ABORT; - } - - env->exception.vaddress = addr; - env->exception.fsr = fsr; - raise_exception(env, exc, syn, target_el); - } -} -#endif - -uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t res = a + b; - if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) - env->QF = 1; - return res; -} - -uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t res = a + b; - if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) { - env->QF = 1; - res = ~(((int32_t)a >> 31) ^ SIGNBIT); - } - return res; -} - -uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t res = a - b; - if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) { - env->QF = 1; - res = ~(((int32_t)a >> 31) ^ SIGNBIT); - } - return res; -} - -uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val) -{ - uint32_t res; - if (val >= 0x40000000) { - res = ~SIGNBIT; - env->QF = 1; - } else if (val <= (int32_t)0xc0000000) { - res = SIGNBIT; - env->QF = 1; - } else { - res = val << 1; - } - return res; -} - -uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t res = a + b; - if (res < a) { - env->QF = 1; - res = ~0; - } - return res; -} - -uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b) -{ - uint32_t res = a - b; - if (res > a) { - env->QF = 1; - res = 0; - } - return res; -} - -/* Signed saturation. */ -static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift) -{ - int32_t top; - uint32_t mask; - - top = val >> shift; - mask = (1u << shift) - 1; - if (top > 0) { - env->QF = 1; - return mask; - } else if (top < -1) { - env->QF = 1; - return ~mask; - } - return val; -} - -/* Unsigned saturation. */ -static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift) -{ - uint32_t max; - - max = (1u << shift) - 1; - if (val < 0) { - env->QF = 1; - return 0; - } else if (val > max) { - env->QF = 1; - return max; - } - return val; -} - -/* Signed saturate. */ -uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift) -{ - return do_ssat(env, x, shift); -} - -/* Dual halfword signed saturate. */ -uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift) -{ - uint32_t res; - - res = (uint16_t)do_ssat(env, (int16_t)x, shift); - res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16; - return res; -} - -/* Unsigned saturate. */ -uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift) -{ - return do_usat(env, x, shift); -} - -/* Dual halfword unsigned saturate. */ -uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift) -{ - uint32_t res; - - res = (uint16_t)do_usat(env, (int16_t)x, shift); - res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16; - return res; -} - -/* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped. - * The function returns the target EL (1-3) if the instruction is to be trapped; - * otherwise it returns 0 indicating it is not trapped. - */ -static inline int check_wfx_trap(CPUARMState *env, bool is_wfe) -{ - int cur_el = arm_current_el(env); - uint64_t mask; - - /* If we are currently in EL0 then we need to check if SCTLR is set up for - * WFx instructions being trapped to EL1. These trap bits don't exist in v7. - */ - if (cur_el < 1 && arm_feature(env, ARM_FEATURE_V8)) { - int target_el; - - mask = is_wfe ? SCTLR_nTWE : SCTLR_nTWI; - if (arm_is_secure_below_el3(env) && !arm_el_is_aa64(env, 3)) { - /* Secure EL0 and Secure PL1 is at EL3 */ - target_el = 3; - } else { - target_el = 1; - } - - if (!(env->cp15.sctlr_el[target_el] & mask)) { - return target_el; - } - } - - /* We are not trapping to EL1; trap to EL2 if HCR_EL2 requires it - * No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the - * bits will be zero indicating no trap. - */ - if (cur_el < 2 && !arm_is_secure(env)) { - mask = (is_wfe) ? HCR_TWE : HCR_TWI; - if (env->cp15.hcr_el2 & mask) { - return 2; - } - } - - /* We are not trapping to EL1 or EL2; trap to EL3 if SCR_EL3 requires it */ - if (cur_el < 3) { - mask = (is_wfe) ? SCR_TWE : SCR_TWI; - if (env->cp15.scr_el3 & mask) { - return 3; - } - } - - return 0; -} - -void HELPER(wfi)(CPUARMState *env) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - int target_el = check_wfx_trap(env, false); - - if (cpu_has_work(cs)) { - /* Don't bother to go into our "low power state" if - * we would just wake up immediately. - */ - return; - } - - if (target_el) { - env->pc -= 4; - raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0), target_el); - } - - /* Tell the NVIC we are executing a WFI instruction so that it can determine if we should - * go into deep sleep mode */ - armv7m_nvic_cpu_executed_wfi(env->nvic); - cs->exception_index = EXCP_HLT; - cs->halted = 1; - cpu_loop_exit(cs); -} - -void HELPER(wfe)(CPUARMState *env) -{ - /* This is a hint instruction that is semantically different - * from YIELD even though we currently implement it identically. - * Don't actually halt the CPU, just yield back to top - * level loop. This is not going into a "low power state" - * (ie halting until some event occurs), so we never take - * a configurable trap to a different exception level. - */ - HELPER(yield)(env); -} - -void HELPER(yield)(CPUARMState *env) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - - /* This is a non-trappable hint instruction that generally indicates - * that the guest is currently busy-looping. Yield control back to the - * top level loop so that a more deserving VCPU has a chance to run. - */ - cs->exception_index = EXCP_YIELD; - cpu_loop_exit(cs); -} - -/* Raise an internal-to-QEMU exception. This is limited to only - * those EXCP values which are special cases for QEMU to interrupt - * execution and not to be used for exceptions which are passed to - * the guest (those must all have syndrome information and thus should - * use exception_with_syndrome). - */ -void HELPER(exception_internal)(CPUARMState *env, uint32_t excp) -{ - CPUState *cs = CPU(arm_env_get_cpu(env)); - - assert(excp_is_internal(excp)); - cs->exception_index = excp; - cpu_loop_exit(cs); -} - -/* Raise an exception with the specified syndrome register value */ -void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp, - uint32_t syndrome, uint32_t target_el) -{ - raise_exception(env, excp, syndrome, target_el); -} - -uint32_t HELPER(cpsr_read)(CPUARMState *env) -{ - return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED); -} - -void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) -{ - cpsr_write(env, val, mask); -} - -/* Access to user mode registers from privileged modes. */ -uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno) -{ - uint32_t val; - - if (regno == 13) { - val = env->banked_r13[BANK_USRSYS]; - } else if (regno == 14) { - val = env->banked_r14[BANK_USRSYS]; - } else if (regno >= 8 - && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) { - val = env->usr_regs[regno - 8]; - } else { - val = env->regs[regno]; - } - return val; -} - -void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val) -{ - if (regno == 13) { - env->banked_r13[BANK_USRSYS] = val; - } else if (regno == 14) { - env->banked_r14[BANK_USRSYS] = val; - } else if (regno >= 8 - && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) { - env->usr_regs[regno - 8] = val; - } else { - env->regs[regno] = val; - } -} - -void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome) -{ - const ARMCPRegInfo *ri = rip; - int target_el; - - if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14 - && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) { - raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env)); - } - - if (!ri->accessfn) { - return; - } - - switch (ri->accessfn(env, ri)) { - case CP_ACCESS_OK: - return; - case CP_ACCESS_TRAP: - target_el = exception_target_el(env); - break; - case CP_ACCESS_TRAP_EL2: - /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is - * a bug in the access function. - */ - assert(!arm_is_secure(env) && arm_current_el(env) != 3); - target_el = 2; - break; - case CP_ACCESS_TRAP_EL3: - target_el = 3; - break; - case CP_ACCESS_TRAP_UNCATEGORIZED: - target_el = exception_target_el(env); - syndrome = syn_uncategorized(); - break; - case CP_ACCESS_TRAP_UNCATEGORIZED_EL2: - target_el = 2; - syndrome = syn_uncategorized(); - break; - case CP_ACCESS_TRAP_UNCATEGORIZED_EL3: - target_el = 3; - syndrome = syn_uncategorized(); - break; - default: - g_assert_not_reached(); - } - - raise_exception(env, EXCP_UDEF, syndrome, target_el); -} - -void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value) -{ - const ARMCPRegInfo *ri = rip; - - ri->writefn(env, ri, value); -} - -uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip) -{ - const ARMCPRegInfo *ri = rip; - - return ri->readfn(env, ri); -} - -void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value) -{ - const ARMCPRegInfo *ri = rip; - - ri->writefn(env, ri, value); -} - -uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip) -{ - const ARMCPRegInfo *ri = rip; - - return ri->readfn(env, ri); -} - -void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm) -{ - /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set. - * Note that SPSel is never OK from EL0; we rely on handle_msr_i() - * to catch that case at translate time. - */ - if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) { - uint32_t syndrome = syn_aa64_sysregtrap(0, extract32(op, 0, 3), - extract32(op, 3, 3), 4, - imm, 0x1f, 0); - raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env)); - } - - switch (op) { - case 0x05: /* SPSel */ - update_spsel(env, imm); - break; - case 0x1e: /* DAIFSet */ - env->daif |= (imm << 6) & PSTATE_DAIF; - break; - case 0x1f: /* DAIFClear */ - env->daif &= ~((imm << 6) & PSTATE_DAIF); - break; - default: - g_assert_not_reached(); - } -} - -void HELPER(clear_pstate_ss)(CPUARMState *env) -{ - env->pstate &= ~PSTATE_SS; -} - -void HELPER(pre_hvc)(CPUARMState *env) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int cur_el = arm_current_el(env); - /* FIXME: Use actual secure state. */ - bool secure = false; - bool undef; - - if (arm_is_psci_call(cpu, EXCP_HVC)) { - /* If PSCI is enabled and this looks like a valid PSCI call then - * that overrides the architecturally mandated HVC behaviour. - */ - return; - } - - if (!arm_feature(env, ARM_FEATURE_EL2)) { - /* If EL2 doesn't exist, HVC always UNDEFs */ - undef = true; - } else if (arm_feature(env, ARM_FEATURE_EL3)) { - /* EL3.HCE has priority over EL2.HCD. */ - undef = !(env->cp15.scr_el3 & SCR_HCE); - } else { - undef = env->cp15.hcr_el2 & HCR_HCD; - } - - /* In ARMv7 and ARMv8/AArch32, HVC is undef in secure state. - * For ARMv8/AArch64, HVC is allowed in EL3. - * Note that we've already trapped HVC from EL0 at translation - * time. - */ - if (secure && (!is_a64(env) || cur_el == 1)) { - undef = true; - } - - if (undef) { - raise_exception(env, EXCP_UDEF, syn_uncategorized(), - exception_target_el(env)); - } -} - -void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - int cur_el = arm_current_el(env); - bool secure = arm_is_secure(env); - bool smd = env->cp15.scr_el3 & SCR_SMD; - /* On ARMv8 AArch32, SMD only applies to NS state. - * On ARMv7 SMD only applies to NS state and only if EL2 is available. - * For ARMv7 non EL2, we force SMD to zero so we don't need to re-check - * the EL2 condition here. - */ - bool undef = is_a64(env) ? smd : (!secure && smd); - - if (arm_is_psci_call(cpu, EXCP_SMC)) { - /* If PSCI is enabled and this looks like a valid PSCI call then - * that overrides the architecturally mandated SMC behaviour. - */ - return; - } - - if (!arm_feature(env, ARM_FEATURE_EL3)) { - /* If we have no EL3 then SMC always UNDEFs */ - undef = true; - } else if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) { - /* In NS EL1, HCR controlled routing to EL2 has priority over SMD. */ - raise_exception(env, EXCP_HYP_TRAP, syndrome, 2); - } - - if (undef) { - raise_exception(env, EXCP_UDEF, syn_uncategorized(), - exception_target_el(env)); - } -} - -void HELPER(exception_return)(CPUARMState *env) -{ - int cur_el = arm_current_el(env); - unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el); - uint32_t spsr = env->banked_spsr[spsr_idx]; - int new_el; - - aarch64_save_sp(env, cur_el); - - env->exclusive_addr = -1; - - /* We must squash the PSTATE.SS bit to zero unless both of the - * following hold: - * 1. debug exceptions are currently disabled - * 2. singlestep will be active in the EL we return to - * We check 1 here and 2 after we've done the pstate/cpsr write() to - * transition to the EL we're going to. - */ - if (arm_generate_debug_exceptions(env)) { - spsr &= ~PSTATE_SS; - } - - if (spsr & PSTATE_nRW) { - /* TODO: We currently assume EL1/2/3 are running in AArch64. */ - env->aarch64 = 0; - new_el = 0; - env->uncached_cpsr = 0x10; - cpsr_write(env, spsr, ~0); - if (!arm_singlestep_active(env)) { - env->uncached_cpsr &= ~PSTATE_SS; - } - aarch64_sync_64_to_32(env); - - env->regs[15] = env->elr_el[1] & ~0x1; - } else { - new_el = extract32(spsr, 2, 2); - if (new_el > cur_el - || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) { - /* Disallow return to an EL which is unimplemented or higher - * than the current one. - */ - goto illegal_return; - } - if (extract32(spsr, 1, 1)) { - /* Return with reserved M[1] bit set */ - goto illegal_return; - } - if (new_el == 0 && (spsr & PSTATE_SP)) { - /* Return to EL0 with M[0] bit set */ - goto illegal_return; - } - env->aarch64 = 1; - pstate_write(env, spsr); - if (!arm_singlestep_active(env)) { - env->pstate &= ~PSTATE_SS; - } - aarch64_restore_sp(env, new_el); - env->pc = env->elr_el[cur_el]; - } - - return; - -illegal_return: - /* Illegal return events of various kinds have architecturally - * mandated behaviour: - * restore NZCV and DAIF from SPSR_ELx - * set PSTATE.IL - * restore PC from ELR_ELx - * no change to exception level, execution state or stack pointer - */ - env->pstate |= PSTATE_IL; - env->pc = env->elr_el[cur_el]; - spsr &= PSTATE_NZCV | PSTATE_DAIF; - spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF); - pstate_write(env, spsr); - if (!arm_singlestep_active(env)) { - env->pstate &= ~PSTATE_SS; - } -} - -/* Return true if the linked breakpoint entry lbn passes its checks */ -static bool linked_bp_matches(ARMCPU *cpu, int lbn) -{ - CPUARMState *env = &cpu->env; - uint64_t bcr = env->cp15.dbgbcr[lbn]; - int brps = extract32(cpu->dbgdidr, 24, 4); - int ctx_cmps = extract32(cpu->dbgdidr, 20, 4); - int bt; - uint32_t contextidr; - - /* Links to unimplemented or non-context aware breakpoints are - * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or - * as if linked to an UNKNOWN context-aware breakpoint (in which - * case DBGWCR_EL1.LBN must indicate that breakpoint). - * We choose the former. - */ - if (lbn > brps || lbn < (brps - ctx_cmps)) { - return false; - } - - bcr = env->cp15.dbgbcr[lbn]; - - if (extract64(bcr, 0, 1) == 0) { - /* Linked breakpoint disabled : generate no events */ - return false; - } - - bt = extract64(bcr, 20, 4); - - /* We match the whole register even if this is AArch32 using the - * short descriptor format (in which case it holds both PROCID and ASID), - * since we don't implement the optional v7 context ID masking. - */ - contextidr = extract64(env->cp15.contextidr_el[1], 0, 32); - - switch (bt) { - case 3: /* linked context ID match */ - if (arm_current_el(env) > 1) { - /* Context matches never fire in EL2 or (AArch64) EL3 */ - return false; - } - return (contextidr == extract64(env->cp15.dbgbvr[lbn], 0, 32)); - case 5: /* linked address mismatch (reserved in AArch64) */ - case 9: /* linked VMID match (reserved if no EL2) */ - case 11: /* linked context ID and VMID match (reserved if no EL2) */ - default: - /* Links to Unlinked context breakpoints must generate no - * events; we choose to do the same for reserved values too. - */ - return false; - } - - return false; -} - -static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp) -{ - CPUARMState *env = &cpu->env; - uint64_t cr; - int pac, hmc, ssc, wt, lbn; - /* Note that for watchpoints the check is against the CPU security - * state, not the S/NS attribute on the offending data access. - */ - bool is_secure = arm_is_secure(env); - int access_el = arm_current_el(env); - - if (is_wp) { - CPUWatchpoint *wp = env->cpu_watchpoint[n]; - - if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) { - return false; - } - cr = env->cp15.dbgwcr[n]; - if (wp->hitattrs.user) { - /* The LDRT/STRT/LDT/STT "unprivileged access" instructions should - * match watchpoints as if they were accesses done at EL0, even if - * the CPU is at EL1 or higher. - */ - access_el = 0; - } - } else { - uint64_t pc = is_a64(env) ? env->pc : env->regs[15]; - - if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) { - return false; - } - cr = env->cp15.dbgbcr[n]; - } - /* The WATCHPOINT_HIT flag guarantees us that the watchpoint is - * enabled and that the address and access type match; for breakpoints - * we know the address matched; check the remaining fields, including - * linked breakpoints. We rely on WCR and BCR having the same layout - * for the LBN, SSC, HMC, PAC/PMC and is-linked fields. - * Note that some combinations of {PAC, HMC, SSC} are reserved and - * must act either like some valid combination or as if the watchpoint - * were disabled. We choose the former, and use this together with - * the fact that EL3 must always be Secure and EL2 must always be - * Non-Secure to simplify the code slightly compared to the full - * table in the ARM ARM. - */ - pac = extract64(cr, 1, 2); - hmc = extract64(cr, 13, 1); - ssc = extract64(cr, 14, 2); - - switch (ssc) { - case 0: - break; - case 1: - case 3: - if (is_secure) { - return false; - } - break; - case 2: - if (!is_secure) { - return false; - } - break; - } - - switch (access_el) { - case 3: - case 2: - if (!hmc) { - return false; - } - break; - case 1: - if (extract32(pac, 0, 1) == 0) { - return false; - } - break; - case 0: - if (extract32(pac, 1, 1) == 0) { - return false; - } - break; - default: - g_assert_not_reached(); - } - - wt = extract64(cr, 20, 1); - lbn = extract64(cr, 16, 4); - - if (wt && !linked_bp_matches(cpu, lbn)) { - return false; - } - - return true; -} - -static bool check_watchpoints(ARMCPU *cpu) -{ - CPUARMState *env = &cpu->env; - int n; - - /* If watchpoints are disabled globally or we can't take debug - * exceptions here then watchpoint firings are ignored. - */ - if (extract32(env->cp15.mdscr_el1, 15, 1) == 0 - || !arm_generate_debug_exceptions(env)) { - return false; - } - - for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) { - if (bp_wp_matches(cpu, n, true)) { - return true; - } - } - return false; -} - -static bool check_breakpoints(ARMCPU *cpu) -{ - CPUARMState *env = &cpu->env; - int n; - - /* If breakpoints are disabled globally or we can't take debug - * exceptions here then breakpoint firings are ignored. - */ - if (extract32(env->cp15.mdscr_el1, 15, 1) == 0 - || !arm_generate_debug_exceptions(env)) { - return false; - } - - for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) { - if (bp_wp_matches(cpu, n, false)) { - return true; - } - } - return false; -} - -void HELPER(check_breakpoints)(CPUARMState *env) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - - if (check_breakpoints(cpu)) { - HELPER(exception_internal(env, EXCP_DEBUG)); - } -} - -void arm_debug_excp_handler(CPUState *cs) -{ - /* Called by core code when a watchpoint or breakpoint fires; - * need to check which one and raise the appropriate exception. - */ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - CPUWatchpoint *wp_hit = cs->watchpoint_hit; - - if (wp_hit) { - if (wp_hit->flags & BP_CPU) { - cs->watchpoint_hit = NULL; - if (check_watchpoints(cpu)) { - bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0; - bool same_el = arm_debug_target_el(env) == arm_current_el(env); - - if (extended_addresses_enabled(env)) { - env->exception.fsr = (1 << 9) | 0x22; - } else { - env->exception.fsr = 0x2; - } - env->exception.vaddress = wp_hit->hitaddr; - raise_exception(env, EXCP_DATA_ABORT, - syn_watchpoint(same_el, 0, wnr), - arm_debug_target_el(env)); - } else { - cpu_resume_from_signal(cs, NULL); - } - } - } else { - uint64_t pc = is_a64(env) ? env->pc : env->regs[15]; - bool same_el = (arm_debug_target_el(env) == arm_current_el(env)); - - /* (1) GDB breakpoints should be handled first. - * (2) Do not raise a CPU exception if no CPU breakpoint has fired, - * since singlestep is also done by generating a debug internal - * exception. - */ - if (cpu_breakpoint_test(cs, pc, BP_GDB) - || !cpu_breakpoint_test(cs, pc, BP_CPU)) { - return; - } - - if (extended_addresses_enabled(env)) { - env->exception.fsr = (1 << 9) | 0x22; - } else { - env->exception.fsr = 0x2; - } - /* FAR is UNKNOWN, so doesn't need setting */ - raise_exception(env, EXCP_PREFETCH_ABORT, - syn_breakpoint(same_el), - arm_debug_target_el(env)); - } -} - -/* ??? Flag setting arithmetic is awkward because we need to do comparisons. - The only way to do that in TCG is a conditional branch, which clobbers - all our temporaries. For now implement these as helper functions. */ - -/* Similarly for variable shift instructions. */ - -uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) { - if (shift == 32) - env->CF = x & 1; - else - env->CF = 0; - return 0; - } else if (shift != 0) { - env->CF = (x >> (32 - shift)) & 1; - return x << shift; - } - return x; -} - -uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) { - if (shift == 32) - env->CF = (x >> 31) & 1; - else - env->CF = 0; - return 0; - } else if (shift != 0) { - env->CF = (x >> (shift - 1)) & 1; - return x >> shift; - } - return x; -} - -uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) { - env->CF = (x >> 31) & 1; - return (int32_t)x >> 31; - } else if (shift != 0) { - env->CF = (x >> (shift - 1)) & 1; - return (int32_t)x >> shift; - } - return x; -} - -uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift1, shift; - shift1 = i & 0xff; - shift = shift1 & 0x1f; - if (shift == 0) { - if (shift1 != 0) - env->CF = (x >> 31) & 1; - return x; - } else { - env->CF = (x >> (shift - 1)) & 1; - return ((uint32_t)x >> shift) | (x << (32 - shift)); - } -} diff --git a/target-arm/translate.c b/target-arm/translate.c deleted file mode 100644 index 029f33783ea28..0000000000000 --- a/target-arm/translate.c +++ /dev/null @@ -1,11688 +0,0 @@ -/* - * ARM translation - * - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2005-2007 CodeSourcery - * Copyright (c) 2007 OpenedHand, Ltd. - * - * 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 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 . - */ -#include -#include -#include -#include -#include - -#include "cpu.h" -#include "internals.h" -#include "disas/disas.h" -#include "tcg-op.h" -#include "qemu/log.h" -#include "qemu/bitops.h" -#include "arm_ldst.h" - -#include "exec/helper-proto.h" -#include "exec/helper-gen.h" - -#include "trace-tcg.h" - - -#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T) -#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5) -/* currently all emulated v5 cores are also v5TE, so don't bother */ -#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5) -#define ENABLE_ARCH_5J 0 -#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6) -#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K) -#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2) -#define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7) -#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8) - -#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0) - -#include "translate.h" - -#if defined(CONFIG_USER_ONLY) -#define IS_USER(s) 1 -#else -#define IS_USER(s) (s->user) -#endif - -TCGv_ptr cpu_env; -/* We reuse the same 64-bit temporaries for efficiency. */ -static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; -static TCGv_i32 cpu_R[16]; -TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF; -TCGv_i64 cpu_exclusive_addr; -TCGv_i64 cpu_exclusive_val; -#ifdef CONFIG_USER_ONLY -TCGv_i64 cpu_exclusive_test; -TCGv_i32 cpu_exclusive_info; -#endif - -/* FIXME: These should be removed. */ -static TCGv_i32 cpu_F0s, cpu_F1s; -static TCGv_i64 cpu_F0d, cpu_F1d; - -#include "exec/gen-icount.h" - -static const char *regnames[] = - { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" }; - -/* initialize TCG globals. */ -void arm_translate_init(void) -{ - int i; - - cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); - - for (i = 0; i < 16; i++) { - cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUARMState, regs[i]), - regnames[i]); - } - cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF"); - cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF"); - cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF"); - cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF"); - - cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUARMState, exclusive_addr), "exclusive_addr"); - cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUARMState, exclusive_val), "exclusive_val"); -#ifdef CONFIG_USER_ONLY - cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUARMState, exclusive_test), "exclusive_test"); - cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUARMState, exclusive_info), "exclusive_info"); -#endif - - a64_translate_init(); -} - -static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s) -{ - /* Return the mmu_idx to use for A32/T32 "unprivileged load/store" - * insns: - * if PL2, UNPREDICTABLE (we choose to implement as if PL0) - * otherwise, access as if at PL0. - */ - switch (s->mmu_idx) { - case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */ - case ARMMMUIdx_S12NSE0: - case ARMMMUIdx_S12NSE1: - return ARMMMUIdx_S12NSE0; - case ARMMMUIdx_S1E3: - case ARMMMUIdx_S1SE0: - case ARMMMUIdx_S1SE1: - return ARMMMUIdx_S1SE0; - case ARMMMUIdx_S2NS: - default: - g_assert_not_reached(); - } -} - -static inline TCGv_i32 load_cpu_offset(int offset) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_ld_i32(tmp, cpu_env, offset); - return tmp; -} - -#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name)) - -static inline void store_cpu_offset(TCGv_i32 var, int offset) -{ - tcg_gen_st_i32(var, cpu_env, offset); - tcg_temp_free_i32(var); -} - -#define store_cpu_field(var, name) \ - store_cpu_offset(var, offsetof(CPUARMState, name)) - -/* Set a variable to the value of a CPU register. */ -static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg) -{ - if (reg == 15) { - uint32_t addr; - /* normally, since we updated PC, we need only to add one insn */ - if (s->thumb) - addr = (long)s->pc + 2; - else - addr = (long)s->pc + 4; - tcg_gen_movi_i32(var, addr); - } else { - tcg_gen_mov_i32(var, cpu_R[reg]); - } -} - -/* Create a new temporary and set it to the value of a CPU register. */ -static inline TCGv_i32 load_reg(DisasContext *s, int reg) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - load_reg_var(s, tmp, reg); - return tmp; -} - -/* Set a CPU register. The source must be a temporary and will be - marked as dead. */ -static void store_reg(DisasContext *s, int reg, TCGv_i32 var) -{ - if (reg == 15) { - tcg_gen_andi_i32(var, var, ~1); - s->is_jmp = DISAS_JUMP; - } - tcg_gen_mov_i32(cpu_R[reg], var); - tcg_temp_free_i32(var); -} - -/* Value extensions. */ -#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var) -#define gen_uxth(var) tcg_gen_ext16u_i32(var, var) -#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) -#define gen_sxth(var) tcg_gen_ext16s_i32(var, var) - -#define gen_sxtb16(var) gen_helper_sxtb16(var, var) -#define gen_uxtb16(var) gen_helper_uxtb16(var, var) - - -static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask) -{ - TCGv_i32 tmp_mask = tcg_const_i32(mask); - gen_helper_cpsr_write(cpu_env, var, tmp_mask); - tcg_temp_free_i32(tmp_mask); -} -/* Set NZCV flags from the high 4 bits of var. */ -#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV) - -static void gen_exception_internal(int excp) -{ - TCGv_i32 tcg_excp = tcg_const_i32(excp); - - assert(excp_is_internal(excp)); - gen_helper_exception_internal(cpu_env, tcg_excp); - tcg_temp_free_i32(tcg_excp); -} - -static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el) -{ - TCGv_i32 tcg_excp = tcg_const_i32(excp); - TCGv_i32 tcg_syn = tcg_const_i32(syndrome); - TCGv_i32 tcg_el = tcg_const_i32(target_el); - - gen_helper_exception_with_syndrome(cpu_env, tcg_excp, - tcg_syn, tcg_el); - - tcg_temp_free_i32(tcg_el); - tcg_temp_free_i32(tcg_syn); - tcg_temp_free_i32(tcg_excp); -} - -static void gen_ss_advance(DisasContext *s) -{ - /* If the singlestep state is Active-not-pending, advance to - * Active-pending. - */ - if (s->ss_active) { - s->pstate_ss = 0; - gen_helper_clear_pstate_ss(cpu_env); - } -} - -static void gen_step_complete_exception(DisasContext *s) -{ - /* We just completed step of an insn. Move from Active-not-pending - * to Active-pending, and then also take the swstep exception. - * This corresponds to making the (IMPDEF) choice to prioritize - * swstep exceptions over asynchronous exceptions taken to an exception - * level where debug is disabled. This choice has the advantage that - * we do not need to maintain internal state corresponding to the - * ISV/EX syndrome bits between completion of the step and generation - * of the exception, and our syndrome information is always correct. - */ - gen_ss_advance(s); - gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex), - default_exception_el(s)); - s->is_jmp = DISAS_EXC; -} - -static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b) -{ - TCGv_i32 tmp1 = tcg_temp_new_i32(); - TCGv_i32 tmp2 = tcg_temp_new_i32(); - tcg_gen_ext16s_i32(tmp1, a); - tcg_gen_ext16s_i32(tmp2, b); - tcg_gen_mul_i32(tmp1, tmp1, tmp2); - tcg_temp_free_i32(tmp2); - tcg_gen_sari_i32(a, a, 16); - tcg_gen_sari_i32(b, b, 16); - tcg_gen_mul_i32(b, b, a); - tcg_gen_mov_i32(a, tmp1); - tcg_temp_free_i32(tmp1); -} - -/* Byteswap each halfword. */ -static void gen_rev16(TCGv_i32 var) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_shri_i32(tmp, var, 8); - tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff); - tcg_gen_shli_i32(var, var, 8); - tcg_gen_andi_i32(var, var, 0xff00ff00); - tcg_gen_or_i32(var, var, tmp); - tcg_temp_free_i32(tmp); -} - -/* Byteswap low halfword and sign extend. */ -static void gen_revsh(TCGv_i32 var) -{ - tcg_gen_ext16u_i32(var, var); - tcg_gen_bswap16_i32(var, var); - tcg_gen_ext16s_i32(var, var); -} - -/* Unsigned bitfield extract. */ -static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask) -{ - if (shift) - tcg_gen_shri_i32(var, var, shift); - tcg_gen_andi_i32(var, var, mask); -} - -/* Signed bitfield extract. */ -static void gen_sbfx(TCGv_i32 var, int shift, int width) -{ - uint32_t signbit; - - if (shift) - tcg_gen_sari_i32(var, var, shift); - if (shift + width < 32) { - signbit = 1u << (width - 1); - tcg_gen_andi_i32(var, var, (1u << width) - 1); - tcg_gen_xori_i32(var, var, signbit); - tcg_gen_subi_i32(var, var, signbit); - } -} - -/* Return (b << 32) + a. Mark inputs as dead */ -static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b) -{ - TCGv_i64 tmp64 = tcg_temp_new_i64(); - - tcg_gen_extu_i32_i64(tmp64, b); - tcg_temp_free_i32(b); - tcg_gen_shli_i64(tmp64, tmp64, 32); - tcg_gen_add_i64(a, tmp64, a); - - tcg_temp_free_i64(tmp64); - return a; -} - -/* Return (b << 32) - a. Mark inputs as dead. */ -static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b) -{ - TCGv_i64 tmp64 = tcg_temp_new_i64(); - - tcg_gen_extu_i32_i64(tmp64, b); - tcg_temp_free_i32(b); - tcg_gen_shli_i64(tmp64, tmp64, 32); - tcg_gen_sub_i64(a, tmp64, a); - - tcg_temp_free_i64(tmp64); - return a; -} - -/* 32x32->64 multiply. Marks inputs as dead. */ -static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b) -{ - TCGv_i32 lo = tcg_temp_new_i32(); - TCGv_i32 hi = tcg_temp_new_i32(); - TCGv_i64 ret; - - tcg_gen_mulu2_i32(lo, hi, a, b); - tcg_temp_free_i32(a); - tcg_temp_free_i32(b); - - ret = tcg_temp_new_i64(); - tcg_gen_concat_i32_i64(ret, lo, hi); - tcg_temp_free_i32(lo); - tcg_temp_free_i32(hi); - - return ret; -} - -static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b) -{ - TCGv_i32 lo = tcg_temp_new_i32(); - TCGv_i32 hi = tcg_temp_new_i32(); - TCGv_i64 ret; - - tcg_gen_muls2_i32(lo, hi, a, b); - tcg_temp_free_i32(a); - tcg_temp_free_i32(b); - - ret = tcg_temp_new_i64(); - tcg_gen_concat_i32_i64(ret, lo, hi); - tcg_temp_free_i32(lo); - tcg_temp_free_i32(hi); - - return ret; -} - -/* Swap low and high halfwords. */ -static void gen_swap_half(TCGv_i32 var) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_shri_i32(tmp, var, 16); - tcg_gen_shli_i32(var, var, 16); - tcg_gen_or_i32(var, var, tmp); - tcg_temp_free_i32(tmp); -} - -/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. - tmp = (t0 ^ t1) & 0x8000; - t0 &= ~0x8000; - t1 &= ~0x8000; - t0 = (t0 + t1) ^ tmp; - */ - -static void gen_add16(TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_xor_i32(tmp, t0, t1); - tcg_gen_andi_i32(tmp, tmp, 0x8000); - tcg_gen_andi_i32(t0, t0, ~0x8000); - tcg_gen_andi_i32(t1, t1, ~0x8000); - tcg_gen_add_i32(t0, t0, t1); - tcg_gen_xor_i32(t0, t0, tmp); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(t1); -} - -/* Set CF to the top bit of var. */ -static void gen_set_CF_bit31(TCGv_i32 var) -{ - tcg_gen_shri_i32(cpu_CF, var, 31); -} - -/* Set N and Z flags from var. */ -static inline void gen_logic_CC(TCGv_i32 var) -{ - tcg_gen_mov_i32(cpu_NF, var); - tcg_gen_mov_i32(cpu_ZF, var); -} - -/* T0 += T1 + CF. */ -static void gen_adc(TCGv_i32 t0, TCGv_i32 t1) -{ - tcg_gen_add_i32(t0, t0, t1); - tcg_gen_add_i32(t0, t0, cpu_CF); -} - -/* dest = T0 + T1 + CF. */ -static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - tcg_gen_add_i32(dest, t0, t1); - tcg_gen_add_i32(dest, dest, cpu_CF); -} - -/* dest = T0 - T1 + CF - 1. */ -static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - tcg_gen_sub_i32(dest, t0, t1); - tcg_gen_add_i32(dest, dest, cpu_CF); - tcg_gen_subi_i32(dest, dest, 1); -} - -/* dest = T0 + T1. Compute C, N, V and Z flags */ -static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp); - tcg_gen_mov_i32(cpu_ZF, cpu_NF); - tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); - tcg_gen_xor_i32(tmp, t0, t1); - tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp); - tcg_temp_free_i32(tmp); - tcg_gen_mov_i32(dest, cpu_NF); -} - -/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */ -static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - if (TCG_TARGET_HAS_add2_i32) { - tcg_gen_movi_i32(tmp, 0); - tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp); - tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp); - } else { - TCGv_i64 q0 = tcg_temp_new_i64(); - TCGv_i64 q1 = tcg_temp_new_i64(); - tcg_gen_extu_i32_i64(q0, t0); - tcg_gen_extu_i32_i64(q1, t1); - tcg_gen_add_i64(q0, q0, q1); - tcg_gen_extu_i32_i64(q1, cpu_CF); - tcg_gen_add_i64(q0, q0, q1); - tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0); - tcg_temp_free_i64(q0); - tcg_temp_free_i64(q1); - } - tcg_gen_mov_i32(cpu_ZF, cpu_NF); - tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); - tcg_gen_xor_i32(tmp, t0, t1); - tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp); - tcg_temp_free_i32(tmp); - tcg_gen_mov_i32(dest, cpu_NF); -} - -/* dest = T0 - T1. Compute C, N, V and Z flags */ -static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 tmp; - tcg_gen_sub_i32(cpu_NF, t0, t1); - tcg_gen_mov_i32(cpu_ZF, cpu_NF); - tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1); - tcg_gen_xor_i32(cpu_VF, cpu_NF, t0); - tmp = tcg_temp_new_i32(); - tcg_gen_xor_i32(tmp, t0, t1); - tcg_gen_and_i32(cpu_VF, cpu_VF, tmp); - tcg_temp_free_i32(tmp); - tcg_gen_mov_i32(dest, cpu_NF); -} - -/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */ -static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_not_i32(tmp, t1); - gen_adc_CC(dest, t0, tmp); - tcg_temp_free_i32(tmp); -} - -#define GEN_SHIFT(name) \ -static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \ -{ \ - TCGv_i32 tmp1, tmp2, tmp3; \ - tmp1 = tcg_temp_new_i32(); \ - tcg_gen_andi_i32(tmp1, t1, 0xff); \ - tmp2 = tcg_const_i32(0); \ - tmp3 = tcg_const_i32(0x1f); \ - tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \ - tcg_temp_free_i32(tmp3); \ - tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \ - tcg_gen_##name##_i32(dest, tmp2, tmp1); \ - tcg_temp_free_i32(tmp2); \ - tcg_temp_free_i32(tmp1); \ -} -GEN_SHIFT(shl) -GEN_SHIFT(shr) -#undef GEN_SHIFT - -static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 tmp1, tmp2; - tmp1 = tcg_temp_new_i32(); - tcg_gen_andi_i32(tmp1, t1, 0xff); - tmp2 = tcg_const_i32(0x1f); - tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1); - tcg_temp_free_i32(tmp2); - tcg_gen_sar_i32(dest, t0, tmp1); - tcg_temp_free_i32(tmp1); -} - -static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src) -{ - TCGv_i32 c0 = tcg_const_i32(0); - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_neg_i32(tmp, src); - tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp); - tcg_temp_free_i32(c0); - tcg_temp_free_i32(tmp); -} - -static void shifter_out_im(TCGv_i32 var, int shift) -{ - if (shift == 0) { - tcg_gen_andi_i32(cpu_CF, var, 1); - } else { - tcg_gen_shri_i32(cpu_CF, var, shift); - if (shift != 31) { - tcg_gen_andi_i32(cpu_CF, cpu_CF, 1); - } - } -} - -/* Shift by immediate. Includes special handling for shift == 0. */ -static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop, - int shift, int flags) -{ - switch (shiftop) { - case 0: /* LSL */ - if (shift != 0) { - if (flags) - shifter_out_im(var, 32 - shift); - tcg_gen_shli_i32(var, var, shift); - } - break; - case 1: /* LSR */ - if (shift == 0) { - if (flags) { - tcg_gen_shri_i32(cpu_CF, var, 31); - } - tcg_gen_movi_i32(var, 0); - } else { - if (flags) - shifter_out_im(var, shift - 1); - tcg_gen_shri_i32(var, var, shift); - } - break; - case 2: /* ASR */ - if (shift == 0) - shift = 32; - if (flags) - shifter_out_im(var, shift - 1); - if (shift == 32) - shift = 31; - tcg_gen_sari_i32(var, var, shift); - break; - case 3: /* ROR/RRX */ - if (shift != 0) { - if (flags) - shifter_out_im(var, shift - 1); - tcg_gen_rotri_i32(var, var, shift); break; - } else { - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_shli_i32(tmp, cpu_CF, 31); - if (flags) - shifter_out_im(var, 0); - tcg_gen_shri_i32(var, var, 1); - tcg_gen_or_i32(var, var, tmp); - tcg_temp_free_i32(tmp); - } - } -}; - -static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop, - TCGv_i32 shift, int flags) -{ - if (flags) { - switch (shiftop) { - case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break; - case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break; - case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break; - case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break; - } - } else { - switch (shiftop) { - case 0: - gen_shl(var, var, shift); - break; - case 1: - gen_shr(var, var, shift); - break; - case 2: - gen_sar(var, var, shift); - break; - case 3: tcg_gen_andi_i32(shift, shift, 0x1f); - tcg_gen_rotr_i32(var, var, shift); break; - } - } - tcg_temp_free_i32(shift); -} - -#define PAS_OP(pfx) \ - switch (op2) { \ - case 0: gen_pas_helper(glue(pfx,add16)); break; \ - case 1: gen_pas_helper(glue(pfx,addsubx)); break; \ - case 2: gen_pas_helper(glue(pfx,subaddx)); break; \ - case 3: gen_pas_helper(glue(pfx,sub16)); break; \ - case 4: gen_pas_helper(glue(pfx,add8)); break; \ - case 7: gen_pas_helper(glue(pfx,sub8)); break; \ - } -static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b) -{ - TCGv_ptr tmp; - - switch (op1) { -#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) - case 1: - tmp = tcg_temp_new_ptr(); - tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); - PAS_OP(s) - tcg_temp_free_ptr(tmp); - break; - case 5: - tmp = tcg_temp_new_ptr(); - tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); - PAS_OP(u) - tcg_temp_free_ptr(tmp); - break; -#undef gen_pas_helper -#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) - case 2: - PAS_OP(q); - break; - case 3: - PAS_OP(sh); - break; - case 6: - PAS_OP(uq); - break; - case 7: - PAS_OP(uh); - break; -#undef gen_pas_helper - } -} -#undef PAS_OP - -/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */ -#define PAS_OP(pfx) \ - switch (op1) { \ - case 0: gen_pas_helper(glue(pfx,add8)); break; \ - case 1: gen_pas_helper(glue(pfx,add16)); break; \ - case 2: gen_pas_helper(glue(pfx,addsubx)); break; \ - case 4: gen_pas_helper(glue(pfx,sub8)); break; \ - case 5: gen_pas_helper(glue(pfx,sub16)); break; \ - case 6: gen_pas_helper(glue(pfx,subaddx)); break; \ - } -static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b) -{ - TCGv_ptr tmp; - - switch (op2) { -#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) - case 0: - tmp = tcg_temp_new_ptr(); - tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); - PAS_OP(s) - tcg_temp_free_ptr(tmp); - break; - case 4: - tmp = tcg_temp_new_ptr(); - tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE)); - PAS_OP(u) - tcg_temp_free_ptr(tmp); - break; -#undef gen_pas_helper -#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) - case 1: - PAS_OP(q); - break; - case 2: - PAS_OP(sh); - break; - case 5: - PAS_OP(uq); - break; - case 6: - PAS_OP(uh); - break; -#undef gen_pas_helper - } -} -#undef PAS_OP - -/* - * Generate a conditional based on ARM condition code cc. - * This is common between ARM and Aarch64 targets. - */ -void arm_test_cc(DisasCompare *cmp, int cc) -{ - TCGv_i32 value; - TCGCond cond; - bool global = true; - - switch (cc) { - case 0: /* eq: Z */ - case 1: /* ne: !Z */ - cond = TCG_COND_EQ; - value = cpu_ZF; - break; - - case 2: /* cs: C */ - case 3: /* cc: !C */ - cond = TCG_COND_NE; - value = cpu_CF; - break; - - case 4: /* mi: N */ - case 5: /* pl: !N */ - cond = TCG_COND_LT; - value = cpu_NF; - break; - - case 6: /* vs: V */ - case 7: /* vc: !V */ - cond = TCG_COND_LT; - value = cpu_VF; - break; - - case 8: /* hi: C && !Z */ - case 9: /* ls: !C || Z -> !(C && !Z) */ - cond = TCG_COND_NE; - value = tcg_temp_new_i32(); - global = false; - /* CF is 1 for C, so -CF is an all-bits-set mask for C; - ZF is non-zero for !Z; so AND the two subexpressions. */ - tcg_gen_neg_i32(value, cpu_CF); - tcg_gen_and_i32(value, value, cpu_ZF); - break; - - case 10: /* ge: N == V -> N ^ V == 0 */ - case 11: /* lt: N != V -> N ^ V != 0 */ - /* Since we're only interested in the sign bit, == 0 is >= 0. */ - cond = TCG_COND_GE; - value = tcg_temp_new_i32(); - global = false; - tcg_gen_xor_i32(value, cpu_VF, cpu_NF); - break; - - case 12: /* gt: !Z && N == V */ - case 13: /* le: Z || N != V */ - cond = TCG_COND_NE; - value = tcg_temp_new_i32(); - global = false; - /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate - * the sign bit then AND with ZF to yield the result. */ - tcg_gen_xor_i32(value, cpu_VF, cpu_NF); - tcg_gen_sari_i32(value, value, 31); - tcg_gen_andc_i32(value, cpu_ZF, value); - break; - - case 14: /* always */ - case 15: /* always */ - /* Use the ALWAYS condition, which will fold early. - * It doesn't matter what we use for the value. */ - cond = TCG_COND_ALWAYS; - value = cpu_ZF; - goto no_invert; - - default: - fprintf(stderr, "Bad condition code 0x%x\n", cc); - abort(); - } - - if (cc & 1) { - cond = tcg_invert_cond(cond); - } - - no_invert: - cmp->cond = cond; - cmp->value = value; - cmp->value_global = global; -} - -void arm_free_cc(DisasCompare *cmp) -{ - if (!cmp->value_global) { - tcg_temp_free_i32(cmp->value); - } -} - -void arm_jump_cc(DisasCompare *cmp, TCGLabel *label) -{ - tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label); -} - -void arm_gen_test_cc(int cc, TCGLabel *label) -{ - DisasCompare cmp; - arm_test_cc(&cmp, cc); - arm_jump_cc(&cmp, label); - arm_free_cc(&cmp); -} - -static const uint8_t table_logic_cc[16] = { - 1, /* and */ - 1, /* xor */ - 0, /* sub */ - 0, /* rsb */ - 0, /* add */ - 0, /* adc */ - 0, /* sbc */ - 0, /* rsc */ - 1, /* andl */ - 1, /* xorl */ - 0, /* cmp */ - 0, /* cmn */ - 1, /* orr */ - 1, /* mov */ - 1, /* bic */ - 1, /* mvn */ -}; - -/* Set PC and Thumb state from an immediate address. */ -static inline void gen_bx_im(DisasContext *s, uint32_t addr) -{ - TCGv_i32 tmp; - - s->is_jmp = DISAS_JUMP; - if (s->thumb != (addr & 1)) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, addr & 1); - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb)); - tcg_temp_free_i32(tmp); - } - tcg_gen_movi_i32(cpu_R[15], addr & ~1); -} - -/* Set PC and Thumb state from var. var is marked as dead. */ -static inline void gen_bx(DisasContext *s, TCGv_i32 var) -{ - s->is_jmp = DISAS_JUMP; - tcg_gen_andi_i32(cpu_R[15], var, ~1); - tcg_gen_andi_i32(var, var, 1); - store_cpu_field(var, thumb); -} - -/* Variant of store_reg which uses branch&exchange logic when storing - to r15 in ARM architecture v7 and above. The source must be a temporary - and will be marked as dead. */ -static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var) -{ - if (reg == 15 && ENABLE_ARCH_7) { - gen_bx(s, var); - } else { - store_reg(s, reg, var); - } -} - -/* Variant of store_reg which uses branch&exchange logic when storing - * to r15 in ARM architecture v5T and above. This is used for storing - * the results of a LDR/LDM/POP into r15, and corresponds to the cases - * in the ARM ARM which use the LoadWritePC() pseudocode function. */ -static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var) -{ - if (reg == 15 && ENABLE_ARCH_5) { - gen_bx(s, var); - } else { - store_reg(s, reg, var); - } -} - -/* Abstractions of "generate code to do a guest load/store for - * AArch32", where a vaddr is always 32 bits (and is zero - * extended if we're a 64 bit core) and data is also - * 32 bits unless specifically doing a 64 bit access. - * These functions work like tcg_gen_qemu_{ld,st}* except - * that the address argument is TCGv_i32 rather than TCGv. - */ -#if TARGET_LONG_BITS == 32 - -#define DO_GEN_LD(SUFF, OPC) \ -static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ -{ \ - tcg_gen_qemu_ld_i32(val, addr, index, OPC); \ -} - -#define DO_GEN_ST(SUFF, OPC) \ -static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ -{ \ - tcg_gen_qemu_st_i32(val, addr, index, OPC); \ -} - -static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index) -{ - tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ); -} - -static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index) -{ - tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ); -} - -#else - -#define DO_GEN_LD(SUFF, OPC) \ -static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ -{ \ - TCGv addr64 = tcg_temp_new(); \ - tcg_gen_extu_i32_i64(addr64, addr); \ - tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \ - tcg_temp_free(addr64); \ -} - -#define DO_GEN_ST(SUFF, OPC) \ -static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \ -{ \ - TCGv addr64 = tcg_temp_new(); \ - tcg_gen_extu_i32_i64(addr64, addr); \ - tcg_gen_qemu_st_i32(val, addr64, index, OPC); \ - tcg_temp_free(addr64); \ -} - -static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index) -{ - TCGv addr64 = tcg_temp_new(); - tcg_gen_extu_i32_i64(addr64, addr); - tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ); - tcg_temp_free(addr64); -} - -static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index) -{ - TCGv addr64 = tcg_temp_new(); - tcg_gen_extu_i32_i64(addr64, addr); - tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ); - tcg_temp_free(addr64); -} - -#endif - -DO_GEN_LD(8s, MO_SB) -DO_GEN_LD(8u, MO_UB) -DO_GEN_LD(16s, MO_TESW) -DO_GEN_LD(16u, MO_TEUW) -DO_GEN_LD(32u, MO_TEUL) -DO_GEN_ST(8, MO_UB) -DO_GEN_ST(16, MO_TEUW) -DO_GEN_ST(32, MO_TEUL) - -static inline void gen_set_pc_im(DisasContext *s, target_ulong val) -{ - tcg_gen_movi_i32(cpu_R[15], val); -} - -static inline void gen_hvc(DisasContext *s, int imm16) -{ - /* The pre HVC helper handles cases when HVC gets trapped - * as an undefined insn by runtime configuration (ie before - * the insn really executes). - */ - gen_set_pc_im(s, s->pc - 4); - gen_helper_pre_hvc(cpu_env); - /* Otherwise we will treat this as a real exception which - * happens after execution of the insn. (The distinction matters - * for the PC value reported to the exception handler and also - * for single stepping.) - */ - s->svc_imm = imm16; - gen_set_pc_im(s, s->pc); - s->is_jmp = DISAS_HVC; -} - -static inline void gen_smc(DisasContext *s) -{ - /* As with HVC, we may take an exception either before or after - * the insn executes. - */ - TCGv_i32 tmp; - - gen_set_pc_im(s, s->pc - 4); - tmp = tcg_const_i32(syn_aa32_smc()); - gen_helper_pre_smc(cpu_env, tmp); - tcg_temp_free_i32(tmp); - gen_set_pc_im(s, s->pc); - s->is_jmp = DISAS_SMC; -} - -static inline void -gen_set_condexec (DisasContext *s) -{ - if (s->condexec_mask) { - uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - store_cpu_field(tmp, condexec_bits); - } -} - -static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) -{ - gen_set_condexec(s); - gen_set_pc_im(s, s->pc - offset); - gen_exception_internal(excp); - s->is_jmp = DISAS_JUMP; -} - -static void gen_exception_insn(DisasContext *s, int offset, int excp, - int syn, uint32_t target_el) -{ - gen_set_condexec(s); - gen_set_pc_im(s, s->pc - offset); - gen_exception(excp, syn, target_el); - s->is_jmp = DISAS_JUMP; -} - -/* Force a TB lookup after an instruction that changes the CPU state. */ -static inline void gen_lookup_tb(DisasContext *s) -{ - tcg_gen_movi_i32(cpu_R[15], s->pc & ~1); - s->is_jmp = DISAS_JUMP; -} - -static inline void gen_add_data_offset(DisasContext *s, unsigned int insn, - TCGv_i32 var) -{ - int val, rm, shift, shiftop; - TCGv_i32 offset; - - if (!(insn & (1 << 25))) { - /* immediate */ - val = insn & 0xfff; - if (!(insn & (1 << 23))) - val = -val; - if (val != 0) - tcg_gen_addi_i32(var, var, val); - } else { - /* shift/register */ - rm = (insn) & 0xf; - shift = (insn >> 7) & 0x1f; - shiftop = (insn >> 5) & 3; - offset = load_reg(s, rm); - gen_arm_shift_im(offset, shiftop, shift, 0); - if (!(insn & (1 << 23))) - tcg_gen_sub_i32(var, var, offset); - else - tcg_gen_add_i32(var, var, offset); - tcg_temp_free_i32(offset); - } -} - -static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, - int extra, TCGv_i32 var) -{ - int val, rm; - TCGv_i32 offset; - - if (insn & (1 << 22)) { - /* immediate */ - val = (insn & 0xf) | ((insn >> 4) & 0xf0); - if (!(insn & (1 << 23))) - val = -val; - val += extra; - if (val != 0) - tcg_gen_addi_i32(var, var, val); - } else { - /* register */ - if (extra) - tcg_gen_addi_i32(var, var, extra); - rm = (insn) & 0xf; - offset = load_reg(s, rm); - if (!(insn & (1 << 23))) - tcg_gen_sub_i32(var, var, offset); - else - tcg_gen_add_i32(var, var, offset); - tcg_temp_free_i32(offset); - } -} - -static TCGv_ptr get_fpstatus_ptr(int neon) -{ - TCGv_ptr statusptr = tcg_temp_new_ptr(); - int offset; - if (neon) { - offset = offsetof(CPUARMState, vfp.standard_fp_status); - } else { - offset = offsetof(CPUARMState, vfp.fp_status); - } - tcg_gen_addi_ptr(statusptr, cpu_env, offset); - return statusptr; -} - -#define VFP_OP2(name) \ -static inline void gen_vfp_##name(int dp) \ -{ \ - TCGv_ptr fpst = get_fpstatus_ptr(0); \ - if (dp) { \ - gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \ - } else { \ - gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \ - } \ - tcg_temp_free_ptr(fpst); \ -} - -VFP_OP2(add) -VFP_OP2(sub) -VFP_OP2(mul) -VFP_OP2(div) - -#undef VFP_OP2 - -static inline void gen_vfp_F1_mul(int dp) -{ - /* Like gen_vfp_mul() but put result in F1 */ - TCGv_ptr fpst = get_fpstatus_ptr(0); - if (dp) { - gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst); - } else { - gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst); - } - tcg_temp_free_ptr(fpst); -} - -static inline void gen_vfp_F1_neg(int dp) -{ - /* Like gen_vfp_neg() but put result in F1 */ - if (dp) { - gen_helper_vfp_negd(cpu_F1d, cpu_F0d); - } else { - gen_helper_vfp_negs(cpu_F1s, cpu_F0s); - } -} - -static inline void gen_vfp_abs(int dp) -{ - if (dp) - gen_helper_vfp_absd(cpu_F0d, cpu_F0d); - else - gen_helper_vfp_abss(cpu_F0s, cpu_F0s); -} - -static inline void gen_vfp_neg(int dp) -{ - if (dp) - gen_helper_vfp_negd(cpu_F0d, cpu_F0d); - else - gen_helper_vfp_negs(cpu_F0s, cpu_F0s); -} - -static inline void gen_vfp_sqrt(int dp) -{ - if (dp) - gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env); - else - gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env); -} - -static inline void gen_vfp_cmp(int dp) -{ - if (dp) - gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env); - else - gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env); -} - -static inline void gen_vfp_cmpe(int dp) -{ - if (dp) - gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env); - else - gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env); -} - -static inline void gen_vfp_F1_ld0(int dp) -{ - if (dp) - tcg_gen_movi_i64(cpu_F1d, 0); - else - tcg_gen_movi_i32(cpu_F1s, 0); -} - -#define VFP_GEN_ITOF(name) \ -static inline void gen_vfp_##name(int dp, int neon) \ -{ \ - TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ - if (dp) { \ - gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \ - } else { \ - gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ - } \ - tcg_temp_free_ptr(statusptr); \ -} - -VFP_GEN_ITOF(uito) -VFP_GEN_ITOF(sito) -#undef VFP_GEN_ITOF - -#define VFP_GEN_FTOI(name) \ -static inline void gen_vfp_##name(int dp, int neon) \ -{ \ - TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ - if (dp) { \ - gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \ - } else { \ - gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ - } \ - tcg_temp_free_ptr(statusptr); \ -} - -VFP_GEN_FTOI(toui) -VFP_GEN_FTOI(touiz) -VFP_GEN_FTOI(tosi) -VFP_GEN_FTOI(tosiz) -#undef VFP_GEN_FTOI - -#define VFP_GEN_FIX(name, round) \ -static inline void gen_vfp_##name(int dp, int shift, int neon) \ -{ \ - TCGv_i32 tmp_shift = tcg_const_i32(shift); \ - TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ - if (dp) { \ - gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \ - statusptr); \ - } else { \ - gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \ - statusptr); \ - } \ - tcg_temp_free_i32(tmp_shift); \ - tcg_temp_free_ptr(statusptr); \ -} -VFP_GEN_FIX(tosh, _round_to_zero) -VFP_GEN_FIX(tosl, _round_to_zero) -VFP_GEN_FIX(touh, _round_to_zero) -VFP_GEN_FIX(toul, _round_to_zero) -VFP_GEN_FIX(shto, ) -VFP_GEN_FIX(slto, ) -VFP_GEN_FIX(uhto, ) -VFP_GEN_FIX(ulto, ) -#undef VFP_GEN_FIX - -static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr) -{ - if (dp) { - gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s)); - } else { - gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s)); - } -} - -static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr) -{ - if (dp) { - gen_aa32_st64(cpu_F0d, addr, get_mem_index(s)); - } else { - gen_aa32_st32(cpu_F0s, addr, get_mem_index(s)); - } -} - -static inline long -vfp_reg_offset (int dp, int reg) -{ - if (dp) - return offsetof(CPUARMState, vfp.regs[reg]); - else if (reg & 1) { - return offsetof(CPUARMState, vfp.regs[reg >> 1]) - + offsetof(CPU_DoubleU, l.upper); - } else { - return offsetof(CPUARMState, vfp.regs[reg >> 1]) - + offsetof(CPU_DoubleU, l.lower); - } -} - -/* Return the offset of a 32-bit piece of a NEON register. - zero is the least significant end of the register. */ -static inline long -neon_reg_offset (int reg, int n) -{ - int sreg; - sreg = reg * 2 + n; - return vfp_reg_offset(0, sreg); -} - -static TCGv_i32 neon_load_reg(int reg, int pass) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass)); - return tmp; -} - -static void neon_store_reg(int reg, int pass, TCGv_i32 var) -{ - tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass)); - tcg_temp_free_i32(var); -} - -static inline void neon_load_reg64(TCGv_i64 var, int reg) -{ - tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg)); -} - -static inline void neon_store_reg64(TCGv_i64 var, int reg) -{ - tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg)); -} - -#define tcg_gen_ld_f32 tcg_gen_ld_i32 -#define tcg_gen_ld_f64 tcg_gen_ld_i64 -#define tcg_gen_st_f32 tcg_gen_st_i32 -#define tcg_gen_st_f64 tcg_gen_st_i64 - -static inline void gen_mov_F0_vreg(int dp, int reg) -{ - if (dp) - tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg)); - else - tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg)); -} - -static inline void gen_mov_F1_vreg(int dp, int reg) -{ - if (dp) - tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg)); - else - tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg)); -} - -static inline void gen_mov_vreg_F0(int dp, int reg) -{ - if (dp) - tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg)); - else - tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg)); -} - -#define ARM_CP_RW_BIT (1 << 20) - -static inline void iwmmxt_load_reg(TCGv_i64 var, int reg) -{ - tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg])); -} - -static inline void iwmmxt_store_reg(TCGv_i64 var, int reg) -{ - tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg])); -} - -static inline TCGv_i32 iwmmxt_load_creg(int reg) -{ - TCGv_i32 var = tcg_temp_new_i32(); - tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg])); - return var; -} - -static inline void iwmmxt_store_creg(int reg, TCGv_i32 var) -{ - tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg])); - tcg_temp_free_i32(var); -} - -static inline void gen_op_iwmmxt_movq_wRn_M0(int rn) -{ - iwmmxt_store_reg(cpu_M0, rn); -} - -static inline void gen_op_iwmmxt_movq_M0_wRn(int rn) -{ - iwmmxt_load_reg(cpu_M0, rn); -} - -static inline void gen_op_iwmmxt_orq_M0_wRn(int rn) -{ - iwmmxt_load_reg(cpu_V1, rn); - tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1); -} - -static inline void gen_op_iwmmxt_andq_M0_wRn(int rn) -{ - iwmmxt_load_reg(cpu_V1, rn); - tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1); -} - -static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn) -{ - iwmmxt_load_reg(cpu_V1, rn); - tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1); -} - -#define IWMMXT_OP(name) \ -static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \ -{ \ - iwmmxt_load_reg(cpu_V1, rn); \ - gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \ -} - -#define IWMMXT_OP_ENV(name) \ -static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \ -{ \ - iwmmxt_load_reg(cpu_V1, rn); \ - gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \ -} - -#define IWMMXT_OP_ENV_SIZE(name) \ -IWMMXT_OP_ENV(name##b) \ -IWMMXT_OP_ENV(name##w) \ -IWMMXT_OP_ENV(name##l) - -#define IWMMXT_OP_ENV1(name) \ -static inline void gen_op_iwmmxt_##name##_M0(void) \ -{ \ - gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \ -} - -IWMMXT_OP(maddsq) -IWMMXT_OP(madduq) -IWMMXT_OP(sadb) -IWMMXT_OP(sadw) -IWMMXT_OP(mulslw) -IWMMXT_OP(mulshw) -IWMMXT_OP(mululw) -IWMMXT_OP(muluhw) -IWMMXT_OP(macsw) -IWMMXT_OP(macuw) - -IWMMXT_OP_ENV_SIZE(unpackl) -IWMMXT_OP_ENV_SIZE(unpackh) - -IWMMXT_OP_ENV1(unpacklub) -IWMMXT_OP_ENV1(unpackluw) -IWMMXT_OP_ENV1(unpacklul) -IWMMXT_OP_ENV1(unpackhub) -IWMMXT_OP_ENV1(unpackhuw) -IWMMXT_OP_ENV1(unpackhul) -IWMMXT_OP_ENV1(unpacklsb) -IWMMXT_OP_ENV1(unpacklsw) -IWMMXT_OP_ENV1(unpacklsl) -IWMMXT_OP_ENV1(unpackhsb) -IWMMXT_OP_ENV1(unpackhsw) -IWMMXT_OP_ENV1(unpackhsl) - -IWMMXT_OP_ENV_SIZE(cmpeq) -IWMMXT_OP_ENV_SIZE(cmpgtu) -IWMMXT_OP_ENV_SIZE(cmpgts) - -IWMMXT_OP_ENV_SIZE(mins) -IWMMXT_OP_ENV_SIZE(minu) -IWMMXT_OP_ENV_SIZE(maxs) -IWMMXT_OP_ENV_SIZE(maxu) - -IWMMXT_OP_ENV_SIZE(subn) -IWMMXT_OP_ENV_SIZE(addn) -IWMMXT_OP_ENV_SIZE(subu) -IWMMXT_OP_ENV_SIZE(addu) -IWMMXT_OP_ENV_SIZE(subs) -IWMMXT_OP_ENV_SIZE(adds) - -IWMMXT_OP_ENV(avgb0) -IWMMXT_OP_ENV(avgb1) -IWMMXT_OP_ENV(avgw0) -IWMMXT_OP_ENV(avgw1) - -IWMMXT_OP_ENV(packuw) -IWMMXT_OP_ENV(packul) -IWMMXT_OP_ENV(packuq) -IWMMXT_OP_ENV(packsw) -IWMMXT_OP_ENV(packsl) -IWMMXT_OP_ENV(packsq) - -static void gen_op_iwmmxt_set_mup(void) -{ - TCGv_i32 tmp; - tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]); - tcg_gen_ori_i32(tmp, tmp, 2); - store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]); -} - -static void gen_op_iwmmxt_set_cup(void) -{ - TCGv_i32 tmp; - tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]); - tcg_gen_ori_i32(tmp, tmp, 1); - store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]); -} - -static void gen_op_iwmmxt_setpsr_nz(void) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0); - store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]); -} - -static inline void gen_op_iwmmxt_addl_M0_wRn(int rn) -{ - iwmmxt_load_reg(cpu_V1, rn); - tcg_gen_ext32u_i64(cpu_V1, cpu_V1); - tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); -} - -static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, - TCGv_i32 dest) -{ - int rd; - uint32_t offset; - TCGv_i32 tmp; - - rd = (insn >> 16) & 0xf; - tmp = load_reg(s, rd); - - offset = (insn & 0xff) << ((insn >> 7) & 2); - if (insn & (1 << 24)) { - /* Pre indexed */ - if (insn & (1 << 23)) - tcg_gen_addi_i32(tmp, tmp, offset); - else - tcg_gen_addi_i32(tmp, tmp, -offset); - tcg_gen_mov_i32(dest, tmp); - if (insn & (1 << 21)) - store_reg(s, rd, tmp); - else - tcg_temp_free_i32(tmp); - } else if (insn & (1 << 21)) { - /* Post indexed */ - tcg_gen_mov_i32(dest, tmp); - if (insn & (1 << 23)) - tcg_gen_addi_i32(tmp, tmp, offset); - else - tcg_gen_addi_i32(tmp, tmp, -offset); - store_reg(s, rd, tmp); - } else if (!(insn & (1 << 23))) - return 1; - return 0; -} - -static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest) -{ - int rd = (insn >> 0) & 0xf; - TCGv_i32 tmp; - - if (insn & (1 << 8)) { - if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) { - return 1; - } else { - tmp = iwmmxt_load_creg(rd); - } - } else { - tmp = tcg_temp_new_i32(); - iwmmxt_load_reg(cpu_V0, rd); - tcg_gen_extrl_i64_i32(tmp, cpu_V0); - } - tcg_gen_andi_i32(tmp, tmp, mask); - tcg_gen_mov_i32(dest, tmp); - tcg_temp_free_i32(tmp); - return 0; -} - -/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred - (ie. an undefined instruction). */ -static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn) -{ - int rd, wrd; - int rdhi, rdlo, rd0, rd1, i; - TCGv_i32 addr; - TCGv_i32 tmp, tmp2, tmp3; - - if ((insn & 0x0e000e00) == 0x0c000000) { - if ((insn & 0x0fe00ff0) == 0x0c400000) { - wrd = insn & 0xf; - rdlo = (insn >> 12) & 0xf; - rdhi = (insn >> 16) & 0xf; - if (insn & ARM_CP_RW_BIT) { /* TMRRC */ - iwmmxt_load_reg(cpu_V0, wrd); - tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0); - tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); - tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0); - } else { /* TMCRR */ - tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); - iwmmxt_store_reg(cpu_V0, wrd); - gen_op_iwmmxt_set_mup(); - } - return 0; - } - - wrd = (insn >> 12) & 0xf; - addr = tcg_temp_new_i32(); - if (gen_iwmmxt_address(s, insn, addr)) { - tcg_temp_free_i32(addr); - return 1; - } - if (insn & ARM_CP_RW_BIT) { - if ((insn >> 28) == 0xf) { /* WLDRW wCx */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - iwmmxt_store_creg(wrd, tmp); - } else { - i = 1; - if (insn & (1 << 8)) { - if (insn & (1 << 22)) { /* WLDRD */ - gen_aa32_ld64(cpu_M0, addr, get_mem_index(s)); - i = 0; - } else { /* WLDRW wRd */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - } - } else { - tmp = tcg_temp_new_i32(); - if (insn & (1 << 22)) { /* WLDRH */ - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - } else { /* WLDRB */ - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - } - } - if (i) { - tcg_gen_extu_i32_i64(cpu_M0, tmp); - tcg_temp_free_i32(tmp); - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - } - } else { - if ((insn >> 28) == 0xf) { /* WSTRW wCx */ - tmp = iwmmxt_load_creg(wrd); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - } else { - gen_op_iwmmxt_movq_M0_wRn(wrd); - tmp = tcg_temp_new_i32(); - if (insn & (1 << 8)) { - if (insn & (1 << 22)) { /* WSTRD */ - gen_aa32_st64(cpu_M0, addr, get_mem_index(s)); - } else { /* WSTRW wRd */ - tcg_gen_extrl_i64_i32(tmp, cpu_M0); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - } - } else { - if (insn & (1 << 22)) { /* WSTRH */ - tcg_gen_extrl_i64_i32(tmp, cpu_M0); - gen_aa32_st16(tmp, addr, get_mem_index(s)); - } else { /* WSTRB */ - tcg_gen_extrl_i64_i32(tmp, cpu_M0); - gen_aa32_st8(tmp, addr, get_mem_index(s)); - } - } - } - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - return 0; - } - - if ((insn & 0x0f000000) != 0x0e000000) - return 1; - - switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) { - case 0x000: /* WOR */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 0) & 0xf; - rd1 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - gen_op_iwmmxt_orq_M0_wRn(rd1); - gen_op_iwmmxt_setpsr_nz(); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x011: /* TMCR */ - if (insn & 0xf) - return 1; - rd = (insn >> 12) & 0xf; - wrd = (insn >> 16) & 0xf; - switch (wrd) { - case ARM_IWMMXT_wCID: - case ARM_IWMMXT_wCASF: - break; - case ARM_IWMMXT_wCon: - gen_op_iwmmxt_set_cup(); - /* Fall through. */ - case ARM_IWMMXT_wCSSF: - tmp = iwmmxt_load_creg(wrd); - tmp2 = load_reg(s, rd); - tcg_gen_andc_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - iwmmxt_store_creg(wrd, tmp); - break; - case ARM_IWMMXT_wCGR0: - case ARM_IWMMXT_wCGR1: - case ARM_IWMMXT_wCGR2: - case ARM_IWMMXT_wCGR3: - gen_op_iwmmxt_set_cup(); - tmp = load_reg(s, rd); - iwmmxt_store_creg(wrd, tmp); - break; - default: - return 1; - } - break; - case 0x100: /* WXOR */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 0) & 0xf; - rd1 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - gen_op_iwmmxt_xorq_M0_wRn(rd1); - gen_op_iwmmxt_setpsr_nz(); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x111: /* TMRC */ - if (insn & 0xf) - return 1; - rd = (insn >> 12) & 0xf; - wrd = (insn >> 16) & 0xf; - tmp = iwmmxt_load_creg(wrd); - store_reg(s, rd, tmp); - break; - case 0x300: /* WANDN */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 0) & 0xf; - rd1 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tcg_gen_neg_i64(cpu_M0, cpu_M0); - gen_op_iwmmxt_andq_M0_wRn(rd1); - gen_op_iwmmxt_setpsr_nz(); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x200: /* WAND */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 0) & 0xf; - rd1 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - gen_op_iwmmxt_andq_M0_wRn(rd1); - gen_op_iwmmxt_setpsr_nz(); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x810: case 0xa10: /* WMADD */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 0) & 0xf; - rd1 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - if (insn & (1 << 21)) - gen_op_iwmmxt_maddsq_M0_wRn(rd1); - else - gen_op_iwmmxt_madduq_M0_wRn(rd1); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - gen_op_iwmmxt_unpacklb_M0_wRn(rd1); - break; - case 1: - gen_op_iwmmxt_unpacklw_M0_wRn(rd1); - break; - case 2: - gen_op_iwmmxt_unpackll_M0_wRn(rd1); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - gen_op_iwmmxt_unpackhb_M0_wRn(rd1); - break; - case 1: - gen_op_iwmmxt_unpackhw_M0_wRn(rd1); - break; - case 2: - gen_op_iwmmxt_unpackhl_M0_wRn(rd1); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - if (insn & (1 << 22)) - gen_op_iwmmxt_sadw_M0_wRn(rd1); - else - gen_op_iwmmxt_sadb_M0_wRn(rd1); - if (!(insn & (1 << 20))) - gen_op_iwmmxt_addl_M0_wRn(wrd); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - if (insn & (1 << 21)) { - if (insn & (1 << 20)) - gen_op_iwmmxt_mulshw_M0_wRn(rd1); - else - gen_op_iwmmxt_mulslw_M0_wRn(rd1); - } else { - if (insn & (1 << 20)) - gen_op_iwmmxt_muluhw_M0_wRn(rd1); - else - gen_op_iwmmxt_mululw_M0_wRn(rd1); - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - if (insn & (1 << 21)) - gen_op_iwmmxt_macsw_M0_wRn(rd1); - else - gen_op_iwmmxt_macuw_M0_wRn(rd1); - if (!(insn & (1 << 20))) { - iwmmxt_load_reg(cpu_V1, wrd); - tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - gen_op_iwmmxt_cmpeqb_M0_wRn(rd1); - break; - case 1: - gen_op_iwmmxt_cmpeqw_M0_wRn(rd1); - break; - case 2: - gen_op_iwmmxt_cmpeql_M0_wRn(rd1); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - if (insn & (1 << 22)) { - if (insn & (1 << 20)) - gen_op_iwmmxt_avgw1_M0_wRn(rd1); - else - gen_op_iwmmxt_avgw0_M0_wRn(rd1); - } else { - if (insn & (1 << 20)) - gen_op_iwmmxt_avgb1_M0_wRn(rd1); - else - gen_op_iwmmxt_avgb0_M0_wRn(rd1); - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3)); - tcg_gen_andi_i32(tmp, tmp, 7); - iwmmxt_load_reg(cpu_V1, rd1); - gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */ - if (((insn >> 6) & 3) == 3) - return 1; - rd = (insn >> 12) & 0xf; - wrd = (insn >> 16) & 0xf; - tmp = load_reg(s, rd); - gen_op_iwmmxt_movq_M0_wRn(wrd); - switch ((insn >> 6) & 3) { - case 0: - tmp2 = tcg_const_i32(0xff); - tmp3 = tcg_const_i32((insn & 7) << 3); - break; - case 1: - tmp2 = tcg_const_i32(0xffff); - tmp3 = tcg_const_i32((insn & 3) << 4); - break; - case 2: - tmp2 = tcg_const_i32(0xffffffff); - tmp3 = tcg_const_i32((insn & 1) << 5); - break; - default: - TCGV_UNUSED_I32(tmp2); - TCGV_UNUSED_I32(tmp3); - } - gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3); - tcg_temp_free_i32(tmp3); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */ - rd = (insn >> 12) & 0xf; - wrd = (insn >> 16) & 0xf; - if (rd == 15 || ((insn >> 22) & 3) == 3) - return 1; - gen_op_iwmmxt_movq_M0_wRn(wrd); - tmp = tcg_temp_new_i32(); - switch ((insn >> 22) & 3) { - case 0: - tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3); - tcg_gen_extrl_i64_i32(tmp, cpu_M0); - if (insn & 8) { - tcg_gen_ext8s_i32(tmp, tmp); - } else { - tcg_gen_andi_i32(tmp, tmp, 0xff); - } - break; - case 1: - tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4); - tcg_gen_extrl_i64_i32(tmp, cpu_M0); - if (insn & 8) { - tcg_gen_ext16s_i32(tmp, tmp); - } else { - tcg_gen_andi_i32(tmp, tmp, 0xffff); - } - break; - case 2: - tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5); - tcg_gen_extrl_i64_i32(tmp, cpu_M0); - break; - } - store_reg(s, rd, tmp); - break; - case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */ - if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3) - return 1; - tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); - switch ((insn >> 22) & 3) { - case 0: - tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0); - break; - case 1: - tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4); - break; - case 2: - tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12); - break; - } - tcg_gen_shli_i32(tmp, tmp, 28); - gen_set_nzcv(tmp); - tcg_temp_free_i32(tmp); - break; - case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */ - if (((insn >> 6) & 3) == 3) - return 1; - rd = (insn >> 12) & 0xf; - wrd = (insn >> 16) & 0xf; - tmp = load_reg(s, rd); - switch ((insn >> 6) & 3) { - case 0: - gen_helper_iwmmxt_bcstb(cpu_M0, tmp); - break; - case 1: - gen_helper_iwmmxt_bcstw(cpu_M0, tmp); - break; - case 2: - gen_helper_iwmmxt_bcstl(cpu_M0, tmp); - break; - } - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */ - if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) - return 1; - tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); - tmp2 = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp2, tmp); - switch ((insn >> 22) & 3) { - case 0: - for (i = 0; i < 7; i ++) { - tcg_gen_shli_i32(tmp2, tmp2, 4); - tcg_gen_and_i32(tmp, tmp, tmp2); - } - break; - case 1: - for (i = 0; i < 3; i ++) { - tcg_gen_shli_i32(tmp2, tmp2, 8); - tcg_gen_and_i32(tmp, tmp, tmp2); - } - break; - case 2: - tcg_gen_shli_i32(tmp2, tmp2, 16); - tcg_gen_and_i32(tmp, tmp, tmp2); - break; - } - gen_set_nzcv(tmp); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; - case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */ - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0); - break; - case 1: - gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0); - break; - case 2: - gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */ - if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) - return 1; - tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); - tmp2 = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp2, tmp); - switch ((insn >> 22) & 3) { - case 0: - for (i = 0; i < 7; i ++) { - tcg_gen_shli_i32(tmp2, tmp2, 4); - tcg_gen_or_i32(tmp, tmp, tmp2); - } - break; - case 1: - for (i = 0; i < 3; i ++) { - tcg_gen_shli_i32(tmp2, tmp2, 8); - tcg_gen_or_i32(tmp, tmp, tmp2); - } - break; - case 2: - tcg_gen_shli_i32(tmp2, tmp2, 16); - tcg_gen_or_i32(tmp, tmp, tmp2); - break; - } - gen_set_nzcv(tmp); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; - case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */ - rd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3) - return 1; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_temp_new_i32(); - switch ((insn >> 22) & 3) { - case 0: - gen_helper_iwmmxt_msbb(tmp, cpu_M0); - break; - case 1: - gen_helper_iwmmxt_msbw(tmp, cpu_M0); - break; - case 2: - gen_helper_iwmmxt_msbl(tmp, cpu_M0); - break; - } - store_reg(s, rd, tmp); - break; - case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */ - case 0x906: case 0xb06: case 0xd06: case 0xf06: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - if (insn & (1 << 21)) - gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1); - else - gen_op_iwmmxt_cmpgtub_M0_wRn(rd1); - break; - case 1: - if (insn & (1 << 21)) - gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1); - else - gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1); - break; - case 2: - if (insn & (1 << 21)) - gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1); - else - gen_op_iwmmxt_cmpgtul_M0_wRn(rd1); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */ - case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - if (insn & (1 << 21)) - gen_op_iwmmxt_unpacklsb_M0(); - else - gen_op_iwmmxt_unpacklub_M0(); - break; - case 1: - if (insn & (1 << 21)) - gen_op_iwmmxt_unpacklsw_M0(); - else - gen_op_iwmmxt_unpackluw_M0(); - break; - case 2: - if (insn & (1 << 21)) - gen_op_iwmmxt_unpacklsl_M0(); - else - gen_op_iwmmxt_unpacklul_M0(); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */ - case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - if (insn & (1 << 21)) - gen_op_iwmmxt_unpackhsb_M0(); - else - gen_op_iwmmxt_unpackhub_M0(); - break; - case 1: - if (insn & (1 << 21)) - gen_op_iwmmxt_unpackhsw_M0(); - else - gen_op_iwmmxt_unpackhuw_M0(); - break; - case 2: - if (insn & (1 << 21)) - gen_op_iwmmxt_unpackhsl_M0(); - else - gen_op_iwmmxt_unpackhul_M0(); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */ - case 0x214: case 0x614: case 0xa14: case 0xe14: - if (((insn >> 22) & 3) == 0) - return 1; - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_temp_new_i32(); - if (gen_iwmmxt_shift(insn, 0xff, tmp)) { - tcg_temp_free_i32(tmp); - return 1; - } - switch ((insn >> 22) & 3) { - case 1: - gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 2: - gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 3: - gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp); - break; - } - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */ - case 0x014: case 0x414: case 0x814: case 0xc14: - if (((insn >> 22) & 3) == 0) - return 1; - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_temp_new_i32(); - if (gen_iwmmxt_shift(insn, 0xff, tmp)) { - tcg_temp_free_i32(tmp); - return 1; - } - switch ((insn >> 22) & 3) { - case 1: - gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 2: - gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 3: - gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp); - break; - } - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */ - case 0x114: case 0x514: case 0x914: case 0xd14: - if (((insn >> 22) & 3) == 0) - return 1; - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_temp_new_i32(); - if (gen_iwmmxt_shift(insn, 0xff, tmp)) { - tcg_temp_free_i32(tmp); - return 1; - } - switch ((insn >> 22) & 3) { - case 1: - gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 2: - gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 3: - gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp); - break; - } - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */ - case 0x314: case 0x714: case 0xb14: case 0xf14: - if (((insn >> 22) & 3) == 0) - return 1; - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_temp_new_i32(); - switch ((insn >> 22) & 3) { - case 1: - if (gen_iwmmxt_shift(insn, 0xf, tmp)) { - tcg_temp_free_i32(tmp); - return 1; - } - gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 2: - if (gen_iwmmxt_shift(insn, 0x1f, tmp)) { - tcg_temp_free_i32(tmp); - return 1; - } - gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp); - break; - case 3: - if (gen_iwmmxt_shift(insn, 0x3f, tmp)) { - tcg_temp_free_i32(tmp); - return 1; - } - gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp); - break; - } - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */ - case 0x916: case 0xb16: case 0xd16: case 0xf16: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - if (insn & (1 << 21)) - gen_op_iwmmxt_minsb_M0_wRn(rd1); - else - gen_op_iwmmxt_minub_M0_wRn(rd1); - break; - case 1: - if (insn & (1 << 21)) - gen_op_iwmmxt_minsw_M0_wRn(rd1); - else - gen_op_iwmmxt_minuw_M0_wRn(rd1); - break; - case 2: - if (insn & (1 << 21)) - gen_op_iwmmxt_minsl_M0_wRn(rd1); - else - gen_op_iwmmxt_minul_M0_wRn(rd1); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */ - case 0x816: case 0xa16: case 0xc16: case 0xe16: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 0: - if (insn & (1 << 21)) - gen_op_iwmmxt_maxsb_M0_wRn(rd1); - else - gen_op_iwmmxt_maxub_M0_wRn(rd1); - break; - case 1: - if (insn & (1 << 21)) - gen_op_iwmmxt_maxsw_M0_wRn(rd1); - else - gen_op_iwmmxt_maxuw_M0_wRn(rd1); - break; - case 2: - if (insn & (1 << 21)) - gen_op_iwmmxt_maxsl_M0_wRn(rd1); - else - gen_op_iwmmxt_maxul_M0_wRn(rd1); - break; - case 3: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */ - case 0x402: case 0x502: case 0x602: case 0x702: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_const_i32((insn >> 20) & 3); - iwmmxt_load_reg(cpu_V1, rd1); - gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */ - case 0x41a: case 0x51a: case 0x61a: case 0x71a: - case 0x81a: case 0x91a: case 0xa1a: case 0xb1a: - case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 20) & 0xf) { - case 0x0: - gen_op_iwmmxt_subnb_M0_wRn(rd1); - break; - case 0x1: - gen_op_iwmmxt_subub_M0_wRn(rd1); - break; - case 0x3: - gen_op_iwmmxt_subsb_M0_wRn(rd1); - break; - case 0x4: - gen_op_iwmmxt_subnw_M0_wRn(rd1); - break; - case 0x5: - gen_op_iwmmxt_subuw_M0_wRn(rd1); - break; - case 0x7: - gen_op_iwmmxt_subsw_M0_wRn(rd1); - break; - case 0x8: - gen_op_iwmmxt_subnl_M0_wRn(rd1); - break; - case 0x9: - gen_op_iwmmxt_subul_M0_wRn(rd1); - break; - case 0xb: - gen_op_iwmmxt_subsl_M0_wRn(rd1); - break; - default: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */ - case 0x41e: case 0x51e: case 0x61e: case 0x71e: - case 0x81e: case 0x91e: case 0xa1e: case 0xb1e: - case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f)); - gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp); - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */ - case 0x418: case 0x518: case 0x618: case 0x718: - case 0x818: case 0x918: case 0xa18: case 0xb18: - case 0xc18: case 0xd18: case 0xe18: case 0xf18: - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 20) & 0xf) { - case 0x0: - gen_op_iwmmxt_addnb_M0_wRn(rd1); - break; - case 0x1: - gen_op_iwmmxt_addub_M0_wRn(rd1); - break; - case 0x3: - gen_op_iwmmxt_addsb_M0_wRn(rd1); - break; - case 0x4: - gen_op_iwmmxt_addnw_M0_wRn(rd1); - break; - case 0x5: - gen_op_iwmmxt_adduw_M0_wRn(rd1); - break; - case 0x7: - gen_op_iwmmxt_addsw_M0_wRn(rd1); - break; - case 0x8: - gen_op_iwmmxt_addnl_M0_wRn(rd1); - break; - case 0x9: - gen_op_iwmmxt_addul_M0_wRn(rd1); - break; - case 0xb: - gen_op_iwmmxt_addsl_M0_wRn(rd1); - break; - default: - return 1; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */ - case 0x408: case 0x508: case 0x608: case 0x708: - case 0x808: case 0x908: case 0xa08: case 0xb08: - case 0xc08: case 0xd08: case 0xe08: case 0xf08: - if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0) - return 1; - wrd = (insn >> 12) & 0xf; - rd0 = (insn >> 16) & 0xf; - rd1 = (insn >> 0) & 0xf; - gen_op_iwmmxt_movq_M0_wRn(rd0); - switch ((insn >> 22) & 3) { - case 1: - if (insn & (1 << 21)) - gen_op_iwmmxt_packsw_M0_wRn(rd1); - else - gen_op_iwmmxt_packuw_M0_wRn(rd1); - break; - case 2: - if (insn & (1 << 21)) - gen_op_iwmmxt_packsl_M0_wRn(rd1); - else - gen_op_iwmmxt_packul_M0_wRn(rd1); - break; - case 3: - if (insn & (1 << 21)) - gen_op_iwmmxt_packsq_M0_wRn(rd1); - else - gen_op_iwmmxt_packuq_M0_wRn(rd1); - break; - } - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - gen_op_iwmmxt_set_cup(); - break; - case 0x201: case 0x203: case 0x205: case 0x207: - case 0x209: case 0x20b: case 0x20d: case 0x20f: - case 0x211: case 0x213: case 0x215: case 0x217: - case 0x219: case 0x21b: case 0x21d: case 0x21f: - wrd = (insn >> 5) & 0xf; - rd0 = (insn >> 12) & 0xf; - rd1 = (insn >> 0) & 0xf; - if (rd0 == 0xf || rd1 == 0xf) - return 1; - gen_op_iwmmxt_movq_M0_wRn(wrd); - tmp = load_reg(s, rd0); - tmp2 = load_reg(s, rd1); - switch ((insn >> 16) & 0xf) { - case 0x0: /* TMIA */ - gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); - break; - case 0x8: /* TMIAPH */ - gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); - break; - case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */ - if (insn & (1 << 16)) - tcg_gen_shri_i32(tmp, tmp, 16); - if (insn & (1 << 17)) - tcg_gen_shri_i32(tmp2, tmp2, 16); - gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); - break; - default: - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - return 1; - } - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - gen_op_iwmmxt_movq_wRn_M0(wrd); - gen_op_iwmmxt_set_mup(); - break; - default: - return 1; - } - - return 0; -} - -/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred - (ie. an undefined instruction). */ -static int disas_dsp_insn(DisasContext *s, uint32_t insn) -{ - int acc, rd0, rd1, rdhi, rdlo; - TCGv_i32 tmp, tmp2; - - if ((insn & 0x0ff00f10) == 0x0e200010) { - /* Multiply with Internal Accumulate Format */ - rd0 = (insn >> 12) & 0xf; - rd1 = insn & 0xf; - acc = (insn >> 5) & 7; - - if (acc != 0) - return 1; - - tmp = load_reg(s, rd0); - tmp2 = load_reg(s, rd1); - switch ((insn >> 16) & 0xf) { - case 0x0: /* MIA */ - gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); - break; - case 0x8: /* MIAPH */ - gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); - break; - case 0xc: /* MIABB */ - case 0xd: /* MIABT */ - case 0xe: /* MIATB */ - case 0xf: /* MIATT */ - if (insn & (1 << 16)) - tcg_gen_shri_i32(tmp, tmp, 16); - if (insn & (1 << 17)) - tcg_gen_shri_i32(tmp2, tmp2, 16); - gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); - break; - default: - return 1; - } - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - - gen_op_iwmmxt_movq_wRn_M0(acc); - return 0; - } - - if ((insn & 0x0fe00ff8) == 0x0c400000) { - /* Internal Accumulator Access Format */ - rdhi = (insn >> 16) & 0xf; - rdlo = (insn >> 12) & 0xf; - acc = insn & 7; - - if (acc != 0) - return 1; - - if (insn & ARM_CP_RW_BIT) { /* MRA */ - iwmmxt_load_reg(cpu_V0, acc); - tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0); - tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); - tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0); - tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1); - } else { /* MAR */ - tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); - iwmmxt_store_reg(cpu_V0, acc); - } - return 0; - } - - return 1; -} - -#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n)) -#define VFP_SREG(insn, bigbit, smallbit) \ - ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1)) -#define VFP_DREG(reg, insn, bigbit, smallbit) do { \ - if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \ - reg = (((insn) >> (bigbit)) & 0x0f) \ - | (((insn) >> ((smallbit) - 4)) & 0x10); \ - } else { \ - if (insn & (1 << (smallbit))) \ - return 1; \ - reg = ((insn) >> (bigbit)) & 0x0f; \ - }} while (0) - -#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22) -#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22) -#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7) -#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7) -#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5) -#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5) - -/* Move between integer and VFP cores. */ -static TCGv_i32 gen_vfp_mrs(void) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp, cpu_F0s); - return tmp; -} - -static void gen_vfp_msr(TCGv_i32 tmp) -{ - tcg_gen_mov_i32(cpu_F0s, tmp); - tcg_temp_free_i32(tmp); -} - -static void gen_neon_dup_u8(TCGv_i32 var, int shift) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - if (shift) - tcg_gen_shri_i32(var, var, shift); - tcg_gen_ext8u_i32(var, var); - tcg_gen_shli_i32(tmp, var, 8); - tcg_gen_or_i32(var, var, tmp); - tcg_gen_shli_i32(tmp, var, 16); - tcg_gen_or_i32(var, var, tmp); - tcg_temp_free_i32(tmp); -} - -static void gen_neon_dup_low16(TCGv_i32 var) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_ext16u_i32(var, var); - tcg_gen_shli_i32(tmp, var, 16); - tcg_gen_or_i32(var, var, tmp); - tcg_temp_free_i32(tmp); -} - -static void gen_neon_dup_high16(TCGv_i32 var) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_andi_i32(var, var, 0xffff0000); - tcg_gen_shri_i32(tmp, var, 16); - tcg_gen_or_i32(var, var, tmp); - tcg_temp_free_i32(tmp); -} - -static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size) -{ - /* Load a single Neon element and replicate into a 32 bit TCG reg */ - TCGv_i32 tmp = tcg_temp_new_i32(); - switch (size) { - case 0: - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - gen_neon_dup_u8(tmp, 0); - break; - case 1: - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - gen_neon_dup_low16(tmp); - break; - case 2: - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - default: /* Avoid compiler warnings. */ - abort(); - } - return tmp; -} - -static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm, - uint32_t dp) -{ - uint32_t cc = extract32(insn, 20, 2); - - if (dp) { - TCGv_i64 frn, frm, dest; - TCGv_i64 tmp, zero, zf, nf, vf; - - zero = tcg_const_i64(0); - - frn = tcg_temp_new_i64(); - frm = tcg_temp_new_i64(); - dest = tcg_temp_new_i64(); - - zf = tcg_temp_new_i64(); - nf = tcg_temp_new_i64(); - vf = tcg_temp_new_i64(); - - tcg_gen_extu_i32_i64(zf, cpu_ZF); - tcg_gen_ext_i32_i64(nf, cpu_NF); - tcg_gen_ext_i32_i64(vf, cpu_VF); - - tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn)); - tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm)); - switch (cc) { - case 0: /* eq: Z */ - tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero, - frn, frm); - break; - case 1: /* vs: V */ - tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero, - frn, frm); - break; - case 2: /* ge: N == V -> N ^ V == 0 */ - tmp = tcg_temp_new_i64(); - tcg_gen_xor_i64(tmp, vf, nf); - tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero, - frn, frm); - tcg_temp_free_i64(tmp); - break; - case 3: /* gt: !Z && N == V */ - tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero, - frn, frm); - tmp = tcg_temp_new_i64(); - tcg_gen_xor_i64(tmp, vf, nf); - tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero, - dest, frm); - tcg_temp_free_i64(tmp); - break; - } - tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd)); - tcg_temp_free_i64(frn); - tcg_temp_free_i64(frm); - tcg_temp_free_i64(dest); - - tcg_temp_free_i64(zf); - tcg_temp_free_i64(nf); - tcg_temp_free_i64(vf); - - tcg_temp_free_i64(zero); - } else { - TCGv_i32 frn, frm, dest; - TCGv_i32 tmp, zero; - - zero = tcg_const_i32(0); - - frn = tcg_temp_new_i32(); - frm = tcg_temp_new_i32(); - dest = tcg_temp_new_i32(); - tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn)); - tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm)); - switch (cc) { - case 0: /* eq: Z */ - tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero, - frn, frm); - break; - case 1: /* vs: V */ - tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero, - frn, frm); - break; - case 2: /* ge: N == V -> N ^ V == 0 */ - tmp = tcg_temp_new_i32(); - tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); - tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero, - frn, frm); - tcg_temp_free_i32(tmp); - break; - case 3: /* gt: !Z && N == V */ - tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero, - frn, frm); - tmp = tcg_temp_new_i32(); - tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF); - tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero, - dest, frm); - tcg_temp_free_i32(tmp); - break; - } - tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd)); - tcg_temp_free_i32(frn); - tcg_temp_free_i32(frm); - tcg_temp_free_i32(dest); - - tcg_temp_free_i32(zero); - } - - return 0; -} - -static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn, - uint32_t rm, uint32_t dp) -{ - uint32_t vmin = extract32(insn, 6, 1); - TCGv_ptr fpst = get_fpstatus_ptr(0); - - if (dp) { - TCGv_i64 frn, frm, dest; - - frn = tcg_temp_new_i64(); - frm = tcg_temp_new_i64(); - dest = tcg_temp_new_i64(); - - tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn)); - tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm)); - if (vmin) { - gen_helper_vfp_minnumd(dest, frn, frm, fpst); - } else { - gen_helper_vfp_maxnumd(dest, frn, frm, fpst); - } - tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd)); - tcg_temp_free_i64(frn); - tcg_temp_free_i64(frm); - tcg_temp_free_i64(dest); - } else { - TCGv_i32 frn, frm, dest; - - frn = tcg_temp_new_i32(); - frm = tcg_temp_new_i32(); - dest = tcg_temp_new_i32(); - - tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn)); - tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm)); - if (vmin) { - gen_helper_vfp_minnums(dest, frn, frm, fpst); - } else { - gen_helper_vfp_maxnums(dest, frn, frm, fpst); - } - tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd)); - tcg_temp_free_i32(frn); - tcg_temp_free_i32(frm); - tcg_temp_free_i32(dest); - } - - tcg_temp_free_ptr(fpst); - return 0; -} - -static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, - int rounding) -{ - TCGv_ptr fpst = get_fpstatus_ptr(0); - TCGv_i32 tcg_rmode; - - tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding)); - gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); - - if (dp) { - TCGv_i64 tcg_op; - TCGv_i64 tcg_res; - tcg_op = tcg_temp_new_i64(); - tcg_res = tcg_temp_new_i64(); - tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm)); - gen_helper_rintd(tcg_res, tcg_op, fpst); - tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd)); - tcg_temp_free_i64(tcg_op); - tcg_temp_free_i64(tcg_res); - } else { - TCGv_i32 tcg_op; - TCGv_i32 tcg_res; - tcg_op = tcg_temp_new_i32(); - tcg_res = tcg_temp_new_i32(); - tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm)); - gen_helper_rints(tcg_res, tcg_op, fpst); - tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd)); - tcg_temp_free_i32(tcg_op); - tcg_temp_free_i32(tcg_res); - } - - gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); - tcg_temp_free_i32(tcg_rmode); - - tcg_temp_free_ptr(fpst); - return 0; -} - -static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, - int rounding) -{ - bool is_signed = extract32(insn, 7, 1); - TCGv_ptr fpst = get_fpstatus_ptr(0); - TCGv_i32 tcg_rmode, tcg_shift; - - tcg_shift = tcg_const_i32(0); - - tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding)); - gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); - - if (dp) { - TCGv_i64 tcg_double, tcg_res; - TCGv_i32 tcg_tmp; - /* Rd is encoded as a single precision register even when the source - * is double precision. - */ - rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1); - tcg_double = tcg_temp_new_i64(); - tcg_res = tcg_temp_new_i64(); - tcg_tmp = tcg_temp_new_i32(); - tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm)); - if (is_signed) { - gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst); - } else { - gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst); - } - tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res); - tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd)); - tcg_temp_free_i32(tcg_tmp); - tcg_temp_free_i64(tcg_res); - tcg_temp_free_i64(tcg_double); - } else { - TCGv_i32 tcg_single, tcg_res; - tcg_single = tcg_temp_new_i32(); - tcg_res = tcg_temp_new_i32(); - tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm)); - if (is_signed) { - gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst); - } else { - gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst); - } - tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd)); - tcg_temp_free_i32(tcg_res); - tcg_temp_free_i32(tcg_single); - } - - gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); - tcg_temp_free_i32(tcg_rmode); - - tcg_temp_free_i32(tcg_shift); - - tcg_temp_free_ptr(fpst); - - return 0; -} - -/* Table for converting the most common AArch32 encoding of - * rounding mode to arm_fprounding order (which matches the - * common AArch64 order); see ARM ARM pseudocode FPDecodeRM(). - */ -static const uint8_t fp_decode_rm[] = { - FPROUNDING_TIEAWAY, - FPROUNDING_TIEEVEN, - FPROUNDING_POSINF, - FPROUNDING_NEGINF, -}; - -static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn) -{ - uint32_t rd, rn, rm, dp = extract32(insn, 8, 1); - - if (!arm_dc_feature(s, ARM_FEATURE_V8)) { - return 1; - } - - if (dp) { - VFP_DREG_D(rd, insn); - VFP_DREG_N(rn, insn); - VFP_DREG_M(rm, insn); - } else { - rd = VFP_SREG_D(insn); - rn = VFP_SREG_N(insn); - rm = VFP_SREG_M(insn); - } - - if ((insn & 0x0f800e50) == 0x0e000a00) { - return handle_vsel(insn, rd, rn, rm, dp); - } else if ((insn & 0x0fb00e10) == 0x0e800a00) { - return handle_vminmaxnm(insn, rd, rn, rm, dp); - } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) { - /* VRINTA, VRINTN, VRINTP, VRINTM */ - int rounding = fp_decode_rm[extract32(insn, 16, 2)]; - return handle_vrint(insn, rd, rm, dp, rounding); - } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) { - /* VCVTA, VCVTN, VCVTP, VCVTM */ - int rounding = fp_decode_rm[extract32(insn, 16, 2)]; - return handle_vcvt(insn, rd, rm, dp, rounding); - } - return 1; -} - -/* Disassemble a VFP instruction. Returns nonzero if an error occurred - (ie. an undefined instruction). */ -static int disas_vfp_insn(DisasContext *s, uint32_t insn) -{ - uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; - int dp, veclen; - TCGv_i32 addr; - TCGv_i32 tmp; - TCGv_i32 tmp2; - - if (!arm_dc_feature(s, ARM_FEATURE_VFP)) { - return 1; - } - - /* FIXME: this access check should not take precedence over UNDEF - * for invalid encodings; we will generate incorrect syndrome information - * for attempts to execute invalid vfp/neon encodings with FP disabled. - */ - if (s->fp_excp_el) { - gen_exception_insn(s, 4, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el); - return 0; - } - - if (!s->vfp_enabled) { - /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ - if ((insn & 0x0fe00fff) != 0x0ee00a10) - return 1; - rn = (insn >> 16) & 0xf; - if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2 - && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) { - return 1; - } - } - - if (extract32(insn, 28, 4) == 0xf) { - /* Encodings with T=1 (Thumb) or unconditional (ARM): - * only used in v8 and above. - */ - return disas_vfp_v8_insn(s, insn); - } - - dp = ((insn & 0xf00) == 0xb00); - switch ((insn >> 24) & 0xf) { - case 0xe: - if (insn & (1 << 4)) { - /* single register transfer */ - rd = (insn >> 12) & 0xf; - if (dp) { - int size; - int pass; - - VFP_DREG_N(rn, insn); - if (insn & 0xf) - return 1; - if (insn & 0x00c00060 - && !arm_dc_feature(s, ARM_FEATURE_NEON)) { - return 1; - } - - pass = (insn >> 21) & 1; - if (insn & (1 << 22)) { - size = 0; - offset = ((insn >> 5) & 3) * 8; - } else if (insn & (1 << 5)) { - size = 1; - offset = (insn & (1 << 6)) ? 16 : 0; - } else { - size = 2; - offset = 0; - } - if (insn & ARM_CP_RW_BIT) { - /* vfp->arm */ - tmp = neon_load_reg(rn, pass); - switch (size) { - case 0: - if (offset) - tcg_gen_shri_i32(tmp, tmp, offset); - if (insn & (1 << 23)) - gen_uxtb(tmp); - else - gen_sxtb(tmp); - break; - case 1: - if (insn & (1 << 23)) { - if (offset) { - tcg_gen_shri_i32(tmp, tmp, 16); - } else { - gen_uxth(tmp); - } - } else { - if (offset) { - tcg_gen_sari_i32(tmp, tmp, 16); - } else { - gen_sxth(tmp); - } - } - break; - case 2: - break; - } - store_reg(s, rd, tmp); - } else { - /* arm->vfp */ - tmp = load_reg(s, rd); - if (insn & (1 << 23)) { - /* VDUP */ - if (size == 0) { - gen_neon_dup_u8(tmp, 0); - } else if (size == 1) { - gen_neon_dup_low16(tmp); - } - for (n = 0; n <= pass * 2; n++) { - tmp2 = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp2, tmp); - neon_store_reg(rn, n, tmp2); - } - neon_store_reg(rn, n, tmp); - } else { - /* VMOV */ - switch (size) { - case 0: - tmp2 = neon_load_reg(rn, pass); - tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8); - tcg_temp_free_i32(tmp2); - break; - case 1: - tmp2 = neon_load_reg(rn, pass); - tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16); - tcg_temp_free_i32(tmp2); - break; - case 2: - break; - } - neon_store_reg(rn, pass, tmp); - } - } - } else { /* !dp */ - if ((insn & 0x6f) != 0x00) - return 1; - rn = VFP_SREG_N(insn); - if (insn & ARM_CP_RW_BIT) { - /* vfp->arm */ - if (insn & (1 << 21)) { - /* system register */ - rn >>= 1; - - switch (rn) { - case ARM_VFP_FPSID: - /* VFP2 allows access to FSID from userspace. - VFP3 restricts all id registers to privileged - accesses. */ - if (IS_USER(s) - && arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - tmp = load_cpu_field(vfp.xregs[rn]); - break; - case ARM_VFP_FPEXC: - if (IS_USER(s)) - return 1; - tmp = load_cpu_field(vfp.xregs[rn]); - break; - case ARM_VFP_FPINST: - case ARM_VFP_FPINST2: - /* Not present in VFP3. */ - if (IS_USER(s) - || arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - tmp = load_cpu_field(vfp.xregs[rn]); - break; - case ARM_VFP_FPSCR: - if (rd == 15) { - tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); - tcg_gen_andi_i32(tmp, tmp, 0xf0000000); - } else { - tmp = tcg_temp_new_i32(); - gen_helper_vfp_get_fpscr(tmp, cpu_env); - } - break; - case ARM_VFP_MVFR2: - if (!arm_dc_feature(s, ARM_FEATURE_V8)) { - return 1; - } - /* fall through */ - case ARM_VFP_MVFR0: - case ARM_VFP_MVFR1: - if (IS_USER(s) - || !arm_dc_feature(s, ARM_FEATURE_MVFR)) { - return 1; - } - tmp = load_cpu_field(vfp.xregs[rn]); - break; - default: - return 1; - } - } else { - gen_mov_F0_vreg(0, rn); - tmp = gen_vfp_mrs(); - } - if (rd == 15) { - /* Set the 4 flag bits in the CPSR. */ - gen_set_nzcv(tmp); - tcg_temp_free_i32(tmp); - } else { - store_reg(s, rd, tmp); - } - } else { - /* arm->vfp */ - if (insn & (1 << 21)) { - rn >>= 1; - /* system register */ - switch (rn) { - case ARM_VFP_FPSID: - case ARM_VFP_MVFR0: - case ARM_VFP_MVFR1: - /* Writes are ignored. */ - break; - case ARM_VFP_FPSCR: - tmp = load_reg(s, rd); - gen_helper_vfp_set_fpscr(cpu_env, tmp); - tcg_temp_free_i32(tmp); - gen_lookup_tb(s); - break; - case ARM_VFP_FPEXC: - if (IS_USER(s)) - return 1; - /* TODO: VFP subarchitecture support. - * For now, keep the EN bit only */ - tmp = load_reg(s, rd); - tcg_gen_andi_i32(tmp, tmp, 1 << 30); - store_cpu_field(tmp, vfp.xregs[rn]); - gen_lookup_tb(s); - break; - case ARM_VFP_FPINST: - case ARM_VFP_FPINST2: - if (IS_USER(s)) { - return 1; - } - tmp = load_reg(s, rd); - store_cpu_field(tmp, vfp.xregs[rn]); - break; - default: - return 1; - } - } else { - tmp = load_reg(s, rd); - gen_vfp_msr(tmp); - gen_mov_vreg_F0(0, rn); - } - } - } - } else { - /* data processing */ - /* The opcode is in bits 23, 21, 20 and 6. */ - op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1); - if (dp) { - if (op == 15) { - /* rn is opcode */ - rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1); - } else { - /* rn is register number */ - VFP_DREG_N(rn, insn); - } - - if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) || - ((rn & 0x1e) == 0x6))) { - /* Integer or single/half precision destination. */ - rd = VFP_SREG_D(insn); - } else { - VFP_DREG_D(rd, insn); - } - if (op == 15 && - (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) || - ((rn & 0x1e) == 0x4))) { - /* VCVT from int or half precision is always from S reg - * regardless of dp bit. VCVT with immediate frac_bits - * has same format as SREG_M. - */ - rm = VFP_SREG_M(insn); - } else { - VFP_DREG_M(rm, insn); - } - } else { - rn = VFP_SREG_N(insn); - if (op == 15 && rn == 15) { - /* Double precision destination. */ - VFP_DREG_D(rd, insn); - } else { - rd = VFP_SREG_D(insn); - } - /* NB that we implicitly rely on the encoding for the frac_bits - * in VCVT of fixed to float being the same as that of an SREG_M - */ - rm = VFP_SREG_M(insn); - } - - veclen = s->vec_len; - if (op == 15 && rn > 3) - veclen = 0; - - /* Shut up compiler warnings. */ - delta_m = 0; - delta_d = 0; - bank_mask = 0; - - if (veclen > 0) { - if (dp) - bank_mask = 0xc; - else - bank_mask = 0x18; - - /* Figure out what type of vector operation this is. */ - if ((rd & bank_mask) == 0) { - /* scalar */ - veclen = 0; - } else { - if (dp) - delta_d = (s->vec_stride >> 1) + 1; - else - delta_d = s->vec_stride + 1; - - if ((rm & bank_mask) == 0) { - /* mixed scalar/vector */ - delta_m = 0; - } else { - /* vector */ - delta_m = delta_d; - } - } - } - - /* Load the initial operands. */ - if (op == 15) { - switch (rn) { - case 16: - case 17: - /* Integer source */ - gen_mov_F0_vreg(0, rm); - break; - case 8: - case 9: - /* Compare */ - gen_mov_F0_vreg(dp, rd); - gen_mov_F1_vreg(dp, rm); - break; - case 10: - case 11: - /* Compare with zero */ - gen_mov_F0_vreg(dp, rd); - gen_vfp_F1_ld0(dp); - break; - case 20: - case 21: - case 22: - case 23: - case 28: - case 29: - case 30: - case 31: - /* Source and destination the same. */ - gen_mov_F0_vreg(dp, rd); - break; - case 4: - case 5: - case 6: - case 7: - /* VCVTB, VCVTT: only present with the halfprec extension - * UNPREDICTABLE if bit 8 is set prior to ARMv8 - * (we choose to UNDEF) - */ - if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) || - !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) { - return 1; - } - if (!extract32(rn, 1, 1)) { - /* Half precision source. */ - gen_mov_F0_vreg(0, rm); - break; - } - /* Otherwise fall through */ - default: - /* One source operand. */ - gen_mov_F0_vreg(dp, rm); - break; - } - } else { - /* Two source operands. */ - gen_mov_F0_vreg(dp, rn); - gen_mov_F1_vreg(dp, rm); - } - - for (;;) { - /* Perform the calculation. */ - switch (op) { - case 0: /* VMLA: fd + (fn * fm) */ - /* Note that order of inputs to the add matters for NaNs */ - gen_vfp_F1_mul(dp); - gen_mov_F0_vreg(dp, rd); - gen_vfp_add(dp); - break; - case 1: /* VMLS: fd + -(fn * fm) */ - gen_vfp_mul(dp); - gen_vfp_F1_neg(dp); - gen_mov_F0_vreg(dp, rd); - gen_vfp_add(dp); - break; - case 2: /* VNMLS: -fd + (fn * fm) */ - /* Note that it isn't valid to replace (-A + B) with (B - A) - * or similar plausible looking simplifications - * because this will give wrong results for NaNs. - */ - gen_vfp_F1_mul(dp); - gen_mov_F0_vreg(dp, rd); - gen_vfp_neg(dp); - gen_vfp_add(dp); - break; - case 3: /* VNMLA: -fd + -(fn * fm) */ - gen_vfp_mul(dp); - gen_vfp_F1_neg(dp); - gen_mov_F0_vreg(dp, rd); - gen_vfp_neg(dp); - gen_vfp_add(dp); - break; - case 4: /* mul: fn * fm */ - gen_vfp_mul(dp); - break; - case 5: /* nmul: -(fn * fm) */ - gen_vfp_mul(dp); - gen_vfp_neg(dp); - break; - case 6: /* add: fn + fm */ - gen_vfp_add(dp); - break; - case 7: /* sub: fn - fm */ - gen_vfp_sub(dp); - break; - case 8: /* div: fn / fm */ - gen_vfp_div(dp); - break; - case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */ - case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */ - case 12: /* VFMA : fd = muladd( fd, fn, fm) */ - case 13: /* VFMS : fd = muladd( fd, -fn, fm) */ - /* These are fused multiply-add, and must be done as one - * floating point operation with no rounding between the - * multiplication and addition steps. - * NB that doing the negations here as separate steps is - * correct : an input NaN should come out with its sign bit - * flipped if it is a negated-input. - */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) { - return 1; - } - if (dp) { - TCGv_ptr fpst; - TCGv_i64 frd; - if (op & 1) { - /* VFNMS, VFMS */ - gen_helper_vfp_negd(cpu_F0d, cpu_F0d); - } - frd = tcg_temp_new_i64(); - tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd)); - if (op & 2) { - /* VFNMA, VFNMS */ - gen_helper_vfp_negd(frd, frd); - } - fpst = get_fpstatus_ptr(0); - gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d, - cpu_F1d, frd, fpst); - tcg_temp_free_ptr(fpst); - tcg_temp_free_i64(frd); - } else { - TCGv_ptr fpst; - TCGv_i32 frd; - if (op & 1) { - /* VFNMS, VFMS */ - gen_helper_vfp_negs(cpu_F0s, cpu_F0s); - } - frd = tcg_temp_new_i32(); - tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd)); - if (op & 2) { - gen_helper_vfp_negs(frd, frd); - } - fpst = get_fpstatus_ptr(0); - gen_helper_vfp_muladds(cpu_F0s, cpu_F0s, - cpu_F1s, frd, fpst); - tcg_temp_free_ptr(fpst); - tcg_temp_free_i32(frd); - } - break; - case 14: /* fconst */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - - n = (insn << 12) & 0x80000000; - i = ((insn >> 12) & 0x70) | (insn & 0xf); - if (dp) { - if (i & 0x40) - i |= 0x3f80; - else - i |= 0x4000; - n |= i << 16; - tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32); - } else { - if (i & 0x40) - i |= 0x780; - else - i |= 0x800; - n |= i << 19; - tcg_gen_movi_i32(cpu_F0s, n); - } - break; - case 15: /* extension space */ - switch (rn) { - case 0: /* cpy */ - /* no-op */ - break; - case 1: /* abs */ - gen_vfp_abs(dp); - break; - case 2: /* neg */ - gen_vfp_neg(dp); - break; - case 3: /* sqrt */ - gen_vfp_sqrt(dp); - break; - case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */ - tmp = gen_vfp_mrs(); - tcg_gen_ext16u_i32(tmp, tmp); - if (dp) { - gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp, - cpu_env); - } else { - gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, - cpu_env); - } - tcg_temp_free_i32(tmp); - break; - case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */ - tmp = gen_vfp_mrs(); - tcg_gen_shri_i32(tmp, tmp, 16); - if (dp) { - gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp, - cpu_env); - } else { - gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, - cpu_env); - } - tcg_temp_free_i32(tmp); - break; - case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */ - tmp = tcg_temp_new_i32(); - if (dp) { - gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d, - cpu_env); - } else { - gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, - cpu_env); - } - gen_mov_F0_vreg(0, rd); - tmp2 = gen_vfp_mrs(); - tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - gen_vfp_msr(tmp); - break; - case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */ - tmp = tcg_temp_new_i32(); - if (dp) { - gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d, - cpu_env); - } else { - gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, - cpu_env); - } - tcg_gen_shli_i32(tmp, tmp, 16); - gen_mov_F0_vreg(0, rd); - tmp2 = gen_vfp_mrs(); - tcg_gen_ext16u_i32(tmp2, tmp2); - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - gen_vfp_msr(tmp); - break; - case 8: /* cmp */ - gen_vfp_cmp(dp); - break; - case 9: /* cmpe */ - gen_vfp_cmpe(dp); - break; - case 10: /* cmpz */ - gen_vfp_cmp(dp); - break; - case 11: /* cmpez */ - gen_vfp_F1_ld0(dp); - gen_vfp_cmpe(dp); - break; - case 12: /* vrintr */ - { - TCGv_ptr fpst = get_fpstatus_ptr(0); - if (dp) { - gen_helper_rintd(cpu_F0d, cpu_F0d, fpst); - } else { - gen_helper_rints(cpu_F0s, cpu_F0s, fpst); - } - tcg_temp_free_ptr(fpst); - break; - } - case 13: /* vrintz */ - { - TCGv_ptr fpst = get_fpstatus_ptr(0); - TCGv_i32 tcg_rmode; - tcg_rmode = tcg_const_i32(float_round_to_zero); - gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); - if (dp) { - gen_helper_rintd(cpu_F0d, cpu_F0d, fpst); - } else { - gen_helper_rints(cpu_F0s, cpu_F0s, fpst); - } - gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); - tcg_temp_free_i32(tcg_rmode); - tcg_temp_free_ptr(fpst); - break; - } - case 14: /* vrintx */ - { - TCGv_ptr fpst = get_fpstatus_ptr(0); - if (dp) { - gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst); - } else { - gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst); - } - tcg_temp_free_ptr(fpst); - break; - } - case 15: /* single<->double conversion */ - if (dp) - gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); - else - gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); - break; - case 16: /* fuito */ - gen_vfp_uito(dp, 0); - break; - case 17: /* fsito */ - gen_vfp_sito(dp, 0); - break; - case 20: /* fshto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_shto(dp, 16 - rm, 0); - break; - case 21: /* fslto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_slto(dp, 32 - rm, 0); - break; - case 22: /* fuhto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_uhto(dp, 16 - rm, 0); - break; - case 23: /* fulto */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_ulto(dp, 32 - rm, 0); - break; - case 24: /* ftoui */ - gen_vfp_toui(dp, 0); - break; - case 25: /* ftouiz */ - gen_vfp_touiz(dp, 0); - break; - case 26: /* ftosi */ - gen_vfp_tosi(dp, 0); - break; - case 27: /* ftosiz */ - gen_vfp_tosiz(dp, 0); - break; - case 28: /* ftosh */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_tosh(dp, 16 - rm, 0); - break; - case 29: /* ftosl */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_tosl(dp, 32 - rm, 0); - break; - case 30: /* ftouh */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_touh(dp, 16 - rm, 0); - break; - case 31: /* ftoul */ - if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) { - return 1; - } - gen_vfp_toul(dp, 32 - rm, 0); - break; - default: /* undefined */ - return 1; - } - break; - default: /* undefined */ - return 1; - } - - /* Write back the result. */ - if (op == 15 && (rn >= 8 && rn <= 11)) { - /* Comparison, do nothing. */ - } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 || - (rn & 0x1e) == 0x6)) { - /* VCVT double to int: always integer result. - * VCVT double to half precision is always a single - * precision result. - */ - gen_mov_vreg_F0(0, rd); - } else if (op == 15 && rn == 15) { - /* conversion */ - gen_mov_vreg_F0(!dp, rd); - } else { - gen_mov_vreg_F0(dp, rd); - } - - /* break out of the loop if we have finished */ - if (veclen == 0) - break; - - if (op == 15 && delta_m == 0) { - /* single source one-many */ - while (veclen--) { - rd = ((rd + delta_d) & (bank_mask - 1)) - | (rd & bank_mask); - gen_mov_vreg_F0(dp, rd); - } - break; - } - /* Setup the next operands. */ - veclen--; - rd = ((rd + delta_d) & (bank_mask - 1)) - | (rd & bank_mask); - - if (op == 15) { - /* One source operand. */ - rm = ((rm + delta_m) & (bank_mask - 1)) - | (rm & bank_mask); - gen_mov_F0_vreg(dp, rm); - } else { - /* Two source operands. */ - rn = ((rn + delta_d) & (bank_mask - 1)) - | (rn & bank_mask); - gen_mov_F0_vreg(dp, rn); - if (delta_m) { - rm = ((rm + delta_m) & (bank_mask - 1)) - | (rm & bank_mask); - gen_mov_F1_vreg(dp, rm); - } - } - } - } - break; - case 0xc: - case 0xd: - if ((insn & 0x03e00000) == 0x00400000) { - /* two-register transfer */ - rn = (insn >> 16) & 0xf; - rd = (insn >> 12) & 0xf; - if (dp) { - VFP_DREG_M(rm, insn); - } else { - rm = VFP_SREG_M(insn); - } - - if (insn & ARM_CP_RW_BIT) { - /* vfp->arm */ - if (dp) { - gen_mov_F0_vreg(0, rm * 2); - tmp = gen_vfp_mrs(); - store_reg(s, rd, tmp); - gen_mov_F0_vreg(0, rm * 2 + 1); - tmp = gen_vfp_mrs(); - store_reg(s, rn, tmp); - } else { - gen_mov_F0_vreg(0, rm); - tmp = gen_vfp_mrs(); - store_reg(s, rd, tmp); - gen_mov_F0_vreg(0, rm + 1); - tmp = gen_vfp_mrs(); - store_reg(s, rn, tmp); - } - } else { - /* arm->vfp */ - if (dp) { - tmp = load_reg(s, rd); - gen_vfp_msr(tmp); - gen_mov_vreg_F0(0, rm * 2); - tmp = load_reg(s, rn); - gen_vfp_msr(tmp); - gen_mov_vreg_F0(0, rm * 2 + 1); - } else { - tmp = load_reg(s, rd); - gen_vfp_msr(tmp); - gen_mov_vreg_F0(0, rm); - tmp = load_reg(s, rn); - gen_vfp_msr(tmp); - gen_mov_vreg_F0(0, rm + 1); - } - } - } else { - /* Load/store */ - rn = (insn >> 16) & 0xf; - if (dp) - VFP_DREG_D(rd, insn); - else - rd = VFP_SREG_D(insn); - if ((insn & 0x01200000) == 0x01000000) { - /* Single load/store */ - offset = (insn & 0xff) << 2; - if ((insn & (1 << 23)) == 0) - offset = -offset; - if (s->thumb && rn == 15) { - /* This is actually UNPREDICTABLE */ - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, rn); - } - tcg_gen_addi_i32(addr, addr, offset); - if (insn & (1 << 20)) { - gen_vfp_ld(s, dp, addr); - gen_mov_vreg_F0(dp, rd); - } else { - gen_mov_F0_vreg(dp, rd); - gen_vfp_st(s, dp, addr); - } - tcg_temp_free_i32(addr); - } else { - /* load/store multiple */ - int w = insn & (1 << 21); - if (dp) - n = (insn >> 1) & 0x7f; - else - n = insn & 0xff; - - if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) { - /* P == U , W == 1 => UNDEF */ - return 1; - } - if (n == 0 || (rd + n) > 32 || (dp && n > 16)) { - /* UNPREDICTABLE cases for bad immediates: we choose to - * UNDEF to avoid generating huge numbers of TCG ops - */ - return 1; - } - if (rn == 15 && w) { - /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */ - return 1; - } - - if (s->thumb && rn == 15) { - /* This is actually UNPREDICTABLE */ - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, rn); - } - if (insn & (1 << 24)) /* pre-decrement */ - tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); - - if (dp) - offset = 8; - else - offset = 4; - for (i = 0; i < n; i++) { - if (insn & ARM_CP_RW_BIT) { - /* load */ - gen_vfp_ld(s, dp, addr); - gen_mov_vreg_F0(dp, rd + i); - } else { - /* store */ - gen_mov_F0_vreg(dp, rd + i); - gen_vfp_st(s, dp, addr); - } - tcg_gen_addi_i32(addr, addr, offset); - } - if (w) { - /* writeback */ - if (insn & (1 << 24)) - offset = -offset * n; - else if (dp && (insn & 1)) - offset = 4; - else - offset = 0; - - if (offset != 0) - tcg_gen_addi_i32(addr, addr, offset); - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - } - } - break; - default: - /* Should never happen. */ - return 1; - } - return 0; -} - -static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) -{ - TranslationBlock *tb; - - tb = s->tb; - if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { - tcg_gen_goto_tb(n); - gen_set_pc_im(s, dest); - tcg_gen_exit_tb((uintptr_t)tb + n); - } else { - gen_set_pc_im(s, dest); - tcg_gen_exit_tb(0); - } -} - -static inline void gen_jmp (DisasContext *s, uint32_t dest) -{ - if (unlikely(s->singlestep_enabled || s->ss_active)) { - /* An indirect jump so that we still trigger the debug exception. */ - if (s->thumb) - dest |= 1; - gen_bx_im(s, dest); - } else { - gen_goto_tb(s, 0, dest); - s->is_jmp = DISAS_TB_JUMP; - } -} - -static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y) -{ - if (x) - tcg_gen_sari_i32(t0, t0, 16); - else - gen_sxth(t0); - if (y) - tcg_gen_sari_i32(t1, t1, 16); - else - gen_sxth(t1); - tcg_gen_mul_i32(t0, t0, t1); -} - -/* Return the mask of PSR bits set by a MSR instruction. */ -static uint32_t msr_mask(DisasContext *s, int flags, int spsr) -{ - uint32_t mask; - - mask = 0; - if (flags & (1 << 0)) - mask |= 0xff; - if (flags & (1 << 1)) - mask |= 0xff00; - if (flags & (1 << 2)) - mask |= 0xff0000; - if (flags & (1 << 3)) - mask |= 0xff000000; - - /* Mask out undefined bits. */ - mask &= ~CPSR_RESERVED; - if (!arm_dc_feature(s, ARM_FEATURE_V4T)) { - mask &= ~CPSR_T; - } - if (!arm_dc_feature(s, ARM_FEATURE_V5)) { - mask &= ~CPSR_Q; /* V5TE in reality*/ - } - if (!arm_dc_feature(s, ARM_FEATURE_V6)) { - mask &= ~(CPSR_E | CPSR_GE); - } - if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) { - mask &= ~CPSR_IT; - } - /* Mask out execution state and reserved bits. */ - if (!spsr) { - mask &= ~(CPSR_EXEC | CPSR_RESERVED); - } - /* Mask out privileged bits. */ - if (IS_USER(s)) - mask &= CPSR_USER; - return mask; -} - -/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */ -static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0) -{ - TCGv_i32 tmp; - if (spsr) { - /* ??? This is also undefined in system mode. */ - if (IS_USER(s)) - return 1; - - tmp = load_cpu_field(spsr); - tcg_gen_andi_i32(tmp, tmp, ~mask); - tcg_gen_andi_i32(t0, t0, mask); - tcg_gen_or_i32(tmp, tmp, t0); - store_cpu_field(tmp, spsr); - } else { - gen_set_cpsr(t0, mask); - } - tcg_temp_free_i32(t0); - gen_lookup_tb(s); - return 0; -} - -/* Returns nonzero if access to the PSR is not permitted. */ -static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val) -{ - TCGv_i32 tmp; - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - return gen_set_psr(s, mask, spsr, tmp); -} - -/* Generate an old-style exception return. Marks pc as dead. */ -static void gen_exception_return(DisasContext *s, TCGv_i32 pc) -{ - TCGv_i32 tmp; - store_reg(s, 15, pc); - tmp = load_cpu_field(spsr); - gen_set_cpsr(tmp, CPSR_ERET_MASK); - tcg_temp_free_i32(tmp); - s->is_jmp = DISAS_JUMP; -} - -/* Generate a v6 exception return. Marks both values as dead. */ -static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr) -{ - gen_set_cpsr(cpsr, CPSR_ERET_MASK); - tcg_temp_free_i32(cpsr); - store_reg(s, 15, pc); - s->is_jmp = DISAS_JUMP; -} - -static void gen_nop_hint(DisasContext *s, int val) -{ - switch (val) { - case 1: /* yield */ - gen_set_pc_im(s, s->pc); - s->is_jmp = DISAS_YIELD; - break; - case 3: /* wfi */ - gen_set_pc_im(s, s->pc); - s->is_jmp = DISAS_WFI; - break; - case 2: /* wfe */ - gen_set_pc_im(s, s->pc); - s->is_jmp = DISAS_WFE; - break; - case 4: /* sev */ - case 5: /* sevl */ - /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */ - default: /* nop */ - break; - } -} - -#define CPU_V001 cpu_V0, cpu_V0, cpu_V1 - -static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1) -{ - switch (size) { - case 0: gen_helper_neon_add_u8(t0, t0, t1); break; - case 1: gen_helper_neon_add_u16(t0, t0, t1); break; - case 2: tcg_gen_add_i32(t0, t0, t1); break; - default: abort(); - } -} - -static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1) -{ - switch (size) { - case 0: gen_helper_neon_sub_u8(t0, t1, t0); break; - case 1: gen_helper_neon_sub_u16(t0, t1, t0); break; - case 2: tcg_gen_sub_i32(t0, t1, t0); break; - default: return; - } -} - -/* 32-bit pairwise ops end up the same as the elementwise versions. */ -#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32 -#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32 -#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32 -#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32 - -#define GEN_NEON_INTEGER_OP_ENV(name) do { \ - switch ((size << 1) | u) { \ - case 0: \ - gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \ - break; \ - case 1: \ - gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \ - break; \ - case 2: \ - gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \ - break; \ - case 3: \ - gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \ - break; \ - case 4: \ - gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \ - break; \ - case 5: \ - gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \ - break; \ - default: return 1; \ - }} while (0) - -#define GEN_NEON_INTEGER_OP(name) do { \ - switch ((size << 1) | u) { \ - case 0: \ - gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \ - break; \ - case 1: \ - gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \ - break; \ - case 2: \ - gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \ - break; \ - case 3: \ - gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \ - break; \ - case 4: \ - gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \ - break; \ - case 5: \ - gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \ - break; \ - default: return 1; \ - }} while (0) - -static TCGv_i32 neon_load_scratch(int scratch) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); - return tmp; -} - -static void neon_store_scratch(int scratch, TCGv_i32 var) -{ - tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); - tcg_temp_free_i32(var); -} - -static inline TCGv_i32 neon_get_scalar(int size, int reg) -{ - TCGv_i32 tmp; - if (size == 1) { - tmp = neon_load_reg(reg & 7, reg >> 4); - if (reg & 8) { - gen_neon_dup_high16(tmp); - } else { - gen_neon_dup_low16(tmp); - } - } else { - tmp = neon_load_reg(reg & 15, reg >> 4); - } - return tmp; -} - -static int gen_neon_unzip(int rd, int rm, int size, int q) -{ - TCGv_i32 tmp, tmp2; - if (!q && size == 2) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rm); - if (q) { - switch (size) { - case 0: - gen_helper_neon_qunzip8(cpu_env, tmp, tmp2); - break; - case 1: - gen_helper_neon_qunzip16(cpu_env, tmp, tmp2); - break; - case 2: - gen_helper_neon_qunzip32(cpu_env, tmp, tmp2); - break; - default: - abort(); - } - } else { - switch (size) { - case 0: - gen_helper_neon_unzip8(cpu_env, tmp, tmp2); - break; - case 1: - gen_helper_neon_unzip16(cpu_env, tmp, tmp2); - break; - default: - abort(); - } - } - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - return 0; -} - -static int gen_neon_zip(int rd, int rm, int size, int q) -{ - TCGv_i32 tmp, tmp2; - if (!q && size == 2) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rm); - if (q) { - switch (size) { - case 0: - gen_helper_neon_qzip8(cpu_env, tmp, tmp2); - break; - case 1: - gen_helper_neon_qzip16(cpu_env, tmp, tmp2); - break; - case 2: - gen_helper_neon_qzip32(cpu_env, tmp, tmp2); - break; - default: - abort(); - } - } else { - switch (size) { - case 0: - gen_helper_neon_zip8(cpu_env, tmp, tmp2); - break; - case 1: - gen_helper_neon_zip16(cpu_env, tmp, tmp2); - break; - default: - abort(); - } - } - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - return 0; -} - -static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 rd, tmp; - - rd = tcg_temp_new_i32(); - tmp = tcg_temp_new_i32(); - - tcg_gen_shli_i32(rd, t0, 8); - tcg_gen_andi_i32(rd, rd, 0xff00ff00); - tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); - tcg_gen_or_i32(rd, rd, tmp); - - tcg_gen_shri_i32(t1, t1, 8); - tcg_gen_andi_i32(t1, t1, 0x00ff00ff); - tcg_gen_andi_i32(tmp, t0, 0xff00ff00); - tcg_gen_or_i32(t1, t1, tmp); - tcg_gen_mov_i32(t0, rd); - - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(rd); -} - -static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1) -{ - TCGv_i32 rd, tmp; - - rd = tcg_temp_new_i32(); - tmp = tcg_temp_new_i32(); - - tcg_gen_shli_i32(rd, t0, 16); - tcg_gen_andi_i32(tmp, t1, 0xffff); - tcg_gen_or_i32(rd, rd, tmp); - tcg_gen_shri_i32(t1, t1, 16); - tcg_gen_andi_i32(tmp, t0, 0xffff0000); - tcg_gen_or_i32(t1, t1, tmp); - tcg_gen_mov_i32(t0, rd); - - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(rd); -} - - -static struct { - int nregs; - int interleave; - int spacing; -} neon_ls_element_type[11] = { - {4, 4, 1}, - {4, 4, 2}, - {4, 1, 1}, - {4, 2, 1}, - {3, 3, 1}, - {3, 3, 2}, - {3, 1, 1}, - {1, 1, 1}, - {2, 2, 1}, - {2, 2, 2}, - {2, 1, 1} -}; - -/* Translate a NEON load/store element instruction. Return nonzero if the - instruction is invalid. */ -static int disas_neon_ls_insn(DisasContext *s, uint32_t insn) -{ - int rd, rn, rm; - int op; - int nregs; - int interleave; - int spacing; - int stride; - int size; - int reg; - int pass; - int load; - int shift; - int n; - TCGv_i32 addr; - TCGv_i32 tmp; - TCGv_i32 tmp2; - TCGv_i64 tmp64; - - /* FIXME: this access check should not take precedence over UNDEF - * for invalid encodings; we will generate incorrect syndrome information - * for attempts to execute invalid vfp/neon encodings with FP disabled. - */ - if (s->fp_excp_el) { - gen_exception_insn(s, 4, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el); - return 0; - } - - if (!s->vfp_enabled) - return 1; - VFP_DREG_D(rd, insn); - rn = (insn >> 16) & 0xf; - rm = insn & 0xf; - load = (insn & (1 << 21)) != 0; - if ((insn & (1 << 23)) == 0) { - /* Load store all elements. */ - op = (insn >> 8) & 0xf; - size = (insn >> 6) & 3; - if (op > 10) - return 1; - /* Catch UNDEF cases for bad values of align field */ - switch (op & 0xc) { - case 4: - if (((insn >> 5) & 1) == 1) { - return 1; - } - break; - case 8: - if (((insn >> 4) & 3) == 3) { - return 1; - } - break; - default: - break; - } - nregs = neon_ls_element_type[op].nregs; - interleave = neon_ls_element_type[op].interleave; - spacing = neon_ls_element_type[op].spacing; - if (size == 3 && (interleave | spacing) != 1) - return 1; - addr = tcg_temp_new_i32(); - load_reg_var(s, addr, rn); - stride = (1 << size) * interleave; - for (reg = 0; reg < nregs; reg++) { - if (interleave > 2 || (interleave == 2 && nregs == 2)) { - load_reg_var(s, addr, rn); - tcg_gen_addi_i32(addr, addr, (1 << size) * reg); - } else if (interleave == 2 && nregs == 4 && reg == 2) { - load_reg_var(s, addr, rn); - tcg_gen_addi_i32(addr, addr, 1 << size); - } - if (size == 3) { - tmp64 = tcg_temp_new_i64(); - if (load) { - gen_aa32_ld64(tmp64, addr, get_mem_index(s)); - neon_store_reg64(tmp64, rd); - } else { - neon_load_reg64(tmp64, rd); - gen_aa32_st64(tmp64, addr, get_mem_index(s)); - } - tcg_temp_free_i64(tmp64); - tcg_gen_addi_i32(addr, addr, stride); - } else { - for (pass = 0; pass < 2; pass++) { - if (size == 2) { - if (load) { - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - neon_store_reg(rd, pass, tmp); - } else { - tmp = neon_load_reg(rd, pass); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_gen_addi_i32(addr, addr, stride); - } else if (size == 1) { - if (load) { - tmp = tcg_temp_new_i32(); - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - tcg_gen_addi_i32(addr, addr, stride); - tmp2 = tcg_temp_new_i32(); - gen_aa32_ld16u(tmp2, addr, get_mem_index(s)); - tcg_gen_addi_i32(addr, addr, stride); - tcg_gen_shli_i32(tmp2, tmp2, 16); - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - neon_store_reg(rd, pass, tmp); - } else { - tmp = neon_load_reg(rd, pass); - tmp2 = tcg_temp_new_i32(); - tcg_gen_shri_i32(tmp2, tmp, 16); - gen_aa32_st16(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - tcg_gen_addi_i32(addr, addr, stride); - gen_aa32_st16(tmp2, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp2); - tcg_gen_addi_i32(addr, addr, stride); - } - } else /* size == 0 */ { - if (load) { - TCGV_UNUSED_I32(tmp2); - for (n = 0; n < 4; n++) { - tmp = tcg_temp_new_i32(); - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - tcg_gen_addi_i32(addr, addr, stride); - if (n == 0) { - tmp2 = tmp; - } else { - tcg_gen_shli_i32(tmp, tmp, n * 8); - tcg_gen_or_i32(tmp2, tmp2, tmp); - tcg_temp_free_i32(tmp); - } - } - neon_store_reg(rd, pass, tmp2); - } else { - tmp2 = neon_load_reg(rd, pass); - for (n = 0; n < 4; n++) { - tmp = tcg_temp_new_i32(); - if (n == 0) { - tcg_gen_mov_i32(tmp, tmp2); - } else { - tcg_gen_shri_i32(tmp, tmp2, n * 8); - } - gen_aa32_st8(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - tcg_gen_addi_i32(addr, addr, stride); - } - tcg_temp_free_i32(tmp2); - } - } - } - } - rd += spacing; - } - tcg_temp_free_i32(addr); - stride = nregs * 8; - } else { - size = (insn >> 10) & 3; - if (size == 3) { - /* Load single element to all lanes. */ - int a = (insn >> 4) & 1; - if (!load) { - return 1; - } - size = (insn >> 6) & 3; - nregs = ((insn >> 8) & 3) + 1; - - if (size == 3) { - if (nregs != 4 || a == 0) { - return 1; - } - /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */ - size = 2; - } - if (nregs == 1 && a == 1 && size == 0) { - return 1; - } - if (nregs == 3 && a == 1) { - return 1; - } - addr = tcg_temp_new_i32(); - load_reg_var(s, addr, rn); - if (nregs == 1) { - /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */ - tmp = gen_load_and_replicate(s, addr, size); - tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); - tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); - if (insn & (1 << 5)) { - tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0)); - tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1)); - } - tcg_temp_free_i32(tmp); - } else { - /* VLD2/3/4 to all lanes: bit 5 indicates register stride */ - stride = (insn & (1 << 5)) ? 2 : 1; - for (reg = 0; reg < nregs; reg++) { - tmp = gen_load_and_replicate(s, addr, size); - tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); - tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); - tcg_temp_free_i32(tmp); - tcg_gen_addi_i32(addr, addr, 1 << size); - rd += stride; - } - } - tcg_temp_free_i32(addr); - stride = (1 << size) * nregs; - } else { - /* Single element. */ - int idx = (insn >> 4) & 0xf; - pass = (insn >> 7) & 1; - switch (size) { - case 0: - shift = ((insn >> 5) & 3) * 8; - stride = 1; - break; - case 1: - shift = ((insn >> 6) & 1) * 16; - stride = (insn & (1 << 5)) ? 2 : 1; - break; - case 2: - shift = 0; - stride = (insn & (1 << 6)) ? 2 : 1; - break; - default: - abort(); - } - nregs = ((insn >> 8) & 3) + 1; - /* Catch the UNDEF cases. This is unavoidably a bit messy. */ - switch (nregs) { - case 1: - if (((idx & (1 << size)) != 0) || - (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) { - return 1; - } - break; - case 3: - if ((idx & 1) != 0) { - return 1; - } - /* fall through */ - case 2: - if (size == 2 && (idx & 2) != 0) { - return 1; - } - break; - case 4: - if ((size == 2) && ((idx & 3) == 3)) { - return 1; - } - break; - default: - abort(); - } - if ((rd + stride * (nregs - 1)) > 31) { - /* Attempts to write off the end of the register file - * are UNPREDICTABLE; we choose to UNDEF because otherwise - * the neon_load_reg() would write off the end of the array. - */ - return 1; - } - addr = tcg_temp_new_i32(); - load_reg_var(s, addr, rn); - for (reg = 0; reg < nregs; reg++) { - if (load) { - tmp = tcg_temp_new_i32(); - switch (size) { - case 0: - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - break; - case 1: - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - case 2: - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - default: /* Avoid compiler warnings. */ - abort(); - } - if (size != 2) { - tmp2 = neon_load_reg(rd, pass); - tcg_gen_deposit_i32(tmp, tmp2, tmp, - shift, size ? 16 : 8); - tcg_temp_free_i32(tmp2); - } - neon_store_reg(rd, pass, tmp); - } else { /* Store */ - tmp = neon_load_reg(rd, pass); - if (shift) - tcg_gen_shri_i32(tmp, tmp, shift); - switch (size) { - case 0: - gen_aa32_st8(tmp, addr, get_mem_index(s)); - break; - case 1: - gen_aa32_st16(tmp, addr, get_mem_index(s)); - break; - case 2: - gen_aa32_st32(tmp, addr, get_mem_index(s)); - break; - } - tcg_temp_free_i32(tmp); - } - rd += stride; - tcg_gen_addi_i32(addr, addr, 1 << size); - } - tcg_temp_free_i32(addr); - stride = nregs * (1 << size); - } - } - if (rm != 15) { - TCGv_i32 base; - - base = load_reg(s, rn); - if (rm == 13) { - tcg_gen_addi_i32(base, base, stride); - } else { - TCGv_i32 index; - index = load_reg(s, rm); - tcg_gen_add_i32(base, base, index); - tcg_temp_free_i32(index); - } - store_reg(s, rn, base); - } - return 0; -} - -/* Bitwise select. dest = c ? t : f. Clobbers T and F. */ -static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c) -{ - tcg_gen_and_i32(t, t, c); - tcg_gen_andc_i32(f, f, c); - tcg_gen_or_i32(dest, t, f); -} - -static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src) -{ - switch (size) { - case 0: gen_helper_neon_narrow_u8(dest, src); break; - case 1: gen_helper_neon_narrow_u16(dest, src); break; - case 2: tcg_gen_extrl_i64_i32(dest, src); break; - default: abort(); - } -} - -static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src) -{ - switch (size) { - case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break; - case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break; - case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break; - default: abort(); - } -} - -static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src) -{ - switch (size) { - case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break; - case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break; - case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break; - default: abort(); - } -} - -static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src) -{ - switch (size) { - case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break; - case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break; - case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break; - default: abort(); - } -} - -static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift, - int q, int u) -{ - if (q) { - if (u) { - switch (size) { - case 1: gen_helper_neon_rshl_u16(var, var, shift); break; - case 2: gen_helper_neon_rshl_u32(var, var, shift); break; - default: abort(); - } - } else { - switch (size) { - case 1: gen_helper_neon_rshl_s16(var, var, shift); break; - case 2: gen_helper_neon_rshl_s32(var, var, shift); break; - default: abort(); - } - } - } else { - if (u) { - switch (size) { - case 1: gen_helper_neon_shl_u16(var, var, shift); break; - case 2: gen_helper_neon_shl_u32(var, var, shift); break; - default: abort(); - } - } else { - switch (size) { - case 1: gen_helper_neon_shl_s16(var, var, shift); break; - case 2: gen_helper_neon_shl_s32(var, var, shift); break; - default: abort(); - } - } - } -} - -static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u) -{ - if (u) { - switch (size) { - case 0: gen_helper_neon_widen_u8(dest, src); break; - case 1: gen_helper_neon_widen_u16(dest, src); break; - case 2: tcg_gen_extu_i32_i64(dest, src); break; - default: abort(); - } - } else { - switch (size) { - case 0: gen_helper_neon_widen_s8(dest, src); break; - case 1: gen_helper_neon_widen_s16(dest, src); break; - case 2: tcg_gen_ext_i32_i64(dest, src); break; - default: abort(); - } - } - tcg_temp_free_i32(src); -} - -static inline void gen_neon_addl(int size) -{ - switch (size) { - case 0: gen_helper_neon_addl_u16(CPU_V001); break; - case 1: gen_helper_neon_addl_u32(CPU_V001); break; - case 2: tcg_gen_add_i64(CPU_V001); break; - default: abort(); - } -} - -static inline void gen_neon_subl(int size) -{ - switch (size) { - case 0: gen_helper_neon_subl_u16(CPU_V001); break; - case 1: gen_helper_neon_subl_u32(CPU_V001); break; - case 2: tcg_gen_sub_i64(CPU_V001); break; - default: abort(); - } -} - -static inline void gen_neon_negl(TCGv_i64 var, int size) -{ - switch (size) { - case 0: gen_helper_neon_negl_u16(var, var); break; - case 1: gen_helper_neon_negl_u32(var, var); break; - case 2: - tcg_gen_neg_i64(var, var); - break; - default: abort(); - } -} - -static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size) -{ - switch (size) { - case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break; - case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break; - default: abort(); - } -} - -static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b, - int size, int u) -{ - TCGv_i64 tmp; - - switch ((size << 1) | u) { - case 0: gen_helper_neon_mull_s8(dest, a, b); break; - case 1: gen_helper_neon_mull_u8(dest, a, b); break; - case 2: gen_helper_neon_mull_s16(dest, a, b); break; - case 3: gen_helper_neon_mull_u16(dest, a, b); break; - case 4: - tmp = gen_muls_i64_i32(a, b); - tcg_gen_mov_i64(dest, tmp); - tcg_temp_free_i64(tmp); - break; - case 5: - tmp = gen_mulu_i64_i32(a, b); - tcg_gen_mov_i64(dest, tmp); - tcg_temp_free_i64(tmp); - break; - default: abort(); - } - - /* gen_helper_neon_mull_[su]{8|16} do not free their parameters. - Don't forget to clean them now. */ - if (size < 2) { - tcg_temp_free_i32(a); - tcg_temp_free_i32(b); - } -} - -static void gen_neon_narrow_op(int op, int u, int size, - TCGv_i32 dest, TCGv_i64 src) -{ - if (op) { - if (u) { - gen_neon_unarrow_sats(size, dest, src); - } else { - gen_neon_narrow(size, dest, src); - } - } else { - if (u) { - gen_neon_narrow_satu(size, dest, src); - } else { - gen_neon_narrow_sats(size, dest, src); - } - } -} - -/* Symbolic constants for op fields for Neon 3-register same-length. - * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B - * table A7-9. - */ -#define NEON_3R_VHADD 0 -#define NEON_3R_VQADD 1 -#define NEON_3R_VRHADD 2 -#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */ -#define NEON_3R_VHSUB 4 -#define NEON_3R_VQSUB 5 -#define NEON_3R_VCGT 6 -#define NEON_3R_VCGE 7 -#define NEON_3R_VSHL 8 -#define NEON_3R_VQSHL 9 -#define NEON_3R_VRSHL 10 -#define NEON_3R_VQRSHL 11 -#define NEON_3R_VMAX 12 -#define NEON_3R_VMIN 13 -#define NEON_3R_VABD 14 -#define NEON_3R_VABA 15 -#define NEON_3R_VADD_VSUB 16 -#define NEON_3R_VTST_VCEQ 17 -#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */ -#define NEON_3R_VMUL 19 -#define NEON_3R_VPMAX 20 -#define NEON_3R_VPMIN 21 -#define NEON_3R_VQDMULH_VQRDMULH 22 -#define NEON_3R_VPADD 23 -#define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */ -#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */ -#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */ -#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */ -#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */ -#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */ -#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */ -#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */ - -static const uint8_t neon_3r_sizes[] = { - [NEON_3R_VHADD] = 0x7, - [NEON_3R_VQADD] = 0xf, - [NEON_3R_VRHADD] = 0x7, - [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */ - [NEON_3R_VHSUB] = 0x7, - [NEON_3R_VQSUB] = 0xf, - [NEON_3R_VCGT] = 0x7, - [NEON_3R_VCGE] = 0x7, - [NEON_3R_VSHL] = 0xf, - [NEON_3R_VQSHL] = 0xf, - [NEON_3R_VRSHL] = 0xf, - [NEON_3R_VQRSHL] = 0xf, - [NEON_3R_VMAX] = 0x7, - [NEON_3R_VMIN] = 0x7, - [NEON_3R_VABD] = 0x7, - [NEON_3R_VABA] = 0x7, - [NEON_3R_VADD_VSUB] = 0xf, - [NEON_3R_VTST_VCEQ] = 0x7, - [NEON_3R_VML] = 0x7, - [NEON_3R_VMUL] = 0x7, - [NEON_3R_VPMAX] = 0x7, - [NEON_3R_VPMIN] = 0x7, - [NEON_3R_VQDMULH_VQRDMULH] = 0x6, - [NEON_3R_VPADD] = 0x7, - [NEON_3R_SHA] = 0xf, /* size field encodes op type */ - [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */ - [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */ - [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */ - [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */ - [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */ - [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */ - [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */ -}; - -/* Symbolic constants for op fields for Neon 2-register miscellaneous. - * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B - * table A7-13. - */ -#define NEON_2RM_VREV64 0 -#define NEON_2RM_VREV32 1 -#define NEON_2RM_VREV16 2 -#define NEON_2RM_VPADDL 4 -#define NEON_2RM_VPADDL_U 5 -#define NEON_2RM_AESE 6 /* Includes AESD */ -#define NEON_2RM_AESMC 7 /* Includes AESIMC */ -#define NEON_2RM_VCLS 8 -#define NEON_2RM_VCLZ 9 -#define NEON_2RM_VCNT 10 -#define NEON_2RM_VMVN 11 -#define NEON_2RM_VPADAL 12 -#define NEON_2RM_VPADAL_U 13 -#define NEON_2RM_VQABS 14 -#define NEON_2RM_VQNEG 15 -#define NEON_2RM_VCGT0 16 -#define NEON_2RM_VCGE0 17 -#define NEON_2RM_VCEQ0 18 -#define NEON_2RM_VCLE0 19 -#define NEON_2RM_VCLT0 20 -#define NEON_2RM_SHA1H 21 -#define NEON_2RM_VABS 22 -#define NEON_2RM_VNEG 23 -#define NEON_2RM_VCGT0_F 24 -#define NEON_2RM_VCGE0_F 25 -#define NEON_2RM_VCEQ0_F 26 -#define NEON_2RM_VCLE0_F 27 -#define NEON_2RM_VCLT0_F 28 -#define NEON_2RM_VABS_F 30 -#define NEON_2RM_VNEG_F 31 -#define NEON_2RM_VSWP 32 -#define NEON_2RM_VTRN 33 -#define NEON_2RM_VUZP 34 -#define NEON_2RM_VZIP 35 -#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ -#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ -#define NEON_2RM_VSHLL 38 -#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */ -#define NEON_2RM_VRINTN 40 -#define NEON_2RM_VRINTX 41 -#define NEON_2RM_VRINTA 42 -#define NEON_2RM_VRINTZ 43 -#define NEON_2RM_VCVT_F16_F32 44 -#define NEON_2RM_VRINTM 45 -#define NEON_2RM_VCVT_F32_F16 46 -#define NEON_2RM_VRINTP 47 -#define NEON_2RM_VCVTAU 48 -#define NEON_2RM_VCVTAS 49 -#define NEON_2RM_VCVTNU 50 -#define NEON_2RM_VCVTNS 51 -#define NEON_2RM_VCVTPU 52 -#define NEON_2RM_VCVTPS 53 -#define NEON_2RM_VCVTMU 54 -#define NEON_2RM_VCVTMS 55 -#define NEON_2RM_VRECPE 56 -#define NEON_2RM_VRSQRTE 57 -#define NEON_2RM_VRECPE_F 58 -#define NEON_2RM_VRSQRTE_F 59 -#define NEON_2RM_VCVT_FS 60 -#define NEON_2RM_VCVT_FU 61 -#define NEON_2RM_VCVT_SF 62 -#define NEON_2RM_VCVT_UF 63 - -static int neon_2rm_is_float_op(int op) -{ - /* Return true if this neon 2reg-misc op is float-to-float */ - return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || - (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) || - op == NEON_2RM_VRINTM || - (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) || - op >= NEON_2RM_VRECPE_F); -} - -/* Each entry in this array has bit n set if the insn allows - * size value n (otherwise it will UNDEF). Since unallocated - * op values will have no bits set they always UNDEF. - */ -static const uint8_t neon_2rm_sizes[] = { - [NEON_2RM_VREV64] = 0x7, - [NEON_2RM_VREV32] = 0x3, - [NEON_2RM_VREV16] = 0x1, - [NEON_2RM_VPADDL] = 0x7, - [NEON_2RM_VPADDL_U] = 0x7, - [NEON_2RM_AESE] = 0x1, - [NEON_2RM_AESMC] = 0x1, - [NEON_2RM_VCLS] = 0x7, - [NEON_2RM_VCLZ] = 0x7, - [NEON_2RM_VCNT] = 0x1, - [NEON_2RM_VMVN] = 0x1, - [NEON_2RM_VPADAL] = 0x7, - [NEON_2RM_VPADAL_U] = 0x7, - [NEON_2RM_VQABS] = 0x7, - [NEON_2RM_VQNEG] = 0x7, - [NEON_2RM_VCGT0] = 0x7, - [NEON_2RM_VCGE0] = 0x7, - [NEON_2RM_VCEQ0] = 0x7, - [NEON_2RM_VCLE0] = 0x7, - [NEON_2RM_VCLT0] = 0x7, - [NEON_2RM_SHA1H] = 0x4, - [NEON_2RM_VABS] = 0x7, - [NEON_2RM_VNEG] = 0x7, - [NEON_2RM_VCGT0_F] = 0x4, - [NEON_2RM_VCGE0_F] = 0x4, - [NEON_2RM_VCEQ0_F] = 0x4, - [NEON_2RM_VCLE0_F] = 0x4, - [NEON_2RM_VCLT0_F] = 0x4, - [NEON_2RM_VABS_F] = 0x4, - [NEON_2RM_VNEG_F] = 0x4, - [NEON_2RM_VSWP] = 0x1, - [NEON_2RM_VTRN] = 0x7, - [NEON_2RM_VUZP] = 0x7, - [NEON_2RM_VZIP] = 0x7, - [NEON_2RM_VMOVN] = 0x7, - [NEON_2RM_VQMOVN] = 0x7, - [NEON_2RM_VSHLL] = 0x7, - [NEON_2RM_SHA1SU1] = 0x4, - [NEON_2RM_VRINTN] = 0x4, - [NEON_2RM_VRINTX] = 0x4, - [NEON_2RM_VRINTA] = 0x4, - [NEON_2RM_VRINTZ] = 0x4, - [NEON_2RM_VCVT_F16_F32] = 0x2, - [NEON_2RM_VRINTM] = 0x4, - [NEON_2RM_VCVT_F32_F16] = 0x2, - [NEON_2RM_VRINTP] = 0x4, - [NEON_2RM_VCVTAU] = 0x4, - [NEON_2RM_VCVTAS] = 0x4, - [NEON_2RM_VCVTNU] = 0x4, - [NEON_2RM_VCVTNS] = 0x4, - [NEON_2RM_VCVTPU] = 0x4, - [NEON_2RM_VCVTPS] = 0x4, - [NEON_2RM_VCVTMU] = 0x4, - [NEON_2RM_VCVTMS] = 0x4, - [NEON_2RM_VRECPE] = 0x4, - [NEON_2RM_VRSQRTE] = 0x4, - [NEON_2RM_VRECPE_F] = 0x4, - [NEON_2RM_VRSQRTE_F] = 0x4, - [NEON_2RM_VCVT_FS] = 0x4, - [NEON_2RM_VCVT_FU] = 0x4, - [NEON_2RM_VCVT_SF] = 0x4, - [NEON_2RM_VCVT_UF] = 0x4, -}; - -/* Translate a NEON data processing instruction. Return nonzero if the - instruction is invalid. - We process data in a mixture of 32-bit and 64-bit chunks. - Mostly we use 32-bit chunks so we can use normal scalar instructions. */ - -static int disas_neon_data_insn(DisasContext *s, uint32_t insn) -{ - int op; - int q; - int rd, rn, rm; - int size; - int shift; - int pass; - int count; - int pairwise; - int u; - uint32_t imm, mask; - TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5; - TCGv_i64 tmp64; - - /* FIXME: this access check should not take precedence over UNDEF - * for invalid encodings; we will generate incorrect syndrome information - * for attempts to execute invalid vfp/neon encodings with FP disabled. - */ - if (s->fp_excp_el) { - gen_exception_insn(s, 4, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el); - return 0; - } - - if (!s->vfp_enabled) - return 1; - q = (insn & (1 << 6)) != 0; - u = (insn >> 24) & 1; - VFP_DREG_D(rd, insn); - VFP_DREG_N(rn, insn); - VFP_DREG_M(rm, insn); - size = (insn >> 20) & 3; - if ((insn & (1 << 23)) == 0) { - /* Three register same length. */ - op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1); - /* Catch invalid op and bad size combinations: UNDEF */ - if ((neon_3r_sizes[op] & (1 << size)) == 0) { - return 1; - } - /* All insns of this form UNDEF for either this condition or the - * superset of cases "Q==1"; we catch the latter later. - */ - if (q && ((rd | rn | rm) & 1)) { - return 1; - } - /* - * The SHA-1/SHA-256 3-register instructions require special treatment - * here, as their size field is overloaded as an op type selector, and - * they all consume their input in a single pass. - */ - if (op == NEON_3R_SHA) { - if (!q) { - return 1; - } - if (!u) { /* SHA-1 */ - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rn); - tmp3 = tcg_const_i32(rm); - tmp4 = tcg_const_i32(size); - gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4); - tcg_temp_free_i32(tmp4); - } else { /* SHA-256 */ - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rn); - tmp3 = tcg_const_i32(rm); - switch (size) { - case 0: - gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3); - break; - case 1: - gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3); - break; - case 2: - gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3); - break; - } - } - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp3); - return 0; - } - if (size == 3 && op != NEON_3R_LOGIC) { - /* 64-bit element instructions. */ - for (pass = 0; pass < (q ? 2 : 1); pass++) { - neon_load_reg64(cpu_V0, rn + pass); - neon_load_reg64(cpu_V1, rm + pass); - switch (op) { - case NEON_3R_VQADD: - if (u) { - gen_helper_neon_qadd_u64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } else { - gen_helper_neon_qadd_s64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } - break; - case NEON_3R_VQSUB: - if (u) { - gen_helper_neon_qsub_u64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } else { - gen_helper_neon_qsub_s64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } - break; - case NEON_3R_VSHL: - if (u) { - gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0); - } else { - gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0); - } - break; - case NEON_3R_VQSHL: - if (u) { - gen_helper_neon_qshl_u64(cpu_V0, cpu_env, - cpu_V1, cpu_V0); - } else { - gen_helper_neon_qshl_s64(cpu_V0, cpu_env, - cpu_V1, cpu_V0); - } - break; - case NEON_3R_VRSHL: - if (u) { - gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0); - } else { - gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0); - } - break; - case NEON_3R_VQRSHL: - if (u) { - gen_helper_neon_qrshl_u64(cpu_V0, cpu_env, - cpu_V1, cpu_V0); - } else { - gen_helper_neon_qrshl_s64(cpu_V0, cpu_env, - cpu_V1, cpu_V0); - } - break; - case NEON_3R_VADD_VSUB: - if (u) { - tcg_gen_sub_i64(CPU_V001); - } else { - tcg_gen_add_i64(CPU_V001); - } - break; - default: - abort(); - } - neon_store_reg64(cpu_V0, rd + pass); - } - return 0; - } - pairwise = 0; - switch (op) { - case NEON_3R_VSHL: - case NEON_3R_VQSHL: - case NEON_3R_VRSHL: - case NEON_3R_VQRSHL: - { - int rtmp; - /* Shift instruction operands are reversed. */ - rtmp = rn; - rn = rm; - rm = rtmp; - } - break; - case NEON_3R_VPADD: - if (u) { - return 1; - } - /* Fall through */ - case NEON_3R_VPMAX: - case NEON_3R_VPMIN: - pairwise = 1; - break; - case NEON_3R_FLOAT_ARITH: - pairwise = (u && size < 2); /* if VPADD (float) */ - break; - case NEON_3R_FLOAT_MINMAX: - pairwise = u; /* if VPMIN/VPMAX (float) */ - break; - case NEON_3R_FLOAT_CMP: - if (!u && size) { - /* no encoding for U=0 C=1x */ - return 1; - } - break; - case NEON_3R_FLOAT_ACMP: - if (!u) { - return 1; - } - break; - case NEON_3R_FLOAT_MISC: - /* VMAXNM/VMINNM in ARMv8 */ - if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) { - return 1; - } - break; - case NEON_3R_VMUL: - if (u && (size != 0)) { - /* UNDEF on invalid size for polynomial subcase */ - return 1; - } - break; - case NEON_3R_VFM: - if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) { - return 1; - } - break; - default: - break; - } - - if (pairwise && q) { - /* All the pairwise insns UNDEF if Q is set */ - return 1; - } - - for (pass = 0; pass < (q ? 4 : 2); pass++) { - - if (pairwise) { - /* Pairwise. */ - if (pass < 1) { - tmp = neon_load_reg(rn, 0); - tmp2 = neon_load_reg(rn, 1); - } else { - tmp = neon_load_reg(rm, 0); - tmp2 = neon_load_reg(rm, 1); - } - } else { - /* Elementwise. */ - tmp = neon_load_reg(rn, pass); - tmp2 = neon_load_reg(rm, pass); - } - switch (op) { - case NEON_3R_VHADD: - GEN_NEON_INTEGER_OP(hadd); - break; - case NEON_3R_VQADD: - GEN_NEON_INTEGER_OP_ENV(qadd); - break; - case NEON_3R_VRHADD: - GEN_NEON_INTEGER_OP(rhadd); - break; - case NEON_3R_LOGIC: /* Logic ops. */ - switch ((u << 2) | size) { - case 0: /* VAND */ - tcg_gen_and_i32(tmp, tmp, tmp2); - break; - case 1: /* BIC */ - tcg_gen_andc_i32(tmp, tmp, tmp2); - break; - case 2: /* VORR */ - tcg_gen_or_i32(tmp, tmp, tmp2); - break; - case 3: /* VORN */ - tcg_gen_orc_i32(tmp, tmp, tmp2); - break; - case 4: /* VEOR */ - tcg_gen_xor_i32(tmp, tmp, tmp2); - break; - case 5: /* VBSL */ - tmp3 = neon_load_reg(rd, pass); - gen_neon_bsl(tmp, tmp, tmp2, tmp3); - tcg_temp_free_i32(tmp3); - break; - case 6: /* VBIT */ - tmp3 = neon_load_reg(rd, pass); - gen_neon_bsl(tmp, tmp, tmp3, tmp2); - tcg_temp_free_i32(tmp3); - break; - case 7: /* VBIF */ - tmp3 = neon_load_reg(rd, pass); - gen_neon_bsl(tmp, tmp3, tmp, tmp2); - tcg_temp_free_i32(tmp3); - break; - } - break; - case NEON_3R_VHSUB: - GEN_NEON_INTEGER_OP(hsub); - break; - case NEON_3R_VQSUB: - GEN_NEON_INTEGER_OP_ENV(qsub); - break; - case NEON_3R_VCGT: - GEN_NEON_INTEGER_OP(cgt); - break; - case NEON_3R_VCGE: - GEN_NEON_INTEGER_OP(cge); - break; - case NEON_3R_VSHL: - GEN_NEON_INTEGER_OP(shl); - break; - case NEON_3R_VQSHL: - GEN_NEON_INTEGER_OP_ENV(qshl); - break; - case NEON_3R_VRSHL: - GEN_NEON_INTEGER_OP(rshl); - break; - case NEON_3R_VQRSHL: - GEN_NEON_INTEGER_OP_ENV(qrshl); - break; - case NEON_3R_VMAX: - GEN_NEON_INTEGER_OP(max); - break; - case NEON_3R_VMIN: - GEN_NEON_INTEGER_OP(min); - break; - case NEON_3R_VABD: - GEN_NEON_INTEGER_OP(abd); - break; - case NEON_3R_VABA: - GEN_NEON_INTEGER_OP(abd); - tcg_temp_free_i32(tmp2); - tmp2 = neon_load_reg(rd, pass); - gen_neon_add(size, tmp, tmp2); - break; - case NEON_3R_VADD_VSUB: - if (!u) { /* VADD */ - gen_neon_add(size, tmp, tmp2); - } else { /* VSUB */ - switch (size) { - case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break; - case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break; - default: abort(); - } - } - break; - case NEON_3R_VTST_VCEQ: - if (!u) { /* VTST */ - switch (size) { - case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break; - case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break; - default: abort(); - } - } else { /* VCEQ */ - switch (size) { - case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; - case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; - default: abort(); - } - } - break; - case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */ - switch (size) { - case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; - case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; - default: abort(); - } - tcg_temp_free_i32(tmp2); - tmp2 = neon_load_reg(rd, pass); - if (u) { /* VMLS */ - gen_neon_rsb(size, tmp, tmp2); - } else { /* VMLA */ - gen_neon_add(size, tmp, tmp2); - } - break; - case NEON_3R_VMUL: - if (u) { /* polynomial */ - gen_helper_neon_mul_p8(tmp, tmp, tmp2); - } else { /* Integer */ - switch (size) { - case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; - case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; - default: abort(); - } - } - break; - case NEON_3R_VPMAX: - GEN_NEON_INTEGER_OP(pmax); - break; - case NEON_3R_VPMIN: - GEN_NEON_INTEGER_OP(pmin); - break; - case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */ - if (!u) { /* VQDMULH */ - switch (size) { - case 1: - gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); - break; - case 2: - gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); - break; - default: abort(); - } - } else { /* VQRDMULH */ - switch (size) { - case 1: - gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); - break; - case 2: - gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); - break; - default: abort(); - } - } - break; - case NEON_3R_VPADD: - switch (size) { - case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; - case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break; - default: abort(); - } - break; - case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */ - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - switch ((u << 2) | size) { - case 0: /* VADD */ - case 4: /* VPADD */ - gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); - break; - case 2: /* VSUB */ - gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus); - break; - case 6: /* VABD */ - gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus); - break; - default: - abort(); - } - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_3R_FLOAT_MULTIPLY: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus); - if (!u) { - tcg_temp_free_i32(tmp2); - tmp2 = neon_load_reg(rd, pass); - if (size == 0) { - gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); - } else { - gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus); - } - } - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_3R_FLOAT_CMP: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - if (!u) { - gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus); - } else { - if (size == 0) { - gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus); - } else { - gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus); - } - } - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_3R_FLOAT_ACMP: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - if (size == 0) { - gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus); - } else { - gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus); - } - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_3R_FLOAT_MINMAX: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - if (size == 0) { - gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus); - } else { - gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus); - } - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_3R_FLOAT_MISC: - if (u) { - /* VMAXNM/VMINNM */ - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - if (size == 0) { - gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus); - } else { - gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus); - } - tcg_temp_free_ptr(fpstatus); - } else { - if (size == 0) { - gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env); - } else { - gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env); - } - } - break; - case NEON_3R_VFM: - { - /* VFMA, VFMS: fused multiply-add */ - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - TCGv_i32 tmp3 = neon_load_reg(rd, pass); - if (size) { - /* VFMS */ - gen_helper_vfp_negs(tmp, tmp); - } - gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus); - tcg_temp_free_i32(tmp3); - tcg_temp_free_ptr(fpstatus); - break; - } - default: - abort(); - } - tcg_temp_free_i32(tmp2); - - /* Save the result. For elementwise operations we can put it - straight into the destination register. For pairwise operations - we have to be careful to avoid clobbering the source operands. */ - if (pairwise && rd == rm) { - neon_store_scratch(pass, tmp); - } else { - neon_store_reg(rd, pass, tmp); - } - - } /* for pass */ - if (pairwise && rd == rm) { - for (pass = 0; pass < (q ? 4 : 2); pass++) { - tmp = neon_load_scratch(pass); - neon_store_reg(rd, pass, tmp); - } - } - /* End of 3 register same size operations. */ - } else if (insn & (1 << 4)) { - if ((insn & 0x00380080) != 0) { - /* Two registers and shift. */ - op = (insn >> 8) & 0xf; - if (insn & (1 << 7)) { - /* 64-bit shift. */ - if (op > 7) { - return 1; - } - size = 3; - } else { - size = 2; - while ((insn & (1 << (size + 19))) == 0) - size--; - } - shift = (insn >> 16) & ((1 << (3 + size)) - 1); - /* To avoid excessive duplication of ops we implement shift - by immediate using the variable shift operations. */ - if (op < 8) { - /* Shift by immediate: - VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ - if (q && ((rd | rm) & 1)) { - return 1; - } - if (!u && (op == 4 || op == 6)) { - return 1; - } - /* Right shifts are encoded as N - shift, where N is the - element size in bits. */ - if (op <= 4) - shift = shift - (1 << (size + 3)); - if (size == 3) { - count = q + 1; - } else { - count = q ? 4: 2; - } - switch (size) { - case 0: - imm = (uint8_t) shift; - imm |= imm << 8; - imm |= imm << 16; - break; - case 1: - imm = (uint16_t) shift; - imm |= imm << 16; - break; - case 2: - case 3: - imm = shift; - break; - default: - abort(); - } - - for (pass = 0; pass < count; pass++) { - if (size == 3) { - neon_load_reg64(cpu_V0, rm + pass); - tcg_gen_movi_i64(cpu_V1, imm); - switch (op) { - case 0: /* VSHR */ - case 1: /* VSRA */ - if (u) - gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); - else - gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1); - break; - case 2: /* VRSHR */ - case 3: /* VRSRA */ - if (u) - gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1); - else - gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1); - break; - case 4: /* VSRI */ - case 5: /* VSHL, VSLI */ - gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); - break; - case 6: /* VQSHLU */ - gen_helper_neon_qshlu_s64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - break; - case 7: /* VQSHL */ - if (u) { - gen_helper_neon_qshl_u64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } else { - gen_helper_neon_qshl_s64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } - break; - } - if (op == 1 || op == 3) { - /* Accumulate. */ - neon_load_reg64(cpu_V1, rd + pass); - tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1); - } else if (op == 4 || (op == 5 && u)) { - /* Insert */ - neon_load_reg64(cpu_V1, rd + pass); - uint64_t mask; - if (shift < -63 || shift > 63) { - mask = 0; - } else { - if (op == 4) { - mask = 0xffffffffffffffffull >> -shift; - } else { - mask = 0xffffffffffffffffull << shift; - } - } - tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask); - tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); - } - neon_store_reg64(cpu_V0, rd + pass); - } else { /* size < 3 */ - /* Operands in T0 and T1. */ - tmp = neon_load_reg(rm, pass); - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, imm); - switch (op) { - case 0: /* VSHR */ - case 1: /* VSRA */ - GEN_NEON_INTEGER_OP(shl); - break; - case 2: /* VRSHR */ - case 3: /* VRSRA */ - GEN_NEON_INTEGER_OP(rshl); - break; - case 4: /* VSRI */ - case 5: /* VSHL, VSLI */ - switch (size) { - case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break; - case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break; - default: abort(); - } - break; - case 6: /* VQSHLU */ - switch (size) { - case 0: - gen_helper_neon_qshlu_s8(tmp, cpu_env, - tmp, tmp2); - break; - case 1: - gen_helper_neon_qshlu_s16(tmp, cpu_env, - tmp, tmp2); - break; - case 2: - gen_helper_neon_qshlu_s32(tmp, cpu_env, - tmp, tmp2); - break; - default: - abort(); - } - break; - case 7: /* VQSHL */ - GEN_NEON_INTEGER_OP_ENV(qshl); - break; - } - tcg_temp_free_i32(tmp2); - - if (op == 1 || op == 3) { - /* Accumulate. */ - tmp2 = neon_load_reg(rd, pass); - gen_neon_add(size, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } else if (op == 4 || (op == 5 && u)) { - /* Insert */ - switch (size) { - case 0: - if (op == 4) - mask = 0xff >> -shift; - else - mask = (uint8_t)(0xff << shift); - mask |= mask << 8; - mask |= mask << 16; - break; - case 1: - if (op == 4) - mask = 0xffff >> -shift; - else - mask = (uint16_t)(0xffff << shift); - mask |= mask << 16; - break; - case 2: - if (shift < -31 || shift > 31) { - mask = 0; - } else { - if (op == 4) - mask = 0xffffffffu >> -shift; - else - mask = 0xffffffffu << shift; - } - break; - default: - abort(); - } - tmp2 = neon_load_reg(rd, pass); - tcg_gen_andi_i32(tmp, tmp, mask); - tcg_gen_andi_i32(tmp2, tmp2, ~mask); - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - neon_store_reg(rd, pass, tmp); - } - } /* for pass */ - } else if (op < 10) { - /* Shift by immediate and narrow: - VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ - int input_unsigned = (op == 8) ? !u : u; - if (rm & 1) { - return 1; - } - shift = shift - (1 << (size + 3)); - size++; - if (size == 3) { - tmp64 = tcg_const_i64(shift); - neon_load_reg64(cpu_V0, rm); - neon_load_reg64(cpu_V1, rm + 1); - for (pass = 0; pass < 2; pass++) { - TCGv_i64 in; - if (pass == 0) { - in = cpu_V0; - } else { - in = cpu_V1; - } - if (q) { - if (input_unsigned) { - gen_helper_neon_rshl_u64(cpu_V0, in, tmp64); - } else { - gen_helper_neon_rshl_s64(cpu_V0, in, tmp64); - } - } else { - if (input_unsigned) { - gen_helper_neon_shl_u64(cpu_V0, in, tmp64); - } else { - gen_helper_neon_shl_s64(cpu_V0, in, tmp64); - } - } - tmp = tcg_temp_new_i32(); - gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); - neon_store_reg(rd, pass, tmp); - } /* for pass */ - tcg_temp_free_i64(tmp64); - } else { - if (size == 1) { - imm = (uint16_t)shift; - imm |= imm << 16; - } else { - /* size == 2 */ - imm = (uint32_t)shift; - } - tmp2 = tcg_const_i32(imm); - tmp4 = neon_load_reg(rm + 1, 0); - tmp5 = neon_load_reg(rm + 1, 1); - for (pass = 0; pass < 2; pass++) { - if (pass == 0) { - tmp = neon_load_reg(rm, 0); - } else { - tmp = tmp4; - } - gen_neon_shift_narrow(size, tmp, tmp2, q, - input_unsigned); - if (pass == 0) { - tmp3 = neon_load_reg(rm, 1); - } else { - tmp3 = tmp5; - } - gen_neon_shift_narrow(size, tmp3, tmp2, q, - input_unsigned); - tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp3); - tmp = tcg_temp_new_i32(); - gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); - neon_store_reg(rd, pass, tmp); - } /* for pass */ - tcg_temp_free_i32(tmp2); - } - } else if (op == 10) { - /* VSHLL, VMOVL */ - if (q || (rd & 1)) { - return 1; - } - tmp = neon_load_reg(rm, 0); - tmp2 = neon_load_reg(rm, 1); - for (pass = 0; pass < 2; pass++) { - if (pass == 1) - tmp = tmp2; - - gen_neon_widen(cpu_V0, tmp, size, u); - - if (shift != 0) { - /* The shift is less than the width of the source - type, so we can just shift the whole register. */ - tcg_gen_shli_i64(cpu_V0, cpu_V0, shift); - /* Widen the result of shift: we need to clear - * the potential overflow bits resulting from - * left bits of the narrow input appearing as - * right bits of left the neighbour narrow - * input. */ - if (size < 2 || !u) { - uint64_t imm64; - if (size == 0) { - imm = (0xffu >> (8 - shift)); - imm |= imm << 16; - } else if (size == 1) { - imm = 0xffff >> (16 - shift); - } else { - /* size == 2 */ - imm = 0xffffffff >> (32 - shift); - } - if (size < 2) { - imm64 = imm | (((uint64_t)imm) << 32); - } else { - imm64 = imm; - } - tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64); - } - } - neon_store_reg64(cpu_V0, rd + pass); - } - } else if (op >= 14) { - /* VCVT fixed-point. */ - if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { - return 1; - } - /* We have already masked out the must-be-1 top bit of imm6, - * hence this 32-shift where the ARM ARM has 64-imm6. - */ - shift = 32 - shift; - for (pass = 0; pass < (q ? 4 : 2); pass++) { - tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); - if (!(op & 1)) { - if (u) - gen_vfp_ulto(0, shift, 1); - else - gen_vfp_slto(0, shift, 1); - } else { - if (u) - gen_vfp_toul(0, shift, 1); - else - gen_vfp_tosl(0, shift, 1); - } - tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); - } - } else { - return 1; - } - } else { /* (insn & 0x00380080) == 0 */ - int invert; - if (q && (rd & 1)) { - return 1; - } - - op = (insn >> 8) & 0xf; - /* One register and immediate. */ - imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf); - invert = (insn & (1 << 5)) != 0; - /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. - * We choose to not special-case this and will behave as if a - * valid constant encoding of 0 had been given. - */ - switch (op) { - case 0: case 1: - /* no-op */ - break; - case 2: case 3: - imm <<= 8; - break; - case 4: case 5: - imm <<= 16; - break; - case 6: case 7: - imm <<= 24; - break; - case 8: case 9: - imm |= imm << 16; - break; - case 10: case 11: - imm = (imm << 8) | (imm << 24); - break; - case 12: - imm = (imm << 8) | 0xff; - break; - case 13: - imm = (imm << 16) | 0xffff; - break; - case 14: - imm |= (imm << 8) | (imm << 16) | (imm << 24); - if (invert) - imm = ~imm; - break; - case 15: - if (invert) { - return 1; - } - imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) - | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); - break; - } - if (invert) - imm = ~imm; - - for (pass = 0; pass < (q ? 4 : 2); pass++) { - if (op & 1 && op < 12) { - tmp = neon_load_reg(rd, pass); - if (invert) { - /* The immediate value has already been inverted, so - BIC becomes AND. */ - tcg_gen_andi_i32(tmp, tmp, imm); - } else { - tcg_gen_ori_i32(tmp, tmp, imm); - } - } else { - /* VMOV, VMVN. */ - tmp = tcg_temp_new_i32(); - if (op == 14 && invert) { - int n; - uint32_t val; - val = 0; - for (n = 0; n < 4; n++) { - if (imm & (1 << (n + (pass & 1) * 4))) - val |= 0xff << (n * 8); - } - tcg_gen_movi_i32(tmp, val); - } else { - tcg_gen_movi_i32(tmp, imm); - } - } - neon_store_reg(rd, pass, tmp); - } - } - } else { /* (insn & 0x00800010 == 0x00800000) */ - if (size != 3) { - op = (insn >> 8) & 0xf; - if ((insn & (1 << 6)) == 0) { - /* Three registers of different lengths. */ - int src1_wide; - int src2_wide; - int prewiden; - /* undefreq: bit 0 : UNDEF if size == 0 - * bit 1 : UNDEF if size == 1 - * bit 2 : UNDEF if size == 2 - * bit 3 : UNDEF if U == 1 - * Note that [2:0] set implies 'always UNDEF' - */ - int undefreq; - /* prewiden, src1_wide, src2_wide, undefreq */ - static const int neon_3reg_wide[16][4] = { - {1, 0, 0, 0}, /* VADDL */ - {1, 1, 0, 0}, /* VADDW */ - {1, 0, 0, 0}, /* VSUBL */ - {1, 1, 0, 0}, /* VSUBW */ - {0, 1, 1, 0}, /* VADDHN */ - {0, 0, 0, 0}, /* VABAL */ - {0, 1, 1, 0}, /* VSUBHN */ - {0, 0, 0, 0}, /* VABDL */ - {0, 0, 0, 0}, /* VMLAL */ - {0, 0, 0, 9}, /* VQDMLAL */ - {0, 0, 0, 0}, /* VMLSL */ - {0, 0, 0, 9}, /* VQDMLSL */ - {0, 0, 0, 0}, /* Integer VMULL */ - {0, 0, 0, 1}, /* VQDMULL */ - {0, 0, 0, 0xa}, /* Polynomial VMULL */ - {0, 0, 0, 7}, /* Reserved: always UNDEF */ - }; - - prewiden = neon_3reg_wide[op][0]; - src1_wide = neon_3reg_wide[op][1]; - src2_wide = neon_3reg_wide[op][2]; - undefreq = neon_3reg_wide[op][3]; - - if ((undefreq & (1 << size)) || - ((undefreq & 8) && u)) { - return 1; - } - if ((src1_wide && (rn & 1)) || - (src2_wide && (rm & 1)) || - (!src2_wide && (rd & 1))) { - return 1; - } - - /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply) - * outside the loop below as it only performs a single pass. - */ - if (op == 14 && size == 2) { - TCGv_i64 tcg_rn, tcg_rm, tcg_rd; - - if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) { - return 1; - } - tcg_rn = tcg_temp_new_i64(); - tcg_rm = tcg_temp_new_i64(); - tcg_rd = tcg_temp_new_i64(); - neon_load_reg64(tcg_rn, rn); - neon_load_reg64(tcg_rm, rm); - gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm); - neon_store_reg64(tcg_rd, rd); - gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm); - neon_store_reg64(tcg_rd, rd + 1); - tcg_temp_free_i64(tcg_rn); - tcg_temp_free_i64(tcg_rm); - tcg_temp_free_i64(tcg_rd); - return 0; - } - - /* Avoid overlapping operands. Wide source operands are - always aligned so will never overlap with wide - destinations in problematic ways. */ - if (rd == rm && !src2_wide) { - tmp = neon_load_reg(rm, 1); - neon_store_scratch(2, tmp); - } else if (rd == rn && !src1_wide) { - tmp = neon_load_reg(rn, 1); - neon_store_scratch(2, tmp); - } - TCGV_UNUSED_I32(tmp3); - for (pass = 0; pass < 2; pass++) { - if (src1_wide) { - neon_load_reg64(cpu_V0, rn + pass); - TCGV_UNUSED_I32(tmp); - } else { - if (pass == 1 && rd == rn) { - tmp = neon_load_scratch(2); - } else { - tmp = neon_load_reg(rn, pass); - } - if (prewiden) { - gen_neon_widen(cpu_V0, tmp, size, u); - } - } - if (src2_wide) { - neon_load_reg64(cpu_V1, rm + pass); - TCGV_UNUSED_I32(tmp2); - } else { - if (pass == 1 && rd == rm) { - tmp2 = neon_load_scratch(2); - } else { - tmp2 = neon_load_reg(rm, pass); - } - if (prewiden) { - gen_neon_widen(cpu_V1, tmp2, size, u); - } - } - switch (op) { - case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */ - gen_neon_addl(size); - break; - case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */ - gen_neon_subl(size); - break; - case 5: case 7: /* VABAL, VABDL */ - switch ((size << 1) | u) { - case 0: - gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2); - break; - case 1: - gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2); - break; - case 2: - gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2); - break; - case 3: - gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2); - break; - case 4: - gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2); - break; - case 5: - gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2); - break; - default: abort(); - } - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; - case 8: case 9: case 10: case 11: case 12: case 13: - /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */ - gen_neon_mull(cpu_V0, tmp, tmp2, size, u); - break; - case 14: /* Polynomial VMULL */ - gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; - default: /* 15 is RESERVED: caught earlier */ - abort(); - } - if (op == 13) { - /* VQDMULL */ - gen_neon_addl_saturate(cpu_V0, cpu_V0, size); - neon_store_reg64(cpu_V0, rd + pass); - } else if (op == 5 || (op >= 8 && op <= 11)) { - /* Accumulate. */ - neon_load_reg64(cpu_V1, rd + pass); - switch (op) { - case 10: /* VMLSL */ - gen_neon_negl(cpu_V0, size); - /* Fall through */ - case 5: case 8: /* VABAL, VMLAL */ - gen_neon_addl(size); - break; - case 9: case 11: /* VQDMLAL, VQDMLSL */ - gen_neon_addl_saturate(cpu_V0, cpu_V0, size); - if (op == 11) { - gen_neon_negl(cpu_V0, size); - } - gen_neon_addl_saturate(cpu_V0, cpu_V1, size); - break; - default: - abort(); - } - neon_store_reg64(cpu_V0, rd + pass); - } else if (op == 4 || op == 6) { - /* Narrowing operation. */ - tmp = tcg_temp_new_i32(); - if (!u) { - switch (size) { - case 0: - gen_helper_neon_narrow_high_u8(tmp, cpu_V0); - break; - case 1: - gen_helper_neon_narrow_high_u16(tmp, cpu_V0); - break; - case 2: - tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); - tcg_gen_extrl_i64_i32(tmp, cpu_V0); - break; - default: abort(); - } - } else { - switch (size) { - case 0: - gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0); - break; - case 1: - gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0); - break; - case 2: - tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31); - tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); - tcg_gen_extrl_i64_i32(tmp, cpu_V0); - break; - default: abort(); - } - } - if (pass == 0) { - tmp3 = tmp; - } else { - neon_store_reg(rd, 0, tmp3); - neon_store_reg(rd, 1, tmp); - } - } else { - /* Write back the result. */ - neon_store_reg64(cpu_V0, rd + pass); - } - } - } else { - /* Two registers and a scalar. NB that for ops of this form - * the ARM ARM labels bit 24 as Q, but it is in our variable - * 'u', not 'q'. - */ - if (size == 0) { - return 1; - } - switch (op) { - case 1: /* Float VMLA scalar */ - case 5: /* Floating point VMLS scalar */ - case 9: /* Floating point VMUL scalar */ - if (size == 1) { - return 1; - } - /* fall through */ - case 0: /* Integer VMLA scalar */ - case 4: /* Integer VMLS scalar */ - case 8: /* Integer VMUL scalar */ - case 12: /* VQDMULH scalar */ - case 13: /* VQRDMULH scalar */ - if (u && ((rd | rn) & 1)) { - return 1; - } - tmp = neon_get_scalar(size, rm); - neon_store_scratch(0, tmp); - for (pass = 0; pass < (u ? 4 : 2); pass++) { - tmp = neon_load_scratch(0); - tmp2 = neon_load_reg(rn, pass); - if (op == 12) { - if (size == 1) { - gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); - } else { - gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); - } - } else if (op == 13) { - if (size == 1) { - gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); - } else { - gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); - } - } else if (op & 1) { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus); - tcg_temp_free_ptr(fpstatus); - } else { - switch (size) { - case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; - case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; - default: abort(); - } - } - tcg_temp_free_i32(tmp2); - if (op < 8) { - /* Accumulate. */ - tmp2 = neon_load_reg(rd, pass); - switch (op) { - case 0: - gen_neon_add(size, tmp, tmp2); - break; - case 1: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - case 4: - gen_neon_rsb(size, tmp, tmp2); - break; - case 5: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - default: - abort(); - } - tcg_temp_free_i32(tmp2); - } - neon_store_reg(rd, pass, tmp); - } - break; - case 3: /* VQDMLAL scalar */ - case 7: /* VQDMLSL scalar */ - case 11: /* VQDMULL scalar */ - if (u == 1) { - return 1; - } - /* fall through */ - case 2: /* VMLAL sclar */ - case 6: /* VMLSL scalar */ - case 10: /* VMULL scalar */ - if (rd & 1) { - return 1; - } - tmp2 = neon_get_scalar(size, rm); - /* We need a copy of tmp2 because gen_neon_mull - * deletes it during pass 0. */ - tmp4 = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp4, tmp2); - tmp3 = neon_load_reg(rn, 1); - - for (pass = 0; pass < 2; pass++) { - if (pass == 0) { - tmp = neon_load_reg(rn, 0); - } else { - tmp = tmp3; - tmp2 = tmp4; - } - gen_neon_mull(cpu_V0, tmp, tmp2, size, u); - if (op != 11) { - neon_load_reg64(cpu_V1, rd + pass); - } - switch (op) { - case 6: - gen_neon_negl(cpu_V0, size); - /* Fall through */ - case 2: - gen_neon_addl(size); - break; - case 3: case 7: - gen_neon_addl_saturate(cpu_V0, cpu_V0, size); - if (op == 7) { - gen_neon_negl(cpu_V0, size); - } - gen_neon_addl_saturate(cpu_V0, cpu_V1, size); - break; - case 10: - /* no-op */ - break; - case 11: - gen_neon_addl_saturate(cpu_V0, cpu_V0, size); - break; - default: - abort(); - } - neon_store_reg64(cpu_V0, rd + pass); - } - - - break; - default: /* 14 and 15 are RESERVED */ - return 1; - } - } - } else { /* size == 3 */ - if (!u) { - /* Extract. */ - imm = (insn >> 8) & 0xf; - - if (imm > 7 && !q) - return 1; - - if (q && ((rd | rn | rm) & 1)) { - return 1; - } - - if (imm == 0) { - neon_load_reg64(cpu_V0, rn); - if (q) { - neon_load_reg64(cpu_V1, rn + 1); - } - } else if (imm == 8) { - neon_load_reg64(cpu_V0, rn + 1); - if (q) { - neon_load_reg64(cpu_V1, rm); - } - } else if (q) { - tmp64 = tcg_temp_new_i64(); - if (imm < 8) { - neon_load_reg64(cpu_V0, rn); - neon_load_reg64(tmp64, rn + 1); - } else { - neon_load_reg64(cpu_V0, rn + 1); - neon_load_reg64(tmp64, rm); - } - tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8); - tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8)); - tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); - if (imm < 8) { - neon_load_reg64(cpu_V1, rm); - } else { - neon_load_reg64(cpu_V1, rm + 1); - imm -= 8; - } - tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); - tcg_gen_shri_i64(tmp64, tmp64, imm * 8); - tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64); - tcg_temp_free_i64(tmp64); - } else { - /* BUGFIX */ - neon_load_reg64(cpu_V0, rn); - tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8); - neon_load_reg64(cpu_V1, rm); - tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); - tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); - } - neon_store_reg64(cpu_V0, rd); - if (q) { - neon_store_reg64(cpu_V1, rd + 1); - } - } else if ((insn & (1 << 11)) == 0) { - /* Two register misc. */ - op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf); - size = (insn >> 18) & 3; - /* UNDEF for unknown op values and bad op-size combinations */ - if ((neon_2rm_sizes[op] & (1 << size)) == 0) { - return 1; - } - if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) && - q && ((rm | rd) & 1)) { - return 1; - } - switch (op) { - case NEON_2RM_VREV64: - for (pass = 0; pass < (q ? 2 : 1); pass++) { - tmp = neon_load_reg(rm, pass * 2); - tmp2 = neon_load_reg(rm, pass * 2 + 1); - switch (size) { - case 0: tcg_gen_bswap32_i32(tmp, tmp); break; - case 1: gen_swap_half(tmp); break; - case 2: /* no-op */ break; - default: abort(); - } - neon_store_reg(rd, pass * 2 + 1, tmp); - if (size == 2) { - neon_store_reg(rd, pass * 2, tmp2); - } else { - switch (size) { - case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break; - case 1: gen_swap_half(tmp2); break; - default: abort(); - } - neon_store_reg(rd, pass * 2, tmp2); - } - } - break; - case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U: - case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U: - for (pass = 0; pass < q + 1; pass++) { - tmp = neon_load_reg(rm, pass * 2); - gen_neon_widen(cpu_V0, tmp, size, op & 1); - tmp = neon_load_reg(rm, pass * 2 + 1); - gen_neon_widen(cpu_V1, tmp, size, op & 1); - switch (size) { - case 0: gen_helper_neon_paddl_u16(CPU_V001); break; - case 1: gen_helper_neon_paddl_u32(CPU_V001); break; - case 2: tcg_gen_add_i64(CPU_V001); break; - default: abort(); - } - if (op >= NEON_2RM_VPADAL) { - /* Accumulate. */ - neon_load_reg64(cpu_V1, rd + pass); - gen_neon_addl(size); - } - neon_store_reg64(cpu_V0, rd + pass); - } - break; - case NEON_2RM_VTRN: - if (size == 2) { - int n; - for (n = 0; n < (q ? 4 : 2); n += 2) { - tmp = neon_load_reg(rm, n); - tmp2 = neon_load_reg(rd, n + 1); - neon_store_reg(rm, n, tmp2); - neon_store_reg(rd, n + 1, tmp); - } - } else { - goto elementwise; - } - break; - case NEON_2RM_VUZP: - if (gen_neon_unzip(rd, rm, size, q)) { - return 1; - } - break; - case NEON_2RM_VZIP: - if (gen_neon_zip(rd, rm, size, q)) { - return 1; - } - break; - case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN: - /* also VQMOVUN; op field and mnemonics don't line up */ - if (rm & 1) { - return 1; - } - TCGV_UNUSED_I32(tmp2); - for (pass = 0; pass < 2; pass++) { - neon_load_reg64(cpu_V0, rm + pass); - tmp = tcg_temp_new_i32(); - gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size, - tmp, cpu_V0); - if (pass == 0) { - tmp2 = tmp; - } else { - neon_store_reg(rd, 0, tmp2); - neon_store_reg(rd, 1, tmp); - } - } - break; - case NEON_2RM_VSHLL: - if (q || (rd & 1)) { - return 1; - } - tmp = neon_load_reg(rm, 0); - tmp2 = neon_load_reg(rm, 1); - for (pass = 0; pass < 2; pass++) { - if (pass == 1) - tmp = tmp2; - gen_neon_widen(cpu_V0, tmp, size, 1); - tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size); - neon_store_reg64(cpu_V0, rd + pass); - } - break; - case NEON_2RM_VCVT_F16_F32: - if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) || - q || (rm & 1)) { - return 1; - } - tmp = tcg_temp_new_i32(); - tmp2 = tcg_temp_new_i32(); - tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0)); - gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); - tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1)); - gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); - tcg_gen_shli_i32(tmp2, tmp2, 16); - tcg_gen_or_i32(tmp2, tmp2, tmp); - tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2)); - gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); - tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3)); - neon_store_reg(rd, 0, tmp2); - tmp2 = tcg_temp_new_i32(); - gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); - tcg_gen_shli_i32(tmp2, tmp2, 16); - tcg_gen_or_i32(tmp2, tmp2, tmp); - neon_store_reg(rd, 1, tmp2); - tcg_temp_free_i32(tmp); - break; - case NEON_2RM_VCVT_F32_F16: - if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) || - q || (rd & 1)) { - return 1; - } - tmp3 = tcg_temp_new_i32(); - tmp = neon_load_reg(rm, 0); - tmp2 = neon_load_reg(rm, 1); - tcg_gen_ext16u_i32(tmp3, tmp); - gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); - tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0)); - tcg_gen_shri_i32(tmp3, tmp, 16); - gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); - tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1)); - tcg_temp_free_i32(tmp); - tcg_gen_ext16u_i32(tmp3, tmp2); - gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); - tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2)); - tcg_gen_shri_i32(tmp3, tmp2, 16); - gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); - tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3)); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp3); - break; - case NEON_2RM_AESE: case NEON_2RM_AESMC: - if (!arm_dc_feature(s, ARM_FEATURE_V8_AES) - || ((rm | rd) & 1)) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rm); - - /* Bit 6 is the lowest opcode bit; it distinguishes between - * encryption (AESE/AESMC) and decryption (AESD/AESIMC) - */ - tmp3 = tcg_const_i32(extract32(insn, 6, 1)); - - if (op == NEON_2RM_AESE) { - gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3); - } else { - gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3); - } - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp3); - break; - case NEON_2RM_SHA1H: - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1) - || ((rm | rd) & 1)) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rm); - - gen_helper_crypto_sha1h(cpu_env, tmp, tmp2); - - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - break; - case NEON_2RM_SHA1SU1: - if ((rm | rd) & 1) { - return 1; - } - /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */ - if (q) { - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) { - return 1; - } - } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { - return 1; - } - tmp = tcg_const_i32(rd); - tmp2 = tcg_const_i32(rm); - if (q) { - gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2); - } else { - gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2); - } - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - break; - default: - elementwise: - for (pass = 0; pass < (q ? 4 : 2); pass++) { - if (neon_2rm_is_float_op(op)) { - tcg_gen_ld_f32(cpu_F0s, cpu_env, - neon_reg_offset(rm, pass)); - TCGV_UNUSED_I32(tmp); - } else { - tmp = neon_load_reg(rm, pass); - } - switch (op) { - case NEON_2RM_VREV32: - switch (size) { - case 0: tcg_gen_bswap32_i32(tmp, tmp); break; - case 1: gen_swap_half(tmp); break; - default: abort(); - } - break; - case NEON_2RM_VREV16: - gen_rev16(tmp); - break; - case NEON_2RM_VCLS: - switch (size) { - case 0: gen_helper_neon_cls_s8(tmp, tmp); break; - case 1: gen_helper_neon_cls_s16(tmp, tmp); break; - case 2: gen_helper_neon_cls_s32(tmp, tmp); break; - default: abort(); - } - break; - case NEON_2RM_VCLZ: - switch (size) { - case 0: gen_helper_neon_clz_u8(tmp, tmp); break; - case 1: gen_helper_neon_clz_u16(tmp, tmp); break; - case 2: gen_helper_clz(tmp, tmp); break; - default: abort(); - } - break; - case NEON_2RM_VCNT: - gen_helper_neon_cnt_u8(tmp, tmp); - break; - case NEON_2RM_VMVN: - tcg_gen_not_i32(tmp, tmp); - break; - case NEON_2RM_VQABS: - switch (size) { - case 0: - gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); - break; - case 1: - gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); - break; - case 2: - gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); - break; - default: abort(); - } - break; - case NEON_2RM_VQNEG: - switch (size) { - case 0: - gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); - break; - case 1: - gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); - break; - case 2: - gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); - break; - default: abort(); - } - break; - case NEON_2RM_VCGT0: case NEON_2RM_VCLE0: - tmp2 = tcg_const_i32(0); - switch(size) { - case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break; - case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break; - default: abort(); - } - tcg_temp_free_i32(tmp2); - if (op == NEON_2RM_VCLE0) { - tcg_gen_not_i32(tmp, tmp); - } - break; - case NEON_2RM_VCGE0: case NEON_2RM_VCLT0: - tmp2 = tcg_const_i32(0); - switch(size) { - case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break; - case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break; - default: abort(); - } - tcg_temp_free_i32(tmp2); - if (op == NEON_2RM_VCLT0) { - tcg_gen_not_i32(tmp, tmp); - } - break; - case NEON_2RM_VCEQ0: - tmp2 = tcg_const_i32(0); - switch(size) { - case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; - case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; - case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; - default: abort(); - } - tcg_temp_free_i32(tmp2); - break; - case NEON_2RM_VABS: - switch(size) { - case 0: gen_helper_neon_abs_s8(tmp, tmp); break; - case 1: gen_helper_neon_abs_s16(tmp, tmp); break; - case 2: tcg_gen_abs_i32(tmp, tmp); break; - default: abort(); - } - break; - case NEON_2RM_VNEG: - tmp2 = tcg_const_i32(0); - gen_neon_rsb(size, tmp, tmp2); - tcg_temp_free_i32(tmp2); - break; - case NEON_2RM_VCGT0_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - tmp2 = tcg_const_i32(0); - gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus); - tcg_temp_free_i32(tmp2); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VCGE0_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - tmp2 = tcg_const_i32(0); - gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus); - tcg_temp_free_i32(tmp2); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VCEQ0_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - tmp2 = tcg_const_i32(0); - gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus); - tcg_temp_free_i32(tmp2); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VCLE0_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - tmp2 = tcg_const_i32(0); - gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus); - tcg_temp_free_i32(tmp2); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VCLT0_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - tmp2 = tcg_const_i32(0); - gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus); - tcg_temp_free_i32(tmp2); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VABS_F: - gen_vfp_abs(0); - break; - case NEON_2RM_VNEG_F: - gen_vfp_neg(0); - break; - case NEON_2RM_VSWP: - tmp2 = neon_load_reg(rd, pass); - neon_store_reg(rm, pass, tmp2); - break; - case NEON_2RM_VTRN: - tmp2 = neon_load_reg(rd, pass); - switch (size) { - case 0: gen_neon_trn_u8(tmp, tmp2); break; - case 1: gen_neon_trn_u16(tmp, tmp2); break; - default: abort(); - } - neon_store_reg(rm, pass, tmp2); - break; - case NEON_2RM_VRINTN: - case NEON_2RM_VRINTA: - case NEON_2RM_VRINTM: - case NEON_2RM_VRINTP: - case NEON_2RM_VRINTZ: - { - TCGv_i32 tcg_rmode; - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - int rmode; - - if (op == NEON_2RM_VRINTZ) { - rmode = FPROUNDING_ZERO; - } else { - rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1]; - } - - tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); - gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, - cpu_env); - gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus); - gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, - cpu_env); - tcg_temp_free_ptr(fpstatus); - tcg_temp_free_i32(tcg_rmode); - break; - } - case NEON_2RM_VRINTX: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VCVTAU: - case NEON_2RM_VCVTAS: - case NEON_2RM_VCVTNU: - case NEON_2RM_VCVTNS: - case NEON_2RM_VCVTPU: - case NEON_2RM_VCVTPS: - case NEON_2RM_VCVTMU: - case NEON_2RM_VCVTMS: - { - bool is_signed = !extract32(insn, 7, 1); - TCGv_ptr fpst = get_fpstatus_ptr(1); - TCGv_i32 tcg_rmode, tcg_shift; - int rmode = fp_decode_rm[extract32(insn, 8, 2)]; - - tcg_shift = tcg_const_i32(0); - tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); - gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, - cpu_env); - - if (is_signed) { - gen_helper_vfp_tosls(cpu_F0s, cpu_F0s, - tcg_shift, fpst); - } else { - gen_helper_vfp_touls(cpu_F0s, cpu_F0s, - tcg_shift, fpst); - } - - gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, - cpu_env); - tcg_temp_free_i32(tcg_rmode); - tcg_temp_free_i32(tcg_shift); - tcg_temp_free_ptr(fpst); - break; - } - case NEON_2RM_VRECPE: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_recpe_u32(tmp, tmp, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VRSQRTE: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_rsqrte_u32(tmp, tmp, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VRECPE_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VRSQRTE_F: - { - TCGv_ptr fpstatus = get_fpstatus_ptr(1); - gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus); - tcg_temp_free_ptr(fpstatus); - break; - } - case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */ - gen_vfp_sito(0, 1); - break; - case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */ - gen_vfp_uito(0, 1); - break; - case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */ - gen_vfp_tosiz(0, 1); - break; - case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */ - gen_vfp_touiz(0, 1); - break; - default: - /* Reserved op values were caught by the - * neon_2rm_sizes[] check earlier. - */ - abort(); - } - if (neon_2rm_is_float_op(op)) { - tcg_gen_st_f32(cpu_F0s, cpu_env, - neon_reg_offset(rd, pass)); - } else { - neon_store_reg(rd, pass, tmp); - } - } - break; - } - } else if ((insn & (1 << 10)) == 0) { - /* VTBL, VTBX. */ - int n = ((insn >> 8) & 3) + 1; - if ((rn + n) > 32) { - /* This is UNPREDICTABLE; we choose to UNDEF to avoid the - * helper function running off the end of the register file. - */ - return 1; - } - n <<= 3; - if (insn & (1 << 6)) { - tmp = neon_load_reg(rd, 0); - } else { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } - tmp2 = neon_load_reg(rm, 0); - tmp4 = tcg_const_i32(rn); - tmp5 = tcg_const_i32(n); - gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5); - tcg_temp_free_i32(tmp); - if (insn & (1 << 6)) { - tmp = neon_load_reg(rd, 1); - } else { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } - tmp3 = neon_load_reg(rm, 1); - gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5); - tcg_temp_free_i32(tmp5); - tcg_temp_free_i32(tmp4); - neon_store_reg(rd, 0, tmp2); - neon_store_reg(rd, 1, tmp3); - tcg_temp_free_i32(tmp); - } else if ((insn & 0x380) == 0) { - /* VDUP */ - if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) { - return 1; - } - if (insn & (1 << 19)) { - tmp = neon_load_reg(rm, 1); - } else { - tmp = neon_load_reg(rm, 0); - } - if (insn & (1 << 16)) { - gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8); - } else if (insn & (1 << 17)) { - if ((insn >> 18) & 1) - gen_neon_dup_high16(tmp); - else - gen_neon_dup_low16(tmp); - } - for (pass = 0; pass < (q ? 4 : 2); pass++) { - tmp2 = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp2, tmp); - neon_store_reg(rd, pass, tmp2); - } - tcg_temp_free_i32(tmp); - } else { - return 1; - } - } - } - return 0; -} - -static int disas_coproc_insn(DisasContext *s, uint32_t insn) -{ - int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2; - const ARMCPRegInfo *ri; - - cpnum = (insn >> 8) & 0xf; - - /* First check for coprocessor space used for XScale/iwMMXt insns */ - if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) { - if (extract32(s->c15_cpar, cpnum, 1) == 0) { - return 1; - } - if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { - return disas_iwmmxt_insn(s, insn); - } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) { - return disas_dsp_insn(s, insn); - } - return 1; - } - - /* Otherwise treat as a generic register access */ - is64 = (insn & (1 << 25)) == 0; - if (!is64 && ((insn & (1 << 4)) == 0)) { - /* cdp */ - return 1; - } - - crm = insn & 0xf; - if (is64) { - crn = 0; - opc1 = (insn >> 4) & 0xf; - opc2 = 0; - rt2 = (insn >> 16) & 0xf; - } else { - crn = (insn >> 16) & 0xf; - opc1 = (insn >> 21) & 7; - opc2 = (insn >> 5) & 7; - rt2 = 0; - } - isread = (insn >> 20) & 1; - rt = (insn >> 12) & 0xf; - - ri = get_arm_cp_reginfo(s->cp_regs, - ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2)); - if (ri) { - /* Check access permissions */ - if (!cp_access_ok(s->current_el, ri, isread)) { - return 1; - } - - if (ri->accessfn || - (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) { - /* Emit code to perform further access permissions checks at - * runtime; this may result in an exception. - * Note that on XScale all cp0..c13 registers do an access check - * call in order to handle c15_cpar. - */ - TCGv_ptr tmpptr; - TCGv_i32 tcg_syn; - uint32_t syndrome; - - /* Note that since we are an implementation which takes an - * exception on a trapped conditional instruction only if the - * instruction passes its condition code check, we can take - * advantage of the clause in the ARM ARM that allows us to set - * the COND field in the instruction to 0xE in all cases. - * We could fish the actual condition out of the insn (ARM) - * or the condexec bits (Thumb) but it isn't necessary. - */ - switch (cpnum) { - case 14: - if (is64) { - syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2, - isread, s->thumb); - } else { - syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm, - rt, isread, s->thumb); - } - break; - case 15: - if (is64) { - syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2, - isread, s->thumb); - } else { - syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm, - rt, isread, s->thumb); - } - break; - default: - /* ARMv8 defines that only coprocessors 14 and 15 exist, - * so this can only happen if this is an ARMv7 or earlier CPU, - * in which case the syndrome information won't actually be - * guest visible. - */ - assert(!arm_dc_feature(s, ARM_FEATURE_V8)); - syndrome = syn_uncategorized(); - break; - } - - gen_set_condexec(s); - gen_set_pc_im(s, s->pc - 4); - tmpptr = tcg_const_ptr(ri); - tcg_syn = tcg_const_i32(syndrome); - gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn); - tcg_temp_free_ptr(tmpptr); - tcg_temp_free_i32(tcg_syn); - } - - /* Handle special cases first */ - switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) { - case ARM_CP_NOP: - return 0; - case ARM_CP_WFI: - if (isread) { - return 1; - } - gen_set_pc_im(s, s->pc); - s->is_jmp = DISAS_WFI; - return 0; - default: - break; - } - - if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) { - gen_io_start(); - } - - if (isread) { - /* Read */ - if (is64) { - TCGv_i64 tmp64; - TCGv_i32 tmp; - if (ri->type & ARM_CP_CONST) { - tmp64 = tcg_const_i64(ri->resetvalue); - } else if (ri->readfn) { - TCGv_ptr tmpptr; - tmp64 = tcg_temp_new_i64(); - tmpptr = tcg_const_ptr(ri); - gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr); - tcg_temp_free_ptr(tmpptr); - } else { - tmp64 = tcg_temp_new_i64(); - tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset); - } - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, tmp64); - store_reg(s, rt, tmp); - tcg_gen_shri_i64(tmp64, tmp64, 32); - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, tmp64); - tcg_temp_free_i64(tmp64); - store_reg(s, rt2, tmp); - } else { - TCGv_i32 tmp; - if (ri->type & ARM_CP_CONST) { - tmp = tcg_const_i32(ri->resetvalue); - } else if (ri->readfn) { - TCGv_ptr tmpptr; - tmp = tcg_temp_new_i32(); - tmpptr = tcg_const_ptr(ri); - gen_helper_get_cp_reg(tmp, cpu_env, tmpptr); - tcg_temp_free_ptr(tmpptr); - } else { - tmp = load_cpu_offset(ri->fieldoffset); - } - if (rt == 15) { - /* Destination register of r15 for 32 bit loads sets - * the condition codes from the high 4 bits of the value - */ - gen_set_nzcv(tmp); - tcg_temp_free_i32(tmp); - } else { - store_reg(s, rt, tmp); - } - } - } else { - /* Write */ - if (ri->type & ARM_CP_CONST) { - /* If not forbidden by access permissions, treat as WI */ - return 0; - } - - if (is64) { - TCGv_i32 tmplo, tmphi; - TCGv_i64 tmp64 = tcg_temp_new_i64(); - tmplo = load_reg(s, rt); - tmphi = load_reg(s, rt2); - tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi); - tcg_temp_free_i32(tmplo); - tcg_temp_free_i32(tmphi); - if (ri->writefn) { - TCGv_ptr tmpptr = tcg_const_ptr(ri); - gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64); - tcg_temp_free_ptr(tmpptr); - } else { - tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset); - } - tcg_temp_free_i64(tmp64); - } else { - if (ri->writefn) { - TCGv_i32 tmp; - TCGv_ptr tmpptr; - tmp = load_reg(s, rt); - tmpptr = tcg_const_ptr(ri); - gen_helper_set_cp_reg(cpu_env, tmpptr, tmp); - tcg_temp_free_ptr(tmpptr); - tcg_temp_free_i32(tmp); - } else { - TCGv_i32 tmp = load_reg(s, rt); - store_cpu_offset(tmp, ri->fieldoffset); - } - } - } - - if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) { - /* I/O operations must end the TB here (whether read or write) */ - gen_io_end(); - gen_lookup_tb(s); - } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) { - /* We default to ending the TB on a coprocessor register write, - * but allow this to be suppressed by the register definition - * (usually only necessary to work around guest bugs). - */ - gen_lookup_tb(s); - } - - return 0; - } - - /* Unknown register; this might be a guest error or a QEMU - * unimplemented feature. - */ - if (is64) { - qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 " - "64 bit system register cp:%d opc1: %d crm:%d " - "(%s)\n", - isread ? "read" : "write", cpnum, opc1, crm, - s->ns ? "non-secure" : "secure"); - } else { - qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 " - "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d " - "(%s)\n", - isread ? "read" : "write", cpnum, opc1, crn, crm, opc2, - s->ns ? "non-secure" : "secure"); - } - - return 1; -} - - -/* Store a 64-bit value to a register pair. Clobbers val. */ -static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val) -{ - TCGv_i32 tmp; - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, val); - store_reg(s, rlow, tmp); - tmp = tcg_temp_new_i32(); - tcg_gen_shri_i64(val, val, 32); - tcg_gen_extrl_i64_i32(tmp, val); - store_reg(s, rhigh, tmp); -} - -/* load a 32-bit value from a register and perform a 64-bit accumulate. */ -static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow) -{ - TCGv_i64 tmp; - TCGv_i32 tmp2; - - /* Load value and extend to 64 bits. */ - tmp = tcg_temp_new_i64(); - tmp2 = load_reg(s, rlow); - tcg_gen_extu_i32_i64(tmp, tmp2); - tcg_temp_free_i32(tmp2); - tcg_gen_add_i64(val, val, tmp); - tcg_temp_free_i64(tmp); -} - -/* load and add a 64-bit value from a register pair. */ -static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh) -{ - TCGv_i64 tmp; - TCGv_i32 tmpl; - TCGv_i32 tmph; - - /* Load 64-bit value rd:rn. */ - tmpl = load_reg(s, rlow); - tmph = load_reg(s, rhigh); - tmp = tcg_temp_new_i64(); - tcg_gen_concat_i32_i64(tmp, tmpl, tmph); - tcg_temp_free_i32(tmpl); - tcg_temp_free_i32(tmph); - tcg_gen_add_i64(val, val, tmp); - tcg_temp_free_i64(tmp); -} - -/* Set N and Z flags from hi|lo. */ -static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi) -{ - tcg_gen_mov_i32(cpu_NF, hi); - tcg_gen_or_i32(cpu_ZF, lo, hi); -} - -/* Load/Store exclusive instructions are implemented by remembering - the value/address loaded, and seeing if these are the same - when the store is performed. This should be sufficient to implement - the architecturally mandated semantics, and avoids having to monitor - regular stores. - - In system emulation mode only one CPU will be running at once, so - this sequence is effectively atomic. In user emulation mode we - throw an exception and handle the atomic operation elsewhere. */ -static void gen_load_exclusive(DisasContext *s, int rt, int rt2, - TCGv_i32 addr, int size) -{ - TCGv_i32 tmp = tcg_temp_new_i32(); - - s->is_ldex = true; - - switch (size) { - case 0: - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - break; - case 1: - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - case 2: - case 3: - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - - if (size == 3) { - TCGv_i32 tmp2 = tcg_temp_new_i32(); - TCGv_i32 tmp3 = tcg_temp_new_i32(); - - tcg_gen_addi_i32(tmp2, addr, 4); - gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s)); - tcg_temp_free_i32(tmp2); - tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3); - store_reg(s, rt2, tmp3); - } else { - tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp); - } - - store_reg(s, rt, tmp); - tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr); -} - -static void gen_clrex(DisasContext *s) -{ - tcg_gen_movi_i64(cpu_exclusive_addr, -1); -} - -#ifdef CONFIG_USER_ONLY -static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, - TCGv_i32 addr, int size) -{ - tcg_gen_extu_i32_i64(cpu_exclusive_test, addr); - tcg_gen_movi_i32(cpu_exclusive_info, - size | (rd << 4) | (rt << 8) | (rt2 << 12)); - gen_exception_internal_insn(s, 4, EXCP_STREX); -} -#else -static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, - TCGv_i32 addr, int size) -{ - TCGv_i32 tmp; - TCGv_i64 val64, extaddr; - TCGLabel *done_label; - TCGLabel *fail_label; - - /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) { - [addr] = {Rt}; - {Rd} = 0; - } else { - {Rd} = 1; - } */ - fail_label = gen_new_label(); - done_label = gen_new_label(); - extaddr = tcg_temp_new_i64(); - tcg_gen_extu_i32_i64(extaddr, addr); - tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label); - tcg_temp_free_i64(extaddr); - - tmp = tcg_temp_new_i32(); - switch (size) { - case 0: - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - break; - case 1: - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - case 2: - case 3: - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - - val64 = tcg_temp_new_i64(); - if (size == 3) { - TCGv_i32 tmp2 = tcg_temp_new_i32(); - TCGv_i32 tmp3 = tcg_temp_new_i32(); - tcg_gen_addi_i32(tmp2, addr, 4); - gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s)); - tcg_temp_free_i32(tmp2); - tcg_gen_concat_i32_i64(val64, tmp, tmp3); - tcg_temp_free_i32(tmp3); - } else { - tcg_gen_extu_i32_i64(val64, tmp); - } - tcg_temp_free_i32(tmp); - - tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label); - tcg_temp_free_i64(val64); - - tmp = load_reg(s, rt); - switch (size) { - case 0: - gen_aa32_st8(tmp, addr, get_mem_index(s)); - break; - case 1: - gen_aa32_st16(tmp, addr, get_mem_index(s)); - break; - case 2: - case 3: - gen_aa32_st32(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - tcg_temp_free_i32(tmp); - if (size == 3) { - tcg_gen_addi_i32(addr, addr, 4); - tmp = load_reg(s, rt2); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_gen_movi_i32(cpu_R[rd], 0); - tcg_gen_br(done_label); - gen_set_label(fail_label); - tcg_gen_movi_i32(cpu_R[rd], 1); - gen_set_label(done_label); - tcg_gen_movi_i64(cpu_exclusive_addr, -1); -} -#endif - -/* gen_srs: - * @env: CPUARMState - * @s: DisasContext - * @mode: mode field from insn (which stack to store to) - * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn - * @writeback: true if writeback bit set - * - * Generate code for the SRS (Store Return State) insn. - */ -static void gen_srs(DisasContext *s, - uint32_t mode, uint32_t amode, bool writeback) -{ - int32_t offset; - TCGv_i32 addr = tcg_temp_new_i32(); - TCGv_i32 tmp = tcg_const_i32(mode); - gen_helper_get_r13_banked(addr, cpu_env, tmp); - tcg_temp_free_i32(tmp); - switch (amode) { - case 0: /* DA */ - offset = -4; - break; - case 1: /* IA */ - offset = 0; - break; - case 2: /* DB */ - offset = -8; - break; - case 3: /* IB */ - offset = 4; - break; - default: - abort(); - } - tcg_gen_addi_i32(addr, addr, offset); - tmp = load_reg(s, 14); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - tmp = load_cpu_field(spsr); - tcg_gen_addi_i32(addr, addr, 4); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - if (writeback) { - switch (amode) { - case 0: - offset = -8; - break; - case 1: - offset = 4; - break; - case 2: - offset = -4; - break; - case 3: - offset = 0; - break; - default: - abort(); - } - tcg_gen_addi_i32(addr, addr, offset); - tmp = tcg_const_i32(mode); - gen_helper_set_r13_banked(cpu_env, tmp, addr); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); -} - -static void disas_arm_insn(DisasContext *s, unsigned int insn) -{ - unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh; - TCGv_i32 tmp; - TCGv_i32 tmp2; - TCGv_i32 tmp3; - TCGv_i32 addr; - TCGv_i64 tmp64; - - /* M variants do not implement ARM mode. */ - if (arm_dc_feature(s, ARM_FEATURE_M)) { - goto illegal_op; - } - cond = insn >> 28; - if (cond == 0xf){ - /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we - * choose to UNDEF. In ARMv5 and above the space is used - * for miscellaneous unconditional instructions. - */ - ARCH(5); - - /* Unconditional instructions. */ - if (((insn >> 25) & 7) == 1) { - /* NEON Data processing. */ - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { - goto illegal_op; - } - - if (disas_neon_data_insn(s, insn)) { - goto illegal_op; - } - return; - } - if ((insn & 0x0f100000) == 0x04000000) { - /* NEON load/store. */ - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { - goto illegal_op; - } - - if (disas_neon_ls_insn(s, insn)) { - goto illegal_op; - } - return; - } - if ((insn & 0x0f000e10) == 0x0e000a00) { - /* VFP. */ - if (disas_vfp_insn(s, insn)) { - goto illegal_op; - } - return; - } - if (((insn & 0x0f30f000) == 0x0510f000) || - ((insn & 0x0f30f010) == 0x0710f000)) { - if ((insn & (1 << 22)) == 0) { - /* PLDW; v7MP */ - if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) { - goto illegal_op; - } - } - /* Otherwise PLD; v5TE+ */ - ARCH(5TE); - return; - } - if (((insn & 0x0f70f000) == 0x0450f000) || - ((insn & 0x0f70f010) == 0x0650f000)) { - ARCH(7); - return; /* PLI; V7 */ - } - if (((insn & 0x0f700000) == 0x04100000) || - ((insn & 0x0f700010) == 0x06100000)) { - if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) { - goto illegal_op; - } - return; /* v7MP: Unallocated memory hint: must NOP */ - } - - if ((insn & 0x0ffffdff) == 0x01010000) { - ARCH(6); - /* setend */ - if (((insn >> 9) & 1) != s->bswap_code) { - /* Dynamic endianness switching not implemented. */ - qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n"); - goto illegal_op; - } - return; - } else if ((insn & 0x0fffff00) == 0x057ff000) { - switch ((insn >> 4) & 0xf) { - case 1: /* clrex */ - ARCH(6K); - gen_clrex(s); - return; - case 4: /* dsb */ - case 5: /* dmb */ - ARCH(7); - /* We don't emulate caches so these are a no-op. */ - return; - case 6: /* isb */ - /* We need to break the TB after this insn to execute - * self-modifying code correctly and also to take - * any pending interrupts immediately. - */ - gen_lookup_tb(s); - return; - default: - goto illegal_op; - } - } else if ((insn & 0x0e5fffe0) == 0x084d0500) { - /* srs */ - if (IS_USER(s)) { - goto illegal_op; - } - ARCH(6); - gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21)); - return; - } else if ((insn & 0x0e50ffe0) == 0x08100a00) { - /* rfe */ - int32_t offset; - if (IS_USER(s)) - goto illegal_op; - ARCH(6); - rn = (insn >> 16) & 0xf; - addr = load_reg(s, rn); - i = (insn >> 23) & 3; - switch (i) { - case 0: offset = -4; break; /* DA */ - case 1: offset = 0; break; /* IA */ - case 2: offset = -8; break; /* DB */ - case 3: offset = 4; break; /* IB */ - default: abort(); - } - if (offset) - tcg_gen_addi_i32(addr, addr, offset); - /* Load PC into tmp and CPSR into tmp2. */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - tcg_gen_addi_i32(addr, addr, 4); - tmp2 = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); - if (insn & (1 << 21)) { - /* Base writeback. */ - switch (i) { - case 0: offset = -8; break; - case 1: offset = 4; break; - case 2: offset = -4; break; - case 3: offset = 0; break; - default: abort(); - } - if (offset) - tcg_gen_addi_i32(addr, addr, offset); - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - gen_rfe(s, tmp, tmp2); - return; - } else if ((insn & 0x0e000000) == 0x0a000000) { - /* branch link and change to thumb (blx ) */ - int32_t offset; - - val = (uint32_t)s->pc; - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - store_reg(s, 14, tmp); - /* Sign-extend the 24-bit offset */ - offset = (((int32_t)insn) << 8) >> 8; - /* offset * 4 + bit24 * 2 + (thumb bit) */ - val += (offset << 2) | ((insn >> 23) & 2) | 1; - /* pipeline offset */ - val += 4; - /* protected by ARCH(5); above, near the start of uncond block */ - gen_bx_im(s, val); - return; - } else if ((insn & 0x0e000f00) == 0x0c000100) { - if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) { - /* iWMMXt register transfer. */ - if (extract32(s->c15_cpar, 1, 1)) { - if (!disas_iwmmxt_insn(s, insn)) { - return; - } - } - } - } else if ((insn & 0x0fe00000) == 0x0c400000) { - /* Coprocessor double register transfer. */ - ARCH(5TE); - } else if ((insn & 0x0f000010) == 0x0e000010) { - /* Additional coprocessor register transfer. */ - } else if ((insn & 0x0ff10020) == 0x01000000) { - uint32_t mask; - uint32_t val; - /* cps (privileged) */ - if (IS_USER(s)) - return; - mask = val = 0; - if (insn & (1 << 19)) { - if (insn & (1 << 8)) - mask |= CPSR_A; - if (insn & (1 << 7)) - mask |= CPSR_I; - if (insn & (1 << 6)) - mask |= CPSR_F; - if (insn & (1 << 18)) - val |= mask; - } - if (insn & (1 << 17)) { - mask |= CPSR_M; - val |= (insn & 0x1f); - } - if (mask) { - gen_set_psr_im(s, mask, 0, val); - } - return; - } - goto illegal_op; - } - if (cond != 0xe) { - /* if not always execute, we generate a conditional jump to - next instruction */ - s->condlabel = gen_new_label(); - arm_gen_test_cc(cond ^ 1, s->condlabel); - s->condjmp = 1; - } - if ((insn & 0x0f900000) == 0x03000000) { - if ((insn & (1 << 21)) == 0) { - ARCH(6T2); - rd = (insn >> 12) & 0xf; - val = ((insn >> 4) & 0xf000) | (insn & 0xfff); - if ((insn & (1 << 22)) == 0) { - /* MOVW */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - } else { - /* MOVT */ - tmp = load_reg(s, rd); - tcg_gen_ext16u_i32(tmp, tmp); - tcg_gen_ori_i32(tmp, tmp, val << 16); - } - store_reg(s, rd, tmp); - } else { - if (((insn >> 12) & 0xf) != 0xf) - goto illegal_op; - if (((insn >> 16) & 0xf) == 0) { - gen_nop_hint(s, insn & 0xff); - } else { - /* CPSR = immediate */ - val = insn & 0xff; - shift = ((insn >> 8) & 0xf) * 2; - if (shift) - val = (val >> shift) | (val << (32 - shift)); - i = ((insn & (1 << 22)) != 0); - if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i), - i, val)) { - goto illegal_op; - } - } - } - } else if ((insn & 0x0f900000) == 0x01000000 - && (insn & 0x00000090) != 0x00000090) { - /* miscellaneous instructions */ - op1 = (insn >> 21) & 3; - sh = (insn >> 4) & 0xf; - rm = insn & 0xf; - switch (sh) { - case 0x0: /* move program status register */ - if (op1 & 1) { - /* PSR = reg */ - tmp = load_reg(s, rm); - i = ((op1 & 2) != 0); - if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp)) - goto illegal_op; - } else { - /* reg = PSR */ - rd = (insn >> 12) & 0xf; - if (op1 & 2) { - if (IS_USER(s)) - goto illegal_op; - tmp = load_cpu_field(spsr); - } else { - tmp = tcg_temp_new_i32(); - gen_helper_cpsr_read(tmp, cpu_env); - } - store_reg(s, rd, tmp); - } - break; - case 0x1: - if (op1 == 1) { - /* branch/exchange thumb (bx). */ - ARCH(4T); - tmp = load_reg(s, rm); - gen_bx(s, tmp); - } else if (op1 == 3) { - /* clz */ - ARCH(5); - rd = (insn >> 12) & 0xf; - tmp = load_reg(s, rm); - gen_helper_clz(tmp, tmp); - store_reg(s, rd, tmp); - } else { - goto illegal_op; - } - break; - case 0x2: - if (op1 == 1) { - ARCH(5J); /* bxj */ - /* Trivial implementation equivalent to bx. */ - tmp = load_reg(s, rm); - gen_bx(s, tmp); - } else { - goto illegal_op; - } - break; - case 0x3: - if (op1 != 1) - goto illegal_op; - - ARCH(5); - /* branch link/exchange thumb (blx) */ - tmp = load_reg(s, rm); - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, s->pc); - store_reg(s, 14, tmp2); - gen_bx(s, tmp); - break; - case 0x4: - { - /* crc32/crc32c */ - uint32_t c = extract32(insn, 8, 4); - - /* Check this CPU supports ARMv8 CRC instructions. - * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED. - * Bits 8, 10 and 11 should be zero. - */ - if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 || - (c & 0xd) != 0) { - goto illegal_op; - } - - rn = extract32(insn, 16, 4); - rd = extract32(insn, 12, 4); - - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - if (op1 == 0) { - tcg_gen_andi_i32(tmp2, tmp2, 0xff); - } else if (op1 == 1) { - tcg_gen_andi_i32(tmp2, tmp2, 0xffff); - } - tmp3 = tcg_const_i32(1 << op1); - if (c & 0x2) { - gen_helper_crc32c(tmp, tmp, tmp2, tmp3); - } else { - gen_helper_crc32(tmp, tmp, tmp2, tmp3); - } - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp3); - store_reg(s, rd, tmp); - break; - } - case 0x5: /* saturating add/subtract */ - ARCH(5TE); - rd = (insn >> 12) & 0xf; - rn = (insn >> 16) & 0xf; - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rn); - if (op1 & 2) - gen_helper_double_saturate(tmp2, cpu_env, tmp2); - if (op1 & 1) - gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2); - else - gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; - case 7: - { - int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4); - switch (op1) { - case 1: - /* bkpt */ - ARCH(5); - gen_exception_insn(s, 4, EXCP_BKPT, - syn_aa32_bkpt(imm16, false), - default_exception_el(s)); - break; - case 2: - /* Hypervisor call (v7) */ - ARCH(7); - if (IS_USER(s)) { - goto illegal_op; - } - gen_hvc(s, imm16); - break; - case 3: - /* Secure monitor call (v6+) */ - ARCH(6K); - if (IS_USER(s)) { - goto illegal_op; - } - gen_smc(s); - break; - default: - goto illegal_op; - } - break; - } - case 0x8: /* signed multiply */ - case 0xa: - case 0xc: - case 0xe: - ARCH(5TE); - rs = (insn >> 8) & 0xf; - rn = (insn >> 12) & 0xf; - rd = (insn >> 16) & 0xf; - if (op1 == 1) { - /* (32 * 16) >> 16 */ - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - if (sh & 4) - tcg_gen_sari_i32(tmp2, tmp2, 16); - else - gen_sxth(tmp2); - tmp64 = gen_muls_i64_i32(tmp, tmp2); - tcg_gen_shri_i64(tmp64, tmp64, 16); - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, tmp64); - tcg_temp_free_i64(tmp64); - if ((sh & 2) == 0) { - tmp2 = load_reg(s, rn); - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - store_reg(s, rd, tmp); - } else { - /* 16 * 16 */ - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - gen_mulxy(tmp, tmp2, sh & 2, sh & 4); - tcg_temp_free_i32(tmp2); - if (op1 == 2) { - tmp64 = tcg_temp_new_i64(); - tcg_gen_ext_i32_i64(tmp64, tmp); - tcg_temp_free_i32(tmp); - gen_addq(s, tmp64, rn, rd); - gen_storeq_reg(s, rn, rd, tmp64); - tcg_temp_free_i64(tmp64); - } else { - if (op1 == 0) { - tmp2 = load_reg(s, rn); - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - store_reg(s, rd, tmp); - } - } - break; - default: - goto illegal_op; - } - } else if (((insn & 0x0e000000) == 0 && - (insn & 0x00000090) != 0x90) || - ((insn & 0x0e000000) == (1 << 25))) { - int set_cc, logic_cc, shiftop; - - op1 = (insn >> 21) & 0xf; - set_cc = (insn >> 20) & 1; - logic_cc = table_logic_cc[op1] & set_cc; - - /* data processing instruction */ - if (insn & (1 << 25)) { - /* immediate operand */ - val = insn & 0xff; - shift = ((insn >> 8) & 0xf) * 2; - if (shift) { - val = (val >> shift) | (val << (32 - shift)); - } - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, val); - if (logic_cc && shift) { - gen_set_CF_bit31(tmp2); - } - } else { - /* register */ - rm = (insn) & 0xf; - tmp2 = load_reg(s, rm); - shiftop = (insn >> 5) & 3; - if (!(insn & (1 << 4))) { - shift = (insn >> 7) & 0x1f; - gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); - } else { - rs = (insn >> 8) & 0xf; - tmp = load_reg(s, rs); - gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); - } - } - if (op1 != 0x0f && op1 != 0x0d) { - rn = (insn >> 16) & 0xf; - tmp = load_reg(s, rn); - } else { - TCGV_UNUSED_I32(tmp); - } - rd = (insn >> 12) & 0xf; - switch(op1) { - case 0x00: - tcg_gen_and_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x01: - tcg_gen_xor_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x02: - if (set_cc && rd == 15) { - /* SUBS r15, ... is used for exception return. */ - if (IS_USER(s)) { - goto illegal_op; - } - gen_sub_CC(tmp, tmp, tmp2); - gen_exception_return(s, tmp); - } else { - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); - } else { - tcg_gen_sub_i32(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - } - break; - case 0x03: - if (set_cc) { - gen_sub_CC(tmp, tmp2, tmp); - } else { - tcg_gen_sub_i32(tmp, tmp2, tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x04: - if (set_cc) { - gen_add_CC(tmp, tmp, tmp2); - } else { - tcg_gen_add_i32(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - break; - case 0x05: - if (set_cc) { - gen_adc_CC(tmp, tmp, tmp2); - } else { - gen_add_carry(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - break; - case 0x06: - if (set_cc) { - gen_sbc_CC(tmp, tmp, tmp2); - } else { - gen_sub_carry(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - break; - case 0x07: - if (set_cc) { - gen_sbc_CC(tmp, tmp2, tmp); - } else { - gen_sub_carry(tmp, tmp2, tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x08: - if (set_cc) { - tcg_gen_and_i32(tmp, tmp, tmp2); - gen_logic_CC(tmp); - } - tcg_temp_free_i32(tmp); - break; - case 0x09: - if (set_cc) { - tcg_gen_xor_i32(tmp, tmp, tmp2); - gen_logic_CC(tmp); - } - tcg_temp_free_i32(tmp); - break; - case 0x0a: - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp); - break; - case 0x0b: - if (set_cc) { - gen_add_CC(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp); - break; - case 0x0c: - tcg_gen_or_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x0d: - if (logic_cc && rd == 15) { - /* MOVS r15, ... is used for exception return. */ - if (IS_USER(s)) { - goto illegal_op; - } - gen_exception_return(s, tmp2); - } else { - if (logic_cc) { - gen_logic_CC(tmp2); - } - store_reg_bx(s, rd, tmp2); - } - break; - case 0x0e: - tcg_gen_andc_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - default: - case 0x0f: - tcg_gen_not_i32(tmp2, tmp2); - if (logic_cc) { - gen_logic_CC(tmp2); - } - store_reg_bx(s, rd, tmp2); - break; - } - if (op1 != 0x0f && op1 != 0x0d) { - tcg_temp_free_i32(tmp2); - } - } else { - /* other instructions */ - op1 = (insn >> 24) & 0xf; - switch(op1) { - case 0x0: - case 0x1: - /* multiplies, extra load/stores */ - sh = (insn >> 5) & 3; - if (sh == 0) { - if (op1 == 0x0) { - rd = (insn >> 16) & 0xf; - rn = (insn >> 12) & 0xf; - rs = (insn >> 8) & 0xf; - rm = (insn) & 0xf; - op1 = (insn >> 20) & 0xf; - switch (op1) { - case 0: case 1: case 2: case 3: case 6: - /* 32 bit mul */ - tmp = load_reg(s, rs); - tmp2 = load_reg(s, rm); - tcg_gen_mul_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - if (insn & (1 << 22)) { - /* Subtract (mls) */ - ARCH(6T2); - tmp2 = load_reg(s, rn); - tcg_gen_sub_i32(tmp, tmp2, tmp); - tcg_temp_free_i32(tmp2); - } else if (insn & (1 << 21)) { - /* Add */ - tmp2 = load_reg(s, rn); - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - if (insn & (1 << 20)) - gen_logic_CC(tmp); - store_reg(s, rd, tmp); - break; - case 4: - /* 64 bit mul double accumulate (UMAAL) */ - ARCH(6); - tmp = load_reg(s, rs); - tmp2 = load_reg(s, rm); - tmp64 = gen_mulu_i64_i32(tmp, tmp2); - gen_addq_lo(s, tmp64, rn); - gen_addq_lo(s, tmp64, rd); - gen_storeq_reg(s, rn, rd, tmp64); - tcg_temp_free_i64(tmp64); - break; - case 8: case 9: case 10: case 11: - case 12: case 13: case 14: case 15: - /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */ - tmp = load_reg(s, rs); - tmp2 = load_reg(s, rm); - if (insn & (1 << 22)) { - tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2); - } else { - tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2); - } - if (insn & (1 << 21)) { /* mult accumulate */ - TCGv_i32 al = load_reg(s, rn); - TCGv_i32 ah = load_reg(s, rd); - tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah); - tcg_temp_free_i32(al); - tcg_temp_free_i32(ah); - } - if (insn & (1 << 20)) { - gen_logicq_cc(tmp, tmp2); - } - store_reg(s, rn, tmp); - store_reg(s, rd, tmp2); - break; - default: - goto illegal_op; - } - } else { - rn = (insn >> 16) & 0xf; - rd = (insn >> 12) & 0xf; - if (insn & (1 << 23)) { - /* load/store exclusive */ - int op2 = (insn >> 8) & 3; - op1 = (insn >> 21) & 0x3; - - switch (op2) { - case 0: /* lda/stl */ - if (op1 == 1) { - goto illegal_op; - } - ARCH(8); - break; - case 1: /* reserved */ - goto illegal_op; - case 2: /* ldaex/stlex */ - ARCH(8); - break; - case 3: /* ldrex/strex */ - if (op1) { - ARCH(6K); - } else { - ARCH(6); - } - break; - } - - addr = tcg_temp_local_new_i32(); - load_reg_var(s, addr, rn); - - /* Since the emulation does not have barriers, - the acquire/release semantics need no special - handling */ - if (op2 == 0) { - if (insn & (1 << 20)) { - tmp = tcg_temp_new_i32(); - switch (op1) { - case 0: /* lda */ - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - case 2: /* ldab */ - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - break; - case 3: /* ldah */ - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - store_reg(s, rd, tmp); - } else { - rm = insn & 0xf; - tmp = load_reg(s, rm); - switch (op1) { - case 0: /* stl */ - gen_aa32_st32(tmp, addr, get_mem_index(s)); - break; - case 2: /* stlb */ - gen_aa32_st8(tmp, addr, get_mem_index(s)); - break; - case 3: /* stlh */ - gen_aa32_st16(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - tcg_temp_free_i32(tmp); - } - } else if (insn & (1 << 20)) { - switch (op1) { - case 0: /* ldrex */ - gen_load_exclusive(s, rd, 15, addr, 2); - break; - case 1: /* ldrexd */ - gen_load_exclusive(s, rd, rd + 1, addr, 3); - break; - case 2: /* ldrexb */ - gen_load_exclusive(s, rd, 15, addr, 0); - break; - case 3: /* ldrexh */ - gen_load_exclusive(s, rd, 15, addr, 1); - break; - default: - abort(); - } - } else { - rm = insn & 0xf; - switch (op1) { - case 0: /* strex */ - gen_store_exclusive(s, rd, rm, 15, addr, 2); - break; - case 1: /* strexd */ - gen_store_exclusive(s, rd, rm, rm + 1, addr, 3); - break; - case 2: /* strexb */ - gen_store_exclusive(s, rd, rm, 15, addr, 0); - break; - case 3: /* strexh */ - gen_store_exclusive(s, rd, rm, 15, addr, 1); - break; - default: - abort(); - } - } - tcg_temp_free_i32(addr); - } else { - /* SWP instruction */ - rm = (insn) & 0xf; - - /* ??? This is not really atomic. However we know - we never have multiple CPUs running in parallel, - so it is good enough. */ - addr = load_reg(s, rn); - tmp = load_reg(s, rm); - tmp2 = tcg_temp_new_i32(); - if (insn & (1 << 22)) { - gen_aa32_ld8u(tmp2, addr, get_mem_index(s)); - gen_aa32_st8(tmp, addr, get_mem_index(s)); - } else { - gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - } - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(addr); - store_reg(s, rd, tmp2); - } - } - } else { - int address_offset; - bool load = insn & (1 << 20); - bool doubleword = false; - /* Misc load/store */ - rn = (insn >> 16) & 0xf; - rd = (insn >> 12) & 0xf; - - if (!load && (sh & 2)) { - /* doubleword */ - ARCH(5TE); - if (rd & 1) { - /* UNPREDICTABLE; we choose to UNDEF */ - goto illegal_op; - } - load = (sh & 1) == 0; - doubleword = true; - } - - addr = load_reg(s, rn); - if (insn & (1 << 24)) - gen_add_datah_offset(s, insn, 0, addr); - address_offset = 0; - - if (doubleword) { - if (!load) { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - tcg_gen_addi_i32(addr, addr, 4); - tmp = load_reg(s, rd + 1); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } else { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - tcg_gen_addi_i32(addr, addr, 4); - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - rd++; - } - address_offset = -4; - } else if (load) { - /* load */ - tmp = tcg_temp_new_i32(); - switch (sh) { - case 1: - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - case 2: - gen_aa32_ld8s(tmp, addr, get_mem_index(s)); - break; - default: - case 3: - gen_aa32_ld16s(tmp, addr, get_mem_index(s)); - break; - } - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st16(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - /* Perform base writeback before the loaded value to - ensure correct behavior with overlapping index registers. - ldrd with base writeback is undefined if the - destination and index registers overlap. */ - if (!(insn & (1 << 24))) { - gen_add_datah_offset(s, insn, address_offset, addr); - store_reg(s, rn, addr); - } else if (insn & (1 << 21)) { - if (address_offset) - tcg_gen_addi_i32(addr, addr, address_offset); - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - if (load) { - /* Complete the load. */ - store_reg(s, rd, tmp); - } - } - break; - case 0x4: - case 0x5: - goto do_ldst; - case 0x6: - case 0x7: - if (insn & (1 << 4)) { - ARCH(6); - /* Armv6 Media instructions. */ - rm = insn & 0xf; - rn = (insn >> 16) & 0xf; - rd = (insn >> 12) & 0xf; - rs = (insn >> 8) & 0xf; - switch ((insn >> 23) & 3) { - case 0: /* Parallel add/subtract. */ - op1 = (insn >> 20) & 7; - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - sh = (insn >> 5) & 7; - if ((op1 & 3) == 0 || sh == 5 || sh == 6) - goto illegal_op; - gen_arm_parallel_addsub(op1, sh, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; - case 1: - if ((insn & 0x00700020) == 0) { - /* Halfword pack. */ - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - shift = (insn >> 7) & 0x1f; - if (insn & (1 << 6)) { - /* pkhtb */ - if (shift == 0) - shift = 31; - tcg_gen_sari_i32(tmp2, tmp2, shift); - tcg_gen_andi_i32(tmp, tmp, 0xffff0000); - tcg_gen_ext16u_i32(tmp2, tmp2); - } else { - /* pkhbt */ - if (shift) - tcg_gen_shli_i32(tmp2, tmp2, shift); - tcg_gen_ext16u_i32(tmp, tmp); - tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); - } - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else if ((insn & 0x00200020) == 0x00200000) { - /* [us]sat */ - tmp = load_reg(s, rm); - shift = (insn >> 7) & 0x1f; - if (insn & (1 << 6)) { - if (shift == 0) - shift = 31; - tcg_gen_sari_i32(tmp, tmp, shift); - } else { - tcg_gen_shli_i32(tmp, tmp, shift); - } - sh = (insn >> 16) & 0x1f; - tmp2 = tcg_const_i32(sh); - if (insn & (1 << 22)) - gen_helper_usat(tmp, cpu_env, tmp, tmp2); - else - gen_helper_ssat(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else if ((insn & 0x00300fe0) == 0x00200f20) { - /* [us]sat16 */ - tmp = load_reg(s, rm); - sh = (insn >> 16) & 0x1f; - tmp2 = tcg_const_i32(sh); - if (insn & (1 << 22)) - gen_helper_usat16(tmp, cpu_env, tmp, tmp2); - else - gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else if ((insn & 0x00700fe0) == 0x00000fa0) { - /* Select bytes. */ - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - tmp3 = tcg_temp_new_i32(); - tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); - gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); - tcg_temp_free_i32(tmp3); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else if ((insn & 0x000003e0) == 0x00000060) { - tmp = load_reg(s, rm); - shift = (insn >> 10) & 3; - /* ??? In many cases it's not necessary to do a - rotate, a shift is sufficient. */ - if (shift != 0) - tcg_gen_rotri_i32(tmp, tmp, shift * 8); - op1 = (insn >> 20) & 7; - switch (op1) { - case 0: gen_sxtb16(tmp); break; - case 2: gen_sxtb(tmp); break; - case 3: gen_sxth(tmp); break; - case 4: gen_uxtb16(tmp); break; - case 6: gen_uxtb(tmp); break; - case 7: gen_uxth(tmp); break; - default: goto illegal_op; - } - if (rn != 15) { - tmp2 = load_reg(s, rn); - if ((op1 & 3) == 0) { - gen_add16(tmp, tmp2); - } else { - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - } - store_reg(s, rd, tmp); - } else if ((insn & 0x003f0f60) == 0x003f0f20) { - /* rev */ - tmp = load_reg(s, rm); - if (insn & (1 << 22)) { - if (insn & (1 << 7)) { - gen_revsh(tmp); - } else { - ARCH(6T2); - gen_helper_rbit(tmp, tmp); - } - } else { - if (insn & (1 << 7)) - gen_rev16(tmp); - else - tcg_gen_bswap32_i32(tmp, tmp); - } - store_reg(s, rd, tmp); - } else { - goto illegal_op; - } - break; - case 2: /* Multiplies (Type 3). */ - switch ((insn >> 20) & 0x7) { - case 5: - if (((insn >> 6) ^ (insn >> 7)) & 1) { - /* op2 not 00x or 11x : UNDEF */ - goto illegal_op; - } - /* Signed multiply most significant [accumulate]. - (SMMUL, SMMLA, SMMLS) */ - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - tmp64 = gen_muls_i64_i32(tmp, tmp2); - - if (rd != 15) { - tmp = load_reg(s, rd); - if (insn & (1 << 6)) { - tmp64 = gen_subq_msw(tmp64, tmp); - } else { - tmp64 = gen_addq_msw(tmp64, tmp); - } - } - if (insn & (1 << 5)) { - tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); - } - tcg_gen_shri_i64(tmp64, tmp64, 32); - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, tmp64); - tcg_temp_free_i64(tmp64); - store_reg(s, rn, tmp); - break; - case 0: - case 4: - /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */ - if (insn & (1 << 7)) { - goto illegal_op; - } - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - if (insn & (1 << 5)) - gen_swap_half(tmp2); - gen_smul_dual(tmp, tmp2); - if (insn & (1 << 22)) { - /* smlald, smlsld */ - TCGv_i64 tmp64_2; - - tmp64 = tcg_temp_new_i64(); - tmp64_2 = tcg_temp_new_i64(); - tcg_gen_ext_i32_i64(tmp64, tmp); - tcg_gen_ext_i32_i64(tmp64_2, tmp2); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - if (insn & (1 << 6)) { - tcg_gen_sub_i64(tmp64, tmp64, tmp64_2); - } else { - tcg_gen_add_i64(tmp64, tmp64, tmp64_2); - } - tcg_temp_free_i64(tmp64_2); - gen_addq(s, tmp64, rd, rn); - gen_storeq_reg(s, rd, rn, tmp64); - tcg_temp_free_i64(tmp64); - } else { - /* smuad, smusd, smlad, smlsd */ - if (insn & (1 << 6)) { - /* This subtraction cannot overflow. */ - tcg_gen_sub_i32(tmp, tmp, tmp2); - } else { - /* This addition cannot overflow 32 bits; - * however it may overflow considered as a - * signed operation, in which case we must set - * the Q flag. - */ - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - } - tcg_temp_free_i32(tmp2); - if (rd != 15) - { - tmp2 = load_reg(s, rd); - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - store_reg(s, rn, tmp); - } - break; - case 1: - case 3: - /* SDIV, UDIV */ - if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) { - goto illegal_op; - } - if (((insn >> 5) & 7) || (rd != 15)) { - goto illegal_op; - } - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - if (insn & (1 << 21)) { - gen_helper_udiv(tmp, tmp, tmp2); - } else { - gen_helper_sdiv(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp2); - store_reg(s, rn, tmp); - break; - default: - goto illegal_op; - } - break; - case 3: - op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7); - switch (op1) { - case 0: /* Unsigned sum of absolute differences. */ - ARCH(6); - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - gen_helper_usad8(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - if (rd != 15) { - tmp2 = load_reg(s, rd); - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - store_reg(s, rn, tmp); - break; - case 0x20: case 0x24: case 0x28: case 0x2c: - /* Bitfield insert/clear. */ - ARCH(6T2); - shift = (insn >> 7) & 0x1f; - i = (insn >> 16) & 0x1f; - if (i < shift) { - /* UNPREDICTABLE; we choose to UNDEF */ - goto illegal_op; - } - i = i + 1 - shift; - if (rm == 15) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else { - tmp = load_reg(s, rm); - } - if (i != 32) { - tmp2 = load_reg(s, rd); - tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i); - tcg_temp_free_i32(tmp2); - } - store_reg(s, rd, tmp); - break; - case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ - case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ - ARCH(6T2); - tmp = load_reg(s, rm); - shift = (insn >> 7) & 0x1f; - i = ((insn >> 16) & 0x1f) + 1; - if (shift + i > 32) - goto illegal_op; - if (i < 32) { - if (op1 & 0x20) { - gen_ubfx(tmp, shift, (1u << i) - 1); - } else { - gen_sbfx(tmp, shift, i); - } - } - store_reg(s, rd, tmp); - break; - default: - goto illegal_op; - } - break; - } - break; - } - do_ldst: - /* Check for undefined extension instructions - * per the ARM Bible IE: - * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx - */ - sh = (0xf << 20) | (0xf << 4); - if (op1 == 0x7 && ((insn & sh) == sh)) - { - goto illegal_op; - } - /* load/store byte/word */ - rn = (insn >> 16) & 0xf; - rd = (insn >> 12) & 0xf; - tmp2 = load_reg(s, rn); - if ((insn & 0x01200000) == 0x00200000) { - /* ldrt/strt */ - i = get_a32_user_mem_index(s); - } else { - i = get_mem_index(s); - } - if (insn & (1 << 24)) - gen_add_data_offset(s, insn, tmp2); - if (insn & (1 << 20)) { - /* load */ - tmp = tcg_temp_new_i32(); - if (insn & (1 << 22)) { - gen_aa32_ld8u(tmp, tmp2, i); - } else { - gen_aa32_ld32u(tmp, tmp2, i); - } - } else { - /* store */ - tmp = load_reg(s, rd); - if (insn & (1 << 22)) { - gen_aa32_st8(tmp, tmp2, i); - } else { - gen_aa32_st32(tmp, tmp2, i); - } - tcg_temp_free_i32(tmp); - } - if (!(insn & (1 << 24))) { - gen_add_data_offset(s, insn, tmp2); - store_reg(s, rn, tmp2); - } else if (insn & (1 << 21)) { - store_reg(s, rn, tmp2); - } else { - tcg_temp_free_i32(tmp2); - } - if (insn & (1 << 20)) { - /* Complete the load. */ - store_reg_from_load(s, rd, tmp); - } - break; - case 0x08: - case 0x09: - { - int j, n, loaded_base; - bool exc_return = false; - bool is_load = extract32(insn, 20, 1); - bool user = false; - TCGv_i32 loaded_var; - /* load/store multiple words */ - /* XXX: store correct base if write back */ - if (insn & (1 << 22)) { - /* LDM (user), LDM (exception return) and STM (user) */ - if (IS_USER(s)) - goto illegal_op; /* only usable in supervisor mode */ - - if (is_load && extract32(insn, 15, 1)) { - exc_return = true; - } else { - user = true; - } - } - rn = (insn >> 16) & 0xf; - addr = load_reg(s, rn); - - /* compute total size */ - loaded_base = 0; - TCGV_UNUSED_I32(loaded_var); - n = 0; - for(i=0;i<16;i++) { - if (insn & (1 << i)) - n++; - } - /* XXX: test invalid n == 0 case ? */ - if (insn & (1 << 23)) { - if (insn & (1 << 24)) { - /* pre increment */ - tcg_gen_addi_i32(addr, addr, 4); - } else { - /* post increment */ - } - } else { - if (insn & (1 << 24)) { - /* pre decrement */ - tcg_gen_addi_i32(addr, addr, -(n * 4)); - } else { - /* post decrement */ - if (n != 1) - tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); - } - } - j = 0; - for(i=0;i<16;i++) { - if (insn & (1 << i)) { - if (is_load) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - if (user) { - tmp2 = tcg_const_i32(i); - gen_helper_set_user_reg(cpu_env, tmp2, tmp); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - } else if (i == rn) { - loaded_var = tmp; - loaded_base = 1; - } else { - store_reg_from_load(s, i, tmp); - } - } else { - /* store */ - if (i == 15) { - /* special case: r15 = PC + 8 */ - val = (long)s->pc + 4; - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - } else if (user) { - tmp = tcg_temp_new_i32(); - tmp2 = tcg_const_i32(i); - gen_helper_get_user_reg(tmp, cpu_env, tmp2); - tcg_temp_free_i32(tmp2); - } else { - tmp = load_reg(s, i); - } - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - j++; - /* no need to add after the last transfer */ - if (j != n) - tcg_gen_addi_i32(addr, addr, 4); - } - } - if (insn & (1 << 21)) { - /* write back */ - if (insn & (1 << 23)) { - if (insn & (1 << 24)) { - /* pre increment */ - } else { - /* post increment */ - tcg_gen_addi_i32(addr, addr, 4); - } - } else { - if (insn & (1 << 24)) { - /* pre decrement */ - if (n != 1) - tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); - } else { - /* post decrement */ - tcg_gen_addi_i32(addr, addr, -(n * 4)); - } - } - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - if (loaded_base) { - store_reg(s, rn, loaded_var); - } - if (exc_return) { - /* Restore CPSR from SPSR. */ - tmp = load_cpu_field(spsr); - gen_set_cpsr(tmp, CPSR_ERET_MASK); - tcg_temp_free_i32(tmp); - s->is_jmp = DISAS_JUMP; - } - } - break; - case 0xa: - case 0xb: - { - int32_t offset; - - /* branch (and link) */ - val = (int32_t)s->pc; - if (insn & (1 << 24)) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - store_reg(s, 14, tmp); - } - offset = sextract32(insn << 2, 0, 26); - val += offset + 4; - gen_jmp(s, val); - } - break; - case 0xc: - case 0xd: - case 0xe: - if (((insn >> 8) & 0xe) == 10) { - /* VFP. */ - if (disas_vfp_insn(s, insn)) { - goto illegal_op; - } - } else if (disas_coproc_insn(s, insn)) { - /* Coprocessor. */ - goto illegal_op; - } - break; - case 0xf: - /* swi */ - gen_set_pc_im(s, s->pc); - s->svc_imm = extract32(insn, 0, 24); - s->is_jmp = DISAS_SWI; - break; - default: - illegal_op: - gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), - default_exception_el(s)); - break; - } - } -} - -/* Return true if this is a Thumb-2 logical op. */ -static int -thumb2_logic_op(int op) -{ - return (op < 8); -} - -/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero - then set condition code flags based on the result of the operation. - If SHIFTER_OUT is nonzero then set the carry flag for logical operations - to the high bit of T1. - Returns zero if the opcode is valid. */ - -static int -gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, - TCGv_i32 t0, TCGv_i32 t1) -{ - int logic_cc; - - logic_cc = 0; - switch (op) { - case 0: /* and */ - tcg_gen_and_i32(t0, t0, t1); - logic_cc = conds; - break; - case 1: /* bic */ - tcg_gen_andc_i32(t0, t0, t1); - logic_cc = conds; - break; - case 2: /* orr */ - tcg_gen_or_i32(t0, t0, t1); - logic_cc = conds; - break; - case 3: /* orn */ - tcg_gen_orc_i32(t0, t0, t1); - logic_cc = conds; - break; - case 4: /* eor */ - tcg_gen_xor_i32(t0, t0, t1); - logic_cc = conds; - break; - case 8: /* add */ - if (conds) - gen_add_CC(t0, t0, t1); - else - tcg_gen_add_i32(t0, t0, t1); - break; - case 10: /* adc */ - if (conds) - gen_adc_CC(t0, t0, t1); - else - gen_adc(t0, t1); - break; - case 11: /* sbc */ - if (conds) { - gen_sbc_CC(t0, t0, t1); - } else { - gen_sub_carry(t0, t0, t1); - } - break; - case 13: /* sub */ - if (conds) - gen_sub_CC(t0, t0, t1); - else - tcg_gen_sub_i32(t0, t0, t1); - break; - case 14: /* rsb */ - if (conds) - gen_sub_CC(t0, t1, t0); - else - tcg_gen_sub_i32(t0, t1, t0); - break; - default: /* 5, 6, 7, 9, 12, 15. */ - return 1; - } - if (logic_cc) { - gen_logic_CC(t0); - if (shifter_out) - gen_set_CF_bit31(t1); - } - return 0; -} - -/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction - is not legal. */ -static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1) -{ - uint32_t insn, imm, shift, offset; - uint32_t rd, rn, rm, rs; - TCGv_i32 tmp; - TCGv_i32 tmp2; - TCGv_i32 tmp3; - TCGv_i32 addr; - TCGv_i64 tmp64; - int op; - int shiftop; - int conds; - int logic_cc; - - if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2) - || arm_dc_feature(s, ARM_FEATURE_M))) { - /* Thumb-1 cores may need to treat bl and blx as a pair of - 16-bit instructions to get correct prefetch abort behavior. */ - insn = insn_hw1; - if ((insn & (1 << 12)) == 0) { - ARCH(5); - /* Second half of blx. */ - offset = ((insn & 0x7ff) << 1); - tmp = load_reg(s, 14); - tcg_gen_addi_i32(tmp, tmp, offset); - tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); - - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, s->pc | 1); - store_reg(s, 14, tmp2); - gen_bx(s, tmp); - return 0; - } - if (insn & (1 << 11)) { - /* Second half of bl. */ - offset = ((insn & 0x7ff) << 1) | 1; - tmp = load_reg(s, 14); - tcg_gen_addi_i32(tmp, tmp, offset); - - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, s->pc | 1); - store_reg(s, 14, tmp2); - gen_bx(s, tmp); - return 0; - } - if ((s->pc & ~TARGET_PAGE_MASK) == 0) { - /* Instruction spans a page boundary. Implement it as two - 16-bit instructions in case the second half causes an - prefetch abort. */ - offset = ((int32_t)insn << 21) >> 9; - tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset); - return 0; - } - /* Fall through to 32-bit decode. */ - } - - insn = arm_lduw_code(env, s->pc, s->bswap_code); - s->pc += 2; - insn |= (uint32_t)insn_hw1 << 16; - - if ((insn & 0xf800e800) != 0xf000e800) { - ARCH(6T2); - } - - rn = (insn >> 16) & 0xf; - rs = (insn >> 12) & 0xf; - rd = (insn >> 8) & 0xf; - rm = insn & 0xf; - switch ((insn >> 25) & 0xf) { - case 0: case 1: case 2: case 3: - /* 16-bit instructions. Should never happen. */ - abort(); - case 4: - if (insn & (1 << 22)) { - /* Other load/store, table branch. */ - if (insn & 0x01200000) { - /* Load/store doubleword. */ - if (rn == 15) { - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~3); - } else { - addr = load_reg(s, rn); - } - offset = (insn & 0xff) * 4; - if ((insn & (1 << 23)) == 0) - offset = -offset; - if (insn & (1 << 24)) { - tcg_gen_addi_i32(addr, addr, offset); - offset = 0; - } - if (insn & (1 << 20)) { - /* ldrd */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - store_reg(s, rs, tmp); - tcg_gen_addi_i32(addr, addr, 4); - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - } else { - /* strd */ - tmp = load_reg(s, rs); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - tcg_gen_addi_i32(addr, addr, 4); - tmp = load_reg(s, rd); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - if (insn & (1 << 21)) { - /* Base writeback. */ - if (rn == 15) - goto illegal_op; - tcg_gen_addi_i32(addr, addr, offset - 4); - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - } else if ((insn & (1 << 23)) == 0) { - /* Load/store exclusive word. */ - addr = tcg_temp_local_new_i32(); - load_reg_var(s, addr, rn); - tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); - if (insn & (1 << 20)) { - gen_load_exclusive(s, rs, 15, addr, 2); - } else { - gen_store_exclusive(s, rd, rs, 15, addr, 2); - } - tcg_temp_free_i32(addr); - } else if ((insn & (7 << 5)) == 0) { - /* Table Branch. */ - if (rn == 15) { - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc); - } else { - addr = load_reg(s, rn); - } - tmp = load_reg(s, rm); - tcg_gen_add_i32(addr, addr, tmp); - if (insn & (1 << 4)) { - /* tbh */ - tcg_gen_add_i32(addr, addr, tmp); - tcg_temp_free_i32(tmp); - tmp = tcg_temp_new_i32(); - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - } else { /* tbb */ - tcg_temp_free_i32(tmp); - tmp = tcg_temp_new_i32(); - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - } - tcg_temp_free_i32(addr); - tcg_gen_shli_i32(tmp, tmp, 1); - tcg_gen_addi_i32(tmp, tmp, s->pc); - store_reg(s, 15, tmp); - } else { - int op2 = (insn >> 6) & 0x3; - op = (insn >> 4) & 0x3; - switch (op2) { - case 0: - goto illegal_op; - case 1: - /* Load/store exclusive byte/halfword/doubleword */ - if (op == 2) { - goto illegal_op; - } - ARCH(7); - break; - case 2: - /* Load-acquire/store-release */ - if (op == 3) { - goto illegal_op; - } - /* Fall through */ - case 3: - /* Load-acquire/store-release exclusive */ - ARCH(8); - break; - } - addr = tcg_temp_local_new_i32(); - load_reg_var(s, addr, rn); - if (!(op2 & 1)) { - if (insn & (1 << 20)) { - tmp = tcg_temp_new_i32(); - switch (op) { - case 0: /* ldab */ - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - break; - case 1: /* ldah */ - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - case 2: /* lda */ - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - store_reg(s, rs, tmp); - } else { - tmp = load_reg(s, rs); - switch (op) { - case 0: /* stlb */ - gen_aa32_st8(tmp, addr, get_mem_index(s)); - break; - case 1: /* stlh */ - gen_aa32_st16(tmp, addr, get_mem_index(s)); - break; - case 2: /* stl */ - gen_aa32_st32(tmp, addr, get_mem_index(s)); - break; - default: - abort(); - } - tcg_temp_free_i32(tmp); - } - } else if (insn & (1 << 20)) { - gen_load_exclusive(s, rs, rd, addr, op); - } else { - gen_store_exclusive(s, rm, rs, rd, addr, op); - } - tcg_temp_free_i32(addr); - } - } else { - /* Load/store multiple, RFE, SRS. */ - if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { - /* RFE, SRS: not available in user mode or on M profile */ - if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) { - goto illegal_op; - } - if (insn & (1 << 20)) { - /* rfe */ - addr = load_reg(s, rn); - if ((insn & (1 << 24)) == 0) - tcg_gen_addi_i32(addr, addr, -8); - /* Load PC into tmp and CPSR into tmp2. */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - tcg_gen_addi_i32(addr, addr, 4); - tmp2 = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); - if (insn & (1 << 21)) { - /* Base writeback. */ - if (insn & (1 << 24)) { - tcg_gen_addi_i32(addr, addr, 4); - } else { - tcg_gen_addi_i32(addr, addr, -4); - } - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - gen_rfe(s, tmp, tmp2); - } else { - /* srs */ - gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2, - insn & (1 << 21)); - } - } else { - int i, loaded_base = 0; - TCGv_i32 loaded_var; - /* Load/store multiple. */ - addr = load_reg(s, rn); - offset = 0; - for (i = 0; i < 16; i++) { - if (insn & (1 << i)) - offset += 4; - } - if (insn & (1 << 24)) { - tcg_gen_addi_i32(addr, addr, -offset); - } - - TCGV_UNUSED_I32(loaded_var); - for (i = 0; i < 16; i++) { - if ((insn & (1 << i)) == 0) - continue; - if (insn & (1 << 20)) { - /* Load. */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - if (i == 15) { - gen_bx(s, tmp); - } else if (i == rn) { - loaded_var = tmp; - loaded_base = 1; - } else { - store_reg(s, i, tmp); - } - } else { - /* Store. */ - tmp = load_reg(s, i); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_gen_addi_i32(addr, addr, 4); - } - if (loaded_base) { - store_reg(s, rn, loaded_var); - } - if (insn & (1 << 21)) { - /* Base register writeback. */ - if (insn & (1 << 24)) { - tcg_gen_addi_i32(addr, addr, -offset); - } - /* Fault if writeback register is in register list. */ - if (insn & (1 << rn)) - goto illegal_op; - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - } - } - break; - case 5: - - op = (insn >> 21) & 0xf; - if (op == 6) { - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - /* Halfword pack. */ - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3); - if (insn & (1 << 5)) { - /* pkhtb */ - if (shift == 0) - shift = 31; - tcg_gen_sari_i32(tmp2, tmp2, shift); - tcg_gen_andi_i32(tmp, tmp, 0xffff0000); - tcg_gen_ext16u_i32(tmp2, tmp2); - } else { - /* pkhbt */ - if (shift) - tcg_gen_shli_i32(tmp2, tmp2, shift); - tcg_gen_ext16u_i32(tmp, tmp); - tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); - } - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else { - /* Data processing register constant shift. */ - if (rn == 15) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else { - tmp = load_reg(s, rn); - } - tmp2 = load_reg(s, rm); - - shiftop = (insn >> 4) & 3; - shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); - conds = (insn & (1 << 20)) != 0; - logic_cc = (conds && thumb2_logic_op(op)); - gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); - if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) - goto illegal_op; - tcg_temp_free_i32(tmp2); - if (rd != 15) { - store_reg(s, rd, tmp); - } else { - tcg_temp_free_i32(tmp); - } - } - break; - case 13: /* Misc data processing. */ - op = ((insn >> 22) & 6) | ((insn >> 7) & 1); - if (op < 4 && (insn & 0xf000) != 0xf000) - goto illegal_op; - switch (op) { - case 0: /* Register controlled shift. */ - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - if ((insn & 0x70) != 0) - goto illegal_op; - op = (insn >> 21) & 3; - logic_cc = (insn & (1 << 20)) != 0; - gen_arm_shift_reg(tmp, op, tmp2, logic_cc); - if (logic_cc) - gen_logic_CC(tmp); - store_reg_bx(s, rd, tmp); - break; - case 1: /* Sign/zero extend. */ - op = (insn >> 20) & 7; - switch (op) { - case 0: /* SXTAH, SXTH */ - case 1: /* UXTAH, UXTH */ - case 4: /* SXTAB, SXTB */ - case 5: /* UXTAB, UXTB */ - break; - case 2: /* SXTAB16, SXTB16 */ - case 3: /* UXTAB16, UXTB16 */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - break; - default: - goto illegal_op; - } - if (rn != 15) { - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - } - tmp = load_reg(s, rm); - shift = (insn >> 4) & 3; - /* ??? In many cases it's not necessary to do a - rotate, a shift is sufficient. */ - if (shift != 0) - tcg_gen_rotri_i32(tmp, tmp, shift * 8); - op = (insn >> 20) & 7; - switch (op) { - case 0: gen_sxth(tmp); break; - case 1: gen_uxth(tmp); break; - case 2: gen_sxtb16(tmp); break; - case 3: gen_uxtb16(tmp); break; - case 4: gen_sxtb(tmp); break; - case 5: gen_uxtb(tmp); break; - default: - g_assert_not_reached(); - } - if (rn != 15) { - tmp2 = load_reg(s, rn); - if ((op >> 1) == 1) { - gen_add16(tmp, tmp2); - } else { - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - } - store_reg(s, rd, tmp); - break; - case 2: /* SIMD add/subtract. */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - op = (insn >> 20) & 7; - shift = (insn >> 4) & 7; - if ((op & 3) == 3 || (shift & 3) == 3) - goto illegal_op; - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; - case 3: /* Other data processing. */ - op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); - if (op < 4) { - /* Saturating add/subtract. */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - if (op & 1) - gen_helper_double_saturate(tmp, cpu_env, tmp); - if (op & 2) - gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp); - else - gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } else { - switch (op) { - case 0x0a: /* rbit */ - case 0x08: /* rev */ - case 0x09: /* rev16 */ - case 0x0b: /* revsh */ - case 0x18: /* clz */ - break; - case 0x10: /* sel */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - break; - case 0x20: /* crc32/crc32c */ - case 0x21: - case 0x22: - case 0x28: - case 0x29: - case 0x2a: - if (!arm_dc_feature(s, ARM_FEATURE_CRC)) { - goto illegal_op; - } - break; - default: - goto illegal_op; - } - tmp = load_reg(s, rn); - switch (op) { - case 0x0a: /* rbit */ - gen_helper_rbit(tmp, tmp); - break; - case 0x08: /* rev */ - tcg_gen_bswap32_i32(tmp, tmp); - break; - case 0x09: /* rev16 */ - gen_rev16(tmp); - break; - case 0x0b: /* revsh */ - gen_revsh(tmp); - break; - case 0x10: /* sel */ - tmp2 = load_reg(s, rm); - tmp3 = tcg_temp_new_i32(); - tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); - gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); - tcg_temp_free_i32(tmp3); - tcg_temp_free_i32(tmp2); - break; - case 0x18: /* clz */ - gen_helper_clz(tmp, tmp); - break; - case 0x20: - case 0x21: - case 0x22: - case 0x28: - case 0x29: - case 0x2a: - { - /* crc32/crc32c */ - uint32_t sz = op & 0x3; - uint32_t c = op & 0x8; - - tmp2 = load_reg(s, rm); - if (sz == 0) { - tcg_gen_andi_i32(tmp2, tmp2, 0xff); - } else if (sz == 1) { - tcg_gen_andi_i32(tmp2, tmp2, 0xffff); - } - tmp3 = tcg_const_i32(1 << sz); - if (c) { - gen_helper_crc32c(tmp, tmp, tmp2, tmp3); - } else { - gen_helper_crc32(tmp, tmp, tmp2, tmp3); - } - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp3); - break; - } - default: - g_assert_not_reached(); - } - } - store_reg(s, rd, tmp); - break; - case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ - switch ((insn >> 20) & 7) { - case 0: /* 32 x 32 -> 32 */ - case 7: /* Unsigned sum of absolute differences. */ - break; - case 1: /* 16 x 16 -> 32 */ - case 2: /* Dual multiply add. */ - case 3: /* 32 * 16 -> 32msb */ - case 4: /* Dual multiply subtract. */ - case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - goto illegal_op; - } - break; - } - op = (insn >> 4) & 0xf; - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - switch ((insn >> 20) & 7) { - case 0: /* 32 x 32 -> 32 */ - tcg_gen_mul_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - if (rs != 15) { - tmp2 = load_reg(s, rs); - if (op) - tcg_gen_sub_i32(tmp, tmp2, tmp); - else - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - break; - case 1: /* 16 x 16 -> 32 */ - gen_mulxy(tmp, tmp2, op & 2, op & 1); - tcg_temp_free_i32(tmp2); - if (rs != 15) { - tmp2 = load_reg(s, rs); - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - break; - case 2: /* Dual multiply add. */ - case 4: /* Dual multiply subtract. */ - if (op) - gen_swap_half(tmp2); - gen_smul_dual(tmp, tmp2); - if (insn & (1 << 22)) { - /* This subtraction cannot overflow. */ - tcg_gen_sub_i32(tmp, tmp, tmp2); - } else { - /* This addition cannot overflow 32 bits; - * however it may overflow considered as a signed - * operation, in which case we must set the Q flag. - */ - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - } - tcg_temp_free_i32(tmp2); - if (rs != 15) - { - tmp2 = load_reg(s, rs); - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - break; - case 3: /* 32 * 16 -> 32msb */ - if (op) - tcg_gen_sari_i32(tmp2, tmp2, 16); - else - gen_sxth(tmp2); - tmp64 = gen_muls_i64_i32(tmp, tmp2); - tcg_gen_shri_i64(tmp64, tmp64, 16); - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, tmp64); - tcg_temp_free_i64(tmp64); - if (rs != 15) - { - tmp2 = load_reg(s, rs); - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - break; - case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ - tmp64 = gen_muls_i64_i32(tmp, tmp2); - if (rs != 15) { - tmp = load_reg(s, rs); - if (insn & (1 << 20)) { - tmp64 = gen_addq_msw(tmp64, tmp); - } else { - tmp64 = gen_subq_msw(tmp64, tmp); - } - } - if (insn & (1 << 4)) { - tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); - } - tcg_gen_shri_i64(tmp64, tmp64, 32); - tmp = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(tmp, tmp64); - tcg_temp_free_i64(tmp64); - break; - case 7: /* Unsigned sum of absolute differences. */ - gen_helper_usad8(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - if (rs != 15) { - tmp2 = load_reg(s, rs); - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - } - break; - } - store_reg(s, rd, tmp); - break; - case 6: case 7: /* 64-bit multiply, Divide. */ - op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); - tmp = load_reg(s, rn); - tmp2 = load_reg(s, rm); - if ((op & 0x50) == 0x10) { - /* sdiv, udiv */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) { - goto illegal_op; - } - if (op & 0x20) - gen_helper_udiv(tmp, tmp, tmp2); - else - gen_helper_sdiv(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else if ((op & 0xe) == 0xc) { - /* Dual multiply accumulate long. */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - goto illegal_op; - } - if (op & 1) - gen_swap_half(tmp2); - gen_smul_dual(tmp, tmp2); - if (op & 0x10) { - tcg_gen_sub_i32(tmp, tmp, tmp2); - } else { - tcg_gen_add_i32(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp2); - /* BUGFIX */ - tmp64 = tcg_temp_new_i64(); - tcg_gen_ext_i32_i64(tmp64, tmp); - tcg_temp_free_i32(tmp); - gen_addq(s, tmp64, rs, rd); - gen_storeq_reg(s, rs, rd, tmp64); - tcg_temp_free_i64(tmp64); - } else { - if (op & 0x20) { - /* Unsigned 64-bit multiply */ - tmp64 = gen_mulu_i64_i32(tmp, tmp2); - } else { - if (op & 8) { - /* smlalxy */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - goto illegal_op; - } - gen_mulxy(tmp, tmp2, op & 2, op & 1); - tcg_temp_free_i32(tmp2); - tmp64 = tcg_temp_new_i64(); - tcg_gen_ext_i32_i64(tmp64, tmp); - tcg_temp_free_i32(tmp); - } else { - /* Signed 64-bit multiply */ - tmp64 = gen_muls_i64_i32(tmp, tmp2); - } - } - if (op & 4) { - /* umaal */ - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - tcg_temp_free_i64(tmp64); - goto illegal_op; - } - gen_addq_lo(s, tmp64, rs); - gen_addq_lo(s, tmp64, rd); - } else if (op & 0x40) { - /* 64-bit accumulate. */ - gen_addq(s, tmp64, rs, rd); - } - gen_storeq_reg(s, rs, rd, tmp64); - tcg_temp_free_i64(tmp64); - } - break; - } - break; - case 6: case 7: case 14: case 15: - /* Coprocessor. */ - if (((insn >> 24) & 3) == 3) { - /* Translate into the equivalent ARM encoding. */ - insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); - if (disas_neon_data_insn(s, insn)) { - goto illegal_op; - } - } else if (((insn >> 8) & 0xe) == 10) { - if (disas_vfp_insn(s, insn)) { - goto illegal_op; - } - } else { - if (insn & (1 << 28)) - goto illegal_op; - if (disas_coproc_insn(s, insn)) { - goto illegal_op; - } - } - break; - case 8: case 9: case 10: case 11: - if (insn & (1 << 15)) { - /* Branches, misc control. */ - if (insn & 0x5000) { - /* Unconditional branch. */ - /* signextend(hw1[10:0]) -> offset[:12]. */ - offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff; - /* hw1[10:0] -> offset[11:1]. */ - offset |= (insn & 0x7ff) << 1; - /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22] - offset[24:22] already have the same value because of the - sign extension above. */ - offset ^= ((~insn) & (1 << 13)) << 10; - offset ^= ((~insn) & (1 << 11)) << 11; - - if (insn & (1 << 14)) { - /* Branch and link. */ - tcg_gen_movi_i32(cpu_R[14], s->pc | 1); - } - - offset += s->pc; - if (insn & (1 << 12)) { - /* b/bl */ - gen_jmp(s, offset); - } else { - /* blx */ - offset &= ~(uint32_t)2; - /* thumb2 bx, no need to check */ - gen_bx_im(s, offset); - } - } else if (((insn >> 23) & 7) == 7) { - /* Misc control */ - if (insn & (1 << 13)) - goto illegal_op; - - if (insn & (1 << 26)) { - if (!(insn & (1 << 20))) { - /* Hypervisor call (v7) */ - int imm16 = extract32(insn, 16, 4) << 12 - | extract32(insn, 0, 12); - ARCH(7); - if (IS_USER(s)) { - goto illegal_op; - } - gen_hvc(s, imm16); - } else { - /* Secure monitor call (v6+) */ - ARCH(6K); - if (IS_USER(s)) { - goto illegal_op; - } - gen_smc(s); - } - } else { - op = (insn >> 20) & 7; - switch (op) { - case 0: /* msr cpsr. */ - if (arm_dc_feature(s, ARM_FEATURE_M)) { - tmp = load_reg(s, rn); - addr = tcg_const_i32(insn & 0xff); - gen_helper_v7m_msr(cpu_env, addr, tmp); - tcg_temp_free_i32(addr); - tcg_temp_free_i32(tmp); - gen_lookup_tb(s); - break; - } - /* fall through */ - case 1: /* msr spsr. */ - if (arm_dc_feature(s, ARM_FEATURE_M)) { - goto illegal_op; - } - tmp = load_reg(s, rn); - if (gen_set_psr(s, - msr_mask(s, (insn >> 8) & 0xf, op == 1), - op == 1, tmp)) - goto illegal_op; - break; - case 2: /* cps, nop-hint. */ - if (((insn >> 8) & 7) == 0) { - gen_nop_hint(s, insn & 0xff); - } - /* Implemented as NOP in user mode. */ - if (IS_USER(s)) - break; - offset = 0; - imm = 0; - if (insn & (1 << 10)) { - if (insn & (1 << 7)) - offset |= CPSR_A; - if (insn & (1 << 6)) - offset |= CPSR_I; - if (insn & (1 << 5)) - offset |= CPSR_F; - if (insn & (1 << 9)) - imm = CPSR_A | CPSR_I | CPSR_F; - } - if (insn & (1 << 8)) { - offset |= 0x1f; - imm |= (insn & 0x1f); - } - if (offset) { - gen_set_psr_im(s, offset, 0, imm); - } - break; - case 3: /* Special control operations. */ - ARCH(7); - op = (insn >> 4) & 0xf; - switch (op) { - case 2: /* clrex */ - gen_clrex(s); - break; - case 4: /* dsb */ - case 5: /* dmb */ - /* These execute as NOPs. */ - break; - case 6: /* isb */ - /* We need to break the TB after this insn - * to execute self-modifying code correctly - * and also to take any pending interrupts - * immediately. - */ - gen_lookup_tb(s); - break; - default: - goto illegal_op; - } - break; - case 4: /* bxj */ - /* Trivial implementation equivalent to bx. */ - tmp = load_reg(s, rn); - gen_bx(s, tmp); - break; - case 5: /* Exception return. */ - if (IS_USER(s)) { - goto illegal_op; - } - if (rn != 14 || rd != 15) { - goto illegal_op; - } - tmp = load_reg(s, rn); - tcg_gen_subi_i32(tmp, tmp, insn & 0xff); - gen_exception_return(s, tmp); - break; - case 6: /* mrs cpsr. */ - tmp = tcg_temp_new_i32(); - if (arm_dc_feature(s, ARM_FEATURE_M)) { - addr = tcg_const_i32(insn & 0xff); - gen_helper_v7m_mrs(tmp, cpu_env, addr); - tcg_temp_free_i32(addr); - } else { - gen_helper_cpsr_read(tmp, cpu_env); - } - store_reg(s, rd, tmp); - break; - case 7: /* mrs spsr. */ - /* Not accessible in user mode. */ - if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) { - goto illegal_op; - } - tmp = load_cpu_field(spsr); - store_reg(s, rd, tmp); - break; - } - } - } else { - /* Conditional branch. */ - op = (insn >> 22) & 0xf; - /* Generate a conditional jump to next instruction. */ - s->condlabel = gen_new_label(); - arm_gen_test_cc(op ^ 1, s->condlabel); - s->condjmp = 1; - - /* offset[11:1] = insn[10:0] */ - offset = (insn & 0x7ff) << 1; - /* offset[17:12] = insn[21:16]. */ - offset |= (insn & 0x003f0000) >> 4; - /* offset[31:20] = insn[26]. */ - offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11; - /* offset[18] = insn[13]. */ - offset |= (insn & (1 << 13)) << 5; - /* offset[19] = insn[11]. */ - offset |= (insn & (1 << 11)) << 8; - - /* jump to the offset */ - gen_jmp(s, s->pc + offset); - } - } else { - /* Data processing immediate. */ - if (insn & (1 << 25)) { - if (insn & (1 << 24)) { - if (insn & (1 << 20)) - goto illegal_op; - /* Bitfield/Saturate. */ - op = (insn >> 21) & 7; - imm = insn & 0x1f; - shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); - if (rn == 15) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else { - tmp = load_reg(s, rn); - } - switch (op) { - case 2: /* Signed bitfield extract. */ - imm++; - if (shift + imm > 32) - goto illegal_op; - if (imm < 32) - gen_sbfx(tmp, shift, imm); - break; - case 6: /* Unsigned bitfield extract. */ - imm++; - if (shift + imm > 32) - goto illegal_op; - if (imm < 32) - gen_ubfx(tmp, shift, (1u << imm) - 1); - break; - case 3: /* Bitfield insert/clear. */ - if (imm < shift) - goto illegal_op; - imm = imm + 1 - shift; - if (imm != 32) { - tmp2 = load_reg(s, rd); - tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm); - tcg_temp_free_i32(tmp2); - } - break; - case 7: - goto illegal_op; - default: /* Saturate. */ - if (shift) { - if (op & 1) - tcg_gen_sari_i32(tmp, tmp, shift); - else - tcg_gen_shli_i32(tmp, tmp, shift); - } - tmp2 = tcg_const_i32(imm); - if (op & 4) { - /* Unsigned. */ - if ((op & 1) && shift == 0) { - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - goto illegal_op; - } - gen_helper_usat16(tmp, cpu_env, tmp, tmp2); - } else { - gen_helper_usat(tmp, cpu_env, tmp, tmp2); - } - } else { - /* Signed. */ - if ((op & 1) && shift == 0) { - if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - goto illegal_op; - } - gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); - } else { - gen_helper_ssat(tmp, cpu_env, tmp, tmp2); - } - } - tcg_temp_free_i32(tmp2); - break; - } - store_reg(s, rd, tmp); - } else { - imm = ((insn & 0x04000000) >> 15) - | ((insn & 0x7000) >> 4) | (insn & 0xff); - if (insn & (1 << 22)) { - /* 16-bit immediate. */ - imm |= (insn >> 4) & 0xf000; - if (insn & (1 << 23)) { - /* movt */ - tmp = load_reg(s, rd); - tcg_gen_ext16u_i32(tmp, tmp); - tcg_gen_ori_i32(tmp, tmp, imm << 16); - } else { - /* movw */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, imm); - } - } else { - /* Add/sub 12-bit immediate. */ - if (rn == 15) { - offset = s->pc & ~(uint32_t)3; - if (insn & (1 << 23)) - offset -= imm; - else - offset += imm; - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, offset); - } else { - tmp = load_reg(s, rn); - if (insn & (1 << 23)) - tcg_gen_subi_i32(tmp, tmp, imm); - else - tcg_gen_addi_i32(tmp, tmp, imm); - } - } - store_reg(s, rd, tmp); - } - } else { - int shifter_out = 0; - /* modified 12-bit immediate. */ - shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); - imm = (insn & 0xff); - switch (shift) { - case 0: /* XY */ - /* Nothing to do. */ - break; - case 1: /* 00XY00XY */ - imm |= imm << 16; - break; - case 2: /* XY00XY00 */ - imm |= imm << 16; - imm <<= 8; - break; - case 3: /* XYXYXYXY */ - imm |= imm << 16; - imm |= imm << 8; - break; - default: /* Rotated constant. */ - shift = (shift << 1) | (imm >> 7); - imm |= 0x80; - imm = imm << (32 - shift); - shifter_out = 1; - break; - } - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, imm); - rn = (insn >> 16) & 0xf; - if (rn == 15) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else { - tmp = load_reg(s, rn); - } - op = (insn >> 21) & 0xf; - if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, - shifter_out, tmp, tmp2)) - goto illegal_op; - tcg_temp_free_i32(tmp2); - rd = (insn >> 8) & 0xf; - if (rd != 15) { - store_reg(s, rd, tmp); - } else { - tcg_temp_free_i32(tmp); - } - } - } - break; - case 12: /* Load/store single data item. */ - { - int postinc = 0; - int writeback = 0; - int memidx; - if ((insn & 0x01100000) == 0x01000000) { - if (disas_neon_ls_insn(s, insn)) { - goto illegal_op; - } - break; - } - op = ((insn >> 21) & 3) | ((insn >> 22) & 4); - if (rs == 15) { - if (!(insn & (1 << 20))) { - goto illegal_op; - } - if (op != 2) { - /* Byte or halfword load space with dest == r15 : memory hints. - * Catch them early so we don't emit pointless addressing code. - * This space is a mix of: - * PLD/PLDW/PLI, which we implement as NOPs (note that unlike - * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP - * cores) - * unallocated hints, which must be treated as NOPs - * UNPREDICTABLE space, which we NOP or UNDEF depending on - * which is easiest for the decoding logic - * Some space which must UNDEF - */ - int op1 = (insn >> 23) & 3; - int op2 = (insn >> 6) & 0x3f; - if (op & 2) { - goto illegal_op; - } - if (rn == 15) { - /* UNPREDICTABLE, unallocated hint or - * PLD/PLDW/PLI (literal) - */ - return 0; - } - if (op1 & 1) { - return 0; /* PLD/PLDW/PLI or unallocated hint */ - } - if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { - return 0; /* PLD/PLDW/PLI or unallocated hint */ - } - /* UNDEF space, or an UNPREDICTABLE */ - return 1; - } - } - memidx = get_mem_index(s); - if (rn == 15) { - addr = tcg_temp_new_i32(); - /* PC relative. */ - /* s->pc has already been incremented by 4. */ - imm = s->pc & 0xfffffffc; - if (insn & (1 << 23)) - imm += insn & 0xfff; - else - imm -= insn & 0xfff; - tcg_gen_movi_i32(addr, imm); - } else { - addr = load_reg(s, rn); - if (insn & (1 << 23)) { - /* Positive offset. */ - imm = insn & 0xfff; - tcg_gen_addi_i32(addr, addr, imm); - } else { - imm = insn & 0xff; - switch ((insn >> 8) & 0xf) { - case 0x0: /* Shifted Register. */ - shift = (insn >> 4) & 0xf; - if (shift > 3) { - tcg_temp_free_i32(addr); - goto illegal_op; - } - tmp = load_reg(s, rm); - if (shift) - tcg_gen_shli_i32(tmp, tmp, shift); - tcg_gen_add_i32(addr, addr, tmp); - tcg_temp_free_i32(tmp); - break; - case 0xc: /* Negative offset. */ - tcg_gen_addi_i32(addr, addr, -imm); - break; - case 0xe: /* User privilege. */ - tcg_gen_addi_i32(addr, addr, imm); - memidx = get_a32_user_mem_index(s); - break; - case 0x9: /* Post-decrement. */ - imm = -imm; - /* Fall through. */ - case 0xb: /* Post-increment. */ - postinc = 1; - writeback = 1; - break; - case 0xd: /* Pre-decrement. */ - imm = -imm; - /* Fall through. */ - case 0xf: /* Pre-increment. */ - tcg_gen_addi_i32(addr, addr, imm); - writeback = 1; - break; - default: - tcg_temp_free_i32(addr); - goto illegal_op; - } - } - } - if (insn & (1 << 20)) { - /* Load. */ - tmp = tcg_temp_new_i32(); - switch (op) { - case 0: - gen_aa32_ld8u(tmp, addr, memidx); - break; - case 4: - gen_aa32_ld8s(tmp, addr, memidx); - break; - case 1: - gen_aa32_ld16u(tmp, addr, memidx); - break; - case 5: - gen_aa32_ld16s(tmp, addr, memidx); - break; - case 2: - gen_aa32_ld32u(tmp, addr, memidx); - break; - default: - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(addr); - goto illegal_op; - } - if (rs == 15) { - gen_bx(s, tmp); - } else { - store_reg(s, rs, tmp); - } - } else { - /* Store. */ - tmp = load_reg(s, rs); - switch (op) { - case 0: - gen_aa32_st8(tmp, addr, memidx); - break; - case 1: - gen_aa32_st16(tmp, addr, memidx); - break; - case 2: - gen_aa32_st32(tmp, addr, memidx); - break; - default: - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(addr); - goto illegal_op; - } - tcg_temp_free_i32(tmp); - } - if (postinc) - tcg_gen_addi_i32(addr, addr, imm); - if (writeback) { - store_reg(s, rn, addr); - } else { - tcg_temp_free_i32(addr); - } - } - break; - default: - goto illegal_op; - } - return 0; -illegal_op: - return 1; -} - -static void disas_thumb_insn(CPUARMState *env, DisasContext *s) -{ - uint32_t val, insn, op, rm, rn, rd, shift, cond; - int32_t offset; - int i; - TCGv_i32 tmp; - TCGv_i32 tmp2; - TCGv_i32 addr; - - if (s->condexec_mask) { - cond = s->condexec_cond; - if (cond != 0x0e) { /* Skip conditional when condition is AL. */ - s->condlabel = gen_new_label(); - arm_gen_test_cc(cond ^ 1, s->condlabel); - s->condjmp = 1; - } - } - - insn = arm_lduw_code(env, s->pc, s->bswap_code); - s->pc += 2; - - switch (insn >> 12) { - case 0: case 1: - - rd = insn & 7; - op = (insn >> 11) & 3; - if (op == 3) { - /* add/subtract */ - rn = (insn >> 3) & 7; - tmp = load_reg(s, rn); - if (insn & (1 << 10)) { - /* immediate */ - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, (insn >> 6) & 7); - } else { - /* reg */ - rm = (insn >> 6) & 7; - tmp2 = load_reg(s, rm); - } - if (insn & (1 << 9)) { - if (s->condexec_mask) - tcg_gen_sub_i32(tmp, tmp, tmp2); - else - gen_sub_CC(tmp, tmp, tmp2); - } else { - if (s->condexec_mask) - tcg_gen_add_i32(tmp, tmp, tmp2); - else - gen_add_CC(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - } else { - /* shift immediate */ - rm = (insn >> 3) & 7; - shift = (insn >> 6) & 0x1f; - tmp = load_reg(s, rm); - gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0); - if (!s->condexec_mask) - gen_logic_CC(tmp); - store_reg(s, rd, tmp); - } - break; - case 2: case 3: - /* arithmetic large immediate */ - op = (insn >> 11) & 3; - rd = (insn >> 8) & 0x7; - if (op == 0) { /* mov */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, insn & 0xff); - if (!s->condexec_mask) - gen_logic_CC(tmp); - store_reg(s, rd, tmp); - } else { - tmp = load_reg(s, rd); - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, insn & 0xff); - switch (op) { - case 1: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - break; - case 2: /* add */ - if (s->condexec_mask) - tcg_gen_add_i32(tmp, tmp, tmp2); - else - gen_add_CC(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; - case 3: /* sub */ - if (s->condexec_mask) - tcg_gen_sub_i32(tmp, tmp, tmp2); - else - gen_sub_CC(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; - } - } - break; - case 4: - if (insn & (1 << 11)) { - rd = (insn >> 8) & 7; - /* load pc-relative. Bit 1 of PC is ignored. */ - val = s->pc + 2 + ((insn & 0xff) * 4); - val &= ~(uint32_t)2; - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, val); - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(addr); - store_reg(s, rd, tmp); - break; - } - if (insn & (1 << 10)) { - /* data processing extended or blx */ - rd = (insn & 7) | ((insn >> 4) & 8); - rm = (insn >> 3) & 0xf; - op = (insn >> 8) & 3; - switch (op) { - case 0: /* add */ - tmp = load_reg(s, rd); - tmp2 = load_reg(s, rm); - tcg_gen_add_i32(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; - case 1: /* cmp */ - tmp = load_reg(s, rd); - tmp2 = load_reg(s, rm); - gen_sub_CC(tmp, tmp, tmp2); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; - case 2: /* mov/cpy */ - tmp = load_reg(s, rm); - store_reg(s, rd, tmp); - break; - case 3:/* branch [and link] exchange thumb register */ - tmp = load_reg(s, rm); - if (insn & (1 << 7)) { - ARCH(5); - val = (uint32_t)s->pc | 1; - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, val); - store_reg(s, 14, tmp2); - } - /* already thumb, no need to check */ - gen_bx(s, tmp); - break; - } - break; - } - - /* data processing register */ - rd = insn & 7; - rm = (insn >> 3) & 7; - op = (insn >> 6) & 0xf; - if (op == 2 || op == 3 || op == 4 || op == 7) { - /* the shift/rotate ops want the operands backwards */ - val = rm; - rm = rd; - rd = val; - val = 1; - } else { - val = 0; - } - - if (op == 9) { /* neg */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else if (op != 0xf) { /* mvn doesn't read its first operand */ - tmp = load_reg(s, rd); - } else { - TCGV_UNUSED_I32(tmp); - } - - tmp2 = load_reg(s, rm); - switch (op) { - case 0x0: /* and */ - tcg_gen_and_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0x1: /* eor */ - tcg_gen_xor_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0x2: /* lsl */ - if (s->condexec_mask) { - gen_shl(tmp2, tmp2, tmp); - } else { - gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x3: /* lsr */ - if (s->condexec_mask) { - gen_shr(tmp2, tmp2, tmp); - } else { - gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x4: /* asr */ - if (s->condexec_mask) { - gen_sar(tmp2, tmp2, tmp); - } else { - gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x5: /* adc */ - if (s->condexec_mask) { - gen_adc(tmp, tmp2); - } else { - gen_adc_CC(tmp, tmp, tmp2); - } - break; - case 0x6: /* sbc */ - if (s->condexec_mask) { - gen_sub_carry(tmp, tmp, tmp2); - } else { - gen_sbc_CC(tmp, tmp, tmp2); - } - break; - case 0x7: /* ror */ - if (s->condexec_mask) { - tcg_gen_andi_i32(tmp, tmp, 0x1f); - tcg_gen_rotr_i32(tmp2, tmp2, tmp); - } else { - gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp); - gen_logic_CC(tmp2); - } - break; - case 0x8: /* tst */ - tcg_gen_and_i32(tmp, tmp, tmp2); - gen_logic_CC(tmp); - rd = 16; - break; - case 0x9: /* neg */ - if (s->condexec_mask) - tcg_gen_neg_i32(tmp, tmp2); - else - gen_sub_CC(tmp, tmp, tmp2); - break; - case 0xa: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); - rd = 16; - break; - case 0xb: /* cmn */ - gen_add_CC(tmp, tmp, tmp2); - rd = 16; - break; - case 0xc: /* orr */ - tcg_gen_or_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0xd: /* mul */ - tcg_gen_mul_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0xe: /* bic */ - tcg_gen_andc_i32(tmp, tmp, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp); - break; - case 0xf: /* mvn */ - tcg_gen_not_i32(tmp2, tmp2); - if (!s->condexec_mask) - gen_logic_CC(tmp2); - val = 1; - rm = rd; - break; - } - if (rd != 16) { - if (val) { - store_reg(s, rm, tmp2); - if (op != 0xf) - tcg_temp_free_i32(tmp); - } else { - store_reg(s, rd, tmp); - tcg_temp_free_i32(tmp2); - } - } else { - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - } - break; - - case 5: - /* load/store register offset. */ - rd = insn & 7; - rn = (insn >> 3) & 7; - rm = (insn >> 6) & 7; - op = (insn >> 9) & 7; - addr = load_reg(s, rn); - tmp = load_reg(s, rm); - tcg_gen_add_i32(addr, addr, tmp); - tcg_temp_free_i32(tmp); - - if (op < 3) { /* store */ - tmp = load_reg(s, rd); - } else { - tmp = tcg_temp_new_i32(); - } - - switch (op) { - case 0: /* str */ - gen_aa32_st32(tmp, addr, get_mem_index(s)); - break; - case 1: /* strh */ - gen_aa32_st16(tmp, addr, get_mem_index(s)); - break; - case 2: /* strb */ - gen_aa32_st8(tmp, addr, get_mem_index(s)); - break; - case 3: /* ldrsb */ - gen_aa32_ld8s(tmp, addr, get_mem_index(s)); - break; - case 4: /* ldr */ - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - break; - case 5: /* ldrh */ - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - break; - case 6: /* ldrb */ - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - break; - case 7: /* ldrsh */ - gen_aa32_ld16s(tmp, addr, get_mem_index(s)); - break; - } - if (op >= 3) { /* load */ - store_reg(s, rd, tmp); - } else { - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 6: - /* load/store word immediate offset */ - rd = insn & 7; - rn = (insn >> 3) & 7; - addr = load_reg(s, rn); - val = (insn >> 4) & 0x7c; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 7: - /* load/store byte immediate offset */ - rd = insn & 7; - rn = (insn >> 3) & 7; - addr = load_reg(s, rn); - val = (insn >> 6) & 0x1f; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld8u(tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st8(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 8: - /* load/store halfword immediate offset */ - rd = insn & 7; - rn = (insn >> 3) & 7; - addr = load_reg(s, rn); - val = (insn >> 5) & 0x3e; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld16u(tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st16(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 9: - /* load/store from stack */ - rd = (insn >> 8) & 7; - addr = load_reg(s, 13); - val = (insn & 0xff) * 4; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 10: - /* add to high reg */ - rd = (insn >> 8) & 7; - if (insn & (1 << 11)) { - /* SP */ - tmp = load_reg(s, 13); - } else { - /* PC. bit 1 is ignored. */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2); - } - val = (insn & 0xff) * 4; - tcg_gen_addi_i32(tmp, tmp, val); - store_reg(s, rd, tmp); - break; - - case 11: - /* misc */ - op = (insn >> 8) & 0xf; - switch (op) { - case 0: - /* adjust stack pointer */ - tmp = load_reg(s, 13); - val = (insn & 0x7f) * 4; - if (insn & (1 << 7)) - val = -(int32_t)val; - tcg_gen_addi_i32(tmp, tmp, val); - store_reg(s, 13, tmp); - break; - - case 2: /* sign/zero extend. */ - ARCH(6); - rd = insn & 7; - rm = (insn >> 3) & 7; - tmp = load_reg(s, rm); - switch ((insn >> 6) & 3) { - case 0: gen_sxth(tmp); break; - case 1: gen_sxtb(tmp); break; - case 2: gen_uxth(tmp); break; - case 3: gen_uxtb(tmp); break; - } - store_reg(s, rd, tmp); - break; - case 4: case 5: case 0xc: case 0xd: - /* push/pop */ - addr = load_reg(s, 13); - if (insn & (1 << 8)) - offset = 4; - else - offset = 0; - for (i = 0; i < 8; i++) { - if (insn & (1 << i)) - offset += 4; - } - if ((insn & (1 << 11)) == 0) { - tcg_gen_addi_i32(addr, addr, -offset); - } - for (i = 0; i < 8; i++) { - if (insn & (1 << i)) { - if (insn & (1 << 11)) { - /* pop */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - store_reg(s, i, tmp); - } else { - /* push */ - tmp = load_reg(s, i); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - /* advance to the next address. */ - tcg_gen_addi_i32(addr, addr, 4); - } - } - TCGV_UNUSED_I32(tmp); - if (insn & (1 << 8)) { - if (insn & (1 << 11)) { - /* pop pc */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - /* don't set the pc until the rest of the instruction - has completed */ - } else { - /* push lr */ - tmp = load_reg(s, 14); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_gen_addi_i32(addr, addr, 4); - } - if ((insn & (1 << 11)) == 0) { - tcg_gen_addi_i32(addr, addr, -offset); - } - /* write back the new stack pointer */ - store_reg(s, 13, addr); - /* set the new PC value */ - if ((insn & 0x0900) == 0x0900) { - store_reg_from_load(s, 15, tmp); - } - break; - - case 1: case 3: case 9: case 11: /* czb */ - rm = insn & 7; - tmp = load_reg(s, rm); - s->condlabel = gen_new_label(); - s->condjmp = 1; - if (insn & (1 << 11)) - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel); - else - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel); - tcg_temp_free_i32(tmp); - offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; - val = (uint32_t)s->pc + 2; - val += offset; - gen_jmp(s, val); - break; - - case 15: /* IT, nop-hint. */ - if ((insn & 0xf) == 0) { - gen_nop_hint(s, (insn >> 4) & 0xf); - break; - } - /* If Then. */ - s->condexec_cond = (insn >> 4) & 0xe; - s->condexec_mask = insn & 0x1f; - /* No actual code generated for this insn, just setup state. */ - break; - - case 0xe: /* bkpt */ - { - int imm8 = extract32(insn, 0, 8); - ARCH(5); - gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true), - default_exception_el(s)); - break; - } - - case 0xa: /* rev */ - ARCH(6); - rn = (insn >> 3) & 0x7; - rd = insn & 0x7; - tmp = load_reg(s, rn); - switch ((insn >> 6) & 3) { - case 0: tcg_gen_bswap32_i32(tmp, tmp); break; - case 1: gen_rev16(tmp); break; - case 3: gen_revsh(tmp); break; - default: goto illegal_op; - } - store_reg(s, rd, tmp); - break; - - case 6: - switch ((insn >> 5) & 7) { - case 2: - /* setend */ - ARCH(6); - if (((insn >> 3) & 1) != s->bswap_code) { - /* Dynamic endianness switching not implemented. */ - qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n"); - goto illegal_op; - } - break; - case 3: - /* cps */ - ARCH(6); - if (IS_USER(s)) { - break; - } - if (arm_dc_feature(s, ARM_FEATURE_M)) { - tmp = tcg_const_i32((insn & (1 << 4)) != 0); - /* FAULTMASK */ - if (insn & 1) { - addr = tcg_const_i32(19); - gen_helper_v7m_msr(cpu_env, addr, tmp); - tcg_temp_free_i32(addr); - } - /* PRIMASK */ - if (insn & 2) { - addr = tcg_const_i32(16); - gen_helper_v7m_msr(cpu_env, addr, tmp); - tcg_temp_free_i32(addr); - } - tcg_temp_free_i32(tmp); - gen_lookup_tb(s); - } else { - if (insn & (1 << 4)) { - shift = CPSR_A | CPSR_I | CPSR_F; - } else { - shift = 0; - } - gen_set_psr_im(s, ((insn & 7) << 6), 0, shift); - } - break; - default: - goto undef; - } - break; - - default: - goto undef; - } - break; - - case 12: - { - /* load/store multiple */ - TCGv_i32 loaded_var; - TCGV_UNUSED_I32(loaded_var); - rn = (insn >> 8) & 0x7; - addr = load_reg(s, rn); - for (i = 0; i < 8; i++) { - if (insn & (1 << i)) { - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(tmp, addr, get_mem_index(s)); - if (i == rn) { - loaded_var = tmp; - } else { - store_reg(s, i, tmp); - } - } else { - /* store */ - tmp = load_reg(s, i); - gen_aa32_st32(tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - /* advance to the next address */ - tcg_gen_addi_i32(addr, addr, 4); - } - } - if ((insn & (1 << rn)) == 0) { - /* base reg not in list: base register writeback */ - store_reg(s, rn, addr); - } else { - /* base reg in list: if load, complete it now */ - if (insn & (1 << 11)) { - store_reg(s, rn, loaded_var); - } - tcg_temp_free_i32(addr); - } - break; - } - case 13: - /* conditional branch or swi */ - cond = (insn >> 8) & 0xf; - if (cond == 0xe) - goto undef; - - if (cond == 0xf) { - /* swi */ - gen_set_pc_im(s, s->pc); - s->svc_imm = extract32(insn, 0, 8); - s->is_jmp = DISAS_SWI; - break; - } - /* generate a conditional jump to next instruction */ - s->condlabel = gen_new_label(); - arm_gen_test_cc(cond ^ 1, s->condlabel); - s->condjmp = 1; - - /* jump to the offset */ - val = (uint32_t)s->pc + 2; - offset = ((int32_t)insn << 24) >> 24; - val += offset << 1; - gen_jmp(s, val); - break; - - case 14: - if (insn & (1 << 11)) { - if (disas_thumb2_insn(env, s, insn)) - goto undef32; - break; - } - /* unconditional branch */ - val = (uint32_t)s->pc; - offset = ((int32_t)insn << 21) >> 21; - val += (offset << 1) + 2; - gen_jmp(s, val); - break; - - case 15: - if (disas_thumb2_insn(env, s, insn)) - goto undef32; - break; - } - return; -undef32: - gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), - default_exception_el(s)); - return; -illegal_op: -undef: - gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(), - default_exception_el(s)); -} - -static bool insn_crosses_page(CPUARMState *env, DisasContext *s) -{ - /* Return true if the insn at dc->pc might cross a page boundary. - * (False positives are OK, false negatives are not.) - */ - uint16_t insn; - - if ((s->pc & 3) == 0) { - /* At a 4-aligned address we can't be crossing a page */ - return false; - } - - /* This must be a Thumb insn */ - insn = arm_lduw_code(env, s->pc, s->bswap_code); - - if ((insn >> 11) >= 0x1d) { - /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the - * First half of a 32-bit Thumb insn. Thumb-1 cores might - * end up actually treating this as two 16-bit insns (see the - * code at the start of disas_thumb2_insn()) but we don't bother - * to check for that as it is unlikely, and false positives here - * are harmless. - */ - return true; - } - /* Definitely a 16-bit insn, can't be crossing a page. */ - return false; -} - -/* generate intermediate code in gen_opc_buf and gen_opparam_buf for - basic block 'tb'. */ -void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) -{ - ARMCPU *cpu = arm_env_get_cpu(env); - CPUState *cs = CPU(cpu); - DisasContext dc1, *dc = &dc1; - target_ulong pc_start; - target_ulong next_page_start; - int num_insns; - int max_insns; - bool end_of_page; - - /* generate intermediate code */ - - /* The A64 decoder has its own top level loop, because it doesn't need - * the A32/T32 complexity to do with conditional execution/IT blocks/etc. - */ - if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) { - gen_intermediate_code_a64(cpu, tb); - return; - } - - pc_start = tb->pc; - - dc->tb = tb; - - dc->is_jmp = DISAS_NEXT; - dc->pc = pc_start; - dc->singlestep_enabled = cs->singlestep_enabled; - dc->condjmp = 0; - - dc->aarch64 = 0; - /* If we are coming from secure EL0 in a system with a 32-bit EL3, then - * there is no secure EL1, so we route exceptions to EL3. - */ - dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) && - !arm_el_is_aa64(env, 3); - dc->thumb = ARM_TBFLAG_THUMB(tb->flags); - dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags); - dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1; - dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4; - dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags); - dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx); -#if !defined(CONFIG_USER_ONLY) - dc->user = (dc->current_el == 0); -#endif - dc->ns = ARM_TBFLAG_NS(tb->flags); - dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags); - dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags); - dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); - dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags); - dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags); - dc->cp_regs = cpu->cp_regs; - dc->features = env->features; - - /* Single step state. The code-generation logic here is: - * SS_ACTIVE == 0: - * generate code with no special handling for single-stepping (except - * that anything that can make us go to SS_ACTIVE == 1 must end the TB; - * this happens anyway because those changes are all system register or - * PSTATE writes). - * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending) - * emit code for one insn - * emit code to clear PSTATE.SS - * emit code to generate software step exception for completed step - * end TB (as usual for having generated an exception) - * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending) - * emit code to generate a software step exception - * end the TB - */ - dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags); - dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags); - dc->is_ldex = false; - dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */ - - cpu_F0s = tcg_temp_new_i32(); - cpu_F1s = tcg_temp_new_i32(); - cpu_F0d = tcg_temp_new_i64(); - cpu_F1d = tcg_temp_new_i64(); - cpu_V0 = cpu_F0d; - cpu_V1 = cpu_F1d; - /* FIXME: cpu_M0 can probably be the same as cpu_V0. */ - cpu_M0 = tcg_temp_new_i64(); - next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; - num_insns = 0; - max_insns = tb->cflags & CF_COUNT_MASK; - if (max_insns == 0) { - max_insns = CF_COUNT_MASK; - } - if (max_insns > TCG_MAX_INSNS) { - max_insns = TCG_MAX_INSNS; - } - - gen_tb_start(tb); - - tcg_clear_temp_count(); - - /* A note on handling of the condexec (IT) bits: - * - * We want to avoid the overhead of having to write the updated condexec - * bits back to the CPUARMState for every instruction in an IT block. So: - * (1) if the condexec bits are not already zero then we write - * zero back into the CPUARMState now. This avoids complications trying - * to do it at the end of the block. (For example if we don't do this - * it's hard to identify whether we can safely skip writing condexec - * at the end of the TB, which we definitely want to do for the case - * where a TB doesn't do anything with the IT state at all.) - * (2) if we are going to leave the TB then we call gen_set_condexec() - * which will write the correct value into CPUARMState if zero is wrong. - * This is done both for leaving the TB at the end, and for leaving - * it because of an exception we know will happen, which is done in - * gen_exception_insn(). The latter is necessary because we need to - * leave the TB with the PC/IT state just prior to execution of the - * instruction which caused the exception. - * (3) if we leave the TB unexpectedly (eg a data abort on a load) - * then the CPUARMState will be wrong and we need to reset it. - * This is handled in the same way as restoration of the - * PC in these situations; we save the value of the condexec bits - * for each PC via tcg_gen_insn_start(), and restore_state_to_opc() - * then uses this to restore them after an exception. - * - * Note that there are no instructions which can read the condexec - * bits, and none which can write non-static values to them, so - * we don't need to care about whether CPUARMState is correct in the - * middle of a TB. - */ - - /* Reset the conditional execution bits immediately. This avoids - complications trying to do it at the end of the block. */ - if (dc->condexec_mask || dc->condexec_cond) - { - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - store_cpu_field(tmp, condexec_bits); - } - do { - tcg_gen_insn_start(dc->pc, - (dc->condexec_cond << 4) | (dc->condexec_mask >> 1)); - num_insns++; - -#ifdef CONFIG_USER_ONLY - /* Intercept jump to the magic kernel page. */ - if (dc->pc >= 0xffff0000) { - /* We always get here via a jump, so know we are not in a - conditional execution block. */ - gen_exception_internal(EXCP_KERNEL_TRAP); - dc->is_jmp = DISAS_EXC; - break; - } -#else - if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) { - /* We always get here via a jump, so know we are not in a - conditional execution block. */ - gen_exception_internal(EXCP_EXCEPTION_EXIT); - dc->is_jmp = DISAS_EXC; - break; - } -#endif - - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { - CPUBreakpoint *bp; - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { - if (bp->pc == dc->pc) { - if (bp->flags & BP_CPU) { - gen_set_condexec(dc); - gen_set_pc_im(dc, dc->pc); - gen_helper_check_breakpoints(cpu_env); - /* End the TB early; it's likely not going to be executed */ - dc->is_jmp = DISAS_UPDATE; - } else { - gen_exception_internal_insn(dc, 0, EXCP_DEBUG); - /* The address covered by the breakpoint must be - included in [tb->pc, tb->pc + tb->size) in order - to for it to be properly cleared -- thus we - increment the PC here so that the logic setting - tb->size below does the right thing. */ - /* TODO: Advance PC by correct instruction length to - * avoid disassembler error messages */ - dc->pc += 2; - goto done_generating; - } - break; - } - } - } - - if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { - gen_io_start(); - } - - if (dc->ss_active && !dc->pstate_ss) { - /* Singlestep state is Active-pending. - * If we're in this state at the start of a TB then either - * a) we just took an exception to an EL which is being debugged - * and this is the first insn in the exception handler - * b) debug exceptions were masked and we just unmasked them - * without changing EL (eg by clearing PSTATE.D) - * In either case we're going to take a swstep exception in the - * "did not step an insn" case, and so the syndrome ISV and EX - * bits should be zero. - */ - assert(num_insns == 1); - gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0), - default_exception_el(dc)); - goto done_generating; - } - - if (dc->thumb) { - disas_thumb_insn(env, dc); - if (dc->condexec_mask) { - dc->condexec_cond = (dc->condexec_cond & 0xe) - | ((dc->condexec_mask >> 4) & 1); - dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f; - if (dc->condexec_mask == 0) { - dc->condexec_cond = 0; - } - } - } else { - unsigned int insn = arm_ldl_code(env, dc->pc, dc->bswap_code); - dc->pc += 4; - disas_arm_insn(dc, insn); - } - - if (dc->condjmp && !dc->is_jmp) { - gen_set_label(dc->condlabel); - dc->condjmp = 0; - } - - if (tcg_check_temp_count()) { - fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n", - dc->pc); - } - - /* Translation stops when a conditional branch is encountered. - * Otherwise the subsequent code could get translated several times. - * Also stop translation when a page boundary is reached. This - * ensures prefetch aborts occur at the right place. */ - - /* We want to stop the TB if the next insn starts in a new page, - * or if it spans between this page and the next. This means that - * if we're looking at the last halfword in the page we need to - * see if it's a 16-bit Thumb insn (which will fit in this TB) - * or a 32-bit Thumb insn (which won't). - * This is to avoid generating a silly TB with a single 16-bit insn - * in it at the end of this page (which would execute correctly - * but isn't very efficient). - */ - end_of_page = (dc->pc >= next_page_start) || - ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc)); - - } while (!dc->is_jmp && !tcg_op_buf_full() && - !cs->singlestep_enabled && - !singlestep && - !dc->ss_active && - !end_of_page && - num_insns < max_insns); - - if (tb->cflags & CF_LAST_IO) { - if (dc->condjmp) { - /* FIXME: This can theoretically happen with self-modifying - code. */ - cpu_abort(cs, "IO on conditional branch instruction"); - } - gen_io_end(); - } - - /* At this stage dc->condjmp will only be set when the skipped - instruction was a conditional branch or trap, and the PC has - already been written. */ - if (unlikely(cs->singlestep_enabled || dc->ss_active)) { - /* Make sure the pc is updated, and raise a debug exception. */ - if (dc->condjmp) { - gen_set_condexec(dc); - if (dc->is_jmp == DISAS_SWI) { - gen_ss_advance(dc); - gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), - default_exception_el(dc)); - } else if (dc->is_jmp == DISAS_HVC) { - gen_ss_advance(dc); - gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); - } else if (dc->is_jmp == DISAS_SMC) { - gen_ss_advance(dc); - gen_exception(EXCP_SMC, syn_aa32_smc(), 3); - } else if (dc->ss_active) { - gen_step_complete_exception(dc); - } else { - gen_exception_internal(EXCP_DEBUG); - } - gen_set_label(dc->condlabel); - } - if (dc->condjmp || dc->is_jmp == DISAS_NEXT || - dc->is_jmp == DISAS_UPDATE) { - gen_set_pc_im(dc, dc->pc); - dc->condjmp = 0; - } - gen_set_condexec(dc); - if (dc->is_jmp == DISAS_SWI && !dc->condjmp) { - gen_ss_advance(dc); - gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), - default_exception_el(dc)); - } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) { - gen_ss_advance(dc); - gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); - } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) { - gen_ss_advance(dc); - gen_exception(EXCP_SMC, syn_aa32_smc(), 3); - } else if (dc->ss_active) { - gen_step_complete_exception(dc); - } else { - /* FIXME: Single stepping a WFI insn will not halt - the CPU. */ - gen_exception_internal(EXCP_DEBUG); - } - } else { - /* While branches must always occur at the end of an IT block, - there are a few other things that can cause us to terminate - the TB in the middle of an IT block: - - Exception generating instructions (bkpt, swi, undefined). - - Page boundaries. - - Hardware watchpoints. - Hardware breakpoints have already been handled and skip this code. - */ - gen_set_condexec(dc); - switch(dc->is_jmp) { - case DISAS_NEXT: - gen_goto_tb(dc, 1, dc->pc); - break; - case DISAS_UPDATE: - gen_set_pc_im(dc, dc->pc); - /* fall through */ - case DISAS_JUMP: - default: - /* indicate that the hash table must be used to find the next TB */ - tcg_gen_exit_tb(0); - break; - case DISAS_TB_JUMP: - /* nothing more to generate */ - break; - case DISAS_WFI: - gen_helper_wfi(cpu_env); - /* The helper doesn't necessarily throw an exception, but we - * must go back to the main loop to check for interrupts anyway. - */ - tcg_gen_exit_tb(0); - break; - case DISAS_WFE: - gen_helper_wfe(cpu_env); - break; - case DISAS_YIELD: - gen_helper_yield(cpu_env); - break; - case DISAS_SWI: - gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), - default_exception_el(dc)); - break; - case DISAS_HVC: - gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); - break; - case DISAS_SMC: - gen_exception(EXCP_SMC, syn_aa32_smc(), 3); - break; - } - if (dc->condjmp) { - gen_set_label(dc->condlabel); - gen_set_condexec(dc); - gen_goto_tb(dc, 1, dc->pc); - dc->condjmp = 0; - } - } - -done_generating: - gen_tb_end(tb, num_insns); - -#ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { - qemu_log("----------------\n"); - qemu_log("IN: %s\n", lookup_symbol(pc_start)); - log_target_disas(cs, pc_start, dc->pc - pc_start, - dc->thumb | (dc->bswap_code << 1)); - qemu_log("\n"); - } -#endif - tb->size = dc->pc - pc_start; - tb->icount = num_insns; -} - -static const char *cpu_mode_names[16] = { - "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt", - "???", "???", "hyp", "und", "???", "???", "???", "sys" -}; - -void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, - int flags) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - int i; - uint32_t psr; - const char *ns_status; - - if (is_a64(env)) { - aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags); - return; - } - - for(i=0;i<16;i++) { - cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]); - if ((i % 4) == 3) - cpu_fprintf(f, "\n"); - else - cpu_fprintf(f, " "); - } - psr = cpsr_read(env); - - if (arm_feature(env, ARM_FEATURE_EL3) && - (psr & CPSR_M) != ARM_CPU_MODE_MON) { - ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S "; - } else { - ns_status = ""; - } - - cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n", - psr, - psr & (1 << 31) ? 'N' : '-', - psr & (1 << 30) ? 'Z' : '-', - psr & (1 << 29) ? 'C' : '-', - psr & (1 << 28) ? 'V' : '-', - psr & CPSR_T ? 'T' : 'A', - ns_status, - cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26); - - if (flags & CPU_DUMP_FPU) { - int numvfpregs = 0; - if (arm_feature(env, ARM_FEATURE_VFP)) { - numvfpregs += 16; - } - if (arm_feature(env, ARM_FEATURE_VFP3)) { - numvfpregs += 16; - } - for (i = 0; i < numvfpregs; i++) { - uint64_t v = float64_val(env->vfp.regs[i]); - cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n", - i * 2, (uint32_t)v, - i * 2 + 1, (uint32_t)(v >> 32), - i, v); - } - cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); - } - - /* When doing the 'mon info registers' command, we get passed the CPU_DUMP_FPU flag. - * There is not flag for supervisor registers, but include those if asked for the FPU - * registers */ - if (flags & CPU_DUMP_FPU) { - cpu_fprintf(f, "xPSR: %08x\n", xpsr_read(env)); - cpu_fprintf(f, "MSP: %08x\n", - env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]); - cpu_fprintf(f, "PSP: %08x\n", - env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp); - cpu_fprintf(f, "PRIMASK: %08x\n", (env->daif & PSTATE_I) != 0); - cpu_fprintf(f, "BASEPRI: %08x\n", env->v7m.basepri); - cpu_fprintf(f, "FAULTMASK: %08x\n", (env->daif & PSTATE_F) != 0); - cpu_fprintf(f, "CONTROL: %08x\n", env->v7m.control); - } -} - -void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, - target_ulong *data) -{ - if (is_a64(env)) { - env->pc = data[0]; - env->condexec_bits = 0; - } else { - env->regs[15] = data[0]; - env->condexec_bits = data[1]; - } -} diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 2e15eca3c5b07..0000000000000 --- a/tests/Makefile +++ /dev/null @@ -1,674 +0,0 @@ -export SRC_PATH - -qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py - -# Get the list of all supported sysemu targets -SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \ - $(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak))) - -check-unit-y = tests/check-qdict$(EXESUF) -gcov-files-check-qdict-y = qobject/qdict.c -check-unit-y += tests/check-qfloat$(EXESUF) -gcov-files-check-qfloat-y = qobject/qfloat.c -check-unit-y += tests/check-qint$(EXESUF) -gcov-files-check-qint-y = qobject/qint.c -check-unit-y += tests/check-qstring$(EXESUF) -gcov-files-check-qstring-y = qobject/qstring.c -check-unit-y += tests/check-qlist$(EXESUF) -gcov-files-check-qlist-y = qobject/qlist.c -check-unit-y += tests/check-qjson$(EXESUF) -gcov-files-check-qjson-y = qobject/qjson.c -check-unit-y += tests/test-qmp-output-visitor$(EXESUF) -gcov-files-test-qmp-output-visitor-y = qapi/qmp-output-visitor.c -check-unit-y += tests/test-qmp-input-visitor$(EXESUF) -gcov-files-test-qmp-input-visitor-y = qapi/qmp-input-visitor.c -check-unit-y += tests/test-qmp-input-strict$(EXESUF) -check-unit-y += tests/test-qmp-commands$(EXESUF) -gcov-files-test-qmp-commands-y = qapi/qmp-dispatch.c -check-unit-y += tests/test-string-input-visitor$(EXESUF) -gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c -check-unit-y += tests/test-string-output-visitor$(EXESUF) -gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c -check-unit-y += tests/test-qmp-event$(EXESUF) -gcov-files-test-qmp-event-y += qapi/qmp-event.c -check-unit-y += tests/test-opts-visitor$(EXESUF) -gcov-files-test-opts-visitor-y = qapi/opts-visitor.c -check-unit-y += tests/test-coroutine$(EXESUF) -gcov-files-test-coroutine-y = coroutine-$(CONFIG_COROUTINE_BACKEND).c -check-unit-y += tests/test-visitor-serialization$(EXESUF) -check-unit-y += tests/test-iov$(EXESUF) -gcov-files-test-iov-y = util/iov.c -check-unit-y += tests/test-aio$(EXESUF) -check-unit-$(CONFIG_POSIX) += tests/test-rfifolock$(EXESUF) -check-unit-y += tests/test-throttle$(EXESUF) -gcov-files-test-aio-$(CONFIG_WIN32) = aio-win32.c -gcov-files-test-aio-$(CONFIG_POSIX) = aio-posix.c -check-unit-y += tests/test-thread-pool$(EXESUF) -gcov-files-test-thread-pool-y = thread-pool.c -gcov-files-test-hbitmap-y = util/hbitmap.c -check-unit-y += tests/test-hbitmap$(EXESUF) -gcov-files-test-hbitmap-y = blockjob.c -check-unit-y += tests/test-blockjob-txn$(EXESUF) -check-unit-y += tests/test-x86-cpuid$(EXESUF) -# all code tested by test-x86-cpuid is inside topology.h -gcov-files-test-x86-cpuid-y = -ifeq ($(CONFIG_SOFTMMU),y) -check-unit-y += tests/test-xbzrle$(EXESUF) -gcov-files-test-xbzrle-y = migration/xbzrle.c -check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF) -endif -check-unit-y += tests/test-cutils$(EXESUF) -gcov-files-test-cutils-y += util/cutils.c -check-unit-y += tests/test-mul64$(EXESUF) -gcov-files-test-mul64-y = util/host-utils.c -check-unit-y += tests/test-int128$(EXESUF) -# all code tested by test-int128 is inside int128.h -gcov-files-test-int128-y = -check-unit-y += tests/rcutorture$(EXESUF) -gcov-files-rcutorture-y = util/rcu.c -check-unit-y += tests/test-rcu-list$(EXESUF) -gcov-files-test-rcu-list-y = util/rcu.c -check-unit-y += tests/test-bitops$(EXESUF) -check-unit-$(CONFIG_HAS_GLIB_SUBPROCESS_TESTS) += tests/test-qdev-global-props$(EXESUF) -check-unit-y += tests/check-qom-interface$(EXESUF) -gcov-files-check-qom-interface-y = qom/object.c -check-unit-y += tests/check-qom-proplist$(EXESUF) -gcov-files-check-qom-proplist-y = qom/object.c -check-unit-y += tests/test-qemu-opts$(EXESUF) -gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c -check-unit-y += tests/test-write-threshold$(EXESUF) -gcov-files-test-write-threshold-y = block/write-threshold.c -check-unit-$(CONFIG_GNUTLS_HASH) += tests/test-crypto-hash$(EXESUF) -check-unit-y += tests/test-crypto-cipher$(EXESUF) -check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF) -check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF) -check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF) -check-unit-y += tests/test-timed-average$(EXESUF) - -check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh - -# All QTests for now are POSIX-only, but the dependencies are -# really in libqtest, not in the testcases themselves. - -check-qtest-generic-y = tests/device-introspect-test$(EXESUF) -gcov-files-generic-y = qdev-monitor.c qmp.c - -gcov-files-ipack-y += hw/ipack/ipack.c -check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF) -gcov-files-ipack-y += hw/char/ipoctal232.c - -check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF) -gcov-files-virtioserial-y += hw/char/virtio-console.c - -gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c -check-qtest-virtio-y += tests/virtio-net-test$(EXESUF) -gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c -check-qtest-virtio-y += tests/virtio-balloon-test$(EXESUF) -gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio-balloon.c -check-qtest-virtio-y += tests/virtio-blk-test$(EXESUF) -gcov-files-virtio-y += i386-softmmu/hw/block/virtio-blk.c -check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF) -gcov-files-virtio-y += hw/virtio/virtio-rng.c -check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF) -gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c -ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) -check-qtest-virtio-y += tests/virtio-9p-test$(EXESUF) -gcov-files-virtio-y += hw/9pfs/virtio-9p.c -gcov-files-virtio-y += i386-softmmu/hw/9pfs/virtio-9p-device.c -endif -check-qtest-virtio-y += tests/virtio-serial-test$(EXESUF) -gcov-files-virtio-y += i386-softmmu/hw/char/virtio-serial-bus.c -check-qtest-virtio-y += $(check-qtest-virtioserial-y) -gcov-files-virtio-y += $(gcov-files-virtioserial-y) - -check-qtest-pci-y += tests/e1000-test$(EXESUF) -gcov-files-pci-y += hw/net/e1000.c -check-qtest-pci-y += tests/rtl8139-test$(EXESUF) -gcov-files-pci-y += hw/net/rtl8139.c -check-qtest-pci-y += tests/pcnet-test$(EXESUF) -gcov-files-pci-y += hw/net/pcnet.c -gcov-files-pci-y += hw/net/pcnet-pci.c -check-qtest-pci-y += tests/eepro100-test$(EXESUF) -gcov-files-pci-y += hw/net/eepro100.c -check-qtest-pci-y += tests/ne2000-test$(EXESUF) -gcov-files-pci-y += hw/net/ne2000.c -check-qtest-pci-y += tests/nvme-test$(EXESUF) -gcov-files-pci-y += hw/block/nvme.c -check-qtest-pci-y += tests/ac97-test$(EXESUF) -gcov-files-pci-y += hw/audio/ac97.c -check-qtest-pci-y += tests/es1370-test$(EXESUF) -gcov-files-pci-y += hw/audio/es1370.c -check-qtest-pci-y += $(check-qtest-virtio-y) -gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c -check-qtest-pci-y += tests/tpci200-test$(EXESUF) -gcov-files-pci-y += hw/ipack/tpci200.c -check-qtest-pci-y += $(check-qtest-ipack-y) -gcov-files-pci-y += $(gcov-files-ipack-y) -check-qtest-pci-y += tests/display-vga-test$(EXESUF) -gcov-files-pci-y += hw/display/vga.c -gcov-files-pci-y += hw/display/cirrus_vga.c -gcov-files-pci-y += hw/display/vga-pci.c -gcov-files-pci-y += hw/display/virtio-gpu.c -gcov-files-pci-y += hw/display/virtio-gpu-pci.c -gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c -check-qtest-pci-y += tests/intel-hda-test$(EXESUF) -gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c -check-qtest-pci-$(CONFIG_POSIX) += tests/ivshmem-test$(EXESUF) -gcov-files-pci-y += hw/misc/ivshmem.c - -check-qtest-i386-y = tests/endianness-test$(EXESUF) -check-qtest-i386-y += tests/fdc-test$(EXESUF) -gcov-files-i386-y = hw/block/fdc.c -check-qtest-i386-y += tests/ide-test$(EXESUF) -check-qtest-i386-y += tests/ahci-test$(EXESUF) -check-qtest-i386-y += tests/hd-geo-test$(EXESUF) -gcov-files-i386-y += hw/block/hd-geometry.c -check-qtest-i386-y += tests/boot-order-test$(EXESUF) -check-qtest-i386-y += tests/bios-tables-test$(EXESUF) -check-qtest-i386-y += tests/rtc-test$(EXESUF) -check-qtest-i386-y += tests/i440fx-test$(EXESUF) -check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) -check-qtest-i386-y += tests/drive_del-test$(EXESUF) -check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF) -check-qtest-i386-y += tests/tco-test$(EXESUF) -gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c -check-qtest-i386-y += $(check-qtest-pci-y) -gcov-files-i386-y += $(gcov-files-pci-y) -check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) -gcov-files-i386-y += hw/net/vmxnet3.c -gcov-files-i386-y += hw/net/vmxnet_rx_pkt.c -gcov-files-i386-y += hw/net/vmxnet_tx_pkt.c -check-qtest-i386-y += tests/pvpanic-test$(EXESUF) -gcov-files-i386-y += i386-softmmu/hw/misc/pvpanic.c -check-qtest-i386-y += tests/i82801b11-test$(EXESUF) -gcov-files-i386-y += hw/pci-bridge/i82801b11.c -check-qtest-i386-y += tests/ioh3420-test$(EXESUF) -gcov-files-i386-y += hw/pci-bridge/ioh3420.c -check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF) -gcov-files-i386-y += hw/usb/hcd-ohci.c -check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF) -gcov-files-i386-y += hw/usb/hcd-uhci.c -check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF) -gcov-files-i386-y += hw/usb/hcd-ehci.c -gcov-files-i386-y += hw/usb/dev-hid.c -gcov-files-i386-y += hw/usb/dev-storage.c -check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF) -gcov-files-i386-y += hw/usb/hcd-xhci.c -check-qtest-i386-y += tests/pc-cpu-test$(EXESUF) -check-qtest-i386-y += tests/q35-test$(EXESUF) -gcov-files-i386-y += hw/pci-host/q35.c -check-qtest-i386-$(CONFIG_VHOST_NET_TEST_i386) += tests/vhost-user-test$(EXESUF) -ifeq ($(CONFIG_VHOST_NET_TEST_i386),) -check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += tests/vhost-user-test$(EXESUF) -endif -check-qtest-i386-y += tests/test-netfilter$(EXESUF) -check-qtest-x86_64-y = $(check-qtest-i386-y) -gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c -gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) -check-qtest-mips-y = tests/endianness-test$(EXESUF) -check-qtest-mips64-y = tests/endianness-test$(EXESUF) -check-qtest-mips64el-y = tests/endianness-test$(EXESUF) -check-qtest-ppc-y = tests/endianness-test$(EXESUF) -check-qtest-ppc64-y = tests/endianness-test$(EXESUF) -check-qtest-sh4-y = tests/endianness-test$(EXESUF) -check-qtest-sh4eb-y = tests/endianness-test$(EXESUF) -check-qtest-sparc64-y = tests/endianness-test$(EXESUF) -#check-qtest-sparc-y = tests/m48t59-test$(EXESUF) -#check-qtest-sparc64-y += tests/m48t59-test$(EXESUF) -gcov-files-sparc-y += hw/timer/m48t59.c -gcov-files-sparc64-y += hw/timer/m48t59.c -check-qtest-arm-y = tests/tmp105-test$(EXESUF) -gcov-files-arm-y += hw/misc/tmp105.c -check-qtest-arm-y += tests/ds1338-test$(EXESUF) -check-qtest-arm-y += tests/test-stm32$(EXESUF) -check-qtest-arm-y += tests/virtio-blk-test$(EXESUF) -gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c -check-qtest-ppc-y += tests/boot-order-test$(EXESUF) -check-qtest-ppc64-y += tests/boot-order-test$(EXESUF) -check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF) -gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c -check-qtest-microblazeel-y = $(check-qtest-microblaze-y) -check-qtest-xtensaeb-y = $(check-qtest-xtensa-y) - -check-qtest-generic-y += tests/qom-test$(EXESUF) - -qapi-schema += alternate-array.json -qapi-schema += alternate-base.json -qapi-schema += alternate-clash.json -qapi-schema += alternate-conflict-dict.json -qapi-schema += alternate-conflict-string.json -qapi-schema += alternate-empty.json -qapi-schema += alternate-nested.json -qapi-schema += alternate-unknown.json -qapi-schema += args-alternate.json -qapi-schema += args-any.json -qapi-schema += args-array-empty.json -qapi-schema += args-array-unknown.json -qapi-schema += args-int.json -qapi-schema += args-invalid.json -qapi-schema += args-member-array-bad.json -qapi-schema += args-member-unknown.json -qapi-schema += args-name-clash.json -qapi-schema += args-union.json -qapi-schema += args-unknown.json -qapi-schema += bad-base.json -qapi-schema += bad-data.json -qapi-schema += bad-ident.json -qapi-schema += bad-type-bool.json -qapi-schema += bad-type-dict.json -qapi-schema += bad-type-int.json -qapi-schema += command-int.json -qapi-schema += comments.json -qapi-schema += double-data.json -qapi-schema += double-type.json -qapi-schema += duplicate-key.json -qapi-schema += empty.json -qapi-schema += enum-bad-name.json -qapi-schema += enum-bad-prefix.json -qapi-schema += enum-clash-member.json -qapi-schema += enum-dict-member.json -qapi-schema += enum-int-member.json -qapi-schema += enum-max-member.json -qapi-schema += enum-missing-data.json -qapi-schema += enum-wrong-data.json -qapi-schema += escape-outside-string.json -qapi-schema += escape-too-big.json -qapi-schema += escape-too-short.json -qapi-schema += event-case.json -qapi-schema += event-max.json -qapi-schema += event-nest-struct.json -qapi-schema += flat-union-array-branch.json -qapi-schema += flat-union-bad-base.json -qapi-schema += flat-union-bad-discriminator.json -qapi-schema += flat-union-base-any.json -qapi-schema += flat-union-base-union.json -qapi-schema += flat-union-clash-branch.json -qapi-schema += flat-union-clash-member.json -qapi-schema += flat-union-clash-type.json -qapi-schema += flat-union-empty.json -qapi-schema += flat-union-inline.json -qapi-schema += flat-union-int-branch.json -qapi-schema += flat-union-invalid-branch-key.json -qapi-schema += flat-union-invalid-discriminator.json -qapi-schema += flat-union-no-base.json -qapi-schema += flat-union-optional-discriminator.json -qapi-schema += flat-union-string-discriminator.json -qapi-schema += funny-char.json -qapi-schema += ident-with-escape.json -qapi-schema += include-before-err.json -qapi-schema += include-cycle.json -qapi-schema += include-format-err.json -qapi-schema += include-nested-err.json -qapi-schema += include-no-file.json -qapi-schema += include-non-file.json -qapi-schema += include-relpath.json -qapi-schema += include-repetition.json -qapi-schema += include-self-cycle.json -qapi-schema += include-simple.json -qapi-schema += indented-expr.json -qapi-schema += leading-comma-list.json -qapi-schema += leading-comma-object.json -qapi-schema += missing-colon.json -qapi-schema += missing-comma-list.json -qapi-schema += missing-comma-object.json -qapi-schema += missing-type.json -qapi-schema += nested-struct-data.json -qapi-schema += non-objects.json -qapi-schema += qapi-schema-test.json -qapi-schema += quoted-structural-chars.json -qapi-schema += redefined-builtin.json -qapi-schema += redefined-command.json -qapi-schema += redefined-event.json -qapi-schema += redefined-type.json -qapi-schema += reserved-command-q.json -qapi-schema += reserved-member-has.json -qapi-schema += reserved-member-q.json -qapi-schema += reserved-member-u.json -qapi-schema += reserved-type-kind.json -qapi-schema += reserved-type-list.json -qapi-schema += returns-alternate.json -qapi-schema += returns-array-bad.json -qapi-schema += returns-dict.json -qapi-schema += returns-unknown.json -qapi-schema += returns-whitelist.json -qapi-schema += struct-base-clash-deep.json -qapi-schema += struct-base-clash.json -qapi-schema += struct-data-invalid.json -qapi-schema += struct-member-invalid.json -qapi-schema += trailing-comma-list.json -qapi-schema += trailing-comma-object.json -qapi-schema += type-bypass-bad-gen.json -qapi-schema += unclosed-list.json -qapi-schema += unclosed-object.json -qapi-schema += unclosed-string.json -qapi-schema += unicode-str.json -qapi-schema += union-bad-branch.json -qapi-schema += union-base-no-discriminator.json -qapi-schema += union-clash-branches.json -qapi-schema += union-clash-data.json -qapi-schema += union-clash-type.json -qapi-schema += union-empty.json -qapi-schema += union-invalid-base.json -qapi-schema += union-max.json -qapi-schema += union-optional-branch.json -qapi-schema += union-unknown.json -qapi-schema += unknown-escape.json -qapi-schema += unknown-expr-key.json -check-qapi-schema-y := $(addprefix tests/qapi-schema/, $(qapi-schema)) - -GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \ - tests/test-qmp-commands.h tests/test-qapi-event.h \ - tests/test-qmp-introspect.h - -test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ - tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \ - tests/test-coroutine.o tests/test-string-output-visitor.o \ - tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \ - tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ - tests/test-qmp-commands.o tests/test-visitor-serialization.o \ - tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \ - tests/test-opts-visitor.o tests/test-qmp-event.o \ - tests/rcutorture.o tests/test-rcu-list.o - -$(test-obj-y): QEMU_INCLUDES += -Itests -QEMU_CFLAGS += -I$(SRC_PATH)/tests - - -# Deps that are common to various different sets of tests below -test-util-obj-y = libqemuutil.a libqemustub.a -test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y) -test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \ - tests/test-qapi-event.o tests/test-qmp-introspect.o \ - $(test-qom-obj-y) -test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y) -test-block-obj-y = $(block-obj-y) $(test-crypto-obj-y) - -tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y) -tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y) -tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y) -tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y) -tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y) -tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y) -tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) -tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y) -tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y) -tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y) -tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o $(test-util-obj-y) -tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y) -tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y) -tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y) -tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y) -tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) -tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o -tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o page_cache.o $(test-util-obj-y) -tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o -tests/test-int128$(EXESUF): tests/test-int128.o -tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y) -tests/test-rcu-list$(EXESUF): tests/test-rcu-list.o $(test-util-obj-y) - -tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ - hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\ - hw/core/irq.o \ - hw/core/fw-path-provider.o \ - $(test-qapi-obj-y) -tests/test-vmstate$(EXESUF): tests/test-vmstate.o \ - migration/vmstate.o migration/qemu-file.o migration/qemu-file-buf.o \ - migration/qemu-file-unix.o qjson.o \ - $(test-qom-obj-y) -tests/test-timed-average$(EXESUF): tests/test-timed-average.o qemu-timer.o \ - $(test-util-obj-y) - -tests/test-qapi-types.c tests/test-qapi-types.h :\ -$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \ - $(gen-out-type) -o tests -p "test-" $<, \ - " GEN $@") -tests/test-qapi-visit.c tests/test-qapi-visit.h :\ -$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \ - $(gen-out-type) -o tests -p "test-" $<, \ - " GEN $@") -tests/test-qmp-commands.h tests/test-qmp-marshal.c :\ -$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \ - $(gen-out-type) -o tests -p "test-" $<, \ - " GEN $@") -tests/test-qapi-event.c tests/test-qapi-event.h :\ -$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py $(qapi-py) - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \ - $(gen-out-type) -o tests -p "test-" $<, \ - " GEN $@") -tests/test-qmp-introspect.c tests/test-qmp-introspect.h :\ -$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py) - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-introspect.py \ - $(gen-out-type) -o tests -p "test-" $<, \ - " GEN $@") - -tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) -tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) -tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) -tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) -tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) -tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) -tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) -tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) -tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) - -tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y) -tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y) -tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y) -tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y) - -tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS) -tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS) -tests/pkix_asn1_tab.o-cflags := $(TASN1_CFLAGS) - -tests/test-crypto-tlscredsx509.o-cflags := $(TASN1_CFLAGS) -tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \ - tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) - -tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS) -tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \ - tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) - -libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o -libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o -libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o -libqos-pc-obj-y += tests/libqos/malloc-pc.o tests/libqos/libqos-pc.o -libqos-pc-obj-y += tests/libqos/ahci.o -libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o -libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o -libqos-usb-obj-y = $(libqos-pc-obj-y) tests/libqos/usb.o -libqos-virtio-obj-y = $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o - -tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o -tests/rtc-test$(EXESUF): tests/rtc-test.o -tests/m48t59-test$(EXESUF): tests/m48t59-test.o -tests/endianness-test$(EXESUF): tests/endianness-test.o -tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) -tests/fdc-test$(EXESUF): tests/fdc-test.o -tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y) -tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) -tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o -tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y) -tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o $(libqos-obj-y) -tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) -tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y) -tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y) -tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y) -tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) -tests/e1000-test$(EXESUF): tests/e1000-test.o -tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y) -tests/pcnet-test$(EXESUF): tests/pcnet-test.o -tests/eepro100-test$(EXESUF): tests/eepro100-test.o -tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o -tests/ne2000-test$(EXESUF): tests/ne2000-test.o -tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o -tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y) -tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o -tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o $(libqos-virtio-obj-y) -tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o $(libqos-pc-obj-y) $(libqos-virtio-obj-y) -tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o $(libqos-pc-obj-y) -tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y) -tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o -tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o -tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o -tests/tpci200-test$(EXESUF): tests/tpci200-test.o -tests/display-vga-test$(EXESUF): tests/display-vga-test.o -tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o -tests/qom-test$(EXESUF): tests/qom-test.o -tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-pc-obj-y) -tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y) -tests/nvme-test$(EXESUF): tests/nvme-test.o -tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o -tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o -tests/ac97-test$(EXESUF): tests/ac97-test.o -tests/es1370-test$(EXESUF): tests/es1370-test.o -tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o -tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o -tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) -tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y) -tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y) -tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y) -tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o -tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) -tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o -tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y) -tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y) -tests/test-stm32$(EXESUF): tests/test-stm32.o -tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y) -tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) -tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o - -ifeq ($(CONFIG_POSIX),y) -LIBS += -lutil -endif - -# QTest rules - -TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS))) -ifeq ($(CONFIG_POSIX),y) -QTEST_TARGETS = $(TARGETS) -check-qtest-y=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) -check-qtest-y += $(check-qtest-generic-y) -else -QTEST_TARGETS = -endif - -qtest-obj-y = tests/libqtest.o $(test-util-obj-y) -$(check-qtest-y): $(qtest-obj-y) - -tests/test-qga: tests/test-qga.o $(qtest-obj-y) - -.PHONY: check-help -check-help: - @echo "Regression testing targets:" - @echo - @echo " make check Run all tests" - @echo " make check-qtest-TARGET Run qtest tests for given target" - @echo " make check-qtest Run qtest tests" - @echo " make check-unit Run qobject tests" - @echo " make check-qapi-schema Run QAPI schema tests" - @echo " make check-block Run block tests" - @echo " make check-report.html Generates an HTML test report" - @echo " make check-clean Clean the tests" - @echo - @echo "Please note that HTML reports do not regenerate if the unit tests" - @echo "has not changed." - @echo - @echo "The variable SPEED can be set to control the gtester speed setting." - @echo "Default options are -k and (for make V=1) --verbose; they can be" - @echo "changed with variable GTESTER_OPTIONS." - -SPEED = quick -GTESTER_OPTIONS = -k $(if $(V),--verbose,-q) -GCOV_OPTIONS = -n $(if $(V),-f,) - -# gtester tests, possibly with verbose output - -.PHONY: $(patsubst %, check-qtest-%, $(QTEST_TARGETS)) -$(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y) - $(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,) - $(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \ - QTEST_QEMU_IMG=qemu-img$(EXESUF) \ - MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \ - gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y) $(check-qtest-generic-y),"GTESTER $@") - $(if $(CONFIG_GCOV),@for f in $(gcov-files-$*-y) $(gcov-files-generic-y); do \ - echo Gcov report for $$f:;\ - $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \ - done,) - -.PHONY: $(patsubst %, check-%, $(check-unit-y)) -$(patsubst %, check-%, $(check-unit-y)): check-%: % - $(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,) - $(call quiet-command, \ - MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \ - gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*") - $(if $(CONFIG_GCOV),@for f in $(gcov-files-$(subst tests/,,$*)-y) $(gcov-files-generic-y); do \ - echo Gcov report for $$f:;\ - $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \ - done,) - -# gtester tests with XML output - -$(patsubst %, check-report-qtest-%.xml, $(QTEST_TARGETS)): check-report-qtest-%.xml: $(check-qtest-y) - $(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \ - QTEST_QEMU_IMG=qemu-img$(EXESUF) \ - gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $(check-qtest-$*-y) $(check-qtest-generic-y),"GTESTER $@") - -check-report-unit.xml: $(check-unit-y) - $(call quiet-command,gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $^, "GTESTER $@") - -# Reports and overall runs - -check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check-report-unit.xml - $(call quiet-command,$(SRC_PATH)/scripts/gtester-cat $^ > $@, " GEN $@") - -check-report.html: check-report.xml - $(call quiet-command,gtester-report $< > $@, " GEN $@") - - -# Other tests - -QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = tests/qemu-iotests/socket_scm_helper$(EXESUF) - -.PHONY: check-tests/qemu-iotests-quick.sh -check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) $(QEMU_IOTESTS_HELPERS-y) - $< - -.PHONY: check-tests/test-qapi.py -check-tests/test-qapi.py: tests/test-qapi.py - -.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y)) -$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json - $(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \ - $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \ - $^ >$*.test.out 2>$*.test.err; \ - echo $$? >$*.test.exit, \ - " TEST $*.out") - @diff -q $(SRC_PATH)/$*.out $*.test.out - @# Sanitize error messages (make them independent of build directory) - @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -q $(SRC_PATH)/$*.err - - @diff -q $(SRC_PATH)/$*.exit $*.test.exit - -# Consolidated targets - -.PHONY: check-qapi-schema check-qtest check-unit check check-clean -check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y)) -check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS)) -check-unit: $(patsubst %,check-%, $(check-unit-y)) -check-block: $(patsubst %,check-%, $(check-block-y)) -check: check-qapi-schema check-unit check-qtest -check-clean: - $(MAKE) -C tests/tcg clean - rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y) - rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), $(check-qtest-$(target)-y)) $(check-qtest-generic-y)) - -clean: check-clean - -# Build the help program automatically - -all: $(QEMU_IOTESTS_HELPERS-y) - --include $(wildcard tests/*.d) --include $(wildcard tests/libqos/*.d) diff --git a/tests/libqtest.c b/tests/libqtest.c deleted file mode 100644 index da212d2efde06..0000000000000 --- a/tests/libqtest.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * QTest - * - * Copyright IBM, Corp. 2012 - * Copyright Red Hat, Inc. 2012 - * Copyright SUSE LINUX Products GmbH 2013 - * - * Authors: - * Anthony Liguori - * Paolo Bonzini - * Andreas Färber - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ -#include "libqtest.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qemu/compiler.h" -#include "qemu/osdep.h" -#include "qapi/qmp/json-parser.h" -#include "qapi/qmp/json-streamer.h" -#include "qapi/qmp/qjson.h" - -#define MAX_GPIO_INTERCEPTS 20 -#define MAX_IRQ 256 -#define SOCKET_TIMEOUT 5 - -QTestState *global_qtest; - -typedef struct SocketInfo -{ - int sock; - int fd; - const char *path; -} SocketInfo; - - -struct QTestState -{ - bool irq_level[MAX_GPIO_INTERCEPTS][MAX_IRQ]; - GString *rx; - pid_t qemu_pid; /* our child QEMU process */ - - // beckus - stm32 specific stuff - /////////////////////////////////////////////// - gpio_id last_intercept_gpio_id; - - // replaces the fd member in upstread - SocketInfo qtest_socket; - // replaces the qmp_fd member in upstream - SocketInfo qmp_socket; - - int num_serial_ports; - SocketInfo *serial_port_sockets; -}; - -static GHookList abrt_hooks; -static GList *qtest_instances; -static struct sigaction sigact_old; - -#define g_assert_no_errno(ret) do { \ - g_assert_cmpint(ret, !=, -1); \ -} while (0) - -static gchar *get_temp_file_path(const gchar *name) -{ - return g_strdup_printf("/tmp/qtest-%d.%s", getpid(), name); -} - -static void init_socket(SocketInfo *socket_info) -{ - struct sockaddr_un addr; - int sock; - int ret; - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - g_assert_no_errno(sock); - - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socket_info->path); - qemu_set_cloexec(sock); - - do { - ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)); - } while (ret == -1 && errno == EINTR); - g_assert_no_errno(ret); - ret = listen(sock, 1); - g_assert_no_errno(ret); - - socket_info->sock = sock; -} - -static void socket_accept(SocketInfo *socket_info) -{ - struct sockaddr_un addr; - socklen_t addrlen; - int sock = socket_info->sock; - int ret; - struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT, - .tv_usec = 0 }; - - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, - sizeof(timeout)); - - do { - addrlen = sizeof(addr); - ret = accept(sock, (struct sockaddr *)&addr, &addrlen); - } while (ret == -1 && errno == EINTR); - if (ret == -1) { - fprintf(stderr, "%s failed: %s\n", __func__, strerror(errno)); - } - close(sock); - - socket_info->fd = ret; -} - -static void kill_qemu(QTestState *s) -{ - if (s->qemu_pid != -1) { - kill(s->qemu_pid, SIGTERM); - waitpid(s->qemu_pid, NULL, 0); - } -} - -static void kill_qemu_hook_func(void *s) -{ - kill_qemu(s); -} - -static void sigabrt_handler(int signo) -{ - g_hook_list_invoke(&abrt_hooks, FALSE); -} - -static void setup_sigabrt_handler(void) -{ - struct sigaction sigact; - - /* Catch SIGABRT to clean up on g_assert() failure */ - sigact = (struct sigaction){ - .sa_handler = sigabrt_handler, - .sa_flags = SA_RESETHAND, - }; - sigemptyset(&sigact.sa_mask); - sigaction(SIGABRT, &sigact, &sigact_old); -} - -static void cleanup_sigabrt_handler(void) -{ - sigaction(SIGABRT, &sigact_old, NULL); -} - -void qtest_add_abrt_handler(GHookFunc fn, const void *data) -{ - GHook *hook; - - /* Only install SIGABRT handler once */ - if (!abrt_hooks.is_setup) { - g_hook_list_init(&abrt_hooks, sizeof(GHook)); - setup_sigabrt_handler(); - } - - hook = g_hook_alloc(&abrt_hooks); - hook->func = fn; - hook->data = (void *)data; - - g_hook_prepend(&abrt_hooks, hook); -} - -QTestState *qtest_init(const char *extra_args, int num_serial_ports) -{ - QTestState *s; - int i, j; - gchar *command; - GString *extra_socket_args; - const char *qemu_binary, *external_args, *qtest_log_path; - - qemu_binary = getenv("QTEST_QEMU_BINARY"); - g_assert(qemu_binary != NULL); - - external_args = getenv("QTEST_QEMU_ARGS"); - qtest_log_path = getenv("QTEST_LOG_FILE"); - - s = g_malloc(sizeof(*s)); - - s->qtest_socket.path = get_temp_file_path("sock"); - s->qmp_socket.path = get_temp_file_path("qmp"); - - init_socket(&s->qtest_socket); - init_socket(&s->qmp_socket); - - qtest_add_abrt_handler(kill_qemu_hook_func, s); - - s->num_serial_ports = num_serial_ports; - s->serial_port_sockets = g_malloc(num_serial_ports * sizeof(SocketInfo)); - extra_socket_args = g_string_new(""); - for(i = 0; i < num_serial_ports; i++) { - gchar *serial_socket_path; - gchar *socket_name = g_strdup_printf("serial%d", i); - serial_socket_path = get_temp_file_path(socket_name); - s->serial_port_sockets[i].path = serial_socket_path; - g_string_append_printf(extra_socket_args, - "-serial unix:%s,nowait ", - serial_socket_path); - init_socket(&s->serial_port_sockets[i]); - } - - s->qemu_pid = fork(); - if (s->qemu_pid == 0) { - setenv("QEMU_AUDIO_DRV", "none", true); - command = g_strdup_printf("exec %s " - "-qtest unix:%s,nowait " - "-qtest-log %s " - "-qmp unix:%s,nowait " - "-machine accel=qtest " - "-display none " - "%s " - "%s " - "%s", - qemu_binary, - s->qtest_socket.path, - qtest_log_path ?: "/dev/null", - s->qmp_socket.path, - extra_socket_args->str, - extra_args ?: "", - external_args ?: ""); - //printf("%s\n", command); - execlp("/bin/sh", "sh", "-c", command, NULL); - exit(1); - } - - socket_accept(&s->qtest_socket); - socket_accept(&s->qmp_socket); - for(i = 0; i < num_serial_ports; i++) { - socket_accept(&s->serial_port_sockets[i]); - } - - s->rx = g_string_new(""); - - s->last_intercept_gpio_id = -1; - for(i = 0; i < MAX_GPIO_INTERCEPTS; i++) { - for (j = 0; j < MAX_IRQ; j++) { - s->irq_level[i][j] = false; - } - } - - - /* Read the QMP greeting and then do the handshake */ - qtest_qmp_discard_response(s, ""); - qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }"); - - if (getenv("QTEST_STOP")) { - kill(s->qemu_pid, SIGSTOP); - } - - g_string_free(extra_socket_args, true); - - return s; -} - -void qtest_quit(QTestState *s) -{ - int i; - - qtest_instances = g_list_remove(qtest_instances, s); - g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s)); - - /* Uninstall SIGABRT handler on last instance */ - if (!qtest_instances) { - cleanup_sigabrt_handler(); - } - - kill_qemu(s); - unlink(s->qtest_socket.path); - unlink(s->qmp_socket.path); - close(s->qtest_socket.fd); - close(s->qmp_socket.fd); - for(i = 0; i < s->num_serial_ports; i++) { - unlink(s->serial_port_sockets[i].path); - } - g_free(s->serial_port_sockets); - g_string_free(s->rx, true); - g_free(s); -} - -static void socket_send(int fd, const char *buf, size_t size) -{ - size_t offset; - - offset = 0; - while (offset < size) { - ssize_t len; - - len = write(fd, buf + offset, size - offset); - if (len == -1 && errno == EINTR) { - continue; - } - - g_assert_no_errno(len); - g_assert_cmpint(len, >, 0); - - offset += len; - } -} - -static void socket_sendf(int fd, const char *fmt, va_list ap) -{ - gchar *str = g_strdup_vprintf(fmt, ap); - size_t size = strlen(str); - - socket_send(fd, str, size); - g_free(str); -} - -static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - socket_sendf(s->qtest_socket.fd, fmt, ap); - va_end(ap); -} - -static GString *qtest_recv_line(QTestState *s) -{ - GString *line; - size_t offset; - char *eol; - - while ((eol = strchr(s->rx->str, '\n')) == NULL) { - ssize_t len; - char buffer[1024]; - - len = read(s->qtest_socket.fd, buffer, sizeof(buffer)); - if (len == -1 && errno == EINTR) { - continue; - } - - if (len == -1 || len == 0) { - fprintf(stderr, "Broken pipe\n"); - exit(1); - } - - g_string_append_len(s->rx, buffer, len); - } - - offset = eol - s->rx->str; - line = g_string_new_len(s->rx->str, offset); - g_string_erase(s->rx, 0, offset + 1); - - return line; -} - -static gchar **qtest_rsp(QTestState *s, int expected_args) -{ - GString *line; - gchar **words; - int i; - -redo: - line = qtest_recv_line(s); - words = g_strsplit(line->str, " ", 0); - if (strcmp(words[0], "FAIL") == 0) { - g_assert_cmpstr(line->str, ==, "OK"); - } - g_string_free(line, TRUE); - - if (strcmp(words[0], "IRQ") == 0) { - int irq; - gpio_id id; - - g_assert(words[1] != NULL); - g_assert(words[2] != NULL); - g_assert(words[3] != NULL); - - id = strtoul(words[2], NULL, 0); - g_assert_cmpint(id, >=, 0); - g_assert_cmpint(id, <, MAX_GPIO_INTERCEPTS); - - irq = strtoul(words[3], NULL, 0); - g_assert_cmpint(irq, >=, 0); - g_assert_cmpint(irq, <, MAX_IRQ); - - if (strcmp(words[1], "raise") == 0) { - s->irq_level[id][irq] = true; - } else { - s->irq_level[id][irq] = false; - } - - g_strfreev(words); - goto redo; - } - - g_assert(words[0] != NULL); - g_assert_cmpstr(words[0], ==, "OK"); - - if (expected_args) { - for (i = 0; i < expected_args; i++) { - g_assert(words[i] != NULL); - } - } else { - g_strfreev(words); - } - - return words; -} - -typedef struct { - JSONMessageParser parser; - QDict *response; -} QMPResponseParser; - -static void qmp_response(JSONMessageParser *parser, GQueue *tokens) -{ - QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser); - QObject *obj; - - obj = json_parser_parse(tokens, NULL); - if (!obj) { - fprintf(stderr, "QMP JSON response parsing failed\n"); - exit(1); - } - - g_assert(qobject_type(obj) == QTYPE_QDICT); - g_assert(!qmp->response); - qmp->response = (QDict *)obj; -} - -QDict *qmp_fd_receive(int fd) -{ - QMPResponseParser qmp; - bool log = getenv("QTEST_LOG") != NULL; - - qmp.response = NULL; - json_message_parser_init(&qmp.parser, qmp_response); - while (!qmp.response) { - ssize_t len; - char c; - - len = read(fd, &c, 1); - if (len == -1 && errno == EINTR) { - continue; - } - - if (len == -1 || len == 0) { - fprintf(stderr, "Broken pipe\n"); - exit(1); - } - - if (log) { - len = write(2, &c, 1); - } - json_message_parser_feed(&qmp.parser, &c, 1); - } - json_message_parser_destroy(&qmp.parser); - - return qmp.response; -} - -QDict *qtest_qmp_receive(QTestState *s) -{ - return qmp_fd_receive(s->qmp_socket.fd); -} - -/** - * Allow users to send a message without waiting for the reply, - * in the case that they choose to discard all replies up until - * a particular EVENT is received. - */ -void qmp_fd_sendv(int fd, const char *fmt, va_list ap) -{ - va_list ap_copy; - QObject *qobj; - - /* Going through qobject ensures we escape strings properly. - * This seemingly unnecessary copy is required in case va_list - * is an array type. - */ - va_copy(ap_copy, ap); - qobj = qobject_from_jsonv(fmt, &ap_copy); - va_end(ap_copy); - - /* No need to send anything for an empty QObject. */ - if (qobj) { - int log = getenv("QTEST_LOG") != NULL; - QString *qstr = qobject_to_json(qobj); - const char *str = qstring_get_str(qstr); - size_t size = qstring_get_length(qstr); - - if (log) { - fprintf(stderr, "%s", str); - } - /* Send QMP request */ - socket_send(fd, str, size); - - QDECREF(qstr); - qobject_decref(qobj); - } -} - -void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap) -{ - qmp_fd_sendv(s->qmp_socket.fd, fmt, ap); -} - -QDict *qmp_fdv(int fd, const char *fmt, va_list ap) -{ - qmp_fd_sendv(fd, fmt, ap); - - return qmp_fd_receive(fd); -} - -QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap) -{ - qtest_async_qmpv(s, fmt, ap); - - /* Receive reply */ - return qtest_qmp_receive(s); -} - -QDict *qmp_fd(int fd, const char *fmt, ...) -{ - va_list ap; - QDict *response; - - va_start(ap, fmt); - response = qmp_fdv(fd, fmt, ap); - va_end(ap); - return response; -} - -void qmp_fd_send(int fd, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - qmp_fd_sendv(fd, fmt, ap); - va_end(ap); -} - -QDict *qtest_qmp(QTestState *s, const char *fmt, ...) -{ - va_list ap; - QDict *response; - - va_start(ap, fmt); - response = qtest_qmpv(s, fmt, ap); - va_end(ap); - return response; -} - -void qtest_async_qmp(QTestState *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - qtest_async_qmpv(s, fmt, ap); - va_end(ap); -} - -void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap) -{ - QDict *response = qtest_qmpv(s, fmt, ap); - QDECREF(response); -} - -void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...) -{ - va_list ap; - QDict *response; - - va_start(ap, fmt); - response = qtest_qmpv(s, fmt, ap); - va_end(ap); - QDECREF(response); -} - -void qtest_qmp_eventwait(QTestState *s, const char *event) -{ - QDict *response; - - for (;;) { - response = qtest_qmp_receive(s); - if ((qdict_haskey(response, "event")) && - (strcmp(qdict_get_str(response, "event"), event) == 0)) { - QDECREF(response); - break; - } - QDECREF(response); - } -} - -char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap) -{ - char *cmd; - QDict *resp; - char *ret; - - cmd = g_strdup_vprintf(fmt, ap); - resp = qtest_qmp(s, "{'execute': 'human-monitor-command'," - " 'arguments': {'command-line': %s}}", - cmd); - ret = g_strdup(qdict_get_try_str(resp, "return")); - g_assert(ret); - QDECREF(resp); - g_free(cmd); - return ret; -} - -char *qtest_hmp(QTestState *s, const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = qtest_hmpv(s, fmt, ap); - va_end(ap); - return ret; -} - -const char *qtest_get_arch(void) -{ - const char *qemu = getenv("QTEST_QEMU_BINARY"); - g_assert(qemu != NULL); - const char *end = strrchr(qemu, '/'); - - return end + strlen("/qemu-system-"); -} - -bool qtest_get_irq(QTestState *s, int num) -{ - g_assert(s->last_intercept_gpio_id >= 0); - return qtest_get_irq_for_gpio(s, 0, num); -} - -bool qtest_get_irq_for_gpio(QTestState *s, gpio_id id, int num) -{ - /* dummy operation in order to make sure irq is up to date */ - qtest_inb(s, 0); - - return s->irq_level[id][num]; -} - -static int64_t qtest_clock_rsp(QTestState *s) -{ - gchar **words; - int64_t clock; - words = qtest_rsp(s, 2); - clock = g_ascii_strtoll(words[1], NULL, 0); - g_strfreev(words); - return clock; -} - -int64_t qtest_clock_step_next(QTestState *s) -{ - qtest_sendf(s, "clock_step\n"); - return qtest_clock_rsp(s); -} - -int64_t qtest_clock_step(QTestState *s, int64_t step) -{ - qtest_sendf(s, "clock_step %"PRIi64"\n", step); - return qtest_clock_rsp(s); -} - -int64_t qtest_clock_set(QTestState *s, int64_t val) -{ - qtest_sendf(s, "clock_set %"PRIi64"\n", val); - return qtest_clock_rsp(s); -} - -static gpio_id get_next_intercept_gpio_id(QTestState *s) -{ - gpio_id next_gpio_id = ++(s->last_intercept_gpio_id); - g_assert(next_gpio_id < MAX_GPIO_INTERCEPTS); - return next_gpio_id; -} - -gpio_id qtest_irq_intercept_out(QTestState *s, const char *qom_path) -{ - gpio_id next_gpio_id = get_next_intercept_gpio_id(s); - qtest_sendf(s, "irq_intercept_out %s %d\n", qom_path, next_gpio_id); - qtest_rsp(s, 0); - return next_gpio_id; -} - -gpio_id qtest_irq_intercept_in(QTestState *s, const char *qom_path) -{ - gpio_id next_gpio_id = get_next_intercept_gpio_id(s); - qtest_sendf(s, "irq_intercept_in %s %d\n", qom_path, next_gpio_id); - qtest_rsp(s, 0); - return next_gpio_id; -} - -void qtest_set_irq_in(QTestState *s, const char *string, int num, int level) -{ - qtest_sendf(s, "set_irq_in %s %d %s\n", string, num, - level ? "raise" : "lower"); - qtest_rsp(s, 0); -} - -static SocketInfo *get_serial_port_socket(QTestState *s, int serial_socket_num) -{ - g_assert(serial_socket_num >= 0 && - serial_socket_num < s->num_serial_ports); - return &s->serial_port_sockets[serial_socket_num]; -} - -void qtest_write_serial_port(QTestState *s, - int serial_port_num, - const char *fmt, ...) -{ - va_list ap; - SocketInfo *socket_info = get_serial_port_socket(s, serial_port_num); - - va_start(ap, fmt); - socket_sendf(socket_info->fd, fmt, ap); - va_end(ap); -} - -uint8_t qtest_read_serial_port_byte(QTestState *s, int serial_port_num) -{ - ssize_t len; - uint8_t buffer; - SocketInfo *socket_info = get_serial_port_socket(s, serial_port_num); - - do { - len = read(socket_info->fd, &buffer, sizeof(buffer)); - if (errno == EINTR) { - continue; - } - - if (len == -1 || len == 0) { - fprintf(stderr, "No character to read from socket %d\n", - serial_port_num); - g_assert(false); - } - } while(len == -1); - - g_assert_cmpint(len, ==, 1); - - return buffer; -} - -static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value) -{ - qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value); - qtest_rsp(s, 0); -} - -void qtest_outb(QTestState *s, uint16_t addr, uint8_t value) -{ - qtest_out(s, "outb", addr, value); -} - -void qtest_outw(QTestState *s, uint16_t addr, uint16_t value) -{ - qtest_out(s, "outw", addr, value); -} - -void qtest_outl(QTestState *s, uint16_t addr, uint32_t value) -{ - qtest_out(s, "outl", addr, value); -} - -static uint32_t qtest_in(QTestState *s, const char *cmd, uint16_t addr) -{ - gchar **args; - uint32_t value; - - qtest_sendf(s, "%s 0x%x\n", cmd, addr); - args = qtest_rsp(s, 2); - value = strtoul(args[1], NULL, 0); - g_strfreev(args); - - return value; -} - -uint8_t qtest_inb(QTestState *s, uint16_t addr) -{ - return qtest_in(s, "inb", addr); -} - -uint16_t qtest_inw(QTestState *s, uint16_t addr) -{ - return qtest_in(s, "inw", addr); -} - -uint32_t qtest_inl(QTestState *s, uint16_t addr) -{ - return qtest_in(s, "inl", addr); -} - -static void qtest_write(QTestState *s, const char *cmd, uint64_t addr, - uint64_t value) -{ - qtest_sendf(s, "%s 0x%" PRIx64 " 0x%" PRIx64 "\n", cmd, addr, value); - qtest_rsp(s, 0); -} - -void qtest_writeb(QTestState *s, uint64_t addr, uint8_t value) -{ - qtest_write(s, "writeb", addr, value); -} - -void qtest_writew(QTestState *s, uint64_t addr, uint16_t value) -{ - qtest_write(s, "writew", addr, value); -} - -void qtest_writel(QTestState *s, uint64_t addr, uint32_t value) -{ - qtest_write(s, "writel", addr, value); -} - -void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value) -{ - qtest_write(s, "writeq", addr, value); -} - -static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr) -{ - gchar **args; - uint64_t value; - - qtest_sendf(s, "%s 0x%" PRIx64 "\n", cmd, addr); - args = qtest_rsp(s, 2); - value = strtoull(args[1], NULL, 0); - g_strfreev(args); - - return value; -} - -uint8_t qtest_readb(QTestState *s, uint64_t addr) -{ - return qtest_read(s, "readb", addr); -} - -uint16_t qtest_readw(QTestState *s, uint64_t addr) -{ - return qtest_read(s, "readw", addr); -} - -uint32_t qtest_readl(QTestState *s, uint64_t addr) -{ - return qtest_read(s, "readl", addr); -} - -uint64_t qtest_readq(QTestState *s, uint64_t addr) -{ - return qtest_read(s, "readq", addr); -} - -static int hex2nib(char ch) -{ - if (ch >= '0' && ch <= '9') { - return ch - '0'; - } else if (ch >= 'a' && ch <= 'f') { - return 10 + (ch - 'a'); - } else if (ch >= 'A' && ch <= 'F') { - return 10 + (ch - 'a'); - } else { - return -1; - } -} - -void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size) -{ - uint8_t *ptr = data; - gchar **args; - size_t i; - - qtest_sendf(s, "read 0x%" PRIx64 " 0x%zx\n", addr, size); - args = qtest_rsp(s, 2); - - for (i = 0; i < size; i++) { - ptr[i] = hex2nib(args[1][2 + (i * 2)]) << 4; - ptr[i] |= hex2nib(args[1][2 + (i * 2) + 1]); - } - - g_strfreev(args); -} - -void qtest_add_func(const char *str, void (*fn)(void)) -{ - gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); - g_test_add_func(path, fn); - g_free(path); -} - -void qtest_add_data_func(const char *str, const void *data, - void (*fn)(const void *)) -{ - gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); - g_test_add_data_func(path, data, fn); - g_free(path); -} - -void qtest_bufwrite(QTestState *s, uint64_t addr, const void *data, size_t size) -{ - gchar *bdata; - - bdata = g_base64_encode(data, size); - qtest_sendf(s, "b64write 0x%" PRIx64 " 0x%zx ", addr, size); - socket_send(s->qtest_socket.fd, bdata, strlen(bdata)); - socket_send(s->qtest_socket.fd, "\n", 1); - qtest_rsp(s, 0); - g_free(bdata); -} - -void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size) -{ - gchar **args; - size_t len; - - qtest_sendf(s, "b64read 0x%" PRIx64 " 0x%zx\n", addr, size); - args = qtest_rsp(s, 2); - - g_base64_decode_inplace(args[1], &len); - if (size != len) { - fprintf(stderr, "bufread: asked for %zu bytes but decoded %zu\n", - size, len); - len = MIN(len, size); - } - - memcpy(data, args[1], len); - g_strfreev(args); -} - -void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size) -{ - const uint8_t *ptr = data; - size_t i; - char *enc = g_malloc(2 * size + 1); - - for (i = 0; i < size; i++) { - sprintf(&enc[i * 2], "%02x", ptr[i]); - } - - qtest_sendf(s, "write 0x%" PRIx64 " 0x%zx 0x%s\n", addr, size, enc); - qtest_rsp(s, 0); - g_free(enc); -} - -void qtest_memset(QTestState *s, uint64_t addr, uint8_t pattern, size_t size) -{ - qtest_sendf(s, "memset 0x%" PRIx64 " 0x%zx 0x%02x\n", addr, size, pattern); - qtest_rsp(s, 0); -} - -void write_serial_port(int serial_port_num, const char *fmt, ...) -{ - va_list ap; - SocketInfo *socket_info = get_serial_port_socket(global_qtest, - serial_port_num); - - va_start(ap, fmt); - socket_sendf(socket_info->fd, fmt, ap); - va_end(ap); -} - -QDict *qmp(const char *fmt, ...) -{ - va_list ap; - QDict *response; - - va_start(ap, fmt); - response = qtest_qmpv(global_qtest, fmt, ap); - va_end(ap); - return response; -} - -void qmp_async(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - qtest_async_qmpv(global_qtest, fmt, ap); - va_end(ap); -} - -void qmp_discard_response(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - qtest_qmpv_discard_response(global_qtest, fmt, ap); - va_end(ap); -} -char *hmp(const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = qtest_hmpv(global_qtest, fmt, ap); - va_end(ap); - return ret; -} - -bool qtest_big_endian(void) -{ - const char *arch = qtest_get_arch(); - int i; - - static const struct { - const char *arch; - bool big_endian; - } endianness[] = { - { "aarch64", false }, - { "alpha", false }, - { "arm", false }, - { "cris", false }, - { "i386", false }, - { "lm32", true }, - { "m68k", true }, - { "microblaze", true }, - { "microblazeel", false }, - { "mips", true }, - { "mips64", true }, - { "mips64el", false }, - { "mipsel", false }, - { "moxie", true }, - { "or32", true }, - { "ppc", true }, - { "ppc64", true }, - { "ppcemb", true }, - { "s390x", true }, - { "sh4", false }, - { "sh4eb", true }, - { "sparc", true }, - { "sparc64", true }, - { "unicore32", false }, - { "x86_64", false }, - { "xtensa", false }, - { "xtensaeb", true }, - {}, - }; - - for (i = 0; endianness[i].arch; i++) { - if (strcmp(endianness[i].arch, arch) == 0) { - return endianness[i].big_endian; - } - } - - return false; -} diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index 8c64ba0235234..413cc4e0f4ab2 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -463,16 +463,7 @@ wrote 65536/65536 bytes at offset 2147483648 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 3221225472 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - (0.00/100%) - (12.50/100%) - (25.00/100%) - (37.50/100%) - (50.00/100%) - (62.50/100%) - (75.00/100%) - (87.50/100%) - (100.00/100%) - (100.00/100%) + (0.00/100%) (12.50/100%) (25.00/100%) (37.50/100%) (50.00/100%) (62.50/100%) (75.00/100%) (87.50/100%) (100.00/100%) (100.00/100%) No errors were found on the image. === Testing progress report with snapshot === @@ -487,24 +478,7 @@ wrote 65536/65536 bytes at offset 2147483648 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 65536/65536 bytes at offset 3221225472 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - (0.00/100%) - (6.25/100%) - (12.50/100%) - (18.75/100%) - (25.00/100%) - (31.25/100%) - (37.50/100%) - (43.75/100%) - (50.00/100%) - (56.25/100%) - (62.50/100%) - (68.75/100%) - (75.00/100%) - (81.25/100%) - (87.50/100%) - (93.75/100%) - (100.00/100%) - (100.00/100%) + (0.00/100%) (6.25/100%) (12.50/100%) (18.75/100%) (25.00/100%) (31.25/100%) (37.50/100%) (43.75/100%) (50.00/100%) (56.25/100%) (62.50/100%) (68.75/100%) (75.00/100%) (81.25/100%) (87.50/100%) (93.75/100%) (100.00/100%) (100.00/100%) No errors were found on the image. === Testing version downgrade with external data file === diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out index 138d42502e443..b10c71db03c82 100644 --- a/tests/qemu-iotests/067.out +++ b/tests/qemu-iotests/067.out @@ -69,83 +69,6 @@ Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk -device vir "return": { } } -<<<<<<< HEAD -======= -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ - "return": [ - { - "io-status": "ok", - "device": "ide1-cd0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - }, - { - "device": "floppy0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - }, - { - "device": "sd0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - } - ] -} -{ - "return": { - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "ide1-cd0", - "tray-open": true - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "floppy0", - "tray-open": true - } -} - ->>>>>>> 919b29ba7d... Pebble Qemu === -drive/device_add and device_del === @@ -217,83 +140,6 @@ Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk "return": { } } -<<<<<<< HEAD -======= -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ - "return": [ - { - "io-status": "ok", - "device": "ide1-cd0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - }, - { - "device": "floppy0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - }, - { - "device": "sd0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - } - ] -} -{ - "return": { - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "ide1-cd0", - "tray-open": true - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "floppy0", - "tray-open": true - } -} - ->>>>>>> 919b29ba7d... Pebble Qemu === drive_add/device_add and device_del === @@ -368,83 +214,6 @@ Testing: "return": { } } -<<<<<<< HEAD -======= -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ - "return": [ - { - "io-status": "ok", - "device": "ide1-cd0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - }, - { - "device": "floppy0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - }, - { - "device": "sd0", - "locked": false, - "removable": true, - "tray_open": false, - "type": "unknown" - } - ] -} -{ - "return": { - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "ide1-cd0", - "tray-open": true - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "floppy0", - "tray-open": true - } -} - ->>>>>>> 919b29ba7d... Pebble Qemu === blockdev_add/device_add and device_del === @@ -642,74 +411,4 @@ Testing: -device virtio-scsi -device scsi-cd,id=cd0 "return": { } } -<<<<<<< HEAD -======= - "type": "qcow2", - "data": { - "compat": "1.1", - "lazy-refcounts": false, - "refcount-bits": 16, - "corrupt": false - } - }, - "dirty-flag": false - }, - "iops_wr": 0, - "ro": false, - "backing_file_depth": 0, - "drv": "qcow2", - "iops": 0, - "bps_wr": 0, - "write_threshold": 0, - "encrypted": false, - "bps": 0, - "bps_rd": 0, - "cache": { - "no-flush": false, - "direct": false, - "writeback": true - }, - "file": "TEST_DIR/t.qcow2", - "encryption_key_missing": false - }, - "tray_open": false, - "type": "unknown" - } - ] -} -{ - "return": { - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "ide1-cd0", - "tray-open": true - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_TRAY_MOVED", - "data": { - "device": "floppy0", - "tray-open": true - } -} - ->>>>>>> 919b29ba7d... Pebble Qemu *** done diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out index 035025630ec57..bca0c02f5c09a 100644 --- a/tests/qemu-iotests/071.out +++ b/tests/qemu-iotests/071.out @@ -46,15 +46,7 @@ QMP_VERSION read failed: Input/output error {"return": ""} {"return": {}} -<<<<<<< HEAD {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -======= -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} -QEMU_PROG: Failed to flush the L2 table cache: Input/output error -QEMU_PROG: Failed to flush the refcount block cache: Input/output error -QEMU_PROG: Failed to flush the L2 table cache: Input/output error -QEMU_PROG: Failed to flush the refcount block cache: Input/output error ->>>>>>> 919b29ba7d... Pebble Qemu === Testing blkverify on existing block device === @@ -96,7 +88,5 @@ read failed: Input/output error {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} QEMU_PROG: Failed to flush the L2 table cache: Input/output error QEMU_PROG: Failed to flush the refcount block cache: Input/output error -QEMU_PROG: Failed to flush the L2 table cache: Input/output error -QEMU_PROG: Failed to flush the refcount block cache: Input/output error *** done diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out index 43e9489a1c5fa..2d92ea847b010 100644 --- a/tests/qemu-iotests/087.out +++ b/tests/qemu-iotests/087.out @@ -64,12 +64,6 @@ QMP_VERSION {"return": {}} {"error": {"class": "GenericError", "desc": "Parameter 'driver' is missing"}} {"return": {}} -<<<<<<< HEAD {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} -======= -{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'driver', expected: string"}} -{"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} ->>>>>>> 919b29ba7d... Pebble Qemu *** done diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index ce13ae7c27623..f5cf93c38629e 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -45,22 +45,6 @@ QTestState *qtest_initf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); */ QTestState *qtest_vinitf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); -typedef int gpio_id; - -/* When running a QTest program stand-alone, the following environment variables - * may be set: - * - * Mandatory: - * QTEST_QEMU_BINARY: The QEMU binary to use. It is set automatically when - * running "make check". - * (e.g. "../arm-softmmu/qemu-system-arm") - * - * Optional: - * QTEST_QEMU_ARGS: Extra arguments to pass to QEMU (e.g. "-d"). - * QTEST_LOG_FILE: A file to which QTest log messages should be written - * (e.g. "/tmp/qtest.log"). - */ - /** * qtest_init: * @extra_args: other arguments to pass to QEMU. CAUTION: these @@ -68,7 +52,7 @@ typedef int gpio_id; * * Returns: #QTestState instance. */ -QTestState *qtest_init(const char *extra_args, int num_serial_ports); +QTestState *qtest_init(const char *extra_args); /** * qtest_init_without_qmp_handshake: @@ -287,16 +271,6 @@ void qtest_module_load(QTestState *s, const char *prefix, const char *libname); */ bool qtest_get_irq(QTestState *s, int num); -/** - * qtest_get_irq_for_gpio: - * @s: #QTestState instance to operate on. - * @id: GPIO to operate on (see qtest_irq_intercept_in/out). - * @num: Interrupt to observe. - * - * Returns: The level of the @num interrupt. - */ -bool qtest_get_irq_for_gpio(QTestState *s, gpio_id id, int num); - /** * qtest_irq_intercept_in: * @s: #QTestState instance to operate on. @@ -304,9 +278,8 @@ bool qtest_get_irq_for_gpio(QTestState *s, gpio_id id, int num); * * Associate qtest irqs with the GPIO-in pins of the device * whose path is specified by @string. - * Returns an id value that can be used when calling qtest_get_irq. */ -gpio_id qtest_irq_intercept_in(QTestState *s, const char *string); +void qtest_irq_intercept_in(QTestState *s, const char *string); /** * qtest_irq_intercept_out: @@ -315,46 +288,8 @@ gpio_id qtest_irq_intercept_in(QTestState *s, const char *string); * * Associate qtest irqs with the GPIO-out pins of the device * whose path is specified by @string. - * Returns an id value that can be used when calling qtest_get_irq. */ -gpio_id qtest_irq_intercept_out(QTestState *s, const char *string); - -/** - * qtest_set_irq_in: - * @s: #QTestState instance to operate on. - * @string: QOM path of a device. - * @num: Interrupt to set (specifies a GPIO-in pin) - * @level: new IRQ level - * - * Sets the GPIO-in pin level of the device whose path is specified by @string. - */ -void qtest_set_irq_in(QTestState *s, const char *string, int num, int level); - -/** - * write_serial_port: - * @s: #QTestState instance to operate on. - * @serial_port_num: Indicates the serial port to write to - * (see qtest_start_with_serial). - * @fmt: The printf style format string to write. - * - * Sends a string to the specified virtual serial port. - */ -void qtest_write_serial_port(QTestState *s, - int serial_port_num, - const char *fmt, ...); - -/** - * read_serial_port_byte: - * @s: #QTestState instance to operate on. - * @serial_port_num: Indicates the serial port to read from - * (see qtest_start_with_serial). - * - * Reads an byte (8-bit value) from the specified virtual serial port. - * If there is no byte to read, an assertion failure will occur. - * - * Returns: Value read. - */ -uint8_t qtest_read_serial_port_byte(QTestState *s, int serial_port_num); +void qtest_irq_intercept_out(QTestState *s, const char *string); /** * qtest_set_irq_in: @@ -692,329 +627,11 @@ void qtest_add_data_func_full(const char *str, void *data, void qtest_add_abrt_handler(GHookFunc fn, const void *data); /** -<<<<<<< HEAD:tests/qtest/libqtest.h * qtest_qmp_assert_success: * @qts: QTestState instance to operate on * @fmt...: QMP message to send to qemu, formatted like * qobject_from_jsonf_nofail(). See parse_escape() for what's * supported after '%'. -======= - * qtest_start: - * @args: other arguments to pass to QEMU - * - * Start QEMU and assign the resulting #QTestState to a global variable. - * The global variable is used by "shortcut" functions documented below. - * - * Returns: #QTestState instance. - */ -static inline QTestState *qtest_start(const char *args) -{ - global_qtest = qtest_init(args, 0); - return global_qtest; -} - -/** - * qtest_start_with_serial: - * @args: See qtest_start - * @num_sockets: number of extra sockets to - * - * Works the same way as qtest_start, except creates a connection to the - * specified number of virtual serial ports. - * - * Use write_serial_port and read_serial_port_byte to communicate via these - * connections. These functions require a serial port number. The serial - * ports are numbered in the same order that they are specified on - * the QEMU command line (using the -serial option). The first serial port - * specified on the command line is numbered 0, the second port is numbered 1, - * and so on. - */ -static inline QTestState *qtest_start_with_serial(const char *args, - int num_serial_ports) -{ - global_qtest = qtest_init(args, num_serial_ports); - return global_qtest; -} - -/** - * qtest_end: - * - * Shut down the QEMU process started by qtest_start(). - */ -static inline void qtest_end(void) -{ - qtest_quit(global_qtest); - global_qtest = NULL; -} - -/** - * qmp: - * @fmt...: QMP message to send to qemu - * - * Sends a QMP message to QEMU and returns the response. - */ -QDict *qmp(const char *fmt, ...); - -/** - * qmp_async: - * @fmt...: QMP message to send to qemu - * - * Sends a QMP message to QEMU and leaves the response in the stream. - */ -void qmp_async(const char *fmt, ...); - -/** - * qmp_discard_response: - * @fmt...: QMP message to send to qemu - * - * Sends a QMP message to QEMU and consumes the response. - */ -void qmp_discard_response(const char *fmt, ...); - -/** - * qmp_receive: - * - * Reads a QMP message from QEMU and returns the response. - */ -static inline QDict *qmp_receive(void) -{ - return qtest_qmp_receive(global_qtest); -} - -/** - * qmp_eventwait: - * @s: #event event to wait for. - * - * Continuosly polls for QMP responses until it receives the desired event. - */ -static inline void qmp_eventwait(const char *event) -{ - return qtest_qmp_eventwait(global_qtest, event); -} - -/** - * hmp: - * @fmt...: HMP command to send to QEMU - * - * Send HMP command to QEMU via QMP's human-monitor-command. - * - * Returns: the command's output. The caller should g_free() it. - */ -char *hmp(const char *fmt, ...); - -/** - * get_irq: - * @num: Interrupt to observe. - * - * Returns: The level of the @num interrupt. - */ -static inline bool get_irq(int num) -{ - return qtest_get_irq(global_qtest, num); -} - -/** - * get_irq_for_gpio: - * @id: GPIO to operate on (see qtest_irq_intercept_in/out). - * @num: Interrupt to observe. - * - * Returns: The level of the @num interrupt. - */ -static inline bool get_irq_for_gpio(gpio_id id, int num) -{ - return qtest_get_irq_for_gpio(global_qtest, id, num); -} - -/** - * irq_intercept_in: - * @string: QOM path of a device. - * - * Associate qtest irqs with the GPIO-in pins of the device - * whose path is specified by @string. - */ -static inline void irq_intercept_in(const char *string) -{ - qtest_irq_intercept_in(global_qtest, string); -} - -/** - * qtest_irq_intercept_out: - * @string: QOM path of a device. - * - * Associate qtest irqs with the GPIO-out pins of the device - * whose path is specified by @string. - */ -static inline void irq_intercept_out(const char *string) -{ - qtest_irq_intercept_out(global_qtest, string); -} - -/** - * set_irq_in: - * @string: QOM path of a device. - * @num: Interrupt to set (specifies a GPIO-in pin) - * @level: new IRQ level - * - * Sets the GPIO-in pin level of the device whose path is specified by @string. - */ -static inline void set_irq_in(const char *string, int num, int level) -{ - qtest_set_irq_in(global_qtest, string, num, level); -} - -/** - * write_serial_port: - * @serial_port_num: Indicates the serial port to write to - * (see qtest_start_with_serial). - * @fmt: The printf style format string to write. - * - * Sends a string to the specified virtual serial port. - */ -void write_serial_port(int serial_port_num, const char *fmt, ...); - -/** - * read_serial_port_byte: - * @serial_port_num: Indicates the serial port to read from - * (see qtest_start_with_serial). - * - * Reads an byte (8-bit value) from the specified virtual serial port. - * If there is no byte to read, an assertion failure will occur. - * - * Returns: Value read. - */ -static inline uint8_t read_serial_port_byte(int serial_port_num) -{ - return qtest_read_serial_port_byte(global_qtest, serial_port_num); -} - -/** - * outb: - * @addr: I/O port to write to. - * @value: Value being written. - * - * Write an 8-bit value to an I/O port. - */ -static inline void outb(uint16_t addr, uint8_t value) -{ - qtest_outb(global_qtest, addr, value); -} - -/** - * outw: - * @addr: I/O port to write to. - * @value: Value being written. - * - * Write a 16-bit value to an I/O port. - */ -static inline void outw(uint16_t addr, uint16_t value) -{ - qtest_outw(global_qtest, addr, value); -} - -/** - * outl: - * @addr: I/O port to write to. - * @value: Value being written. - * - * Write a 32-bit value to an I/O port. - */ -static inline void outl(uint16_t addr, uint32_t value) -{ - qtest_outl(global_qtest, addr, value); -} - -/** - * inb: - * @addr: I/O port to read from. - * - * Reads an 8-bit value from an I/O port. - * - * Returns: Value read. - */ -static inline uint8_t inb(uint16_t addr) -{ - return qtest_inb(global_qtest, addr); -} - -/** - * inw: - * @addr: I/O port to read from. - * - * Reads a 16-bit value from an I/O port. - * - * Returns: Value read. - */ -static inline uint16_t inw(uint16_t addr) -{ - return qtest_inw(global_qtest, addr); -} - -/** - * inl: - * @addr: I/O port to read from. - * - * Reads a 32-bit value from an I/O port. - * - * Returns: Value read. - */ -static inline uint32_t inl(uint16_t addr) -{ - return qtest_inl(global_qtest, addr); -} - -/** - * writeb: - * @addr: Guest address to write to. - * @value: Value being written. - * - * Writes an 8-bit value to guest memory. - */ -static inline void writeb(uint64_t addr, uint8_t value) -{ - qtest_writeb(global_qtest, addr, value); -} - -/** - * writew: - * @addr: Guest address to write to. - * @value: Value being written. - * - * Writes a 16-bit value to guest memory. - */ -static inline void writew(uint64_t addr, uint16_t value) -{ - qtest_writew(global_qtest, addr, value); -} - -/** - * writel: - * @addr: Guest address to write to. - * @value: Value being written. - * - * Writes a 32-bit value to guest memory. - */ -static inline void writel(uint64_t addr, uint32_t value) -{ - qtest_writel(global_qtest, addr, value); -} - -/** - * writeq: - * @addr: Guest address to write to. - * @value: Value being written. - * - * Writes a 64-bit value to guest memory. - */ -static inline void writeq(uint64_t addr, uint64_t value) -{ - qtest_writeq(global_qtest, addr, value); -} - -/** - * readb: - * @addr: Guest address to read from. - * - * Reads an 8-bit value from guest memory. ->>>>>>> 919b29ba7d... Pebble Qemu:tests/libqtest.h * * Sends a QMP message to QEMU and asserts that a 'return' key is present in * the response. diff --git a/tests/test-stm32.c b/tests/test-stm32.c deleted file mode 100644 index bb8166fe72fb8..0000000000000 --- a/tests/test-stm32.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * QTest testcase for the STM32 Microcontroller - * - * Copyright 2013 - * - * Authors: - * Andre Beckus - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ -#include "libqtest.h" - -#include -#include - -// These are only needed for getpid -#include -#include - -#define GPIOA_BASE_ADDR 0x40010800 -#define GPIOB_BASE_ADDR 0x40010c00 -#define GPIOC_BASE_ADDR 0x40011000 -#define RCC_BASE_ADDR 0x40021000 -#define AFIO_BASE_ADDR 0x40010000 -#define EXTI_BASE_ADDR 0x40010400 -#define UART2_BASE_ADDR 0x40004400 - -const char *dummy_kernel_path = "tests/test-stm32-dummy-kernel.bin"; -const uint32_t dummy_kernel_data = 0x12345678; - -const int uart2_socket_num = 0; - -gpio_id gpio_a_out_id; -gpio_id nvic_in_id; -//gpio_id gpio_b_out_id; - -//int uart_sock, uart_fd; - -static void write_dummy_kernel_bin(void) -{ - FILE *kernel_file = fopen(dummy_kernel_path, "wb"); - g_assert(kernel_file); - - size_t write_size = fwrite(&dummy_kernel_data, 4, 1, kernel_file); - g_assert(write_size == 1); - - int close_result = fclose(kernel_file); - g_assert(close_result == 0); -} - -static void enable_all_periph_clocks(void) -{ - writel(RCC_BASE_ADDR + 0x18, 0x0038fffd); - writel(RCC_BASE_ADDR + 0x1c, 0x3afec9ff); -} - -static void config_gpio(uint32_t gpio_base_addr, - uint32_t config_value_high, - uint32_t config_value_low) -{ - writel(gpio_base_addr + 0x00, config_value_low); - writel(gpio_base_addr + 0x04, config_value_high); -} - -static void test_flash_alias(void) -{ - g_assert_cmpint(readl(0), ==, dummy_kernel_data); - g_assert_cmpint(readl(0x08000000), ==, dummy_kernel_data); - - g_assert_cmpint(readw(2), ==, dummy_kernel_data >> 16); - g_assert_cmpint(readw(0x08000002), ==, dummy_kernel_data >> 16); -} - -static void test_gpio_read(void) -{ - const uint32_t addr_idr = GPIOA_BASE_ADDR + 0x08; // Input Data Register - uint32_t value; - - config_gpio(GPIOA_BASE_ADDR, 0x44444444, 0x44444444); // All inputs - - value = readl(addr_idr); - g_assert_cmpint(value, ==, 0); - - set_irq_in("/machine/stm32/gpio[a]", 0, 1); - - value = readl(addr_idr); - g_assert_cmpint(value, ==, 1); - - set_irq_in("/machine/stm32/gpio[a]", 7, 1); - - value = readl(addr_idr); - g_assert_cmpint(value, ==, 0x81); -} - -static void test_gpio_write(void) -{ - const uint32_t addr_odr = GPIOA_BASE_ADDR + 0x0c; // Output Data Register - const uint32_t addr_bsrr = GPIOA_BASE_ADDR + 0x10; // Bit Set Reset Register - const uint32_t addr_brr = GPIOA_BASE_ADDR + 0x14; // Bit Reset Register - - config_gpio(GPIOA_BASE_ADDR, 0x33333333, 0x33333333); // All outputs - - writel(addr_odr, 0x00000000); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 0); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 0); - - writel(addr_odr, 0x0000ffff); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 1); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 1); - - writel(addr_brr, 0x00008001); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 0); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x1), ==, 1); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 0); - - writel(addr_bsrr, 0x00028001); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x0), ==, 1); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0x1), ==, 0); - g_assert_cmpint(get_irq_for_gpio(gpio_a_out_id, 0xf), ==, 1); - - writel(addr_bsrr, 0x0000ffef); - - - //config_gpio(GPIOB_BASE_ADDR, 0x33333333, 0x33333333); // All outputs - - //writel(GPIOB_BASE_ADDR + 0x0c, 0x00000000); - //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0x0), ==, 0); - //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0xf), ==, 0); - - //writel(GPIOB_BASE_ADDR + 0x0c, 0x0000ffff); - //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0x0), ==, 1); - //g_assert_cmpint(get_irq_for_gpio(gpio_b_out_id, 0xf), ==, 1); -} - -static void test_gpio_interrupt(void) -{ - config_gpio(GPIOA_BASE_ADDR, 0x44444444, 0x44444444); // All inputs - - set_irq_in("/machine/stm32/gpio[a]", 0, 0); - - writel(EXTI_BASE_ADDR + 0x00, 0x000fffff); // All interrupts enabled - writel(EXTI_BASE_ADDR + 0x08, 0x000fffff); // All rising triggers - writel(EXTI_BASE_ADDR + 0x0c, 0x000fffff); // All falling triggers - - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - set_irq_in("/machine/stm32/gpio[a]", 0, 1); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); - set_irq_in("/machine/stm32/gpio[a]", 0, 0); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); - - writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts - - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - set_irq_in("/machine/stm32/gpio[a]", 0, 1); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); - writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - set_irq_in("/machine/stm32/gpio[a]", 0, 0); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); - writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts - - set_irq_in("/machine/stm32/gpio[b]", 0, 0); - set_irq_in("/machine/stm32/gpio[b]", 0, 1); - set_irq_in("/machine/stm32/gpio[b]", 0, 0); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - - writel(AFIO_BASE_ADDR + 0x08, 0x00000001); // Attach EXTI0 to Port B - - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - set_irq_in("/machine/stm32/gpio[b]", 0, 1); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); - writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x7), ==, 0); - writel(EXTI_BASE_ADDR + 0x10, 0x00000003); // Clear all interrupts - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 1); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x7), ==, 1); - g_assert_cmpint(readl(EXTI_BASE_ADDR + 0x10), ==, 0x00000003); - writel(EXTI_BASE_ADDR + 0x14, 0x000fffff); // Clear all interrupts - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x6), ==, 0); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 0x7), ==, 0); - g_assert_cmpint(readl(EXTI_BASE_ADDR + 0x10), ==, 0x00000000); -} - -static void test_uart(void) -{ - uint32_t status; - uint8_t recv_byte; - uint8_t sent_byte; - uint32_t cr1_enabled = 0x0000200c; - - /* TODO: Clean this up and modularize. */ - - // All inputs except pin 2 (which is the transmit pin). - config_gpio(GPIOA_BASE_ADDR, 0x44444444, 0x44444b44); - - writel(UART2_BASE_ADDR + 0x0c, cr1_enabled); // Enable UART, Transmit, and Receive - - status = readl(UART2_BASE_ADDR + 0x00); - g_assert_cmpint(status & 0x020, ==, 0); - - write_serial_port(uart2_socket_num, "A"); - //TODO: Add a timeout to avoid infinite loop - do { - status = readl(UART2_BASE_ADDR + 0x00); - } while((status & 0x020) == 0); - recv_byte = readl(UART2_BASE_ADDR + 0x04); - g_assert_cmpint(recv_byte, ==, 'A'); - - write_serial_port(uart2_socket_num, "B"); - //TODO: Add a timeout to avoid infinite loop - do { - status = readl(UART2_BASE_ADDR + 0x00); - } while((status & 0x020) == 0); - recv_byte = readl(UART2_BASE_ADDR + 0x04); - g_assert_cmpint(recv_byte, ==, 'B'); - - writel(UART2_BASE_ADDR + 0x04, 'C'); // Transmit a character - sent_byte = read_serial_port_byte(uart2_socket_num); - g_assert_cmpint(sent_byte, ==, 'C'); - - writel(UART2_BASE_ADDR + 0x04, 'D'); // Transmit a character - sent_byte = read_serial_port_byte(uart2_socket_num); - g_assert_cmpint(sent_byte, ==, 'D'); - - writel(UART2_BASE_ADDR + 0x0c, cr1_enabled | 0x0020); // Receive interrupt - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 0); - write_serial_port(uart2_socket_num, "E"); - //TODO: Add a timeout to avoid infinite loop - do { - status = readl(UART2_BASE_ADDR + 0x00); - } while((status & 0x020) == 0); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 1); - recv_byte = readl(UART2_BASE_ADDR + 0x04); - g_assert_cmpint(recv_byte, ==, 'E'); - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 0); - - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 0); - writel(UART2_BASE_ADDR + 0x0c, cr1_enabled | 0x0040); // transmit complete interrupt - writel(UART2_BASE_ADDR + 0x04, 'F'); // Transmit a character - //TODO: Add a timeout to avoid infinite loop - do { - status = readl(UART2_BASE_ADDR + 0x00); - } while((status & 0x040) == 0); // Loop until transmit complete - g_assert_cmpint(get_irq_for_gpio(nvic_in_id, 38), ==, 1); - sent_byte = read_serial_port_byte(uart2_socket_num); - g_assert_cmpint(sent_byte, ==, 'F'); - - // Test half-word (16 bit) memory accesses. - // Note that half-word memory accesses are only supported in the UART - // if they are word (32 bit) address aligned. - writew(UART2_BASE_ADDR + 0x0c, 0); - writew(UART2_BASE_ADDR + 0x0e, 0); - g_assert_cmpint(readw(UART2_BASE_ADDR + 0x0c), ==, 0); - g_assert_cmpint(readw(UART2_BASE_ADDR + 0x0e), ==, 0); - writew(UART2_BASE_ADDR + 0x0c, 0x200c); - g_assert_cmpint(readw(UART2_BASE_ADDR + 0x0c), ==, 0x200c); - - - // To do: test TXE interrupt, overflow, simulated delays, TC clearing - // These get tough to do because they involve race conditions. - // Maybe we can add a property for testing to tell the uart to pause - // when sending a character so that the unit tests can check things - // out and then change the property back to resume operations. - // Of course, this interferes with and complicates the unit under test, making - // it more prone to defects. - // Maybe if timers were objects, they could have the test properties instead - // so that we did not need to add test logic into the UART itself..... -} - -int main(int argc, char **argv) -{ - QTestState *s = NULL; - int ret; - - g_test_init(&argc, &argv, NULL); - - write_dummy_kernel_bin(); - - gchar *qemu_args = g_strdup_printf("-display none " - "-machine stm32-p103 " - "-kernel %s", - dummy_kernel_path); - s = qtest_start_with_serial(qemu_args, 1); - - enable_all_periph_clocks(); - - gpio_a_out_id = qtest_irq_intercept_out(s, "/machine/stm32/gpio[a]"); - nvic_in_id = qtest_irq_intercept_in(s, "/machine/stm32/nvic"); - //gpio_b_out_id = qtest_irq_intercept_out(s, "/machine/stm32/gpio[b]"); - - qtest_add_func("/stm32/flash/alias", test_flash_alias); - qtest_add_func("/stm32/gpio/read", test_gpio_read); - qtest_add_func("/stm32/gpio/write", test_gpio_write); - qtest_add_func("/stm32/gpio/interrupt", test_gpio_interrupt); - qtest_add_func("/stm32/uart", test_uart); - - ret = g_test_run(); - - if (s) { - qtest_quit(s); - } - - unlink(qemu_args); - g_free(qemu_args); - - return ret; -} diff --git a/ui/cocoa.m b/ui/cocoa.m index a0ab851992948..fb112cb662cc4 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -544,11 +544,14 @@ - (void) switchSurface:(pixman_image_t *)image [[fullScreenWindow contentView] setFrame:[[NSScreen mainScreen] frame]]; [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:NO animate:NO]; } else { - if (qemu_name) { + if (qemu_name) [normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s", qemu_name]]; - } [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:YES animate:NO]; } + + if (isResize) { + [normalWindow center]; + } } - (void) toggleFullScreen:(id)sender @@ -1093,19 +1096,9 @@ - (id) init // set the supported image file types that can be opened supportedImageFileTypes = [NSArray arrayWithObjects: @"img", @"iso", @"dmg", -<<<<<<< HEAD @"qcow", @"qcow2", @"cloop", @"vmdk", @"cdr", @"toast", nil]; [self make_about_window]; -======= - @"qcow", @"qcow2", @"cloop", @"vmdk", nil]; - - // Save window position - [[normalWindow windowController] setShouldCascadeWindows:NO]; - [normalWindow setFrameAutosaveName:@"normalWindow"]; - - [normalWindow makeKeyAndOrderFront:self]; ->>>>>>> 919b29ba7d... Pebble Qemu } return self; } @@ -1597,24 +1590,6 @@ static void create_initial_menus(void) menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease]; [menuItem setSubmenu:menu]; [[NSApp mainMenu] addItem:menuItem]; -<<<<<<< HEAD -======= - - // Create an Application controller - QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init]; - [NSApp setDelegate:appController]; - - // Bring application to the front of all windows - [NSApp activateIgnoringOtherApps:YES]; - - // Start the main event loop - [NSApp run]; - - [appController release]; - [pool release]; - - return 0; ->>>>>>> 919b29ba7d... Pebble Qemu } /* Returns a name for a given console */ diff --git a/ui/sdl.c b/ui/sdl.c deleted file mode 100644 index b008f8dd035d2..0000000000000 --- a/ui/sdl.c +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * QEMU SDL display driver - * - * Copyright (c) 2003 Fabrice Bellard - * - * 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. - */ - -/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */ -#undef WIN32_LEAN_AND_MEAN - -#include -#include - -#include "qemu-common.h" -#include "ui/console.h" -#include "ui/input.h" -#include "sysemu/sysemu.h" -#include "x_keymap.h" -#include "sdl_zoom.h" - -static DisplayChangeListener *dcl; -static DisplaySurface *surface; -static SDL_Surface *real_screen; -static SDL_Surface *guest_screen = NULL; -static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ -static int last_vm_running; -static bool gui_saved_scaling; -static int gui_saved_width; -static int gui_saved_height; -static int gui_saved_grab; -static int gui_fullscreen; -static int gui_noframe; -static int gui_key_modifier_pressed; -static int gui_keysym; -static int gui_grab_code = KMOD_LALT | KMOD_LCTRL; -static uint8_t modifiers_state[256]; -static SDL_Cursor *sdl_cursor_normal; -static SDL_Cursor *sdl_cursor_hidden; -static int absolute_enabled = 0; -static int guest_cursor = 0; -static int guest_x, guest_y; -static SDL_Cursor *guest_sprite = NULL; -static SDL_PixelFormat host_format; -static int scaling_active = 0; -static Notifier mouse_mode_notifier; - -#if 0 -#define DEBUG_SDL -#endif - -static void sdl_update(DisplayChangeListener *dcl, - int x, int y, int w, int h) -{ - SDL_Rect rec; - rec.x = x; - rec.y = y; - rec.w = w; - rec.h = h; - -#ifdef DEBUG_SDL - printf("SDL: Updating x=%d y=%d w=%d h=%d (scaling: %d)\n", - x, y, w, h, scaling_active); -#endif - - if (guest_screen) { - if (!scaling_active) { - SDL_BlitSurface(guest_screen, &rec, real_screen, &rec); - } else { - if (sdl_zoom_blit(guest_screen, real_screen, SMOOTHING_ON, &rec) < 0) { - fprintf(stderr, "Zoom blit failed\n"); - exit(1); - } - } - } - SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h); -} - -static void do_sdl_resize(int width, int height, int bpp) -{ - int flags; - SDL_Surface *tmp_screen; - -#ifdef DEBUG_SDL - printf("SDL: Resizing to %dx%d bpp %d\n", width, height, bpp); -#endif - - flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; - if (gui_fullscreen) { - flags |= SDL_FULLSCREEN; - } else { - flags |= SDL_RESIZABLE; - } - if (gui_noframe) - flags |= SDL_NOFRAME; - - tmp_screen = SDL_SetVideoMode(width, height, bpp, flags); - if (!real_screen) { - if (!tmp_screen) { - fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", - width, height, bpp, SDL_GetError()); - exit(1); - } - } else { - /* - * Revert to the previous video mode if the change of resizing or - * resolution failed. - */ - if (!tmp_screen) { - fprintf(stderr, "Failed to set SDL display (%dx%dx%d): %s\n", - width, height, bpp, SDL_GetError()); - return; - } - } - - real_screen = tmp_screen; -} - -static void sdl_switch(DisplayChangeListener *dcl, - DisplaySurface *new_surface) -{ - PixelFormat pf; - - /* temporary hack: allows to call sdl_switch to handle scaling changes */ - if (new_surface) { - surface = new_surface; - } - pf = qemu_pixelformat_from_pixman(surface->format); - - if (!scaling_active) { - do_sdl_resize(surface_width(surface), surface_height(surface), 0); - } else if (real_screen->format->BitsPerPixel != - surface_bits_per_pixel(surface)) { - do_sdl_resize(real_screen->w, real_screen->h, - surface_bits_per_pixel(surface)); - } - - if (guest_screen != NULL) { - SDL_FreeSurface(guest_screen); - } - -#ifdef DEBUG_SDL - printf("SDL: Creating surface with masks: %08x %08x %08x %08x\n", - pf.rmask, pf.gmask, pf.bmask, pf.amask); -#endif - - guest_screen = SDL_CreateRGBSurfaceFrom - (surface_data(surface), - surface_width(surface), surface_height(surface), - surface_bits_per_pixel(surface), surface_stride(surface), - pf.rmask, pf.gmask, - pf.bmask, pf.amask); -} - -static bool sdl_check_format(DisplayChangeListener *dcl, - pixman_format_code_t format) -{ - /* - * We let SDL convert for us a few more formats than, - * the native ones. Thes are the ones I have tested. - */ - return (format == PIXMAN_x8r8g8b8 || - format == PIXMAN_b8g8r8x8 || - format == PIXMAN_x1r5g5b5 || - format == PIXMAN_r5g6b5); -} - -/* generic keyboard conversion */ - -#include "sdl_keysym.h" - -static kbd_layout_t *kbd_layout = NULL; - -static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) -{ - int keysym; - /* workaround for X11+SDL bug with AltGR */ - keysym = ev->keysym.sym; - if (keysym == 0 && ev->keysym.scancode == 113) - keysym = SDLK_MODE; - /* For Japanese key '\' and '|' */ - if (keysym == 92 && ev->keysym.scancode == 133) { - keysym = 0xa5; - } - return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK; -} - -/* specific keyboard conversions from scan codes */ - -#if defined(_WIN32) - -static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) -{ - return ev->keysym.scancode; -} - -#else - -#if defined(SDL_VIDEO_DRIVER_X11) -#include - -static int check_for_evdev(void) -{ - SDL_SysWMinfo info; - XkbDescPtr desc = NULL; - int has_evdev = 0; - char *keycodes = NULL; - - SDL_VERSION(&info.version); - if (!SDL_GetWMInfo(&info)) { - return 0; - } - desc = XkbGetKeyboard(info.info.x11.display, - XkbGBN_AllComponentsMask, - XkbUseCoreKbd); - if (desc && desc->names) { - keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes); - if (keycodes == NULL) { - fprintf(stderr, "could not lookup keycode name\n"); - } else if (strstart(keycodes, "evdev", NULL)) { - has_evdev = 1; - } else if (!strstart(keycodes, "xfree86", NULL)) { - fprintf(stderr, "unknown keycodes `%s', please report to " - "qemu-devel@nongnu.org\n", keycodes); - } - } - - if (desc) { - XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); - } - if (keycodes) { - XFree(keycodes); - } - return has_evdev; -} -#else -static int check_for_evdev(void) -{ - return 0; -} -#endif - -static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) -{ - int keycode; - static int has_evdev = -1; - - if (has_evdev == -1) - has_evdev = check_for_evdev(); - - keycode = ev->keysym.scancode; - - if (keycode < 9) { - keycode = 0; - } else if (keycode < 97) { - keycode -= 8; /* just an offset */ - } else if (keycode < 158) { - /* use conversion table */ - if (has_evdev) - keycode = translate_evdev_keycode(keycode - 97); - else - keycode = translate_xfree86_keycode(keycode - 97); - } else if (keycode == 208) { /* Hiragana_Katakana */ - keycode = 0x70; - } else if (keycode == 211) { /* backslash */ - keycode = 0x73; - } else { - keycode = 0; - } - return keycode; -} - -#endif - -static void reset_keys(void) -{ - int i; - for(i = 0; i < 256; i++) { - if (modifiers_state[i]) { - qemu_input_event_send_key_number(dcl->con, i, false); - modifiers_state[i] = 0; - } - } -} - -static void sdl_process_key(SDL_KeyboardEvent *ev) -{ - int keycode; - - if (ev->keysym.sym == SDLK_PAUSE) { - /* specific case */ - qemu_input_event_send_key_qcode(dcl->con, Q_KEY_CODE_PAUSE, - ev->type == SDL_KEYDOWN); - return; - } - - if (kbd_layout) { - keycode = sdl_keyevent_to_keycode_generic(ev); - } else { - keycode = sdl_keyevent_to_keycode(ev); - } - - switch(keycode) { - case 0x00: - /* sent when leaving window: reset the modifiers state */ - reset_keys(); - return; - case 0x2a: /* Left Shift */ - case 0x36: /* Right Shift */ - case 0x1d: /* Left CTRL */ - case 0x9d: /* Right CTRL */ - case 0x38: /* Left ALT */ - case 0xb8: /* Right ALT */ - if (ev->type == SDL_KEYUP) - modifiers_state[keycode] = 0; - else - modifiers_state[keycode] = 1; - break; -#define QEMU_SDL_VERSION ((SDL_MAJOR_VERSION << 8) + SDL_MINOR_VERSION) -#if QEMU_SDL_VERSION < 0x102 || QEMU_SDL_VERSION == 0x102 && SDL_PATCHLEVEL < 14 - /* SDL versions before 1.2.14 don't support key up for caps/num lock. */ - case 0x45: /* num lock */ - case 0x3a: /* caps lock */ - /* SDL does not send the key up event, so we generate it */ - qemu_input_event_send_key_number(dcl->con, keycode, true); - qemu_input_event_send_key_number(dcl->con, keycode, false); - return; -#endif - } - - /* now send the key code */ - qemu_input_event_send_key_number(dcl->con, keycode, - ev->type == SDL_KEYDOWN); -} - -static void sdl_update_caption(void) -{ - char win_title[1024]; - char icon_title[1024]; - const char *status = ""; - - if (!runstate_is_running()) - status = " [Stopped]"; - else if (gui_grab) { - if (alt_grab) - status = " - Press Ctrl-Alt-Shift to exit mouse grab"; - else if (ctrl_grab) - status = " - Press Right-Ctrl to exit mouse grab"; - else - status = " - Press Ctrl-Alt to exit mouse grab"; - } - - if (qemu_name) { - snprintf(win_title, sizeof(win_title), "QEMU (%s)%s", qemu_name, status); - snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name); - } else { - snprintf(win_title, sizeof(win_title), "QEMU%s", status); - snprintf(icon_title, sizeof(icon_title), "QEMU"); - } - - SDL_WM_SetCaption(win_title, icon_title); -} - -static void sdl_hide_cursor(void) -{ - if (!cursor_hide) - return; - - if (qemu_input_is_absolute()) { - SDL_ShowCursor(1); - SDL_SetCursor(sdl_cursor_hidden); - } else { - SDL_ShowCursor(0); - } -} - -static void sdl_show_cursor(void) -{ - if (!cursor_hide) - return; - - if (!qemu_input_is_absolute() || !qemu_console_is_graphic(NULL)) { - SDL_ShowCursor(1); - if (guest_cursor && - (gui_grab || qemu_input_is_absolute() || absolute_enabled)) - SDL_SetCursor(guest_sprite); - else - SDL_SetCursor(sdl_cursor_normal); - } -} - -static void sdl_grab_start(void) -{ -#ifdef NO_MOUSE - return; -#endif - /* - * If the application is not active, do not try to enter grab state. This - * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the - * application (SDL bug). - */ - if (!(SDL_GetAppState() & SDL_APPINPUTFOCUS)) { - return; - } - if (guest_cursor) { - SDL_SetCursor(guest_sprite); - if (!qemu_input_is_absolute() && !absolute_enabled) { - SDL_WarpMouse(guest_x, guest_y); - } - } else - sdl_hide_cursor(); - SDL_WM_GrabInput(SDL_GRAB_ON); - gui_grab = 1; - sdl_update_caption(); -} - -static void sdl_grab_end(void) -{ -#ifdef NO_MOUSE - return; -#endif - SDL_WM_GrabInput(SDL_GRAB_OFF); - gui_grab = 0; - sdl_show_cursor(); - sdl_update_caption(); -} - -static void absolute_mouse_grab(void) -{ - int mouse_x, mouse_y; - - SDL_GetMouseState(&mouse_x, &mouse_y); - if (mouse_x > 0 && mouse_x < real_screen->w - 1 && - mouse_y > 0 && mouse_y < real_screen->h - 1) { - sdl_grab_start(); - } -} - -static void sdl_mouse_mode_change(Notifier *notify, void *data) -{ - if (qemu_input_is_absolute()) { - if (!absolute_enabled) { - absolute_enabled = 1; - if (qemu_console_is_graphic(NULL)) { - absolute_mouse_grab(); - } - } - } else if (absolute_enabled) { - if (!gui_fullscreen) { - sdl_grab_end(); - } - absolute_enabled = 0; - } -} - -static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state) -{ - static uint32_t bmap[INPUT_BUTTON_MAX] = { - [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), - [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), - [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), - [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), - [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), - }; - static uint32_t prev_state; - - if (prev_state != state) { - qemu_input_update_buttons(dcl->con, bmap, prev_state, state); - prev_state = state; - } - - if (qemu_input_is_absolute()) { - qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x, - real_screen->w); - qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y, - real_screen->h); - } else { - if (guest_cursor) { - x -= guest_x; - y -= guest_y; - guest_x += x; - guest_y += y; - dx = x; - dy = y; - } - qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, dx); - qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, dy); - } - qemu_input_event_sync(); -} - -static void sdl_scale(int width, int height) -{ - int bpp = real_screen->format->BitsPerPixel; - -#ifdef DEBUG_SDL - printf("SDL: Scaling to %dx%d bpp %d\n", width, height, bpp); -#endif - - if (bpp != 16 && bpp != 32) { - bpp = 32; - } - do_sdl_resize(width, height, bpp); - scaling_active = 1; -} - -static void toggle_full_screen(void) -{ - int width = surface_width(surface); - int height = surface_height(surface); - int bpp = surface_bits_per_pixel(surface); - - gui_fullscreen = !gui_fullscreen; - if (gui_fullscreen) { - gui_saved_width = real_screen->w; - gui_saved_height = real_screen->h; - gui_saved_scaling = scaling_active; - - do_sdl_resize(width, height, bpp); - scaling_active = 0; - - gui_saved_grab = gui_grab; - sdl_grab_start(); - } else { - if (gui_saved_scaling) { - sdl_scale(gui_saved_width, gui_saved_height); - } else { - do_sdl_resize(width, height, 0); - } - if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) { - sdl_grab_end(); - } - } - graphic_hw_invalidate(NULL); - graphic_hw_update(NULL); -} - -static void handle_keydown(SDL_Event *ev) -{ - int mod_state; - int keycode; - - if (alt_grab) { - mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == - (gui_grab_code | KMOD_LSHIFT); - } else if (ctrl_grab) { - mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; - } else { - mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code; - } - gui_key_modifier_pressed = mod_state; - - if (gui_key_modifier_pressed) { - keycode = sdl_keyevent_to_keycode(&ev->key); - switch (keycode) { - case 0x21: /* 'f' key on US keyboard */ - toggle_full_screen(); - gui_keysym = 1; - break; - case 0x16: /* 'u' key on US keyboard */ - if (scaling_active) { - scaling_active = 0; - sdl_switch(dcl, NULL); - graphic_hw_invalidate(NULL); - graphic_hw_update(NULL); - } - gui_keysym = 1; - break; - case 0x02 ... 0x0a: /* '1' to '9' keys */ - /* Reset the modifiers sent to the current console */ - reset_keys(); - console_select(keycode - 0x02); - gui_keysym = 1; - if (gui_fullscreen) { - break; - } - if (!qemu_console_is_graphic(NULL)) { - /* release grab if going to a text console */ - if (gui_grab) { - sdl_grab_end(); - } else if (absolute_enabled) { - sdl_show_cursor(); - } - } else if (absolute_enabled) { - sdl_hide_cursor(); - absolute_mouse_grab(); - } - break; - case 0x1b: /* '+' */ - case 0x35: /* '-' */ - if (!gui_fullscreen) { - int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50), - 160); - int height = (surface_height(surface) * width) / - surface_width(surface); - - sdl_scale(width, height); - graphic_hw_invalidate(NULL); - graphic_hw_update(NULL); - gui_keysym = 1; - } - default: - break; - } - } else if (!qemu_console_is_graphic(NULL)) { - int keysym = 0; - - if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { - switch (ev->key.keysym.sym) { - case SDLK_UP: - keysym = QEMU_KEY_CTRL_UP; - break; - case SDLK_DOWN: - keysym = QEMU_KEY_CTRL_DOWN; - break; - case SDLK_LEFT: - keysym = QEMU_KEY_CTRL_LEFT; - break; - case SDLK_RIGHT: - keysym = QEMU_KEY_CTRL_RIGHT; - break; - case SDLK_HOME: - keysym = QEMU_KEY_CTRL_HOME; - break; - case SDLK_END: - keysym = QEMU_KEY_CTRL_END; - break; - case SDLK_PAGEUP: - keysym = QEMU_KEY_CTRL_PAGEUP; - break; - case SDLK_PAGEDOWN: - keysym = QEMU_KEY_CTRL_PAGEDOWN; - break; - default: - break; - } - } else { - switch (ev->key.keysym.sym) { - case SDLK_UP: - keysym = QEMU_KEY_UP; - break; - case SDLK_DOWN: - keysym = QEMU_KEY_DOWN; - break; - case SDLK_LEFT: - keysym = QEMU_KEY_LEFT; - break; - case SDLK_RIGHT: - keysym = QEMU_KEY_RIGHT; - break; - case SDLK_HOME: - keysym = QEMU_KEY_HOME; - break; - case SDLK_END: - keysym = QEMU_KEY_END; - break; - case SDLK_PAGEUP: - keysym = QEMU_KEY_PAGEUP; - break; - case SDLK_PAGEDOWN: - keysym = QEMU_KEY_PAGEDOWN; - break; - case SDLK_BACKSPACE: - keysym = QEMU_KEY_BACKSPACE; - break; - case SDLK_DELETE: - keysym = QEMU_KEY_DELETE; - break; - default: - break; - } - } - if (keysym) { - kbd_put_keysym(keysym); - } else if (ev->key.keysym.unicode != 0) { - kbd_put_keysym(ev->key.keysym.unicode); - } - } - if (qemu_console_is_graphic(NULL) && !gui_keysym) { - sdl_process_key(&ev->key); - } -} - -static void handle_keyup(SDL_Event *ev) -{ - int mod_state; - - if (!alt_grab) { - mod_state = (ev->key.keysym.mod & gui_grab_code); - } else { - mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT)); - } - if (!mod_state && gui_key_modifier_pressed) { - gui_key_modifier_pressed = 0; - if (gui_keysym == 0) { - /* exit/enter grab if pressing Ctrl-Alt */ - if (!gui_grab) { - if (qemu_console_is_graphic(NULL)) { - sdl_grab_start(); - } - } else if (!gui_fullscreen) { - sdl_grab_end(); - } - /* SDL does not send back all the modifiers key, so we must - * correct it. */ - reset_keys(); - return; - } - gui_keysym = 0; - } - if (qemu_console_is_graphic(NULL) && !gui_keysym) { - sdl_process_key(&ev->key); - } -} - -static void handle_mousemotion(SDL_Event *ev) -{ - int max_x, max_y; - - if (qemu_console_is_graphic(NULL) && - (qemu_input_is_absolute() || absolute_enabled)) { - max_x = real_screen->w - 1; - max_y = real_screen->h - 1; - if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 || - ev->motion.x == max_x || ev->motion.y == max_y)) { - sdl_grab_end(); - } - if (!gui_grab && - (ev->motion.x > 0 && ev->motion.x < max_x && - ev->motion.y > 0 && ev->motion.y < max_y)) { - sdl_grab_start(); - } - } - if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { - sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, - ev->motion.x, ev->motion.y, ev->motion.state); - } -} - -static void handle_mousebutton(SDL_Event *ev) -{ - int buttonstate = SDL_GetMouseState(NULL, NULL); - SDL_MouseButtonEvent *bev; - - if (!qemu_console_is_graphic(NULL)) { - return; - } - - bev = &ev->button; - if (!gui_grab && !qemu_input_is_absolute()) { - if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) { - /* start grabbing all events */ - sdl_grab_start(); - } - } else { - if (ev->type == SDL_MOUSEBUTTONDOWN) { - buttonstate |= SDL_BUTTON(bev->button); - } else { - buttonstate &= ~SDL_BUTTON(bev->button); - } - sdl_send_mouse_event(0, 0, bev->x, bev->y, buttonstate); - } -} - -static void handle_activation(SDL_Event *ev) -{ -#ifdef _WIN32 - /* Disable grab if the window no longer has the focus - * (Windows-only workaround) */ - if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS && - !ev->active.gain && !gui_fullscreen) { - sdl_grab_end(); - } -#endif - if (!gui_grab && ev->active.gain && qemu_console_is_graphic(NULL) && - (qemu_input_is_absolute() || absolute_enabled)) { - absolute_mouse_grab(); - } - if (ev->active.state & SDL_APPACTIVE) { - if (ev->active.gain) { - /* Back to default interval */ - update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT); - } else { - /* Sleeping interval. Not using the long default here as - * sdl_refresh does not only update the guest screen, but - * also checks for gui events. */ - update_displaychangelistener(dcl, 500); - } - } -} - -static void sdl_refresh(DisplayChangeListener *dcl) -{ - SDL_Event ev1, *ev = &ev1; - - if (last_vm_running != runstate_is_running()) { - last_vm_running = runstate_is_running(); - sdl_update_caption(); - } - - graphic_hw_update(NULL); - SDL_EnableUNICODE(!qemu_console_is_graphic(NULL)); - - while (SDL_PollEvent(ev)) { - switch (ev->type) { - case SDL_VIDEOEXPOSE: - sdl_update(dcl, 0, 0, real_screen->w, real_screen->h); - break; - case SDL_KEYDOWN: - handle_keydown(ev); - break; - case SDL_KEYUP: - handle_keyup(ev); - break; - case SDL_QUIT: - if (!no_quit) { - no_shutdown = 0; - qemu_system_shutdown_request(); - } - break; - case SDL_MOUSEMOTION: - handle_mousemotion(ev); - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - handle_mousebutton(ev); - break; - case SDL_ACTIVEEVENT: - handle_activation(ev); - break; - case SDL_VIDEORESIZE: - sdl_scale(ev->resize.w, ev->resize.h); - graphic_hw_invalidate(NULL); - graphic_hw_update(NULL); - break; - default: - break; - } - } -} - -static void sdl_mouse_warp(DisplayChangeListener *dcl, - int x, int y, int on) -{ - if (on) { - if (!guest_cursor) - sdl_show_cursor(); - if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { - SDL_SetCursor(guest_sprite); - if (!qemu_input_is_absolute() && !absolute_enabled) { - SDL_WarpMouse(x, y); - } - } - } else if (gui_grab) - sdl_hide_cursor(); - guest_cursor = on; - guest_x = x, guest_y = y; -} - -static void sdl_mouse_define(DisplayChangeListener *dcl, - QEMUCursor *c) -{ - uint8_t *image, *mask; - int bpl; - - if (guest_sprite) - SDL_FreeCursor(guest_sprite); - - bpl = cursor_get_mono_bpl(c); - image = g_malloc0(bpl * c->height); - mask = g_malloc0(bpl * c->height); - cursor_get_mono_image(c, 0x000000, image); - cursor_get_mono_mask(c, 0, mask); - guest_sprite = SDL_CreateCursor(image, mask, c->width, c->height, - c->hot_x, c->hot_y); - g_free(image); - g_free(mask); - - if (guest_cursor && - (gui_grab || qemu_input_is_absolute() || absolute_enabled)) - SDL_SetCursor(guest_sprite); -} - -static void sdl_cleanup(void) -{ - if (guest_sprite) - SDL_FreeCursor(guest_sprite); - SDL_QuitSubSystem(SDL_INIT_VIDEO); -} - -static const DisplayChangeListenerOps dcl_ops = { - .dpy_name = "sdl", - .dpy_gfx_update = sdl_update, - .dpy_gfx_switch = sdl_switch, - .dpy_gfx_check_format = sdl_check_format, - .dpy_refresh = sdl_refresh, - .dpy_mouse_set = sdl_mouse_warp, - .dpy_cursor_define = sdl_mouse_define, -}; - -void sdl_display_early_init(int opengl) -{ - if (opengl == 1 /* on */) { - fprintf(stderr, - "SDL1 display code has no opengl support.\n" - "Please recompile qemu with SDL2, using\n" - "./configure --enable-sdl --with-sdlabi=2.0\n"); - } -} - -void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) -{ - int flags; - uint8_t data = 0; - const SDL_VideoInfo *vi; - char *filename; - -#if defined(__APPLE__) - /* always use generic keymaps */ - if (!keyboard_layout) - keyboard_layout = "en-us"; -#endif - if(keyboard_layout) { - kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout); - if (!kbd_layout) - exit(1); - } - - if (no_frame) - gui_noframe = 1; - - if (!full_screen) { - setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0); - } -#ifdef __linux__ - /* on Linux, SDL may use fbcon|directfb|svgalib when run without - * accessible $DISPLAY to open X11 window. This is often the case - * when qemu is run using sudo. But in this case, and when actually - * run in X11 environment, SDL fights with X11 for the video card, - * making current display unavailable, often until reboot. - * So make x11 the default SDL video driver if this variable is unset. - * This is a bit hackish but saves us from bigger problem. - * Maybe it's a good idea to fix this in SDL instead. - */ - setenv("SDL_VIDEODRIVER", "x11", 0); -#endif - - /* Enable normal up/down events for Caps-Lock and Num-Lock keys. - * This requires SDL >= 1.2.14. */ - setenv("SDL_DISABLE_LOCK_KEYS", "1", 1); - - flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE; - if (SDL_Init (flags)) { - fprintf(stderr, "Could not initialize SDL(%s) - exiting\n", - SDL_GetError()); - exit(1); - } - vi = SDL_GetVideoInfo(); - host_format = *(vi->vfmt); - - /* Load a 32x32x4 image. White pixels are transparent. */ - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp"); - if (filename) { - SDL_Surface *image = SDL_LoadBMP(filename); - if (image) { - uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255); - SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey); - SDL_WM_SetIcon(image, NULL); - } - g_free(filename); - } - - if (full_screen) { - gui_fullscreen = 1; - sdl_grab_start(); - } - - dcl = g_new0(DisplayChangeListener, 1); - dcl->ops = &dcl_ops; - register_displaychangelistener(dcl); - - mouse_mode_notifier.notify = sdl_mouse_mode_change; - qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier); - - sdl_update_caption(); - SDL_EnableKeyRepeat(250, 50); - gui_grab = 0; - - sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0); - sdl_cursor_normal = SDL_GetCursor(); - - atexit(sdl_cleanup); -} diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 64da1ef10ad33..95c9703c72401 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -45,37 +45,6 @@ static void vncws_tls_handshake_done(QIOTask *task, } } -<<<<<<< HEAD -======= -void vncws_tls_handshake_io(void *opaque) -{ - VncState *vs = (VncState *)opaque; - Error *err = NULL; - - if (!vs->tls) { - vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds, - NULL, - vs->vd->tlsaclname, - QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, - &err); - } - if (!vs->tls) { - VNC_DEBUG("Failed to setup TLS %s\n", - error_get_pretty(err)); - error_free(err); - vnc_client_error(vs); - return; - } - - qcrypto_tls_session_set_callbacks(vs->tls, - vnc_tls_push, - vnc_tls_pull, - vs); - - VNC_DEBUG("Start TLS WS handshake process\n"); - vncws_start_tls_handshake(vs); -} ->>>>>>> 919b29ba7d... Pebble Qemu gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED, GIOCondition condition G_GNUC_UNUSED, diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index f01449736fd8d..838980aaa55b4 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -541,15 +541,11 @@ void qemu_thread_create(QemuThread *thread, const char *name, /* Leave signal handling to the iothread. */ sigfillset(&set); -<<<<<<< HEAD /* Blocking the signals can result in undefined behaviour. */ sigdelset(&set, SIGSEGV); sigdelset(&set, SIGFPE); sigdelset(&set, SIGILL); /* TODO avoid SIGBUS loss on macOS */ -======= - sigemptyset(&oldset); /* keeps valgrind happy */ ->>>>>>> 919b29ba7d... Pebble Qemu pthread_sigmask(SIG_SETMASK, &set, &oldset); qemu_thread_args = g_new0(QemuThreadArgs, 1);