aboutsummaryrefslogtreecommitdiff
path: root/target-sparc
AgeCommit message (Collapse)Author
2016-08-12trace-events: fix first line comment in trace-eventsLaurent Vivier
Documentation is docs/tracing.txt instead of docs/trace-events.txt. find . -name trace-events -exec \ sed -i "s?See docs/trace-events.txt for syntax documentation.?See docs/tracing.txt for syntax documentation.?" \ {} \; Signed-off-by: Laurent Vivier <lvivier@redhat.com> Message-id: 1470669081-17860-1-git-send-email-lvivier@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-07-12target-sparc: Elide duplicate updates to fprsRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Use cpu_loop_exit_restore from helper_check_ieee_exceptionsRichard Henderson
This avoids needing to save state before every FP operation. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Use cpu_fsr in stfsrRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Use explicit writes to cpu_fsrRichard Henderson
By arranging for explicit writes to cpu_fsr after floating point operations, we are able to mark the helpers as not writing to tcg globals, which means that we don't need to invalidate the integer register set across said calls. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Remove helper_ldf_asi, helper_stf_asiRichard Henderson
We've now implemented all fp asis inline, except for the no-fault memory reads. The latter can be passed directly to helper_ld_asi. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Directly implement block and short ldf/stf asisRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Directly implement easy ldf/stf asisRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Pass TCGMemOp constants to helper_ld/st_asiRichard Henderson
Reduces the argument count for helper_ld_asi; do helper_st_asi for consistency. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Fix obvious error in ASI_M_BFILLRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Directly implement easy ldd/std asisRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Introduce gen_check_alignRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Use QT0 to return results from lddaRichard Henderson
Also implement a few more twinx asis. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Directly implement easy ld/st asisRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Use defines from asi.hRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Add UA2005 defines to asi.hRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Import linux/arch/sparc/include/uapi/asm/asi.hRichard Henderson
Copied from tag v4.2, 64291f7db5bd8150a74ad2036f1037e6a0428df2. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Pass TCGMemOp to gen_ld/st_asiRichard Henderson
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Introduce get_asiRichard Henderson
Replace gen_get_asi, and use it for both 32-bit and 64-bit. For v8, do supervisor and immediate checks here. Also, move save_state and TB ending into the respective subroutines, out of disas_sparc_insn. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Store %asi in TB flagsRichard Henderson
Knowing the value of %asi at translation time means that we can handle the common settings without a function call. The steady state appears to be %asi == ASI_P, so that sparcv9 code can use offset forms of lda/sta. The %asi register gets pushed and popped on entry to certain functions, but it rarely takes on values other than ASI_P or ASI_AIUP. Therefore we're unlikely to be expanding the set of TBs created. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Unify asi handling between 32 and 64-bitRichard Henderson
We now have a single copy of gen_ld_asi, gen_st_asi, gen_swap_asi, and everything uses gen_get_asi. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Create gen_exceptionRichard Henderson
This unifies quite a few duplicate code fragments. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Store mmu index in TB flagsRichard Henderson
Doing this instead of saving the raw PS_PRIV and TL. This means that all nucleus mode TBs (TL > 0) can be shared. This fixes a bug in that we didn't include HS_PRIV in the TB flags, and so could produce incorrect TB matches for hypervisor state. The LSU and DMMU states were unused by the translator. Including them in TB flags meant unnecessary mismatches from tb_find_fast. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Remove softint as a TCG globalRichard Henderson
The global is only ever read for one insn; we can just as well use a load from env instead and generate the same code. This also allows us to indicate the the associated helpers do not touch TCG globals. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-sparc: Mark more flags for helpersRichard Henderson
Quite a few helpers do not modify tcg globals but did not so indicate. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-07-12target-*: Clean up cpu.h header guardsMarkus Armbruster
Most of them use guard symbols like CPU_$target_H, but we also have __MIPS_CPU_H__ and __TRICORE_CPU_H__. They all upset scripts/clean-header-guards.pl. The script dislikes CPU_$target_H because they don't match their file name (they should, to make guard collisions less likely). The others are reserved identifiers. Clean them all up: use guard symbol $target_CPU_H for target-$target/cpu.h. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Richard Henderson <rth@twiddle.net>
2016-07-12Fix confusing argument names in some common functionsSergey Sorokin
There are functions tlb_fill(), cpu_unaligned_access() and do_unaligned_access() that are called with access type and mmu index arguments. But these arguments are named 'is_write' and 'is_user' in their declarations. The patches fix the arguments to avoid a confusion. Signed-off-by: Sergey Sorokin <afarallax@yandex.ru> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Acked-by: David Gibson <david@gibson.dropbear.id.au> Message-id: 1465907177-1399402-1-git-send-email-afarallax@yandex.ru Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2016-07-07target-sparc: Use sparc_cpu_parse_features() directlyIgor Mammedov
Make SPARC target use sparc_cpu_parse_features() directly so it won't get in the way of switching other propertified targets to handling features as global properties. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2016-06-29Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into stagingPeter Maydell
* serial port fixes (Paolo) * Q35 modeling improvements (Paolo, Vasily) * chardev cleanup improvements (Marc-André) * iscsi bugfix (Peter L.) * cpu_exec patch from multi-arch patches (Peter C.) * pci-assign tweak (Lin Ma) # gpg: Signature made Wed 29 Jun 2016 15:56:30 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (35 commits) socket: unlink unix socket on remove socket: add listen feature char: clean up remaining chardevs when leaving vhost-user: disable chardev handlers on close vhost-user-test: fix g_cond_wait_until compat implementation vl: smp_parse: fix regression ich9: implement SCI_IRQ_SEL register ich9: implement ACPI_EN register serial: reinstate watch after migration serial: remove watch on reset char: change qemu_chr_fe_add_watch to return unsigned serial: separate serial_xmit and serial_watch_cb serial: simplify tsr_retry reset serial: make tsr_retry unsigned iscsi: fix assertion in is_sector_request_lun_aligned target-*: Don't redefine cpu_exec() pci-assign: Move "Invalid ROM" error message to pci-assign-load-rom.c vnc: generalize "VNC server running on ..." message scsi: esp: fix migration MC146818 RTC: add GPIO access to output IRQ ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2016-06-29target-*: Don't redefine cpu_exec()Peter Crosthwaite
This function needs to be converted to QOM hook and virtualised for multi-arch. This rename interferes, as cpu-qom will not have access to the renaming causing name divergence. This rename doesn't really do anything anyway so just delete it. Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> Message-Id: <69bd25a8678b8b31b91cd9760c777bed1aafb44e.1437212383.git.crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Peter Crosthwaite <crosthwaitepeter@gmail.com>
2016-06-24target-sparc: fix register corruption in ldstub if there is no write permissionArtyom Tarasenko
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-06-20Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' ↵Peter Maydell
into staging # gpg: Signature made Mon 20 Jun 2016 21:29:27 BST # gpg: using RSA key 0x9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/tracing-pull-request: (42 commits) trace: split out trace events for linux-user/ directory trace: split out trace events for qom/ directory trace: split out trace events for target-ppc/ directory trace: split out trace events for target-s390x/ directory trace: split out trace events for target-sparc/ directory trace: split out trace events for net/ directory trace: split out trace events for audio/ directory trace: split out trace events for ui/ directory trace: split out trace events for hw/alpha/ directory trace: split out trace events for hw/arm/ directory trace: split out trace events for hw/acpi/ directory trace: split out trace events for hw/vfio/ directory trace: split out trace events for hw/s390x/ directory trace: split out trace events for hw/pci/ directory trace: split out trace events for hw/ppc/ directory trace: split out trace events for hw/9pfs/ directory trace: split out trace events for hw/i386/ directory trace: split out trace events for hw/isa/ directory trace: split out trace events for hw/sd/ directory trace: split out trace events for hw/sparc/ directory ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2016-06-20trace: split out trace events for target-sparc/ directoryDaniel P. Berrange
Move all trace-events for files in the target-sparc/ directory to their own file. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-id: 1466066426-16657-37-git-send-email-berrange@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-06-20coccinelle: Remove unnecessary variables for function return valueEduardo Habkost
Use Coccinelle script to replace 'ret = E; return ret' with 'return E'. The script will do the substitution only when the function return type and variable type are the same. Manual fixups: * audio/audio.c: coding style of "read (...)" and "write (...)" * block/qcow2-cluster.c: wrap line to make it shorter * block/qcow2-refcount.c: change indentation of wrapped line * target-tricore/op_helper.c: fix coding style of "remainder|quotient" * target-mips/dsp_helper.c: reverted changes because I don't want to argue about checkpatch.pl * ui/qemu-pixman.c: fix line indentation * block/rbd.c: restore blank line between declarations and statements Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <1465855078-19435-4-git-send-email-ehabkost@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Unused Coccinelle rule name dropped along with a redundant comment; whitespace touched up in block/qcow2-cluster.c; stale commit message paragraph deleted] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-06-20exec: [tcg] Track which vCPU is performing translation and executionLluís Vilanova
Information is tracked inside the TCGContext structure, and later used by tracing events with the 'tcg' and 'vcpu' properties. The 'cpu' field is used to check tracing of translation-time events ("*_trans"). The 'tcg_env' field is used to pass it to execution-time events ("*_exec"). Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net> Message-id: 146549350162.18437.3033661139638458143.stgit@fimbulvetr.bsc.es Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-06-05target-*: dfilter support for in_asmRichard Henderson
The arm target was handled by 06486077, but other targets were ignored. This handles all the rest which actually support disassembly (that is, skipping moxie and tilegx). Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-05-19cpu: move exec-all.h inclusion out of cpu.hPaolo Bonzini
exec-all.h contains TCG-specific definitions. It is not needed outside TCG-specific files such as translate.c, exec.c or *helper.c. One generic function had snuck into include/exec/exec-all.h; move it to include/qom/cpu.h. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-05-19qemu-common: push cpu.h inclusion out of qemu-common.hPaolo Bonzini
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-05-19hw: move CPU state serialization to migration/cpu.hPaolo Bonzini
Remove usage of NEED_CPU_H from hw/hw.h. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-05-19target-sparc: make cpu-qom.h not target specificPaolo Bonzini
Make SPARCCPU an opaque type within cpu-qom.h, and move all definitions of private methods, as well as all type definitions that require knowledge of the layout to cpu.h. This helps making files independent of NEED_CPU_H if they only need to pass around CPU pointers. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-05-19cpu: make cpu-qom.h only include-able from cpu.hPaolo Bonzini
Make cpu-qom.h so that it is only included from cpu.h. Then there is no need for it to include cpu.h again. Later we will make cpu-qom.h target independent and we will _want_ to include it from elsewhere, but for now reduce the number of cases to handle. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-05-12tcg: Allow goto_tb to any target PC in user modeSergey Fedorov
In user mode, there's only a static address translation, TBs are always invalidated properly and direct jumps are reset when mapping change. Thus the destination address is always valid for direct jumps and there's no need to restrict it to the pages the TB resides in. Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com> Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org> Cc: Riku Voipio <riku.voipio@iki.fi> Cc: Blue Swirl <blauwirbel@gmail.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-05-12tb: consistently use uint32_t for tb->flagsEmilio G. Cota
We are inconsistent with the type of tb->flags: usage varies loosely between int and uint64_t. Settle to uint32_t everywhere, which is superior to both: at least one target (aarch64) uses the most significant bit in the u32, and uint64_t is wasteful. Compile-tested for all targets. Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com> Suggested-by: Richard Henderson <rth@twiddle.net> Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com> Signed-off-by: Emilio G. Cota <cota@braap.org> Signed-off-by: Richard Henderson <rth@twiddle.net> Message-Id: <1460049562-23517-1-git-send-email-cota@braap.org>
2016-04-15target-sparc: fix Trap Based Address Register behavior for sparc64Artyom Tarasenko
Accoding the chapter 7.6 Trap Processing of the SPARC Architecture Manual v9, the Trap Based Address Register is not modified as a trap is taken. This fix allows booting FreeBSD-10.3-RELEASE-sparc64. Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com> Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-04-15target-sparc: fix Nucleus quad LDD 128 bit access for windowed registersArtyom Tarasenko
Fix register offset calculation when regwptr is used. Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com> Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-04-11target-sparc: fix ldstub sign-extension bugMark Cave-Ayland
ldstub [addr], reg incorrectly reads a signed byte from memory which causes problems in the 32-bit Solaris mutex code. Here the byte value being read is 0xff which is incorrectly sign-extended to 0xffffffff before being written back to the target register causing lock detection to behave incorrectly. This fixes the intermittent hangs and MUTEX_HELD warnings issued to the console when running 32-bit Solaris images under qemu-system-sparc. With thanks to Joseph Dery for providing a condensed test image to consistently reproduce the problem on demand, and Martin Husemann for allowing me access to real hardware for comparison. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-By: Artyom Tarasenko <atar4qemu@gmail.com> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-03-22include/qemu/osdep.h: Don't include qapi/error.hMarkus Armbruster
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the Error typedef. Since then, we've moved to include qemu/osdep.h everywhere. Its file comment explains: "To avoid getting into possible circular include dependencies, this file should not include any other QEMU headers, with the exceptions of config-host.h, compiler.h, os-posix.h and os-win32.h, all of which are doing a similar job to this file and are under similar constraints." qapi/error.h doesn't do a similar job, and it doesn't adhere to similar constraints: it includes qapi-types.h. That's in excess of 100KiB of crap most .c files don't actually need. Add the typedef to qemu/typedefs.h, and include that instead of qapi/error.h. Include qapi/error.h in .c files that need it and don't get it now. Include qapi-types.h in qom/object.h for uint16List. Update scripts/clean-includes accordingly. Update it further to match reality: replace config.h by config-target.h, add sysemu/os-posix.h, sysemu/os-win32.h. Update the list of includes in the qemu/osdep.h comment quoted above similarly. This reduces the number of objects depending on qapi/error.h from "all of them" to less than a third. Unfortunately, the number depending on qapi-types.h shrinks only a little. More work is needed for that one. Signed-off-by: Markus Armbruster <armbru@redhat.com> [Fix compilation without the spice devel packages. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-01tcg: Add type for vCPU pointersLluís Vilanova
Adds the 'TCGv_env' type for pointers to 'CPUArchState' objects. The tracing infrastructure later needs to differentiate between regular pointers and pointers to vCPUs. Also changes all targets to use the new 'TCGv_env' type instead of the generic 'TCGv_ptr'. As of now, the change is merely cosmetic ('TCGv_env' translates into 'TCGv_ptr'), but that could change in the future to enforce the difference. Note that a 'TCGv_env' type (for 'CPUState') is not added, since all helpers currently receive the architecture-specific pointer ('CPUArchState'). Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Acked-by: Richard Henderson <rth@twiddle.net> Message-id: 145641859552.30295.7821536833590725201.stgit@localhost Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-02-23target-sparc: Use global registers for the register windowRichard Henderson
Via indirection off cpu_regwptr. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-02-23target-sparc: Tidy global register initializationRichard Henderson
Create tables for the various global registers that need allocation. Remove one level of indirection from gregnames and fregnames. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>