Hello, 

QEMU's e500/e6500 models expose the Book E debug registers but do not 
emulate the facility behind them. I would like to check whether adding 
it would be welcome, and to agree on the scope before any code is 
written. 

What is missing today (checked against master) 
---------------------------------------------- 

* IAC1/IAC2 and DAC1/DAC2 are registered with a plain generic write 
callback. Values written are stored and never compared against 
anything, so no instruction-address-compare or data-address-compare 
event is ever generated. 

* IAC3-IAC8 and DBCR4/DBCR5 are not registered at all for e500mc and 
later. Writes are silently discarded, which hides the gap from guest 
software that probes the registers by writing and reading back. 

* DBCR0[TRAP] is not consulted. A trap instruction (or a conditional 
tw/td whose condition is met) always raises a Program interrupt, 
never a Debug interrupt, so the architecture's trap debug event does 
not exist. 

The delivery side is already present and correct: POWERPC_EXCP_DEBUG is 
routed through IVOR15 with DSRR0/DSRR1, and rfdi returns from it. Only 
the event sources are missing. DBCR0[ICMP] single-stepping is the one 
source that does work today. 

Why it matters 
-------------- 

Any guest that programs the hardware debug registers is affected: 
on-target debug agents in embedded operating systems, bare-metal test 
harnesses that place watchpoints on device registers, and firmware 
self-tests that verify the debug facility is present. Such guests either 
see no events at all, or - for IAC5-IAC8 - cannot even tell that the 
register is unimplemented, because the write appears to succeed and only 
the read-back fails. 

It is also an emulation-fidelity question on its own: the e6500 model 
advertises a CPU whose debug facility has eight instruction-address 
comparators, and software is entitled to use them. 

What an implementation would need to cover 
------------------------------------------ 

Registers: 

IAC1-IAC8 instruction address comparators (IAC5-IAC8 on e6500 only) 
DAC1, DAC2 data address comparators 
DBCR0 IDM master enable, per-comparator enables IAC1-IAC8, 
DAC1R/W, DAC2R/W, TRAP, ICMP, FT 
DBCR1 IAC1-IAC4 user/supervisor (US) and address-space (ER) 
filters, range modes 
DBCR2 DAC1/DAC2 US/ER filters, DAC12M range mode, data value 
compare control 
DBCR4/DBCR5 e500mc and later; DBCR5 carries the IAC5-IAC8 filters 
DBSR status bits per event, write-1-to-clear 

Semantics: 

* An event is generated only when DBCR0[IDM] and MSR[DE] are both set. 
* US filters on MSR[PR]; ER filters on MSR[IS] for instruction events 
and MSR[DS] for data events. 
* An IAC event fires before the instruction at the comparator address 
executes; DSRR0 holds that instruction's address. 
* A DAC event is reported for the access direction enabled in DBCR0 
(DACnR for loads, DACnW for stores). DBCR2[DAC12M] selects exact 
compare, inclusive range (DAC1 <= EA < DAC2) or exclusive range. 
* On delivery the corresponding DBSR bit is set and the Debug 
interrupt is taken through IVOR15 using DSRR0/DSRR1. 
* With DBCR0[TRAP] set, a trap instruction whose condition is met 
produces a trap debug event (DBSR[TRAP] plus Debug interrupt) 
instead of a Program interrupt. 

Implementation approach 
----------------------- 

The comparators map onto the generic TCG debug machinery: each enabled 
IACn becomes a BP_CPU breakpoint and each enabled DACn a BP_CPU 
watchpoint, re-synchronised from one function whenever DBCR0/DBCR1/ 
DBCR2, IACn or DACn is written, at reset and after migration. The 
TCGCPUOps hooks debug_check_breakpoint, debug_check_watchpoint and 
debug_excp_handler then decide at hit time whether the event passes the 
enable and filter conditions, set the DBSR bits and raise the interrupt. 

That is the same shape as the existing x86 DRx handling and the Power 
ISA CIABR/DAWR handling in target/ppc, so TCG code generation, 
translation block invalidation and coexistence with gdb breakpoints come 
for free. Writes to the control and comparator registers have to end the 
translation block, because the breakpoint set has changed. 

Limitations I would propose for a first version 
----------------------------------------------- 

* Events ignored while MSR[DE] is clear; no imprecise path 
(DBSR[IDE], event recorded and delivered when DE is set again). 
* DBCR1 IAC12M/IAC34M range modes fall back to exact compare, logged 
with LOG_UNIMP. 
* Data value compare (DVC1/DVC2, DBCR2 DVC1M/DVC2M) not implemented, 
logged with LOG_UNIMP. 
* DBCR0[IRPT] and DBCR0[RET] events not implemented. 
* A DAC event delivered after the access completes, so DSRR0 points at 
the following instruction. This matches e500 behaviour but differs 
from a strictly before-the-access model. 

Are these acceptable, or would any of them need to be in the first 
version? 

A related defect 
---------------- 

DBSR is write-1-to-clear, and spr_write_clear() in target/ppc/translate.c 
computes "spr & -value" instead of "spr & ~value". Negation is not 
complement, so writing a single bit to clear it leaves that bit set and 
instead clears the zero bits below it. Without this fixed, a guest cannot 
acknowledge a debug event at all. It also affects the 40x DBSR and HID0 
on the 970, so it stands on its own regardless of this RFC. I am filing 
it separately on the issue tracker. 

What we exercised 
----------------- 

We built a prototype against v9.2.0-rc2 and ran it on -M ppce500 
-cpu e6500 with a four-core guest that programs the facility directly: 

* instruction breakpoints hit at the expected address, with the guest 
handler reading DSRR0 and the DBSR bits correctly; 
* counting mode (comparator enabled, handler does not halt) produced 
exact hit counts over a free-running workload; 
* data watchpoints on a kernel variable caught the storing 
instruction, with the register context showing the written address; 
* the trap debug event took the Debug interrupt rather than the 
Program interrupt; 
* ICMP single-step interacted correctly with re-arming a comparator. 

Boot time and the -d guest_errors output were unchanged from stock QEMU. 

I am sending this as an RFC rather than a patch so the scope and the 
limitations above can be settled first. Comments welcome. 

Thanks, 
[ http://www.tubitak.gov.tr/sorumlulukreddi ] 

Reply via email to