Re: [PATCH] audio: allow spice buffer_length to be adjusted

2022-01-08 Thread Volker Rümelin

Hi,


Spice clients that are running directly on the host system have
pratcially unlimited bandwidth so to reduce latency allow the user to
configure the buffer_length to a lower value if desired.

While virt-viewer can not take advantage of this, the PureSpice [1]
library used by Looking Glass [2] is able to produce and consume audio
at these rates, combined with the merge request for spice-server [3]
this allows for latencies close to realtime.

[1]https://github.com/gnif/PureSpice
[2]https://github.com/gnif/LookingGlass
[3]https://gitlab.freedesktop.org/spice/spice/-/merge_requests/199

Signed-off-by: Geoffrey McRae
---
  audio/spiceaudio.c | 19 ---
  1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index a8d370fe6f..0c44bbe836 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -76,7 +76,7 @@ static void *spice_audio_init(Audiodev *dev)
  if (!using_spice) {
  return NULL;
  }
-return &spice_audio_init;
+return dev;
  }
  
  static void spice_audio_fini (void *opaque)

@@ -90,6 +90,8 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings 
*as,
   void *drv_opaque)
  {
  SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
+Audiodev  *dev = (Audiodev *)drv_opaque;
+
  struct audsettings settings;
  
  #if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3

@@ -102,7 +104,12 @@ static int line_out_init(HWVoiceOut *hw, struct 
audsettings *as,
  settings.endianness = AUDIO_HOST_ENDIANNESS;
  
  audio_pcm_init_info (&hw->info, &settings);

-hw->samples = LINE_OUT_SAMPLES;
+if (dev->u.none.out->has_buffer_length) {
+hw->samples = audio_buffer_samples(dev->u.none.out, &settings, 1);


hw->samples counts in frames. The buffer is twice as large as expected.

+    hw->samples = audio_buffer_frames(dev->u.none.out, &settings, 
1);


I'm aware the default size of 1us will not be used, but it's a bad 
example because with a default timer-period of 1us the buffer has to 
be a few percent larger than timer-period. Otherwise the emulated audio 
device will never catch up if a AUD_write() has been delayed.



+} else {
+hw->samples = LINE_OUT_SAMPLES;
+}
+
  out->active = 0;
  
  out->sin.base.sif = &playback_sif.base;

@@ -199,6 +206,7 @@ static void line_out_volume(HWVoiceOut *hw, Volume *vol)
  static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void 
*drv_opaque)
  {
  SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
+Audiodev *dev = (Audiodev *)drv_opaque;
  struct audsettings settings;
  
  #if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3

@@ -211,7 +219,12 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings 
*as, void *drv_opaque)
  settings.endianness = AUDIO_HOST_ENDIANNESS;
  
  audio_pcm_init_info (&hw->info, &settings);

-hw->samples = LINE_IN_SAMPLES;
+if (dev->u.none.out->has_buffer_length) {
+hw->samples = audio_buffer_samples(dev->u.none.in, &settings, 1);


-    hw->samples = audio_buffer_samples(dev->u.none.in, &settings, 
1);
+    hw->samples = audio_buffer_frames(dev->u.none.in, &settings, 
1);



+} else {
+hw->samples = LINE_IN_SAMPLES;
+}
+
  in->active = 0;
  
  in->sin.base.sif = &record_sif.base;


Btw. have you seen my "[PATCH 00/15] reduce audio playback latency" 
patch series at 
https://lists.nongnu.org/archive/html/qemu-devel/2022-01/msg00780.html? 
I haven't tested, but I think it's possible to add a buffer_get_free 
function to audio/spiceaudio.c. That would eliminate the need to 
fine-tune the audio buffer length.


With best regards,
Volker



Re: [PULL v3 12/55] virtio-pci: add support for configure interrupt

2022-01-08 Thread Volker Rümelin

Hi,


From: Cindy Lu 

Add support for configure interrupt, The process is used kvm_irqfd_assign
to set the gsi to kernel. When the configure notifier was signal by
host, qemu will inject a msix interrupt to guest

Signed-off-by: Cindy Lu 
Message-Id: <20211104164827.21911-11-l...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
  hw/virtio/virtio-pci.h |  4 +-
  hw/virtio/virtio-pci.c | 92 --
  2 files changed, 83 insertions(+), 13 deletions(-)



Since this commit I see the following warnings.

With -drive 
if=virtio,id=disk1,file=/srv/cdimg/Linux/images/opensuse.qcow2,discard=unmap


qemu-system-x86_64: virtio-blk failed to set guest notifier (-16), 
ensure -accel kvm is set.
qemu-system-x86_64: virtio_bus_start_ioeventfd: failed. Fallback to 
userspace (slower).


With libvirt
    
  function='0'

   multifunction='on'/>
    
    
  function='1'/>

    
    
  
  function='0'/>

    
    
  io='io_uring'/>

  
  
  
  
    

2022-01-08T17:45:26.911491Z qemu-system-x86_64: virtio-scsi: Failed to 
set guest notifiers (-16), ensure -accel kvm is set.
2022-01-08T17:45:26.911505Z qemu-system-x86_64: 
virtio_bus_start_ioeventfd: failed. Fallback to userspace (slower).


The messages appear around the time the Linux guest initializes the drivers.

With best regards,
Volker



Re: [PATCH v14 00/26] Add LoongArch linux-user emulation support

2022-01-08 Thread WANG Xuerui

Hi,

On 1/7/22 15:59, gaosong wrote:

Hi Richard.
On 2022/1/7 下午1:01, Richard Henderson wrote:

On 1/6/22 1:41 AM, Song Gao wrote:

Based-on:<20220106074740.1754661-1-gaos...@loongson.cn>

Hi all,

This series only support linux-user emulation.
More about LoongArch at:https://github.com/loongson/

The latest kernel:
   *https://github.com/loongson/linux/tree/loongarch-next

Patches need review:
   * 0018-linux-user-Add-LoongArch-specific-structures.patch
   * 0019-linux-user-Add-LoongArch-signal-support.patch


You're still blocked on no upstream kernel support.
As shown in patch 19, the kernel abi is still in flux.


We hope the kernel will support as soon as possible. but ...
It would be best if you could work toward getting full system 
emulation completed.  Then all of the basic cpu emulation can be 
merged and all you'd need to keep updating is the linux-user portions.



We are going to submit V4 system emulation, maybe tommorrow or next-week, and 
We'll keep updating the linux-user portions.


I believe what Richard meant is suggesting you to re-order your patches 
so that the CPU emulation part (first half of this series) and the 
system emulation part (Xiaojuan's series) would be combined to one new 
series, to be reviewed and merged independent of the still-unstable 
Linux ABI that's blocking this series at the moment. To "keep updating 
the linux-user portions" without re-arranging the series will just delay 
inclusion further, IMO.


In case the description above is not clear enough:

We basically have 3 parts for full LoongArch target support: (a) CPU 
emulation, (b) privileged architecture & hw emulation, and (c) 
linux-user emulation. Currently this series consists of (a) and (c), 
while Xiaojuan's series has (b). And the tcg-dev branch you seem to be 
staging your work at [1] has the same ordering: (a) then (c) then (b), 
which is consistent with Xiaojuan's series cover letter.


However, because (c) is blocked by kernel port upstreaming, (a) could 
not be merged, and by re-combining (a) with (b) we can speed up review 
and inclusion of things. This would require you to coordinate with 
Xiaojuan and reorder your patches in the tcg-dev branch, so that you can 
generate the right series to send.


[1]: https://github.com/loongson/qemu/tree/tcg-dev



Thanks
Song

r~

[PATCH v2] hw: misc: edu: fix 2 off-by-one errors

2022-01-08 Thread Christopher Friedt
In the case that size1 was zero, because of the explicit
'end1 > addr' check, the range check would fail and the error
message would read as shown below. The correct comparison
is 'end1 >= addr' (or 'addr <= end1').

EDU: DMA range 0x4-0x3 out of bounds (0x4-0x3)!

At the opposite end, in the case that size1 was 4096, within()
would fail because of the non-inclusive check 'end1 < end2',
which should have been 'end1 <= end2'. The error message would
previously say

EDU: DMA range 0x4-0x40fff out of bounds (0x4-0x40fff)!

The solution is to use non-inclusive ranges e.g. [begin,end).

Signed-off-by: Christopher Friedt 
---
 hw/misc/edu.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index e935c418d4..73e97a54e7 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -103,25 +103,21 @@ static void edu_lower_irq(EduState *edu, uint32_t val)
 }
 }
 
-static bool within(uint64_t addr, uint64_t start, uint64_t end)
-{
-return start <= addr && addr < end;
-}
-
 static void edu_check_range(uint64_t addr, uint64_t size1, uint64_t start,
 uint64_t size2)
 {
 uint64_t end1 = addr + size1;
 uint64_t end2 = start + size2;
 
-if (within(addr, start, end2) &&
-end1 > addr && within(end1, start, end2)) {
+if (start <= addr && addr < end2 &&
+addr <= end1 &&
+start <= end1 && end1 <= end2) {
 return;
 }
 
-hw_error("EDU: DMA range 0x%016"PRIx64"-0x%016"PRIx64
- " out of bounds (0x%016"PRIx64"-0x%016"PRIx64")!",
-addr, end1 - 1, start, end2 - 1);
+hw_error("EDU: DMA range [0x%016"PRIx64", 0x%016"PRIx64")"
+ " out of bounds [0x%016"PRIx64", 0x%016"PRIx64")!",
+addr, end1, start, end2);
 }
 
 static dma_addr_t edu_clamp_addr(const EduState *edu, dma_addr_t addr)
-- 
2.30.1 (Apple Git-130)




Re: [PATCH 01/37] target/ppc: Introduce TRANS*FLAGS macros

2022-01-08 Thread Richard Henderson

On 1/7/22 10:56 AM, matheus.fe...@eldorado.org.br wrote:

From: Luis Pires

New macros that add FLAGS and FLAGS2 checking were added for
both TRANS and TRANS64.

Signed-off-by: Luis Pires
[ferst: - TRANS_FLAGS2 instead of TRANS_FLAGS_E
 - Use the new macros in load/store vector insns ]
Signed-off-by: Matheus Ferst
---
  target/ppc/translate.c  | 19 +++
  target/ppc/translate/vsx-impl.c.inc | 37 ++---
  2 files changed, 31 insertions(+), 25 deletions(-)


Reviewed-by: Richard Henderson 

r~



[PATCH] audio: allow spice buffer_length to be adjusted

2022-01-08 Thread Geoffrey McRae
Spice clients that are running directly on the host system have
pratcially unlimited bandwidth so to reduce latency allow the user to
configure the buffer_length to a lower value if desired.

While virt-viewer can not take advantage of this, the PureSpice [1]
library used by Looking Glass [2] is able to produce and consume audio
at these rates, combined with the merge request for spice-server [3]
this allows for latencies close to realtime.

[1] https://github.com/gnif/PureSpice
[2] https://github.com/gnif/LookingGlass
[3] https://gitlab.freedesktop.org/spice/spice/-/merge_requests/199

Signed-off-by: Geoffrey McRae 
---
 audio/spiceaudio.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index a8d370fe6f..0c44bbe836 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -76,7 +76,7 @@ static void *spice_audio_init(Audiodev *dev)
 if (!using_spice) {
 return NULL;
 }
-return &spice_audio_init;
+return dev;
 }
 
 static void spice_audio_fini (void *opaque)
@@ -90,6 +90,8 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings 
*as,
  void *drv_opaque)
 {
 SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
+Audiodev  *dev = (Audiodev *)drv_opaque;
+
 struct audsettings settings;
 
 #if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
@@ -102,7 +104,12 @@ static int line_out_init(HWVoiceOut *hw, struct 
audsettings *as,
 settings.endianness = AUDIO_HOST_ENDIANNESS;
 
 audio_pcm_init_info (&hw->info, &settings);
-hw->samples = LINE_OUT_SAMPLES;
+if (dev->u.none.out->has_buffer_length) {
+hw->samples = audio_buffer_samples(dev->u.none.out, &settings, 1);
+} else {
+hw->samples = LINE_OUT_SAMPLES;
+}
+
 out->active = 0;
 
 out->sin.base.sif = &playback_sif.base;
@@ -199,6 +206,7 @@ static void line_out_volume(HWVoiceOut *hw, Volume *vol)
 static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void 
*drv_opaque)
 {
 SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
+Audiodev *dev = (Audiodev *)drv_opaque;
 struct audsettings settings;
 
 #if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
@@ -211,7 +219,12 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings 
*as, void *drv_opaque)
 settings.endianness = AUDIO_HOST_ENDIANNESS;
 
 audio_pcm_init_info (&hw->info, &settings);
-hw->samples = LINE_IN_SAMPLES;
+if (dev->u.none.out->has_buffer_length) {
+hw->samples = audio_buffer_samples(dev->u.none.in, &settings, 1);
+} else {
+hw->samples = LINE_IN_SAMPLES;
+}
+
 in->active = 0;
 
 in->sin.base.sif = &record_sif.base;
-- 
2.30.2




[PATCH] hw: misc: edu: fix 2 off-by-one errors

2022-01-08 Thread Christopher Friedt
In the case that size1 was zero, because of the explicit
'end1 > addr' check, the range check would fail and the error
message would read as shown below. The correct comparison
is 'end1 >= addr' (or 'addr <= end1').

EDU: DMA range 0x4-0x3 out of bounds (0x4-0x3)!

At the opposite end, in the case that size1 was 4096, within()
would fail because of the non-inclusive check 'end1 < end2',
which should have been 'end1 <= end2'. The error message would
previously say

EDU: DMA range 0x4-0x40fff out of bounds (0x4-0x40fff)!

The solution is to use non-inclusive ranges e.g. [begin,end).

Signed-off-by: Christopher Friedt 
---
 hw/misc/edu.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index e935c418d4..73e97a54e7 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -103,25 +103,21 @@ static void edu_lower_irq(EduState *edu, uint32_t val)
 }
 }
 
-static bool within(uint64_t addr, uint64_t start, uint64_t end)
-{
-return start <= addr && addr < end;
-}
-
 static void edu_check_range(uint64_t addr, uint64_t size1, uint64_t start,
 uint64_t size2)
 {
 uint64_t end1 = addr + size1;
 uint64_t end2 = start + size2;
 
-if (within(addr, start, end2) &&
-end1 > addr && within(end1, start, end2)) {
+if (start <= addr && addr < end2 &&
+addr <= end1 &&
+start <= end1 && end1 <= end2) {
 return;
 }
 
-hw_error("EDU: DMA range 0x%016"PRIx64"-0x%016"PRIx64
- " out of bounds (0x%016"PRIx64"-0x%016"PRIx64")!",
-addr, end1 - 1, start, end2 - 1);
+hw_error("EDU: DMA range [0x%016"PRIx64", 0x%016"PRIx64")"
+ " out of bounds [0x%016"PRIx64", 0x%016"PRIx64")!",
+addr, end1, start, end2);
 }
 
 static dma_addr_t edu_clamp_addr(const EduState *edu, dma_addr_t addr)
-- 
2.30.2




[PULL 2/2] hw/sd: Add SDHC support for SD card SPI-mode

2022-01-08 Thread Philippe Mathieu-Daudé
From: Frank Chang 

In SPI-mode, SD card's OCR register: Card Capacity Status (CCS) bit
is not set to 1 correclty when the assigned SD image size is larger
than 2GB (SDHC). This will cause the SD card to be indentified as SDSC
incorrectly. CCS bit should be set to 1 if we are using SDHC.

Also, as there's no power up emulation in SPI-mode.
The OCR register: Card power up status bit bit (busy) should also
be set to 1 when reset. (busy bit is set to LOW if the card has not
finished the power up routine.)

Signed-off-by: Frank Chang 
Reviewed-by: Jim Shu 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211228125719.14712-1-frank.ch...@sifive.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index c10a1e469b7..cd67a7bac8e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -290,12 +290,6 @@ FIELD(OCR, CARD_POWER_UP,  31,  1)
| R_OCR_CARD_CAPACITY_MASK \
| R_OCR_CARD_POWER_UP_MASK)
 
-static void sd_set_ocr(SDState *sd)
-{
-/* All voltages OK */
-sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
-}
-
 static void sd_ocr_powerup(void *opaque)
 {
 SDState *sd = opaque;
@@ -311,6 +305,22 @@ static void sd_ocr_powerup(void *opaque)
 }
 }
 
+static void sd_set_ocr(SDState *sd)
+{
+/* All voltages OK */
+sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+
+if (sd->spi) {
+/*
+ * We don't need to emulate power up sequence in SPI-mode.
+ * Thus, the card's power up status bit should be set to 1 when reset.
+ * The card's capacity status bit should also be set if SD card size
+ * is larger than 2GB for SDHC support.
+ */
+sd_ocr_powerup(sd);
+}
+}
+
 static void sd_set_scr(SDState *sd)
 {
 sd->scr[0] = 0 << 4;/* SCR structure version 1.0 */
@@ -560,6 +570,7 @@ static void sd_reset(DeviceState *dev)
 
 sd->state = sd_idle_state;
 sd->rca = 0x;
+sd->size = size;
 sd_set_ocr(sd);
 sd_set_scr(sd);
 sd_set_cid(sd);
@@ -574,7 +585,6 @@ static void sd_reset(DeviceState *dev)
 memset(sd->function_group, 0, sizeof(sd->function_group));
 sd->erase_start = INVALID_ADDRESS;
 sd->erase_end = INVALID_ADDRESS;
-sd->size = size;
 sd->blk_len = 0x200;
 sd->pwd_len = 0;
 sd->expecting_acmd = false;
-- 
2.33.1




[PULL 1/2] hw/sd/sdcard: Rename Write Protect Group variables

2022-01-08 Thread Philippe Mathieu-Daudé
'wp_groups' holds a bitmap, rename it as 'wp_group_bmap'.
'wpgrps_size' is the bitmap size (in bits), rename it as
'wp_group_bits'.

Patch created mechanically using:

  $ sed -i -e s/wp_groups/wp_group_bmap/ \
   -e s/wpgrps_size/wp_group_bits/ hw/sd/sd.c

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210728181728.2012952-4-f4...@amsat.org>
Reviewed-by: Alexander Bulekov 
---
 hw/sd/sd.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bb5dbff68c0..c10a1e469b7 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -116,8 +116,8 @@ struct SDState {
 int32_t state;/* current card state, one of SDCardStates */
 uint32_t vhs;
 bool wp_switch;
-unsigned long *wp_groups;
-int32_t wpgrps_size;
+unsigned long *wp_group_bmap;
+int32_t wp_group_bits;
 uint64_t size;
 uint32_t blk_len;
 uint32_t multi_blk_cnt;
@@ -567,10 +567,10 @@ static void sd_reset(DeviceState *dev)
 sd_set_cardstatus(sd);
 sd_set_sdstatus(sd);
 
-g_free(sd->wp_groups);
+g_free(sd->wp_group_bmap);
 sd->wp_switch = sd->blk ? !blk_is_writable(sd->blk) : false;
-sd->wpgrps_size = sect;
-sd->wp_groups = bitmap_new(sd->wpgrps_size);
+sd->wp_group_bits = sect;
+sd->wp_group_bmap = bitmap_new(sd->wp_group_bits);
 memset(sd->function_group, 0, sizeof(sd->function_group));
 sd->erase_start = INVALID_ADDRESS;
 sd->erase_end = INVALID_ADDRESS;
@@ -673,7 +673,7 @@ static const VMStateDescription sd_vmstate = {
 VMSTATE_UINT32(card_status, SDState),
 VMSTATE_PARTIAL_BUFFER(sd_status, SDState, 1),
 VMSTATE_UINT32(vhs, SDState),
-VMSTATE_BITMAP(wp_groups, SDState, 0, wpgrps_size),
+VMSTATE_BITMAP(wp_group_bmap, SDState, 0, wp_group_bits),
 VMSTATE_UINT32(blk_len, SDState),
 VMSTATE_UINT32(multi_blk_cnt, SDState),
 VMSTATE_UINT32(erase_start, SDState),
@@ -803,8 +803,8 @@ static void sd_erase(SDState *sd)
 if (sdsc) {
 /* Only SDSC cards support write protect groups */
 wpnum = sd_addr_to_wpnum(erase_addr);
-assert(wpnum < sd->wpgrps_size);
-if (test_bit(wpnum, sd->wp_groups)) {
+assert(wpnum < sd->wp_group_bits);
+if (test_bit(wpnum, sd->wp_group_bmap)) {
 sd->card_status |= WP_ERASE_SKIP;
 continue;
 }
@@ -828,8 +828,8 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
  */
 continue;
 }
-assert(wpnum < sd->wpgrps_size);
-if (test_bit(wpnum, sd->wp_groups)) {
+assert(wpnum < sd->wp_group_bits);
+if (test_bit(wpnum, sd->wp_group_bmap)) {
 ret |= (1 << i);
 }
 }
@@ -869,7 +869,7 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
 
 static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
 {
-return test_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
+return test_bit(sd_addr_to_wpnum(addr), sd->wp_group_bmap);
 }
 
 static void sd_lock_command(SDState *sd)
@@ -897,7 +897,7 @@ static void sd_lock_command(SDState *sd)
 sd->card_status |= LOCK_UNLOCK_FAILED;
 return;
 }
-bitmap_zero(sd->wp_groups, sd->wpgrps_size);
+bitmap_zero(sd->wp_group_bmap, sd->wp_group_bits);
 sd->csd[14] &= ~0x10;
 sd->card_status &= ~CARD_IS_LOCKED;
 sd->pwd_len = 0;
@@ -1348,7 +1348,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 
 sd->state = sd_programming_state;
-set_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
+set_bit(sd_addr_to_wpnum(addr), sd->wp_group_bmap);
 /* Bzzztt  Operation complete.  */
 sd->state = sd_transfer_state;
 return sd_r1b;
@@ -1370,7 +1370,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 
 sd->state = sd_programming_state;
-clear_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
+clear_bit(sd_addr_to_wpnum(addr), sd->wp_group_bmap);
 /* Bzzztt  Operation complete.  */
 sd->state = sd_transfer_state;
 return sd_r1b;
-- 
2.33.1




[PULL 0/2] SD/MMC patches for 2022-01-08

2022-01-08 Thread Philippe Mathieu-Daudé
Hi Richard,

This is the SD/MMC PR that ought to be sent previously.

The following changes since commit b5a3d8bc9146ba22a25116cb748c97341bf99737:

  Merge tag 'pull-misc-20220103' of https://gitlab.com/rth7680/qemu into 
staging (2022-01-03 09:34:41 -0800)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/sdmmc-20220108

for you to fetch changes up to b66f73a0cb312c81470433dfd5275d2824bb89de:

  hw/sd: Add SDHC support for SD card SPI-mode (2022-01-04 08:50:28 +0100)


SD/MMC patches queue

- Add SDHC support for SD card SPI-mode (Frank Chang)



Frank Chang (1):
  hw/sd: Add SDHC support for SD card SPI-mode

Philippe Mathieu-Daudé (1):
  hw/sd/sdcard: Rename Write Protect Group variables

 hw/sd/sd.c | 52 +++-
 1 file changed, 31 insertions(+), 21 deletions(-)

-- 
2.33.1




Re: [PATCH v2] target/arm/cpu64: Use 32-bit GDBstub when running in 32-bit KVM mode

2022-01-08 Thread Philippe Mathieu-Daudé
On 1/8/22 16:09, Ard Biesheuvel wrote:
> When running under KVM, we may decide to run the CPU in 32-bit mode, by
> setting the 'aarch64=off' CPU option. In this case, we need to switch to
> the 32-bit version of the GDB stub too, so that GDB has the correct view
> of the CPU state. Without this, GDB debugging does not work at all, and
> errors out upon connecting to the target with a mysterious 'g' packet
> length error.
> 
> Cc: Richard Henderson 
> Cc: Peter Maydell 
> Cc: Alex Bennee 
> Signed-off-by: Ard Biesheuvel 
> ---
> v2: refactor existing CPUClass::gdb_... member assignments for the
> 32-bit code so we can reuse it for the 64-bit code

Way cleaner.

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH] target/m68k: don't word align SP in stack frame if M68K_FEATURE_UNALIGNED_DATA feature enabled

2022-01-08 Thread Laurent Vivier

Le 08/01/2022 à 19:04, Mark Cave-Ayland a écrit :

Commit a9431a03f7 ("target/m68k: add M68K_FEATURE_UNALIGNED_DATA feature") added
a new feature for processors from the 68020 onwards which do not require data
accesses to be word aligned.

Unfortunately the original commit missed an additional case whereby the SP is
still word aligned when setting up an additional format 1 stack frame so add the
necessary M68K_FEATURE_UNALIGNED_DATA feature guard.

Signed-off-by: Mark Cave-Ayland 
Fixes: a9431a03f7 ("target/m68k: add M68K_FEATURE_UNALIGNED_DATA feature")
---
  target/m68k/op_helper.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index ab6b559fd3..59d8d5a09e 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -429,7 +429,10 @@ static void m68k_interrupt_all(CPUM68KState *env, int 
is_hw)
  oldsr = sr;
  env->aregs[7] = sp;
  cpu_m68k_set_sr(env, sr &= ~SR_M);
-sp = env->aregs[7] & ~1;
+sp = env->aregs[7];
+if (!m68k_feature(env, M68K_FEATURE_UNALIGNED_DATA)) {
+sp &= ~1;
+}
  do_stack_frame(env, &sp, 1, oldsr, 0, retaddr);
  } else {
  do_stack_frame(env, &sp, 0, oldsr, 0, retaddr);


Reviewed-by: Laurent Vivier 



Re: [PULL 00/37] Bsd user arm patches

2022-01-08 Thread Richard Henderson

On 1/7/22 11:37 PM, Warner Losh wrote:

The following changes since commit 7d4ae4d4978079d564d3b6354c90a949130409fe:

   Merge tag 'pull-request-2022-01-05' of https://gitlab.com/thuth/qemu into 
staging (2022-01-05 08:47:18 -0800)

are available in the Git repository at:

   g...@gitlab.com:bsdimp/qemu.git tags/bsd-user-arm-pull-request

for you to fetch changes up to 18fe5d99f27fa7458724aa367e3c6784c36d5771:

   bsd-user: add arm target build (2022-01-07 22:58:51 -0700)


bsd-user: arm (32-bit) support

This series of patches brings in 32-bit arm support for bsd-user.  It implements
all the bits needed to do image activation, signal handling, stack management
and threading. This allows us to get to the "Hello World" level. The arm and x86
code are now the same as in the bsd-user fork. For full context, the fork is at
https://github.com/qemu-bsd-user/qemu-bsd-user/tree/blitz (though the the recent
sig{bus,segv} needed updates are incomplete).

v5 changes:
o Moved to using the CPUArchState typedef and move
  set_sigtramp_args, get_mcontext, set_mcontext, and
  get_ucontext_sigreturn prototypes to
  bsd-user/freebsd/target_os_ucontext.h
o Fix issues with arm's set_mcontext related to masking
  and remove an unnecessary check.

We're down to only one hunk needing review:
 bsd-user/arm/target_arch_signal.c: arm set_mcontext

Warnings that should be ignored:
o make checkpatch has a couple of complaints about the comments for the
  signal trampoline, since it's a false positive IMHO.
WARNING: Block comments use a leading /* on a separate line
+/* 8 */ sys_sigreturn,
WARNING: Block comments use a leading /* on a separate line
+/* 9 */ sys_exit



Warner Losh (37):
   bsd-user/mips*: Remove mips support
   bsd-user/freebsd: Create common target_os_ucontext.h file
   bsd-user: create a per-arch signal.c file
   bsd-user/i386/target_arch_signal.h: Remove target_sigcontext
   bsd-user/i386/target_arch_signal.h: use new target_os_ucontext.h
   bsd-user/i386/target_arch_signal.h: Update mcontext_t to match FreeBSD
   bsd-user/i386: Move the inlines into signal.c
   bsd-user/x86_64/target_arch_signal.h: Remove target_sigcontext
   bsd-user/x86_64/target_arch_signal.h: use new target_os_ucontext.h
   bsd-user/x86_64/target_arch_signal.h: Fill in mcontext_t
   bsd-user/x86_64: Move functions into signal.c
   bsd-user/target_os_signal.h: Move signal prototypes to
 target_os_ucontext.h
   bsd-user/arm/target_arch_sysarch.h: Use consistent include guards
   bsd-user/arm/target_syscall.h: Add copyright and update name
   bsd-user/arm/target_arch_cpu.c: Target specific TLS routines
   bsd-user/arm/target_arch_cpu.h: CPU Loop definitions
   bsd-user/arm/target_arch_cpu.h: Implement target_cpu_clone_regs
   bsd-user/arm/target_arch_cpu.h: Dummy target_cpu_loop implementation
   bsd-user/arm/target_arch_cpu.h: Implement trivial EXCP exceptions
   bsd-user/arm/target_arch_cpu.h: Implement data abort exceptions
   bsd-user/arm/target_arch_cpu.h: Implement system call dispatch
   bsd-user/arm/target_arch_reg.h: Implement core dump register copying
   bsd-user/arm/target_arch_vmparam.h: Parameters for arm address space
   bsd-user/arm/target_arch_sigtramp.h: Signal Trampoline for arm
   bsd-user/arm/target_arch_thread.h: Routines to create and switch to a
 thread
   bsd-user/arm/target_arch_elf.h: arm defines for ELF
   bsd-user/arm/target_arch_elf.h: arm get hwcap
   bsd-user/arm/target_arch_elf.h: arm get_hwcap2 impl
   bsd-user/arm/target_arch_signal.h: arm specific signal registers and
 stack
   bsd-user/arm/target_arch_signal.h: arm machine context and trapframe
 for signals
   bsd-user/arm/target_arch_signal.h: Define size of *context_t
   bsd-user/arm/signal.c: arm set_sigtramp_args
   bsd-user/arm/signal.c: arm get_mcontext
   bsd-user/arm/signal.c: arm set_mcontext
   bsd-user/arm/signal.c: arm get_ucontext_sigreturn
   bsd-user/freebsd/target_os_ucontext.h: Require TARGET_*CONTEXT_SIZE
   bsd-user: add arm target build

  bsd-user/arm/signal.c | 196 
  bsd-user/arm/target_arch.h|  28 
  bsd-user/arm/target_arch_cpu.c|  39 +
  bsd-user/arm/target_arch_cpu.h| 211 ++
  bsd-user/arm/target_arch_elf.h| 128 
  bsd-user/arm/target_arch_reg.h|  60 
  bsd-user/arm/target_arch_signal.h |  88 +++
  bsd-user/arm/target_arch_sigtramp.h   |  49 ++
  bsd-user/arm/target_arch_sysarch.h|   6 +-
  bsd-user/arm/target_arch_thread.h |  82 ++
  bsd-user/arm/target_arch_vmparam.h|  48 ++
  bsd-user/arm/target_syscall.h |  27 +++-
  bsd-user/freebsd/target_os_signal.h   |   3 -
  bsd-user/freebsd/target_os_ucontext.h |  44 ++
  bsd-user/i386/signal.c|  55 

Re: [PATCH v2] target/arm/cpu64: Use 32-bit GDBstub when running in 32-bit KVM mode

2022-01-08 Thread Richard Henderson

On 1/8/22 7:09 AM, Ard Biesheuvel wrote:

When running under KVM, we may decide to run the CPU in 32-bit mode, by
setting the 'aarch64=off' CPU option. In this case, we need to switch to
the 32-bit version of the GDB stub too, so that GDB has the correct view
of the CPU state. Without this, GDB debugging does not work at all, and
errors out upon connecting to the target with a mysterious 'g' packet
length error.

Cc: Richard Henderson
Cc: Peter Maydell
Cc: Alex Bennee
Signed-off-by: Ard Biesheuvel
---
v2: refactor existing CPUClass::gdb_... member assignments for the
 32-bit code so we can reuse it for the 64-bit code

  target/arm/cpu.c   | 16 +++-
  target/arm/cpu.h   |  2 ++
  target/arm/cpu64.c |  3 +++
  3 files changed, 16 insertions(+), 5 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH] linux-user: rt_sigprocmask, check read perms first

2022-01-08 Thread Laurent Vivier

Le 06/01/2022 à 23:00, Patrick Venture a écrit :

From: Shu-Chun Weng 

Linux kernel does it this way (checks read permission before validating `how`)
and the latest version of ABSL's `AddressIsReadable()` depends on this
behavior.

c.f.  
https://github.com/torvalds/linux/blob/9539ba4308ad5bdca6cb41c7b73cbb9f796dcdd7/kernel/signal.c#L3147
Reviewed-by: Patrick Venture 
Signed-off-by: Shu-Chun Weng 
---
  linux-user/syscall.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..3070d31f34 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9491,6 +9491,11 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
  }
  
  if (arg2) {

+if (!(p = lock_user(VERIFY_READ, arg2, 
sizeof(target_sigset_t), 1)))
+return -TARGET_EFAULT;
+target_to_host_sigset(&set, p);
+unlock_user(p, arg2, 0);
+set_ptr = &set;
  switch(how) {
  case TARGET_SIG_BLOCK:
  how = SIG_BLOCK;
@@ -9504,11 +9509,6 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
  default:
  return -TARGET_EINVAL;
  }
-if (!(p = lock_user(VERIFY_READ, arg2, 
sizeof(target_sigset_t), 1)))
-return -TARGET_EFAULT;
-target_to_host_sigset(&set, p);
-unlock_user(p, arg2, 0);
-set_ptr = &set;
  } else {
  how = 0;
  set_ptr = NULL;


I know it's only code move but generally we also update the style to pass scripts/checkpatch.pl 
successfully.


Could you also update TARGET_NR_sigprocmask in the same way as it seems the kernel behaves like this 
too in this case?


Thanks,
Laurent



[PATCH] target/m68k: don't word align SP in stack frame if M68K_FEATURE_UNALIGNED_DATA feature enabled

2022-01-08 Thread Mark Cave-Ayland
Commit a9431a03f7 ("target/m68k: add M68K_FEATURE_UNALIGNED_DATA feature") added
a new feature for processors from the 68020 onwards which do not require data
accesses to be word aligned.

Unfortunately the original commit missed an additional case whereby the SP is
still word aligned when setting up an additional format 1 stack frame so add the
necessary M68K_FEATURE_UNALIGNED_DATA feature guard.

Signed-off-by: Mark Cave-Ayland 
Fixes: a9431a03f7 ("target/m68k: add M68K_FEATURE_UNALIGNED_DATA feature")
---
 target/m68k/op_helper.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index ab6b559fd3..59d8d5a09e 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -429,7 +429,10 @@ static void m68k_interrupt_all(CPUM68KState *env, int 
is_hw)
 oldsr = sr;
 env->aregs[7] = sp;
 cpu_m68k_set_sr(env, sr &= ~SR_M);
-sp = env->aregs[7] & ~1;
+sp = env->aregs[7];
+if (!m68k_feature(env, M68K_FEATURE_UNALIGNED_DATA)) {
+sp &= ~1;
+}
 do_stack_frame(env, &sp, 1, oldsr, 0, retaddr);
 } else {
 do_stack_frame(env, &sp, 0, oldsr, 0, retaddr);
-- 
2.20.1




Re: [PATCH 0/4] linux-user: prctl follow-ups

2022-01-08 Thread Laurent Vivier

Le 06/01/2022 à 23:57, Richard Henderson a écrit :

Hi Laurent, as requested.  I did all of the cap_task_prctl options,
and fixed a few existing bugs with PR_GET_DEATHSIG.

r~

Richard Henderson (4):
   linux-user: Do not special-case NULL for PR_GET_PDEATHSIG
   linux-user: Map signal number in PR_GET_PDEATHSIG
   linux-user: Implement PR_SET_PDEATHSIG
   linux-user: Implement capability prctls

  linux-user/syscall.c | 11 ++-
  1 file changed, 10 insertions(+), 1 deletion(-)



Series applied to my linux-user-for-7.0 branch.

Thanks,
Laurent



Re: [PATCH 2/2] linux-user: Move target_struct.h generic definitions to generic/

2022-01-08 Thread Laurent Vivier

Le 07/01/2022 à 05:26, Richard Henderson a écrit :

Most targets share the same generic ipc structure definitions.

Signed-off-by: Richard Henderson 
---
  linux-user/aarch64/target_structs.h| 59 +-
  linux-user/arm/target_structs.h| 52 +--
  linux-user/cris/target_structs.h   | 59 +-
  linux-user/generic/target_structs.h| 58 +
  linux-user/hexagon/target_structs.h| 55 +---
  linux-user/i386/target_structs.h   | 59 +-
  linux-user/m68k/target_structs.h   | 59 +-
  linux-user/microblaze/target_structs.h | 59 +-
  linux-user/nios2/target_structs.h  | 59 +-
  linux-user/openrisc/target_structs.h   | 59 +-
  linux-user/riscv/target_structs.h  | 47 +---
  linux-user/sh4/target_structs.h| 59 +-
  linux-user/x86_64/target_structs.h | 36 +---
  13 files changed, 70 insertions(+), 650 deletions(-)
  create mode 100644 linux-user/generic/target_structs.h

diff --git a/linux-user/aarch64/target_structs.h 
b/linux-user/aarch64/target_structs.h
index 7c748344ca..3a06f373c3 100644
--- a/linux-user/aarch64/target_structs.h
+++ b/linux-user/aarch64/target_structs.h
@@ -1,58 +1 @@
-/*
- * ARM AArch64 specific structures for linux-user
- *
- * Copyright (c) 2013 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.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#ifndef AARCH64_TARGET_STRUCTS_H
-#define AARCH64_TARGET_STRUCTS_H
-
-struct target_ipc_perm {
-abi_int __key;  /* Key.  */
-abi_uint uid;   /* Owner's user ID.  */
-abi_uint gid;   /* Owner's group ID.  */
-abi_uint cuid;  /* Creator's user ID.  */
-abi_uint cgid;  /* Creator's group ID.  */
-abi_ushort mode;/* Read/write permission.  */
-abi_ushort __pad1;
-abi_ushort __seq;   /* Sequence number.  */
-abi_ushort __pad2;
-abi_ulong __unused1;
-abi_ulong __unused2;
-};
-
-struct target_shmid_ds {
-struct target_ipc_perm shm_perm;/* operation permission struct */
-abi_long shm_segsz; /* size of segment in bytes */
-abi_ulong shm_atime;/* time of last shmat() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused1;
-#endif
-abi_ulong shm_dtime;/* time of last shmdt() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused2;
-#endif
-abi_ulong shm_ctime;/* time of last change by shmctl() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused3;
-#endif
-abi_int shm_cpid;   /* pid of creator */
-abi_int shm_lpid;   /* pid of last shmop */
-abi_ulong shm_nattch;   /* number of current attaches */
-abi_ulong __unused4;
-abi_ulong __unused5;
-};
-
-#endif
+#include "../generic/target_structs.h"
diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 25bf8dd3a5..3a06f373c3 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -1,51 +1 @@
-/*
- * ARM specific structures for linux-user
- *
- * Copyright (c) 2013 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.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#ifndef ARM_TARGET_STRUCTS_H
-#define ARM_TARGET_STRUCTS_H
-
-struct target_ipc_perm {
-abi_int __key;  /* Key.  */
-abi_uint uid;   /* Owner's user ID.  */
-abi_uint gid;   /* Owner's group ID.  */
- 

Re: [PATCH 1/2] linux-user/arm: Move target_oabi_flock64 out of target_structs.h

2022-01-08 Thread Laurent Vivier

Le 07/01/2022 à 05:25, Richard Henderson a écrit :

Place it next to copy_from/to_user_oabi_flock64, the only users,
inside the existing target-specific ifdef.  This leaves only
generic ipc structs in target_structs.h.

Signed-off-by: Richard Henderson 
---
  linux-user/arm/target_structs.h | 8 
  linux-user/syscall.c| 8 
  2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 339b070bf1..25bf8dd3a5 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -48,12 +48,4 @@ struct target_shmid_ds {
  abi_ulong __unused4;
  abi_ulong __unused5;
  };
-
-struct target_oabi_flock64 {
-abi_short l_type;
-abi_short l_whence;
-abi_llong l_start;
-abi_llong l_len;
-abi_int   l_pid;
-} QEMU_PACKED;
  #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..ca6e0b8fb0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6927,6 +6927,14 @@ typedef abi_long from_flock64_fn(struct flock64 *fl, 
abi_ulong target_addr);
  typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 
*fl);
  
  #if defined(TARGET_ARM) && TARGET_ABI_BITS == 32

+struct target_oabi_flock64 {
+abi_short l_type;
+abi_short l_whence;
+abi_llong l_start;
+abi_llong l_len;
+abi_int   l_pid;
+} QEMU_PACKED;
+
  static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
 abi_ulong 
target_flock_addr)
  {


Reviewed-by: Laurent Vivier 



Re: [PATCH 2/2] linux-user: Move target_struct.h generic definitions to generic/

2022-01-08 Thread Laurent Vivier

Le 07/01/2022 à 05:26, Richard Henderson a écrit :

Most targets share the same generic ipc structure definitions.

Signed-off-by: Richard Henderson 
---
  linux-user/aarch64/target_structs.h| 59 +-
  linux-user/arm/target_structs.h| 52 +--
  linux-user/cris/target_structs.h   | 59 +-
  linux-user/generic/target_structs.h| 58 +
  linux-user/hexagon/target_structs.h| 55 +---
  linux-user/i386/target_structs.h   | 59 +-
  linux-user/m68k/target_structs.h   | 59 +-
  linux-user/microblaze/target_structs.h | 59 +-
  linux-user/nios2/target_structs.h  | 59 +-
  linux-user/openrisc/target_structs.h   | 59 +-
  linux-user/riscv/target_structs.h  | 47 +---
  linux-user/sh4/target_structs.h| 59 +-
  linux-user/x86_64/target_structs.h | 36 +---
  13 files changed, 70 insertions(+), 650 deletions(-)
  create mode 100644 linux-user/generic/target_structs.h

diff --git a/linux-user/aarch64/target_structs.h 
b/linux-user/aarch64/target_structs.h
index 7c748344ca..3a06f373c3 100644
--- a/linux-user/aarch64/target_structs.h
+++ b/linux-user/aarch64/target_structs.h
@@ -1,58 +1 @@
-/*
- * ARM AArch64 specific structures for linux-user
- *
- * Copyright (c) 2013 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.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#ifndef AARCH64_TARGET_STRUCTS_H
-#define AARCH64_TARGET_STRUCTS_H
-
-struct target_ipc_perm {
-abi_int __key;  /* Key.  */
-abi_uint uid;   /* Owner's user ID.  */
-abi_uint gid;   /* Owner's group ID.  */
-abi_uint cuid;  /* Creator's user ID.  */
-abi_uint cgid;  /* Creator's group ID.  */
-abi_ushort mode;/* Read/write permission.  */
-abi_ushort __pad1;
-abi_ushort __seq;   /* Sequence number.  */
-abi_ushort __pad2;
-abi_ulong __unused1;
-abi_ulong __unused2;
-};
-
-struct target_shmid_ds {
-struct target_ipc_perm shm_perm;/* operation permission struct */
-abi_long shm_segsz; /* size of segment in bytes */
-abi_ulong shm_atime;/* time of last shmat() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused1;
-#endif
-abi_ulong shm_dtime;/* time of last shmdt() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused2;
-#endif
-abi_ulong shm_ctime;/* time of last change by shmctl() */
-#if TARGET_ABI_BITS == 32
-abi_ulong __unused3;
-#endif
-abi_int shm_cpid;   /* pid of creator */
-abi_int shm_lpid;   /* pid of last shmop */
-abi_ulong shm_nattch;   /* number of current attaches */
-abi_ulong __unused4;
-abi_ulong __unused5;
-};
-
-#endif
+#include "../generic/target_structs.h"
diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 25bf8dd3a5..3a06f373c3 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -1,51 +1 @@
-/*
- * ARM specific structures for linux-user
- *
- * Copyright (c) 2013 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.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#ifndef ARM_TARGET_STRUCTS_H
-#define ARM_TARGET_STRUCTS_H
-
-struct target_ipc_perm {
-abi_int __key;  /* Key.  */
-abi_uint uid;   /* Owner's user ID.  */
-abi_uint gid;   /* Owner's group ID.  */
- 

Re: [PATCH 1/2] linux-user/arm: Move target_oabi_flock64 out of target_structs.h

2022-01-08 Thread Laurent Vivier

Le 07/01/2022 à 05:25, Richard Henderson a écrit :

Place it next to copy_from/to_user_oabi_flock64, the only users,
inside the existing target-specific ifdef.  This leaves only
generic ipc structs in target_structs.h.

Signed-off-by: Richard Henderson 
---
  linux-user/arm/target_structs.h | 8 
  linux-user/syscall.c| 8 
  2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 339b070bf1..25bf8dd3a5 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -48,12 +48,4 @@ struct target_shmid_ds {
  abi_ulong __unused4;
  abi_ulong __unused5;
  };
-
-struct target_oabi_flock64 {
-abi_short l_type;
-abi_short l_whence;
-abi_llong l_start;
-abi_llong l_len;
-abi_int   l_pid;
-} QEMU_PACKED;
  #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..ca6e0b8fb0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6927,6 +6927,14 @@ typedef abi_long from_flock64_fn(struct flock64 *fl, 
abi_ulong target_addr);
  typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 
*fl);
  
  #if defined(TARGET_ARM) && TARGET_ABI_BITS == 32

+struct target_oabi_flock64 {
+abi_short l_type;
+abi_short l_whence;
+abi_llong l_start;
+abi_llong l_len;
+abi_int   l_pid;
+} QEMU_PACKED;
+
  static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
 abi_ulong 
target_flock_addr)
  {


Applied to my linux-user-for-7.0 branch.

Thanks,
Laurent




Re: [PATCH] macfb: fix VRAM dirty memory region logging

2022-01-08 Thread Laurent Vivier

Le 08/01/2022 à 18:15, Mark Cave-Ayland a écrit :

On 08/01/2022 16:53, Laurent Vivier wrote:


Le 08/01/2022 à 17:41, Mark Cave-Ayland a écrit :

The macfb VRAM memory region was configured with coalescing rather than dirty
memory logging enabled, causing some areas of the screen not to redraw after
a full screen update.

Signed-off-by: Mark Cave-Ayland 
Fixes: 8ac919a065 ("hw/m68k: add Nubus macfb video card")
---
  hw/display/macfb.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/macfb.c b/hw/display/macfb.c
index 277d3e6633..4bd7c3ad6a 100644
--- a/hw/display/macfb.c
+++ b/hw/display/macfb.c
@@ -661,9 +661,9 @@ static bool macfb_common_realize(DeviceState *dev, 
MacfbState *s, Error **errp)
  memory_region_init_ram(&s->mem_vram, OBJECT(dev), "macfb-vram",
 MACFB_VRAM_SIZE, &error_abort);
+    memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
  s->vram = memory_region_get_ram_ptr(&s->mem_vram);
  s->vram_bit_mask = MACFB_VRAM_SIZE - 1;
-    memory_region_set_coalescing(&s->mem_vram);
  s->vbl_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, macfb_vbl_timer, s);
  macfb_update_mode(s);


I understant why you add memory_region_set_log() but I don't understand why you remove 
memory_region_set_coalescing().


Looking at the other display devices, only VGA and cirrus use memory_region_set_coalescing() and 
that's on the IO ports rather than the VRAM.

>
Based upon this my suspicion is that this is mainly a vmexit optimisation when using KVM which isn't 
relevant here for macfb.


You're right.

Reviewed-by: Laurent Vivier 

Thanks,
Laurent



Re: [PATCH V3] block/rbd: implement bdrv_co_block_status

2022-01-08 Thread Peter Lieven
Am 06.01.22 um 17:01 schrieb Ilya Dryomov:
> On Thu, Jan 6, 2022 at 4:27 PM Peter Lieven  wrote:
>> Am 05.10.21 um 10:36 schrieb Ilya Dryomov:
>>> On Tue, Oct 5, 2021 at 10:19 AM Peter Lieven  wrote:
 Am 05.10.21 um 09:54 schrieb Ilya Dryomov:
> On Thu, Sep 16, 2021 at 2:21 PM Peter Lieven  wrote:
>> the qemu rbd driver currently lacks support for bdrv_co_block_status.
>> This results mainly in incorrect progress during block operations (e.g.
>> qemu-img convert with an rbd image as source).
>>
>> This patch utilizes the rbd_diff_iterate2 call from librbd to detect
>> allocated and unallocated (all zero areas).
>>
>> To avoid querying the ceph OSDs for the answer this is only done if
>> the image has the fast-diff feature which depends on the object-map and
>> exclusive-lock features. In this case it is guaranteed that the 
>> information
>> is present in memory in the librbd client and thus very fast.
>>
>> If fast-diff is not available all areas are reported to be allocated
>> which is the current behaviour if bdrv_co_block_status is not 
>> implemented.
>>
>> Signed-off-by: Peter Lieven 
>> ---
>> V2->V3:
>> - check rbd_flags every time (they can change during runtime) [Ilya]
>> - also check for fast-diff invalid flag [Ilya]
>> - *map and *file cant be NULL [Ilya]
>> - set ret = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID in case of an
>> unallocated area [Ilya]
>> - typo: catched -> caught [Ilya]
>> - changed wording about fast-diff, object-map and exclusive lock in
>> commit msg [Ilya]
>>
>> V1->V2:
>> - add commit comment [Stefano]
>> - use failed_post_open [Stefano]
>> - remove redundant assert [Stefano]
>> - add macro+comment for the magic -9000 value [Stefano]
>> - always set *file if its non NULL [Stefano]
>>
>>block/rbd.c | 126 
>>1 file changed, 126 insertions(+)
>>
>> diff --git a/block/rbd.c b/block/rbd.c
>> index dcf82b15b8..3cb24f9981 100644
>> --- a/block/rbd.c
>> +++ b/block/rbd.c
>> @@ -1259,6 +1259,131 @@ static ImageInfoSpecific 
>> *qemu_rbd_get_specific_info(BlockDriverState *bs,
>>return spec_info;
>>}
>>
>> +typedef struct rbd_diff_req {
>> +uint64_t offs;
>> +uint64_t bytes;
>> +int exists;
> Hi Peter,
>
> Nit: make exists a bool.  The one in the callback has to be an int
> because of the callback signature but let's not spread that.
>
>> +} rbd_diff_req;
>> +
>> +/*
>> + * rbd_diff_iterate2 allows to interrupt the exection by returning a 
>> negative
>> + * value in the callback routine. Choose a value that does not conflict 
>> with
>> + * an existing exitcode and return it if we want to prematurely stop the
>> + * execution because we detected a change in the allocation status.
>> + */
>> +#define QEMU_RBD_EXIT_DIFF_ITERATE2 -9000
>> +
>> +static int qemu_rbd_co_block_status_cb(uint64_t offs, size_t len,
>> +   int exists, void *opaque)
>> +{
>> +struct rbd_diff_req *req = opaque;
>> +
>> +assert(req->offs + req->bytes <= offs);
>> +
>> +if (req->exists && offs > req->offs + req->bytes) {
>> +/*
>> + * we started in an allocated area and jumped over an 
>> unallocated area,
>> + * req->bytes contains the length of the allocated area before 
>> the
>> + * unallocated area. stop further processing.
>> + */
>> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
>> +}
>> +if (req->exists && !exists) {
>> +/*
>> + * we started in an allocated area and reached a hole. 
>> req->bytes
>> + * contains the length of the allocated area before the hole.
>> + * stop further processing.
>> + */
>> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
> Do you have a test case for when this branch is taken?
 That would happen if you diff from a snapshot, the question is if it can 
 also happen if the image is a clone from a snapshot?


>> +}
>> +if (!req->exists && exists && offs > req->offs) {
>> +/*
>> + * we started in an unallocated area and hit the first allocated
>> + * block. req->bytes must be set to the length of the 
>> unallocated area
>> + * before the allocated area. stop further processing.
>> + */
>> +req->bytes = offs - req->offs;
>> +return QEMU_RBD_EXIT_DIFF_ITERATE2;
>> +}
>> +
>> +/*
>> + * assert that we caught all cases above and allocation state has 
>> not
>> + * changed during callbacks.
>> + */
>> +assert(ex

Re: [PULL 00/37] riscv-to-apply queue

2022-01-08 Thread Richard Henderson

On 1/7/22 9:50 PM, Alistair Francis wrote:

From: Alistair Francis 

The following changes since commit d70075373af51b6aa1d637962c962120e201fc98:

   Merge tag 'for_upstream' of git://git.kernel.org/pub/scm/virt/kvm/mst/qemu 
into staging (2022-01-07 17:24:24 -0800)

are available in the Git repository at:

   g...@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220108

for you to fetch changes up to 48eaeb56debf91817dea00a2cd9c1f6c986eb531:

   target/riscv: Implement the stval/mtval illegal instruction (2022-01-08 
15:46:10 +1000)


Second RISC-V PR for QEMU 7.0

  - Fix illegal instruction when PMP is disabled
  - SiFive PDMA 64-bit support
  - SiFive PLIC cleanups
  - Mark Hypervisor extension as non experimental
  - Enable Hypervisor extension by default
  - Support 32 cores on the virt machine
  - Corrections for the Vector extension
  - Experimental support for 128-bit CPUs
  - stval and mtval support for illegal instructions


Alistair Francis (11):
   hw/intc: sifive_plic: Add a reset function
   hw/intc: sifive_plic: Cleanup the write function
   hw/intc: sifive_plic: Cleanup the read function
   hw/intc: sifive_plic: Cleanup remaining functions
   target/riscv: Mark the Hypervisor extension as non experimental
   target/riscv: Enable the Hypervisor extension by default
   hw/riscv: Use error_fatal for SoC realisation
   hw/riscv: virt: Allow support for 32 cores
   target/riscv: Set the opcode in DisasContext
   target/riscv: Fixup setting GVA
   target/riscv: Implement the stval/mtval illegal instruction

Bin Meng (1):
   roms/opensbi: Upgrade from v0.9 to v1.0

Frank Chang (3):
   target/riscv: rvv-1.0: Call the correct RVF/RVD check function for 
widening fp insns
   target/riscv: rvv-1.0: Call the correct RVF/RVD check function for 
widening fp/int type-convert insns
   target/riscv: rvv-1.0: Call the correct RVF/RVD check function for 
narrowing fp/int type-convert insns

Frédéric Pétrot (18):
   exec/memop: Adding signedness to quad definitions
   exec/memop: Adding signed quad and octo defines
   qemu/int128: addition of div/rem 128-bit operations
   target/riscv: additional macros to check instruction support
   target/riscv: separation of bitwise logic and arithmetic helpers
   target/riscv: array for the 64 upper bits of 128-bit registers
   target/riscv: setup everything for rv64 to support rv128 execution
   target/riscv: moving some insns close to similar insns
   target/riscv: accessors to registers upper part and 128-bit load/store
   target/riscv: support for 128-bit bitwise instructions
   target/riscv: support for 128-bit U-type instructions
   target/riscv: support for 128-bit shift instructions
   target/riscv: support for 128-bit arithmetic instructions
   target/riscv: support for 128-bit M extension
   target/riscv: adding high part of some csrs
   target/riscv: helper functions to wrap calls to 128-bit csr insns
   target/riscv: modification of the trans_csrxx for 128-bit support
   target/riscv: actual functions to realize crs 128-bit insns

Jim Shu (2):
   hw/dma: sifive_pdma: support high 32-bit access of 64-bit register
   hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers

Nikita Shubin (1):
   target/riscv/pmp: fix no pmp illegal intrs

Philipp Tomsich (1):
   target/riscv: Fix position of 'experimental' comment

  include/disas/dis-asm.h|   1 +
  include/exec/memop.h   |  15 +-
  include/hw/riscv/virt.h|   2 +-
  include/qemu/int128.h  |  27 +
  include/tcg/tcg-op.h   |   4 +-
  target/arm/translate-a32.h |   4 +-
  target/riscv/cpu.h |  24 +
  target/riscv/cpu_bits.h|   3 +
  target/riscv/helper.h  |   9 +
  target/riscv/insn16.decode |  27 +-
  target/riscv/insn32.decode |  25 +
  accel/tcg/cputlb.c |  30 +-
  accel/tcg/user-exec.c  |   8 +-
  disas/riscv.c  |   5 +
  hw/dma/sifive_pdma.c   | 181 ++-
  hw/intc/sifive_plic.c  | 254 +++--
  hw/riscv/microchip_pfsoc.c |   2 +-
  hw/riscv/opentitan.c   |   2 +-
  hw/riscv/sifive_e.c|   2 +-
  hw/riscv/sifive_u.c|   2 +-
  target/alpha/translate.c   |  32 +-
  target/arm/helper-a64.c|   8 +-
  target/arm/translate-a64.c |   8 +-
  target/

Re: [PATCH v5 00/24] linux-user: Clean up siginfo_t handling

2022-01-08 Thread Laurent Vivier

Le 07/01/2022 à 22:32, Richard Henderson a écrit :

Changes from v4:
   * Rebase on master.

All patches are reviewed.


Series applied to my linux-user-for-7.0 branch.

Thanks,
Laurent



r~


Richard Henderson (24):
   linux-user/alpha: Set TRAP_UNK for bugchk and unknown gentrap
   linux-user/alpha: Set FPE_FLTUNK for gentrap ROPRAND
   linux-user/alpha: Use force_sig_fault
   linux-user/cris: Use force_sig_fault
   linux-user/hppa: Use force_sig_fault
   linux-user/hppa: Use the proper si_code for PRIV_OPR, PRIV_REG,
 OVERFLOW
   linux-user: Remove TARGET_NSIGFPE
   linux-user/hppa: Set FPE_CONDTRAP for COND
   linux-user/i386: Split out maybe_handle_vm86_trap
   linux-user/i386: Use force_sig, force_sig_fault
   linux-user/m68k: Use force_sig_fault
   linux-user/microblaze: Use force_sig_fault
   linux-user/microblaze: Fix SIGFPE si_codes
   linux-user/mips: Improve do_break
   linux-user/mips: Use force_sig_fault
   target/mips: Extract break code into env->error_code
   target/mips: Extract trap code into env->error_code
   linux-user/openrisc: Use force_sig_fault
   linux-user/ppc: Use force_sig_fault
   linux-user/riscv: Use force_sig_fault
   linux-user/s390x: Use force_sig_fault
   linux-user/sh4: Use force_sig_fault
   linux-user/sparc: Use force_sig_fault
   linux-user/xtensa: Use force_sig_fault

  linux-user/syscall_defs.h |   3 +-
  target/mips/tcg/translate.h   |   1 +
  linux-user/alpha/cpu_loop.c   |  61 +++-
  linux-user/cris/cpu_loop.c|  12 +-
  linux-user/hppa/cpu_loop.c|  26 ++--
  linux-user/i386/cpu_loop.c|  78 +-
  linux-user/m68k/cpu_loop.c|  24 +---
  linux-user/microblaze/cpu_loop.c  |  71 +
  linux-user/mips/cpu_loop.c| 166 +-
  linux-user/openrisc/cpu_loop.c|  18 +--
  linux-user/ppc/cpu_loop.c | 136 --
  linux-user/riscv/cpu_loop.c   |  31 +---
  linux-user/s390x/cpu_loop.c   |   7 +-
  linux-user/sh4/cpu_loop.c |   6 +-
  linux-user/sparc/cpu_loop.c   |  14 +-
  linux-user/xtensa/cpu_loop.c  |  26 ++--
  target/mips/tcg/translate.c   |  36 -
  target/mips/tcg/micromips_translate.c.inc |  10 +-
  target/mips/tcg/mips16e_translate.c.inc   |   2 +-
  target/mips/tcg/nanomips_translate.c.inc  |   4 +-
  20 files changed, 230 insertions(+), 502 deletions(-)






Re: [PATCH 4/4] linux-user: Implement capability prctls

2022-01-08 Thread Laurent Vivier

Le 06/01/2022 à 23:57, Richard Henderson a écrit :

This is PR_CAPBSET_READ, PR_CAPBSET_DROP and the "legacy"
PR_CAP_AMBIENT PR_GET_SECUREBITS, PR_SET_SECUREBITS.

All of these arguments are integer values only, and do not
require mapping of values between host and guest.

Signed-off-by: Richard Henderson 
---
  linux-user/syscall.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8495f5e08e..4711afaf8c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6504,10 +6504,15 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
  case PR_SET_UNALIGN:
  return do_prctl_set_unalign(env, arg2);
  
+case PR_CAP_AMBIENT:

+case PR_CAPBSET_READ:
+case PR_CAPBSET_DROP:
  case PR_GET_DUMPABLE:
  case PR_SET_DUMPABLE:
  case PR_GET_KEEPCAPS:
  case PR_SET_KEEPCAPS:
+case PR_GET_SECUREBITS:
+case PR_SET_SECUREBITS:
  case PR_GET_TIMING:
  case PR_SET_TIMING:
  case PR_GET_TIMERSLACK:


Reviewed-by: Laurent Vivier 



Re: [PATCH] macfb: fix VRAM dirty memory region logging

2022-01-08 Thread Mark Cave-Ayland

On 08/01/2022 16:53, Laurent Vivier wrote:


Le 08/01/2022 à 17:41, Mark Cave-Ayland a écrit :

The macfb VRAM memory region was configured with coalescing rather than dirty
memory logging enabled, causing some areas of the screen not to redraw after
a full screen update.

Signed-off-by: Mark Cave-Ayland 
Fixes: 8ac919a065 ("hw/m68k: add Nubus macfb video card")
---
  hw/display/macfb.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/macfb.c b/hw/display/macfb.c
index 277d3e6633..4bd7c3ad6a 100644
--- a/hw/display/macfb.c
+++ b/hw/display/macfb.c
@@ -661,9 +661,9 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState 
*s, Error **errp)

  memory_region_init_ram(&s->mem_vram, OBJECT(dev), "macfb-vram",
 MACFB_VRAM_SIZE, &error_abort);
+    memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
  s->vram = memory_region_get_ram_ptr(&s->mem_vram);
  s->vram_bit_mask = MACFB_VRAM_SIZE - 1;
-    memory_region_set_coalescing(&s->mem_vram);
  s->vbl_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, macfb_vbl_timer, s);
  macfb_update_mode(s);


I understant why you add memory_region_set_log() but I don't understand why you 
remove memory_region_set_coalescing().


Looking at the other display devices, only VGA and cirrus use 
memory_region_set_coalescing() and that's on the IO ports rather than the VRAM.


Based upon this my suspicion is that this is mainly a vmexit optimisation when using 
KVM which isn't relevant here for macfb.



ATB,

Mark.



Re: [PATCH 3/4] linux-user: Implement PR_SET_PDEATHSIG

2022-01-08 Thread Laurent Vivier

Le 06/01/2022 à 23:57, Richard Henderson a écrit :

Signed-off-by: Richard Henderson 
---
  linux-user/syscall.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9eb2fb2bb2..8495f5e08e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6450,6 +6450,9 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
  }
  return ret;
  }
+case PR_SET_PDEATHSIG:
+return get_errno(prctl(PR_SET_PDEATHSIG, target_to_host_signal(arg2),
+   arg3, arg4, arg5));
  case PR_GET_NAME:
  {
  void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);


Reviewed-by: Laurent Vivier 



Re: [PATCH 1/4] linux-user: Do not special-case NULL for PR_GET_PDEATHSIG

2022-01-08 Thread Laurent Vivier

Le 08/01/2022 à 18:10, Laurent Vivier a écrit :

Le 06/01/2022 à 23:57, Richard Henderson a écrit :

The kernel does not special-case arg2 != NULL, so
neither should we.

Signed-off-by: Richard Henderson 
---
  linux-user/syscall.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..e8f9e0643e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6444,7 +6444,7 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
  int deathsig;
  ret = get_errno(prctl(PR_GET_PDEATHSIG, &deathsig,
    arg3, arg4, arg5));
-    if (!is_error(ret) && arg2 && put_user_s32(deathsig, arg2)) {
+    if (!is_error(ret) && put_user_s32(deathsig, arg2)) {
  return -TARGET_EFAULT;
  }
  return ret;


Reviewed-by: Laurent Vivier 



Reviewed-by: Laurent Vivier 



Re: [PATCH 1/4] linux-user: Do not special-case NULL for PR_GET_PDEATHSIG

2022-01-08 Thread Laurent Vivier

Le 06/01/2022 à 23:57, Richard Henderson a écrit :

The kernel does not special-case arg2 != NULL, so
neither should we.

Signed-off-by: Richard Henderson 
---
  linux-user/syscall.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce9d64896c..e8f9e0643e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6444,7 +6444,7 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
  int deathsig;
  ret = get_errno(prctl(PR_GET_PDEATHSIG, &deathsig,
arg3, arg4, arg5));
-if (!is_error(ret) && arg2 && put_user_s32(deathsig, arg2)) {
+if (!is_error(ret) && put_user_s32(deathsig, arg2)) {
  return -TARGET_EFAULT;
  }
  return ret;


Reviewed-by: Laurent Vivier 



Re: [PATCH] macfb: fix VRAM dirty memory region logging

2022-01-08 Thread Laurent Vivier

Le 08/01/2022 à 17:41, Mark Cave-Ayland a écrit :

The macfb VRAM memory region was configured with coalescing rather than dirty
memory logging enabled, causing some areas of the screen not to redraw after
a full screen update.

Signed-off-by: Mark Cave-Ayland 
Fixes: 8ac919a065 ("hw/m68k: add Nubus macfb video card")
---
  hw/display/macfb.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/macfb.c b/hw/display/macfb.c
index 277d3e6633..4bd7c3ad6a 100644
--- a/hw/display/macfb.c
+++ b/hw/display/macfb.c
@@ -661,9 +661,9 @@ static bool macfb_common_realize(DeviceState *dev, 
MacfbState *s, Error **errp)
  
  memory_region_init_ram(&s->mem_vram, OBJECT(dev), "macfb-vram",

 MACFB_VRAM_SIZE, &error_abort);
+memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
  s->vram = memory_region_get_ram_ptr(&s->mem_vram);
  s->vram_bit_mask = MACFB_VRAM_SIZE - 1;
-memory_region_set_coalescing(&s->mem_vram);
  
  s->vbl_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, macfb_vbl_timer, s);

  macfb_update_mode(s);


I understant why you add memory_region_set_log() but I don't understand why you remove 
memory_region_set_coalescing().


Thanks,
Laurent



[PATCH] macfb: fix VRAM dirty memory region logging

2022-01-08 Thread Mark Cave-Ayland
The macfb VRAM memory region was configured with coalescing rather than dirty
memory logging enabled, causing some areas of the screen not to redraw after
a full screen update.

Signed-off-by: Mark Cave-Ayland 
Fixes: 8ac919a065 ("hw/m68k: add Nubus macfb video card")
---
 hw/display/macfb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/macfb.c b/hw/display/macfb.c
index 277d3e6633..4bd7c3ad6a 100644
--- a/hw/display/macfb.c
+++ b/hw/display/macfb.c
@@ -661,9 +661,9 @@ static bool macfb_common_realize(DeviceState *dev, 
MacfbState *s, Error **errp)
 
 memory_region_init_ram(&s->mem_vram, OBJECT(dev), "macfb-vram",
MACFB_VRAM_SIZE, &error_abort);
+memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
 s->vram = memory_region_get_ram_ptr(&s->mem_vram);
 s->vram_bit_mask = MACFB_VRAM_SIZE - 1;
-memory_region_set_coalescing(&s->mem_vram);
 
 s->vbl_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, macfb_vbl_timer, s);
 macfb_update_mode(s);
-- 
2.20.1




[PATCH v4 4/5] ui/sdl2: pass horizontal scroll information to the device code

2022-01-08 Thread Dmitry Petrov
Signed-off-by: Dmitry Petrov 
---
 ui/sdl2.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 0bd30504cf..46a252d7d9 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -33,6 +33,7 @@
 #include "sysemu/runstate-action.h"
 #include "sysemu/sysemu.h"
 #include "ui/win32-kbd-hook.h"
+#include "qemu/log.h"
 
 static int sdl2_num_outputs;
 static struct sdl2_console *sdl2_console;
@@ -535,6 +536,10 @@ static void handle_mousewheel(SDL_Event *ev)
 btn = INPUT_BUTTON_WHEEL_UP;
 } else if (wev->y < 0) {
 btn = INPUT_BUTTON_WHEEL_DOWN;
+} else if (wev->x < 0) {
+btn = INPUT_BUTTON_WHEEL_RIGHT;
+} else if (wev->x > 0) {
+btn = INPUT_BUTTON_WHEEL_LEFT;
 } else {
 return;
 }
-- 
2.32.0




Re: [PATCH v2 1/5] ps2: Initial horizontal scroll support

2022-01-08 Thread Dmitry Petrov
Hi Daniel,

Thanks for the link! I've sent a v4 patch with a cover letter that includes
it as well
as the latest comments by Marc-André to v2 of the patch.

Kind regards, Dmitry

On Tue, 4 Jan 2022 at 13:30, Daniel P. Berrangé  wrote:

> On Wed, Dec 22, 2021 at 02:06:43AM +0100, Dmitry Petrov wrote:
> > v2:
> >   - Patch is split into a sequence
> >   - value is clamped to 31 for horizontal scroll
> >
> > This patch introduces horizontal scroll support for the ps/2
> > mouse.
> >
> > The patch is based on the previous work
> > by Brad Jorsch done in 2010
> > but never merge, see
> > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579968
>
> The bugs attached to that ticket don't have any Signed-off-by
> from Brad. Fortunately at the time he did re-submit them on
> qemu-devel with Signed-off-by present.
>
> Can you include this link to his patches in your commit
> message to get the paper trail
>
>   https://lists.gnu.org/archive/html/qemu-devel/2010-05/msg00223.html
>
> > This change adds support for horizontal scroll to ps/2 mouse device
> > code. The code is implemented to match the logic of linux kernel
> > which is used as a reference.
> >
> > Signed-off-by: Dmitry Petrov 
> > ---
> >  hw/input/ps2.c | 57 +++---
> >  qapi/ui.json   |  2 +-
> >  2 files changed, 50 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/input/ps2.c b/hw/input/ps2.c
> > index 9376a8f4ce..6236711e1b 100644
> > --- a/hw/input/ps2.c
> > +++ b/hw/input/ps2.c
> > @@ -123,6 +123,7 @@ typedef struct {
> >  int mouse_dx; /* current values, needed for 'poll' mode */
> >  int mouse_dy;
> >  int mouse_dz;
> > +int mouse_dw;
> >  uint8_t mouse_buttons;
> >  } PS2MouseState;
> >
> > @@ -715,7 +716,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
> >  /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
> >  const int needed = s->mouse_type ? 4 : 3;
> >  unsigned int b;
> > -int dx1, dy1, dz1;
> > +int dx1, dy1, dz1, dw1;
> >
> >  if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
> >  return 0;
> > @@ -724,6 +725,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
> >  dx1 = s->mouse_dx;
> >  dy1 = s->mouse_dy;
> >  dz1 = s->mouse_dz;
> > +dw1 = s->mouse_dw;
> >  /* XXX: increase range to 8 bits ? */
> >  if (dx1 > 127)
> >  dx1 = 127;
> > @@ -740,6 +742,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
> >  /* extra byte for IMPS/2 or IMEX */
> >  switch(s->mouse_type) {
> >  default:
> > +/* Just ignore the wheels if not supported */
> > +s->mouse_dz = 0;
> > +s->mouse_dw = 0;
> >  break;
> >  case 3:
> >  if (dz1 > 127)
> > @@ -747,13 +752,41 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
> >  else if (dz1 < -127)
> >  dz1 = -127;
> >  ps2_queue_noirq(&s->common, dz1 & 0xff);
> > +s->mouse_dz -= dz1;
> > +s->mouse_dw = 0;
> >  break;
> >  case 4:
> > -if (dz1 > 7)
> > -dz1 = 7;
> > -else if (dz1 < -7)
> > -dz1 = -7;
> > -b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
> > +/*
> > + * This matches what the Linux kernel expects for exps/2 in
> > + * drivers/input/mouse/psmouse-base.c. Note, if you happen to
> > + * press/release the 4th or 5th buttons at the same moment as a
> > + * horizontal wheel scroll, those button presses will get lost.
> I'm not
> > + * sure what to do about that, since by this point we don't know
> > + * whether those buttons actually changed state.
> > + */
> > +if (dw1 != 0) {
> > +if (dw1 > 31) {
> > +dw1 = 31;
> > +} else if (dw1 < -31) {
> > +dw1 = -31;
> > +}
> > +
> > +/*
> > + * linux kernel expects first 6 bits to represent the value
> > + * for horizontal scroll
> > + */
> > +b = (dw1 & 0x3f) | 0x40;
> > +s->mouse_dw -= dw1;
> > +} else {
> > +if (dz1 > 7) {
> > +dz1 = 7;
> > +} else if (dz1 < -7) {
> > +dz1 = -7;
> > +}
> > +
> > +b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
> > +s->mouse_dz -= dz1;
> > +}
> >  ps2_queue_noirq(&s->common, b);
> >  break;
> >  }
> > @@ -764,7 +797,6 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
> >  /* update deltas */
> >  s->mouse_dx -= dx1;
> >  s->mouse_dy -= dy1;
> > -s->mouse_dz -= dz1;
> >
> >  return 1;
> >  }
> > @@ -806,6 +838,12 @@ static void ps2_mouse_event(DeviceState *dev,
> QemuConsole *src,
> >  } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
> >  s->mouse_dz++;
> >  }
> > +
> > +if (btn->button == INPUT

[PATCH v4 5/5] ui/input-legacy: pass horizontal scroll information

2022-01-08 Thread Dmitry Petrov
This code seems to be used by vmport hack, passing these values allows
to implement horizontal scroll support even when using vmport.
In case it's not supported horizontal scroll will act as a vertical one.

Signed-off-by: Dmitry Petrov 
---
 ui/input-legacy.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index 9fc78a639b..46ea74e44d 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "qapi/qapi-commands-ui.h"
 #include "ui/console.h"
 #include "keymaps.h"
@@ -179,6 +180,20 @@ static void legacy_mouse_event(DeviceState *dev, 
QemuConsole *src,
 1,
 s->buttons);
 }
+if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
+s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
+s->axis[INPUT_AXIS_X],
+s->axis[INPUT_AXIS_Y],
+-2,
+s->buttons);
+}
+if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) {
+s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
+s->axis[INPUT_AXIS_X],
+s->axis[INPUT_AXIS_Y],
+2,
+s->buttons);
+}
 break;
 case INPUT_EVENT_KIND_ABS:
 move = evt->u.abs.data;
-- 
2.32.0




[PATCH v4 2/5] ui/cocoa: pass horizontal scroll information to the device code

2022-01-08 Thread Dmitry Petrov
Signed-off-by: Dmitry Petrov 
---
 ui/cocoa.m | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 69745c483b..ac18e14ce0 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -970,21 +970,27 @@ QemuCocoaView *cocoaView;
  */
 
 /*
- * When deltaY is zero, it means that this scrolling event was
- * either horizontal, or so fine that it only appears in
- * scrollingDeltaY. So we drop the event.
+ * We shouldn't have got a scroll event when deltaY and delta Y
+ * are zero, hence no harm in dropping the event
  */
-if ([event deltaY] != 0) {
+if ([event deltaY] != 0 || [event deltaX] != 0) {
 /* Determine if this is a scroll up or scroll down event */
-buttons = ([event deltaY] > 0) ?
+if ([event deltaY] != 0) {
+  buttons = ([event deltaY] > 0) ?
 INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
+} else if ([event deltaX] != 0) {
+  buttons = ([event deltaX] > 0) ?
+INPUT_BUTTON_WHEEL_LEFT : INPUT_BUTTON_WHEEL_RIGHT;
+}
+
 qemu_input_queue_btn(dcl.con, buttons, true);
 qemu_input_event_sync();
 qemu_input_queue_btn(dcl.con, buttons, false);
 qemu_input_event_sync();
 }
+
 /*
- * Since deltaY also reports scroll wheel events we prevent mouse
+ * Since deltaX/deltaY also report scroll wheel events we prevent 
mouse
  * movement code from executing.
  */
 mouse_event = false;
-- 
2.32.0




[PATCH v4 0/5] Add horizontal mouse scroll support

2022-01-08 Thread Dmitry Petrov
This patchset adds implements passing horizontal scroll
events from the host system to guest systems via ps/2
mouse device.

This is useful during testing horizontal scroll behaviour
in guest operating systems as well as using it in case it
provides any benefits for a particular application.

The patch is based on the previous work by Brad Jorsch done
in 2010 but never merged, see
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579968

Original submission: 
https://lists.gnu.org/archive/html/qemu-devel/2010-05/msg00223.html

Changes from V1 to V2:
  - Patch is split into a sequence
  - Value is clamped to 31 for horizontal scroll in the device code

Changes from V2 to V3:
  - Cover letter
  - Removed unnecessary log line

Changes from V3 to V4:
  - Added a link to the original submission by Brad

Dmitry Petrov (5):
  ps2: Initial horizontal scroll support
  ui/cocoa: pass horizontal scroll information to the device code
  ui/gtk: pass horizontal scroll information to the device code
  ui/sdl2: pass horizontal scroll information to the device code
  ui/input-legacy: pass horizontal scroll information

 hw/input/ps2.c| 57 ---
 qapi/ui.json  |  2 +-
 ui/cocoa.m| 18 ++-
 ui/gtk.c  | 54 ++--
 ui/input-legacy.c | 15 +
 ui/sdl2.c |  5 +
 6 files changed, 124 insertions(+), 27 deletions(-)

-- 
2.32.0




[PATCH v4 3/5] ui/gtk: pass horizontal scroll information to the device code

2022-01-08 Thread Dmitry Petrov
Signed-off-by: Dmitry Petrov 
---
 ui/gtk.c | 54 ++
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 6a1f65d518..a8567b9ddc 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -968,33 +968,63 @@ static gboolean gd_scroll_event(GtkWidget *widget, 
GdkEventScroll *scroll,
 void *opaque)
 {
 VirtualConsole *vc = opaque;
-InputButton btn;
+InputButton btn_vertical;
+InputButton btn_horizontal;
+bool has_vertical = false;
+bool has_horizontal = false;
 
 if (scroll->direction == GDK_SCROLL_UP) {
-btn = INPUT_BUTTON_WHEEL_UP;
+btn_vertical = INPUT_BUTTON_WHEEL_UP;
+has_vertical = true;
 } else if (scroll->direction == GDK_SCROLL_DOWN) {
-btn = INPUT_BUTTON_WHEEL_DOWN;
+btn_vertical = INPUT_BUTTON_WHEEL_DOWN;
+has_vertical = true;
+} else if (scroll->direction == GDK_SCROLL_LEFT) {
+btn_horizontal = INPUT_BUTTON_WHEEL_LEFT;
+has_horizontal = true;
+} else if (scroll->direction == GDK_SCROLL_RIGHT) {
+btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT;
+has_horizontal = true;
 } else if (scroll->direction == GDK_SCROLL_SMOOTH) {
 gdouble delta_x, delta_y;
 if (!gdk_event_get_scroll_deltas((GdkEvent *)scroll,
  &delta_x, &delta_y)) {
 return TRUE;
 }
-if (delta_y == 0) {
-return TRUE;
-} else if (delta_y > 0) {
-btn = INPUT_BUTTON_WHEEL_DOWN;
+
+if (delta_y > 0) {
+btn_vertical = INPUT_BUTTON_WHEEL_DOWN;
+has_vertical = true;
+} else if (delta_y < 0) {
+btn_vertical = INPUT_BUTTON_WHEEL_UP;
+has_vertical = true;
+} else if (delta_x > 0) {
+btn_horizontal = INPUT_BUTTON_WHEEL_RIGHT;
+has_horizontal = true;
+} else if (delta_x < 0) {
+btn_horizontal = INPUT_BUTTON_WHEEL_LEFT;
+has_horizontal = true;
 } else {
-btn = INPUT_BUTTON_WHEEL_UP;
+return TRUE;
 }
 } else {
 return TRUE;
 }
 
-qemu_input_queue_btn(vc->gfx.dcl.con, btn, true);
-qemu_input_event_sync();
-qemu_input_queue_btn(vc->gfx.dcl.con, btn, false);
-qemu_input_event_sync();
+if (has_vertical) {
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, true);
+qemu_input_event_sync();
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_vertical, false);
+qemu_input_event_sync();
+}
+
+if (has_horizontal) {
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, true);
+qemu_input_event_sync();
+qemu_input_queue_btn(vc->gfx.dcl.con, btn_horizontal, false);
+qemu_input_event_sync();
+}
+
 return TRUE;
 }
 
-- 
2.32.0




[PATCH v4 1/5] ps2: Initial horizontal scroll support

2022-01-08 Thread Dmitry Petrov
This change adds support for horizontal scroll to ps/2 mouse device
code. The code is implemented to match the logic of linux kernel
which is used as a reference.

Signed-off-by: Dmitry Petrov 
---
 hw/input/ps2.c | 57 +++---
 qapi/ui.json   |  2 +-
 2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 9376a8f4ce..6236711e1b 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -123,6 +123,7 @@ typedef struct {
 int mouse_dx; /* current values, needed for 'poll' mode */
 int mouse_dy;
 int mouse_dz;
+int mouse_dw;
 uint8_t mouse_buttons;
 } PS2MouseState;
 
@@ -715,7 +716,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
 const int needed = s->mouse_type ? 4 : 3;
 unsigned int b;
-int dx1, dy1, dz1;
+int dx1, dy1, dz1, dw1;
 
 if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
 return 0;
@@ -724,6 +725,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 dx1 = s->mouse_dx;
 dy1 = s->mouse_dy;
 dz1 = s->mouse_dz;
+dw1 = s->mouse_dw;
 /* XXX: increase range to 8 bits ? */
 if (dx1 > 127)
 dx1 = 127;
@@ -740,6 +742,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 /* extra byte for IMPS/2 or IMEX */
 switch(s->mouse_type) {
 default:
+/* Just ignore the wheels if not supported */
+s->mouse_dz = 0;
+s->mouse_dw = 0;
 break;
 case 3:
 if (dz1 > 127)
@@ -747,13 +752,41 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 else if (dz1 < -127)
 dz1 = -127;
 ps2_queue_noirq(&s->common, dz1 & 0xff);
+s->mouse_dz -= dz1;
+s->mouse_dw = 0;
 break;
 case 4:
-if (dz1 > 7)
-dz1 = 7;
-else if (dz1 < -7)
-dz1 = -7;
-b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
+/*
+ * This matches what the Linux kernel expects for exps/2 in
+ * drivers/input/mouse/psmouse-base.c. Note, if you happen to
+ * press/release the 4th or 5th buttons at the same moment as a
+ * horizontal wheel scroll, those button presses will get lost. I'm not
+ * sure what to do about that, since by this point we don't know
+ * whether those buttons actually changed state.
+ */
+if (dw1 != 0) {
+if (dw1 > 31) {
+dw1 = 31;
+} else if (dw1 < -31) {
+dw1 = -31;
+}
+
+/*
+ * linux kernel expects first 6 bits to represent the value
+ * for horizontal scroll
+ */
+b = (dw1 & 0x3f) | 0x40;
+s->mouse_dw -= dw1;
+} else {
+if (dz1 > 7) {
+dz1 = 7;
+} else if (dz1 < -7) {
+dz1 = -7;
+}
+
+b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
+s->mouse_dz -= dz1;
+}
 ps2_queue_noirq(&s->common, b);
 break;
 }
@@ -764,7 +797,6 @@ static int ps2_mouse_send_packet(PS2MouseState *s)
 /* update deltas */
 s->mouse_dx -= dx1;
 s->mouse_dy -= dy1;
-s->mouse_dz -= dz1;
 
 return 1;
 }
@@ -806,6 +838,12 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole 
*src,
 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 s->mouse_dz++;
 }
+
+if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
+s->mouse_dw--;
+} else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) {
+s->mouse_dw++;
+}
 } else {
 s->mouse_buttons &= ~bmap[btn->button];
 }
@@ -833,8 +871,10 @@ static void ps2_mouse_sync(DeviceState *dev)
 /* if not remote, send event. Multiple events are sent if
too big deltas */
 while (ps2_mouse_send_packet(s)) {
-if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
+if (s->mouse_dx == 0 && s->mouse_dy == 0
+&& s->mouse_dz == 0 && s->mouse_dw == 0) {
 break;
+}
 }
 }
 }
@@ -1036,6 +1076,7 @@ static void ps2_mouse_reset(void *opaque)
 s->mouse_dx = 0;
 s->mouse_dy = 0;
 s->mouse_dz = 0;
+s->mouse_dw = 0;
 s->mouse_buttons = 0;
 }
 
diff --git a/qapi/ui.json b/qapi/ui.json
index 2b4371da37..9354f4c467 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -905,7 +905,7 @@
 ##
 { 'enum'  : 'InputButton',
   'data'  : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side',
-  'extra' ] }
+  'extra', 'wheel-left', 'wheel-right' ] }
 
 ##
 # @InputAxis:
-- 
2.32.0




[PATCH v2] target/arm/cpu64: Use 32-bit GDBstub when running in 32-bit KVM mode

2022-01-08 Thread Ard Biesheuvel
When running under KVM, we may decide to run the CPU in 32-bit mode, by
setting the 'aarch64=off' CPU option. In this case, we need to switch to
the 32-bit version of the GDB stub too, so that GDB has the correct view
of the CPU state. Without this, GDB debugging does not work at all, and
errors out upon connecting to the target with a mysterious 'g' packet
length error.

Cc: Richard Henderson 
Cc: Peter Maydell 
Cc: Alex Bennee 
Signed-off-by: Ard Biesheuvel 
---
v2: refactor existing CPUClass::gdb_... member assignments for the
32-bit code so we can reuse it for the 64-bit code

 target/arm/cpu.c   | 16 +++-
 target/arm/cpu.h   |  2 ++
 target/arm/cpu64.c |  3 +++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a211804fd3df..ae8e78fc1472 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2049,6 +2049,15 @@ static const struct TCGCPUOps arm_tcg_ops = {
 };
 #endif /* CONFIG_TCG */
 
+void arm_cpu_class_gdb_init(CPUClass *cc)
+{
+cc->gdb_read_register = arm_cpu_gdb_read_register;
+cc->gdb_write_register = arm_cpu_gdb_write_register;
+cc->gdb_num_core_regs = 26;
+cc->gdb_core_xml_file = "arm-core.xml";
+cc->gdb_arch_name = arm_gdb_arch_name;
+}
+
 static void arm_cpu_class_init(ObjectClass *oc, void *data)
 {
 ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@@ -2061,18 +2070,15 @@ static void arm_cpu_class_init(ObjectClass *oc, void 
*data)
 device_class_set_props(dc, arm_cpu_properties);
 device_class_set_parent_reset(dc, arm_cpu_reset, &acc->parent_reset);
 
+arm_cpu_class_gdb_init(cc);
+
 cc->class_by_name = arm_cpu_class_by_name;
 cc->has_work = arm_cpu_has_work;
 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;
 #ifndef CONFIG_USER_ONLY
 cc->sysemu_ops = &arm_sysemu_ops;
 #endif
-cc->gdb_num_core_regs = 26;
-cc->gdb_core_xml_file = "arm-core.xml";
-cc->gdb_arch_name = arm_gdb_arch_name;
 cc->gdb_get_dynamic_xml = arm_gdb_get_dynamic_xml;
 cc->gdb_stop_before_watchpoint = true;
 cc->disas_set_info = arm_disas_set_info;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e33f37b70ada..208da8e35697 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1064,6 +1064,8 @@ int arm_gen_dynamic_svereg_xml(CPUState *cpu, int 
base_reg);
  */
 const char *arm_gdb_get_dynamic_xml(CPUState *cpu, const char *xmlname);
 
+void arm_cpu_class_gdb_init(CPUClass *cc);
+
 int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
  int cpuid, void *opaque);
 int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 15245a60a8c7..df7667864e11 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -906,6 +906,7 @@ static bool aarch64_cpu_get_aarch64(Object *obj, Error 
**errp)
 static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
 {
 ARMCPU *cpu = ARM_CPU(obj);
+CPUClass *cc = CPU_GET_CLASS(obj);
 
 /* At this time, this property is only allowed if KVM is enabled.  This
  * restriction allows us to avoid fixing up functionality that assumes a
@@ -919,6 +920,8 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool 
value, Error **errp)
 return;
 }
 unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
+
+arm_cpu_class_gdb_init(cc)
 } else {
 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
 }
-- 
2.30.2




Re: [PATCH v3] hw/arm/virt: KVM: Enable PAuth when supported by the host

2022-01-08 Thread Marc Zyngier

On 2022-01-07 20:23, Richard Henderson wrote:

On 1/7/22 7:01 AM, Marc Zyngier wrote:
@@ -1380,17 +1380,10 @@ void arm_cpu_finalize_features(ARMCPU *cpu, 
Error **errp)

  return;
  }
  -/*
- * KVM does not support modifications to this feature.
- * We have not registered the cpu properties when KVM
- * is in use, so the user will not be able to set them.
- */
-if (!kvm_enabled()) {
-arm_cpu_pauth_finalize(cpu, &local_err);
-if (local_err != NULL) {
+arm_cpu_pauth_finalize(cpu, &local_err);
+if (local_err != NULL) {
  error_propagate(errp, local_err);
  return;
-}
  }


Indentation is still off -- error + return should be out-dented one 
level.




Duh. Clearly, my brain can't spot these. Apologies for the extra noise.


Otherwise,
Reviewed-by: Richard Henderson 


Thanks. I'll repost a version shortly, unless someone shouts.

M.
--
Jazz is not dead. It just smells funny...



Re: [PATCH v6 18/23] hw/intc: Add RISC-V AIA APLIC device emulation

2022-01-08 Thread Anup Patel
On Fri, Jan 7, 2022 at 2:23 PM Frank Chang  wrote:
>
> Anup Patel  於 2021年12月30日 週四 下午8:55寫道:
>>
>> From: Anup Patel 
>>
>> The RISC-V AIA (Advanced Interrupt Architecture) defines a new
>> interrupt controller for wired interrupts called APLIC (Advanced
>> Platform Level Interrupt Controller). The APLIC is capabable of
>> forwarding wired interupts to RISC-V HARTs directly or as MSIs
>> (Message Signaled Interupts).
>>
>> This patch adds device emulation for RISC-V AIA APLIC.
>>
>> Signed-off-by: Anup Patel 
>> Signed-off-by: Anup Patel 
>> ---
>>  hw/intc/Kconfig   |   3 +
>>  hw/intc/meson.build   |   1 +
>>  hw/intc/riscv_aplic.c | 970 ++
>>  include/hw/intc/riscv_aplic.h |  79 +++
>>  4 files changed, 1053 insertions(+)
>>  create mode 100644 hw/intc/riscv_aplic.c
>>  create mode 100644 include/hw/intc/riscv_aplic.h
>>
>> diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
>> index 010ded7eae..528e77b4a6 100644
>> --- a/hw/intc/Kconfig
>> +++ b/hw/intc/Kconfig
>> @@ -70,6 +70,9 @@ config LOONGSON_LIOINTC
>>  config RISCV_ACLINT
>>  bool
>>
>> +config RISCV_APLIC
>> +bool
>> +
>>  config SIFIVE_PLIC
>>  bool
>>
>> diff --git a/hw/intc/meson.build b/hw/intc/meson.build
>> index 70080bc161..7466024402 100644
>> --- a/hw/intc/meson.build
>> +++ b/hw/intc/meson.build
>> @@ -50,6 +50,7 @@ specific_ss.add(when: 'CONFIG_S390_FLIC', if_true: 
>> files('s390_flic.c'))
>>  specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true: 
>> files('s390_flic_kvm.c'))
>>  specific_ss.add(when: 'CONFIG_SH_INTC', if_true: files('sh_intc.c'))
>>  specific_ss.add(when: 'CONFIG_RISCV_ACLINT', if_true: 
>> files('riscv_aclint.c'))
>> +specific_ss.add(when: 'CONFIG_RISCV_APLIC', if_true: files('riscv_aplic.c'))
>>  specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true: files('sifive_plic.c'))
>>  specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c'))
>>  specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'],
>> diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
>> new file mode 100644
>> index 00..f4b8828dac
>> --- /dev/null
>> +++ b/hw/intc/riscv_aplic.c
>> @@ -0,0 +1,970 @@
>> +/*
>> + * RISC-V APLIC (Advanced Platform Level Interrupt Controller)
>> + *
>> + * Copyright (c) 2021 Western Digital Corporation or its affiliates.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2 or later, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope 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 "qemu/osdep.h"
>> +#include "qapi/error.h"
>> +#include "qemu/log.h"
>> +#include "qemu/module.h"
>> +#include "qemu/error-report.h"
>> +#include "qemu/bswap.h"
>> +#include "exec/address-spaces.h"
>> +#include "hw/sysbus.h"
>> +#include "hw/pci/msi.h"
>> +#include "hw/boards.h"
>> +#include "hw/qdev-properties.h"
>> +#include "hw/intc/riscv_aplic.h"
>> +#include "hw/irq.h"
>> +#include "target/riscv/cpu.h"
>> +#include "sysemu/sysemu.h"
>> +#include "migration/vmstate.h"
>> +
>> +#define APLIC_MAX_IDC  (1UL << 14)
>> +#define APLIC_MAX_SOURCE   1024
>> +#define APLIC_MIN_IPRIO_BITS   1
>> +#define APLIC_MAX_IPRIO_BITS   8
>> +#define APLIC_MAX_CHILDREN 1024
>> +
>> +#define APLIC_DOMAINCFG0x
>> +#define APLIC_DOMAINCFG_IE (1 << 8)
>> +#define APLIC_DOMAINCFG_DM (1 << 2)
>> +#define APLIC_DOMAINCFG_BE (1 << 0)
>> +
>> +#define APLIC_SOURCECFG_BASE   0x0004
>> +#define APLIC_SOURCECFG_D  (1 << 10)
>> +#define APLIC_SOURCECFG_CHILDIDX_MASK  0x03ff
>> +#define APLIC_SOURCECFG_SM_MASK0x0007
>> +#define APLIC_SOURCECFG_SM_INACTIVE0x0
>> +#define APLIC_SOURCECFG_SM_DETACH  0x1
>> +#define APLIC_SOURCECFG_SM_EDGE_RISE   0x4
>> +#define APLIC_SOURCECFG_SM_EDGE_FALL   0x5
>> +#define APLIC_SOURCECFG_SM_LEVEL_HIGH  0x6
>> +#define APLIC_SOURCECFG_SM_LEVEL_LOW   0x7
>> +
>> +#define APLIC_MMSICFGADDR  0x1bc0
>> +#define APLIC_MMSICFGADDRH 0x1bc4
>> +#define APLIC_SMSICFGADDR  0x1bc8
>> +#define APLIC_SMSICFGADDRH 0x1bcc
>> +
>> +#define APLIC_xMSICFGADDRH_L   (1UL << 31)
>> +#define APLIC_xMSICFGADDRH_HHXS_MASK   0x1f
>> +#define APLIC_xMSICFGADDRH_HHXS_SHIFT  24
>> +#define APLIC_xMSICFGADDRH_LHXS_MASK   0x7
>> +#define APLIC_xMSICFGADDRH_LHXS_SHIFT  20
>> +#define APLIC_xMSICFGADDRH_HHXW_MASK   0x7
>> +#define APLIC_xMSICFGADDRH_HHXW_SHIFT  16
>> +#defin

Re: [PATCH v2 17/18] ppc/pnv: Introduce user creatable pnv-phb4 devices

2022-01-08 Thread Daniel Henrique Barboza




On 1/8/22 08:11, Cédric Le Goater wrote:

+    object_property_set_int(OBJECT(phb), "index",
+    phb->phb_id, &error_abort);
+
+    pnv_phb4_set_stack_phb_props(stack, phb);
+
+    /* Assign the phb to the stack */
+    stack->phb = phb;


The stack object should check the validity of the stack->phb pointer always.



What do you mean by "check the validity"?



I am thinking of the usage of 'stack->phb', for instance in the routine
pnv_phb4_update_regions(). We should add an assert there.


Oh ok. I'll add an assert in this point (and in the code above that where you
also pointed it out.

And about pnv_phb4_update_regions(), v3 will need to handle it but not with
an assert but with a phb != NULL verification to become a NO-OP if phb is NULL.
It's an easier and less intrusive fix than trying to change the order of the
XSCOM initialization in stk_realize().

I will (hopefully) explain it better in the v3.


Thanks,


Daniel



Your changes seem to cleanup the stack <-> phb relation quite a lot. Which
is good.

Thanks,

C.




Re: [PATCH v6 15/23] target/riscv: Implement AIA IMSIC interface CSRs

2022-01-08 Thread Anup Patel
On Wed, Jan 5, 2022 at 9:01 AM Frank Chang  wrote:
>
> Anup Patel  於 2021年12月30日 週四 下午8:53寫道:
>>
>> From: Anup Patel 
>>
>> The AIA specification defines IMSIC interface CSRs for easy access
>> to the per-HART IMSIC registers without using indirect xiselect and
>> xireg CSRs. This patch implements the AIA IMSIC interface CSRs.
>>
>> Signed-off-by: Anup Patel 
>> Signed-off-by: Anup Patel 
>> ---
>>  target/riscv/csr.c | 202 +
>>  1 file changed, 202 insertions(+)
>>
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index 488877e89c..89e74f848d 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -906,6 +906,16 @@ static int aia_xlate_vs_csrno(CPURISCVState *env, int 
>> csrno)
>>  return CSR_VSISELECT;
>>  case CSR_SIREG:
>>  return CSR_VSIREG;
>> +case CSR_SSETEIPNUM:
>> +return CSR_VSSETEIPNUM;
>> +case CSR_SCLREIPNUM:
>> +return CSR_VSCLREIPNUM;
>> +case CSR_SSETEIENUM:
>> +return CSR_VSSETEIENUM;
>> +case CSR_SCLREIENUM:
>> +return CSR_VSCLREIENUM;
>> +case CSR_STOPEI:
>> +return CSR_VSTOPEI;
>>  default:
>>  return csrno;
>>  };
>> @@ -1058,6 +1068,177 @@ done:
>>  return RISCV_EXCP_NONE;
>>  }
>>
>> +static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong 
>> *val,
>> +target_ulong new_val, target_ulong wr_mask)
>> +{
>> +int ret = -EINVAL;
>> +bool set, pend, virt;
>> +target_ulong priv, isel, vgein, xlen, nval, wmask;
>> +
>> +/* Translate CSR number for VS-mode */
>> +csrno = aia_xlate_vs_csrno(env, csrno);
>> +
>> +/* Decode register details from CSR number */
>> +virt = set = pend = false;
>> +switch (csrno) {
>> +case CSR_MSETEIPNUM:
>> +priv = PRV_M;
>> +set = true;
>
>
> Missing: pend = true; here?

Ahh, good catch. I will fix this in the next revision.

Thanks,
Anup

>
> Frank Chang
>
>>
>> +break;
>> +case CSR_MCLREIPNUM:
>> +priv = PRV_M;
>> +pend = true;
>> +break;
>> +case CSR_MSETEIENUM:
>> +priv = PRV_M;
>> +set = true;
>> +break;
>> +case CSR_MCLREIENUM:
>> +priv = PRV_M;
>> +break;
>> +case CSR_SSETEIPNUM:
>> +priv = PRV_S;
>> +set = true;
>> +pend = true;
>> +break;
>> +case CSR_SCLREIPNUM:
>> +priv = PRV_S;
>> +pend = true;
>> +break;
>> +case CSR_SSETEIENUM:
>> +priv = PRV_S;
>> +set = true;
>> +break;
>> +case CSR_SCLREIENUM:
>> +priv = PRV_S;
>> +break;
>> +case CSR_VSSETEIPNUM:
>> +priv = PRV_S;
>> +virt = true;
>> +set = true;
>> +pend = true;
>> +break;
>> +case CSR_VSCLREIPNUM:
>> +priv = PRV_S;
>> +virt = true;
>> +pend = true;
>> +break;
>> +case CSR_VSSETEIENUM:
>> +priv = PRV_S;
>> +virt = true;
>> +set = true;
>> +break;
>> +case CSR_VSCLREIENUM:
>> +priv = PRV_S;
>> +virt = true;
>> +break;
>> +default:
>> + goto done;
>> +};
>> +
>> +/* IMSIC CSRs only available when machine implements IMSIC. */
>> +if (!env->aia_ireg_rmw_fn[priv]) {
>> +goto done;
>> +}
>> +
>> +/* Find the selected guest interrupt file */
>> +vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
>> +
>> +/* Selected guest interrupt file should be valid */
>> +if (virt && (!vgein || env->geilen < vgein)) {
>> +goto done;
>> +}
>> +
>> +/* Set/Clear CSRs always read zero */
>> +if (val) {
>> +*val = 0;
>> +}
>> +
>> +if (wr_mask) {
>> +/* Get interrupt number */
>> +new_val &= wr_mask;
>> +
>> +/* Find target interrupt pending/enable register */
>> +xlen = riscv_cpu_mxl_bits(env);
>> +isel = (new_val / xlen);
>> +isel *= (xlen / IMSIC_EIPx_BITS);
>> +isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0;
>> +
>> +/* Find the interrupt bit to be set/clear */
>> +wmask = ((target_ulong)1) << (new_val % xlen);
>> +nval = (set) ? wmask : 0;
>> +
>> +/* Call machine specific IMSIC register emulation */
>> +ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
>> + AIA_MAKE_IREG(isel, priv, virt,
>> +   vgein, xlen),
>> + NULL, nval, wmask);
>> +} else {
>> +ret = 0;
>> +}
>> +
>> +done:
>> +if (ret) {
>> +return (riscv_cpu_virt_enabled(env) && virt) ?
>> +   RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
>> +}
>> +return RISCV_EXCP_NONE;
>> +}
>> +
>> +static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val

Re: [PATCH v6 18/23] hw/intc: Add RISC-V AIA APLIC device emulation

2022-01-08 Thread Anup Patel
On Sat, Jan 8, 2022 at 12:05 PM Frank Chang  wrote:
>
> Anup Patel  於 2021年12月30日 週四 下午8:55寫道:
>>
>> From: Anup Patel 
>>
>> The RISC-V AIA (Advanced Interrupt Architecture) defines a new
>> interrupt controller for wired interrupts called APLIC (Advanced
>> Platform Level Interrupt Controller). The APLIC is capabable of
>> forwarding wired interupts to RISC-V HARTs directly or as MSIs
>> (Message Signaled Interupts).
>>
>> This patch adds device emulation for RISC-V AIA APLIC.
>>
>> Signed-off-by: Anup Patel 
>> Signed-off-by: Anup Patel 
>> ---
>>  hw/intc/Kconfig   |   3 +
>>  hw/intc/meson.build   |   1 +
>>  hw/intc/riscv_aplic.c | 970 ++
>>  include/hw/intc/riscv_aplic.h |  79 +++
>>  4 files changed, 1053 insertions(+)
>>  create mode 100644 hw/intc/riscv_aplic.c
>>  create mode 100644 include/hw/intc/riscv_aplic.h
>>
>> diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
>> index 010ded7eae..528e77b4a6 100644
>> --- a/hw/intc/Kconfig
>> +++ b/hw/intc/Kconfig
>> @@ -70,6 +70,9 @@ config LOONGSON_LIOINTC
>>  config RISCV_ACLINT
>>  bool
>>
>> +config RISCV_APLIC
>> +bool
>> +
>>  config SIFIVE_PLIC
>>  bool
>>
>> diff --git a/hw/intc/meson.build b/hw/intc/meson.build
>> index 70080bc161..7466024402 100644
>> --- a/hw/intc/meson.build
>> +++ b/hw/intc/meson.build
>> @@ -50,6 +50,7 @@ specific_ss.add(when: 'CONFIG_S390_FLIC', if_true: 
>> files('s390_flic.c'))
>>  specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true: 
>> files('s390_flic_kvm.c'))
>>  specific_ss.add(when: 'CONFIG_SH_INTC', if_true: files('sh_intc.c'))
>>  specific_ss.add(when: 'CONFIG_RISCV_ACLINT', if_true: 
>> files('riscv_aclint.c'))
>> +specific_ss.add(when: 'CONFIG_RISCV_APLIC', if_true: files('riscv_aplic.c'))
>>  specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true: files('sifive_plic.c'))
>>  specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c'))
>>  specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'],
>> diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
>> new file mode 100644
>> index 00..f4b8828dac
>> --- /dev/null
>> +++ b/hw/intc/riscv_aplic.c
>> @@ -0,0 +1,970 @@
>> +/*
>> + * RISC-V APLIC (Advanced Platform Level Interrupt Controller)
>> + *
>> + * Copyright (c) 2021 Western Digital Corporation or its affiliates.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2 or later, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope 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 "qemu/osdep.h"
>> +#include "qapi/error.h"
>> +#include "qemu/log.h"
>> +#include "qemu/module.h"
>> +#include "qemu/error-report.h"
>> +#include "qemu/bswap.h"
>> +#include "exec/address-spaces.h"
>> +#include "hw/sysbus.h"
>> +#include "hw/pci/msi.h"
>> +#include "hw/boards.h"
>> +#include "hw/qdev-properties.h"
>> +#include "hw/intc/riscv_aplic.h"
>> +#include "hw/irq.h"
>> +#include "target/riscv/cpu.h"
>> +#include "sysemu/sysemu.h"
>> +#include "migration/vmstate.h"
>> +
>> +#define APLIC_MAX_IDC  (1UL << 14)
>> +#define APLIC_MAX_SOURCE   1024
>> +#define APLIC_MIN_IPRIO_BITS   1
>> +#define APLIC_MAX_IPRIO_BITS   8
>> +#define APLIC_MAX_CHILDREN 1024
>> +
>> +#define APLIC_DOMAINCFG0x
>> +#define APLIC_DOMAINCFG_IE (1 << 8)
>> +#define APLIC_DOMAINCFG_DM (1 << 2)
>> +#define APLIC_DOMAINCFG_BE (1 << 0)
>> +
>> +#define APLIC_SOURCECFG_BASE   0x0004
>> +#define APLIC_SOURCECFG_D  (1 << 10)
>> +#define APLIC_SOURCECFG_CHILDIDX_MASK  0x03ff
>> +#define APLIC_SOURCECFG_SM_MASK0x0007
>> +#define APLIC_SOURCECFG_SM_INACTIVE0x0
>> +#define APLIC_SOURCECFG_SM_DETACH  0x1
>> +#define APLIC_SOURCECFG_SM_EDGE_RISE   0x4
>> +#define APLIC_SOURCECFG_SM_EDGE_FALL   0x5
>> +#define APLIC_SOURCECFG_SM_LEVEL_HIGH  0x6
>> +#define APLIC_SOURCECFG_SM_LEVEL_LOW   0x7
>> +
>> +#define APLIC_MMSICFGADDR  0x1bc0
>> +#define APLIC_MMSICFGADDRH 0x1bc4
>> +#define APLIC_SMSICFGADDR  0x1bc8
>> +#define APLIC_SMSICFGADDRH 0x1bcc
>> +
>> +#define APLIC_xMSICFGADDRH_L   (1UL << 31)
>> +#define APLIC_xMSICFGADDRH_HHXS_MASK   0x1f
>> +#define APLIC_xMSICFGADDRH_HHXS_SHIFT  24
>> +#define APLIC_xMSICFGADDRH_LHXS_MASK   0x7
>> +#define APLIC_xMSICFGADDRH_LHXS_SHIFT  20
>> +#define APLIC_xMSICFGADDRH_HHXW_MASK   0x7
>> +#define APLIC_xMSICFGADDRH_HHXW_SHIFT  16
>> +#defi

Re: [PATCH v2 17/18] ppc/pnv: Introduce user creatable pnv-phb4 devices

2022-01-08 Thread Cédric Le Goater

+    object_property_set_int(OBJECT(phb), "index",
+    phb->phb_id, &error_abort);
+
+    pnv_phb4_set_stack_phb_props(stack, phb);
+
+    /* Assign the phb to the stack */
+    stack->phb = phb;


The stack object should check the validity of the stack->phb pointer always.



What do you mean by "check the validity"?



I am thinking of the usage of 'stack->phb', for instance in the routine
pnv_phb4_update_regions(). We should add an assert there.

Your changes seem to cleanup the stack <-> phb relation quite a lot. Which
is good.

Thanks,

C.



[RFC PATCH v4 20/30] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC)

2022-01-08 Thread Xiaojuan Yang
This patch realize the EIOINTC interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/intc/Kconfig|   3 +
 hw/intc/loongarch_extioi.c | 376 +
 hw/intc/meson.build|   1 +
 hw/intc/trace-events   |  11 +
 hw/loongarch/Kconfig   |   1 +
 include/hw/intc/loongarch_extioi.h |  69 ++
 6 files changed, 461 insertions(+)
 create mode 100644 hw/intc/loongarch_extioi.c
 create mode 100644 include/hw/intc/loongarch_extioi.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 727a3bb3e6..ecdf821205 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -90,3 +90,6 @@ config LOONGARCH_PCH_MSI
 select MSI_NONBROKEN
 bool
 select UNIMP
+
+config LOONGARCH_EXTIOI
+bool
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
new file mode 100644
index 00..b9a91f77b3
--- /dev/null
+++ b/hw/intc/loongarch_extioi.c
@@ -0,0 +1,376 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson 3A5000 ext interrupt controller emulation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/loongarch.h"
+#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "hw/intc/loongarch_extioi.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static void extioi_update_irq(void *opaque, int irq_num, int level)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+uint8_t  ipnum, cpu;
+unsigned long found1, found2;
+
+ipnum = s->sw_ipmap[irq_num];
+cpu   = s->sw_coremap[irq_num];
+if (level == 1) {
+if (test_bit(irq_num, (void *)s->enable) == false) {
+return;
+}
+bitmap_set((void *)s->coreisr[cpu], irq_num, 1);
+found1 = find_next_bit((void *)&(s->sw_ipisr[cpu][ipnum]),
+   EXTIOI_IRQS, 0);
+bitmap_set((void *)&(s->sw_ipisr[cpu][ipnum]), irq_num, 1);
+
+if (found1 >= EXTIOI_IRQS) {
+qemu_set_irq(s->parent_irq[cpu][ipnum], level);
+}
+} else {
+bitmap_clear((void *)s->coreisr[cpu], irq_num, 1);
+found1 = find_next_bit((void *)&(s->sw_ipisr[cpu][ipnum]),
+   EXTIOI_IRQS, 0);
+bitmap_clear((void *)&(s->sw_ipisr[cpu][ipnum]), irq_num, 1);
+found2 = find_next_bit((void *)&(s->sw_ipisr[cpu][ipnum]),
+   EXTIOI_IRQS, 0);
+
+if ((found1 < EXTIOI_IRQS) && (found2 >= EXTIOI_IRQS)) {
+qemu_set_irq(s->parent_irq[cpu][ipnum], level);
+}
+}
+}
+
+static void extioi_setirq(void *opaque, int irq, int level)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+trace_extioi_setirq(irq, level);
+extioi_update_irq(s, irq, level);
+}
+
+static uint64_t extioi_readw(void *opaque, hwaddr addr, unsigned size)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+unsigned long offset = addr & 0x;
+uint32_t ret, index;
+int cpu;
+
+if ((offset >= EXTIOI_NODETYPE_START) && (offset < EXTIOI_NODETYPE_END)) {
+index = (offset - EXTIOI_NODETYPE_START) >> 2;
+ret = s->nodetype[index];
+} else if ((offset >= EXTIOI_BOUNCE_START) &&
+   (offset < EXTIOI_BOUNCE_END)) {
+index = (offset - EXTIOI_BOUNCE_START) >> 2;
+ret = s->bounce[index];
+} else if ((offset >= EXTIOI_COREISR_START) &&
+   (offset < EXTIOI_COREISR_END)) {
+index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
+cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+ret = s->coreisr[cpu][index];
+}
+
+trace_loongarch_extioi_readw((uint32_t)addr, ret);
+return ret;
+}
+
+static void extioi_writew(void *opaque, hwaddr addr,
+   uint64_t val, unsigned size)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+int cpu, index;
+uint32_t offset, old_data, i, j, bits;
+
+offset = addr & 0x;
+trace_loongarch_extioi_writew(size, (uint32_t)addr, val);
+
+if ((offset >= EXTIOI_NODETYPE_START) && (offset < EXTIOI_NODETYPE_END)) {
+index = (offset - EXTIOI_NODETYPE_START) >> 2;
+s->nodetype[index] = val;
+} else if ((offset >= EXTIOI_BOUNCE_START) &&
+   (offset < EXTIOI_BOUNCE_END)) {
+index = (offset - EXTIOI_BOUNCE_START) >> 2;
+s->bounce[index] = val;
+} else if ((offset >= EXTIOI_COREISR_START) &&
+   (offset < EXTIOI_COREISR_END)) {
+index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
+cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+
+/* Ext_core_ioisr */
+old_data = s->coreisr[cpu][index];
+s->coreisr[cpu][index] = old_data & ~val;
+
+if (old_data != s->coreisr[cpu][index]) {
+bits = size * 8;
+

Re: [RFC PATCH v3 18/27] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC)

2022-01-08 Thread yangxiaojuan
Hi,Mark:

  Sorry for the late reply. I just saw the mail after I send the v4 patch. I 
sorted the mail into different folders from
the qemu-devel, so I didn't see the mail in time. Sorry again.

Xiaojuan

On 12/23/2021 06:21 PM, Mark Cave-Ayland wrote:
> On 22/12/2021 02:38, yangxiaojuan wrote:
> 
>> Hi, Mark
>>
>> On 12/18/2021 08:33 AM, Mark Cave-Ayland wrote:
>>> On 04/12/2021 12:07, Xiaojuan Yang wrote:
>>>
 This patch realize the PCH-PIC interrupt controller.

 Signed-off-by: Xiaojuan Yang 
 Signed-off-by: Song Gao 
 ---
hw/intc/Kconfig |   4 +
hw/intc/loongarch_pch_pic.c | 357 
hw/intc/meson.build |   1 +
hw/intc/trace-events|   5 +
hw/loongarch/Kconfig|   1 +
include/hw/intc/loongarch_pch_pic.h |  61 +
6 files changed, 429 insertions(+)
create mode 100644 hw/intc/loongarch_pch_pic.c
create mode 100644 include/hw/intc/loongarch_pch_pic.h

 diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
 index 511dcac537..96da13ad1d 100644
 --- a/hw/intc/Kconfig
 +++ b/hw/intc/Kconfig
 @@ -76,3 +76,7 @@ config M68K_IRQC
  config LOONGARCH_IPI
bool
 +
 +config LOONGARCH_PCH_PIC
 +bool
 +select UNIMP
 diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
 new file mode 100644
 index 00..2ede29ceb0
 --- /dev/null
 +++ b/hw/intc/loongarch_pch_pic.c
 @@ -0,0 +1,357 @@
 +/* SPDX-License-Identifier: GPL-2.0-or-later */
 +/*
 + * QEMU Loongson 7A1000 I/O interrupt controller.
 + *
 + * Copyright (C) 2021 Loongson Technology Corporation Limited
 + */
 +
 +#include "qemu/osdep.h"
 +#include "hw/sysbus.h"
 +#include "hw/loongarch/loongarch.h"
 +#include "hw/irq.h"
 +#include "hw/intc/loongarch_pch_pic.h"
 +#include "migration/vmstate.h"
 +#include "trace.h"
 +
 +#define for_each_set_bit(bit, addr, size) \
 + for ((bit) = find_first_bit((addr), (size));\
 +  (bit) < (size);\
 +  (bit) = find_next_bit((addr), (size), (bit) + 1))
 +
 +static void pch_pic_update_irq(loongarch_pch_pic *s, uint64_t mask, int 
 level)
 +{
 +int i;
 +uint64_t val;
 +val = mask & s->intirr & (~s->int_mask);
 +
 +for_each_set_bit(i, &val, 64) {
 +if (level == 1) {
 +if ((s->intisr & (0x1ULL << i)) == 0) {
 +s->intisr |= 1ULL << i;
 +qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 1);
 +}
 +} else if (level == 0) {
 +if (s->intisr & (0x1ULL << i)) {
 +s->intisr &= ~(0x1ULL << i);
 +qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 0);
 +}
 +}
 +}
 +}
>>>
>>> The normal pattern would be to use something like:
>>>
>>> for (i = 0; i < 64; i++) {
>>>  if (level) {
>>>  s->intisr |= 1ULL << i;
>>>  } else {
>>>  s->intisr &= ~(0x1ULL << i);
>>>  }
>>>
>>>  qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], level);
>>> }
>>>
>>> Why is it necessary to check the previous value of (s->intisr & (0x1ULL << 
>>> i)) here?
>>
>> Here check the previous value to avoid Unnecessary write. It seems make 
>> things more complicated. I will modify
> 
> In general a *_update_irq() function should be fine to propagate the IRQ up 
> to the parent directly: I think this is fine in this case because you are 
> directly manipulating the parent_irq elements rather than using e.g. a 
> priority encoder within this device to raise an IRQ to the CPU. I'm presuming 
> this final prioritisation and delivery is done elsewhere?
> 
 +static void pch_pic_irq_handler(void *opaque, int irq, int level)
 +{
 +loongarch_pch_pic *s = LOONGARCH_PCH_PIC(opaque);
 +
 +assert(irq < PCH_PIC_IRQ_NUM);
 +uint64_t mask = 1ULL << irq;
 +
 +trace_pch_pic_irq_handler(s->intedge, irq, level);
 +
 +if (s->intedge & mask) {
 +/* Edge triggered */
 +if (level) {
 +if ((s->last_intirr & mask) == 0) {
 +s->intirr |= mask;
 +}
 +s->last_intirr |= mask;
 +} else {
 +s->last_intirr &= ~mask;
 +}
 +} else {
 +/* Level triggered */
 +if (level) {
 +s->intirr |= mask;
 +s->last_intirr |= mask;
 +} else {
 +s->intirr &= ~mask;
 +s->last_intirr &= ~mask;
 +}
 +
 +}
 +pch_pic_update_irq(s, mask, level);
 +}
 +
 +static uint64_t loongarch_pch_pic_reg_rea

[RFC PATCH v4 22/30] Enable common virtio pci support for LoongArch

2022-01-08 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 softmmu/qdev-monitor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 01f3834db5..49491d74a1 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -60,7 +60,8 @@ typedef struct QDevAlias
   QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \
   QEMU_ARCH_MIPS | QEMU_ARCH_PPC |  \
   QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \
-  QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA)
+  QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \
+  QEMU_ARCH_LOONGARCH)
 #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
 #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
 
-- 
2.27.0




[RFC PATCH v4 29/30] hw/loongarch: Add fdt support.

2022-01-08 Thread Xiaojuan Yang
Add tree nodes for 3A5000 device tree.
- cpu nodes;
- fw_cfg nodes;
- pcie nodes.

The lastest loongarch bios have supported fdt.
- https://github.com/loongson/edk2
- https://github.com/loongson/edk2-platforms

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/loongson3.c | 136 +++
 include/hw/loongarch/loongarch.h |   5 ++
 target/loongarch/cpu.c   |   2 +
 target/loongarch/cpu.h   |   3 +
 4 files changed, 146 insertions(+)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 17419c2bf4..9574efa604 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -31,6 +31,9 @@
 #include "hw/firmware/smbios.h"
 #include "hw/acpi/aml-build.h"
 #include "qapi/qapi-visit-common.h"
+#include "sysemu/device_tree.h"
+
+#include 
 
 #define LOONGSON3_BIOSNAME "loongarch_bios.bin"
 
@@ -378,6 +381,125 @@ static void loongarch_irq_init(LoongArchMachineState 
*lams)
 loongarch_devices_init(pch_pic);
 }
 
+static void create_fdt(LoongArchMachineState *lams)
+{
+MachineState *ms = MACHINE(lams);
+
+ms->fdt = create_device_tree(&lams->fdt_size);
+if (!ms->fdt) {
+error_report("create_device_tree() failed");
+exit(1);
+}
+
+/* Header */
+qemu_fdt_setprop_string(ms->fdt, "/", "compatible", 
"linux,dummy-loongson3");
+qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
+qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
+}
+
+static void fdt_add_cpu_nodes(const LoongArchMachineState *lams)
+{
+int num;
+const MachineState *ms = MACHINE(lams);
+int smp_cpus = ms->smp.cpus;
+
+qemu_fdt_add_subnode(ms->fdt, "/cpus");
+qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
+qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
+
+/* cpu nodes */
+for (num = smp_cpus - 1; num >= 0; num--) {
+char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
+LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num));
+
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+cpu->dtb_compatible);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
+  qemu_fdt_alloc_phandle(ms->fdt));
+g_free(nodename);
+}
+
+/*cpu map */
+qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
+
+for (num = smp_cpus - 1; num >= 0; num--) {
+char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num);
+char *map_path;
+
+if (ms->smp.threads > 1) {
+map_path = g_strdup_printf(
+"/cpus/cpu-map/socket%d/core%d/thread%d",
+num / (ms->smp.cores * ms->smp.threads),
+(num / ms->smp.threads) % ms->smp.cores,
+num % ms->smp.threads);
+} else {
+map_path = g_strdup_printf(
+"/cpus/cpu-map/socket%d/core%d",
+num / ms->smp.cores,
+num % ms->smp.cores);
+}
+qemu_fdt_add_path(ms->fdt, map_path);
+qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path);
+
+g_free(map_path);
+g_free(cpu_path);
+}
+}
+
+static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams)
+{
+char *nodename;
+hwaddr base = FW_CFG_ADDR;
+const MachineState *ms = MACHINE(lams);
+
+nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_string(ms->fdt, nodename,
+"compatible", "qemu,fw-cfg-mmio");
+qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
+ 2, base, 2, 0x8);
+qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
+g_free(nodename);
+}
+
+static void fdt_add_pcie_node(const LoongArchMachineState *lams)
+{
+char *nodename;
+hwaddr base_mmio = LS7A_PCI_MEM_BASE;
+hwaddr size_mmio = LS7A_PCI_MEM_SIZE;
+hwaddr base_pio = LS7A_PCI_IO_BASE;
+hwaddr size_pio = LS7A_PCI_IO_SIZE;
+hwaddr base_pcie = LS_PCIECFG_BASE;
+hwaddr size_pcie = LS_PCIECFG_SIZE;
+hwaddr base = base_pcie;
+
+const MachineState *ms = MACHINE(lams);
+
+nodename = g_strdup_printf("/pcie@%" PRIx64, base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_string(ms->fdt, nodename,
+"compatible", "pci-host-ecam-generic");
+qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "pci");
+qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 3);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "linux,pci-domain", 0);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "bus-range", 0,
+   

[RFC PATCH v4 18/30] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC)

2022-01-08 Thread Xiaojuan Yang
This patch realize the PCH-PIC interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/intc/Kconfig |   4 +
 hw/intc/loongarch_pch_pic.c | 428 
 hw/intc/meson.build |   1 +
 hw/intc/trace-events|   7 +
 hw/loongarch/Kconfig|   1 +
 include/hw/intc/loongarch_pch_pic.h |  74 +
 6 files changed, 515 insertions(+)
 create mode 100644 hw/intc/loongarch_pch_pic.c
 create mode 100644 include/hw/intc/loongarch_pch_pic.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 9f5aaffb6f..928db92bb4 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -81,3 +81,7 @@ config M68K_IRQC
 
 config LOONGARCH_IPI
 bool
+
+config LOONGARCH_PCH_PIC
+bool
+select UNIMP
diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
new file mode 100644
index 00..4da78b5bc8
--- /dev/null
+++ b/hw/intc/loongarch_pch_pic.c
@@ -0,0 +1,428 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson 7A1000 I/O interrupt controller.
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/loongarch.h"
+#include "hw/irq.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static void pch_pic_update_irq(LoongArchPCHPIC *s, uint32_t mask,
+   int level, int hi)
+{
+uint32_t val, irq;
+
+if (level == 1) {
+if (hi) {
+val = mask & s->intirr_hi & (~s->int_mask_hi);
+irq = find_first_bit((void *)&val, 32);
+if (irq != 32) {
+s->intisr_hi |= 1ULL << irq;
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq + 32]], 1);
+}
+} else {
+val = mask & s->intirr_lo & (~s->int_mask_lo);
+irq = find_first_bit((void *)&val, 32);
+if (irq != 32) {
+s->intisr_lo |= 1ULL << irq;
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
+}
+}
+} else {
+if (hi) {
+val = mask & s->intisr_hi;
+irq = find_first_bit((void *)&val, 32);
+if (irq != 32) {
+s->intisr_hi &= ~(0x1ULL << irq);
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq + 32]], 0);
+}
+} else {
+val = mask & s->intisr_lo;
+irq = find_first_bit((void *)&val, 32);
+if (irq != 32) {
+s->intisr_lo &= ~(0x1ULL << irq);
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
+}
+}
+}
+}
+
+static void pch_pic_irq_handler(void *opaque, int irq, int level)
+{
+LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
+int hi = 0;
+uint32_t mask;
+
+assert(irq < PCH_PIC_IRQ_NUM);
+trace_pch_pic_irq_handler(irq, level);
+
+hi = (irq >= 32) ? 1 : 0;
+if (hi) {
+irq = irq - 32;
+}
+
+mask = 1ULL << irq;
+
+if (hi) {
+if (s->intedge_hi & mask) {
+/* Edge triggered */
+if (level) {
+if ((s->last_intirr_hi & mask) == 0) {
+s->intirr_hi |= mask;
+}
+s->last_intirr_hi |= mask;
+} else {
+s->last_intirr_hi &= ~mask;
+}
+} else {
+/* Level triggered */
+if (level) {
+s->intirr_hi |= mask;
+s->last_intirr_hi |= mask;
+} else {
+s->intirr_hi &= ~mask;
+s->last_intirr_hi &= ~mask;
+}
+}
+} else {
+if (s->intedge_lo & mask) {
+/* Edge triggered */
+if (level) {
+if ((s->last_intirr_lo & mask) == 0) {
+s->intirr_lo |= mask;
+}
+s->last_intirr_lo |= mask;
+} else {
+s->last_intirr_lo &= ~mask;
+}
+} else {
+/* Level triggered */
+if (level) {
+s->intirr_lo |= mask;
+s->last_intirr_lo |= mask;
+} else {
+s->intirr_lo &= ~mask;
+s->last_intirr_lo &= ~mask;
+}
+
+}
+}
+pch_pic_update_irq(s, mask, level, hi);
+}
+
+static uint64_t loongarch_pch_pic_readw(void *opaque, hwaddr addr,
+unsigned size)
+{
+LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
+uint64_t val = 0;
+uint32_t offset = addr & 0xfff;
+
+switch (offset) {
+case PCH_PIC_INT_ID_LO:
+val = PCH_PIC_INT_ID_VAL;
+break;
+case PCH_PIC_INT_ID_HI:
+val = PCH_PIC_INT_ID_NUM;
+break;
+case PCH_PIC_INT_MASK_LO:
+val = s->int_mask_lo;
+break;
+case PCH_PIC_INT_MASK_HI:
+

[RFC PATCH v4 21/30] hw/loongarch: Add irq hierarchy for the system

2022-01-08 Thread Xiaojuan Yang
This patch add the irq hierarchy for the virt board.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/loongson3.c   | 85 ++
 include/hw/pci-host/ls7a.h | 13 ++
 2 files changed, 98 insertions(+)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 6e796c2c08..cc7ee02003 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -15,6 +15,10 @@
 #include "sysemu/runstate.h"
 #include "sysemu/reset.h"
 #include "hw/loongarch/loongarch.h"
+#include "hw/intc/loongarch_ipi.h"
+#include "hw/intc/loongarch_extioi.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "hw/intc/loongarch_pch_msi.h"
 #include "hw/pci-host/ls7a.h"
 
 static void loongarch_cpu_reset(void *opaque)
@@ -93,6 +97,84 @@ static void loongarch_cpu_set_irq(void *opaque, int irq, int 
level)
 }
 }
 
+static void loongarch_irq_init(LoongArchMachineState *lams)
+{
+MachineState *ms = MACHINE(lams);
+DeviceState *ipi, *extioi, *pch_pic, *pch_msi, *cpudev;
+SysBusDevice *d;
+int cpu, pin, i;
+unsigned long ipi_addr;
+CPULoongArchState *env;
+
+ipi = qdev_new(TYPE_LOONGARCH_IPI);
+d = SYS_BUS_DEVICE(ipi);
+sysbus_realize_and_unref(d, &error_fatal);
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+cpudev = DEVICE(qemu_get_cpu(cpu));
+env = (qemu_get_cpu(cpu))->env_ptr;
+ipi_addr = SMP_IPI_MAILBOX + cpu * 0x100;
+memory_region_add_subregion(env->system_iocsr, ipi_addr,
+sysbus_mmio_get_region(d, cpu));
+/* connect ipi irq to cpu irq */
+qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
+}
+
+extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
+d = SYS_BUS_DEVICE(extioi);
+sysbus_realize_and_unref(d, &error_fatal);
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+env = (qemu_get_cpu(cpu))->env_ptr;
+memory_region_add_subregion(env->system_iocsr, APIC_BASE,
+sysbus_mmio_get_region(d, cpu * 4));
+memory_region_add_subregion_overlap(env->system_iocsr, ENABLE_OFFSET,
+sysbus_mmio_get_region(d, cpu * 4 
+ 1), 1);
+memory_region_add_subregion_overlap(env->system_iocsr, IPMAP_OFFSET,
+sysbus_mmio_get_region(d, cpu * 4 
+ 2), 1);
+memory_region_add_subregion_overlap(env->system_iocsr, COREMAP_OFFSET,
+sysbus_mmio_get_region(d, cpu * 4 
+ 3), 1);
+}
+
+for (i = 0; i < EXTIOI_IRQS; i++) {
+sysbus_connect_irq(d, i, qdev_get_gpio_in(extioi, i));
+}
+
+/*
+ * connect ext irq to the cpu irq
+ * cpu_pin[9:2] <= intc_pin[7:0]
+ */
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+cpudev = DEVICE(qemu_get_cpu(cpu));
+for (pin = 0; pin < LS3A_INTC_IP; pin++) {
+qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
+  qdev_get_gpio_in(cpudev, pin + 2));
+}
+}
+
+pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
+d = SYS_BUS_DEVICE(pch_pic);
+sysbus_realize_and_unref(d, &error_fatal);
+memory_region_add_subregion(get_system_memory(), LS7A_IOAPIC_REG_BASE,
+sysbus_mmio_get_region(d, 0));
+memory_region_add_subregion_overlap(get_system_memory(),
+LS7A_IOAPIC_REG_BASE + 
PCH_PIC_ROUTE_ENTRY_OFFSET,
+sysbus_mmio_get_region(d, 1), 1);
+
+/* Connect 64 pch_pic irqs to extioi */
+for (int i = 0; i < PCH_PIC_IRQ_NUM; i++) {
+sysbus_connect_irq(d, i, qdev_get_gpio_in(extioi, i));
+}
+
+pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
+d = SYS_BUS_DEVICE(pch_msi);
+sysbus_realize_and_unref(d, &error_fatal);
+sysbus_mmio_map(d, 0, LS7A_PCH_MSI_ADDR_LOW);
+for (i = 0; i < PCH_MSI_IRQ_NUM; i++) {
+/* Connect 192 pch_msi irqs to extioi */
+sysbus_connect_irq(d, i,
+   qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START));
+}
+}
+
 static void loongarch_init(MachineState *machine)
 {
 const char *cpu_model = machine->cpu_type;
@@ -145,6 +227,9 @@ static void loongarch_init(MachineState *machine)
  get_system_io(), 0, LOONGARCH_ISA_IO_SIZE);
 memory_region_add_subregion(get_system_memory(), LOONGARCH_ISA_IO_BASE,
 &lams->isa_io);
+
+/* Initialize the IO interrupt subsystem */
+loongarch_irq_init(lams);
 }
 
 static void loongarch_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index 6adbfbe443..447450828e 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -24,6 +24,19 @@
 #define LS7A_PCI_IO_BASE 0x18004000UL
 #define LS7A_PCI_IO_SIZE 0xC000
 
+#define LS7A_PCH_REG_BASE  

[RFC PATCH v4 26/30] hw/loongarch: Add -kernel and -initrd options support

2022-01-08 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/loongson3.c | 81 
 include/hw/loongarch/loongarch.h |  5 ++
 2 files changed, 86 insertions(+)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 31c285a74d..546ef6f4f1 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -30,6 +30,76 @@
 
 #define LOONGSON3_BIOSNAME "loongarch_bios.bin"
 
+static struct _loaderparams {
+unsigned long ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
+{
+return addr & 0x1fffll;
+}
+
+static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg)
+{
+int64_t kernel_entry, kernel_low, kernel_high, initrd_size = 0;
+long kernel_size;
+ram_addr_t initrd_offset = 0;
+void *cmdline_buf;
+int ret = 0;
+
+kernel_size = load_elf(loaderparams.kernel_filename, NULL,
+   cpu_loongarch_virt_to_phys, NULL,
+   (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+   (uint64_t *)&kernel_high, NULL, 0,
+   EM_LOONGARCH, 1, 0);
+
+if (kernel_size < 0) {
+error_report("could not load kernel '%s': %s",
+ loaderparams.kernel_filename,
+ load_elf_strerror(kernel_size));
+exit(1);
+}
+
+fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ENTRY, kernel_entry);
+
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size(loaderparams.initrd_filename);
+
+if (initrd_size > 0) {
+initrd_offset = MAX(INITRD_BASE,
+ROUND_UP(kernel_high, INITRD_PAGE_SIZE));
+if (initrd_offset + initrd_size > 0x1000) {
+error_report("ramdisk '%s' is too big",
+ loaderparams.initrd_filename);
+exit(1);
+}
+initrd_size = load_image_targphys(loaderparams.initrd_filename,
+  initrd_offset,
+  loaderparams.ram_size - 
initrd_offset);
+}
+if (initrd_size == (target_ulong) -1) {
+error_report("could not load initial ram disk '%s'",
+ loaderparams.initrd_filename);
+exit(1);
+}
+}
+
+cmdline_buf = g_malloc0(COMMAND_LINE_SIZE);
+if (initrd_size > 0)
+ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE,
+"initrd=0x%lx,%li %s", initrd_offset,
+initrd_size, loaderparams.kernel_cmdline));
+else
+ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, "%s",
+loaderparams.kernel_cmdline));
+
+fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, ret);
+fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, (const char *)cmdline_buf);
+}
+
 static void loongarch_cpu_reset(void *opaque)
 {
 LoongArchCPU *cpu = opaque;
@@ -257,6 +327,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
 static void loongarch_init(MachineState *machine)
 {
 const char *cpu_model = machine->cpu_type;
+const char *kernel_filename = machine->kernel_filename;
+const char *kernel_cmdline = machine->kernel_cmdline;
+const char *initrd_filename = machine->initrd_filename;
 LoongArchCPU *la_cpu;
 CPULoongArchState *env;
 ram_addr_t offset = 0;
@@ -331,6 +404,14 @@ static void loongarch_init(MachineState *machine)
 exit(1);
 }
 
+if (kernel_filename) {
+loaderparams.ram_size = ram_size;
+loaderparams.kernel_filename = kernel_filename;
+loaderparams.kernel_cmdline = kernel_cmdline;
+loaderparams.initrd_filename = initrd_filename;
+fw_cfg_add_kernel_info(lams->fw_cfg);
+}
+
 memory_region_init_ram(&lams->bios, NULL, "loongarch.bios",
LA_BIOS_SIZE, &error_fatal);
 memory_region_set_readonly(&lams->bios, true);
diff --git a/include/hw/loongarch/loongarch.h b/include/hw/loongarch/loongarch.h
index 59bbea86fe..9ffcf8429f 100644
--- a/include/hw/loongarch/loongarch.h
+++ b/include/hw/loongarch/loongarch.h
@@ -39,6 +39,11 @@
 #define LA_BIOS_BASE0x1c00
 #define LA_BIOS_SIZE(4 * 1024 * 1024)
 
+/* Kernels can be configured with 64KB pages */
+#define INITRD_PAGE_SIZE(64 * KiB)
+#define INITRD_BASE 0x0400
+#define COMMAND_LINE_SIZE   4096
+
 typedef struct LoongArchMachineState {
 /*< private >*/
 MachineState parent_obj;
-- 
2.27.0




Re: [PATCH v4 05/12] tcg/mips: Unify TCG_GUEST_BASE_REG tests

2022-01-08 Thread Philippe Mathieu-Daudé
On 1/8/22 07:36, Richard Henderson wrote:
> In tcg_out_qemu_ld/st, we already check for guest_base matching int16_t.
> Mirror that when setting up TCG_GUEST_BASE_REG in the prologue.
> 
> Signed-off-by: Richard Henderson 
> ---
>  tcg/mips/tcg-target.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé 



[RFC PATCH v4 15/30] hw/loongarch: Add support loongson3-ls7a machine type.

2022-01-08 Thread Xiaojuan Yang
Emulate a 3A5000 board use the new loongarch instruction.
3A5000 belongs to the Loongson3 series processors.
The board consists of a 3A5000 cpu model and the 7A1000
bridge. The host 3A5000 board is really complicated and
contains many functions.Now for the tcg softmmu mode
only part functions are emulated.

More detailed info you can see
https://github.com/loongson/LoongArch-Documentation

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 .../devices/loongarch64-softmmu/default.mak   |   3 +
 configs/targets/loongarch64-softmmu.mak   |   3 +
 hw/Kconfig|   1 +
 hw/loongarch/Kconfig  |   3 +
 hw/loongarch/loongson3.c  | 152 ++
 hw/loongarch/meson.build  |   4 +
 hw/meson.build|   1 +
 include/exec/poison.h |   2 +
 include/hw/loongarch/loongarch.h  |  50 ++
 include/sysemu/arch_init.h|   1 +
 qapi/machine.json |   2 +-
 target/Kconfig|   1 +
 target/loongarch/Kconfig  |   2 +
 target/loongarch/cpu.c|   3 +
 target/loongarch/cpu.h|   2 +
 15 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 configs/devices/loongarch64-softmmu/default.mak
 create mode 100644 hw/loongarch/Kconfig
 create mode 100644 hw/loongarch/loongson3.c
 create mode 100644 hw/loongarch/meson.build
 create mode 100644 include/hw/loongarch/loongarch.h
 create mode 100644 target/loongarch/Kconfig

diff --git a/configs/devices/loongarch64-softmmu/default.mak 
b/configs/devices/loongarch64-softmmu/default.mak
new file mode 100644
index 00..973ce4c30a
--- /dev/null
+++ b/configs/devices/loongarch64-softmmu/default.mak
@@ -0,0 +1,3 @@
+# Default configuration for loongarch64-softmmu
+
+CONFIG_LOONGSON3_LS7A=y
diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
index f33fa1590b..7bc06c850c 100644
--- a/configs/targets/loongarch64-softmmu.mak
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -1 +1,4 @@
+TARGET_ARCH=loongarch64
+TARGET_BASE_ARCH=loongarch
+TARGET_SUPPORTS_MTTCG=y
 TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml
diff --git a/hw/Kconfig b/hw/Kconfig
index ad20cce0a9..f71b2155ed 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -49,6 +49,7 @@ source avr/Kconfig
 source cris/Kconfig
 source hppa/Kconfig
 source i386/Kconfig
+source loongarch/Kconfig
 source m68k/Kconfig
 source microblaze/Kconfig
 source mips/Kconfig
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
new file mode 100644
index 00..ae8498de6a
--- /dev/null
+++ b/hw/loongarch/Kconfig
@@ -0,0 +1,3 @@
+config LOONGSON3_LS7A
+bool
+select PCI_EXPRESS_7A
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
new file mode 100644
index 00..3e72c1666c
--- /dev/null
+++ b/hw/loongarch/loongson3.c
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU loongson 3a5000 develop board emulation
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qemu/datadir.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
+#include "sysemu/runstate.h"
+#include "sysemu/reset.h"
+#include "hw/loongarch/loongarch.h"
+#include "hw/pci-host/ls7a.h"
+
+static void loongarch_cpu_reset(void *opaque)
+{
+LoongArchCPU *cpu = opaque;
+
+cpu_reset(CPU(cpu));
+}
+
+#define LOONGARCH_SIMPLE_MMIO_OPS(ADDR, NAME, SIZE, INDEX) \
+({\
+ memory_region_init_io(env->iocsr_mem[INDEX], NULL, &loongarch_qemu_ops,\
+   (void *)ADDR, NAME, SIZE);\
+ memory_region_add_subregion(env->system_iocsr, ADDR, 
env->iocsr_mem[INDEX]);\
+})
+
+static void loongarch_qemu_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+}
+
+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
+{
+uint64_t feature = 0UL;
+addr = ((hwaddr)(long)opaque) + addr;
+
+switch (addr) {
+case FEATURE_REG:
+feature |= 1UL << IOCSRF_MSI | 1UL << IOCSRF_EXTIOI |
+   1UL << IOCSRF_CSRIPI;
+return feature ;
+case VENDOR_REG:
+return *(uint64_t *)"Loongson";
+case CPUNAME_REG:
+return *(uint64_t *)"3A5000";
+case MISC_FUNC_REG:
+return 1UL << IOCSRM_EXTIOI_EN;
+}
+return 0;
+}
+
+static const MemoryRegionOps loongarch_qemu_ops = {
+.read = loongarch_qemu_read,
+.write = loongarch_qemu_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 8,
+},
+.impl = {
+.min_access_size = 4,
+.max_access_size = 8,
+}

[RFC PATCH v4 28/30] hw/loongarch: Add LoongArch acpi support

2022-01-08 Thread Xiaojuan Yang
Add a simple acpi model for LoongArch cpu
More complex functions will be added later

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/acpi/Kconfig  |   4 +
 hw/acpi/ls7a.c   | 374 ++
 hw/acpi/meson.build  |   1 +
 hw/loongarch/Kconfig |   2 +
 hw/loongarch/acpi-build.c| 636 +++
 hw/loongarch/loongson3.c |  62 ++-
 hw/loongarch/meson.build |   1 +
 include/hw/acpi/ls7a.h   |  53 +++
 include/hw/loongarch/loongarch.h |   6 +
 include/hw/pci-host/ls7a.h   |   5 +
 10 files changed, 1142 insertions(+), 2 deletions(-)
 create mode 100644 hw/acpi/ls7a.c
 create mode 100644 hw/loongarch/acpi-build.c
 create mode 100644 include/hw/acpi/ls7a.h

diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 622b0b50b7..30f887d479 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -11,6 +11,10 @@ config ACPI_X86
 select ACPI_PIIX4
 select ACPI_PCIHP
 
+config ACPI_LOONGARCH
+bool
+select ACPI
+
 config ACPI_X86_ICH
 bool
 select ACPI_X86
diff --git a/hw/acpi/ls7a.c b/hw/acpi/ls7a.c
new file mode 100644
index 00..cc658422dd
--- /dev/null
+++ b/hw/acpi/ls7a.c
@@ -0,0 +1,374 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch ACPI implementation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/sysemu.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/ls7a.h"
+#include "hw/nvram/fw_cfg.h"
+#include "qemu/config-file.h"
+#include "qapi/opts-visitor.h"
+#include "qapi/qapi-events-run-state.h"
+#include "qapi/error.h"
+#include "hw/pci-host/ls7a.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
+#include "migration/vmstate.h"
+
+static void ls7a_pm_update_sci_fn(ACPIREGS *regs)
+{
+LS7APMState *pm = container_of(regs, LS7APMState, acpi_regs);
+acpi_update_sci(&pm->acpi_regs, pm->irq);
+}
+
+static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width)
+{
+LS7APMState *pm = opaque;
+return acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
+}
+
+static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
+unsigned width)
+{
+LS7APMState *pm = opaque;
+acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
+acpi_update_sci(&pm->acpi_regs, pm->irq);
+}
+
+static const MemoryRegionOps ls7a_gpe_ops = {
+.read = ls7a_gpe_readb,
+.write = ls7a_gpe_writeb,
+.valid.min_access_size = 1,
+.valid.max_access_size = 8,
+.impl.min_access_size = 1,
+.impl.max_access_size = 1,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+#define VMSTATE_GPE_ARRAY(_field, _state)\
+ {   \
+ .name   = (stringify(_field)),  \
+ .version_id = 0,\
+ .num= ACPI_GPE0_LEN,\
+ .info   = &vmstate_info_uint8,  \
+ .size   = sizeof(uint8_t),  \
+ .flags  = VMS_ARRAY | VMS_POINTER,  \
+ .offset = vmstate_offset_pointer(_state, _field, uint8_t),  \
+ }
+
+static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width)
+{
+return 0;
+}
+
+static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val,
+  unsigned width)
+{
+if (val & 1) {
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+return;
+}
+}
+
+static const MemoryRegionOps ls7a_reset_ops = {
+.read = ls7a_reset_readw,
+.write = ls7a_reset_writew,
+.valid.min_access_size = 4,
+.valid.max_access_size = 4,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+const VMStateDescription vmstate_ls7a_pm = {
+.name = "ls7a_pm",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APMState),
+VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APMState),
+VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APMState),
+VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APMState),
+VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APMState),
+VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APMState),
+VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APMState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static inline int64_t acpi_pm_tmr_get_clock(void)
+{
+return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
+NANOSECONDS_PER_SECOND);
+}
+
+static uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
+{
+uint32_t d = acpi_pm_tmr_get_clock();
+return d & 0xff;
+}
+
+static void acpi_pm_tmr_timer(void *opaque)
+{
+ACP

[RFC PATCH v4 12/30] target/loongarch: Add timer related instructions support.

2022-01-08 Thread Xiaojuan Yang
This includes:
-RDTIME{L/H}.W
-RDTIME.D

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/helper.h |  1 +
 target/loongarch/insn_trans/trans_extra.c.inc | 32 +++
 target/loongarch/op_helper.c  |  6 
 target/loongarch/translate.c  |  2 ++
 4 files changed, 41 insertions(+)

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index c916f2650b..035bd141ed 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -116,4 +116,5 @@ DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
 DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
 DEF_HELPER_1(ertn, void, env)
 DEF_HELPER_1(idle, void, env)
+DEF_HELPER_1(rdtime_d, i64, env)
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_extra.c.inc 
b/target/loongarch/insn_trans/trans_extra.c.inc
index 2ce95d3382..8d3425ba61 100644
--- a/target/loongarch/insn_trans/trans_extra.c.inc
+++ b/target/loongarch/insn_trans/trans_extra.c.inc
@@ -33,22 +33,54 @@ static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d 
* a)
 return true;
 }
 
+#ifndef CONFIG_USER_ONLY
+static bool gen_rdtime(DisasContext *ctx, arg_rr *a,
+   bool word, bool high)
+{
+TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE);
+
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+gen_helper_rdtime_d(dst1, cpu_env);
+if (word) {
+tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32);
+}
+tcg_gen_ld_i64(dst2, cpu_env, offsetof(CPULoongArchState, CSR_TID));
+
+return true;
+}
+#endif
+
 static bool trans_rdtimel_w(DisasContext *ctx, arg_rdtimel_w *a)
 {
+#ifdef CONFIG_USER_ONLY
 tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
 return true;
+#else
+return gen_rdtime(ctx, a, 1, 0);
+#endif
 }
 
 static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)
 {
+#ifdef CONFIG_USER_ONLY
 tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
 return true;
+#else
+return gen_rdtime(ctx, a, 1, 1);
+#endif
 }
 
 static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)
 {
+#ifdef CONFIG_USER_ONLY
 tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
 return true;
+#else
+return gen_rdtime(ctx, a, 0, 0);
+#endif
 }
 
 static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index 6f9742054a..1d8b501ab9 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -133,4 +133,10 @@ void helper_idle(CPULoongArchState *env)
  */
 do_raise_exception(env, EXCP_HLT, 0);
 }
+
+uint64_t helper_rdtime_d(CPULoongArchState *env)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(env_cpu(env));
+ return cpu_loongarch_get_constant_timer_counter(cpu);
+}
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index ddb97661fa..53a5ef3aa9 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -25,6 +25,8 @@ static TCGv cpu_lladdr, cpu_llval;
 TCGv_i32 cpu_fcsr0;
 TCGv_i64 cpu_fpr[32];
 
+#include "exec/gen-icount.h"
+
 #define DISAS_STOP   DISAS_TARGET_0
 #define DISAS_EXIT   DISAS_TARGET_1
 
-- 
2.27.0




[RFC PATCH v4 14/30] hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson3 Platform

2022-01-08 Thread Xiaojuan Yang
This is a model of the PCIe Host Bridge found on a Loongson-5000
processor. It includes a interrupt controller, some interface for
pci and nonpci devices. Mainly emulate part of it that is not
exactly the same as the host and only use part devices for
tcg mode. It support for MSI and MSIX interrupt sources.

For more detailed info about ls7a1000 you can see the doc at
https://github.com/loongson/LoongArch-Documentation/releases/latest/
download/Loongson-7A1000-usermanual-2.00-EN.pdf

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/pci-host/Kconfig|   4 +
 hw/pci-host/ls7a.c | 178 +
 hw/pci-host/meson.build|   1 +
 include/hw/pci-host/ls7a.h |  52 +++
 include/hw/pci/pci_ids.h   |   3 +
 5 files changed, 238 insertions(+)
 create mode 100644 hw/pci-host/ls7a.c
 create mode 100644 include/hw/pci-host/ls7a.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 2b5f7d58cc..b02a9d1454 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -77,3 +77,7 @@ config MV64361
 bool
 select PCI
 select I8259
+
+config PCI_EXPRESS_7A
+bool
+select PCI_EXPRESS
diff --git a/hw/pci-host/ls7a.c b/hw/pci-host/ls7a.c
new file mode 100644
index 00..eb16b669bb
--- /dev/null
+++ b/hw/pci-host/ls7a.c
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson 7A1000 North Bridge Emulation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/pci/pci.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "hw/irq.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pci_bus.h"
+#include "sysemu/reset.h"
+#include "hw/pci-host/ls7a.h"
+#include "migration/vmstate.h"
+
+static const VMStateDescription vmstate_ls7a_pcie = {
+.name = "LS7A_PCI_DEVICE",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(parent_obj, LS7APCIState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void pci_ls7a_config_write(void *opaque, hwaddr addr,
+  uint64_t val, unsigned size)
+{
+pci_data_write(opaque, addr, val, size);
+}
+
+static uint64_t pci_ls7a_config_read(void *opaque,
+ hwaddr addr, unsigned size)
+{
+uint64_t val;
+
+val = pci_data_read(opaque, addr, size);
+
+return val;
+}
+
+static const MemoryRegionOps pci_ls7a_config_ops = {
+.read = pci_ls7a_config_read,
+.write = pci_ls7a_config_write,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+.impl = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void ls7a_pciehost_realize(DeviceState *dev, Error **errp)
+{
+PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+LS7APCIEHost *s = LS7A_HOST_DEVICE(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
+
+pcie_host_mmcfg_init(pex, LS_PCIECFG_SIZE);
+sysbus_init_mmio(sbd, &pex->mmio);
+
+/* Add ls7a pci-io/pci-mmio */
+memory_region_init(&s->pci_io, OBJECT(s), "io", LS7A_PCI_IO_SIZE);
+memory_region_init(&s->pci_mmio, OBJECT(s), "ls7a_mmio", UINT64_MAX);
+sysbus_init_mmio(sbd, &s->pci_io);
+sysbus_init_mmio(sbd, &s->pci_mmio);
+
+pci->bus = pci_register_root_bus(dev, "pcie.0", NULL, NULL, s,
+ &s->pci_mmio, &s->pci_io,
+ PCI_DEVFN(1, 0), 128, TYPE_PCIE_BUS);
+
+memory_region_init_io(&s->pci_conf, OBJECT(dev),
+  &pci_ls7a_config_ops, pci->bus,
+  "ls7a_pci_conf", HT1LO_PCICFG_SIZE);
+sysbus_init_mmio(sbd, &s->pci_conf);
+
+qdev_realize(DEVICE(&s->pci_dev), BUS(pci->bus), &error_fatal);
+}
+
+static void ls7a_reset(DeviceState *qdev)
+{
+PCIDevice *d = PCI_DEVICE(qdev);
+
+/* pci status */
+d->config[0x6] = 0x01;
+/* base class code */
+d->config[0xb] = 0x06;
+/* header type */
+d->config[0xe] = 0x80;
+/* capabilities pointer */
+d->config[0x34] = 0x40;
+/* link status and control register 0 */
+d->config[0x44] = 0x20;
+}
+
+static void ls7a_pcie_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+dc->desc = "LS7A1000 PCIE Host bridge";
+dc->vmsd = &vmstate_ls7a_pcie;
+k->vendor_id = PCI_VENDOR_ID_LOONGSON;
+k->device_id = PCI_DEVICE_ID_LOONGSON_HOST;
+k->revision = 0x0;
+k->class_id = PCI_CLASS_BRIDGE_HOST;
+dc->reset = ls7a_reset;
+/*
+ * PCI-facing part of the host bridge, not usable without the
+ * host-facing part, which can't be device_add'ed, yet.
+ */
+dc->user_creatable =

[RFC PATCH v4 05/30] target/loongarch: Add constant timer support

2022-01-08 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/constant_timer.c | 63 +++
 target/loongarch/cpu.c|  9 +
 target/loongarch/cpu.h| 10 +
 target/loongarch/meson.build  |  1 +
 4 files changed, 83 insertions(+)
 create mode 100644 target/loongarch/constant_timer.c

diff --git a/target/loongarch/constant_timer.c 
b/target/loongarch/constant_timer.c
new file mode 100644
index 00..e7d0f5ffe7
--- /dev/null
+++ b/target/loongarch/constant_timer.c
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch constant timer support
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/loongarch/loongarch.h"
+#include "qemu/timer.h"
+#include "cpu.h"
+
+#define TIMER_PERIOD10 /* 10 ns period for 100 Mhz frequency */
+#define CONSTANT_TIMER_TICK_MASK0xfffcUL
+#define CONSTANT_TIMER_ENABLE   0x1UL
+
+/* LoongArch timer */
+uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu)
+{
+return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD;
+}
+
+uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu)
+{
+uint64_t now, expire;
+
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+expire = timer_expire_time_ns(&cpu->timer);
+
+return (expire - now) / TIMER_PERIOD;
+}
+
+void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
+   uint64_t value)
+{
+CPULoongArchState *env = &cpu->env;
+uint64_t now, next;
+
+env->CSR_TCFG = value;
+if (value & CONSTANT_TIMER_ENABLE) {
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
+timer_mod(&cpu->timer, next);
+}
+}
+
+void loongarch_constant_timer_cb(void *opaque)
+{
+LoongArchCPU *cpu  = opaque;
+CPULoongArchState *env = &cpu->env;
+uint64_t now, next;
+
+if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) {
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+next = now + (env->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
+timer_mod(&cpu->timer, next);
+} else {
+env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0);
+}
+
+env->CSR_ESTAT |= 1 << IRQ_TIMER;
+cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 690eeea2e6..823951 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -235,12 +235,21 @@ static void loongarch_cpu_realizefn(DeviceState *dev, 
Error **errp)
 LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(dev);
 Error *local_err = NULL;
 
+#ifndef CONFIG_USER_ONLY
+LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+#endif
+
 cpu_exec_realizefn(cs, &local_err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
 return;
 }
 
+#ifndef CONFIG_USER_ONLY
+timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
+  &loongarch_constant_timer_cb, cpu);
+#endif
+
 cpu_reset(cs);
 qemu_init_vcpu(cs);
 
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index cf7fc46f72..ef84584678 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -12,6 +12,7 @@
 #include "fpu/softfloat-types.h"
 #include "hw/registerfields.h"
 #include "cpu-csr.h"
+#include "qemu/timer.h"
 
 #define TCG_GUEST_DEFAULT_MO (0)
 
@@ -148,6 +149,9 @@ FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
 extern const char * const regnames[32];
 extern const char * const fregnames[32];
 
+#define N_IRQS  14
+#define IRQ_TIMER   11
+
 typedef struct CPULoongArchState CPULoongArchState;
 struct CPULoongArchState {
 uint64_t gpr[32];
@@ -242,6 +246,7 @@ struct LoongArchCPU {
 
 CPUNegativeOffsetState neg;
 CPULoongArchState env;
+QEMUTimer timer; /* Internal timer */
 };
 
 #define TYPE_LOONGARCH_CPU "loongarch-cpu"
@@ -306,4 +311,9 @@ enum {
 #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
 #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
 
+void loongarch_constant_timer_cb(void *opaque);
+uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
+uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
+void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
+   uint64_t value);
 #endif /* LOONGARCH_CPU_H */
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
index 103f36ee15..6168e910a0 100644
--- a/target/loongarch/meson.build
+++ b/target/loongarch/meson.build
@@ -17,6 +17,7 @@ loongarch_tcg_ss.add(zlib)
 loongarch_softmmu_ss = ss.source_set()
 loongarch_softmmu_ss.add(files(
   'machine.c',
+  'constant_timer.c',
 ))
 
 loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
-- 
2.27.0




[RFC PATCH v4 24/30] hw/loongarch: Add LoongArch ls7a rtc device support

2022-01-08 Thread Xiaojuan Yang
This patch add ls7a rtc device support.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/Kconfig   |   1 +
 hw/loongarch/loongson3.c   |   4 +
 hw/rtc/Kconfig |   3 +
 hw/rtc/ls7a_rtc.c  | 322 +
 hw/rtc/meson.build |   1 +
 include/hw/pci-host/ls7a.h |   4 +
 6 files changed, 335 insertions(+)
 create mode 100644 hw/rtc/ls7a_rtc.c

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index e607c84d21..0f759eaa37 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -12,3 +12,4 @@ config LOONGSON3_LS7A
 select LOONGARCH_PCH_PIC
 select LOONGARCH_PCH_MSI
 select LOONGARCH_EXTIOI
+select LS7A_RTC
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 85a4be0c7b..ff0ef71e7b 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -163,6 +163,10 @@ static void loongarch_devices_init(DeviceState *pch_pic)
  * Create some unimplemented devices to emulate this.
  */
 create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
+
+sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE,
+ qdev_get_gpio_in(pch_pic,
+ LS7A_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
 }
 
 static void loongarch_irq_init(LoongArchMachineState *lams)
diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index f06e133b8a..ba8f7bc202 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -25,3 +25,6 @@ config SUN4V_RTC
 
 config GOLDFISH_RTC
 bool
+
+config LS7A_RTC
+bool
diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c
new file mode 100644
index 00..292acb3500
--- /dev/null
+++ b/hw/rtc/ls7a_rtc.c
@@ -0,0 +1,322 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongarch LS7A Real Time Clock emulation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "include/hw/register.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/misc/unimp.h"
+
+#define SYS_TOYTRIM0x20
+#define SYS_TOYWRITE0  0x24
+#define SYS_TOYWRITE1  0x28
+#define SYS_TOYREAD0   0x2C
+#define SYS_TOYREAD1   0x30
+#define SYS_TOYMATCH0  0x34
+#define SYS_TOYMATCH1  0x38
+#define SYS_TOYMATCH2  0x3C
+#define SYS_RTCCTRL0x40
+#define SYS_RTCTRIM0x60
+#define SYS_RTCWRTIE0  0x64
+#define SYS_RTCREAD0   0x68
+#define SYS_RTCMATCH0  0x6C
+#define SYS_RTCMATCH1  0x70
+#define SYS_RTCMATCH2  0x74
+
+/*
+ * Shift bits and filed mask
+ */
+#define TOY_MON_MASK   0x3f
+#define TOY_DAY_MASK   0x1f
+#define TOY_HOUR_MASK  0x1f
+#define TOY_MIN_MASK   0x3f
+#define TOY_SEC_MASK   0x3f
+#define TOY_MSEC_MASK  0xf
+
+#define TOY_MON_SHIFT  26
+#define TOY_DAY_SHIFT  21
+#define TOY_HOUR_SHIFT 16
+#define TOY_MIN_SHIFT  10
+#define TOY_SEC_SHIFT  4
+#define TOY_MSEC_SHIFT 0
+
+#define TOY_MATCH_YEAR_MASK  0x3f
+#define TOY_MATCH_MON_MASK   0xf
+#define TOY_MATCH_DAY_MASK   0x1f
+#define TOY_MATCH_HOUR_MASK  0x1f
+#define TOY_MATCH_MIN_MASK   0x3f
+#define TOY_MATCH_SEC_MASK   0x3f
+
+#define TOY_MATCH_YEAR_SHIFT 26
+#define TOY_MATCH_MON_SHIFT  22
+#define TOY_MATCH_DAY_SHIFT  17
+#define TOY_MATCH_HOUR_SHIFT 12
+#define TOY_MATCH_MIN_SHIFT  6
+#define TOY_MATCH_SEC_SHIFT  0
+
+#define TOY_ENABLE_BIT (1U << 11)
+
+#define TYPE_LS7A_RTC "ls7a_rtc"
+OBJECT_DECLARE_SIMPLE_TYPE(LS7ARtcState, LS7A_RTC)
+
+typedef struct LS7ARtcState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+QEMUTimer *timer;
+/*
+ * Needed to preserve the tick_count across migration, even if the
+ * absolute value of the rtc_clock is different on the source and
+ * destination.
+ */
+int64_t offset;
+int64_t data;
+int64_t save_alarm_offset;
+int tidx;
+uint32_t toymatch[3];
+uint32_t toytrim;
+uint32_t cntrctl;
+uint32_t rtctrim;
+uint32_t rtccount;
+uint32_t rtcmatch[3];
+qemu_irq toy_irq;
+} LS7ARtcState;
+
+enum {
+TOYEN = 1UL << 11,
+RTCEN = 1UL << 13,
+};
+
+static uint64_t ls7a_rtc_read(void *opaque, hwaddr addr, unsigned size)
+{
+LS7ARtcState *s = LS7A_RTC(opaque);
+struct tm tm;
+unsigned int val;
+
+val = 0;
+
+switch (addr) {
+case SYS_TOYREAD0:
+qemu_get_timedate(&tm, s->offset);
+val = (((tm.tm_mon + 1) & TOY_MON_MASK) << TOY_MON_SHIFT)
+| (((tm.tm_mday) & TOY_DAY_MASK) << TOY_DAY_SHIFT)
+| (((tm.tm_hour) & TOY_HOUR_MASK) << TOY_HOUR_SHIFT)
+| (((tm.tm_min) & TOY_MIN_MASK) << TOY_MIN_SHIFT)
+| (((tm.tm_sec) & TOY_SEC_MASK) << TOY_SEC_SHIFT) | 0x0;
+break;
+case SYS_TOYREAD1:
+qemu_get_timedate(&tm, s->offset);
+val = tm.tm_year;
+break;
+case SYS_TOYMATCH0:
+val = s->toymatch[0];
+break;
+

[RFC PATCH v4 25/30] hw/loongarch: Add default bios startup support.

2022-01-08 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/Kconfig |  4 
 hw/loongarch/fw_cfg.c| 33 ++
 hw/loongarch/fw_cfg.h| 15 ++
 hw/loongarch/loongson3.c | 35 
 hw/loongarch/meson.build |  1 +
 include/hw/loongarch/loongarch.h |  8 
 6 files changed, 96 insertions(+)
 create mode 100644 hw/loongarch/fw_cfg.c
 create mode 100644 hw/loongarch/fw_cfg.h

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 0f759eaa37..06bfb82b1d 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -13,3 +13,7 @@ config LOONGSON3_LS7A
 select LOONGARCH_PCH_MSI
 select LOONGARCH_EXTIOI
 select LS7A_RTC
+select FW_CFG_LOONGARCH
+
+config FW_CFG_LOONGARCH
+bool
diff --git a/hw/loongarch/fw_cfg.c b/hw/loongarch/fw_cfg.c
new file mode 100644
index 00..4cefffc896
--- /dev/null
+++ b/hw/loongarch/fw_cfg.c
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU fw_cfg helpers (LoongArch specific)
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/loongarch/fw_cfg.h"
+#include "hw/loongarch/loongarch.h"
+#include "hw/nvram/fw_cfg.h"
+#include "sysemu/sysemu.h"
+
+static void fw_cfg_boot_set(void *opaque, const char *boot_device,
+Error **errp)
+{
+fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
+}
+
+FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms)
+{
+FWCfgState *fw_cfg;
+int max_cpus = ms->smp.max_cpus;
+int smp_cpus = ms->smp.cpus;
+
+fw_cfg = fw_cfg_init_mem_wide(FW_CFG_ADDR + 8, FW_CFG_ADDR, 8, 0, NULL);
+fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
+fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
+
+qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
+return fw_cfg;
+}
diff --git a/hw/loongarch/fw_cfg.h b/hw/loongarch/fw_cfg.h
new file mode 100644
index 00..7c0de4db4a
--- /dev/null
+++ b/hw/loongarch/fw_cfg.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU fw_cfg helpers (LoongArch specific)
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef HW_LOONGARCH_FW_CFG_H
+#define HW_LOONGARCH_FW_CFG_H
+
+#include "hw/boards.h"
+#include "hw/nvram/fw_cfg.h"
+
+FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms);
+#endif
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index ff0ef71e7b..31c285a74d 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -17,6 +17,8 @@
 #include "sysemu/reset.h"
 #include "hw/irq.h"
 #include "net/net.h"
+#include "hw/loader.h"
+#include "elf.h"
 #include "hw/loongarch/loongarch.h"
 #include "hw/intc/loongarch_ipi.h"
 #include "hw/intc/loongarch_extioi.h"
@@ -24,6 +26,9 @@
 #include "hw/intc/loongarch_pch_msi.h"
 #include "hw/pci-host/ls7a.h"
 #include "hw/misc/unimp.h"
+#include "hw/loongarch/fw_cfg.h"
+
+#define LOONGSON3_BIOSNAME "loongarch_bios.bin"
 
 static void loongarch_cpu_reset(void *opaque)
 {
@@ -260,6 +265,8 @@ static void loongarch_init(MachineState *machine)
 MemoryRegion *address_space_mem = get_system_memory();
 LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
 int i;
+int bios_size;
+char *filename;
 
 if (!cpu_model) {
 cpu_model = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000");
@@ -284,6 +291,11 @@ static void loongarch_init(MachineState *machine)
 LOONGARCH_SIMPLE_MMIO_OPS(MISC_FUNC_REG, "loongarch_misc_func", 0x8, 
3);
 }
 
+if (ram_size < 1 * GiB) {
+error_report("ram_size must be greater than 1G due to the bios memory 
layout");
+exit(1);
+}
+
 /* Add memory region */
 memory_region_init_alias(&lams->lowmem, NULL, "loongarch.lowram",
  machine->ram, 0, 256 * MiB);
@@ -302,6 +314,28 @@ static void loongarch_init(MachineState *machine)
 memory_region_add_subregion(get_system_memory(), LOONGARCH_ISA_IO_BASE,
 &lams->isa_io);
 
+/* load the BIOS image. */
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
+  machine->firmware ?: LOONGSON3_BIOSNAME);
+if (filename) {
+bios_size = load_image_targphys(filename, LA_BIOS_BASE, LA_BIOS_SIZE);
+lams->fw_cfg = loongarch_fw_cfg_init(ram_size, machine);
+rom_set_fw(lams->fw_cfg);
+g_free(filename);
+} else {
+bios_size = -1;
+}
+
+if ((bios_size < 0 || bios_size > LA_BIOS_SIZE) && !qtest_enabled()) {
+error_report("Could not load LOONGARCH bios '%s'", machine->firmware);
+exit(1);
+}
+
+memory_region_init_ram(&lams->bios, NULL, "loongarch.bios",
+   LA_BIOS_SIZE, &error_fatal);

[RFC PATCH v4 10/30] target/loongarch: Add other core instructions support

2022-01-08 Thread Xiaojuan Yang
This includes:
-CACOP
-LDDIR
-LDPTE
-ERTN
-DBCL
-IDLE

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/cpu.h   |  2 +
 target/loongarch/disas.c | 17 
 target/loongarch/helper.h|  4 +
 target/loongarch/insn_trans/trans_core.c.inc | 74 +
 target/loongarch/insns.decode| 11 +++
 target/loongarch/internals.h |  5 ++
 target/loongarch/op_helper.c | 43 ++
 target/loongarch/tlb_helper.c| 87 
 8 files changed, 243 insertions(+)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ddb69ffecf..2d5bae1af4 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -442,6 +442,8 @@ enum {
 EXCP_LAST = EXCP_FPE,
 };
 
+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
+
 #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
 #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
 #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 483270f331..516866c2d3 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -226,6 +226,17 @@ static void output_i_rr(DisasContext *ctx, arg_i_rr *a, 
const char *mnemonic)
 output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
 }
 
+static void output_cop_r_i(DisasContext *ctx, arg_cop_r_i *a,
+   const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->cop, a->rj, a->imm);
+}
+
+static void output_j_i(DisasContext *ctx, arg_j_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rj, a->imm);
+}
+
 #define INSN(insn, type)\
 static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
 {   \
@@ -556,6 +567,12 @@ INSN(tlbfill,  empty)
 INSN(tlbclr,   empty)
 INSN(tlbflush, empty)
 INSN(invtlb,   i_rr)
+INSN(cacop,cop_r_i)
+INSN(lddir,rr_i)
+INSN(ldpte,j_i)
+INSN(ertn, empty)
+INSN(idle, i)
+INSN(dbcl, i)
 
 #define output_fcmp(C, PREFIX, SUFFIX) 
\
 {  
\
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 97af7ac8aa..c916f2650b 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -112,4 +112,8 @@ DEF_HELPER_2(invtlb_all_g, void, env, i32)
 DEF_HELPER_2(invtlb_all_asid, void, env, tl)
 DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
 DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
+DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
+DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
+DEF_HELPER_1(ertn, void, env)
+DEF_HELPER_1(idle, void, env)
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc 
b/target/loongarch/insn_trans/trans_core.c.inc
index 5a8e9e0643..834ffc03d5 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -35,6 +35,12 @@ GEN_FALSE_TRANS(tlbfill)
 GEN_FALSE_TRANS(tlbclr)
 GEN_FALSE_TRANS(tlbflush)
 GEN_FALSE_TRANS(invtlb)
+GEN_FALSE_TRANS(cacop)
+GEN_FALSE_TRANS(ldpte)
+GEN_FALSE_TRANS(lddir)
+GEN_FALSE_TRANS(ertn)
+GEN_FALSE_TRANS(dbcl)
+GEN_FALSE_TRANS(idle)
 
 #else
 
@@ -335,4 +341,72 @@ static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
 return true;
 }
 
+static bool trans_cacop(DisasContext *ctx, arg_cacop *a)
+{
+/* Treat the cacop as a nop */
+if (check_plv(ctx)) {
+return false;
+}
+return true;
+}
+
+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a)
+{
+TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_ldpte(cpu_env, src1, tcg_constant_tl(a->imm), mem_idx);
+return true;
+}
+
+static bool trans_lddir(DisasContext *ctx, arg_lddir *a)
+{
+TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_lddir(dest, cpu_env, src, tcg_constant_tl(a->imm), mem_idx);
+return true;
+}
+
+static bool trans_ertn(DisasContext *ctx, arg_ertn *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_ertn(cpu_env);
+ctx->base.is_jmp = DISAS_EXIT;
+return true;
+}
+
+static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a)
+{
+/*
+ * XXX: not clear which exception should be raised
+ *  when in debug mode...
+ */
+if (check_plv(ctx)) {
+return false;
+}
+generate_exception(ctx, EXCCODE_DBP);
+return true;
+}
+
+static bool trans_idle(DisasContext *ctx, arg_idle *a)
+{
+if (check_plv(ctx))

[RFC PATCH v4 06/30] target/loongarch: Add MMU support for LoongArch CPU.

2022-01-08 Thread Xiaojuan Yang
This patch introduces basic TLB interfaces.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/cpu-param.h  |   2 +-
 target/loongarch/cpu.c|  32 
 target/loongarch/cpu.h|  45 -
 target/loongarch/internals.h  |  10 ++
 target/loongarch/machine.c|  17 ++
 target/loongarch/meson.build  |   1 +
 target/loongarch/op_helper.c  |   8 +
 target/loongarch/tlb_helper.c | 326 ++
 8 files changed, 439 insertions(+), 2 deletions(-)
 create mode 100644 target/loongarch/tlb_helper.c

diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
index 9a769b67e0..414d8fff46 100644
--- a/target/loongarch/cpu-param.h
+++ b/target/loongarch/cpu-param.h
@@ -13,6 +13,6 @@
 #define TARGET_VIRT_ADDR_SPACE_BITS 48
 
 #define TARGET_PAGE_BITS 14
-#define NB_MMU_MODES 4
+#define NB_MMU_MODES 5
 
 #endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 823951..780eb96a3c 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -237,6 +237,7 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error 
**errp)
 
 #ifndef CONFIG_USER_ONLY
 LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+CPULoongArchState *env = &cpu->env;
 #endif
 
 cpu_exec_realizefn(cs, &local_err);
@@ -248,6 +249,7 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error 
**errp)
 #ifndef CONFIG_USER_ONLY
 timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
   &loongarch_constant_timer_cb, cpu);
+loongarch_mmu_init(env);
 #endif
 
 cpu_reset(cs);
@@ -295,6 +297,23 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 }
 }
 
+#ifndef CONFIG_USER_ONLY
+qemu_fprintf(f, "EUEN=%016" PRIx64 "\n", env->CSR_EUEN);
+qemu_fprintf(f, "ESTAT=%016" PRIx64 "\n", env->CSR_ESTAT);
+qemu_fprintf(f, "ERA=%016" PRIx64 "\n", env->CSR_ERA);
+qemu_fprintf(f, "CRMD=%016" PRIx64 "\n", env->CSR_CRMD);
+qemu_fprintf(f, "PRMD=%016" PRIx64 "\n", env->CSR_PRMD);
+qemu_fprintf(f, "BadVAddr=%016" PRIx64 "\n", env->CSR_BADV);
+qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY);
+qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA);
+qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV);
+qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY);
+qemu_fprintf(f, "BadInstr=%016" PRIx64 "\n", env->CSR_BADI);
+qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 ","
+ " PRCFG3=%016" PRIx64 "\n",
+ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3);
+#endif
+
 /* fpr */
 if (flags & CPU_DUMP_FPU) {
 for (i = 0; i < 32; i++) {
@@ -312,9 +331,21 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 static struct TCGCPUOps loongarch_tcg_ops = {
 .initialize = loongarch_translate_init,
 .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
+
+#if !defined(CONFIG_USER_ONLY)
+.tlb_fill = loongarch_cpu_tlb_fill,
+#endif /* !CONFIG_USER_ONLY */
 };
 #endif /* CONFIG_TCG */
 
+#ifndef CONFIG_USER_ONLY
+#include "hw/core/sysemu-cpu-ops.h"
+
+static const struct SysemuCPUOps loongarch_sysemu_ops = {
+.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
+};
+#endif
+
 static void loongarch_cpu_class_init(ObjectClass *c, void *data)
 {
 LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c);
@@ -331,6 +362,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 cc->set_pc = loongarch_cpu_set_pc;
 #ifndef CONFIG_USER_ONLY
 dc->vmsd = &vmstate_loongarch_cpu;
+cc->sysemu_ops = &loongarch_sysemu_ops;
 #endif
 cc->disas_set_info = loongarch_cpu_disas_set_info;
 #ifdef CONFIG_TCG
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ef84584678..232d51e788 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -152,6 +152,29 @@ extern const char * const fregnames[32];
 #define N_IRQS  14
 #define IRQ_TIMER   11
 
+#define LOONGARCH_TLB_MAX  (2048 + 64) /* 2048 STLB + 64 MTLB */
+#define LOONGARCH_STLB 2048 /* 2048 STLB */
+#define LOONGARCH_MTLB 64   /* 64 MTLB */
+
+/*
+ * define the ASID PS E VPPN field of TLB
+ *
+ * PS of stlb come from stlbps.ps
+ * PS of mtlb come from tlbidx.ps
+ */
+FIELD(TLB_MISC, E, 0, 1)
+FIELD(TLB_MISC, ASID, 1, 10)
+FIELD(TLB_MISC, VPPN, 13, 35)
+FIELD(TLB_MISC, PS, 48, 6)
+
+struct LoongArchTLB {
+uint64_t tlb_misc;
+/* Fields corresponding to CSR_TLBELO0/1 */
+uint64_t tlb_entry0;
+uint64_t tlb_entry1;
+};
+typedef struct LoongArchTLB LoongArchTLB;
+
 typedef struct CPULoongArchState CPULoongArchState;
 struct CPULoongArchState {
 uint64_t gpr[32];
@@ -231,6 +254,10 @@ struct CPULoongArchState {
 uint64_t CSR_DBG;
 uint64_t CSR_DERA;
 uint64_t CSR_DSAVE;
+
+#ifndef CONFIG_USER_ONLY
+LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
+#endif
 };
 
 /**
@@ -270,11 +297,27 @@ struct LoongArchCPUClass {
 DeviceReset pare

[RFC PATCH v4 23/30] hw/loongarch: Add some devices support for 3A5000.

2022-01-08 Thread Xiaojuan Yang
1.Add uart,virtio-net,vga and usb for 3A5000.
2.Add irq set and map for the pci host. Non pci device
use irq 0-16, pci device use 16-64.
3.Add some unimplented device to emulate guest unused
memory space.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/Kconfig   |  7 
 hw/loongarch/loongson3.c   | 70 ++
 hw/pci-host/ls7a.c | 42 ++-
 include/hw/pci-host/ls7a.h |  5 +++
 4 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 468e3acc74..e607c84d21 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -1,5 +1,12 @@
 config LOONGSON3_LS7A
 bool
+imply VGA_PCI
+imply VIRTIO_VGA
+imply PCI_DEVICES
+select ISA_BUS
+select SERIAL
+select SERIAL_ISA
+select VIRTIO_PCI
 select PCI_EXPRESS_7A
 select LOONGARCH_IPI
 select LOONGARCH_PCH_PIC
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index cc7ee02003..85a4be0c7b 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -10,16 +10,20 @@
 #include "qemu/datadir.h"
 #include "qapi/error.h"
 #include "hw/boards.h"
+#include "hw/char/serial.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/qtest.h"
 #include "sysemu/runstate.h"
 #include "sysemu/reset.h"
+#include "hw/irq.h"
+#include "net/net.h"
 #include "hw/loongarch/loongarch.h"
 #include "hw/intc/loongarch_ipi.h"
 #include "hw/intc/loongarch_extioi.h"
 #include "hw/intc/loongarch_pch_pic.h"
 #include "hw/intc/loongarch_pch_msi.h"
 #include "hw/pci-host/ls7a.h"
+#include "hw/misc/unimp.h"
 
 static void loongarch_cpu_reset(void *opaque)
 {
@@ -97,6 +101,70 @@ static void loongarch_cpu_set_irq(void *opaque, int irq, 
int level)
 }
 }
 
+static void loongarch_devices_init(DeviceState *pch_pic)
+{
+DeviceState *pciehost;
+SysBusDevice *d;
+PCIBus *pci_bus;
+MemoryRegion *pio_alias;
+int i;
+
+pciehost = qdev_new(TYPE_LS7A_HOST_DEVICE);
+d = SYS_BUS_DEVICE(pciehost);
+sysbus_realize_and_unref(d, &error_fatal);
+pci_bus = PCI_HOST_BRIDGE(pciehost)->bus;
+
+/* Map pcie ecam space */
+memory_region_add_subregion(get_system_memory(), LS_PCIECFG_BASE,
+sysbus_mmio_get_region(d, 0));
+
+/* Map PCI IO port space. */
+pio_alias = g_new0(MemoryRegion, 1);
+memory_region_init_alias(pio_alias, OBJECT(pciehost), "ls7a-pci-io",
+ sysbus_mmio_get_region(d, 1),
+ LS7A_PCI_IO_OFFSET, LS7A_PCI_IO_SIZE);
+memory_region_add_subregion(get_system_memory(), LS7A_PCI_IO_BASE,
+pio_alias);
+
+/* Map PCI mem space */
+memory_region_add_subregion(get_system_memory(), 0,
+sysbus_mmio_get_region(d, 2));
+
+/* Map PCI conf space */
+memory_region_add_subregion(get_system_memory(), HT1LO_PCICFG_BASE,
+sysbus_mmio_get_region(d, 3));
+
+/* Connect 48 pci irqs to pch_pic */
+for (i = 0; i < LS7A_PCI_IRQS; i++) {
+qdev_connect_gpio_out(pciehost, i,
+  qdev_get_gpio_in(pch_pic, i + LS7A_DEVICE_IRQS));
+}
+
+serial_mm_init(get_system_memory(), LS7A_UART_BASE, 0,
+   qdev_get_gpio_in(pch_pic, LS7A_UART_IRQ - 
PCH_PIC_IRQ_OFFSET),
+   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+/* Network init */
+for (i = 0; i < nb_nics; i++) {
+NICInfo *nd = &nd_table[i];
+
+if (!nd->model) {
+nd->model = g_strdup("virtio");
+}
+
+pci_nic_init_nofail(nd, pci_bus, nd->model, NULL);
+}
+
+/* VGA setup */
+pci_vga_init(pci_bus);
+
+/*
+ * There are some invalid guest memory access.
+ * Create some unimplemented devices to emulate this.
+ */
+create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
+}
+
 static void loongarch_irq_init(LoongArchMachineState *lams)
 {
 MachineState *ms = MACHINE(lams);
@@ -173,6 +241,8 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
 sysbus_connect_irq(d, i,
qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START));
 }
+
+loongarch_devices_init(pch_pic);
 }
 
 static void loongarch_init(MachineState *machine)
diff --git a/hw/pci-host/ls7a.c b/hw/pci-host/ls7a.c
index eb16b669bb..c1e08e2356 100644
--- a/hw/pci-host/ls7a.c
+++ b/hw/pci-host/ls7a.c
@@ -28,6 +28,41 @@ static const VMStateDescription vmstate_ls7a_pcie = {
 }
 };
 
+static PCIINTxRoute ls7a_route_intx_pin_to_irq(void *opaque, int pin)
+{
+PCIINTxRoute route;
+
+route.irq = pin;
+route.mode = PCI_INTX_ENABLED;
+return route;
+}
+
+static int pci_ls7a_map_irq(PCIDevice *d, int irq_num)
+{
+PCIBus *bus;
+int offset, irq;
+
+bus = pci_get_bus(d);
+if (bus->parent_dev) {
+irq = pci_swizzle_map_irq_fn(d, irq_num);
+r

[RFC PATCH v4 19/30] hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI)

2022-01-08 Thread Xiaojuan Yang
This patch realize PCH-MSI interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/intc/Kconfig |  5 ++
 hw/intc/loongarch_pch_msi.c | 75 +
 hw/intc/meson.build |  1 +
 hw/intc/trace-events|  3 ++
 hw/loongarch/Kconfig|  1 +
 include/hw/intc/loongarch_pch_msi.h | 21 
 6 files changed, 106 insertions(+)
 create mode 100644 hw/intc/loongarch_pch_msi.c
 create mode 100644 include/hw/intc/loongarch_pch_msi.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 928db92bb4..727a3bb3e6 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -85,3 +85,8 @@ config LOONGARCH_IPI
 config LOONGARCH_PCH_PIC
 bool
 select UNIMP
+
+config LOONGARCH_PCH_MSI
+select MSI_NONBROKEN
+bool
+select UNIMP
diff --git a/hw/intc/loongarch_pch_msi.c b/hw/intc/loongarch_pch_msi.c
new file mode 100644
index 00..57a894f3e5
--- /dev/null
+++ b/hw/intc/loongarch_pch_msi.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson 7A1000 msi interrupt controller.
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "hw/intc/loongarch_pch_msi.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "hw/pci/msi.h"
+#include "hw/misc/unimp.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static uint64_t loongarch_msi_mem_read(void *opaque, hwaddr addr, unsigned 
size)
+{
+return 0;
+}
+
+static void loongarch_msi_mem_write(void *opaque, hwaddr addr,
+uint64_t val, unsigned size)
+{
+LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
+int irq_num = val & 0xff;
+
+trace_loongarch_msi_set_irq(irq_num);
+qemu_set_irq(s->pch_msi_irq[irq_num - PCH_PIC_IRQ_NUM], 1);
+}
+
+static const MemoryRegionOps loongarch_pch_msi_ops = {
+.read  = loongarch_msi_mem_read,
+.write = loongarch_msi_mem_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void pch_msi_irq_handler(void *opaque, int irq, int level)
+{
+LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
+
+qemu_set_irq(s->pch_msi_irq[irq], level);
+}
+
+static void loongarch_pch_msi_init(Object *obj)
+{
+LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+int i;
+
+memory_region_init_io(&s->msi_mmio, obj, &loongarch_pch_msi_ops,
+  s, TYPE_LOONGARCH_PCH_MSI, 0x8);
+sysbus_init_mmio(sbd, &s->msi_mmio);
+msi_nonbroken = true;
+
+for (i = 0; i < PCH_MSI_IRQ_NUM; i++) {
+sysbus_init_irq(sbd, &s->pch_msi_irq[i]);
+}
+qdev_init_gpio_in(DEVICE(obj), pch_msi_irq_handler, PCH_MSI_IRQ_NUM);
+}
+
+static const TypeInfo loongarch_pch_msi_info = {
+.name  = TYPE_LOONGARCH_PCH_MSI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(LoongArchPCHMSI),
+.instance_init = loongarch_pch_msi_init,
+};
+
+static void loongarch_pch_msi_register_types(void)
+{
+type_register_static(&loongarch_pch_msi_info);
+}
+
+type_init(loongarch_pch_msi_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index cf08816547..c679223420 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -62,3 +62,4 @@ specific_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: 
files('goldfish_pic.c'))
 specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
 specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: 
files('loongarch_ipi.c'))
 specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: 
files('loongarch_pch_pic.c'))
+specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: 
files('loongarch_pch_msi.c'))
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index ec42cfd3d5..6d2d041766 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -257,3 +257,6 @@ loongarch_pch_pic_readw(unsigned size, uint32_t addr, 
unsigned long val) "size:
 loongarch_pch_pic_writew(unsigned size, uint32_t addr, unsigned long val) 
"size: %u addr: 0x%"PRIx32 "val: 0x%" PRIx64
 loongarch_pch_pic_readb(unsigned size, uint32_t addr, unsigned long val) 
"size: %u addr: 0x%"PRIx32 "val: 0x%" PRIx64
 loongarch_pch_pic_writeb(unsigned size, uint32_t addr, unsigned long val) 
"size: %u addr: 0x%"PRIx32 "val: 0x%" PRIx64
+
+# loongarch_pch_msi.c
+loongarch_msi_set_irq(int irq_num) "set msi irq %d"
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index c2b8046b94..cd38d03a19 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -3,3 +3,4 @@ config LOONGSON3_LS7A
 select PCI_EXPRESS_7A
 select LOONGARCH_IPI
 select LOONGARCH_PCH_PIC
+select LOONGARCH_PCH_MSI
diff --git a/include/hw/intc/loongarch_pch_msi.h 
b/include/hw/intc/loongarch_pch_msi.h
new file mode 100644
index 00..68009d4b4a
--- /dev/null
+++ b/include/hw/intc/loongarch_pch_msi.h
@@ -0,0 +1,21 @@
+/* SPDX-Lic

[RFC PATCH v4 16/30] hw/loongarch: Add LoongArch cpu interrupt support(CPUINTC)

2022-01-08 Thread Xiaojuan Yang
Loongson-3A5000 support 14 interrupts from 64 - 77(Timer->75 IPI->76)
Loongson-3A5000 and ls7a form a legacy model and extended model irq
hierarchy.Tcg mode emulate a simplified extended model which
has no Legacy I/O Interrupt Controller(LIOINTC) and LPC.
e.g:

 |+-++-+ +---+ |
 || IPI |--> | CPUINTC | <-- | Timer | |
 |+-++-+ +---+ |
 |^|
 |||
 |   +-+
 |   | EIOINTC |
 |   +-+
 |^   ^|
 ||   ||
 | +-+ +-+ |
 | | PCH-PIC | | PCH-MSI | |
 | +-+ +-+ |
 |   ^ ^   ^   |
 |   | |   |   |
 |   +-+ +-+ +-+   |
 |   | UARTs | | Devices | | Devices | |
 |   +-+ +-+ +-+   |
 |^|

The following series patch will realize the interrupt
controller in this model.

More detailed info can be found at the kernel doc or manual
1.https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/
linux-loongson.git/tree/Documentation/loongarch?h=loongarch-next
2.https://github.com/loongson/LoongArch-Documentation

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/loongson3.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 3e72c1666c..6e796c2c08 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -70,6 +70,29 @@ static const MemoryRegionOps loongarch_qemu_ops = {
 },
 };
 
+static void loongarch_cpu_set_irq(void *opaque, int irq, int level)
+{
+LoongArchCPU *cpu = opaque;
+CPULoongArchState *env = &cpu->env;
+CPUState *cs = CPU(cpu);
+
+if (irq < 0 || irq > N_IRQS) {
+return;
+}
+
+if (level) {
+env->CSR_ESTAT |= 1 << irq;
+} else {
+env->CSR_ESTAT &= ~(1 << irq);
+}
+
+if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
+cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+} else {
+cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+}
+}
+
 static void loongarch_init(MachineState *machine)
 {
 const char *cpu_model = machine->cpu_type;
@@ -94,6 +117,7 @@ static void loongarch_init(MachineState *machine)
 /* Init CPUs */
 for (i = 0; i < machine->smp.cpus; i++) {
 la_cpu = LOONGARCH_CPU(cpu_create(machine->cpu_type));
+qdev_init_gpio_in(DEVICE(la_cpu), loongarch_cpu_set_irq, N_IRQS);
 
 qemu_register_reset(loongarch_cpu_reset, la_cpu);
 
-- 
2.27.0




[RFC PATCH v4 11/30] target/loongarch: Add LoongArch interrupt and exception handle

2022-01-08 Thread Xiaojuan Yang
1.This patch Add loongarch interrupt and exception handle.
2.Rename the user excp to the exccode from the csr defintions.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 linux-user/loongarch64/cpu_loop.c |   8 +-
 target/loongarch/cpu.c| 252 +-
 target/loongarch/cpu.h|  11 -
 target/loongarch/fpu_helper.c |   2 +-
 target/loongarch/insn_trans/trans_extra.c.inc |   4 +-
 target/loongarch/translate.c  |   2 +-
 6 files changed, 254 insertions(+), 25 deletions(-)

diff --git a/linux-user/loongarch64/cpu_loop.c 
b/linux-user/loongarch64/cpu_loop.c
index 6628d215ca..dd58eb048f 100644
--- a/linux-user/loongarch64/cpu_loop.c
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -28,7 +28,7 @@ void cpu_loop(CPULoongArchState *env)
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
 break;
-case EXCP_SYSCALL:
+case EXCCODE_SYS:
 env->pc += 4;
 ret = do_syscall(env, env->gpr[11],
  env->gpr[4], env->gpr[5],
@@ -48,10 +48,10 @@ void cpu_loop(CPULoongArchState *env)
 }
 env->gpr[4] = ret;
 break;
-case EXCP_INE:
+case EXCCODE_INE:
 force_sig_fault(TARGET_SIGILL, 0, env->pc);
 break;
-case EXCP_FPE:
+case EXCCODE_FPE:
 si_code = TARGET_FPE_FLTUNK;
 if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
 si_code = TARGET_FPE_FLTINV;
@@ -67,7 +67,7 @@ void cpu_loop(CPULoongArchState *env)
 force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
 break;
 case EXCP_DEBUG:
-case EXCP_BREAK:
+case EXCCODE_BRK:
 force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
 break;
 case EXCP_ATOMIC:
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 571092ce53..caab59b83a 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -30,11 +30,23 @@ const char * const fregnames[32] = {
 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
 };
 
-static const char * const excp_names[EXCP_LAST + 1] = {
-[EXCP_SYSCALL] = "Syscall",
-[EXCP_BREAK] = "Break",
-[EXCP_INE] = "Instruction Non-existent",
-[EXCP_FPE] = "Floating Point Exception",
+static const char * const excp_names[] = {
+[EXCCODE_INT] = "Interrupt",
+[EXCCODE_PIL] = "TLB load page invalid",
+[EXCCODE_PIS] = "TLB store page invalid",
+[EXCCODE_PIF] = "TLB Fetch page invalid",
+[EXCCODE_PME] = "TLB Page modify",
+[EXCCODE_PNR] = "TLB read-inhibit",
+[EXCCODE_PNX] = "TLB execute-inhibit",
+[EXCCODE_PPI] = "TLB priviledged error",
+[EXCCODE_ADEF] = "Fetch instruction error",
+[EXCCODE_ADEM] = "Memory access error",
+[EXCCODE_SYS] = "Syscall",
+[EXCCODE_BRK] = "Break",
+[EXCCODE_INE] = "Instruction Non-existent",
+[EXCCODE_IPE] = "Instruction priveiledged error",
+[EXCCODE_FPE] = "Floating Point Exception",
+[EXCCODE_DBP] = "Debug breakpoint",
 };
 
 const char *loongarch_exception_name(int32_t exception)
@@ -66,6 +78,215 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
 env->pc = value;
 }
 
+#if !defined(CONFIG_USER_ONLY)
+static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env)
+{
+bool ret = 0;
+
+ret = (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE) &&
+  !(FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)));
+
+return ret;
+}
+
+/* Check if there is pending and not masked out interrupt */
+static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
+{
+uint32_t pending;
+uint32_t status;
+bool r;
+
+pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS);
+status  = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE);
+
+r = (pending & status) != 0;
+return r;
+}
+
+static inline unsigned int get_vint_size(CPULoongArchState *env)
+{
+uint64_t vs = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS);
+uint64_t size = 0;
+
+if (vs == 0) {
+return 0;
+}
+
+if (vs < 8) {
+size = 1 << (vs + 2);
+}
+
+if (vs > 8) {
+qemu_log("%s: unexpected value", __func__);
+assert(0);
+}
+
+return size;
+}
+
+static void loongarch_cpu_do_interrupt(CPUState *cs)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+bool update_badinstr = 1;
+int cause = -1;
+const char *name;
+bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR);
+
+if (cs->exception_index != EXCCODE_INT) {
+if (cs->exception_index < 0 ||
+cs->exception_index > ARRAY_SIZE(excp_names)) {
+name = "unknown";
+} else {
+name = excp_names[cs->exception_index];
+}
+
+qemu_log_mask(CPU_LOG_INT,
+ "%s enter: pc " TAR

[RFC PATCH v4 13/30] target/loongarch: Add gdb support.

2022-01-08 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 configs/targets/loongarch64-softmmu.mak |  1 +
 gdb-xml/loongarch-base64.xml| 43 +++
 gdb-xml/loongarch-fpu64.xml | 57 +++
 target/loongarch/cpu.c  |  7 ++
 target/loongarch/gdbstub.c  | 97 +
 target/loongarch/internals.h| 10 +++
 target/loongarch/meson.build|  1 +
 7 files changed, 216 insertions(+)
 create mode 100644 configs/targets/loongarch64-softmmu.mak
 create mode 100644 gdb-xml/loongarch-base64.xml
 create mode 100644 gdb-xml/loongarch-fpu64.xml
 create mode 100644 target/loongarch/gdbstub.c

diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
new file mode 100644
index 00..f33fa1590b
--- /dev/null
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -0,0 +1 @@
+TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml
diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml
new file mode 100644
index 00..f2af2a4b6e
--- /dev/null
+++ b/gdb-xml/loongarch-base64.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml
new file mode 100644
index 00..e52cf89fbc
--- /dev/null
+++ b/gdb-xml/loongarch-fpu64.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+  
+
+
+  
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index caab59b83a..8d0be47d4b 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -146,11 +146,18 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
  " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__,
  env->pc, env->CSR_ERA, env->CSR_TLBRERA, name);
 }
+if (cs->exception_index == EXCCODE_INT &&
+   (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))) {
+env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1);
+goto set_DERA;
+}
 
 switch (cs->exception_index) {
 case EXCCODE_DBP:
 env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1);
 env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC);
+goto set_DERA;
+set_DERA:
 env->CSR_DERA = env->pc;
 env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
 env->pc = env->CSR_EENTRY + 0x480;
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
new file mode 100644
index 00..2fec9364de
--- /dev/null
+++ b/target/loongarch/gdbstub.c
@@ -0,0 +1,97 @@
+/*
+ * LOONGARCH gdb server stub
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/gdbstub.h"
+#include "exec/helper-proto.h"
+
+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+if (0 <= n && n < 32) {
+return gdb_get_regl(mem_buf, env->gpr[n]);
+} else if (n == 32) {
+return gdb_get_regl(mem_buf, env->pc);
+}
+return 0;
+}
+
+int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+target_ulong tmp = ldtul_p(mem_buf);
+
+if (0 <= n && n < 32) {
+return env->gpr[n] = tmp, sizeof(target_ulong);
+} else if (n == 32) {
+return env->pc = tmp, sizeof(target_ulong);
+}
+return 0;
+}
+
+static int loongarch_gdb_get_fpu(CPULoongArchState *env,
+ GByteArray *mem_buf, int n)
+{
+if (0 <= n && n < 32) {
+return gdb_get_reg64(mem_buf, env->fpr[n]);
+} else if (32 <= n && n < 40) {
+return gdb_get_reg8(mem_buf, env->cf[n - 32]);
+} else if (n == 40) {
+return gdb_get_reg32(mem_buf, env->fcsr0);
+}
+return 0;
+}
+
+static int loongarch_gdb_set_fpu(CPULoongArchState *env,
+ uint8_t *mem_buf, int n)
+{
+if (0 <= n && n < 32) {
+return env->fpr[n] = ldq_p(mem_buf), 8;
+} else if (32 <= n && n < 40) {
+return env->cf[n - 32] = ldub_p(mem_buf), 1;
+} else if (n == 40) {
+return env->fcsr0 = ldl_p(mem_buf), 4;
+}
+return 0;
+}
+
+void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs)
+{
+gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu,
+ 41, "loongarch-fpu64.xml", 0);
+}
+
+int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf,
+   

[RFC PATCH v4 30/30] tests/tcg/loongarch64: Add hello/memory test in loongarch64 system

2022-01-08 Thread Xiaojuan Yang
- We write a very minimal softmmu harness.
- This is a very simple smoke test with no need to run a full Linux/kernel.
- The Makefile.softmmu-target record the rule to run.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 tests/tcg/loongarch64/Makefile.softmmu-target | 33 +++
 tests/tcg/loongarch64/system/boot.S   | 58 +
 tests/tcg/loongarch64/system/kernel.ld| 30 +++
 tests/tcg/loongarch64/system/regdef.h | 86 +++
 4 files changed, 207 insertions(+)
 create mode 100644 tests/tcg/loongarch64/Makefile.softmmu-target
 create mode 100644 tests/tcg/loongarch64/system/boot.S
 create mode 100644 tests/tcg/loongarch64/system/kernel.ld
 create mode 100644 tests/tcg/loongarch64/system/regdef.h

diff --git a/tests/tcg/loongarch64/Makefile.softmmu-target 
b/tests/tcg/loongarch64/Makefile.softmmu-target
new file mode 100644
index 00..908f3a8c0f
--- /dev/null
+++ b/tests/tcg/loongarch64/Makefile.softmmu-target
@@ -0,0 +1,33 @@
+#
+# Loongarch64 system tests
+#
+
+LOONGARCH64_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/loongarch64/system
+VPATH+=$(LOONGARCH64_SYSTEM_SRC)
+
+# These objects provide the basic boot code and helper functions for all tests
+CRT_OBJS=boot.o
+
+LOONGARCH64_TEST_SRCS=$(wildcard $(LOONGARCH64_SYSTEM_SRC)/*.c)
+LOONGARCH64_TESTS = $(patsubst $(LOONGARCH64_SYSTEM_SRC)/%.c, %, 
$(LOONGARCH64_TEST_SRCS))
+
+CRT_PATH=$(LOONGARCH64_SYSTEM_SRC)
+LINK_SCRIPT=$(LOONGARCH64_SYSTEM_SRC)/kernel.ld
+LDFLAGS=-Wl,-T$(LINK_SCRIPT)
+TESTS+=$(LOONGARCH64_TESTS) $(MULTIARCH_TESTS)
+CFLAGS+=-nostdlib -g -O1 -march=loongarch64 -mabi=lp64d $(MINILIB_INC)
+LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
+
+# building head blobs
+.PRECIOUS: $(CRT_OBJS)
+
+%.o: $(CRT_PATH)/%.S
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -c $< -o $@
+
+# Build and link the tests
+%: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+
+memory: CFLAGS+=-DCHECK_UNALIGNED=0
+# Running
+QEMU_OPTS+=-serial chardev:output -kernel
diff --git a/tests/tcg/loongarch64/system/boot.S 
b/tests/tcg/loongarch64/system/boot.S
new file mode 100644
index 00..6a0671a5bf
--- /dev/null
+++ b/tests/tcg/loongarch64/system/boot.S
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Minimal LoongArch system boot code.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "regdef.h"
+
+   .global _start
+   .align 16
+_start:
+   bl main
+
+   .type _start 2
+   .size _start, .-_start
+
+   .global _exit
+   .align 16
+_exit:
+2:  /* QEMU ACPI poweroff */
+   li.w  t0, 0x3c00
+   li.w  t1, 0x100d0014
+   st.w  t0, t1, 0
+   idle  0
+   bl2b
+
+   .type _exit 2
+   .size _exit, .-_exit
+
+   .global __sys_outc
+__sys_outc:
+   li.d t1, 100
+loop:
+   lu12i.w t2, 0x1fe00
+   ori t0, t2, 0x1e5
+   lu52i.d t0, t0, -2048
+   ld.bu   t0, t0, 0
+   andit0, t0, 0x20
+   ext.w.b t0, t0
+   bnezt0, in
+   addi.w  t1, t1, -1
+   bnezt1, loop
+in:
+   ext.w.b a0, a0
+   lu12i.w t0, 0x1fe00
+   ori t0, t0, 0x1e0
+   lu52i.d t0, t0, -2048
+   st.ba0, t0, 0
+   jirl$r0, ra, 0
+
+   .data
+   .align 4
+stack:
+   .skip   65536
+$stack_end:
+   .type   stack,@object
+   .size   stack, . - stack
diff --git a/tests/tcg/loongarch64/system/kernel.ld 
b/tests/tcg/loongarch64/system/kernel.ld
new file mode 100644
index 00..f1a7c0168c
--- /dev/null
+++ b/tests/tcg/loongarch64/system/kernel.ld
@@ -0,0 +1,30 @@
+ENTRY(_start)
+
+SECTIONS
+{
+/* Linux kernel legacy start address.  */
+. = 0x9020;
+_text = .;
+.text : {
+*(.text)
+}
+.rodata : {
+*(.rodata)
+}
+_etext = .;
+
+. = ALIGN(8192);
+_data = .;
+.got : {
+*(.got)
+}
+.data : {
+   *(.sdata)
+*(.data)
+}
+_edata = .;
+.bss : {
+*(.bss)
+}
+_end = .;
+}
diff --git a/tests/tcg/loongarch64/system/regdef.h 
b/tests/tcg/loongarch64/system/regdef.h
new file mode 100644
index 00..faa09b2377
--- /dev/null
+++ b/tests/tcg/loongarch64/system/regdef.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+#ifndef _ASM_REGDEF_H
+#define _ASM_REGDEF_H
+
+#define zero$r0 /* wired zero */
+#define ra  $r1 /* return address */
+#define tp  $r2
+#define sp  $r3 /* stack pointer */
+#define v0  $r4 /* return value - caller saved */
+#define v1  $r5
+#define a0  $r4 /* argument registers */
+#define a1  $r5
+#define a2  $r6
+#define a3  $r7
+#define a4  $r8
+#define a5  $r9
+#define a6  $r10
+#define a7  $r11
+#define t0  $r12/* caller saved */
+#define t1  

[RFC PATCH v4 08/30] target/loongarch: Add LoongArch IOCSR instruction

2022-01-08 Thread Xiaojuan Yang
This includes:
- IOCSR{RD/WR}.{B/H/W/D}

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/cpu.c   |   8 ++
 target/loongarch/cpu.h   |   4 +
 target/loongarch/disas.c |   8 ++
 target/loongarch/helper.h|   2 +
 target/loongarch/insn_trans/trans_core.c.inc | 103 
 target/loongarch/insns.decode|   9 ++
 target/loongarch/iocsr_helper.c  | 120 +++
 target/loongarch/meson.build |   1 +
 8 files changed, 255 insertions(+)
 create mode 100644 target/loongarch/iocsr_helper.c

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 780eb96a3c..571092ce53 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -158,6 +158,14 @@ static void loongarch_3a5000_initfn(Object *obj)
 env->cpucfg[20] = data;
 
 env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
+
+#ifndef CONFIG_USER_ONLY
+env->address_space_iocsr = g_malloc(sizeof(*env->address_space_iocsr));
+env->system_iocsr = g_malloc(sizeof(*env->system_iocsr));
+memory_region_init_io(env->system_iocsr, obj, NULL,
+  env, "iocsr", UINT64_MAX);
+address_space_init(env->address_space_iocsr, env->system_iocsr, "IOCSR");
+#endif
 }
 
 static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 2a1841a708..ddb69ffecf 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -151,6 +151,7 @@ extern const char * const fregnames[32];
 
 #define N_IRQS  14
 #define IRQ_TIMER   11
+#define IRQ_IPI 12
 
 #define LOONGARCH_TLB_MAX  (2048 + 64) /* 2048 STLB + 64 MTLB */
 #define LOONGARCH_STLB 2048 /* 2048 STLB */
@@ -257,6 +258,9 @@ struct CPULoongArchState {
 
 #ifndef CONFIG_USER_ONLY
 LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
+
+AddressSpace *address_space_iocsr;
+MemoryRegion *system_iocsr;
 #endif
 };
 
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index de683bb88b..cbb264a318 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -531,6 +531,14 @@ INSN(bgeu, rr_offs)
 INSN(csrrd,r_csr)
 INSN(csrwr,r_csr)
 INSN(csrxchg,  rr_csr)
+INSN(iocsrrd_b,rr)
+INSN(iocsrrd_h,rr)
+INSN(iocsrrd_w,rr)
+INSN(iocsrrd_d,rr)
+INSN(iocsrwr_b,rr)
+INSN(iocsrwr_h,rr)
+INSN(iocsrwr_w,rr)
+INSN(iocsrwr_d,rr)
 
 #define output_fcmp(C, PREFIX, SUFFIX) 
\
 {  
\
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 036dbf31f8..1bcd082858 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -98,4 +98,6 @@ DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, 
env, i32)
 DEF_HELPER_2(csr_rdq, i64, env, i64)
 DEF_HELPER_3(csr_wrq, i64, env, tl, i64)
 DEF_HELPER_4(csr_xchgq, i64, env, tl, tl, i64)
+DEF_HELPER_3(iocsr_read, i64, env, tl, i32)
+DEF_HELPER_4(iocsr_write, void, env, tl, tl, i32)
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc 
b/target/loongarch/insn_trans/trans_core.c.inc
index 7d2cfe3534..592d2a339e 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -20,6 +20,14 @@ static bool trans_##name(DisasContext *ctx, arg_##name * a)  
\
 GEN_FALSE_TRANS(csrrd)
 GEN_FALSE_TRANS(csrwr)
 GEN_FALSE_TRANS(csrxchg)
+GEN_FALSE_TRANS(iocsrrd_b)
+GEN_FALSE_TRANS(iocsrrd_h)
+GEN_FALSE_TRANS(iocsrrd_w)
+GEN_FALSE_TRANS(iocsrrd_d)
+GEN_FALSE_TRANS(iocsrwr_b)
+GEN_FALSE_TRANS(iocsrwr_h)
+GEN_FALSE_TRANS(iocsrwr_w)
+GEN_FALSE_TRANS(iocsrwr_d)
 
 #else
 
@@ -120,4 +128,99 @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg 
*a)
 return true;
 }
 
+static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_iocsr_read(dest, cpu_env, src1, tcg_constant_i32(1));
+return true;
+}
+
+static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_iocsr_read(dest, cpu_env, src1, tcg_constant_i32(2));
+return true;
+}
+
+static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_iocsr_read(dest, cpu_env, src1, tcg_constant_i32(4));
+return true;
+}
+
+static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a)
+{
+TCGv dest = gpr_dst(ctx, 

[RFC PATCH v4 04/30] target/loongarch: Implement qmp_query_cpu_definitions()

2022-01-08 Thread Xiaojuan Yang
This patch introduce qmp_query_cpu_definitions interface.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 qapi/machine-target.json |  6 --
 target/loongarch/cpu.c   | 26 ++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index f5ec4bc172..682dc86b42 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -324,7 +324,8 @@
'TARGET_ARM',
'TARGET_I386',
'TARGET_S390X',
-   'TARGET_MIPS' ] } }
+   'TARGET_MIPS',
+   'TARGET_LOONGARCH64' ] } }
 
 ##
 # @query-cpu-definitions:
@@ -340,4 +341,5 @@
'TARGET_ARM',
'TARGET_I386',
'TARGET_S390X',
-   'TARGET_MIPS' ] } }
+   'TARGET_MIPS',
+   'TARGET_LOONGARCH64' ] } }
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 6e3dc5e6fa..690eeea2e6 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -351,3 +351,29 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
 };
 
 DEFINE_TYPES(loongarch_cpu_type_infos)
+
+static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ObjectClass *oc = data;
+CpuDefinitionInfoList **cpu_list = user_data;
+CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
+const char *typename = object_class_get_name(oc);
+
+info->name = g_strndup(typename,
+   strlen(typename) - strlen("-" TYPE_LOONGARCH_CPU));
+info->q_typename = g_strdup(typename);
+
+QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+CpuDefinitionInfoList *cpu_list = NULL;
+GSList *list;
+
+list = object_class_get_list(TYPE_LOONGARCH_CPU, false);
+g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list);
+g_slist_free(list);
+
+return cpu_list;
+}
-- 
2.27.0




[RFC PATCH v4 27/30] hw/loongarch: Add LoongArch smbios support

2022-01-08 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/Kconfig |  1 +
 hw/loongarch/loongson3.c | 40 
 include/hw/loongarch/loongarch.h |  1 +
 3 files changed, 42 insertions(+)

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 06bfb82b1d..6e24e112b3 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -14,6 +14,7 @@ config LOONGSON3_LS7A
 select LOONGARCH_EXTIOI
 select LS7A_RTC
 select FW_CFG_LOONGARCH
+select SMBIOS
 
 config FW_CFG_LOONGARCH
 bool
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 546ef6f4f1..8856225a99 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -27,6 +27,7 @@
 #include "hw/pci-host/ls7a.h"
 #include "hw/misc/unimp.h"
 #include "hw/loongarch/fw_cfg.h"
+#include "hw/firmware/smbios.h"
 
 #define LOONGSON3_BIOSNAME "loongarch_bios.bin"
 
@@ -100,6 +101,42 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg)
 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, (const char *)cmdline_buf);
 }
 
+static void loongarch_build_smbios(LoongArchMachineState *lams)
+{
+MachineState *ms = MACHINE(lams);
+MachineClass *mc = MACHINE_GET_CLASS(lams);
+uint8_t *smbios_tables, *smbios_anchor;
+size_t smbios_tables_len, smbios_anchor_len;
+const char *product = "QEMU Virtual Machine";
+
+if (!lams->fw_cfg) {
+return;
+}
+
+product = "Loongson-3A5000-7A1000-TCG";
+
+smbios_set_defaults("QEMU", product, mc->name, false,
+true, SMBIOS_ENTRY_POINT_TYPE_64);
+
+smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
+  &smbios_anchor, &smbios_anchor_len, &error_fatal);
+
+if (smbios_anchor) {
+fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-tables",
+smbios_tables, smbios_tables_len);
+fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-anchor",
+smbios_anchor, smbios_anchor_len);
+}
+}
+
+static
+void loongarch_machine_done(Notifier *notifier, void *data)
+{
+LoongArchMachineState *lams = container_of(notifier,
+LoongArchMachineState, machine_done);
+loongarch_build_smbios(lams);
+}
+
 static void loongarch_cpu_reset(void *opaque)
 {
 LoongArchCPU *cpu = opaque;
@@ -417,6 +454,9 @@ static void loongarch_init(MachineState *machine)
 memory_region_set_readonly(&lams->bios, true);
 memory_region_add_subregion(get_system_memory(), LA_BIOS_BASE, 
&lams->bios);
 
+lams->machine_done.notify = loongarch_machine_done;
+qemu_add_machine_init_done_notifier(&lams->machine_done);
+
 /* Initialize the IO interrupt subsystem */
 loongarch_irq_init(lams);
 }
diff --git a/include/hw/loongarch/loongarch.h b/include/hw/loongarch/loongarch.h
index 9ffcf8429f..9080864804 100644
--- a/include/hw/loongarch/loongarch.h
+++ b/include/hw/loongarch/loongarch.h
@@ -54,6 +54,7 @@ typedef struct LoongArchMachineState {
 MemoryRegion bios;
 
 /* State for other subsystems/APIs: */
+Notifier machine_done;
 FWCfgState  *fw_cfg;
 } LoongArchMachineState;
 
-- 
2.27.0




[RFC PATCH v4 03/30] target/loongarch: Add basic vmstate description of CPU.

2022-01-08 Thread Xiaojuan Yang
This patch introduce vmstate_loongarch_cpu

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c   |  3 ++
 target/loongarch/internals.h |  4 ++
 target/loongarch/machine.c   | 84 
 target/loongarch/meson.build |  6 +++
 4 files changed, 97 insertions(+)
 create mode 100644 target/loongarch/machine.c

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index ed03ec2986..6e3dc5e6fa 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -320,6 +320,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 cc->has_work = loongarch_cpu_has_work;
 cc->dump_state = loongarch_cpu_dump_state;
 cc->set_pc = loongarch_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+dc->vmsd = &vmstate_loongarch_cpu;
+#endif
 cc->disas_set_info = loongarch_cpu_disas_set_info;
 #ifdef CONFIG_TCG
 cc->tcg_ops = &loongarch_tcg_ops;
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 774a87ec80..c8e6f7012c 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -25,4 +25,8 @@ const char *loongarch_exception_name(int32_t exception);
 
 void restore_fp_status(CPULoongArchState *env);
 
+#ifndef CONFIG_USER_ONLY
+extern const VMStateDescription vmstate_loongarch_cpu;
+#endif
+
 #endif
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
new file mode 100644
index 00..b9effe6db2
--- /dev/null
+++ b/target/loongarch/machine.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch machine State
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/cpu.h"
+
+/* LoongArch CPU state */
+
+const VMStateDescription vmstate_loongarch_cpu = {
+.name = "cpu",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+
+VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
+VMSTATE_UINTTL(env.pc, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.fpr, LoongArchCPU, 32),
+VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
+
+/* Remaining CSR registers */
+VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CPUID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16),
+VMSTATE_UINT64(env.CSR_TID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU),
+VMSTATE_UINT

[RFC PATCH v4 02/30] target/loongarch: Add CSR registers definition

2022-01-08 Thread Xiaojuan Yang
1.Define All the CSR registers and its field.
2.Set some default csr values.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/cpu-csr.h | 236 +
 target/loongarch/cpu.c |  35 ++
 target/loongarch/cpu.h |  57 +
 3 files changed, 328 insertions(+)
 create mode 100644 target/loongarch/cpu-csr.h

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
new file mode 100644
index 00..7a57b7ea36
--- /dev/null
+++ b/target/loongarch/cpu-csr.h
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch CPU CSR registers
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_CSR_H
+#define LOONGARCH_CPU_CSR_H
+
+/* Base on: kernal: arch/loongarch/include/asm/loongarch.h */
+
+/* Basic CSR register */
+#define LOONGARCH_CSR_CRMD   0x0 /* Current mode info */
+FIELD(CSR_CRMD, PLV, 0, 2)
+FIELD(CSR_CRMD, IE, 2, 1)
+FIELD(CSR_CRMD, DA, 3, 1)
+FIELD(CSR_CRMD, PG, 4, 1)
+FIELD(CSR_CRMD, DATF, 5, 2)
+FIELD(CSR_CRMD, DATM, 7, 2)
+FIELD(CSR_CRMD, WE, 9, 1)
+
+#define LOONGARCH_CSR_PRMD   0x1 /* Prev-exception mode info */
+FIELD(CSR_PRMD, PPLV, 0, 2)
+FIELD(CSR_PRMD, PIE, 2, 1)
+FIELD(CSR_PRMD, PWE, 3, 1)
+
+#define LOONGARCH_CSR_EUEN   0x2 /* Extended unit enable */
+FIELD(CSR_EUEN, FPE, 0, 1)
+FIELD(CSR_EUEN, SXE, 1, 1)
+FIELD(CSR_EUEN, ASXE, 2, 1)
+FIELD(CSR_EUEN, BTE, 3, 1)
+
+#define LOONGARCH_CSR_MISC   0x3 /* Misc config */
+
+#define LOONGARCH_CSR_ECFG   0x4 /* Exception config */
+FIELD(CSR_ECFG, LIE, 0, 13)
+FIELD(CSR_ECFG, VS, 16, 3)
+
+#define LOONGARCH_CSR_ESTAT  0x5 /* Exception status */
+FIELD(CSR_ESTAT, IS, 0, 13)
+FIELD(CSR_ESTAT, ECODE, 16, 6)
+FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
+
+#define  EXCCODE_EXTERNAL_INT   64   /* plus external interrupt number */
+#define  EXCCODE_INT 0
+#define  EXCCODE_PIL 1
+#define  EXCCODE_PIS 2
+#define  EXCCODE_PIF 3
+#define  EXCCODE_PME 4
+#define  EXCCODE_PNR 5
+#define  EXCCODE_PNX 6
+#define  EXCCODE_PPI 7
+#define  EXCCODE_ADEF8 /* Have different expsubcode */
+#define  EXCCODE_ADEM8 /* Have different expsubcode */
+#define  EXCCODE_ALE 9
+#define  EXCCODE_BCE 10
+#define  EXCCODE_SYS 11
+#define  EXCCODE_BRK 12
+#define  EXCCODE_INE 13
+#define  EXCCODE_IPE 14
+#define  EXCCODE_FPD 15
+#define  EXCCODE_SXD 16
+#define  EXCCODE_ASXD17
+#define  EXCCODE_FPE 18 /* Have different expsubcode */
+#define  EXCCODE_VFPE18
+#define  EXCCODE_WPEF19 /* Have different expsubcode */
+#define  EXCCODE_WPEM19
+#define  EXCCODE_BTD 20
+#define  EXCCODE_BTE 21
+#define  EXCCODE_DBP 26 /* Reserved decode used for debug */
+
+#define LOONGARCH_CSR_ERA0x6 /* Exception return address */
+
+#define LOONGARCH_CSR_BADV   0x7 /* Bad virtual address */
+
+#define LOONGARCH_CSR_BADI   0x8 /* Bad instruction */
+
+#define LOONGARCH_CSR_EENTRY 0xc /* Exception enter base address */
+
+/* TLB related CSR register */
+#define LOONGARCH_CSR_TLBIDX 0x10 /* TLB Index, EHINV, PageSize, NP */
+FIELD(CSR_TLBIDX, INDEX, 0, 12)
+FIELD(CSR_TLBIDX, PS, 24, 6)
+FIELD(CSR_TLBIDX, NE, 31, 1)
+
+#define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi without ASID */
+FIELD(CSR_TLBEHI, VPPN, 13, 35)
+
+#define LOONGARCH_CSR_TLBELO00x12 /* TLB EntryLo0 */
+#define LOONGARCH_CSR_TLBELO10x13 /* TLB EntryLo1 */
+FIELD(TLBENTRY, V, 0, 1)
+FIELD(TLBENTRY, D, 1, 1)
+FIELD(TLBENTRY, PLV, 2, 2)
+FIELD(TLBENTRY, MAT, 4, 2)
+FIELD(TLBENTRY, G, 6, 1)
+FIELD(TLBENTRY, PPN, 12, 36)
+FIELD(TLBENTRY, NR, 61, 1)
+FIELD(TLBENTRY, NX, 62, 1)
+FIELD(TLBENTRY, RPLV, 63, 1)
+
+#define LOONGARCH_CSR_ASID   0x18 /* Address space identifier */
+FIELD(CSR_ASID, ASID, 0, 10)
+FIELD(CSR_ASID, ASIDBITS, 16, 8)
+
+/* Page table base address when badv[47] = 0 */
+#define LOONGARCH_CSR_PGDL   0x19
+/* Page table base address when badv[47] = 1 */
+#define LOONGARCH_CSR_PGDH   0x1a
+
+#define LOONGARCH_CSR_PGD0x1b /* Page table base */
+
+/* Page walk controller's low addr */
+#define LOONGARCH_CSR_PWCL   0x1c
+FIELD(CSR_PWCL, PTBASE, 0, 5)
+FIELD(CSR_PWCL, PTWIDTH, 5, 5)
+FIELD(CSR_PWCL, DIR1_BASE, 10, 5)
+FIELD(CSR_PWCL, DIR1_WIDTH, 15, 5)
+FIELD(CSR_PWCL, DIR2_BASE, 20, 5)
+FIELD(CSR_PWCL, DIR2_WIDTH, 25, 5)
+FIELD(CSR_PWCL, PTEWIDTH, 30, 2)
+
+/* Page walk controller's high addr */
+#define LOONGARCH_CSR_PWCH   0x1d
+FIELD(CSR_PWCH, DIR3_BASE, 0, 6)
+FIELD(CSR_PWCH, DIR3_WIDTH, 6, 6)
+FIELD(CSR_PWCH, DIR

[RFC PATCH v4 01/30] target/loongarch: Update README

2022-01-08 Thread Xiaojuan Yang
Mainly introduce how to run the softmmu

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/README | 25 +
 1 file changed, 25 insertions(+)

diff --git a/target/loongarch/README b/target/loongarch/README
index d5780c5918..337ba55f33 100644
--- a/target/loongarch/README
+++ b/target/loongarch/README
@@ -72,6 +72,31 @@
   ./qemu-loongarch64  /opt/clfs/usr/bin/pwd
   ...
 
+- Softmmu emulation
+
+  Add support softmmu emulation support in the following series patches.
+  Mainly emulate a virt 3A5000 board and ls7a bridge that is not exactly
+  the same as the host. Kernel code and uefi code is on the github.
+  All required binaries can get from github for test.
+
+  1.Download kernel and the cross-tools.(vmlinux)
+
+  https://github.com/loongson/linux/tree/loongarch-next
+  
https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz
+
+  2.Download uefi code.(loongarch_bios.bin)
+
+  https://github.com/loongson/edk2/tree/LoongArch
+  https://github.com/loongson/edk2-platforms
+
+  3.Download the clfs-system and make a ramdisk with busybox.(ramdisk)
+
+  4.Run with command,eg:
+
+   ./build/qemu-system-loongarch64 -m 4G -smp 4 --cpu Loongson-3A5000 
--machine loongson3-ls7a -kernel ./vmlinux -initrd ./ramdisk  -append 
"root=/dev/ram console=ttyS0,115200 rdinit=/sbin/init loglevel=8" -monitor 
tcp::4000,server,nowait -nographic
+
+The vmlinux, ramdisk and uefi binary loongarch_bios.bin can get from :
+git clone https://github.com/yangxiaojuan-loongson/qemu-binary
 
 - Note.
   We can get the latest LoongArch documents or LoongArch tools at 
https://github.com/loongson/
-- 
2.27.0




[RFC PATCH v4 17/30] hw/loongarch: Add LoongArch ipi interrupt support(IPI)

2022-01-08 Thread Xiaojuan Yang
This patch realize the IPI interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/intc/Kconfig |   3 +
 hw/intc/loongarch_ipi.c | 164 
 hw/intc/meson.build |   1 +
 hw/intc/trace-events|   4 +
 hw/loongarch/Kconfig|   1 +
 include/hw/intc/loongarch_ipi.h |  48 ++
 6 files changed, 221 insertions(+)
 create mode 100644 hw/intc/loongarch_ipi.c
 create mode 100644 include/hw/intc/loongarch_ipi.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 010ded7eae..9f5aaffb6f 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -78,3 +78,6 @@ config GOLDFISH_PIC
 
 config M68K_IRQC
 bool
+
+config LOONGARCH_IPI
+bool
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
new file mode 100644
index 00..b358ac68e5
--- /dev/null
+++ b/hw/intc/loongarch_ipi.c
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch ipi interrupt support
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/intc/loongarch_ipi.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "hw/loongarch/loongarch.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size)
+{
+IPICore *s = opaque;
+uint64_t ret = 0;
+int index = 0;
+
+addr &= 0xff;
+switch (addr) {
+case CORE_STATUS_OFF:
+ret = s->status;
+break;
+case CORE_EN_OFF:
+ret = s->en;
+break;
+case CORE_SET_OFF:
+ret = 0;
+break;
+case CORE_CLEAR_OFF:
+ret = 0;
+break;
+case CORE_BUF_20 ... CORE_BUF_38 + 4:
+index = (addr - CORE_BUF_20) >> 2;
+ret = s->buf[index];
+break;
+case IOCSR_IPI_SEND:
+ret = s->status;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
+break;
+}
+
+trace_loongarch_ipi_read(size, (uint64_t)addr, ret);
+return ret;
+}
+
+static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+IPICore *s = opaque;
+int index = 0;
+
+addr &= 0xff;
+trace_loongarch_ipi_write(size, (uint64_t)addr, val);
+switch (addr) {
+case CORE_STATUS_OFF:
+qemu_log_mask(LOG_GUEST_ERROR, "can not be written");
+break;
+case CORE_EN_OFF:
+s->en = val;
+break;
+case CORE_SET_OFF:
+s->status |= val;
+if (s->status != 0) {
+qemu_irq_raise(s->irq);
+}
+break;
+case CORE_CLEAR_OFF:
+s->status ^= val;
+if (s->status == 0) {
+qemu_irq_lower(s->irq);
+}
+break;
+case CORE_BUF_20 ... CORE_BUF_38 + 4:
+index = (addr - CORE_BUF_20) >> 2;
+s->buf[index] = val;
+break;
+case IOCSR_IPI_SEND:
+s->status |= val;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
+break;
+}
+}
+
+static const MemoryRegionOps loongarch_ipi_ops = {
+.read = loongarch_ipi_readl,
+.write = loongarch_ipi_writel,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void loongarch_ipi_init(Object *obj)
+{
+LoongArchIPI *s = LOONGARCH_IPI(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+int cpu;
+
+for (cpu = 0; cpu < MACHINE(qdev_get_machine())->smp.cpus; cpu++) {
+memory_region_init_io(&s->ipi_mmio[cpu], obj, &loongarch_ipi_ops,
+  &s->core[cpu], "loongarch_ipi", 0x100);
+sysbus_init_mmio(sbd, &s->ipi_mmio[cpu]);
+qdev_init_gpio_out(DEVICE(obj), &s->core[cpu].irq, 1);
+   }
+}
+
+static const VMStateDescription vmstate_ipi_core = {
+.name = "ipi-single",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(status, IPICore),
+VMSTATE_UINT32(en, IPICore),
+VMSTATE_UINT32(set, IPICore),
+VMSTATE_UINT32(clear, IPICore),
+VMSTATE_UINT32_ARRAY(buf, IPICore, MAX_IPI_MBX_NUM * 2),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const VMStateDescription vmstate_loongarch_ipi = {
+.name = TYPE_LOONGARCH_IPI,
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+VMSTATE_STRUCT_ARRAY(core, LoongArchIPI, MAX_IPI_CORE_NUM, 0,
+ vmstate_ipi_core, IPICore),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->vmsd = &vmstate_loongarch_ipi

[RFC PATCH v4 07/30] target/loongarch: Add LoongArch CSR instruction

2022-01-08 Thread Xiaojuan Yang
This includes:
- CSRRD
- CSRWR
- CSRXCHG

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/cpu.h   |  88 +
 target/loongarch/csr_helper.c| 112 +
 target/loongarch/disas.c |  15 +++
 target/loongarch/helper.h|   7 ++
 target/loongarch/insn_trans/trans_core.c.inc | 123 +++
 target/loongarch/insns.decode|  13 ++
 target/loongarch/meson.build |   1 +
 target/loongarch/translate.c |   5 +
 8 files changed, 364 insertions(+)
 create mode 100644 target/loongarch/csr_helper.c
 create mode 100644 target/loongarch/insn_trans/trans_core.c.inc

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 232d51e788..2a1841a708 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -260,6 +260,94 @@ struct CPULoongArchState {
 #endif
 };
 
+#define CSR_OFF(X)  \
+   [LOONGARCH_CSR_##X] = offsetof(CPULoongArchState, CSR_##X)
+#define CSR_OFF_ARRAY(X, N)  \
+   [LOONGARCH_CSR_##X(N)] = offsetof(CPULoongArchState, CSR_##X[N])
+
+static const int csr_offsets[] = {
+ CSR_OFF(CRMD),
+ CSR_OFF(PRMD),
+ CSR_OFF(EUEN),
+ CSR_OFF(MISC),
+ CSR_OFF(ECFG),
+ CSR_OFF(ESTAT),
+ CSR_OFF(ERA),
+ CSR_OFF(BADV),
+ CSR_OFF(BADI),
+ CSR_OFF(EENTRY),
+ CSR_OFF(TLBIDX),
+ CSR_OFF(TLBEHI),
+ CSR_OFF(TLBELO0),
+ CSR_OFF(TLBELO1),
+ CSR_OFF(ASID),
+ CSR_OFF(PGDL),
+ CSR_OFF(PGDH),
+ CSR_OFF(PGD),
+ CSR_OFF(PWCL),
+ CSR_OFF(PWCH),
+ CSR_OFF(STLBPS),
+ CSR_OFF(RVACFG),
+ CSR_OFF(CPUID),
+ CSR_OFF(PRCFG1),
+ CSR_OFF(PRCFG2),
+ CSR_OFF(PRCFG3),
+ CSR_OFF_ARRAY(SAVE, 0),
+ CSR_OFF_ARRAY(SAVE, 1),
+ CSR_OFF_ARRAY(SAVE, 2),
+ CSR_OFF_ARRAY(SAVE, 3),
+ CSR_OFF_ARRAY(SAVE, 4),
+ CSR_OFF_ARRAY(SAVE, 5),
+ CSR_OFF_ARRAY(SAVE, 6),
+ CSR_OFF_ARRAY(SAVE, 7),
+ CSR_OFF_ARRAY(SAVE, 8),
+ CSR_OFF_ARRAY(SAVE, 9),
+ CSR_OFF_ARRAY(SAVE, 10),
+ CSR_OFF_ARRAY(SAVE, 11),
+ CSR_OFF_ARRAY(SAVE, 12),
+ CSR_OFF_ARRAY(SAVE, 13),
+ CSR_OFF_ARRAY(SAVE, 14),
+ CSR_OFF_ARRAY(SAVE, 15),
+ CSR_OFF(TID),
+ CSR_OFF(TCFG),
+ CSR_OFF(TVAL),
+ CSR_OFF(CNTC),
+ CSR_OFF(TICLR),
+ CSR_OFF(LLBCTL),
+ CSR_OFF(IMPCTL1),
+ CSR_OFF(IMPCTL2),
+ CSR_OFF(TLBRENTRY),
+ CSR_OFF(TLBRBADV),
+ CSR_OFF(TLBRERA),
+ CSR_OFF(TLBRSAVE),
+ CSR_OFF(TLBRELO0),
+ CSR_OFF(TLBRELO1),
+ CSR_OFF(TLBREHI),
+ CSR_OFF(TLBRPRMD),
+ CSR_OFF(MERRCTL),
+ CSR_OFF(MERRINFO1),
+ CSR_OFF(MERRINFO2),
+ CSR_OFF(MERRENTRY),
+ CSR_OFF(MERRERA),
+ CSR_OFF(MERRSAVE),
+ CSR_OFF(CTAG),
+ CSR_OFF_ARRAY(DMW, 0),
+ CSR_OFF_ARRAY(DMW, 1),
+ CSR_OFF_ARRAY(DMW, 2),
+ CSR_OFF_ARRAY(DMW, 3),
+ CSR_OFF(DBG),
+ CSR_OFF(DERA),
+ CSR_OFF(DSAVE),
+};
+
+static inline int cpu_csr_offset(unsigned csr_num)
+{
+if (csr_num < ARRAY_SIZE(csr_offsets)) {
+return csr_offsets[csr_num];
+}
+return 0;
+}
+
 /**
  * LoongArchCPU:
  * @env: #CPULoongArchState
diff --git a/target/loongarch/csr_helper.c b/target/loongarch/csr_helper.c
new file mode 100644
index 00..4d0619cec8
--- /dev/null
+++ b/target/loongarch/csr_helper.c
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation helpers for csr registers
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "internals.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "hw/irq.h"
+#include "cpu-csr.h"
+#include "hw/loongarch/loongarch.h"
+#include "tcg/tcg-ldst.h"
+
+target_ulong helper_csr_rdq(CPULoongArchState *env, uint64_t csr)
+{
+LoongArchCPU *cpu;
+int64_t v;
+
+switch (csr) {
+case LOONGARCH_CSR_PGD:
+if (env->CSR_TLBRERA & 0x1) {
+v = env->CSR_TLBRBADV;
+} else {
+v = env->CSR_BADV;
+}
+
+if ((v >> 63) & 0x1) {
+v = env->CSR_PGDH;
+} else {
+v = env->CSR_PGDL;
+}
+break;
+case LOONGARCH_CSR_CPUID:
+v = (env_cpu(env))->cpu_index;
+break;
+case LOONGARCH_CSR_TVAL:
+cpu = LOONGARCH_CPU(env_cpu(env));
+v = cpu_loongarch_get_constant_timer_ticks(cpu);
+break;
+default:
+break;
+}
+
+return v;
+}
+
+target_ulong helper_csr_wrq(CPULoongArchState *env, target_ulong val,
+uint64_t csr)
+{
+LoongArchCPU *cpu;
+int64_t old_v = -1;
+
+switch (csr) {
+case LOONGARCH_CSR_ESTAT:
+/* Only IS[1:0] can be write */
+env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, IS, val & 0x3);
+break;
+case LOONGARCH

[RFC PATCH v4 09/30] target/loongarch: Add TLB instruction support

2022-01-08 Thread Xiaojuan Yang
This includes:
- TLBSRCH
- TLBRD
- TLBWR
- TLBFILL
- TLBCLR
- TLBFLUSH
- INVTLB

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 target/loongarch/disas.c |  17 +
 target/loongarch/helper.h|  12 +
 target/loongarch/insn_trans/trans_core.c.inc | 112 ++
 target/loongarch/insns.decode|  11 +
 target/loongarch/tlb_helper.c| 364 +++
 5 files changed, 516 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index cbb264a318..483270f331 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -216,6 +216,16 @@ static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
 output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->csr);
 }
 
+static void output_empty(DisasContext *ctx, arg_empty *a,
+ const char *mnemonic)
+{
+}
+
+static void output_i_rr(DisasContext *ctx, arg_i_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
+}
+
 #define INSN(insn, type)\
 static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
 {   \
@@ -539,6 +549,13 @@ INSN(iocsrwr_b,rr)
 INSN(iocsrwr_h,rr)
 INSN(iocsrwr_w,rr)
 INSN(iocsrwr_d,rr)
+INSN(tlbsrch,  empty)
+INSN(tlbrd,empty)
+INSN(tlbwr,empty)
+INSN(tlbfill,  empty)
+INSN(tlbclr,   empty)
+INSN(tlbflush, empty)
+INSN(invtlb,   i_rr)
 
 #define output_fcmp(C, PREFIX, SUFFIX) 
\
 {  
\
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 1bcd082858..97af7ac8aa 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -100,4 +100,16 @@ DEF_HELPER_3(csr_wrq, i64, env, tl, i64)
 DEF_HELPER_4(csr_xchgq, i64, env, tl, tl, i64)
 DEF_HELPER_3(iocsr_read, i64, env, tl, i32)
 DEF_HELPER_4(iocsr_write, void, env, tl, tl, i32)
+
+DEF_HELPER_1(tlbwr, void, env)
+DEF_HELPER_1(tlbfill, void, env)
+DEF_HELPER_1(tlbsrch, void, env)
+DEF_HELPER_1(tlbrd, void, env)
+DEF_HELPER_1(tlbclr, void, env)
+DEF_HELPER_1(tlbflush, void, env)
+DEF_HELPER_1(invtlb_all, void, env)
+DEF_HELPER_2(invtlb_all_g, void, env, i32)
+DEF_HELPER_2(invtlb_all_asid, void, env, tl)
+DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
+DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc 
b/target/loongarch/insn_trans/trans_core.c.inc
index 592d2a339e..5a8e9e0643 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -28,6 +28,13 @@ GEN_FALSE_TRANS(iocsrwr_b)
 GEN_FALSE_TRANS(iocsrwr_h)
 GEN_FALSE_TRANS(iocsrwr_w)
 GEN_FALSE_TRANS(iocsrwr_d)
+GEN_FALSE_TRANS(tlbsrch)
+GEN_FALSE_TRANS(tlbrd)
+GEN_FALSE_TRANS(tlbwr)
+GEN_FALSE_TRANS(tlbfill)
+GEN_FALSE_TRANS(tlbclr)
+GEN_FALSE_TRANS(tlbflush)
+GEN_FALSE_TRANS(invtlb)
 
 #else
 
@@ -223,4 +230,109 @@ static bool trans_iocsrwr_d(DisasContext *ctx, 
arg_iocsrwr_d *a)
 gen_helper_iocsr_write(cpu_env, addr, val, tcg_constant_i32(8));
 return true;
 }
+
+static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbsrch(cpu_env);
+return true;
+}
+
+static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbrd(cpu_env);
+return true;
+}
+
+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbwr(cpu_env);
+
+if (ctx->mem_idx != MMU_DA_IDX) {
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+}
+return true;
+}
+
+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbfill(cpu_env);
+
+if (ctx->mem_idx != MMU_DA_IDX) {
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+}
+return true;
+}
+
+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbclr(cpu_env);
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+return true;
+}
+
+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbflush(cpu_env);
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+return true;
+}
+
+static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
+{
+TCGv rj = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv rk = gpr_src(ctx, a->rk, EXT_NONE);
+
+if (check

[RFC PATCH v4 00/30] Add LoongArch softmmu support.

2022-01-08 Thread Xiaojuan Yang
This series patch add softmmu support for LoongArch.
Base on the linux-user emulation support V14 patch.
  * https://patchew.org/QEMU/20220106094200.1801206-1-gaos...@loongson.cn/
The latest kernel:
  * https://github.com/loongson/linux/tree/loongarch-next
The latest uefi:
  * https://github.com/loongson/edk2
  * https://github.com/loongson/edk2-platforms
The manual:
  * https://github.com/loongson/LoongArch-Documentation/releases/tag/2021.10.11


Changes for v4:
1. Uefi code is open and add some fdt interface to pass info between qemu and 
uefi. 
2. Use a per cpu address space for iocsr.
3. Modify the tlb emulation.
4. Machine and board code mainly follow Mark's advice.
5. Adjust pci host space map.
6. Use more memregion to simplify the interrupt controller's emulate.


Changes for v3:
1.Target code mainly follow Richard's code review comments.
2.Put the csr and iocsr read/write instruction emulate into 2 different patch.
3.Simply the tlb emulation.
4.Delete some unused csr registers defintion.
5.Machine and board code mainly follow Mark's advice, discard the obsolete 
interface.
6.NUMA function is removed for it is not completed.
7.Adjust some format problem and the Naming problem 


Changes for v2:
1.Combine patch 2 and 3 into one.
2.Adjust the order of the patch.
3.Put all the binaries on the github.
4.Modify some emulate errors when use the kernel from the github.
5.Adjust some format problem and the Naming problem 
6.Others mainly follow Richard's code review comments.

Please help review!

Thanks

Xiaojuan Yang (30):
  target/loongarch: Update README
  target/loongarch: Add CSR registers definition
  target/loongarch: Add basic vmstate description of CPU.
  target/loongarch: Implement qmp_query_cpu_definitions()
  target/loongarch: Add constant timer support
  target/loongarch: Add MMU support for LoongArch CPU.
  target/loongarch: Add LoongArch CSR instruction
  target/loongarch: Add LoongArch IOCSR instruction
  target/loongarch: Add TLB instruction support
  target/loongarch: Add other core instructions support
  target/loongarch: Add LoongArch interrupt and exception handle
  target/loongarch: Add timer related instructions support.
  target/loongarch: Add gdb support.
  hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson3
Platform
  hw/loongarch: Add support loongson3-ls7a machine type.
  hw/loongarch: Add LoongArch cpu interrupt support(CPUINTC)
  hw/loongarch: Add LoongArch ipi interrupt support(IPI)
  hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC)
  hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI)
  hw/intc: Add LoongArch extioi interrupt controller(EIOINTC)
  hw/loongarch: Add irq hierarchy for the system
  Enable common virtio pci support for LoongArch
  hw/loongarch: Add some devices support for 3A5000.
  hw/loongarch: Add LoongArch ls7a rtc device support
  hw/loongarch: Add default bios startup support.
  hw/loongarch: Add -kernel and -initrd options support
  hw/loongarch: Add LoongArch smbios support
  hw/loongarch: Add LoongArch acpi support
  hw/loongarch: Add fdt support.
  tests/tcg/loongarch64: Add hello/memory test in loongarch64 system

 .../devices/loongarch64-softmmu/default.mak   |   3 +
 configs/targets/loongarch64-softmmu.mak   |   4 +
 gdb-xml/loongarch-base64.xml  |  43 +
 gdb-xml/loongarch-fpu64.xml   |  57 ++
 hw/Kconfig|   1 +
 hw/acpi/Kconfig   |   4 +
 hw/acpi/ls7a.c| 374 +
 hw/acpi/meson.build   |   1 +
 hw/intc/Kconfig   |  15 +
 hw/intc/loongarch_extioi.c| 376 +
 hw/intc/loongarch_ipi.c   | 164 
 hw/intc/loongarch_pch_msi.c   |  75 ++
 hw/intc/loongarch_pch_pic.c   | 428 ++
 hw/intc/meson.build   |   4 +
 hw/intc/trace-events  |  25 +
 hw/loongarch/Kconfig  |  22 +
 hw/loongarch/acpi-build.c | 636 ++
 hw/loongarch/fw_cfg.c |  33 +
 hw/loongarch/fw_cfg.h |  15 +
 hw/loongarch/loongson3.c  | 685 +++
 hw/loongarch/meson.build  |   6 +
 hw/meson.build|   1 +
 hw/pci-host/Kconfig   |   4 +
 hw/pci-host/ls7a.c| 218 +
 hw/pci-host/meson.build   |   1 +
 hw/rtc/Kconfig|   3 +
 hw/rtc/ls7a_rtc.c | 322 
 hw/rtc/meson.build|   1 +
 include/exec/poison.h |   2 +
 include/hw/acpi/ls7a.h|  53 ++
 include/hw/intc/loongarch_extioi.h|  69 ++
 include/hw/intc/loongarch_ipi.h  

[PULL 37/37] bsd-user: add arm target build

2022-01-08 Thread Warner Losh
CC: Paolo Bonzini 
Signed-off-by: Warner Losh 
Acked-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 configs/targets/arm-bsd-user.mak | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 configs/targets/arm-bsd-user.mak

diff --git a/configs/targets/arm-bsd-user.mak b/configs/targets/arm-bsd-user.mak
new file mode 100644
index 000..cb143e6426a
--- /dev/null
+++ b/configs/targets/arm-bsd-user.mak
@@ -0,0 +1,2 @@
+TARGET_ARCH=arm
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml
-- 
2.33.1




[PULL 34/37] bsd-user/arm/signal.c: arm set_mcontext

2022-01-08 Thread Warner Losh
Move the machine context to the CPU state.

Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/signal.c | 76 +++
 1 file changed, 76 insertions(+)

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index 93c9bfc0d37..fb6228db6cf 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -109,3 +109,79 @@ abi_long get_mcontext(CPUARMState *env, target_mcontext_t 
*mcp, int flags)
 }
 return err;
 }
+
+/* Compare to arm/arm/exec_machdep.c set_mcontext() */
+abi_long set_mcontext(CPUARMState *env, target_mcontext_t *mcp, int srflag)
+{
+int err = 0;
+const uint32_t *gr = mcp->__gregs;
+uint32_t cpsr, ccpsr = cpsr_read(env);
+uint32_t fpscr, mask;
+
+cpsr = tswap32(gr[TARGET_REG_CPSR]);
+/*
+ * Only allow certain bits to change, reject attempted changes to non-user
+ * bits. In addition, make sure we're headed for user mode and none of the
+ * interrupt bits are set.
+ */
+if ((ccpsr & ~CPSR_USER) != (cpsr & ~CPSR_USER)) {
+return -TARGET_EINVAL;
+}
+if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR ||
+(cpsr & (CPSR_I | CPSR_F)) != 0) {
+return -TARGET_EINVAL;
+}
+
+/*
+ * The movs pc,lr instruction that implements the return to userland masks
+ * these bits out.
+ */
+mask = cpsr & CPSR_T ? 0x1 : 0x3;
+
+/*
+ * Make sure that we either have no vfp, or it's the correct size.
+ * FreeBSD just ignores it, though, so maybe we'll need to adjust
+ * things below instead.
+ */
+if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != 
sizeof(target_mcontext_vfp_t)) {
+return -TARGET_EINVAL;
+}
+
+env->regs[0] = tswap32(gr[TARGET_REG_R0]);
+env->regs[1] = tswap32(gr[TARGET_REG_R1]);
+env->regs[2] = tswap32(gr[TARGET_REG_R2]);
+env->regs[3] = tswap32(gr[TARGET_REG_R3]);
+env->regs[4] = tswap32(gr[TARGET_REG_R4]);
+env->regs[5] = tswap32(gr[TARGET_REG_R5]);
+env->regs[6] = tswap32(gr[TARGET_REG_R6]);
+env->regs[7] = tswap32(gr[TARGET_REG_R7]);
+env->regs[8] = tswap32(gr[TARGET_REG_R8]);
+env->regs[9] = tswap32(gr[TARGET_REG_R9]);
+env->regs[10] = tswap32(gr[TARGET_REG_R10]);
+env->regs[11] = tswap32(gr[TARGET_REG_R11]);
+env->regs[12] = tswap32(gr[TARGET_REG_R12]);
+
+env->regs[13] = tswap32(gr[TARGET_REG_SP]);
+env->regs[14] = tswap32(gr[TARGET_REG_LR]);
+env->regs[15] = tswap32(gr[TARGET_REG_PC] & ~mask);
+if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr != 0) {
+/* see set_vfpcontext in sys/arm/arm/exec_machdep.c */
+target_mcontext_vfp_t *vfp;
+
+vfp = lock_user(VERIFY_READ, mcp->mc_vfp_ptr, sizeof(*vfp), 1);
+for (int i = 0; i < 32; i++) {
+__get_user(*aa32_vfp_dreg(env, i), &vfp->mcv_reg[i]);
+}
+__get_user(fpscr, &vfp->mcv_fpscr);
+vfp_set_fpscr(env, fpscr);
+unlock_user(vfp, mcp->mc_vfp_ptr, sizeof(target_ucontext_t));
+
+/*
+ * linux-user sets fpexc, fpinst and fpinst2, but these aren't in
+ * FreeBSD's mcontext, what to do?
+ */
+}
+cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
+
+return err;
+}
-- 
2.33.1




[PULL 26/37] bsd-user/arm/target_arch_elf.h: arm defines for ELF

2022-01-08 Thread Warner Losh
Basic set of defines needed for arm ELF file activation.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_elf.h | 36 ++
 1 file changed, 36 insertions(+)
 create mode 100644 bsd-user/arm/target_arch_elf.h

diff --git a/bsd-user/arm/target_arch_elf.h b/bsd-user/arm/target_arch_elf.h
new file mode 100644
index 000..15b5c66511f
--- /dev/null
+++ b/bsd-user/arm/target_arch_elf.h
@@ -0,0 +1,36 @@
+/*
+ *  arm ELF definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 _TARGET_ARCH_ELF_H_
+#define _TARGET_ARCH_ELF_H_
+
+#define ELF_START_MMAP 0x8000
+#define ELF_ET_DYN_LOAD_ADDR0x50
+
+#define elf_check_arch(x) ((x) == EM_ARM)
+
+#define ELF_CLASS   ELFCLASS32
+#define ELF_DATAELFDATA2LSB
+#define ELF_ARCHEM_ARM
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE   4096
+
+#define ELF_HWCAP 0
+
+#endif /* _TARGET_ARCH_ELF_H_ */
-- 
2.33.1




[PULL 29/37] bsd-user/arm/target_arch_signal.h: arm specific signal registers and stack

2022-01-08 Thread Warner Losh
Defines for registers and stack layout related to signals.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_signal.h | 57 +++
 1 file changed, 57 insertions(+)
 create mode 100644 bsd-user/arm/target_arch_signal.h

diff --git a/bsd-user/arm/target_arch_signal.h 
b/bsd-user/arm/target_arch_signal.h
new file mode 100644
index 000..973183d99ca
--- /dev/null
+++ b/bsd-user/arm/target_arch_signal.h
@@ -0,0 +1,57 @@
+/*
+ *  arm signal definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 _TARGET_ARCH_SIGNAL_H_
+#define _TARGET_ARCH_SIGNAL_H_
+
+#include "cpu.h"
+
+#define TARGET_REG_R0   0
+#define TARGET_REG_R1   1
+#define TARGET_REG_R2   2
+#define TARGET_REG_R3   3
+#define TARGET_REG_R4   4
+#define TARGET_REG_R5   5
+#define TARGET_REG_R6   6
+#define TARGET_REG_R7   7
+#define TARGET_REG_R8   8
+#define TARGET_REG_R9   9
+#define TARGET_REG_R10  10
+#define TARGET_REG_R11  11
+#define TARGET_REG_R12  12
+#define TARGET_REG_R13  13
+#define TARGET_REG_R14  14
+#define TARGET_REG_R15  15
+#define TARGET_REG_CPSR 16
+#define TARGET__NGREG   17
+/* Convenience synonyms */
+#define TARGET_REG_FP   TARGET_REG_R11
+#define TARGET_REG_SP   TARGET_REG_R13
+#define TARGET_REG_LR   TARGET_REG_R14
+#define TARGET_REG_PC   TARGET_REG_R15
+
+#define TARGET_INSN_SIZE4   /* arm instruction size */
+
+/* Size of the signal trampolin code. See _sigtramp(). */
+#define TARGET_SZSIGCODE((abi_ulong)(9 * TARGET_INSN_SIZE))
+
+/* compare to arm/include/_limits.h */
+#define TARGET_MINSIGSTKSZ  (1024 * 4)  /* min sig stack size 
*/
+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)  /* recommended size 
*/
+
+#endif /* !_TARGET_ARCH_SIGNAL_H_ */
-- 
2.33.1




[PULL 31/37] bsd-user/arm/target_arch_signal.h: Define size of *context_t

2022-01-08 Thread Warner Losh
Define the native sizes of mcontext_t and ucontext_t so that the tests
in target_os_ucontext.h ensure the size of arm's version of these
structures is correct.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_signal.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/bsd-user/arm/target_arch_signal.h 
b/bsd-user/arm/target_arch_signal.h
index 9527335cc98..f1844dbf225 100644
--- a/bsd-user/arm/target_arch_signal.h
+++ b/bsd-user/arm/target_arch_signal.h
@@ -74,6 +74,9 @@ typedef struct target_mcontext {
 abi_int mc_spare[33];
 } target_mcontext_t;
 
+#define TARGET_MCONTEXT_SIZE 208
+#define TARGET_UCONTEXT_SIZE 260
+
 #include "target_os_ucontext.h"
 
 struct target_sigframe {
-- 
2.33.1




[PULL 24/37] bsd-user/arm/target_arch_sigtramp.h: Signal Trampoline for arm

2022-01-08 Thread Warner Losh
Copy of the signal trampoline code for arm, as well as setup_sigtramp to
write it to the stack.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_sigtramp.h | 49 +
 1 file changed, 49 insertions(+)
 create mode 100644 bsd-user/arm/target_arch_sigtramp.h

diff --git a/bsd-user/arm/target_arch_sigtramp.h 
b/bsd-user/arm/target_arch_sigtramp.h
new file mode 100644
index 000..5d434a9e7e8
--- /dev/null
+++ b/bsd-user/arm/target_arch_sigtramp.h
@@ -0,0 +1,49 @@
+/*
+ *  arm sysarch() system call emulation
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+unsigned sys_sigreturn)
+{
+int i;
+uint32_t sys_exit = TARGET_FREEBSD_NR_exit;
+uint32_t sigtramp_code[] = {
+/* 1 */ 0xE1AD,  /* mov r0, sp */
+/* 2 */ 0xE280 + sigf_uc,/* add r0, r0, #SIGF_UC */
+/* 3 */ 0xE59F700C,  /* ldr r7, [pc, #12] */
+/* 4 */ 0xEF00 + sys_sigreturn,  /* swi (SYS_sigreturn) */
+/* 5 */ 0xE59F7008,  /* ldr r7, [pc, #8] */
+/* 6 */ 0xEF00 + sys_exit,   /* swi (SYS_exit)*/
+/* 7 */ 0xEAFA,  /* b . -16 */
+/* 8 */ sys_sigreturn,
+/* 9 */ sys_exit
+};
+
+G_STATIC_ASSERT(sizeof(sigtramp_code) == TARGET_SZSIGCODE);
+
+for (i = 0; i < 9; i++) {
+tswap32s(&sigtramp_code[i]);
+}
+
+return memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE);
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
-- 
2.33.1




[PULL 27/37] bsd-user/arm/target_arch_elf.h: arm get hwcap

2022-01-08 Thread Warner Losh
Implement get_elf_hwcap to get the first word of hardware capabilities.

Signed-off-by: Kyle Evans 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_elf.h | 72 +-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/bsd-user/arm/target_arch_elf.h b/bsd-user/arm/target_arch_elf.h
index 15b5c66511f..02d25b89264 100644
--- a/bsd-user/arm/target_arch_elf.h
+++ b/bsd-user/arm/target_arch_elf.h
@@ -31,6 +31,76 @@
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE   4096
 
-#define ELF_HWCAP 0
+#define ELF_HWCAP get_elf_hwcap()
+
+#define GET_FEATURE(feat, hwcap) \
+do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+
+#define GET_FEATURE_ID(feat, hwcap) \
+do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
+
+enum {
+ARM_HWCAP_ARM_SWP   = 1 << 0,
+ARM_HWCAP_ARM_HALF  = 1 << 1,
+ARM_HWCAP_ARM_THUMB = 1 << 2,
+ARM_HWCAP_ARM_26BIT = 1 << 3,
+ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
+ARM_HWCAP_ARM_FPA   = 1 << 5,
+ARM_HWCAP_ARM_VFP   = 1 << 6,
+ARM_HWCAP_ARM_EDSP  = 1 << 7,
+ARM_HWCAP_ARM_JAVA  = 1 << 8,
+ARM_HWCAP_ARM_IWMMXT= 1 << 9,
+ARM_HWCAP_ARM_CRUNCH= 1 << 10,
+ARM_HWCAP_ARM_THUMBEE   = 1 << 11,
+ARM_HWCAP_ARM_NEON  = 1 << 12,
+ARM_HWCAP_ARM_VFPv3 = 1 << 13,
+ARM_HWCAP_ARM_VFPv3D16  = 1 << 14,
+ARM_HWCAP_ARM_TLS   = 1 << 15,
+ARM_HWCAP_ARM_VFPv4 = 1 << 16,
+ARM_HWCAP_ARM_IDIVA = 1 << 17,
+ARM_HWCAP_ARM_IDIVT = 1 << 18,
+ARM_HWCAP_ARM_VFPD32= 1 << 19,
+ARM_HWCAP_ARM_LPAE  = 1 << 20,
+ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
+};
+
+static uint32_t get_elf_hwcap(void)
+{
+ARMCPU *cpu = ARM_CPU(thread_cpu);
+uint32_t hwcaps = 0;
+
+hwcaps |= ARM_HWCAP_ARM_SWP;
+hwcaps |= ARM_HWCAP_ARM_HALF;
+hwcaps |= ARM_HWCAP_ARM_THUMB;
+hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
+
+/* probe for the extra features */
+/* EDSP is in v5TE and above */
+GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
+GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
+GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
+GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
+GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
+GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
+GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
+GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
+GET_FEATURE_ID(aa32_vfp, ARM_HWCAP_ARM_VFP);
+
+if (cpu_isar_feature(aa32_fpsp_v3, cpu) ||
+cpu_isar_feature(aa32_fpdp_v3, cpu)) {
+hwcaps |= ARM_HWCAP_ARM_VFPv3;
+if (cpu_isar_feature(aa32_simd_r32, cpu)) {
+hwcaps |= ARM_HWCAP_ARM_VFPD32;
+} else {
+hwcaps |= ARM_HWCAP_ARM_VFPv3D16;
+}
+}
+GET_FEATURE_ID(aa32_simdfmac, ARM_HWCAP_ARM_VFPv4);
+
+return hwcaps;
+}
+
+#undef GET_FEATURE
+#undef GET_FEATURE_ID
 
 #endif /* _TARGET_ARCH_ELF_H_ */
-- 
2.33.1




[PULL 35/37] bsd-user/arm/signal.c: arm get_ucontext_sigreturn

2022-01-08 Thread Warner Losh
Update ucontext to implement sigreturn.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/signal.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index fb6228db6cf..1478f008d13 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -185,3 +185,12 @@ abi_long set_mcontext(CPUARMState *env, target_mcontext_t 
*mcp, int srflag)
 
 return err;
 }
+
+/* Compare to arm/arm/machdep.c sys_sigreturn() */
+abi_long get_ucontext_sigreturn(CPUARMState *env, abi_ulong target_sf,
+abi_ulong *target_uc)
+{
+*target_uc = target_sf;
+
+return 0;
+}
-- 
2.33.1




[PULL 20/37] bsd-user/arm/target_arch_cpu.h: Implement data abort exceptions

2022-01-08 Thread Warner Losh
Implement EXCP_PREFETCH_ABORT AND EXCP_DATA_ABORT. Both of these data
exceptions cause a SIGSEGV.

Signed-off-by: Kyle Evans 
Signed-off-by: Olivier Houchard 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_cpu.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 9f9b380b137..905a5ffaffa 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -65,6 +65,17 @@ static inline void target_cpu_loop(CPUARMState *env)
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
 break;
+case EXCP_PREFETCH_ABORT:
+/* See arm/arm/trap.c prefetch_abort_handler() */
+case EXCP_DATA_ABORT:
+/* See arm/arm/trap.c data_abort_handler() */
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = 0;
+info.si_addr = env->exception.vaddress;
+queue_signal(env, info.si_signo, &info);
+break;
 case EXCP_DEBUG:
 {
 
-- 
2.33.1




[PULL 33/37] bsd-user/arm/signal.c: arm get_mcontext

2022-01-08 Thread Warner Losh
Get the machine context from the CPU state.

Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/signal.c | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index 3c0db30a85e..93c9bfc0d37 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -58,3 +58,54 @@ abi_long set_sigtramp_args(CPUARMState *env, int sig,
 
 return 0;
 }
+
+/*
+ * Compare to arm/arm/machdep.c get_mcontext()
+ * Assumes that the memory is locked if mcp points to user memory.
+ */
+abi_long get_mcontext(CPUARMState *env, target_mcontext_t *mcp, int flags)
+{
+int err = 0;
+uint32_t *gr = mcp->__gregs;
+
+if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != 
sizeof(target_mcontext_vfp_t)) {
+return -TARGET_EINVAL;
+}
+
+gr[TARGET_REG_CPSR] = tswap32(cpsr_read(env));
+if (flags & TARGET_MC_GET_CLEAR_RET) {
+gr[TARGET_REG_R0] = 0;
+gr[TARGET_REG_CPSR] &= ~CPSR_C;
+} else {
+gr[TARGET_REG_R0] = tswap32(env->regs[0]);
+}
+
+gr[TARGET_REG_R1] = tswap32(env->regs[1]);
+gr[TARGET_REG_R2] = tswap32(env->regs[2]);
+gr[TARGET_REG_R3] = tswap32(env->regs[3]);
+gr[TARGET_REG_R4] = tswap32(env->regs[4]);
+gr[TARGET_REG_R5] = tswap32(env->regs[5]);
+gr[TARGET_REG_R6] = tswap32(env->regs[6]);
+gr[TARGET_REG_R7] = tswap32(env->regs[7]);
+gr[TARGET_REG_R8] = tswap32(env->regs[8]);
+gr[TARGET_REG_R9] = tswap32(env->regs[9]);
+gr[TARGET_REG_R10] = tswap32(env->regs[10]);
+gr[TARGET_REG_R11] = tswap32(env->regs[11]);
+gr[TARGET_REG_R12] = tswap32(env->regs[12]);
+
+gr[TARGET_REG_SP] = tswap32(env->regs[13]);
+gr[TARGET_REG_LR] = tswap32(env->regs[14]);
+gr[TARGET_REG_PC] = tswap32(env->regs[15]);
+
+if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr != 0) {
+/* see get_vfpcontext in sys/arm/arm/exec_machdep.c */
+target_mcontext_vfp_t *vfp;
+vfp = lock_user(VERIFY_WRITE, mcp->mc_vfp_ptr, sizeof(*vfp), 0);
+for (int i = 0; i < 32; i++) {
+vfp->mcv_reg[i] = tswap64(*aa32_vfp_dreg(env, i));
+}
+vfp->mcv_fpscr = tswap32(vfp_get_fpscr(env));
+unlock_user(vfp, mcp->mc_vfp_ptr, sizeof(*vfp));
+}
+return err;
+}
-- 
2.33.1




[PULL 28/37] bsd-user/arm/target_arch_elf.h: arm get_hwcap2 impl

2022-01-08 Thread Warner Losh
Implement the extended HW capabilities for HWCAP2.

Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_elf.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/bsd-user/arm/target_arch_elf.h b/bsd-user/arm/target_arch_elf.h
index 02d25b89264..4a0215d02ed 100644
--- a/bsd-user/arm/target_arch_elf.h
+++ b/bsd-user/arm/target_arch_elf.h
@@ -32,6 +32,7 @@
 #define ELF_EXEC_PAGESIZE   4096
 
 #define ELF_HWCAP get_elf_hwcap()
+#define ELF_HWCAP2 get_elf_hwcap2()
 
 #define GET_FEATURE(feat, hwcap) \
 do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
@@ -64,6 +65,14 @@ enum {
 ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
+enum {
+ARM_HWCAP2_ARM_AES  = 1 << 0,
+ARM_HWCAP2_ARM_PMULL= 1 << 1,
+ARM_HWCAP2_ARM_SHA1 = 1 << 2,
+ARM_HWCAP2_ARM_SHA2 = 1 << 3,
+ARM_HWCAP2_ARM_CRC32= 1 << 4,
+};
+
 static uint32_t get_elf_hwcap(void)
 {
 ARMCPU *cpu = ARM_CPU(thread_cpu);
@@ -100,6 +109,19 @@ static uint32_t get_elf_hwcap(void)
 return hwcaps;
 }
 
+static uint32_t get_elf_hwcap2(void)
+{
+ARMCPU *cpu = ARM_CPU(thread_cpu);
+uint32_t hwcaps = 0;
+
+GET_FEATURE_ID(aa32_aes, ARM_HWCAP2_ARM_AES);
+GET_FEATURE_ID(aa32_pmull, ARM_HWCAP2_ARM_PMULL);
+GET_FEATURE_ID(aa32_sha1, ARM_HWCAP2_ARM_SHA1);
+GET_FEATURE_ID(aa32_sha2, ARM_HWCAP2_ARM_SHA2);
+GET_FEATURE_ID(aa32_crc32, ARM_HWCAP2_ARM_CRC32);
+return hwcaps;
+}
+
 #undef GET_FEATURE
 #undef GET_FEATURE_ID
 
-- 
2.33.1




[PULL 36/37] bsd-user/freebsd/target_os_ucontext.h: Require TARGET_*CONTEXT_SIZE

2022-01-08 Thread Warner Losh
Now that all architecutres define TARGET_[MU]CONTEXT_SIZE, enforce
requiring them and always check the sizeof target_{u,m}context_t
sizes.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_ucontext.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bsd-user/freebsd/target_os_ucontext.h 
b/bsd-user/freebsd/target_os_ucontext.h
index dd61aec7cce..41b28b2c150 100644
--- a/bsd-user/freebsd/target_os_ucontext.h
+++ b/bsd-user/freebsd/target_os_ucontext.h
@@ -27,10 +27,8 @@ typedef struct target_ucontext {
 int32_t __spare__[4];
 } target_ucontext_t;
 
-#ifdef TARGET_MCONTEXT_SIZE
 G_STATIC_ASSERT(TARGET_MCONTEXT_SIZE == sizeof(target_mcontext_t));
 G_STATIC_ASSERT(TARGET_UCONTEXT_SIZE == sizeof(target_ucontext_t));
-#endif /* TARGET_MCONTEXT_SIZE */
 
 struct target_sigframe;
 
-- 
2.33.1




[PULL 32/37] bsd-user/arm/signal.c: arm set_sigtramp_args

2022-01-08 Thread Warner Losh
Implement set_sigtramp_args to setup the arguments to the sigtramp
calls.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/signal.c | 60 +++
 1 file changed, 60 insertions(+)
 create mode 100644 bsd-user/arm/signal.c

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
new file mode 100644
index 000..3c0db30a85e
--- /dev/null
+++ b/bsd-user/arm/signal.c
@@ -0,0 +1,60 @@
+/*
+ *  arm signal functions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 "qemu.h"
+
+/*
+ * Compare to arm/arm/machdep.c sendsig()
+ * Assumes that target stack frame memory is locked.
+ */
+abi_long set_sigtramp_args(CPUARMState *env, int sig,
+   struct target_sigframe *frame,
+   abi_ulong frame_addr,
+   struct target_sigaction *ka)
+{
+/*
+ * Arguments to signal handler:
+ *  r0 = signal number
+ *  r1 = siginfo pointer
+ *  r2 = ucontext pointer
+ *  r5 = ucontext pointer
+ *  pc = signal handler pointer
+ *  sp = sigframe struct pointer
+ *  lr = sigtramp at base of user stack
+ */
+
+env->regs[0] = sig;
+env->regs[1] = frame_addr +
+offsetof(struct target_sigframe, sf_si);
+env->regs[2] = frame_addr +
+offsetof(struct target_sigframe, sf_uc);
+
+/* the trampoline uses r5 as the uc address */
+env->regs[5] = frame_addr +
+offsetof(struct target_sigframe, sf_uc);
+env->regs[TARGET_REG_PC] = ka->_sa_handler & ~1;
+env->regs[TARGET_REG_SP] = frame_addr;
+env->regs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
+/*
+ * Low bit indicates whether or not we're entering thumb mode.
+ */
+cpsr_write(env, (ka->_sa_handler & 1) * CPSR_T, CPSR_T, CPSRWriteByInstr);
+
+return 0;
+}
-- 
2.33.1




[PULL 15/37] bsd-user/arm/target_arch_cpu.c: Target specific TLS routines

2022-01-08 Thread Warner Losh
Target specific TLS routines to get and set the TLS values.

Signed-off-by: Kyle Evans 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch.h | 28 
 bsd-user/arm/target_arch_cpu.c | 39 ++
 2 files changed, 67 insertions(+)
 create mode 100644 bsd-user/arm/target_arch.h
 create mode 100644 bsd-user/arm/target_arch_cpu.c

diff --git a/bsd-user/arm/target_arch.h b/bsd-user/arm/target_arch.h
new file mode 100644
index 000..93cfaea0986
--- /dev/null
+++ b/bsd-user/arm/target_arch.h
@@ -0,0 +1,28 @@
+/*
+ * ARM 32-bit specific prototypes for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+#include "qemu.h"
+
+void target_cpu_set_tls(CPUARMState *env, target_ulong newtls);
+target_ulong target_cpu_get_tls(CPUARMState *env);
+
+#endif /* !_TARGET_ARCH_H_ */
diff --git a/bsd-user/arm/target_arch_cpu.c b/bsd-user/arm/target_arch_cpu.c
new file mode 100644
index 000..02bf9149d54
--- /dev/null
+++ b/bsd-user/arm/target_arch_cpu.c
@@ -0,0 +1,39 @@
+/*
+ *  arm cpu related code
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 "target_arch.h"
+
+void target_cpu_set_tls(CPUARMState *env, target_ulong newtls)
+{
+if (access_secure_reg(env)) {
+env->cp15.tpidrurw_s = newtls;
+env->cp15.tpidruro_s = newtls;
+return;
+}
+
+env->cp15.tpidr_el[0] = newtls;
+env->cp15.tpidrro_el[0] = newtls;
+}
+
+target_ulong target_cpu_get_tls(CPUARMState *env)
+{
+if (access_secure_reg(env)) {
+return env->cp15.tpidruro_s;
+}
+return env->cp15.tpidrro_el[0];
+}
-- 
2.33.1




[PULL 19/37] bsd-user/arm/target_arch_cpu.h: Implement trivial EXCP exceptions

2022-01-08 Thread Warner Losh
Implement EXCP_UDEF, EXCP_DEBUG, EXCP_INTERRUPT, EXCP_ATOMIC and
EXCP_YIELD. The first two generate a signal to the emulated
binary. EXCP_ATOMIC handles atomic operations. The remainder are fancy
nops.

Signed-off-by: Stacey Son 
Signed-off-by: Mikaël Urankar 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_cpu.h | 33 +
 1 file changed, 33 insertions(+)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 2484bdc2f7a..9f9b380b137 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -48,6 +48,39 @@ static inline void target_cpu_loop(CPUARMState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 switch (trapnr) {
+case EXCP_UDEF:
+{
+/* See arm/arm/undefined.c undefinedinstruction(); */
+info.si_addr = env->regs[15];
+
+/* illegal instruction */
+info.si_signo = TARGET_SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_ILLOPC;
+queue_signal(env, info.si_signo, &info);
+
+/* TODO: What about instruction emulation? */
+}
+break;
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_DEBUG:
+{
+
+info.si_signo = TARGET_SIGTRAP;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+info.si_addr = env->exception.vaddress;
+queue_signal(env, info.si_signo, &info);
+}
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+case EXCP_YIELD:
+/* nothing to do here for user-mode, just resume guest code */
+break;
 default:
 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 trapnr);
-- 
2.33.1




[PULL 25/37] bsd-user/arm/target_arch_thread.h: Routines to create and switch to a thread

2022-01-08 Thread Warner Losh
Implement target_thread_init (to create a thread) and target_set_upcall
(to switch to a thread) for arm.

Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
---
 bsd-user/arm/target_arch_thread.h | 82 +++
 1 file changed, 82 insertions(+)
 create mode 100644 bsd-user/arm/target_arch_thread.h

diff --git a/bsd-user/arm/target_arch_thread.h 
b/bsd-user/arm/target_arch_thread.h
new file mode 100644
index 000..11c7f765838
--- /dev/null
+++ b/bsd-user/arm/target_arch_thread.h
@@ -0,0 +1,82 @@
+/*
+ *  arm thread support
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 _TARGET_ARCH_THREAD_H_
+#define _TARGET_ARCH_THREAD_H_
+
+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
+static inline void target_thread_set_upcall(CPUARMState *env, abi_ulong entry,
+abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size)
+{
+abi_ulong sp;
+
+/*
+ * Make sure the stack is properly aligned.
+ * arm/include/param.h (STACKLIGN() macro)
+ */
+sp = (u_int)(stack_base + stack_size) & ~0x7;
+
+/* sp = stack base */
+env->regs[13] = sp;
+/* pc = start function entry */
+env->regs[15] = entry & 0xfffe;
+/* r0 = arg */
+env->regs[0] = arg;
+env->spsr = ARM_CPU_MODE_USR;
+/*
+ * Thumb mode is encoded by the low bit in the entry point (since ARM can't
+ * execute at odd addresses). When it's set, set the Thumb bit (T) in the
+ * CPSR.
+ */
+cpsr_write(env, (entry & 1) * CPSR_T, CPSR_T, CPSRWriteByInstr);
+}
+
+static inline void target_thread_init(struct target_pt_regs *regs,
+struct image_info *infop)
+{
+abi_long stack = infop->start_stack;
+memset(regs, 0, sizeof(*regs));
+regs->ARM_cpsr = ARM_CPU_MODE_USR;
+/*
+ * Thumb mode is encoded by the low bit in the entry point (since ARM can't
+ * execute at odd addresses). When it's set, set the Thumb bit (T) in the
+ * CPSR.
+ */
+if (infop->entry & 1) {
+regs->ARM_cpsr |= CPSR_T;
+}
+regs->ARM_pc = infop->entry & 0xfffe;
+regs->ARM_sp = stack;
+if (bsd_type == target_freebsd) {
+regs->ARM_lr = infop->entry & 0xfffe;
+}
+/*
+ * FreeBSD kernel passes the ps_strings pointer in r0. This is used by some
+ * programs to set status messages that we see in ps. bsd-user doesn't
+ * support that functionality, so it's ignored. When set to 0, FreeBSD's 
csu
+ * code ignores it. For the static case, r1 and r2 are effectively ignored
+ * by the csu __startup() routine. For the dynamic case, rtld saves r0 but
+ * generates r1 and r2 and passes them into the csu _startup.
+ *
+ * r0 ps_strings 0 passed since ps arg setting not supported
+ * r1 obj_main   ignored by _start(), so 0 passed
+ * r2 cleanupgenerated by rtld or ignored by _start(), so 0 passed
+ */
+}
+
+#endif /* !_TARGET_ARCH_THREAD_H_ */
-- 
2.33.1




[PULL 17/37] bsd-user/arm/target_arch_cpu.h: Implement target_cpu_clone_regs

2022-01-08 Thread Warner Losh
Implement target_cpu_clone_regs to clone the resister state on a fork.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_cpu.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 66215684d6f..fa45d9335d6 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -36,6 +36,14 @@ static inline void target_cpu_init(CPUARMState *env,
 }
 }
 
+static inline void target_cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+{
+if (newsp) {
+env->regs[13] = newsp;
+}
+env->regs[0] = 0;
+}
+
 static inline void target_cpu_reset(CPUArchState *cpu)
 {
 }
-- 
2.33.1




[PULL 30/37] bsd-user/arm/target_arch_signal.h: arm machine context and trapframe for signals

2022-01-08 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_signal.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/bsd-user/arm/target_arch_signal.h 
b/bsd-user/arm/target_arch_signal.h
index 973183d99ca..9527335cc98 100644
--- a/bsd-user/arm/target_arch_signal.h
+++ b/bsd-user/arm/target_arch_signal.h
@@ -54,4 +54,32 @@
 #define TARGET_MINSIGSTKSZ  (1024 * 4)  /* min sig stack size 
*/
 #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)  /* recommended size 
*/
 
+/*
+ * Floating point register state
+ */
+typedef struct target_mcontext_vfp {
+abi_ullong  mcv_reg[32];
+abi_ulong   mcv_fpscr;
+} target_mcontext_vfp_t;
+
+typedef struct target_mcontext {
+abi_uint__gregs[TARGET__NGREG];
+
+/*
+ * Originally, rest of this structure was named __fpu, 35 * 4 bytes
+ * long, never accessed from kernel.
+ */
+abi_ulong   mc_vfp_size;
+abi_ptr mc_vfp_ptr;
+abi_int mc_spare[33];
+} target_mcontext_t;
+
+#include "target_os_ucontext.h"
+
+struct target_sigframe {
+target_siginfo_tsf_si;  /* saved siginfo */
+target_ucontext_t   sf_uc;  /* saved ucontext */
+target_mcontext_vfp_t sf_vfp; /* actual saved VFP context */
+};
+
 #endif /* !_TARGET_ARCH_SIGNAL_H_ */
-- 
2.33.1




[PULL 07/37] bsd-user/i386: Move the inlines into signal.c

2022-01-08 Thread Warner Losh
Move the (now stubbed out) inlines into bsd-user/i386/signal.c.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/i386/signal.c | 56 +-
 bsd-user/i386/target_arch_signal.h | 43 +--
 2 files changed, 63 insertions(+), 36 deletions(-)

diff --git a/bsd-user/i386/signal.c b/bsd-user/i386/signal.c
index ac903233653..2939d32400c 100644
--- a/bsd-user/i386/signal.c
+++ b/bsd-user/i386/signal.c
@@ -1 +1,55 @@
-/* Placeholder for signal.c */
+/*
+ *  i386 dependent signal definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 "qemu.h"
+
+/*
+ * Compare to i386/i386/machdep.c sendsig()
+ * Assumes that target stack frame memory is locked.
+ */
+abi_long set_sigtramp_args(CPUX86State *env, int sig,
+   struct target_sigframe *frame,
+   abi_ulong frame_addr,
+   struct target_sigaction *ka)
+{
+/* XXX return -TARGET_EOPNOTSUPP; */
+return 0;
+}
+
+/* Compare to i386/i386/machdep.c get_mcontext() */
+abi_long get_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int flags)
+{
+/* XXX */
+return -TARGET_EOPNOTSUPP;
+}
+
+/* Compare to i386/i386/machdep.c set_mcontext() */
+abi_long set_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int srflag)
+{
+/* XXX */
+return -TARGET_EOPNOTSUPP;
+}
+
+abi_long get_ucontext_sigreturn(CPUX86State *regs, abi_ulong target_sf,
+abi_ulong *target_uc)
+{
+/* XXX */
+*target_uc = 0;
+return -TARGET_EOPNOTSUPP;
+}
diff --git a/bsd-user/i386/target_arch_signal.h 
b/bsd-user/i386/target_arch_signal.h
index 701c6f964f8..982c7035c75 100644
--- a/bsd-user/i386/target_arch_signal.h
+++ b/bsd-user/i386/target_arch_signal.h
@@ -88,40 +88,13 @@ struct target_sigframe {
 uint32_t__spare__[2];
 };
 
-/*
- * Compare to i386/i386/machdep.c sendsig()
- * Assumes that target stack frame memory is locked.
- */
-static inline abi_long set_sigtramp_args(CPUX86State *regs,
-int sig, struct target_sigframe *frame, abi_ulong frame_addr,
-struct target_sigaction *ka)
-{
-/* XXX return -TARGET_EOPNOTSUPP; */
-return 0;
-}
-
-/* Compare to i386/i386/machdep.c get_mcontext() */
-static inline abi_long get_mcontext(CPUX86State *regs,
-target_mcontext_t *mcp, int flags)
-{
-/* XXX */
-return -TARGET_EOPNOTSUPP;
-}
-
-/* Compare to i386/i386/machdep.c set_mcontext() */
-static inline abi_long set_mcontext(CPUX86State *regs,
-target_mcontext_t *mcp, int srflag)
-{
-/* XXX */
-return -TARGET_EOPNOTSUPP;
-}
-
-static inline abi_long get_ucontext_sigreturn(CPUX86State *regs,
-abi_ulong target_sf, abi_ulong *target_uc)
-{
-/* XXX */
-*target_uc = 0;
-return -TARGET_EOPNOTSUPP;
-}
+abi_long set_sigtramp_args(CPUX86State *env, int sig,
+   struct target_sigframe *frame,
+   abi_ulong frame_addr,
+   struct target_sigaction *ka);
+abi_long get_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int flags);
+abi_long set_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int srflag);
+abi_long get_ucontext_sigreturn(CPUX86State *regs, abi_ulong target_sf,
+abi_ulong *target_uc);
 
 #endif /* TARGET_ARCH_SIGNAL_H */
-- 
2.33.1




[PULL 23/37] bsd-user/arm/target_arch_vmparam.h: Parameters for arm address space

2022-01-08 Thread Warner Losh
Various parameters describing the layout of the ARM address space. In
addition, define routines to get the stack pointer and to set the second
return value.

Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Reviewed-by: Kyle Evans 
Reviewed-by: Richard Henderson 
---
 bsd-user/arm/target_arch_vmparam.h | 48 ++
 1 file changed, 48 insertions(+)
 create mode 100644 bsd-user/arm/target_arch_vmparam.h

diff --git a/bsd-user/arm/target_arch_vmparam.h 
b/bsd-user/arm/target_arch_vmparam.h
new file mode 100644
index 000..4bbc04ddf5b
--- /dev/null
+++ b/bsd-user/arm/target_arch_vmparam.h
@@ -0,0 +1,48 @@
+/*
+ *  arm VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  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 _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to sys/arm/include/vmparam.h */
+#define TARGET_MAXTSIZ  (64 * MiB)   /* max text size */
+#define TARGET_DFLDSIZ  (128 * MiB)  /* initial data size limit */
+#define TARGET_MAXDSIZ  (512 * MiB)  /* max data size */
+#define TARGET_DFLSSIZ  (4 * MiB)/* initial stack size limit */
+#define TARGET_MAXSSIZ  (64 * MiB)   /* max stack size */
+#define TARGET_SGROWSIZ (128 * KiB)  /* amount to grow stack */
+
+#define TARGET_RESERVED_VA  0xf700
+
+/* KERNBASE - 512 MB */
+#define TARGET_VM_MAXUSER_ADDRESS   (0xc000 - (512 * MiB))
+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS
+
+static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
+{
+return state->regs[13]; /* sp */
+}
+
+static inline void set_second_rval(CPUARMState *state, abi_ulong retval2)
+{
+state->regs[1] = retval2;
+}
+
+#endif  /* ! _TARGET_ARCH_VMPARAM_H_ */
-- 
2.33.1




[PULL 12/37] bsd-user/target_os_signal.h: Move signal prototypes to target_os_ucontext.h

2022-01-08 Thread Warner Losh
Switch to the CPUArchState typedef and move target-provided prototypes
to target_os_ucontext.h.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_ucontext.h | 11 +++
 bsd-user/i386/target_arch_signal.h|  9 -
 bsd-user/x86_64/target_arch_signal.h  |  9 -
 3 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/bsd-user/freebsd/target_os_ucontext.h 
b/bsd-user/freebsd/target_os_ucontext.h
index 1d0c3c4e651..dd61aec7cce 100644
--- a/bsd-user/freebsd/target_os_ucontext.h
+++ b/bsd-user/freebsd/target_os_ucontext.h
@@ -32,4 +32,15 @@ G_STATIC_ASSERT(TARGET_MCONTEXT_SIZE == 
sizeof(target_mcontext_t));
 G_STATIC_ASSERT(TARGET_UCONTEXT_SIZE == sizeof(target_ucontext_t));
 #endif /* TARGET_MCONTEXT_SIZE */
 
+struct target_sigframe;
+
+abi_long set_sigtramp_args(CPUArchState *env, int sig,
+   struct target_sigframe *frame,
+   abi_ulong frame_addr,
+   struct target_sigaction *ka);
+abi_long get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags);
+abi_long set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int srflag);
+abi_long get_ucontext_sigreturn(CPUArchState *regs, abi_ulong target_sf,
+abi_ulong *target_uc);
+
 #endif /* TARGET_OS_UCONTEXT_H */
diff --git a/bsd-user/i386/target_arch_signal.h 
b/bsd-user/i386/target_arch_signal.h
index 982c7035c75..279dadc22c7 100644
--- a/bsd-user/i386/target_arch_signal.h
+++ b/bsd-user/i386/target_arch_signal.h
@@ -88,13 +88,4 @@ struct target_sigframe {
 uint32_t__spare__[2];
 };
 
-abi_long set_sigtramp_args(CPUX86State *env, int sig,
-   struct target_sigframe *frame,
-   abi_ulong frame_addr,
-   struct target_sigaction *ka);
-abi_long get_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int flags);
-abi_long set_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int srflag);
-abi_long get_ucontext_sigreturn(CPUX86State *regs, abi_ulong target_sf,
-abi_ulong *target_uc);
-
 #endif /* TARGET_ARCH_SIGNAL_H */
diff --git a/bsd-user/x86_64/target_arch_signal.h 
b/bsd-user/x86_64/target_arch_signal.h
index b39b70466ef..b4a0ebf2bd5 100644
--- a/bsd-user/x86_64/target_arch_signal.h
+++ b/bsd-user/x86_64/target_arch_signal.h
@@ -96,13 +96,4 @@ struct target_sigframe {
 uint32_t__spare__[2];
 };
 
-abi_long set_sigtramp_args(CPUX86State *env, int sig,
-   struct target_sigframe *frame,
-   abi_ulong frame_addr,
-   struct target_sigaction *ka);
-abi_long get_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int flags);
-abi_long set_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int srflag);
-abi_long get_ucontext_sigreturn(CPUX86State *regs, abi_ulong target_sf,
-abi_ulong *target_uc);
-
 #endif /* !TARGET_ARCH_SIGNAL_H_ */
-- 
2.33.1




  1   2   >