diff mbox series

hw/char/pl011: Enable TxFIFO and async transmission

Message ID 20200221044908.266883-1-gshan@redhat.com (mailing list archive)
State New, archived
Headers show
Series hw/char/pl011: Enable TxFIFO and async transmission | expand

Commit Message

Gavin Shan Feb. 21, 2020, 4:49 a.m. UTC
The depth of TxFIFO can be 1 or 16 depending on LCR[4]. The TxFIFO is
disabled when its depth is 1. It's nice to have TxFIFO enabled if
possible because more characters can be piled and transmitted at once,
which would have less overhead. Besides, we can be blocked because of
qemu_chr_fe_write_all(), which isn't nice.

This enables TxFIFO if possible. On ther other hand, the asynchronous
transmission is enabled if needed, as we did in hw/char/cadence_uart.c

Signed-off-by: Gavin Shan <gshan@redhat.com>
---
 hw/char/pl011.c         | 70 +++++++++++++++++++++++++++++++++++++----
 include/hw/char/pl011.h |  2 ++
 2 files changed, 66 insertions(+), 6 deletions(-)

Comments

no-reply@patchew.org Feb. 21, 2020, 6:28 a.m. UTC | #1
Patchew URL: https://patchew.org/QEMU/20200221044908.266883-1-gshan@redhat.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

  TEST    iotest-qcow2: 283
Passed all 116 iotests
**
ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: code should not be reached
ERROR - Bail out! ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: code should not be reached
make: *** [check-qtest-aarch64] Error 1
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 664, in <module>
    sys.exit(main())
---
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=fa7130c63a4e4192bda02ab29bd45081', '-u', '1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-sjyvkaqh/src/docker-src.2020-02-21-01.12.04.15392:/var/tmp/qemu:z,ro', 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2.
filter=--filter=label=com.qemu.instance.uuid=fa7130c63a4e4192bda02ab29bd45081
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-sjyvkaqh/src'
make: *** [docker-run-test-quick@centos7] Error 2

real    16m9.616s
user    0m8.253s


The full log is available at
http://patchew.org/logs/20200221044908.266883-1-gshan@redhat.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
Paolo Bonzini Feb. 21, 2020, 8:25 a.m. UTC | #2
On 21/02/20 05:49, Gavin Shan wrote:
> @@ -306,6 +362,7 @@ static const VMStateDescription vmstate_pl011 = {
>          VMSTATE_UINT32(int_enabled, PL011State),
>          VMSTATE_UINT32(int_level, PL011State),
>          VMSTATE_UINT32_ARRAY(read_fifo, PL011State, 16),
> +        VMSTATE_UINT8_ARRAY(write_fifo, PL011State, 16),
>          VMSTATE_UINT32(ilpr, PL011State),
>          VMSTATE_UINT32(ibrd, PL011State),
>          VMSTATE_UINT32(fbrd, PL011State),
> @@ -313,6 +370,7 @@ static const VMStateDescription vmstate_pl011 = {
>          VMSTATE_INT32(read_pos, PL011State),
>          VMSTATE_INT32(read_count, PL011State),
>          VMSTATE_INT32(read_trigger, PL011State),
> +        VMSTATE_INT32(write_count, PL011State),

Hi Gavin, please add these two fields to a subsection, so that they are
emitted only if write_count > 0.

Thanks!

Paolo

>          VMSTATE_END_OF_LIST()
>      }
>  };
> diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
> index 14187165c6..aeaf332eca 100644
> --- a/include/hw/char/pl011.h
> +++ b/include/hw/char/pl011.h
> @@ -38,6 +38,7 @@ typedef struct PL011State {
>      uint32_t int_enabled;
>      uint32_t int_level;
>      uint32_t read_fifo[16];
> +    uint8_t  write_fifo[16];
>      uint32_t ilpr;
>      uint32_t ibrd;
>      uint32_t fbrd;
> @@ -45,6 +46,7 @@ typedef struct PL011State {
>      int read_pos;
>      int read_count;
>      int read_trigger;
> +    int write_count;
>      CharBackend chr;
>      qemu_irq irq[6];
>      const unsigned char *id;
>
Gavin Shan Feb. 21, 2020, 8:56 a.m. UTC | #3
On 2/21/20 7:25 PM, Paolo Bonzini wrote:
> On 21/02/20 05:49, Gavin Shan wrote:
>> @@ -306,6 +362,7 @@ static const VMStateDescription vmstate_pl011 = {
>>           VMSTATE_UINT32(int_enabled, PL011State),
>>           VMSTATE_UINT32(int_level, PL011State),
>>           VMSTATE_UINT32_ARRAY(read_fifo, PL011State, 16),
>> +        VMSTATE_UINT8_ARRAY(write_fifo, PL011State, 16),
>>           VMSTATE_UINT32(ilpr, PL011State),
>>           VMSTATE_UINT32(ibrd, PL011State),
>>           VMSTATE_UINT32(fbrd, PL011State),
>> @@ -313,6 +370,7 @@ static const VMStateDescription vmstate_pl011 = {
>>           VMSTATE_INT32(read_pos, PL011State),
>>           VMSTATE_INT32(read_count, PL011State),
>>           VMSTATE_INT32(read_trigger, PL011State),
>> +        VMSTATE_INT32(write_count, PL011State),
> 
> Hi Gavin, please add these two fields to a subsection, so that they are
> emitted only if write_count > 0.
> 

Hi Paolo, sure, will do in next respin :)

Thanks,
Gavin
> 
>>           VMSTATE_END_OF_LIST()
>>       }
>>   };
>> diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
>> index 14187165c6..aeaf332eca 100644
>> --- a/include/hw/char/pl011.h
>> +++ b/include/hw/char/pl011.h
>> @@ -38,6 +38,7 @@ typedef struct PL011State {
>>       uint32_t int_enabled;
>>       uint32_t int_level;
>>       uint32_t read_fifo[16];
>> +    uint8_t  write_fifo[16];
>>       uint32_t ilpr;
>>       uint32_t ibrd;
>>       uint32_t fbrd;
>> @@ -45,6 +46,7 @@ typedef struct PL011State {
>>       int read_pos;
>>       int read_count;
>>       int read_trigger;
>> +    int write_count;
>>       CharBackend chr;
>>       qemu_irq irq[6];
>>       const unsigned char *id;
>>
>
Philippe Mathieu-Daudé Feb. 21, 2020, 9:37 a.m. UTC | #4
Cc'ing Igor & Drew.

On 2/21/20 7:28 AM, no-reply@patchew.org wrote:
> Patchew URL: https://patchew.org/QEMU/20200221044908.266883-1-gshan@redhat.com/
 >
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> make docker-image-centos7 V=1 NETWORK=1
> time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
> === TEST SCRIPT END ===
[...]
   TEST    check-qtest-aarch64: tests/qtest/bios-tables-test
> **
> ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: code should not be reached
> ERROR - Bail out! ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: code should not be reached
> make: *** [check-qtest-aarch64] Error 1

The virt machine is not happy, busy-looping?

$ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 \
   tests/qtest/bios-tables-test
/aarch64/acpi/virt: ^C
Philippe Mathieu-Daudé Feb. 21, 2020, 9:46 a.m. UTC | #5
On 2/21/20 10:37 AM, Philippe Mathieu-Daudé wrote:
> Cc'ing Igor & Drew.
> 
> On 2/21/20 7:28 AM, no-reply@patchew.org wrote:
>> Patchew URL: 
>> https://patchew.org/QEMU/20200221044908.266883-1-gshan@redhat.com/
>  >
>> === TEST SCRIPT BEGIN ===
>> #!/bin/bash
>> make docker-image-centos7 V=1 NETWORK=1
>> time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
>> === TEST SCRIPT END ===
> [...]
>    TEST    check-qtest-aarch64: tests/qtest/bios-tables-test
>> **
>> ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: 
>> code should not be reached
>> ERROR - Bail out! 
>> ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: 
>> code should not be reached
>> make: *** [check-qtest-aarch64] Error 1
> 
> The virt machine is not happy, busy-looping?
> 
> $ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 \
>    tests/qtest/bios-tables-test
> /aarch64/acpi/virt: ^C

So this test runs:

$ qemu-system-aarch64 -M virt -pflash pc-bios/edk2-aarch64-code.fd 
-pflash pc-bios/edk2-arm-vars.fd -cdrom 
tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2 -cpu 
cortex-a57 -serial stdio
[...]
[Bds]=============End Load Options Dumping============= 
 
 

[Bds]BdsWait ...Zzzzzzzzzzzz... 
 
 

[Bds]BdsWait(3)..Zzzz... 
 
 

[Bds]BdsWait(2)..Zzzz... 
 
 

[Bds]BdsWait(1)..Zzzz... 
 
 

[Bds]Exit the waiting! 
 
 

[Bds]Stop Hotkey Service! 
 
 

[Bds]UnregisterKeyNotify: 000C/0000 Success 
 
 

[Bds]UnregisterKeyNotify: 0017/0000 Success 
 
 

[Bds]UnregisterKeyNotify: 0000/000D Success 
 
 

Memory  Previous  Current    Next
  Type    Pages     Pages     Pages
======  ========  ========  ========
   09    00000000  00000080  000000A0
   0A    00000000  00000020  00000028
   00    00000000  00000000  00000000
   06    0000012C  00000370  0000044C
   05    00000096  00000280  00000320
   03    000003E8  000003AB  000003E8
   04    00002EE0  00002000  00002EE0
   01    00000014  00000000  00000014
   02    00000000  00000000  00000000
Memory Type Information settings change.
[Bds]Booting UEFI Misc Device
  BlockSize : 262144
  LastBlock : FF
[Bds] Expand VenHw(93E34C7E-B50E-11DF-9223-2443DFD72085,00) -> <null string>
BdsDxe: failed to load Boot0001 "UEFI Misc Device" from 
VenHw(93E34C7E-B50E-11DF-9223-2443DFD72085,00): Not Found
Memory  Previous  Current    Next
  Type    Pages     Pages     Pages
======  ========  ========  ========
   09    00000000  00000080  000000A0
   0A    00000000  00000020  00000028
   00    00000000  00000000  00000000
   06    0000012C  00000370  0000044C
   05    00000096  00000280  00000320
   03    000003E8  000003AB  000003E8
   04    00002EE0  00002040  00002EE0
   01    00000014  00000000  00000014
   02    00000000  00000000  00000000
Memory Type Information settings change.
[Bds]Booting UEFI Misc Device 2
  BlockSize : 512
  LastBlock : 33F
FatDiskIo: Cache Page OutBound occurred!
FSOpen: Open '\EFI\BOOT\BOOTAA64.EFI' Success
[Bds] Expand PciRoot(0x0)/Pci(0x2,0x0) -> 
PciRoot(0x0)/Pci(0x2,0x0)/CDROM(0x0,0x68,0x200)/\EFI\BOOT\BOOTAA64.EFI
BdsDxe: loading Boot0002 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x2,0x0)
[Security] 3rd party image[0] can be loaded after EndOfDxe: 
PciRoot(0x0)/Pci(0x2,0x0)/CDROM(0x0,0x68,0x200)/\EFI\BOOT\BOOTAA64.EFI.
InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 452B5840
add-symbol-file 
/home/lacos/src/upstream/qemu/tests/uefi-test-tools/Build/UefiTestTools/DEBUG_GCC5/AARCH64/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest/DEBUG/BiosTablesTest.dll 
0x442C3000
Loading driver at 0x000442C2000 EntryPoint=0x000442C47AC BiosTablesTest.efi
InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 4654E718
ProtectUefiImageCommon - 0x452B5840
   - 0x00000000442C2000 - 0x0000000000006000
SetUefiImageMemoryAttributes - 0x00000000442C2000 - 0x0000000000001000 
(0x0000000000004008)
SetUefiImageMemoryAttributes - 0x00000000442C3000 - 0x0000000000003000 
(0x0000000000020008)
SetUefiImageMemoryAttributes - 0x00000000442C6000 - 0x0000000000002000 
(0x0000000000004008)
BdsDxe: starting Boot0002 "UEFI Misc Device 2" from 
PciRoot(0x0)/Pci(0x2,0x0)
BiosTablesTest: BiosTablesTest=45100000 Rsdp10=0 Rsdp20=44020000
BiosTablesTest: Smbios21=0 Smbios30=47640000
BiosTablesTest: press any key to exit
qemu-system-aarch64: terminating on signal 2

Using -d in_asm -trace pl011\* you see after "press any key to exit" it 
is looping for a key on the uart:

12638@1582277983.168226:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168229:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168233:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168236:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168239:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168242:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168246:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168249:pl011_write addr 0x00000000 value 0x00000020
12638@1582277983.168252:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168255:pl011_write addr 0x00000000 value 0x0000002d
12638@1582277983.168259:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168262:pl011_write addr 0x00000000 value 0x00000020
12638@1582277983.168265:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168268:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168272:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168275:pl011_write addr 0x00000000 value 0x00000078
12638@1582277983.168279:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168281:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168285:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168288:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168292:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168295:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168298:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168303:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168307:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168310:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168313:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168316:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168320:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168323:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168327:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168329:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168333:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168336:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168340:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168342:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168346:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168349:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168353:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168356:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168359:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168362:pl011_write addr 0x00000000 value 0x00000036
12638@1582277983.168366:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168369:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168372:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168375:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168379:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168382:pl011_write addr 0x00000000 value 0x00000030
12638@1582277983.168385:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168388:pl011_write addr 0x00000000 value 0x0000000d
12638@1582277983.168392:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.168395:pl011_write addr 0x00000000 value 0x0000000a
----------------
IN:
0x4753da98:  a9bc7bfd  stp      x29, x30, [sp, #-0x40]!
0x4753da9c:  910003fd  mov      x29, sp
0x4753daa0:  a9025bf5  stp      x21, x22, [sp, #0x20]
0x4753daa4:  d0000015  adrp     x21, #0x4753f000
0x4753daa8:  a90153f3  stp      x19, x20, [sp, #0x10]
0x4753daac:  aa0003f6  mov      x22, x0
0x4753dab0:  aa0103f3  mov      x19, x1
0x4753dab4:  910082b5  add      x21, x21, #0x20
0x4753dab8:  a90363f7  stp      x23, x24, [sp, #0x30]
0x4753dabc:  d2800014  movz     x20, #0
0x4753dac0:  d2800318  movz     x24, #0x18
0x4753dac4:  f9403660  ldr      x0, [x19, #0x68]
0x4753dac8:  eb00029f  cmp      x20, x0
0x4753dacc:  54000083  b.lo     #0x4753dadc

----------------
IN:
0x4753dadc:  f9403a61  ldr      x1, [x19, #0x70]
0x4753dae0:  9b187e97  mul      x23, x20, x24
0x4753dae4:  aa1503e0  mov      x0, x21
0x4753dae8:  8b170021  add      x1, x1, x23
0x4753daec:  97ffff85  bl       #0x4753d900

----------------
IN:
0x4753d900:  a9be7bfd  stp      x29, x30, [sp, #-0x20]!
0x4753d904:  910003fd  mov      x29, sp
0x4753d908:  a90153f3  stp      x19, x20, [sp, #0x10]
0x4753d90c:  aa0003f3  mov      x19, x0
0x4753d910:  aa0103f4  mov      x20, x1
0x4753d914:  97ffff9d  bl       #0x4753d788

----------------
IN:
0x4753d788:  52800020  movz     w0, #0x1
0x4753d78c:  d65f03c0  ret

----------------
IN:
0x4753d918:  72001c1f  tst      w0, #0xff
0x4753d91c:  540001e0  b.eq     #0x4753d958

----------------
IN:
0x4753d920:  b50000f3  cbnz     x19, #0x4753d93c

----------------
IN:
0x4753d93c:  b50000f4  cbnz     x20, #0x4753d958

----------------
IN:
0x4753d958:  aa1403e1  mov      x1, x20
0x4753d95c:  aa1303e0  mov      x0, x19
0x4753d960:  a94153f3  ldp      x19, x20, [sp, #0x10]
0x4753d964:  a8c27bfd  ldp      x29, x30, [sp], #0x20
0x4753d968:  1400011e  b        #0x4753dde0

----------------
IN:
0x4753dde0:  aa1f03e2  mov      x2, xzr
0x4753dde4:  a9401003  ldp      x3, x4, [x0]
0x4753dde8:  b4000041  cbz      x1, #0x4753ddf0

----------------
IN:
0x4753ddec:  a9400821  ldp      x1, x2, [x1]
0x4753ddf0:  eb03003f  cmp      x1, x3
0x4753ddf4:  fa440040  ccmp     x2, x4, #0, eq
0x4753ddf8:  1a9f17e0  cset     w0, eq
0x4753ddfc:  d65f03c0  ret

----------------
IN:
0x4753daf0:  72001c1f  tst      w0, #0xff
0x4753daf4:  540013c0  b.eq     #0x4753dd6c

----------------
IN:
0x4753dd6c:  91000694  add      x20, x20, #1
0x4753dd70:  17ffff55  b        #0x4753dac4

----------------
IN:
0x4753dac4:  f9403660  ldr      x0, [x19, #0x68]
0x4753dac8:  eb00029f  cmp      x20, x0
0x4753dacc:  54000083  b.lo     #0x4753dadc

----------------
IN:
0x4753daf8:  f9403a60  ldr      x0, [x19, #0x70]
0x4753dafc:  d2800014  movz     x20, #0
0x4753db00:  8b170000  add      x0, x0, x23
0x4753db04:  f9400801  ldr      x1, [x0, #0x10]
0x4753db08:  d0000000  adrp     x0, #0x4753f000
0x4753db0c:  f9007801  str      x1, [x0, #0xf0]
0x4753db10:  97ffff1e  bl       #0x4753d788

----------------
IN:
0x4753db14:  53001c15  uxtb     w21, w0
0x4753db18:  34000275  cbz      w21, #0x4753db64

----------------
IN:
0x4753db1c:  b6f80254  tbz      x20, #0x3f, #0x4753db64

----------------
IN:
0x4753db64:  97ffff82  bl       #0x4753d96c

----------------
IN:
0x4753d96c:  a9bb7bfd  stp      x29, x30, [sp, #-0x50]!
0x4753d970:  d0000000  adrp     x0, #0x4753f000
0x4753d974:  910003fd  mov      x29, sp
0x4753d978:  a90153f3  stp      x19, x20, [sp, #0x10]
0x4753d97c:  f9407813  ldr      x19, [x0, #0xf0]
0x4753d980:  f90013f5  str      x21, [sp, #0x20]
0x4753d984:  b5000053  cbnz     x19, #0x4753d98c

----------------
IN:
0x4753d98c:  d0000014  adrp     x20, #0x4753f000
0x4753d990:  529ffff5  movz     w21, #0xffff
0x4753d994:  91000294  add      x20, x20, #0
0x4753d998:  b5000053  cbnz     x19, #0x4753d9a0

----------------
IN:
0x4753d9a0:  79400260  ldrh     w0, [x19]
0x4753d9a4:  6b15001f  cmp      w0, w21
0x4753d9a8:  54000141  b.ne     #0x4753d9d0

----------------
IN:
0x4753d9d0:  7100101f  cmp      w0, #4
0x4753d9d4:  54000080  b.eq     #0x4753d9e4

----------------
IN:
0x4753d9d8:  79400660  ldrh     w0, [x19, #2]
0x4753d9dc:  8b000273  add      x19, x19, x0
0x4753d9e0:  17fffff0  b        #0x4753d9a0

----------------
IN:
0x4753d9e4:  91002261  add      x1, x19, #8
0x4753d9e8:  aa1403e0  mov      x0, x20
0x4753d9ec:  97ffffc5  bl       #0x4753d900

----------------
IN:
0x4753d9f0:  72001c1f  tst      w0, #0xff
0x4753d9f4:  54fffe80  b.eq     #0x4753d9c4

----------------
IN:
0x4753d9c4:  79400660  ldrh     w0, [x19, #2]
0x4753d9c8:  8b000273  add      x19, x19, x0
0x4753d9cc:  17fffff3  b        #0x4753d998

----------------
IN:
0x4753d998:  b5000053  cbnz     x19, #0x4753d9a0

----------------
IN:
0x4753d9f8:  79400660  ldrh     w0, [x19, #2]
0x4753d9fc:  7100801f  cmp      w0, #0x20
0x4753da00:  54fffd61  b.ne     #0x4753d9ac

----------------
IN:
0x4753da04:  d0000001  adrp     x1, #0x4753f000
0x4753da08:  f9400e60  ldr      x0, [x19, #0x18]
0x4753da0c:  f9006820  str      x0, [x1, #0xd0]
0x4753da10:  b4fffce0  cbz      x0, #0x4753d9ac

----------------
IN:
0x4753da14:  d292c001  movz     x1, #0x9600
0x4753da18:  910143a5  add      x5, x29, #0x50
0x4753da1c:  52800102  movz     w2, #0x8
0x4753da20:  9100efa4  add      x4, x29, #0x3b
0x4753da24:  f90027a1  str      x1, [x29, #0x48]
0x4753da28:  52800021  movz     w1, #0x1
0x4753da2c:  3900efa2  strb     w2, [x29, #0x3b]
0x4753da30:  910103a3  add      x3, x29, #0x40
0x4753da34:  b81ecca1  str      w1, [x5, #-0x14]!
0x4753da38:  910113a2  add      x2, x29, #0x44
0x4753da3c:  b90043a1  str      w1, [x29, #0x40]
0x4753da40:  910123a1  add      x1, x29, #0x48
0x4753da44:  b90047bf  str      wzr, [x29, #0x44]
0x4753da48:  97fffd4d  bl       #0x4753cf7c

----------------
IN:
0x4753cf7c:  a9bb7bfd  stp      x29, x30, [sp, #-0x50]!
0x4753cf80:  910003fd  mov      x29, sp
0x4753cf84:  a90153f3  stp      x19, x20, [sp, #0x10]
0x4753cf88:  aa0003f4  mov      x20, x0
0x4753cf8c:  913fa000  add      x0, x0, #0xfe8
0x4753cf90:  a9025bf5  stp      x21, x22, [sp, #0x20]
0x4753cf94:  aa0203f5  mov      x21, x2
0x4753cf98:  a90363f7  stp      x23, x24, [sp, #0x30]
0x4753cf9c:  f90023f9  str      x25, [sp, #0x40]
0x4753cfa0:  aa0303f8  mov      x24, x3
0x4753cfa4:  aa0103f9  mov      x25, x1
0x4753cfa8:  aa0403f7  mov      x23, x4
0x4753cfac:  aa0503f6  mov      x22, x5
0x4753cfb0:  97ffffe0  bl       #0x4753cf30

----------------
IN:
0x4753cf30:  a9be7bfd  stp      x29, x30, [sp, #-0x20]!
0x4753cf34:  910003fd  mov      x29, sp
0x4753cf38:  f9000bf3  str      x19, [sp, #0x10]
0x4753cf3c:  aa0003f3  mov      x19, x0
0x4753cf40:  94000212  bl       #0x4753d788

----------------
IN:
0x4753cf44:  72001c1f  tst      w0, #0xff
0x4753cf48:  54000120  b.eq     #0x4753cf6c

----------------
IN:
0x4753cf4c:  f240067f  tst      x19, #3
0x4753cf50:  540000e0  b.eq     #0x4753cf6c

----------------
IN:
0x4753cf6c:  aa1303e0  mov      x0, x19
0x4753cf70:  f9400bf3  ldr      x19, [sp, #0x10]
0x4753cf74:  a8c27bfd  ldp      x29, x30, [sp], #0x20
0x4753cf78:  140003ae  b        #0x4753de30

----------------
IN:
0x4753de30:  b9400000  ldr      w0, [x0]
0x4753de34:  d5033dbf  dmb      ld
0x4753de38:  d65f03c0  ret

12638@1582277983.170601:pl011_read addr 0x00000fe8 value 0x00000014
----------------
IN:
0x4753cfb4:  b94002a1  ldr      w1, [x21]
0x4753cfb8:  d3441c00  ubfx     x0, x0, #4, #4
0x4753cfbc:  7100081f  cmp      w0, #2
0x4753cfc0:  52800213  movz     w19, #0x10
0x4753cfc4:  52800400  movz     w0, #0x20
0x4753cfc8:  1a938000  csel     w0, w0, w19, hi
0x4753cfcc:  7100003f  cmp      w1, #0
0x4753cfd0:  7a401022  ccmp     w1, w0, #2, ne
0x4753cfd4:  54000163  b.lo     #0x4753d000

----------------
IN:
0x4753cfd8:  b90002a0  str      w0, [x21]
0x4753cfdc:  b9400302  ldr      w2, [x24]
0x4753cfe0:  7100145f  cmp      w2, #5
0x4753cfe4:  54000508  b.hi     #0x4753d084

----------------
IN:
0x4753cfe8:  b0000000  adrp     x0, #0x4753d000
0x4753cfec:  91398000  add      x0, x0, #0xe60
0x4753cff0:  38624800  ldrb     w0, [x0, w2, uxtw]
0x4753cff4:  10000061  adr      x1, #0x4753d000
0x4753cff8:  8b208820  add      x0, x1, w0, sxtb #2
0x4753cffc:  d61f0000  br       x0

----------------
IN:
0x4753d018:  394002e2  ldrb     w2, [x23]
0x4753d01c:  7100205f  cmp      w2, #8
0x4753d020:  54000328  b.hi     #0x4753d084

----------------
IN:
0x4753d024:  90000000  adrp     x0, #0x4753d000
0x4753d028:  9139a000  add      x0, x0, #0xe68
0x4753d02c:  38624800  ldrb     w0, [x0, w2, uxtw]
0x4753d030:  10000061  adr      x1, #0x4753d03c
0x4753d034:  8b208820  add      x0, x1, w0, sxtb #2
0x4753d038:  d61f0000  br       x0

----------------
IN:
0x4753d068:  321b0673  orr      w19, w19, #0x60
0x4753d06c:  b94002c0  ldr      w0, [x22]
0x4753d070:  7100041f  cmp      w0, #1
0x4753d074:  540001a0  b.eq     #0x4753d0a8

----------------
IN:
0x4753d0a8:  f9400320  ldr      x0, [x25]
0x4753d0ac:  b5000080  cbnz     x0, #0x4753d0bc

----------------
IN:
0x4753d0bc:  f9400320  ldr      x0, [x25]
0x4753d0c0:  d29b0015  movz     x21, #0xd800
0x4753d0c4:  f2a0b715  movk     x21, #0x5b8, lsl #16
0x4753d0c8:  9100c296  add      x22, x20, #0x30
0x4753d0cc:  9ac00ab5  udiv     x21, x21, x0
0x4753d0d0:  aa1603e0  mov      x0, x22
0x4753d0d4:  53067eb7  lsr      w23, w21, #6
0x4753d0d8:  120016b5  and      w21, w21, #0x3f
0x4753d0dc:  97ffff95  bl       #0x4753cf30

12638@1582277983.171071:pl011_read addr 0x00000030 value 0x00000301
----------------
IN:
0x4753d0e0:  37000360  tbnz     w0, #0, #0x4753d14c

----------------
IN:
0x4753d14c:  9100b280  add      x0, x20, #0x2c
0x4753d150:  97ffff78  bl       #0x4753cf30

12638@1582277983.171143:pl011_read addr 0x0000002c value 0x00000070
----------------
IN:
0x4753d154:  6b13001f  cmp      w0, w19
0x4753d158:  54fffc61  b.ne     #0x4753d0e4

----------------
IN:
0x4753d15c:  91009280  add      x0, x20, #0x24
0x4753d160:  97ffff74  bl       #0x4753cf30

12638@1582277983.171221:pl011_read addr 0x00000024 value 0x00000027
----------------
IN:
0x4753d164:  6b0002ff  cmp      w23, w0
0x4753d168:  54fffbe1  b.ne     #0x4753d0e4

----------------
IN:
0x4753d16c:  9100a280  add      x0, x20, #0x28
0x4753d170:  97ffff70  bl       #0x4753cf30

12638@1582277983.171300:pl011_read addr 0x00000028 value 0x00000004
----------------
IN:
0x4753d174:  6b0002bf  cmp      w21, w0
0x4753d178:  d2800001  movz     x1, #0
0x4753d17c:  54fffb41  b.ne     #0x4753d0e4

----------------
IN:
0x4753d180:  aa0103e0  mov      x0, x1
0x4753d184:  f94023f9  ldr      x25, [sp, #0x40]
0x4753d188:  a94153f3  ldp      x19, x20, [sp, #0x10]
0x4753d18c:  a9425bf5  ldp      x21, x22, [sp, #0x20]
0x4753d190:  a94363f7  ldp      x23, x24, [sp, #0x30]
0x4753d194:  a8c57bfd  ldp      x29, x30, [sp], #0x50
0x4753d198:  d65f03c0  ret

----------------
IN:
0x4753da4c:  17ffffda  b        #0x4753d9b4

----------------
IN:
0x4753d9b4:  a94153f3  ldp      x19, x20, [sp, #0x10]
0x4753d9b8:  f94013f5  ldr      x21, [sp, #0x20]
0x4753d9bc:  a8c57bfd  ldp      x29, x30, [sp], #0x50
0x4753d9c0:  d65f03c0  ret

----------------
IN:
0x4753db68:  aa0003f4  mov      x20, x0
0x4753db6c:  34000275  cbz      w21, #0x4753dbb8

----------------
IN:
0x4753db70:  b6f80240  tbz      x0, #0x3f, #0x4753dbb8

----------------
IN:
0x4753dbb8:  97fffd9e  bl       #0x4753d230

----------------
IN:
0x4753d230:  d2800000  movz     x0, #0
0x4753d234:  d65f03c0  ret

----------------
IN:
0x4753dbbc:  aa0003f4  mov      x20, x0
0x4753dbc0:  34000275  cbz      w21, #0x4753dc0c

----------------
IN:
0x4753dbc4:  b6f80240  tbz      x0, #0x3f, #0x4753dc0c

----------------
IN:
0x4753dc0c:  d0000000  adrp     x0, #0x4753f000
0x4753dc10:  710002bf  cmp      w21, #0
0x4753dc14:  1a9f07f4  cset     w20, ne
0x4753dc18:  f10002df  cmp      x22, #0
0x4753dc1c:  f9007016  str      x22, [x0, #0xe0]
0x4753dc20:  1a9f17e0  cset     w0, eq
0x4753dc24:  6a00029f  tst      w20, w0
0x4753dc28:  540000e0  b.eq     #0x4753dc44

----------------
IN:
0x4753dc44:  d0000000  adrp     x0, #0x4753f000
0x4753dc48:  d0000017  adrp     x23, #0x4753f000
0x4753dc4c:  f9007413  str      x19, [x0, #0xe8]
0x4753dc50:  f9403260  ldr      x0, [x19, #0x60]
0x4753dc54:  f100001f  cmp      x0, #0
0x4753dc58:  f9006ee0  str      x0, [x23, #0xd8]
0x4753dc5c:  1a9f17e0  cset     w0, eq
0x4753dc60:  6a00029f  tst      w20, w0
0x4753dc64:  540000e0  b.eq     #0x4753dc80

----------------
IN:
0x4753dc80:  d0000000  adrp     x0, #0x4753f000
0x4753dc84:  d0000013  adrp     x19, #0x4753f000
0x4753dc88:  d0000016  adrp     x22, #0x4753f000
0x4753dc8c:  9101c000  add      x0, x0, #0x70
0x4753dc90:  91010273  add      x19, x19, #0x40
0x4753dc94:  910242d6  add      x22, x22, #0x90
0x4753dc98:  52800021  movz     w1, #0x1
0x4753dc9c:  52800102  movz     w2, #0x8
0x4753dca0:  d292c003  movz     x3, #0x9600
0x4753dca4:  29020801  stp      w1, w2, [x0, #0x10]
0x4753dca8:  29030401  stp      w1, w1, [x0, #0x18]
0x4753dcac:  39009661  strb     w1, [x19, #0x25]
0x4753dcb0:  39009a61  strb     w1, [x19, #0x26]
0x4753dcb4:  f94006c1  ldr      x1, [x22, #8]
0x4753dcb8:  f9000403  str      x3, [x0, #8]
0x4753dcbc:  aa1603e0  mov      x0, x22
0x4753dcc0:  39009262  strb     w2, [x19, #0x24]
0x4753dcc4:  f801c263  stur     x3, [x19, #0x1c]
0x4753dcc8:  d63f0020  blr      x1

----------------
IN:
0x4753d250:  a9bf7bfd  stp      x29, x30, [sp, #-0x10]!
0x4753d254:  aa0003e7  mov      x7, x0
0x4753d258:  910003fd  mov      x29, sp
0x4753d25c:  97fffff3  bl       #0x4753d228

----------------
IN:
0x4753d228:  d2800000  movz     x0, #0
0x4753d22c:  d65f03c0  ret

----------------
IN:
0x4753d260:  b7f801c0  tbnz     x0, #0x3f, #0x4753d298

----------------
IN:
0x4753d264:  f9401ce0  ldr      x0, [x7, #0x38]
0x4753d268:  f94008e8  ldr      x8, [x7, #0x10]
0x4753d26c:  f9400401  ldr      x1, [x0, #8]
0x4753d270:  39405005  ldrb     w5, [x0, #0x14]
0x4753d274:  b9400403  ldr      w3, [x0, #4]
0x4753d278:  b9401002  ldr      w2, [x0, #0x10]
0x4753d27c:  29431804  ldp      w4, w6, [x0, #0x18]
0x4753d280:  aa0703e0  mov      x0, x7
0x4753d284:  d63f0100  blr      x8

----------------
IN:
0x4753d51c:  a9b97bfd  stp      x29, x30, [sp, #-0x70]!
0x4753d520:  910003fd  mov      x29, sp
0x4753d524:  a90153f3  stp      x19, x20, [sp, #0x10]
0x4753d528:  aa0003f3  mov      x19, x0
0x4753d52c:  9101c3a0  add      x0, x29, #0x70
0x4753d530:  a9025bf5  stp      x21, x22, [sp, #0x20]
0x4753d534:  a90363f7  stp      x23, x24, [sp, #0x30]
0x4753d538:  2a0303f5  mov      w21, w3
0x4753d53c:  f90023f9  str      x25, [sp, #0x40]
0x4753d540:  aa0103f8  mov      x24, x1
0x4753d544:  b81e8c06  str      w6, [x0, #-0x18]!
0x4753d548:  2a0203f7  mov      w23, w2
0x4753d54c:  290c0ba4  stp      w4, w2, [x29, #0x60]
0x4753d550:  2a0403f6  mov      w22, w4
0x4753d554:  f90037a1  str      x1, [x29, #0x68]
0x4753d558:  aa0003e4  mov      x4, x0
0x4753d55c:  91017fa3  add      x3, x29, #0x5f
0x4753d560:  910183a2  add      x2, x29, #0x60
0x4753d564:  910193a1  add      x1, x29, #0x64
0x4753d568:  9101a3a0  add      x0, x29, #0x68
0x4753d56c:  39017fa5  strb     w5, [x29, #0x5f]
0x4753d570:  2a0603f4  mov      w20, w6
0x4753d574:  53001cb9  uxtb     w25, w5
0x4753d578:  97ffff09  bl       #0x4753d19c

----------------
IN:
0x4753d19c:  aa0003e6  mov      x6, x0
0x4753d1a0:  d0000000  adrp     x0, #0x4753f000
0x4753d1a4:  f9406800  ldr      x0, [x0, #0xd0]
0x4753d1a8:  b40000e0  cbz      x0, #0x4753d1c4

----------------
IN:
0x4753d1ac:  aa0403e5  mov      x5, x4
0x4753d1b0:  aa0303e4  mov      x4, x3
0x4753d1b4:  aa0203e3  mov      x3, x2
0x4753d1b8:  aa0103e2  mov      x2, x1
0x4753d1bc:  aa0603e1  mov      x1, x6
0x4753d1c0:  17ffff6f  b        #0x4753cf7c

12638@1582277983.172418:pl011_read addr 0x00000fe8 value 0x00000014
----------------
IN:
0x4753d000:  52800020  movz     w0, #0x1
0x4753d004:  52800013  movz     w19, #0
0x4753d008:  b90002a0  str      w0, [x21]
0x4753d00c:  17fffff4  b        #0x4753cfdc

----------------
IN:
0x4753cfdc:  b9400302  ldr      w2, [x24]
0x4753cfe0:  7100145f  cmp      w2, #5
0x4753cfe4:  54000508  b.hi     #0x4753d084

12638@1582277983.172518:pl011_read addr 0x00000030 value 0x00000301
12638@1582277983.172523:pl011_read addr 0x0000002c value 0x00000070
----------------
IN:
0x4753d0e4:  91006298  add      x24, x20, #0x18
0x4753d0e8:  aa1803e0  mov      x0, x24
0x4753d0ec:  97ffff91  bl       #0x4753cf30

12638@1582277983.172561:pl011_read addr 0x00000018 value 0x00000010
----------------
IN:
0x4753d0f0:  363fffc0  tbz      w0, #7, #0x4753d0e8

----------------
IN:
0x4753d0e8:  aa1803e0  mov      x0, x24
0x4753d0ec:  97ffff91  bl       #0x4753cf30

12638@1582277983.172625:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172629:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172633:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172636:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172640:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172643:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172647:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172650:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172654:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172658:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172661:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172665:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172668:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172672:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172675:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172679:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172682:pl011_read addr 0x00000018 value 0x00000010
12638@1582277983.172686:pl011_read addr 0x00000018 value 0x00000010
[keep looping]
Gavin Shan Feb. 24, 2020, 3:42 a.m. UTC | #6
On 2/21/20 8:46 PM, Philippe Mathieu-Daudé wrote:
> On 2/21/20 10:37 AM, Philippe Mathieu-Daudé wrote:
>> Cc'ing Igor & Drew.
>>
>> On 2/21/20 7:28 AM, no-reply@patchew.org wrote:
>>> Patchew URL: https://patchew.org/QEMU/20200221044908.266883-1-gshan@redhat.com/
>>  >
>>> === TEST SCRIPT BEGIN ===
>>> #!/bin/bash
>>> make docker-image-centos7 V=1 NETWORK=1
>>> time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
>>> === TEST SCRIPT END ===
>> [...]
>>    TEST    check-qtest-aarch64: tests/qtest/bios-tables-test
>>> **
>>> ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: code should not be reached
>>> ERROR - Bail out! ERROR:/tmp/qemu-test/src/tests/qtest/acpi-utils.c:145:acpi_find_rsdp_address_uefi: code should not be reached
>>> make: *** [check-qtest-aarch64] Error 1
>>
>> The virt machine is not happy, busy-looping?
>>
>> $ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 \
>>    tests/qtest/bios-tables-test
>> /aarch64/acpi/virt: ^C
> 
> So this test runs:
> 
> $ qemu-system-aarch64 -M virt -pflash pc-bios/edk2-aarch64-code.fd -pflash pc-bios/edk2-arm-vars.fd -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2 -cpu cortex-a57 -serial stdio

.../...

> 
> 12638@1582277983.172625:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172629:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172633:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172636:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172640:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172643:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172647:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172650:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172654:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172658:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172661:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172665:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172668:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172672:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172675:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172679:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172682:pl011_read addr 0x00000018 value 0x00000010
> 12638@1582277983.172686:pl011_read addr 0x00000018 value 0x00000010
> [keep looping]
> 

Thanks, Phil. It seems there is some race, which causes the PL011_FLAG_TXFF
isn't cleared properly. It should be fixed in v2, which was just posted.
At least, I didn't see the error locally with v2 :)

    # QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/qtest/bios-tables-test
      :
    # End of virt tests
    # End of acpi tests
    # End of aarch64 tests

Thanks,
Gavin
diff mbox series

Patch

diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 13e784f9d9..14ed04c8c8 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -169,6 +169,66 @@  static void pl011_set_read_trigger(PL011State *s)
         s->read_trigger = 1;
 }
 
+static gboolean pl011_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
+{
+    PL011State *s = (PL011State *)opaque;
+    int ret;
+
+    /* instant drain the fifo when there's no back-end */
+    if (!qemu_chr_fe_backend_connected(&s->chr)) {
+        s->write_count = 0;
+        return FALSE;
+    }
+
+    if (!s->write_count) {
+        return FALSE;
+    }
+
+    ret = qemu_chr_fe_write(&s->chr, s->write_fifo, s->write_count);
+    if (ret > 0) {
+        s->write_count -= ret;
+        memmove(s->write_fifo, s->write_fifo + ret, s->write_count);
+        s->flags &= ~PL011_FLAG_TXFF;
+        if (!s->write_count) {
+            s->flags |= PL011_FLAG_TXFE;
+        }
+    }
+
+    if (s->write_count) {
+        guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
+                                        pl011_xmit, s);
+        if (!r) {
+            s->write_count = 0;
+            s->flags &= ~PL011_FLAG_TXFF;
+            s->flags |= PL011_FLAG_TXFE;
+            return FALSE;
+        }
+    }
+
+    s->int_level |= PL011_INT_TX;
+    pl011_update(s);
+    return FALSE;
+}
+
+static void pl011_write_fifo(void *opaque, const unsigned char *buf, int size)
+{
+    PL011State *s = (PL011State *)opaque;
+    int depth = (s->lcr & 0x10) ? 16 : 1;
+
+    if (size >= (depth - s->write_count)) {
+        size = depth - s->write_count;
+        s->flags |= PL011_FLAG_TXFF;
+    }
+
+    if (size > 0) {
+        memcpy(s->write_fifo + s->write_count, buf, size);
+        s->write_count += size;
+        s->flags &= ~PL011_FLAG_TXFE;
+    }
+
+    pl011_xmit(NULL, G_IO_OUT, s);
+}
+
 static void pl011_write(void *opaque, hwaddr offset,
                         uint64_t value, unsigned size)
 {
@@ -179,13 +239,8 @@  static void pl011_write(void *opaque, hwaddr offset,
 
     switch (offset >> 2) {
     case 0: /* UARTDR */
-        /* ??? Check if transmitter is enabled.  */
         ch = value;
-        /* XXX this blocks entire thread. Rewrite to use
-         * qemu_chr_fe_write and background I/O callbacks */
-        qemu_chr_fe_write_all(&s->chr, &ch, 1);
-        s->int_level |= PL011_INT_TX;
-        pl011_update(s);
+        pl011_write_fifo(opaque, &ch, 1);
         break;
     case 1: /* UARTRSR/UARTECR */
         s->rsr = 0;
@@ -207,6 +262,7 @@  static void pl011_write(void *opaque, hwaddr offset,
         if ((s->lcr ^ value) & 0x10) {
             s->read_count = 0;
             s->read_pos = 0;
+            s->write_count = 0;
         }
         s->lcr = value;
         pl011_set_read_trigger(s);
@@ -306,6 +362,7 @@  static const VMStateDescription vmstate_pl011 = {
         VMSTATE_UINT32(int_enabled, PL011State),
         VMSTATE_UINT32(int_level, PL011State),
         VMSTATE_UINT32_ARRAY(read_fifo, PL011State, 16),
+        VMSTATE_UINT8_ARRAY(write_fifo, PL011State, 16),
         VMSTATE_UINT32(ilpr, PL011State),
         VMSTATE_UINT32(ibrd, PL011State),
         VMSTATE_UINT32(fbrd, PL011State),
@@ -313,6 +370,7 @@  static const VMStateDescription vmstate_pl011 = {
         VMSTATE_INT32(read_pos, PL011State),
         VMSTATE_INT32(read_count, PL011State),
         VMSTATE_INT32(read_trigger, PL011State),
+        VMSTATE_INT32(write_count, PL011State),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
index 14187165c6..aeaf332eca 100644
--- a/include/hw/char/pl011.h
+++ b/include/hw/char/pl011.h
@@ -38,6 +38,7 @@  typedef struct PL011State {
     uint32_t int_enabled;
     uint32_t int_level;
     uint32_t read_fifo[16];
+    uint8_t  write_fifo[16];
     uint32_t ilpr;
     uint32_t ibrd;
     uint32_t fbrd;
@@ -45,6 +46,7 @@  typedef struct PL011State {
     int read_pos;
     int read_count;
     int read_trigger;
+    int write_count;
     CharBackend chr;
     qemu_irq irq[6];
     const unsigned char *id;