Re: [PATCH 0/2] tests/acceptance: Add tests for the PA-RISC machine

2019-10-18 Thread Sven Schnelle
Hi Philippe,
On Fri, Oct 18, 2019 at 04:23:10PM +0200, Philippe Mathieu-Daudé wrote:

> Sven since you tested this series, can I add your Tested-by tag?

Sure, please do.

> On Thu, Oct 10, 2019 at 2:21 PM Philippe Mathieu-Daudé  
> wrote:
> >
> > This tests boot a HP-UX firmware CD-ROM which allow serial
> > console interaction. This exercise the PCI LSI53C895A SCSI
> > controller.
> >
> > I'm not adding it to the Travis-CI list because I'm not sure
> > how to split/rename the current job, see:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg644753.html
> >
> > Philippe Mathieu-Daudé (2):
> >   tests/boot_console: Send  on serial lines
> >   tests/boot_console: Test booting HP-UX firmware upgrade
> >
> >  tests/acceptance/boot_linux_console.py | 27 +-
> >  1 file changed, 26 insertions(+), 1 deletion(-)

Best Regards
Sven



[Qemu-devel] [PATCH 0/2] HPPA tcg fixes

2019-09-13 Thread Sven Schnelle
Hi Richard,

here are two patches for HPPA tcg. QEMU was crashing with a tcg assert
because dead temporaries where used. This could be observed at the end·
of a HP-UX 11.11 installation, or by running the STARBASE X11 demos in
HP-UX 10.20.

Thanks,
Sven

Sven Schnelle (2):
  target/hppa: prevent trashing of temporary in trans_mtctl()
  target/hppa: prevent trashing of temporary in do_depw_sar()

 target/hppa/translate.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

-- 
2.23.0.rc1




[Qemu-devel] [PATCH 2/2] target/hppa: prevent trashing of temporary in do_depw_sar()

2019-09-13 Thread Sven Schnelle
nullify_over() calls brcond which destroys all temporaries.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index b12525d535..c1b2822f60 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3404,10 +3404,6 @@ static bool do_depw_sar(DisasContext *ctx, unsigned rt, 
unsigned c,
 TCGv_reg mask, tmp, shift, dest;
 unsigned msb = 1U << (len - 1);
 
-if (c) {
-nullify_over(ctx);
-}
-
 dest = dest_gpr(ctx, rt);
 shift = tcg_temp_new();
 tmp = tcg_temp_new();
@@ -3440,11 +3436,17 @@ static bool do_depw_sar(DisasContext *ctx, unsigned rt, 
unsigned c,
 
 static bool trans_depw_sar(DisasContext *ctx, arg_depw_sar *a)
 {
+if (a->c) {
+nullify_over(ctx);
+}
 return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_gpr(ctx, a->r));
 }
 
 static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a)
 {
+if (a->c) {
+nullify_over(ctx);
+}
 return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_const(ctx, a->i));
 }
 
-- 
2.23.0.rc1




[Qemu-devel] [PATCH 1/2] target/hppa: prevent trashing of temporary in trans_mtctl()

2019-09-13 Thread Sven Schnelle
nullify_over() calls brcond which destroys all temporaries.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 53e17d8963..b12525d535 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2214,10 +2214,11 @@ static bool trans_mtsp(DisasContext *ctx, arg_mtsp *a)
 static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
 {
 unsigned ctl = a->t;
-TCGv_reg reg = load_gpr(ctx, a->r);
+TCGv_reg reg;
 TCGv_reg tmp;
 
 if (ctl == CR_SAR) {
+reg = load_gpr(ctx, a->r);
 tmp = tcg_temp_new();
 tcg_gen_andi_reg(tmp, reg, TARGET_REGISTER_BITS - 1);
 save_or_nullify(ctx, cpu_sar, tmp);
@@ -2232,6 +2233,8 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
 
 #ifndef CONFIG_USER_ONLY
 nullify_over(ctx);
+reg = load_gpr(ctx, a->r);
+
 switch (ctl) {
 case CR_IT:
 gen_helper_write_interval_timer(cpu_env, reg);
-- 
2.23.0.rc1




Re: [Qemu-devel] [PATCH 2/2] target/hppa: prevent trashing of temporary in do_depw_sar()

2019-09-13 Thread Sven Schnelle
Hi Philippe,

On Fri, Sep 13, 2019 at 12:58:14PM +0200, Philippe Mathieu-Daudé wrote:
> Hi Sven,
> 
> On 9/13/19 12:17 PM, Sven Schnelle wrote:
> > nullify_over() calls brcond which destroys all temporaries.
> > 
> > Signed-off-by: Sven Schnelle 
> > ---
> >  target/hppa/translate.c | 10 ++
> >  1 file changed, 6 insertions(+), 4 deletions(-)
> > 
> > diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> > index b12525d535..c1b2822f60 100644
> > --- a/target/hppa/translate.c
> > +++ b/target/hppa/translate.c
> > @@ -3404,10 +3404,6 @@ static bool do_depw_sar(DisasContext *ctx, unsigned 
> > rt, unsigned c,
> >  TCGv_reg mask, tmp, shift, dest;
> >  unsigned msb = 1U << (len - 1);
> >  
> > -if (c) {
> > -nullify_over(ctx);
> > -}
> > -
> >  dest = dest_gpr(ctx, rt);
> >  shift = tcg_temp_new();
> >  tmp = tcg_temp_new();
> > @@ -3440,11 +3436,17 @@ static bool do_depw_sar(DisasContext *ctx, unsigned 
> > rt, unsigned c,
> >  
> >  static bool trans_depw_sar(DisasContext *ctx, arg_depw_sar *a)
> >  {
> > +if (a->c) {
> > +nullify_over(ctx);
> > +}
> >  return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_gpr(ctx, 
> > a->r));
> >  }
> >  
> >  static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a)
> >  {
> > +if (a->c) {
> > +nullify_over(ctx);
> > +}
> 
> I don't see how this patch helps or change anything, isn't it the same?
> You clean in the caller rather than the callee.

The Problem is that load_gpr()/load_const() allocate a temporary, which
gets destroyed in do_depw_sar() when nullify_over() is called. If we
move the nullify_over() before doing the load_gpr()/load_const() this
doesn't happen.

> >  return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_const(ctx, 
> > a->i));
> >  }
> >  
> >

Regards
Sven



Re: [Qemu-devel] [PATCH 1/5] lsi: use ldn_le_p()/stn_le_p()

2019-03-04 Thread Sven Schnelle
Hi Eric,

On Mon, Mar 04, 2019 at 12:40:50PM -0600, Eric Blake wrote:
> On 3/4/19 12:09 PM, Sven Schnelle wrote:
> > Signed-off-by: Sven Schnelle 
> 
> The commit header says "what" (good), but the commit body says nothing at
> all (generally, it should say "why"). If you give your reviewers a reason
> why it is good to use the new functions, it makes it easier to apply your
> patch.
> 
> Also, don't forget to send a 0/5 cover letter when sending a patch series;
> you can have git do this for you with 'git config format.coverletter auto'.
> https://wiki.qemu.org/Contribute/SubmitAPatch has more hints for improved
> patch handling.

Thanks, will keep this in mind, sorry. Should i resend the series?

Regards
Sven



Re: [Qemu-devel] [PATCH 2/5] lsi: use enum type for s->waiting

2019-03-04 Thread Sven Schnelle
Hi Philippe,

On Tue, Mar 05, 2019 at 12:18:01AM +0100, Philippe Mathieu-Daudé wrote:
> >  
> > +enum {
> > +LSI_NOWAIT,
> 
> You forgot the comment for NOWAIT.

I thought LSI_NOWAIT is self-explaining, but will add that.

> >  int waiting;
> 
> When a field is not used by migration, you can declare it as enum:
> 
>enum {
>LSI_NOWAIT = 0, /* SCRIPTS are running or stopped */
>LSI_WAIT_RESELECT = 1, /* Wait Reselect instruction has been
> issued */
>LSI_DMA_SCRIPTS = 2, /* processing DMA from lsi_execute_script */
>LSI_DMA_IN_PROGRESS = 3, /* DMA operation is in progress */
>} waiting;
> 
> This gives hints to the compiler about values to check.

But it is used by migration, so this doesn't apply here? I had a typedef enum 
before,
but this doesn't compile.

Otherwise thanks for reviewing.

Regards
Sven




[Qemu-devel] [PATCH v2 0/5] LSI53C895 cleanups

2019-03-05 Thread Sven Schnelle
Hi,

this series contains a few cosmetic cleanups and one small bugfix for the
LSI53C895 emulation.

Regards
Sven

Sven Schnelle (5):
  lsi: use ldn_le_p()/stn_le_p()
  lsi: use enum type for s->waiting
  lsi: use enum type for s->msg_action
  lsi: use SCSI phase names instead of numbers in trace
  lsi: return dfifo value

 hw/scsi/lsi53c895a.c | 126 +++
 hw/scsi/trace-events |   6 +--
 2 files changed, 70 insertions(+), 62 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCH v2 1/5] lsi: use ldn_le_p()/stn_le_p()

2019-03-05 Thread Sven Schnelle
Instead of using the open-coded versions, use the helper already
present as this makes the code easier to read and less error-prone.

Signed-off-by: Sven Schnelle 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/lsi53c895a.c | 24 
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 5623da8950..5f336606b9 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -289,8 +289,7 @@ typedef struct {
 uint8_t sbr;
 uint32_t adder;
 
-/* Script ram is stored as 32-bit words in host byteorder.  */
-uint32_t script_ram[2048];
+uint8_t script_ram[2048 * sizeof(uint32_t)];
 } LSIState;
 
 #define TYPE_LSI53C810  "lsi53c810"
@@ -2079,29 +2078,14 @@ static void lsi_ram_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
 LSIState *s = opaque;
-uint32_t newval;
-uint32_t mask;
-int shift;
-
-newval = s->script_ram[addr >> 2];
-shift = (addr & 3) * 8;
-mask = ((uint64_t)1 << (size * 8)) - 1;
-newval &= ~(mask << shift);
-newval |= val << shift;
-s->script_ram[addr >> 2] = newval;
+stn_le_p(s->script_ram + addr, size, val);
 }
 
 static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
  unsigned size)
 {
 LSIState *s = opaque;
-uint32_t val;
-uint32_t mask;
-
-val = s->script_ram[addr >> 2];
-mask = ((uint64_t)1 << (size * 8)) - 1;
-val >>= (addr & 3) * 8;
-return val & mask;
+return ldn_le_p(s->script_ram + addr, size);
 }
 
 static const MemoryRegionOps lsi_ram_ops = {
@@ -2244,7 +2228,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
 VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)),
 VMSTATE_UINT8(sbr, LSIState),
 
-VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 2048 * 
sizeof(uint32_t)),
+VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 8192),
 VMSTATE_END_OF_LIST()
 }
 };
-- 
2.20.1




[Qemu-devel] [PATCH v2 4/5] lsi: use SCSI phase names instead of numbers in trace

2019-03-05 Thread Sven Schnelle
This makes trace logs much easier to read, especially for
people who are not fluent in SCSI.

Signed-off-by: Sven Schnelle 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/lsi53c895a.c | 31 +++
 hw/scsi/trace-events |  6 +++---
 2 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 843fa90b39..7d66d1a870 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -306,6 +306,22 @@ typedef struct {
 #define LSI53C895A(obj) \
 OBJECT_CHECK(LSIState, (obj), TYPE_LSI53C895A)
 
+static const char *scsi_phases[] = {
+"DOUT",
+"DIN",
+"CMD",
+"STATUS",
+"RSVOUT",
+"RSVIN",
+"MSGOUT",
+"MSGIN"
+};
+
+static const char *scsi_phase_name(int phase)
+{
+return scsi_phases[phase & PHASE_MASK];
+}
+
 static inline int lsi_irq_on_rsl(LSIState *s)
 {
 return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
@@ -1201,8 +1217,9 @@ again:
 s->ia = s->dsp - 12;
 }
 if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
-trace_lsi_execute_script_blockmove_badphase(s->sstat1 & PHASE_MASK,
-(insn >> 24) & 7);
+trace_lsi_execute_script_blockmove_badphase(
+scsi_phase_name(s->sstat1),
+scsi_phase_name(insn >> 24));
 lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
 break;
 }
@@ -1234,8 +1251,8 @@ again:
 lsi_do_msgin(s);
 break;
 default:
-qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %d\n",
-  s->sstat1 & PHASE_MASK);
+qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %s\n",
+  scsi_phase_name(s->sstat1));
 }
 s->dfifo = s->dbc & 0xff;
 s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
@@ -1463,10 +1480,8 @@ again:
 cond = s->carry != 0;
 }
 if (cond == jmp && (insn & (1 << 17))) {
-trace_lsi_execute_script_tc_compp(
-(s->sstat1 & PHASE_MASK),
-jmp ? '=' : '!',
-((insn >> 24) & 7));
+trace_lsi_execute_script_tc_compp(scsi_phase_name(s->sstat1),
+jmp ? '=' : '!', scsi_phase_name(insn >> 24));
 cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
 }
 if (cond == jmp && (insn & (1 << 18))) {
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 29aaa752d1..09f3fc3086 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -268,7 +268,7 @@ lsi_memcpy(uint32_t dest, uint32_t src, int count) "memcpy 
dest 0x%"PRIx32" src
 lsi_wait_reselect(void) "Wait Reselect"
 lsi_execute_script(uint32_t dsp, uint32_t insn, uint32_t addr) "SCRIPTS 
dsp=0x%"PRIx32" opcode 0x%"PRIx32" arg 0x%"PRIx32
 lsi_execute_script_blockmove_delayed(void) "Delayed select timeout"
-lsi_execute_script_blockmove_badphase(uint8_t phase, uint8_t expected) "Wrong 
phase got %d expected %d"
+lsi_execute_script_blockmove_badphase(const char *phase, const char *expected) 
"Wrong phase got %s expected %s"
 lsi_execute_script_io_alreadyreselected(void) "Already reselected, jumping to 
alternative address"
 lsi_execute_script_io_selected(uint8_t id, const char *atn) "Selected target 
%d%s"
 lsi_execute_script_io_disconnect(void) "Wait Disconnect"
@@ -278,8 +278,8 @@ lsi_execute_script_io_opcode(const char *opcode, int reg, 
const char *opname, ui
 lsi_execute_script_tc_nop(void) "NOP"
 lsi_execute_script_tc_delayedselect_timeout(void) "Delayed select timeout"
 lsi_execute_script_tc_compc(int result) "Compare carry %d"
-lsi_execute_script_tc_compp(uint8_t phase, int op, uint8_t insn_phase) 
"Compare phase %d %c= %d"
-lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, int op, int result) 
"Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
+lsi_execute_script_tc_compp(const char *phase, char op, const char 
*insn_phase) "Compare phase %s %c= %s"
+lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, char op, int result) 
"Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
 lsi_execute_script_tc_jump(uint32_t addr) "Jump to 0x%"PRIx32
 lsi_execute_script_tc_call(uint32_t addr) "Call 0x%"PRIx32
 lsi_execute_script_tc_return(uint32_t addr) "Return to 0x%"PRIx32
-- 
2.20.1




[Qemu-devel] [PATCH v2 3/5] lsi: use enum type for s->msg_action

2019-03-05 Thread Sven Schnelle
This makes the code easier to read - no functional change.

Signed-off-by: Sven Schnelle 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/lsi53c895a.c | 27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index cafe84c85b..843fa90b39 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -201,6 +201,13 @@ enum {
 LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
 };
 
+enum {
+LSI_MSG_ACTION_COMMAND = 0,
+LSI_MSG_ACTION_DISCONNECT = 1,
+LSI_MSG_ACTION_DOUT = 2,
+LSI_MSG_ACTION_DIN = 3,
+};
+
 typedef struct {
 /*< private >*/
 PCIDevice parent_obj;
@@ -214,8 +221,6 @@ typedef struct {
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
-/* Action to take at the end of a MSG IN phase.
-   0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
 int msg_action;
 int msg_len;
 uint8_t msg[LSI_MAX_MSGIN_LEN];
@@ -323,7 +328,7 @@ static void lsi_soft_reset(LSIState *s)
 trace_lsi_reset();
 s->carry = 0;
 
-s->msg_action = 0;
+s->msg_action = LSI_MSG_ACTION_COMMAND;
 s->msg_len = 0;
 s->waiting = LSI_NOWAIT;
 s->dsa = 0;
@@ -686,7 +691,7 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
 trace_lsi_reselect(id);
 s->scntl1 |= LSI_SCNTL1_CON;
 lsi_set_phase(s, PHASE_MI);
-s->msg_action = p->out ? 2 : 3;
+s->msg_action = p->out ? LSI_MSG_ACTION_DOUT : LSI_MSG_ACTION_DIN;
 s->current->dma_len = p->pending;
 lsi_add_msg_byte(s, 0x80);
 if (s->current->tag & LSI_TAG_VALID) {
@@ -857,7 +862,7 @@ static void lsi_do_command(LSIState *s)
 lsi_add_msg_byte(s, 4); /* DISCONNECT */
 /* wait data */
 lsi_set_phase(s, PHASE_MI);
-s->msg_action = 1;
+s->msg_action = LSI_MSG_ACTION_DISCONNECT;
 lsi_queue_command(s);
 } else {
 /* wait command complete */
@@ -878,7 +883,7 @@ static void lsi_do_status(LSIState *s)
 s->sfbr = status;
 pci_dma_write(PCI_DEVICE(s), s->dnad, &status, 1);
 lsi_set_phase(s, PHASE_MI);
-s->msg_action = 1;
+s->msg_action = LSI_MSG_ACTION_DISCONNECT;
 lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
 }
 
@@ -901,16 +906,16 @@ static void lsi_do_msgin(LSIState *s)
 /* ??? Check if ATN (not yet implemented) is asserted and maybe
switch to PHASE_MO.  */
 switch (s->msg_action) {
-case 0:
+case LSI_MSG_ACTION_COMMAND:
 lsi_set_phase(s, PHASE_CMD);
 break;
-case 1:
+case LSI_MSG_ACTION_DISCONNECT:
 lsi_disconnect(s);
 break;
-case 2:
+case LSI_MSG_ACTION_DOUT:
 lsi_set_phase(s, PHASE_DO);
 break;
-case 3:
+case LSI_MSG_ACTION_DIN:
 lsi_set_phase(s, PHASE_DI);
 break;
 default:
@@ -1062,7 +1067,7 @@ bad:
 qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg);
 lsi_set_phase(s, PHASE_MI);
 lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
-s->msg_action = 0;
+s->msg_action = LSI_MSG_ACTION_COMMAND;
 }
 
 #define LSI_BUF_SIZE 4096
-- 
2.20.1




[Qemu-devel] [PATCH v2 2/5] lsi: use enum type for s->waiting

2019-03-05 Thread Sven Schnelle
This makes the code easier to read - no functional change.

Signed-off-by: Sven Schnelle 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/lsi53c895a.c | 42 +++---
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 5f336606b9..cafe84c85b 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -194,6 +194,13 @@ typedef struct lsi_request {
 QTAILQ_ENTRY(lsi_request) next;
 } lsi_request;
 
+enum {
+LSI_NOWAIT, /* SCRIPTS are running or stopped */
+LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
+LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
+LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+};
+
 typedef struct {
 /*< private >*/
 PCIDevice parent_obj;
@@ -212,10 +219,6 @@ typedef struct {
 int msg_action;
 int msg_len;
 uint8_t msg[LSI_MAX_MSGIN_LEN];
-/* 0 if SCRIPTS are running or stopped.
- * 1 if a Wait Reselect instruction has been issued.
- * 2 if processing DMA from lsi_execute_script.
- * 3 if a DMA operation is in progress.  */
 int waiting;
 SCSIBus bus;
 int current_lun;
@@ -322,7 +325,7 @@ static void lsi_soft_reset(LSIState *s)
 
 s->msg_action = 0;
 s->msg_len = 0;
-s->waiting = 0;
+s->waiting = LSI_NOWAIT;
 s->dsa = 0;
 s->dnad = 0;
 s->dbc = 0;
@@ -564,10 +567,10 @@ static void lsi_bad_phase(LSIState *s, int out, int 
new_phase)
 static void lsi_resume_script(LSIState *s)
 {
 if (s->waiting != 2) {
-s->waiting = 0;
+s->waiting = LSI_NOWAIT;
 lsi_execute_script(s);
 } else {
-s->waiting = 0;
+s->waiting = LSI_NOWAIT;
 }
 }
 
@@ -744,7 +747,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, 
uint32_t len)
Since no interrupt stacking is implemented in the emulation, it
is also required that there are no pending interrupts waiting
for service from the device driver. */
-if (s->waiting == 1 ||
+if (s->waiting == LSI_WAIT_RESELECT ||
 (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
  !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP {
 /* Reselect device.  */
@@ -789,7 +792,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t 
len)
 int out;
 
 assert(req->hba_private);
-if (s->waiting == 1 || req->hba_private != s->current ||
+if (s->waiting == LSI_WAIT_RESELECT || req->hba_private != s->current ||
 (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
 if (lsi_queue_req(s, req, len)) {
 return;
@@ -803,7 +806,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t 
len)
 s->current->dma_len = len;
 s->command_complete = 1;
 if (s->waiting) {
-if (s->waiting == 1 || s->dbc == 0) {
+if (s->waiting == LSI_WAIT_RESELECT || s->dbc == 0) {
 lsi_resume_script(s);
 } else {
 lsi_do_dma(s, out);
@@ -1093,7 +1096,7 @@ static void lsi_wait_reselect(LSIState *s)
 lsi_reselect(s, p);
 }
 if (s->current == NULL) {
-s->waiting = 1;
+s->waiting = LSI_WAIT_RESELECT;
 }
 }
 
@@ -1202,16 +1205,16 @@ again:
 s->dnad64 = addr_high;
 switch (s->sstat1 & 0x7) {
 case PHASE_DO:
-s->waiting = 2;
+s->waiting = LSI_DMA_SCRIPTS;
 lsi_do_dma(s, 1);
 if (s->waiting)
-s->waiting = 3;
+s->waiting = LSI_DMA_IN_PROGRESS;
 break;
 case PHASE_DI:
-s->waiting = 2;
+s->waiting = LSI_DMA_SCRIPTS;
 lsi_do_dma(s, 0);
 if (s->waiting)
-s->waiting = 3;
+s->waiting = LSI_DMA_IN_PROGRESS;
 break;
 case PHASE_CMD:
 lsi_do_command(s);
@@ -1278,6 +1281,7 @@ again:
 }
 s->sbcl |= LSI_SBCL_BSY;
 lsi_set_phase(s, PHASE_MO);
+s->waiting = LSI_NOWAIT;
 break;
 case 1: /* Disconnect */
 trace_lsi_execute_script_io_disconnect();
@@ -1544,7 +1548,7 @@ again:
 }
 }
 }
-if (insn_processed > 1 && !s->waiting) {
+if (insn_processed > 1 && s->waiting == LSI_NOWAIT) {
 /* Some windows drivers make the device spin waiting for a memory
location to change.  If we have been executed a lot of code then
assume this is the case and force an unexpected device disconnect.
@@ -1556,7 +1560,7 @@ again:
 }
 lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
 lsi_disconnect(s);
-} else

[Qemu-devel] [PATCH v2 5/5] lsi: return dfifo value

2019-03-05 Thread Sven Schnelle
Code was assigning DFIFO, but didn't return the value to users.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 7d66d1a870..3783779da6 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -1688,7 +1688,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
 break;
 CASE_GET_REG32(temp, 0x1c)
 case 0x20: /* DFIFO */
-ret = 0;
+ret = s->dfifo;
 break;
 case 0x21: /* CTEST4 */
 ret = s->ctest4;
-- 
2.20.1




Re: [Qemu-devel] [PATCH 1/2] lsi: 810/895A are always little endian

2019-03-08 Thread Sven Schnelle
Hi Paolo,

can you please also queue this patch? This is the last one required to get HP-UX
10.20 running in QEMU. It still needs -d nochain, but that's a different 
story...

Thanks
Sven

On Mon, Feb 18, 2019 at 06:55:28PM +0100, Sven Schnelle wrote:
> Signed-off-by: Sven Schnelle 
> ---
>  hw/scsi/lsi53c895a.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
> index bcff859bac..c493e3c4c7 100644
> --- a/hw/scsi/lsi53c895a.c
> +++ b/hw/scsi/lsi53c895a.c
> @@ -2061,14 +2061,13 @@ static uint64_t lsi_mmio_read(void *opaque, hwaddr 
> addr,
>unsigned size)
>  {
>  LSIState *s = opaque;
> -
>  return lsi_reg_readb(s, addr & 0xff);
>  }
>  
>  static const MemoryRegionOps lsi_mmio_ops = {
>  .read = lsi_mmio_read,
>  .write = lsi_mmio_write,
> -.endianness = DEVICE_NATIVE_ENDIAN,
> +.endianness = DEVICE_LITTLE_ENDIAN,
>  .impl = {
>  .min_access_size = 1,
>  .max_access_size = 1,
> @@ -2107,7 +2106,7 @@ static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
>  static const MemoryRegionOps lsi_ram_ops = {
>  .read = lsi_ram_read,
>  .write = lsi_ram_write,
> -.endianness = DEVICE_NATIVE_ENDIAN,
> +.endianness = DEVICE_LITTLE_ENDIAN,
>  };
>  
>  static uint64_t lsi_io_read(void *opaque, hwaddr addr,
> @@ -2127,7 +2126,7 @@ static void lsi_io_write(void *opaque, hwaddr addr,
>  static const MemoryRegionOps lsi_io_ops = {
>  .read = lsi_io_read,
>  .write = lsi_io_write,
> -.endianness = DEVICE_NATIVE_ENDIAN,
> +.endianness = DEVICE_LITTLE_ENDIAN,
>  .impl = {
>  .min_access_size = 1,
>  .max_access_size = 1,
> -- 
> 2.20.1
> 
> 



[Qemu-devel] [PATCH 11/11] target/hppa: call eval_interrupt() after ssm

2019-03-11 Thread Sven Schnelle
HP-UX (all versions) is losing timer interrupts, which leads to
hangs. Pressing a key on the console fixes this, so it looks like
QEMU is just looping trough TBs without checking for interrupts.
Further investion showed that this happens when interrupts are
triggered, without PSW_I enabled. Calling eval_interrupt() after
PSW_I is set seems to fix this.

Signed-off-by: Sven Schnelle 
---
 target/hppa/cpu.h| 1 +
 target/hppa/int_helper.c | 2 +-
 target/hppa/op_helper.c  | 6 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index d808796ee3..3440ccad28 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -366,5 +366,6 @@ void hppa_cpu_alarm_timer(void *);
 int hppa_artype_for_page(CPUHPPAState *env, target_ulong vaddr);
 #endif
 void QEMU_NORETURN hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t 
ra);
+void eval_interrupt(HPPACPU *cpu);
 
 #endif /* HPPA_CPU_H */
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 8d5edd3a20..e3acaa39eb 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -25,7 +25,7 @@
 #include "qom/cpu.h"
 
 #ifndef CONFIG_USER_ONLY
-static void eval_interrupt(HPPACPU *cpu)
+void eval_interrupt(HPPACPU *cpu)
 {
 CPUState *cs = CPU(cpu);
 if (cpu->env.cr[CR_EIRR] & cpu->env.cr[CR_EIEM]) {
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index a55a5dfc02..f93211c84f 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -662,6 +662,7 @@ void HELPER(reset)(CPUHPPAState *env)
 
 target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm)
 {
+HPPACPU *cpu = hppa_env_get_cpu(env);
 target_ulong psw = env->psw;
 /*
  * Setting the PSW Q bit to 1, if it was not already 1, is an
@@ -673,6 +674,11 @@ target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, 
target_ureg nsm)
  * so let this go without comment.
  */
 env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM);
+if (!(psw & PSW_I) && (nsm & PSW_I)) {
+qemu_mutex_lock_iothread();
+eval_interrupt(cpu);
+qemu_mutex_unlock_iothread();
+}
 return psw & PSW_SM;
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH 06/11] target/hppa: ignore DIAG opcode

2019-03-11 Thread Sven Schnelle
DIAG is usually only used by diagnostics software as it's CPU
specific. In most of the cases it's better to ignore it and log
a message that it's not implemented.

Signed-off-by: Sven Schnelle 
---
 target/hppa/insns.decode | 3 +++
 target/hppa/translate.c  | 6 ++
 2 files changed, 9 insertions(+)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 55ff39dd05..098370c2f0 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -525,3 +525,6 @@ fmpy_d  001110 . . 010 . ... .  
@f0e_d_3
 fdiv_d  001110 . . 011 . ... .  @f0e_d_3
 
 xmpyu   001110 . . 010 .0111 .00 t:5r1=%ra64 r2=%rb64
+
+# diag
+diag000101 - -    
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7001c2eb80..441f0ea9d6 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -4292,3 +4292,9 @@ void restore_state_to_opc(CPUHPPAState *env, 
TranslationBlock *tb,
that the instruction was not nullified.  */
 env->psw_n = 0;
 }
+
+static bool trans_diag(DisasContext *ctx, arg_diag *a)
+{
+qemu_log_mask(LOG_UNIMP, "DIAG opcode ignored\n");
+return true;
+}
-- 
2.20.1




[Qemu-devel] [PATCH 05/11] target/hppa: remove PSW I/R/Q bit check

2019-03-11 Thread Sven Schnelle
HP ODE use rfi to set the Q bit, and i don't see anything in the
documentation that this is forbidden. So remove it.

Signed-off-by: Sven Schnelle 
---
 target/hppa/op_helper.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index a05681d480..a55a5dfc02 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -678,11 +678,6 @@ target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, 
target_ureg nsm)
 
 void HELPER(rfi)(CPUHPPAState *env)
 {
-/* ??? On second reading this condition simply seems
-   to be undefined rather than a diagnosed trap.  */
-if (env->psw & (PSW_I | PSW_R | PSW_Q)) {
-helper_excp(env, EXCP_ILL);
-}
 env->iasq_f = (uint64_t)env->cr[CR_IIASQ] << 32;
 env->iasq_b = (uint64_t)env->cr_back[0] << 32;
 env->iaoq_f = env->cr[CR_IIAOQ];
-- 
2.20.1




[Qemu-devel] [PATCH 09/11] target/hppa: add TLB protection id check

2019-03-11 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/cpu.h|  4 
 target/hppa/mem_helper.c | 28 ++--
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 861bbb1f16..d808796ee3 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -143,6 +143,10 @@
 #endif
 
 #define CR_RC0
+#define CR_PID1  8
+#define CR_PID2  9
+#define CR_PID3  12
+#define CR_PID4  13
 #define CR_SCRCCR10
 #define CR_SAR   11
 #define CR_IVA   14
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index fc1b6a4fcd..a52d691d15 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -85,7 +85,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, 
int mmu_idx,
   int type, hwaddr *pphys, int *pprot)
 {
 hwaddr phys;
-int prot, r_prot, w_prot, x_prot;
+int prot, r_prot, w_prot, x_prot, wd;
 hppa_tlb_entry *ent;
 int ret = -1;
 
@@ -130,7 +130,31 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr 
addr, int mmu_idx,
 break;
 }
 
-/* ??? Check PSW_P and ent->access_prot.  This can remove PAGE_WRITE.  */
+/* access_id == 0 means public page and no check is performed */
+if ((env->psw & PSW_P) && ent->access_id) {
+wd = 1;
+
+if (ent->access_id == (env->cr[CR_PID1] >> 1)) {
+wd &= env->cr[CR_PID1];
+}
+
+if (ent->access_id == (env->cr[CR_PID2] >> 1)) {
+wd &= env->cr[CR_PID2];
+}
+
+if (ent->access_id == (env->cr[CR_PID3] >> 1)) {
+wd &= env->cr[CR_PID3];
+}
+
+if (ent->access_id == (env->cr[CR_PID4] >> 1)) {
+wd &= env->cr[CR_PID4];
+}
+
+if (wd && (type & w_prot)) {
+ret = EXCP_DMPI;
+goto egress;
+}
+}
 
 /* No guest access type indicates a non-architectural access from
within QEMU.  Bypass checks for access, D, B and T bits.  */
-- 
2.20.1




[Qemu-devel] [PATCH 00/11] target/hppa patches

2019-03-11 Thread Sven Schnelle
Hi Richard,

here are a few fixes for the HPPA architecture. Some fixes for
problems reported by diagnostics software, some TLB fixes to make
HP-UX 10.20 work with TB chaining in QEMU. I'm not sure whether the
'call eval_interrupt() after ssm' fix is really the right way - please
check.

I haven't seen any problems with these HP-UX 10.20 anymore, and Linux also
still works.

Thanks
Sven

Sven Schnelle (11):
  target/hppa: fix overwriting source reg in addb
  target/hppa: fix TLB handling for page 0
  target/hppa: report ITLB_EXCP_MISS for ITLB misses
  target/hppa: add TLB trace events
  target/hppa: remove PSW I/R/Q bit check
  target/hppa: ignore DIAG opcode
  target/hppa: fix b,gate instruction
  target/hppa: allow multiple itlbp without itlba
  target/hppa: add TLB protection id check
  target/hppa: exit TB if either Data or Instruction TLB changes
  target/hppa: call eval_interrupt() after ssm

 Makefile.objs|  1 +
 target/hppa/cpu.h|  5 +++
 target/hppa/insns.decode |  3 ++
 target/hppa/int_helper.c |  2 +-
 target/hppa/mem_helper.c | 68 +++-
 target/hppa/op_helper.c  | 13 +---
 target/hppa/trace-events | 18 +++
 target/hppa/translate.c  | 23 +-
 8 files changed, 106 insertions(+), 27 deletions(-)
 create mode 100644 target/hppa/trace-events

-- 
2.20.1




[Qemu-devel] [PATCH 07/11] target/hppa: fix b,gate instruction

2019-03-11 Thread Sven Schnelle
b,gate does GR[t] ← cat(GR[t]{0..29},IAOQ_Front{30..31});
instead of saving the link address to register t.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 441f0ea9d6..a393a12252 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3464,6 +3464,7 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a)
 }
 
 #ifndef CONFIG_USER_ONLY
+TCGv_reg tmp;
 if (ctx->tb_flags & PSW_C) {
 CPUHPPAState *env = ctx->cs->env_ptr;
 int type = hppa_artype_for_page(env, ctx->base.pc_next);
@@ -3480,12 +3481,13 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate 
*a)
 if (type >= 4 && type - 4 < ctx->privilege) {
 dest = deposit32(dest, 0, 2, type - 4);
 }
+tmp = dest_gpr(ctx, a->l);
+tcg_gen_deposit_reg(tmp, tmp, cpu_iaoq_f, 0, 2);
 } else {
 dest &= -4;  /* priv = 0 */
 }
 #endif
-
-return do_dbranch(ctx, dest, a->l, a->n);
+return do_dbranch(ctx, dest, 0, a->n);
 }
 
 static bool trans_blr(DisasContext *ctx, arg_blr *a)
-- 
2.20.1




[Qemu-devel] [PATCH 10/11] target/hppa: exit TB if either Data or Instruction TLB changes

2019-03-11 Thread Sven Schnelle
The current code assumes that we don't need to exit the TB
if a Data Cache Flush or Insert has happend. However, as we
have a shared Data/Instruction TLB, a Data cache flush also
flushes Instruction TLB entries, and a Data cache TLB insert
might also evict a Instruction TLB entry.

So exit the TB in all cases if Instruction translation is enabled.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index a393a12252..fcacff963e 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2474,9 +2474,8 @@ static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a)
 gen_helper_itlbp(cpu_env, addr, reg);
 }
 
-/* Exit TB for ITLB change if mmu is enabled.  This *should* not be
-   the case, since the OS TLB fill handler runs with mmu disabled.  */
-if (!a->data && (ctx->tb_flags & PSW_C)) {
+/* Exit TB for TLB change if mmu is enabled.  */
+if (ctx->tb_flags & PSW_C) {
 ctx->base.is_jmp = DISAS_IAQ_N_STALE;
 }
 return nullify_end(ctx);
@@ -2503,7 +2502,7 @@ static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a)
 }
 
 /* Exit TB for TLB change if mmu is enabled.  */
-if (!a->data && (ctx->tb_flags & PSW_C)) {
+if (ctx->tb_flags & PSW_C) {
 ctx->base.is_jmp = DISAS_IAQ_N_STALE;
 }
 return nullify_end(ctx);
-- 
2.20.1




[Qemu-devel] [PATCH 03/11] target/hppa: report ITLB_EXCP_MISS for ITLB misses

2019-03-11 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/mem_helper.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index f30824f4e1..07ecfaf092 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -96,9 +96,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, 
int mmu_idx,
 if (ent == NULL || !ent->entry_valid) {
 phys = 0;
 prot = 0;
-/* ??? Unconditionally report data tlb miss,
-   even if this is an instruction fetch.  */
-ret = EXCP_DTLB_MISS;
+ret = (type == PAGE_EXEC) ? EXCP_ITLB_MISS : EXCP_DTLB_MISS;
 goto egress;
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH 04/11] target/hppa: add TLB trace events

2019-03-11 Thread Sven Schnelle
To ease TLB debugging add a few trace events, which are disabled
by default so that there's no performance impact.

Signed-off-by: Sven Schnelle 
---
 Makefile.objs|  1 +
 target/hppa/mem_helper.c | 20 ++--
 target/hppa/op_helper.c  |  2 ++
 target/hppa/trace-events | 18 ++
 4 files changed, 39 insertions(+), 2 deletions(-)
 create mode 100644 target/hppa/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index ef65a6c12e..4df63e1633 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -183,6 +183,7 @@ trace-events-subdirs += qapi
 trace-events-subdirs += qom
 trace-events-subdirs += scsi
 trace-events-subdirs += target/arm
+trace-events-subdirs += target/hppa
 trace-events-subdirs += target/i386
 trace-events-subdirs += target/mips
 trace-events-subdirs += target/ppc
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 07ecfaf092..26da953185 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -22,6 +22,7 @@
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "qom/cpu.h"
+#include "trace.h"
 
 #ifdef CONFIG_USER_ONLY
 int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
@@ -43,9 +44,11 @@ static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, 
vaddr addr)
 for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
 hppa_tlb_entry *ent = &env->tlb[i];
 if (ent->va_b <= addr && addr <= ent->va_e) {
+trace_hppa_tlb_find_entry(env, ent + i, ent->entry_valid, 
ent->va_b, ent->va_e, ent->pa);
 return ent;
 }
 }
+trace_hppa_tlb_find_entry_not_found(env, addr);
 return NULL;
 }
 
@@ -55,6 +58,8 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
hppa_tlb_entry *ent)
 unsigned i, n = 1 << (2 * ent->page_size);
 uint64_t addr = ent->va_b;
 
+trace_hppa_tlb_flush_ent(env, ent, ent->va_b, ent->va_e, ent->pa);
+
 for (i = 0; i < n; ++i, addr += TARGET_PAGE_SIZE) {
 /* Do not flush MMU_PHYS_IDX.  */
 tlb_flush_page_by_mmuidx(cs, addr, 0xf);
@@ -169,6 +174,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr 
addr, int mmu_idx,
  egress:
 *pphys = phys;
 *pprot = prot;
+trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys);
 return ret;
 }
 
@@ -198,6 +204,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
   MMUAccessType type, int mmu_idx, uintptr_t retaddr)
 {
 HPPACPU *cpu = HPPA_CPU(cs);
+CPUHPPAState *env = &cpu->env;
 int prot, excp, a_prot;
 hwaddr phys;
 
@@ -213,9 +220,10 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
 break;
 }
 
-excp = hppa_get_physical_address(&cpu->env, addr, mmu_idx,
+excp = hppa_get_physical_address(env, addr, mmu_idx,
  a_prot, &phys, &prot);
 if (unlikely(excp >= 0)) {
+trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);
 /* Failure.  Raise the indicated exception.  */
 cs->exception_index = excp;
 if (cpu->env.psw & PSW_Q) {
@@ -226,6 +234,8 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
 cpu_loop_exit_restore(cs, retaddr);
 }
 
+trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK,
+phys & TARGET_PAGE_MASK, size, type, mmu_idx);
 /* Success!  Store the translation into the QEMU TLB.  */
 tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK,
  prot, mmu_idx, TARGET_PAGE_SIZE);
@@ -259,6 +269,7 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 empty->va_b = addr & TARGET_PAGE_MASK;
 empty->va_e = empty->va_b + TARGET_PAGE_SIZE - 1;
 empty->pa = extract32(reg, 5, 20) << TARGET_PAGE_BITS;
+trace_hppa_tlb_itlba(env, empty, empty->va_b, empty->va_e, empty->pa);
 }
 
 /* Insert (Insn/Data) TLB Protection.  Note this is PA 1.1 only.  */
@@ -280,6 +291,8 @@ void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 ent->d = extract32(reg, 28, 1);
 ent->t = extract32(reg, 29, 1);
 ent->entry_valid = 1;
+trace_hppa_tlb_itlbp(env, ent, ent->access_id, ent->u, ent->ar_pl2,
+ ent->ar_pl1, ent->ar_type, ent->b, ent->d, ent->t);
 }
 
 /* Purge (Insn/Data) TLB.  This is explicitly page-based, and is
@@ -299,6 +312,7 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
 {
 CPUState *src = CPU(hppa_env_get_cpu(env));
 CPUState *cpu;
+trace_hppa_tlb_ptlb(env);
 run_on_cpu_data data = RUN_ON_CPU_TARGET_PTR(addr);
 
 CPU_FOREACH(cpu) {
@@ -314,7 +328,7 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
 void HELPER(ptlbe)(CPUHPPAState *env)
 {
 CPUState *src = CPU(hppa_env_get_

[Qemu-devel] [PATCH 01/11] target/hppa: fix overwriting source reg in addb

2019-03-11 Thread Sven Schnelle
When one of the source registers is the same as the destination register,
the source register gets overwritten with the destionation value before
do_add_sv() is called, which leads to unexpection condition matches.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index dc5636fe94..7001c2eb80 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3033,7 +3033,7 @@ static bool do_addb(DisasContext *ctx, unsigned r, 
TCGv_reg in1,
 DisasCond cond;
 
 in2 = load_gpr(ctx, r);
-dest = dest_gpr(ctx, r);
+dest = tcg_temp_new();
 sv = NULL;
 cb_msb = NULL;
 
@@ -3049,6 +3049,8 @@ static bool do_addb(DisasContext *ctx, unsigned r, 
TCGv_reg in1,
 }
 
 cond = do_cond(c * 2 + f, dest, cb_msb, sv);
+save_gpr(ctx, r, dest);
+tcg_temp_free(dest);
 return do_cbranch(ctx, disp, n, &cond);
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH 02/11] target/hppa: fix TLB handling for page 0

2019-03-11 Thread Sven Schnelle
Assume the following sequence:

pitlbe r0(sr0,r0)
iitlba r4,(sr0,r0)
ldil L%300,r5
iitlbp r5,(sr0,r0)

This will purge the whole TLB and add an entry for page 0. However
the current TLB implementation in helper_iitlba() will store to
the last empty TLB entry, while helper_iitlbp() will write to the
first empty entry. That is because an empty entry will match address
0 in helper_iitlba()

Signed-off-by: Sven Schnelle 
---
 target/hppa/mem_helper.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index aecf3075f6..f30824f4e1 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -238,15 +238,17 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 {
 hppa_tlb_entry *empty = NULL;
 int i;
-
 /* Zap any old entries covering ADDR; notice empty entries on the way.  */
 for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
 hppa_tlb_entry *ent = &env->tlb[i];
-if (!ent->entry_valid) {
-empty = ent;
-} else if (ent->va_b <= addr && addr <= ent->va_e) {
-hppa_flush_tlb_ent(env, ent);
-empty = ent;
+if (ent->va_b <= addr && addr <= ent->va_e) {
+if (ent->entry_valid) {
+hppa_flush_tlb_ent(env, ent);
+}
+
+if (!empty) {
+empty = ent;
+}
 }
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH 08/11] target/hppa: allow multiple itlbp without itlba

2019-03-11 Thread Sven Schnelle
The ODE software calls itlbp on existing TLB entries without
calling itlba first, so this seems to be valid.

Signed-off-by: Sven Schnelle 
---
 target/hppa/mem_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 26da953185..fc1b6a4fcd 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -277,7 +277,7 @@ void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, 
target_ureg reg)
 {
 hppa_tlb_entry *ent = hppa_find_tlb(env, addr);
 
-if (unlikely(ent == NULL || ent->entry_valid)) {
+if (unlikely(ent == NULL)) {
 qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n");
 return;
 }
-- 
2.20.1




Re: [Qemu-devel] [PATCH 11/11] target/hppa: call eval_interrupt() after ssm

2019-03-12 Thread Sven Schnelle
Hi Richard,

On Mon, Mar 11, 2019 at 09:01:32PM -0700, Richard Henderson wrote:
> On 3/11/19 8:28 PM, Richard Henderson wrote:
> > On 3/11/19 12:16 PM, Sven Schnelle wrote:
> >> HP-UX (all versions) is losing timer interrupts, which leads to
> >> hangs. Pressing a key on the console fixes this, so it looks like
> >> QEMU is just looping trough TBs without checking for interrupts.
> >> Further investion showed that this happens when interrupts are
> >> triggered, without PSW_I enabled. Calling eval_interrupt() after
> >> PSW_I is set seems to fix this.
> >>
> >> Signed-off-by: Sven Schnelle 
> >> ---
> >>  target/hppa/cpu.h| 1 +
> >>  target/hppa/int_helper.c | 2 +-
> >>  target/hppa/op_helper.c  | 6 ++
> >>  3 files changed, 8 insertions(+), 1 deletion(-)
> > 
> > The correct fix is to exit to the main loop.
> 
> ... except what we're already doing that.  So I don't see what
> can be changed to help.  This doesn't seem to make a difference.

I looked into this again, and with my limited TCG knowledge it looks like the
exit_tb is not happening because ssm is called in a branch delay slot:

This is the TB it's calling when it looses the timer interrupt:

IN: 
0x00045758:  bv r0(rp)
0x0004575c:  ssm 1,r0

OP:
 ld_i32 tmp0,env,$0xffe0
 movi_i32 tmp1,$0x0
 brcond_i32 tmp0,tmp1,lt,$L0

  00045758 0004575c
 mov_i32 tmp0,r2
 mov_i32 iaoq_b,tmp0

  0004575c 
 movi_i32 tmp1,$0x4
 add_i32 tmp0,iaoq_b,tmp1
 ld_i32 tmp1,env,$0x1c0
 movi_i32 tmp2,$0x1
 or_i32 tmp1,tmp1,tmp2
 call swap_system_mask,$0x1,$1,tmp1,env,tmp1

Everything above is ssm, and below this is the branch instruction, which skips
the exit_tb (i think):

 mov_i32 iaoq_f,iaoq_b
 mov_i32 iaoq_b,tmp0
 mov_i64 iasq_f,iasq_b
 call lookup_tb_ptr,$0x6,$1,tmp3,env
 goto_ptr tmp3
 set_label $L0
 exit_tb $0x7f373c33cb83

I might also be totally wrong, let me know if that's the case. ;-)

Regards
Sven



Re: [Qemu-devel] [PATCH] target/hppa: Avoid squishing DISAS_IAQ_N_STALE_EXIT

2019-03-12 Thread Sven Schnelle
On Tue, Mar 12, 2019 at 03:49:23PM -0700, Richard Henderson wrote:
> Within a delay slot, we were squishing both DISAS_IAQ_N_STALE and
> DISAS_IAQ_N_STALE_EXIT to DISAS_IAQ_N_UPDATED.  This lost the
> required exit to the main loop, and could result in interrupts
> never being delivered.
> 
> Reported-by: Sven Schnelle 
> Signed-off-by: Richard Henderson 
> ---
> 
> Sven, this should be a better fix for your 11/11.

Indeed, much better.

Tested-by: Sven Schnelle 

Thanks
Sven



Re: [Qemu-devel] [PATCH v2] hw/hppa/dino: mask out lower 2 bits of PCI config addr

2019-02-21 Thread Sven Schnelle
Hi Richard,

On Wed, Feb 20, 2019 at 10:57:50AM -0800, Richard Henderson wrote:

> Can you re-test with the following?
> 
> If the stores are all aligned, then the reads to not need to re-align.
> Also, partial writes to the config register don't make much sense.
> Over in hw/pci/pci_host.c, we check addr == 0 && len == 4, which is a
> very old fashioned way to do the .valid thing.

With your proposed change it works as well - should i send a v2 or will you
take care of updating the patch?

Thanks
Sven



Re: [Qemu-devel] [PATCH v2] lsi: implement basic SBCL functionality

2019-03-04 Thread Sven Schnelle
Hi All,

is this patch going to be accepted?

Thanks
Sven

On Fri, Feb 15, 2019 at 08:40:21PM +0100, Sven Schnelle wrote:
> HP-UX checks this register after sending data to the target. If there's no 
> valid
> information present, it assumes the client disconnected because the kernel 
> sent
> to much data. Implement at least some of the SBCL functionality that is 
> possible
> without having a real SCSI bus.
> 
> Signed-off-by: Sven Schnelle 
> ---
>  hw/scsi/lsi53c895a.c | 31 +++
>  1 file changed, 27 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
> index 89def1421f..8ba07f8756 100644
> --- a/hw/scsi/lsi53c895a.c
> +++ b/hw/scsi/lsi53c895a.c
> @@ -160,6 +160,11 @@ static const char *names[] = {
>  #define LSI_CCNTL1_DDAC  0x08
>  #define LSI_CCNTL1_ZMOD  0x80
>  
> +#define LSI_SBCL_ATN 0x08
> +#define LSI_SBCL_BSY 0x20
> +#define LSI_SBCL_ACK 0x40
> +#define LSI_SBCL_REQ 0x80
> +
>  /* Enable Response to Reselection */
>  #define LSI_SCID_RRE  0x60
>  
> @@ -258,6 +263,7 @@ typedef struct {
>  uint8_t sdid;
>  uint8_t ssid;
>  uint8_t sfbr;
> +uint8_t sbcl;
>  uint8_t stest1;
>  uint8_t stest2;
>  uint8_t stest3;
> @@ -356,6 +362,7 @@ static void lsi_soft_reset(LSIState *s)
>  s->socl = 0;
>  s->sdid = 0;
>  s->ssid = 0;
> +s->sbcl = 0;
>  s->stest1 = 0;
>  s->stest2 = 0;
>  s->stest3 = 0;
> @@ -530,6 +537,8 @@ static void lsi_script_dma_interrupt(LSIState *s, int 
> stat)
>  
>  static inline void lsi_set_phase(LSIState *s, int phase)
>  {
> +s->sbcl &= ~PHASE_MASK;
> +s->sbcl |= phase | LSI_SBCL_REQ;
>  s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
>  }
>  
> @@ -567,6 +576,7 @@ static void lsi_disconnect(LSIState *s)
>  {
>  s->scntl1 &= ~LSI_SCNTL1_CON;
>  s->sstat1 &= ~PHASE_MASK;
> +s->sbcl = 0;
>  }
>  
>  static void lsi_bad_selection(LSIState *s, uint32_t id)
> @@ -1265,7 +1275,9 @@ again:
>  s->scntl1 |= LSI_SCNTL1_CON;
>  if (insn & (1 << 3)) {
>  s->socl |= LSI_SOCL_ATN;
> +s->sbcl |= LSI_SBCL_ATN;
>  }
> +s->sbcl |= LSI_SBCL_BSY;
>  lsi_set_phase(s, PHASE_MO);
>  break;
>  case 1: /* Disconnect */
> @@ -1297,8 +1309,14 @@ again:
>  insn & (1 << 10) ? " CC" : "");
>  if (insn & (1 << 3)) {
>  s->socl |= LSI_SOCL_ATN;
> +s->sbcl |= LSI_SBCL_ATN;
>  lsi_set_phase(s, PHASE_MO);
>  }
> +
> +if (insn & (1 << 6)) {
> +s->sbcl |= LSI_SBCL_ACK;
> +}
> +
>  if (insn & (1 << 9)) {
>  qemu_log_mask(LOG_UNIMP,
>  "lsi_scsi: Target mode not implemented\n");
> @@ -1314,7 +1332,13 @@ again:
>  insn & (1 << 10) ? " CC" : "");
>  if (insn & (1 << 3)) {
>  s->socl &= ~LSI_SOCL_ATN;
> +s->sbcl &= ~LSI_SBCL_ATN;
>  }
> +
> +if (insn & (1 << 6)) {
> +s->sbcl &= ~LSI_SBCL_ACK;
> +}
> +
>  if (insn & (1 << 10))
>  s->carry = 0;
>  break;
> @@ -1591,9 +1615,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
>  ret = s->ssid;
>  break;
>  case 0xb: /* SBCL */
> -/* ??? This is not correct. However it's (hopefully) only
> -   used for diagnostics, so should be ok.  */
> -ret = 0;
> +ret = s->sbcl;
>  break;
>  case 0xc: /* DSTAT */
>  ret = s->dstat | LSI_DSTAT_DFE;
> @@ -2143,7 +2165,7 @@ static int lsi_post_load(void *opaque, int version_id)
>  
>  static const VMStateDescription vmstate_lsi_scsi = {
>  .name = "lsiscsi",
> -.version_id = 0,
> +.version_id = 1,
>  .minimum_version_id = 0,
>  .pre_save = lsi_pre_save,
>  .post_load = lsi_post_load,
> @@ -2202,6 +2224,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
>  VMSTATE_UINT8(stime0, LSIState),
>  VMSTATE_UINT8(respid0, LSIState),
>  VMSTATE_UINT8(respid1, LSIState),
> +VMSTATE_UINT8_V(sbcl, LSIState, 1),
>  VMSTATE_UINT32(mmrs, LSIState),
>  VMSTATE_UINT32(mmws, LSIState),
>  VMSTATE_UINT32(sfs, LSIState),
> -- 
> 2.20.1
> 
> 



Re: [Qemu-devel] [PATCH] lsi: check if SIGP bit is already set in Wait reselect

2019-03-04 Thread Sven Schnelle
Hi List,

is this patch going to be accepted?

Thanks
Sven

On Sun, Feb 17, 2019 at 12:37:17PM +0100, Sven Schnelle wrote:
> If SIGP is set, the 'Wait for Reselection' command should jump
> immediately to the address stored in the second DWORD of the
> instruction. This fixes spurious hangs in the HP-UX 11.11
> installer when the SIGP bit gets set by the kernel before the
> 'Wait for Reselection' command is executed by SCRIPTS.
> 
> Signed-off-by: Sven Schnelle 
> Tested-by: Helge Deller 
> ---
>  hw/scsi/lsi53c895a.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
> index 8ba07f8756..bcff859bac 100644
> --- a/hw/scsi/lsi53c895a.c
> +++ b/hw/scsi/lsi53c895a.c
> @@ -1297,8 +1297,10 @@ again:
>  }
>  break;
>  case 2: /* Wait Reselect */
> -if (!lsi_irq_on_rsl(s)) {
> -lsi_wait_reselect(s);
> +if (s->istat0 & LSI_ISTAT0_SIGP) {
> +s->dsp = s->dnad;
> +} else if (!lsi_irq_on_rsl(s)) {
> +lsi_wait_reselect(s);
>  }
>  break;
>  case 3: /* Set */
> -- 
> 2.20.1
> 
> 



[Qemu-devel] [PATCH 1/5] lsi: use ldn_le_p()/stn_le_p()

2019-03-04 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 24 
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 25c6926039..6d280f8b77 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -289,8 +289,7 @@ typedef struct {
 uint8_t sbr;
 uint32_t adder;
 
-/* Script ram is stored as 32-bit words in host byteorder.  */
-uint32_t script_ram[2048];
+uint8_t script_ram[8192];
 } LSIState;
 
 #define TYPE_LSI53C810  "lsi53c810"
@@ -2077,29 +2076,14 @@ static void lsi_ram_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
 LSIState *s = opaque;
-uint32_t newval;
-uint32_t mask;
-int shift;
-
-newval = s->script_ram[addr >> 2];
-shift = (addr & 3) * 8;
-mask = ((uint64_t)1 << (size * 8)) - 1;
-newval &= ~(mask << shift);
-newval |= val << shift;
-s->script_ram[addr >> 2] = newval;
+stn_le_p(s->script_ram + addr, size, val);
 }
 
 static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
  unsigned size)
 {
 LSIState *s = opaque;
-uint32_t val;
-uint32_t mask;
-
-val = s->script_ram[addr >> 2];
-mask = ((uint64_t)1 << (size * 8)) - 1;
-val >>= (addr & 3) * 8;
-return val & mask;
+return ldn_le_p(s->script_ram + addr, size);
 }
 
 static const MemoryRegionOps lsi_ram_ops = {
@@ -2242,7 +2226,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
 VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)),
 VMSTATE_UINT8(sbr, LSIState),
 
-VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 2048 * 
sizeof(uint32_t)),
+VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 8192),
 VMSTATE_END_OF_LIST()
 }
 };
-- 
2.20.1




[Qemu-devel] [PATCH 2/5] lsi: use enum type for s->waiting

2019-03-04 Thread Sven Schnelle
This makes the code easier to read - no functional change.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 42 +++---
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 6d280f8b77..fb9c6db4b2 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -194,6 +194,13 @@ typedef struct lsi_request {
 QTAILQ_ENTRY(lsi_request) next;
 } lsi_request;
 
+enum {
+LSI_NOWAIT,
+LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
+LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
+LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+};
+
 typedef struct {
 /*< private >*/
 PCIDevice parent_obj;
@@ -212,10 +219,6 @@ typedef struct {
 int msg_action;
 int msg_len;
 uint8_t msg[LSI_MAX_MSGIN_LEN];
-/* 0 if SCRIPTS are running or stopped.
- * 1 if a Wait Reselect instruction has been issued.
- * 2 if processing DMA from lsi_execute_script.
- * 3 if a DMA operation is in progress.  */
 int waiting;
 SCSIBus bus;
 int current_lun;
@@ -322,7 +325,7 @@ static void lsi_soft_reset(LSIState *s)
 
 s->msg_action = 0;
 s->msg_len = 0;
-s->waiting = 0;
+s->waiting = LSI_NOWAIT;
 s->dsa = 0;
 s->dnad = 0;
 s->dbc = 0;
@@ -564,10 +567,10 @@ static void lsi_bad_phase(LSIState *s, int out, int 
new_phase)
 static void lsi_resume_script(LSIState *s)
 {
 if (s->waiting != 2) {
-s->waiting = 0;
+s->waiting = LSI_NOWAIT;
 lsi_execute_script(s);
 } else {
-s->waiting = 0;
+s->waiting = LSI_NOWAIT;
 }
 }
 
@@ -744,7 +747,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, 
uint32_t len)
Since no interrupt stacking is implemented in the emulation, it
is also required that there are no pending interrupts waiting
for service from the device driver. */
-if (s->waiting == 1 ||
+if (s->waiting == LSI_WAIT_RESELECT ||
 (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
  !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP {
 /* Reselect device.  */
@@ -789,7 +792,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t 
len)
 int out;
 
 assert(req->hba_private);
-if (s->waiting == 1 || req->hba_private != s->current ||
+if (s->waiting == LSI_WAIT_RESELECT || req->hba_private != s->current ||
 (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
 if (lsi_queue_req(s, req, len)) {
 return;
@@ -803,7 +806,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t 
len)
 s->current->dma_len = len;
 s->command_complete = 1;
 if (s->waiting) {
-if (s->waiting == 1 || s->dbc == 0) {
+if (s->waiting == LSI_WAIT_RESELECT || s->dbc == 0) {
 lsi_resume_script(s);
 } else {
 lsi_do_dma(s, out);
@@ -1093,7 +1096,7 @@ static void lsi_wait_reselect(LSIState *s)
 lsi_reselect(s, p);
 }
 if (s->current == NULL) {
-s->waiting = 1;
+s->waiting = LSI_WAIT_RESELECT;
 }
 }
 
@@ -1202,16 +1205,16 @@ again:
 s->dnad64 = addr_high;
 switch (s->sstat1 & 0x7) {
 case PHASE_DO:
-s->waiting = 2;
+s->waiting = LSI_DMA_SCRIPTS;
 lsi_do_dma(s, 1);
 if (s->waiting)
-s->waiting = 3;
+s->waiting = LSI_DMA_IN_PROGRESS;
 break;
 case PHASE_DI:
-s->waiting = 2;
+s->waiting = LSI_DMA_SCRIPTS;
 lsi_do_dma(s, 0);
 if (s->waiting)
-s->waiting = 3;
+s->waiting = LSI_DMA_IN_PROGRESS;
 break;
 case PHASE_CMD:
 lsi_do_command(s);
@@ -1278,6 +1281,7 @@ again:
 }
 s->sbcl |= LSI_SBCL_BSY;
 lsi_set_phase(s, PHASE_MO);
+s->waiting = LSI_NOWAIT;
 break;
 case 1: /* Disconnect */
 trace_lsi_execute_script_io_disconnect();
@@ -1542,7 +1546,7 @@ again:
 }
 }
 }
-if (insn_processed > 1 && !s->waiting) {
+if (insn_processed > 1 && s->waiting == LSI_NOWAIT) {
 /* Some windows drivers make the device spin waiting for a memory
location to change.  If we have been executed a lot of code then
assume this is the case and force an unexpected device disconnect.
@@ -1554,7 +1558,7 @@ again:
 }
 lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
 lsi_disconnect(s);
-} else if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
+} else if (s

[Qemu-devel] [PATCH 3/5] lsi: use enum type for s->msg_action

2019-03-04 Thread Sven Schnelle
This makes the code easier to read - no functional change.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index fb9c6db4b2..d1eb2cf074 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -201,6 +201,13 @@ enum {
 LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
 };
 
+enum {
+LSI_MSG_ACTION_COMMAND,
+LSI_MSG_ACTION_DISCONNECT,
+LSI_MSG_ACTION_DOUT,
+LSI_MSG_ACTION_DIN,
+};
+
 typedef struct {
 /*< private >*/
 PCIDevice parent_obj;
@@ -214,8 +221,6 @@ typedef struct {
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
-/* Action to take at the end of a MSG IN phase.
-   0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
 int msg_action;
 int msg_len;
 uint8_t msg[LSI_MAX_MSGIN_LEN];
@@ -323,7 +328,7 @@ static void lsi_soft_reset(LSIState *s)
 trace_lsi_reset();
 s->carry = 0;
 
-s->msg_action = 0;
+s->msg_action = LSI_MSG_ACTION_COMMAND;
 s->msg_len = 0;
 s->waiting = LSI_NOWAIT;
 s->dsa = 0;
@@ -686,7 +691,7 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
 trace_lsi_reselect(id);
 s->scntl1 |= LSI_SCNTL1_CON;
 lsi_set_phase(s, PHASE_MI);
-s->msg_action = p->out ? 2 : 3;
+s->msg_action = p->out ? LSI_MSG_ACTION_DOUT : LSI_MSG_ACTION_DIN;
 s->current->dma_len = p->pending;
 lsi_add_msg_byte(s, 0x80);
 if (s->current->tag & LSI_TAG_VALID) {
@@ -857,7 +862,7 @@ static void lsi_do_command(LSIState *s)
 lsi_add_msg_byte(s, 4); /* DISCONNECT */
 /* wait data */
 lsi_set_phase(s, PHASE_MI);
-s->msg_action = 1;
+s->msg_action = LSI_MSG_ACTION_DISCONNECT;
 lsi_queue_command(s);
 } else {
 /* wait command complete */
@@ -878,7 +883,7 @@ static void lsi_do_status(LSIState *s)
 s->sfbr = status;
 pci_dma_write(PCI_DEVICE(s), s->dnad, &status, 1);
 lsi_set_phase(s, PHASE_MI);
-s->msg_action = 1;
+s->msg_action = LSI_MSG_ACTION_DISCONNECT;
 lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
 }
 
@@ -901,16 +906,16 @@ static void lsi_do_msgin(LSIState *s)
 /* ??? Check if ATN (not yet implemented) is asserted and maybe
switch to PHASE_MO.  */
 switch (s->msg_action) {
-case 0:
+case LSI_MSG_ACTION_COMMAND:
 lsi_set_phase(s, PHASE_CMD);
 break;
-case 1:
+case LSI_MSG_ACTION_DISCONNECT:
 lsi_disconnect(s);
 break;
-case 2:
+case LSI_MSG_ACTION_DOUT:
 lsi_set_phase(s, PHASE_DO);
 break;
-case 3:
+case LSI_MSG_ACTION_DIN:
 lsi_set_phase(s, PHASE_DI);
 break;
 default:
@@ -1062,7 +1067,7 @@ bad:
 qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg);
 lsi_set_phase(s, PHASE_MI);
 lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
-s->msg_action = 0;
+s->msg_action = LSI_MSG_ACTION_COMMAND;
 }
 
 #define LSI_BUF_SIZE 4096
-- 
2.20.1




[Qemu-devel] [PATCH 5/5] lsi: return dfifo value

2019-03-04 Thread Sven Schnelle
Code was assigning DFIFO, but didn't return the value to users.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index f635d56e0f..a0e0c57b9b 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -1683,7 +1683,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
 break;
 CASE_GET_REG32(temp, 0x1c)
 case 0x20: /* DFIFO */
-ret = 0;
+ret = s->dfifo;
 break;
 case 0x21: /* CTEST4 */
 ret = s->ctest4;
-- 
2.20.1




[Qemu-devel] [PATCH 4/5] lsi: use SCSI phase names instead of numbers in trace

2019-03-04 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 24 ++--
 hw/scsi/trace-events |  4 ++--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d1eb2cf074..f635d56e0f 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -184,6 +184,17 @@ static const char *names[] = {
 /* Flag set if this is a tagged command.  */
 #define LSI_TAG_VALID (1 << 16)
 
+static const char *scsi_phases[] = {
+"DOUT",
+"DIN",
+"CMD",
+"STATUS",
+"RSVIN",
+"RSVOUT",
+"MSGOUT",
+"MSGIN"
+};
+
 typedef struct lsi_request {
 SCSIRequest *req;
 uint32_t tag;
@@ -1201,8 +1212,9 @@ again:
 s->ia = s->dsp - 12;
 }
 if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
-trace_lsi_execute_script_blockmove_badphase(s->sstat1 & PHASE_MASK,
-(insn >> 24) & 7);
+trace_lsi_execute_script_blockmove_badphase(
+scsi_phases[s->sstat1 & PHASE_MASK],
+scsi_phases[(insn >> 24) & 7]);
 lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
 break;
 }
@@ -1234,8 +1246,8 @@ again:
 lsi_do_msgin(s);
 break;
 default:
-qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %d\n",
-  s->sstat1 & PHASE_MASK);
+qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %s\n",
+  scsi_phases[s->sstat1 & PHASE_MASK]);
 }
 s->dfifo = s->dbc & 0xff;
 s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
@@ -1462,9 +1474,9 @@ again:
 }
 if (cond == jmp && (insn & (1 << 17))) {
 trace_lsi_execute_script_tc_compp(
-(s->sstat1 & PHASE_MASK),
+scsi_phases[(s->sstat1 & PHASE_MASK)],
 jmp ? '=' : '!',
-((insn >> 24) & 7));
+scsi_phases[((insn >> 24) & 7)]);
 cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
 }
 if (cond == jmp && (insn & (1 << 18))) {
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 29aaa752d1..34feb6f42d 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -268,7 +268,7 @@ lsi_memcpy(uint32_t dest, uint32_t src, int count) "memcpy 
dest 0x%"PRIx32" src
 lsi_wait_reselect(void) "Wait Reselect"
 lsi_execute_script(uint32_t dsp, uint32_t insn, uint32_t addr) "SCRIPTS 
dsp=0x%"PRIx32" opcode 0x%"PRIx32" arg 0x%"PRIx32
 lsi_execute_script_blockmove_delayed(void) "Delayed select timeout"
-lsi_execute_script_blockmove_badphase(uint8_t phase, uint8_t expected) "Wrong 
phase got %d expected %d"
+lsi_execute_script_blockmove_badphase(const char *phase, const char *expected) 
"Wrong phase got %s expected %s"
 lsi_execute_script_io_alreadyreselected(void) "Already reselected, jumping to 
alternative address"
 lsi_execute_script_io_selected(uint8_t id, const char *atn) "Selected target 
%d%s"
 lsi_execute_script_io_disconnect(void) "Wait Disconnect"
@@ -278,7 +278,7 @@ lsi_execute_script_io_opcode(const char *opcode, int reg, 
const char *opname, ui
 lsi_execute_script_tc_nop(void) "NOP"
 lsi_execute_script_tc_delayedselect_timeout(void) "Delayed select timeout"
 lsi_execute_script_tc_compc(int result) "Compare carry %d"
-lsi_execute_script_tc_compp(uint8_t phase, int op, uint8_t insn_phase) 
"Compare phase %d %c= %d"
+lsi_execute_script_tc_compp(const char *phase, int op, const char *insn_phase) 
"Compare phase %s %c= %s"
 lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, int op, int result) 
"Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
 lsi_execute_script_tc_jump(uint32_t addr) "Jump to 0x%"PRIx32
 lsi_execute_script_tc_call(uint32_t addr) "Call 0x%"PRIx32
-- 
2.20.1




Re: [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree

2019-02-11 Thread Sven Schnelle
Hi Richard,

On Thu, Feb 07, 2019 at 11:53:41AM +, Richard Henderson wrote:

> Helge or Sven, if you have a chance to do a bit more testing in
> the next week, I would appreciate it.  Otherwise we can fix any
> other minor problems on mainline.

I tested this during the weekend with my HP-UX branch and found no
problems. Feel free to add

Tested-by: Sven Schnelle 

Regards
Sven



[Qemu-devel] [PATCH 1/5] target/hppa: move GETPC to HELPER() functions

2019-02-11 Thread Sven Schnelle
When QEMU is compiled with -O0, these functions are inlined
which will cause a wrong restart address generated for the TB.

Signed-off-by: Sven Schnelle 
---
 target/hppa/op_helper.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 6bf478e7b0..268c20 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -81,10 +81,8 @@ static void atomic_store_3(CPUHPPAState *env, target_ulong 
addr, uint32_t val,
 }
 
 static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ureg val,
-  bool parallel)
+  bool parallel, uintptr_t ra)
 {
-uintptr_t ra = GETPC();
-
 switch (addr & 3) {
 case 3:
 cpu_stb_data_ra(env, addr, val, ra);
@@ -109,20 +107,18 @@ static void do_stby_b(CPUHPPAState *env, target_ulong 
addr, target_ureg val,
 
 void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ureg val)
 {
-do_stby_b(env, addr, val, false);
+do_stby_b(env, addr, val, false, GETPC());
 }
 
 void HELPER(stby_b_parallel)(CPUHPPAState *env, target_ulong addr,
  target_ureg val)
 {
-do_stby_b(env, addr, val, true);
+do_stby_b(env, addr, val, true, GETPC());
 }
 
 static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ureg val,
-  bool parallel)
+  bool parallel, uintptr_t ra)
 {
-uintptr_t ra = GETPC();
-
 switch (addr & 3) {
 case 3:
 /* The 3 byte store must appear atomic.  */
@@ -151,13 +147,13 @@ static void do_stby_e(CPUHPPAState *env, target_ulong 
addr, target_ureg val,
 
 void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ureg val)
 {
-do_stby_e(env, addr, val, false);
+do_stby_e(env, addr, val, false, GETPC());
 }
 
 void HELPER(stby_e_parallel)(CPUHPPAState *env, target_ulong addr,
  target_ureg val)
 {
-do_stby_e(env, addr, val, true);
+do_stby_e(env, addr, val, true, GETPC());
 }
 
 target_ureg HELPER(probe)(CPUHPPAState *env, target_ulong addr,
-- 
2.20.1




[Qemu-devel] [PATCH 5/5] target/hppa: fix dcor instruction

2019-02-11 Thread Sven Schnelle
It looks like the operands where exchanged. HP bootrom tests the
following sequence:

0xf0004064:  ldil L%-6800,r7
0xf0004068:  addi 19f,r7,r7
0xf000406c:  addi -1,r0,rp
0xf0004070:  addi f,r0,r4
0xf0004074:  addi 1,r4,r5
0xf0004078:  dcor rp,r6
0xf000407c:  cmpb,<>,n r6,r7,0xf000411

This returned 0x6661 instead of the expected 0x999f in QEMU.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index d858fabd3a..69c5a558fc 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2797,7 +2797,7 @@ static DisasJumpType trans_dcor(DisasContext *ctx, 
uint32_t insn,
 }
 tcg_gen_andi_reg(tmp, tmp, 0x);
 tcg_gen_muli_reg(tmp, tmp, 6);
-ret = do_unit(ctx, rt, tmp, load_gpr(ctx, r2), cf, false,
+ret = do_unit(ctx, rt, load_gpr(ctx, r2), tmp, cf, false,
   is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
 
 return nullify_end(ctx, ret);
-- 
2.20.1




[Qemu-devel] [PATCH 3/5] target/hppa: fix log conditions

2019-02-11 Thread Sven Schnelle
Now that do_cond() uses sign overflow for some condition matches we
need to roll our own version without sign overflow checks.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 0e8cc8117a..bce8773b1a 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -996,12 +996,35 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
 
 static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
 {
+DisasCond cond;
+TCGv_reg tmp;
+
 switch (cf >> 1) {
-case 4: case 5: case 6:
-cf &= 1;
+case 0: /* never */
+cond = cond_make_f();
+break;
+case 1: /* = all bits are zero */
+cond = cond_make_0(TCG_COND_EQ, res);
+break;
+case 2: /* < leftmost bit is 1 */
+cond = cond_make_0(TCG_COND_LT, res);
+break;
+case 3: /* <= leftmost bit is 1 or all bits 0 */
+cond = cond_make_0(TCG_COND_LE, res);
+break;
+case 7: /* OD rightmost bit is 1 */
+tmp = tcg_temp_new();
+tcg_gen_andi_reg(tmp, res, 1);
+cond = cond_make_0(TCG_COND_NE, tmp);
+tcg_temp_free(tmp);
+break;
+default:
 break;
 }
-return do_cond(cf, res, res, res);
+if (cf & 1) {
+cond.c = tcg_invert_cond(cond.c);
+}
+return cond;
 }
 
 /* Similar, but for shift/extract/deposit conditions.  */
-- 
2.20.1




[Qemu-devel] [PATCH 4/5] target/hppa: fix sed conditions

2019-02-11 Thread Sven Schnelle
Now that do_cond() uses sign overflow for some condition matches we
need to roll our own version without sign overflow checks.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index bce8773b1a..d858fabd3a 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1029,20 +1029,32 @@ static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
 
 /* Similar, but for shift/extract/deposit conditions.  */
 
-static DisasCond do_sed_cond(unsigned orig, TCGv_reg res)
+static DisasCond do_sed_cond(unsigned c, TCGv_reg res)
 {
-unsigned c, f;
+DisasCond cond;
+TCGv_reg tmp;
 
-/* Convert the compressed condition codes to standard.
-   0-2 are the same as logicals (nv,<,<=), while 3 is OD.
-   4-7 are the reverse of 0-3.  */
-c = orig & 3;
-if (c == 3) {
-c = 7;
+switch(c & 3) {
+case 0: /* never */
+cond = cond_make_f();
+break;
+case 1: /* = all bits are zero */
+cond = cond_make_0(TCG_COND_EQ, res);
+break;
+case 2: /* < leftmost bit is 1 */
+cond = cond_make_0(TCG_COND_LT, res);
+break;
+case 3: /* OD rightmost bit is 1 */
+tmp = tcg_temp_new();
+tcg_gen_andi_reg(tmp, res, 1);
+cond = cond_make_0(TCG_COND_NE, tmp);
+tcg_temp_free(tmp);
+break;
 }
-f = (orig & 4) / 4;
-
-return do_log_cond(c * 2 + f, res);
+if (c & 4) {
+cond.c = tcg_invert_cond(cond.c);
+}
+return cond;
 }
 
 /* Similar, but for unit conditions.  */
-- 
2.20.1




[Qemu-devel] [PATCH 2/5] target/hppa: fix '

2019-02-11 Thread Sven Schnelle
These condition include the signed overflow bit. See Page 5-3 of
the Parisc 1.1 Architecture Reference manual for details.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 30 ++
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 51bfd9849d..0e8cc8117a 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -404,6 +404,11 @@ static DisasCond cond_make_n(void)
 };
 }
 
+static bool cond_need_sv(int c)
+{
+return c == 2 || c == 3 || c == 6;
+}
+
 static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
 {
 DisasCond r = { .c = c, .a1 = NULL, .a1_is_0 = true };
@@ -910,11 +915,17 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
 case 1: /* = / <>(Z / !Z) */
 cond = cond_make_0(TCG_COND_EQ, res);
 break;
-case 2: /* < / >=(N / !N) */
-cond = cond_make_0(TCG_COND_LT, res);
+case 2: /* < / >=(N ^ V / !(N ^ V)) */
+tmp = tcg_temp_new();
+tcg_gen_xor_reg(tmp, res, sv);
+cond = cond_make_0(TCG_COND_LT, tmp);
+tcg_temp_free(tmp);
 break;
 case 3: /* <= / >(N | Z / !N & !Z) */
-cond = cond_make_0(TCG_COND_LE, res);
+tmp = tcg_temp_new();
+tcg_gen_xor_reg(tmp, res, sv);
+cond = cond_make_0(TCG_COND_LE, tmp);
+tcg_temp_free(tmp);
 break;
 case 4: /* NUV / UV  (!C / C) */
 cond = cond_make_0(TCG_COND_EQ, cb_msb);
@@ -1159,7 +1170,7 @@ static DisasJumpType do_add(DisasContext *ctx, unsigned 
rt, TCGv_reg in1,
 
 /* Compute signed overflow if required.  */
 sv = NULL;
-if (is_tsv || c == 6) {
+if (is_tsv || cond_need_sv(c)) {
 sv = do_add_sv(ctx, dest, in1, in2);
 if (is_tsv) {
 /* ??? Need to include overflow from shift.  */
@@ -1223,7 +1234,7 @@ static DisasJumpType do_sub(DisasContext *ctx, unsigned 
rt, TCGv_reg in1,
 
 /* Compute signed overflow if required.  */
 sv = NULL;
-if (is_tsv || c == 6) {
+if (is_tsv || cond_need_sv(c)) {
 sv = do_sub_sv(ctx, dest, in1, in2);
 if (is_tsv) {
 gen_helper_tsv(cpu_env, sv);
@@ -1263,13 +1274,14 @@ static DisasJumpType do_cmpclr(DisasContext *ctx, 
unsigned rt, TCGv_reg in1,
 {
 TCGv_reg dest, sv;
 DisasCond cond;
+int c = cf >> 1;
 
 dest = tcg_temp_new();
 tcg_gen_sub_reg(dest, in1, in2);
 
 /* Compute signed overflow if required.  */
 sv = NULL;
-if ((cf >> 1) == 6) {
+if (cond_need_sv(c)) {
 sv = do_sub_sv(ctx, dest, in1, in2);
 }
 
@@ -2808,7 +2820,7 @@ static DisasJumpType trans_ds(DisasContext *ctx, uint32_t 
insn,
 /* Install the new nullification.  */
 if (cf) {
 TCGv_reg sv = NULL;
-if (cf >> 1 == 6) {
+if (cond_need_sv(cf >> 1)) {
 /* ??? The lshift is supposed to contribute to overflow.  */
 sv = do_add_sv(ctx, dest, add1, add2);
 }
@@ -3369,7 +3381,7 @@ static DisasJumpType trans_cmpb(DisasContext *ctx, 
uint32_t insn,
 tcg_gen_sub_reg(dest, in1, in2);
 
 sv = NULL;
-if (c == 6) {
+if (cond_need_sv(c)) {
 sv = do_sub_sv(ctx, dest, in1, in2);
 }
 
@@ -3409,6 +3421,8 @@ static DisasJumpType trans_addb(DisasContext *ctx, 
uint32_t insn,
 tcg_gen_movi_reg(cb_msb, 0);
 tcg_gen_add2_reg(dest, cb_msb, in1, cb_msb, in2, cb_msb);
 break;
+case 2:
+case 3:
 case 6:
 tcg_gen_add_reg(dest, in1, in2);
 sv = do_add_sv(ctx, dest, in1, in2);
-- 
2.20.1




[Qemu-devel] [PATCH] target/hppa: forward requests to CPU HPA

2019-02-11 Thread Sven Schnelle
HP-UX 10.20 uses busmaster writes to the CPU EIR to signal
interrupts from the SCSI constroller. (Similar to what is known
as MSI on x86)

Signed-off-by: Sven Schnelle 
---
 hw/hppa/dino.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index 31e09942b5..360716de57 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -105,6 +105,7 @@ typedef struct DinoState {
 MemoryRegion bm;
 MemoryRegion bm_ram_alias;
 MemoryRegion bm_pci_alias;
+MemoryRegion bm_cpu_alias;
 
 MemoryRegion cpu0_eir_mem;
 } DinoState;
@@ -473,12 +474,17 @@ PCIBus *dino_init(MemoryRegion *addr_space,
 memory_region_init_alias(&s->bm_pci_alias, OBJECT(s),
  "bm-pci", &s->pci_mem,
  0xf000 + DINO_MEM_CHUNK_SIZE,
- 31 * DINO_MEM_CHUNK_SIZE);
+ 30 * DINO_MEM_CHUNK_SIZE);
+memory_region_init_alias(&s->bm_cpu_alias, OBJECT(s),
+ "bm-cpu", addr_space, 0xfff0,
+ 0xf);
 memory_region_add_subregion(&s->bm, 0,
 &s->bm_ram_alias);
 memory_region_add_subregion(&s->bm,
 0xf000 + DINO_MEM_CHUNK_SIZE,
 &s->bm_pci_alias);
+memory_region_add_subregion(&s->bm, 0xfff0,
+&s->bm_cpu_alias);
 address_space_init(&s->bm_as, &s->bm, "pci-bm");
 pci_setup_iommu(b, dino_pcihost_set_iommu, s);
 
-- 
2.20.1




[Qemu-devel] [PATCH] target/hppa: fix setting registers via gdb

2019-01-28 Thread Sven Schnelle
While doing 'set $pcoqh=0xf000' i triggered the assertion below. From 
looking
at the source, it looks like the argument order for deposit64() is wrong, and 
val
needs to be moved to the end.

Signed-off-by: Sven Schnelle 

qemu-system-hppa: /home/svens/qemu/include/qemu/bitops.h:419: deposit64: 
Assertion `start >= 0 && length > 0 && length <= 64 - start' failed.

Thread 1 "qemu-system-hpp" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:50
50  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
 #0  0x74f8785b in __GI_raise (sig=sig@entry=0x6) at 
../sysdeps/unix/sysv/linux/raise.c:50
 #1  0x74f72535 in __GI_abort () at abort.c:79
 #2  0x74f7240f in __assert_fail_base
(fmt=0x750d4ee0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
assertion=0x55cc62a8 "start >= 0 && length > 0 && length <= 64 - start", 
file=0x55cc6280 "/home/svens/qemu/include/qemu/bitops.h", line=0x1a3, 
function=) at assert.c:92
 #3  0x74f800a2 in __GI___assert_fail
(assertion=0x55cc62a8 "start >= 0 && length > 0 && length <= 64 - 
start", file=0x55cc6280 "/home/svens/qemu/include/qemu/bitops.h", 
line=0x1a3, function=0x55cc6760 <__PRETTY_FUNCTION__.15114> "deposit64") at 
assert.c:101
 #4  0x558dd0db in deposit64 (value=0x0, start=0x0, length=0x0, 
fieldval=0x20) at /home/svens/qemu/include/qemu/bitops.h:419
 #5  0x558dd87a in hppa_cpu_gdb_write_register (cs=0x563394e0, 
mem_buf=0x7fffb134 "", n=0x41) at /home/svens/qemu/target/hppa/gdbstub.c:269
 #6  0x55822397 in gdb_write_register (cpu=0x563394e0, 
mem_buf=0x7fffb134 "", reg=0x41) at /home/svens/qemu/gdbstub.c:905
 #7  0x55823802 in gdb_handle_packet (s=0x56992020, 
line_buf=0x5699203c "G", '0' , "fff1", '0' , "1", '0' , "6"...) at /home/svens/qemu/gdbstub.c:1481
 #8  0x5582573c in gdb_read_byte (s=0x56992020, ch=0x35) at 
/home/svens/qemu/gdbstub.c:2131
 #9  0x55825972 in gdb_chr_receive (opaque=0x56992020, 
buf=0x7fffd170 "$G", '0' , "fff1", '0' , "1", '0' ..., size=0x405) at 
/home/svens/qemu/gdbstub.c:2369
 #10 0x55bd51bc in qemu_chr_be_write_impl (s=0x566cd100, 
buf=0x7fffd170 "$G", '0' , "fff1", '0' , "1", '0' ..., len=0x405) at chardev/char.c:175
 #11 0x55bd5220 in qemu_chr_be_write (s=0x566cd100, 
buf=0x7fffd170 "$G", '0' , "fff1", '0' , "1", '0' ..., len=0x405) at chardev/char.c:187
 #12 0x55bdde8d in tcp_chr_read (chan=0x5697ea00, cond=G_IO_IN, 
opaque=0x566cd100) at chardev/char-socket.c:490
 #13 0x55bf81c3 in qio_channel_fd_source_dispatch 
(source=0x569c6220, callback=0x55bddcdf , 
user_data=0x566cd100) at io/channel-watch.c:84
 #14 0x76937cb8 in g_main_context_dispatch () at 
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
 #15 0x55c73851 in glib_pollfds_poll () at util/main-loop.c:215
 #16 0x55c738cb in os_host_main_loop_wait (timeout=0x3b9aca00) at 
util/main-loop.c:238
 #17 0x55c73984 in main_loop_wait (nonblocking=0x0) at 
util/main-loop.c:497
 #18 0x558f4130 in main_loop () at vl.c:1925
 #19 0x558fbb43 in main (argc=0xd, argv=0x7fffe5e8, 
envp=0x7fffe658) at vl.c:4662

Signed-off-by: Sven Schnelle 
---
 target/hppa/gdbstub.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c
index e2e9c4d77f..3157a690f2 100644
--- a/target/hppa/gdbstub.c
+++ b/target/hppa/gdbstub.c
@@ -266,7 +266,7 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 case 65 ... 127:
 {
 uint64_t *fr = &env->fr[(n - 64) / 2];
-*fr = deposit64(*fr, val, (n & 1 ? 0 : 32), 32);
+*fr = deposit64(*fr, (n & 1 ? 0 : 32), 32, val);
 }
 break;
 default:
-- 
2.20.1




[Qemu-devel] [PATCH] target/hppa: fix PSW Q bit behaviour to match hardware

2019-01-29 Thread Sven Schnelle
PA-RISC specification says: "Setting the PSW Q-bit, PSW{28}, to 1
with this instruction, if it was not already 1, is an undefined
operation." However, at least HP-UX 10.20 sets the Q bit from 0 to 1
with the SSM instruction. Tested this both on HP9000/712 and
HP9000/785/C3750, both machines set the Q bit from 0 to 1 without
exception. This makes HP-UX 10.20 progress a little bit further.

Signed-off-by: Sven Schnelle 
---
 target/hppa/op_helper.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 912e8d5be4..3adcfd8976 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -665,11 +665,6 @@ void HELPER(reset)(CPUHPPAState *env)
 target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm)
 {
 target_ulong psw = env->psw;
-/* ??? On second reading this condition simply seems
-   to be undefined rather than a diagnosed trap.  */
-if (nsm & ~psw & PSW_Q) {
-hppa_dynamic_excp(env, EXCP_ILL, GETPC());
-}
 env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM);
 return psw & PSW_SM;
 }
-- 
2.20.1




[Qemu-devel] [PATCH] hw/scsi: print SCSI command as hex number in trace

2019-01-31 Thread Sven Schnelle
Otherwise it's hard for people fluent in SCSI to read the traces.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/trace-events | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 2fe8a7c062..a71c5596ac 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -8,9 +8,9 @@ scsi_req_data_canceled(int target, int lun, int tag, int len) 
"target %d lun %d
 scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
 scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
 scsi_req_continue_canceled(int target, int lun, int tag) "target %d lun %d tag 
%d"
-scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) 
"target %d lun %d tag %d command %d dir %d length %d"
-scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) 
"target %d lun %d tag %d command %d lba %"PRIu64
-scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d 
tag %d command %d"
+scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) 
"target %d lun %d tag %d command 0x%x dir %d length %d"
+scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) 
"target %d lun %d tag %d command 0x%x lba %"PRIu64
+scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d 
tag %d command 0x%x"
 scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) 
"target %d lun %d tag %d key 0x%02x asc 0x%02x ascq 0x%02x"
 scsi_device_set_ua(int target, int lun, int key, int asc, int ascq) "target %d 
lun %d key 0x%02x asc 0x%02x ascq 0x%02x"
 scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
-- 
2.20.1




Re: [Qemu-devel] [PATCH 4/5] target/hppa: fix sed conditions

2019-02-14 Thread Sven Schnelle
Hi Richard,


On Mon, Feb 11, 2019 at 08:27:32PM -0800, Richard Henderson wrote:
> On 2/11/19 10:19 AM, Sven Schnelle wrote:
> > -f = (orig & 4) / 4;
> > -
> > -return do_log_cond(c * 2 + f, res);
> 
> Given that this used to reference do_log_cond, and you've fixed do_log_cond,
> why is there any reason for a change here?

You're right, this patch can be dropped.

Regards
Sven



[Qemu-devel] [PATCH] lsi: implement basic SBCL functionality

2019-02-14 Thread Sven Schnelle
HP-UX checks this register after sending data to the target. If there's no valid
information present, it assumes the client disconnected because the kernel sent
to much data. Implement at least some of the SBCL functionality that is possible
without having a real SCSI bus.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 89def1421f..b12be02bf1 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -160,6 +160,11 @@ static const char *names[] = {
 #define LSI_CCNTL1_DDAC  0x08
 #define LSI_CCNTL1_ZMOD  0x80
 
+#define LSI_SBCL_ATN 0x08
+#define LSI_SBCL_BSY 0x20
+#define LSI_SBCL_ACK 0x40
+#define LSI_SBCL_REQ 0x80
+
 /* Enable Response to Reselection */
 #define LSI_SCID_RRE  0x60
 
@@ -258,6 +263,7 @@ typedef struct {
 uint8_t sdid;
 uint8_t ssid;
 uint8_t sfbr;
+uint8_t sbcl;
 uint8_t stest1;
 uint8_t stest2;
 uint8_t stest3;
@@ -356,6 +362,7 @@ static void lsi_soft_reset(LSIState *s)
 s->socl = 0;
 s->sdid = 0;
 s->ssid = 0;
+s->sbcl = 0;
 s->stest1 = 0;
 s->stest2 = 0;
 s->stest3 = 0;
@@ -530,6 +537,8 @@ static void lsi_script_dma_interrupt(LSIState *s, int stat)
 
 static inline void lsi_set_phase(LSIState *s, int phase)
 {
+s->sbcl &= ~PHASE_MASK;
+s->sbcl |= phase | LSI_SBCL_REQ;
 s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
 }
 
@@ -567,6 +576,7 @@ static void lsi_disconnect(LSIState *s)
 {
 s->scntl1 &= ~LSI_SCNTL1_CON;
 s->sstat1 &= ~PHASE_MASK;
+s->sbcl = 0;
 }
 
 static void lsi_bad_selection(LSIState *s, uint32_t id)
@@ -1265,7 +1275,9 @@ again:
 s->scntl1 |= LSI_SCNTL1_CON;
 if (insn & (1 << 3)) {
 s->socl |= LSI_SOCL_ATN;
+s->sbcl |= LSI_SBCL_ATN;
 }
+s->sbcl |= LSI_SBCL_BSY;
 lsi_set_phase(s, PHASE_MO);
 break;
 case 1: /* Disconnect */
@@ -1297,8 +1309,14 @@ again:
 insn & (1 << 10) ? " CC" : "");
 if (insn & (1 << 3)) {
 s->socl |= LSI_SOCL_ATN;
+s->sbcl |= LSI_SBCL_ATN;
 lsi_set_phase(s, PHASE_MO);
 }
+
+if (insn & (1 << 6)) {
+s->sbcl |= LSI_SBCL_ACK;
+}
+
 if (insn & (1 << 9)) {
 qemu_log_mask(LOG_UNIMP,
 "lsi_scsi: Target mode not implemented\n");
@@ -1314,7 +1332,13 @@ again:
 insn & (1 << 10) ? " CC" : "");
 if (insn & (1 << 3)) {
 s->socl &= ~LSI_SOCL_ATN;
+s->sbcl &= ~LSI_SBCL_ATN;
 }
+
+if (insn & (1 << 6)) {
+s->sbcl &= ~LSI_SBCL_ACK;
+}
+
 if (insn & (1 << 10))
 s->carry = 0;
 break;
@@ -1591,9 +1615,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
 ret = s->ssid;
 break;
 case 0xb: /* SBCL */
-/* ??? This is not correct. However it's (hopefully) only
-   used for diagnostics, so should be ok.  */
-ret = 0;
+ret = s->sbcl;
 break;
 case 0xc: /* DSTAT */
 ret = s->dstat | LSI_DSTAT_DFE;
@@ -2202,6 +2224,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
 VMSTATE_UINT8(stime0, LSIState),
 VMSTATE_UINT8(respid0, LSIState),
 VMSTATE_UINT8(respid1, LSIState),
+VMSTATE_UINT8(sbcl, LSIState),
 VMSTATE_UINT32(mmrs, LSIState),
 VMSTATE_UINT32(mmws, LSIState),
 VMSTATE_UINT32(sfs, LSIState),
-- 
2.20.1




Re: [Qemu-devel] [PATCH] lsi: implement basic SBCL functionality

2019-02-15 Thread Sven Schnelle
On Fri, Feb 15, 2019 at 10:36:53AM +0100, Paolo Bonzini wrote:
> > HP-UX checks this register after sending data to the target. If there's no 
> > valid
> > information present, it assumes the client disconnected because the kernel 
> > sent
> > to much data. Implement at least some of the SBCL functionality that is 
> > possible
> > without having a real SCSI bus.
> > 
> > Signed-off-by: Sven Schnelle 
>  [..]
>
> This breaks live migration.  You need to bump the version number higher
> in vmstate_lsi_scsi and use "VMSTATE_UINT8_V(sbcl, LSIState, 1)" so that
> the field is only marshalled/unmarshalled for version 1 of the migration
> state.

Thanks, i wasn't aware of that. I'll send a revised v2.

Regards
Sven



[Qemu-devel] [PATCH v2] lsi: implement basic SBCL functionality

2019-02-15 Thread Sven Schnelle
HP-UX checks this register after sending data to the target. If there's no valid
information present, it assumes the client disconnected because the kernel sent
to much data. Implement at least some of the SBCL functionality that is possible
without having a real SCSI bus.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 31 +++
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 89def1421f..8ba07f8756 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -160,6 +160,11 @@ static const char *names[] = {
 #define LSI_CCNTL1_DDAC  0x08
 #define LSI_CCNTL1_ZMOD  0x80
 
+#define LSI_SBCL_ATN 0x08
+#define LSI_SBCL_BSY 0x20
+#define LSI_SBCL_ACK 0x40
+#define LSI_SBCL_REQ 0x80
+
 /* Enable Response to Reselection */
 #define LSI_SCID_RRE  0x60
 
@@ -258,6 +263,7 @@ typedef struct {
 uint8_t sdid;
 uint8_t ssid;
 uint8_t sfbr;
+uint8_t sbcl;
 uint8_t stest1;
 uint8_t stest2;
 uint8_t stest3;
@@ -356,6 +362,7 @@ static void lsi_soft_reset(LSIState *s)
 s->socl = 0;
 s->sdid = 0;
 s->ssid = 0;
+s->sbcl = 0;
 s->stest1 = 0;
 s->stest2 = 0;
 s->stest3 = 0;
@@ -530,6 +537,8 @@ static void lsi_script_dma_interrupt(LSIState *s, int stat)
 
 static inline void lsi_set_phase(LSIState *s, int phase)
 {
+s->sbcl &= ~PHASE_MASK;
+s->sbcl |= phase | LSI_SBCL_REQ;
 s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
 }
 
@@ -567,6 +576,7 @@ static void lsi_disconnect(LSIState *s)
 {
 s->scntl1 &= ~LSI_SCNTL1_CON;
 s->sstat1 &= ~PHASE_MASK;
+s->sbcl = 0;
 }
 
 static void lsi_bad_selection(LSIState *s, uint32_t id)
@@ -1265,7 +1275,9 @@ again:
 s->scntl1 |= LSI_SCNTL1_CON;
 if (insn & (1 << 3)) {
 s->socl |= LSI_SOCL_ATN;
+s->sbcl |= LSI_SBCL_ATN;
 }
+s->sbcl |= LSI_SBCL_BSY;
 lsi_set_phase(s, PHASE_MO);
 break;
 case 1: /* Disconnect */
@@ -1297,8 +1309,14 @@ again:
 insn & (1 << 10) ? " CC" : "");
 if (insn & (1 << 3)) {
 s->socl |= LSI_SOCL_ATN;
+s->sbcl |= LSI_SBCL_ATN;
 lsi_set_phase(s, PHASE_MO);
 }
+
+if (insn & (1 << 6)) {
+s->sbcl |= LSI_SBCL_ACK;
+}
+
 if (insn & (1 << 9)) {
 qemu_log_mask(LOG_UNIMP,
 "lsi_scsi: Target mode not implemented\n");
@@ -1314,7 +1332,13 @@ again:
 insn & (1 << 10) ? " CC" : "");
 if (insn & (1 << 3)) {
 s->socl &= ~LSI_SOCL_ATN;
+s->sbcl &= ~LSI_SBCL_ATN;
 }
+
+if (insn & (1 << 6)) {
+s->sbcl &= ~LSI_SBCL_ACK;
+}
+
 if (insn & (1 << 10))
 s->carry = 0;
 break;
@@ -1591,9 +1615,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
 ret = s->ssid;
 break;
 case 0xb: /* SBCL */
-/* ??? This is not correct. However it's (hopefully) only
-   used for diagnostics, so should be ok.  */
-ret = 0;
+ret = s->sbcl;
 break;
 case 0xc: /* DSTAT */
 ret = s->dstat | LSI_DSTAT_DFE;
@@ -2143,7 +2165,7 @@ static int lsi_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_lsi_scsi = {
 .name = "lsiscsi",
-.version_id = 0,
+.version_id = 1,
 .minimum_version_id = 0,
 .pre_save = lsi_pre_save,
 .post_load = lsi_post_load,
@@ -2202,6 +2224,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
 VMSTATE_UINT8(stime0, LSIState),
 VMSTATE_UINT8(respid0, LSIState),
 VMSTATE_UINT8(respid1, LSIState),
+VMSTATE_UINT8_V(sbcl, LSIState, 1),
 VMSTATE_UINT32(mmrs, LSIState),
 VMSTATE_UINT32(mmws, LSIState),
 VMSTATE_UINT32(sfs, LSIState),
-- 
2.20.1




[Qemu-devel] [PATCH] lsi: check if SIGP bit is already set in Wait reselect

2019-02-17 Thread Sven Schnelle
If SIGP is set, the 'Wait for Reselection' command should jump
immediately to the address stored in the second DWORD of the
instruction. This fixes spurious hangs in the HP-UX 11.11
installer when the SIGP bit gets set by the kernel before the
'Wait for Reselection' command is executed by SCRIPTS.

Signed-off-by: Sven Schnelle 
Tested-by: Helge Deller 
---
 hw/scsi/lsi53c895a.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 8ba07f8756..bcff859bac 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -1297,8 +1297,10 @@ again:
 }
 break;
 case 2: /* Wait Reselect */
-if (!lsi_irq_on_rsl(s)) {
-lsi_wait_reselect(s);
+if (s->istat0 & LSI_ISTAT0_SIGP) {
+s->dsp = s->dnad;
+} else if (!lsi_irq_on_rsl(s)) {
+lsi_wait_reselect(s);
 }
 break;
 case 3: /* Set */
-- 
2.20.1




[Qemu-devel] [PATCH 1/2] lsi: 810/895A are always little endian

2019-02-18 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index bcff859bac..c493e3c4c7 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2061,14 +2061,13 @@ static uint64_t lsi_mmio_read(void *opaque, hwaddr addr,
   unsigned size)
 {
 LSIState *s = opaque;
-
 return lsi_reg_readb(s, addr & 0xff);
 }
 
 static const MemoryRegionOps lsi_mmio_ops = {
 .read = lsi_mmio_read,
 .write = lsi_mmio_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -2107,7 +2106,7 @@ static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps lsi_ram_ops = {
 .read = lsi_ram_read,
 .write = lsi_ram_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static uint64_t lsi_io_read(void *opaque, hwaddr addr,
@@ -2127,7 +2126,7 @@ static void lsi_io_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps lsi_io_ops = {
 .read = lsi_io_read,
 .write = lsi_io_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
-- 
2.20.1




[Qemu-devel] [PATCH 2/2] lsi: use ldn_le_p()/stn_le_p()

2019-02-18 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 19 ++-
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index c493e3c4c7..93c4434bfb 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2078,29 +2078,14 @@ static void lsi_ram_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
 LSIState *s = opaque;
-uint32_t newval;
-uint32_t mask;
-int shift;
-
-newval = s->script_ram[addr >> 2];
-shift = (addr & 3) * 8;
-mask = ((uint64_t)1 << (size * 8)) - 1;
-newval &= ~(mask << shift);
-newval |= val << shift;
-s->script_ram[addr >> 2] = newval;
+stn_le_p(((void*)s->script_ram) + addr, size, val);
 }
 
 static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
  unsigned size)
 {
 LSIState *s = opaque;
-uint32_t val;
-uint32_t mask;
-
-val = s->script_ram[addr >> 2];
-mask = ((uint64_t)1 << (size * 8)) - 1;
-val >>= (addr & 3) * 8;
-return val & mask;
+return ldn_le_p(((void *)s->script_ram) + addr, size);
 }
 
 static const MemoryRegionOps lsi_ram_ops = {
-- 
2.20.1




[Qemu-devel] [PATCH] hw/hppa/dino: mask out lower 2 bits of PCI config addr

2019-02-18 Thread Sven Schnelle
some versions of HP-UX 10.20 seems to rely on the fact that DINO
strips out the lower 2 bits of the PCI configuration address.
Also update the binary SeaBIOS distributed to the latest version
from Helge's repository, which is required with that change.

Signed-off-by: Sven Schnelle 
---
 hw/hppa/dino.c|  25 ++---
 pc-bios/hppa-firmware.img | Bin 215936 -> 53 bytes
 2 files changed, 22 insertions(+), 3 deletions(-)
 mode change 100644 => 12 pc-bios/hppa-firmware.img

diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index 360716de57..63441783c4 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -178,7 +178,7 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, 
hwaddr addr,
 case DINO_PCI_IO_DATA ... DINO_PCI_IO_DATA + 3:
 /* Read from PCI IO space. */
 io = &address_space_io;
-ioaddr = s->parent_obj.config_reg;
+ioaddr = s->parent_obj.config_reg + (addr & 3);
 switch (size) {
 case 1:
 val = address_space_ldub(io, ioaddr, attrs, &ret);
@@ -250,7 +250,7 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, 
hwaddr addr,
 case DINO_IO_DATA ... DINO_PCI_IO_DATA + 3:
 /* Write into PCI IO space.  */
 io = &address_space_io;
-ioaddr = s->parent_obj.config_reg;
+ioaddr = s->parent_obj.config_reg + (addr & 3);
 switch (size) {
 case 1:
 address_space_stb(io, ioaddr, val, attrs, &ret);
@@ -360,6 +360,25 @@ static const MemoryRegionOps dino_config_data_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static uint64_t dino_config_addr_read(void *opaque, hwaddr addr, unsigned len)
+{
+PCIHostState *s = opaque;
+return s->config_reg & ~3U;
+}
+
+static void dino_config_addr_write(void *opaque, hwaddr addr,
+   uint64_t val, unsigned len)
+{
+PCIHostState *s = opaque;
+s->config_reg = val & ~3U;
+}
+
+static const MemoryRegionOps dino_config_addr_ops = {
+.read = dino_config_addr_read,
+.write = dino_config_addr_write,
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
 static AddressSpace *dino_pcihost_set_iommu(PCIBus *bus, void *opaque,
 int devfn)
 {
@@ -440,7 +459,7 @@ PCIBus *dino_init(MemoryRegion *addr_space,
 
 /* Dino PCI config. */
 memory_region_init_io(&s->parent_obj.conf_mem, OBJECT(&s->parent_obj),
-  &pci_host_conf_be_ops, dev, "pci-conf-idx", 4);
+  &dino_config_addr_ops, dev, "pci-conf-idx", 4);
 memory_region_init_io(&s->parent_obj.data_mem, OBJECT(&s->parent_obj),
   &dino_config_data_ops, dev, "pci-conf-data", 4);
 memory_region_add_subregion(&s->this_mem, DINO_PCI_CONFIG_ADDR,
diff --git a/pc-bios/hppa-firmware.img b/pc-bios/hppa-firmware.img
deleted file mode 100644
index 
4ec0dbfc4ae065c29004156ce2933e66b761adf2..
GIT binary patch
literal 0
HcmV?d1

literal 215936
zcmeFaeRNdSxj(+=YU~m(_P4xWy-JJy!LLC@P)ki1AmYWA_KF?La$UTwtD#?z-{-T>
z8HiNx+xM^US~qKD?Q{0oFVBAVv!DIE?LCiIe`~5mv80IPpCYpGXt^Xr2hyNOnK~$h
zV#AXzETUNC3m?DZKZY`b|HAT*n}ss@1w3WoKaBtX^k2g7|8qi!f15e^j{B$2s{EUp
znKLKrGpj1~sf)k=@ZZk;{zAQY*21|{rr$eDfAEp-w~i7m%a$!!I`MD*X3^qhEz9TK
zIscJ||E6WZ!iOGO`2D|Gx^V8i#g8n#qh-mGxgvDO*pe|5O2(E1o5uu8#*8hyWBx;r
zEMG8h`S+JDyK~v!E?%(Up@nyTZ{actsaqGK4*$FG|33aF;C}`F58{7NSA-*~7iV1y
z1~BMb^q4A?u$rdS>$<}d3@E*pBkpj}61ryjtvf6%nTs)|&#g0*8N%w0TF$$}MPY}f
zv_b2sNfCM?+AC0hihd{ST4KQp5i9y`g{AcGY`Xq%fh9OUGp0X@ZyhQ3$J(FyvpwqC
zuaB-kS(|R3=-O{D!~X>Qm*Rgs{>R}zh%$>%XMWoC_J#Rpz-T#`&}F~jWPURJpYL)W
z{s%w*Lmyn1;pDnVrvJCCkJi^iXIuX{bfooz&}*${Loc_!A9|s6AoOhM2cgwTK9iU_
zytDMzB3AnA(CS*0PlS6#E$SF!)q21y6#Z84qCl2zq}qA?);sYoip_M1K9b+lcA4)7
zjnpEN<^MBq=-`XNDRwt`(^tX6Ifyq{uMBiM-0?ly6~L(!#kO8!+mE~@Vyah}s(O@$
z)}x^frEA6U);B}j^%&ah@Ly|vBec7;UA$i!(Ji))&KUNXu~}1HF^spq7UgSEwiabL
z_Iuw7txh!itI5;ByLYN7O2hSjjsj0c+Z%?oz5S-PM`wkdKH2u0X#0)OcG>Pxwp*~%
zY`-X5z1t}Bax-_q`^Sk^AR`(mtDxg^xv
z@vq}Q7ys%dk#Pn8m+=1)a5^kr=5Fg->AnIyTvbz*hQ5`aHauT2pP7Hcc=j^?fceb)
zy~cAM^VgcsSD124!10EJzhKV2Z-!PA?yMSTch*d2S9@2FPCR7ob_wQ{b_*pd;_4*r
zfLXyxb49qc8~wLyzD?~tUXJDDQvcw_
zW#KyJgT5jxlgwWi)!oF^#%0X|950{Q@4at;E-~L(F_#kbSq5#p6(9Q=c*Za1Jl>FZ
ziF1zmuF|7huMIR<)!<5T+!j$963y<4{h%@;T}^vyY_Cw^=9WVreL;_of9`AyAN8ZIV$ZDu)P+pGC*TLb|VWot@RJ?Ig$
zZ=2^7H4`%S2mPXH)6-EW+M2`h1bv}vSw4M-qsKY?tdm`=G-eA&+0RXzje{j`tb*ZvgUE!>-e$J#>RN4dHfE{vEP3;zezm*KzH&P
zdAAtf3O;39TdVY$gtewT{dj2?-edaymb=oAOZaodt;p}Qbx9sHg*ezcC3J${%sRcS
zvpyEui#omh&UZZb$@+ox_tkRk2xPw)WIsvA?=}R&n43uDY*BJ%naz!K?3o>!Q(LCY
zuAC);XO>!3txG-4NZ$I;@RYiKI_Np>_y{_-qy0l#I19f9p&rh-nojIVlRM2|P
znq@s39gjOPXQAJd1|6&9^Lu%a%yar|U7Anp?&Mk!oCmIjjmv&79ZAAL7yz#rzch42`+=lG@(#uEm@}92
z=2+nzcIE)ucvYF>Xk#AQz&ttr-Z@O$sn

Re: [Qemu-devel] [PATCH] hw/hppa/dino: mask out lower 2 bits of PCI config addr

2019-02-18 Thread Sven Schnelle
Hi List,

On Mon, Feb 18, 2019 at 07:28:51PM +0100, Sven Schnelle wrote:
> some versions of HP-UX 10.20 seems to rely on the fact that DINO
> strips out the lower 2 bits of the PCI configuration address.
> Also update the binary SeaBIOS distributed to the latest version
> from Helge's repository, which is required with that change.
> 
> Signed-off-by: Sven Schnelle 
> ---
>  hw/hppa/dino.c|  25 ++---
>  pc-bios/hppa-firmware.img | Bin 215936 -> 53 bytes
>  2 files changed, 22 insertions(+), 3 deletions(-)
>  mode change 100644 => 12 pc-bios/hppa-firmware.img
> 

please ignore that patch and use v2 instead. I've accidently committed
a symlink to hppa-firmware.img.

Regards
Sven



Re: [Qemu-devel] [PATCH 2/2] lsi: use ldn_le_p()/stn_le_p()

2019-02-18 Thread Sven Schnelle
Hi Philippe,

On Mon, Feb 18, 2019 at 10:39:54PM +0100, Philippe Mathieu-Daudé wrote:

> > -newval = s->script_ram[addr >> 2];
> > -shift = (addr & 3) * 8;
> > -mask = ((uint64_t)1 << (size * 8)) - 1;
> > -newval &= ~(mask << shift);
> > -newval |= val << shift;
> > -s->script_ram[addr >> 2] = newval;
> > +stn_le_p(((void*)s->script_ram) + addr, size, val);
> 
> If you want to do pointer arithmetic, it is safer to cast to a uintptr_t.
> But since you update all the places that use script_ram[], it seems
> pointless to keep it as an array of uint32_t. We can simply convert it
> to an array of char.

You're right, i was assuming that the array is used somewhere else in the code,
but all the accesses are routed through these two functions, so it makes sense
to convert the type. However, i'm not sure whether i have to increase the 
version
number in the VMSTATE_BUFFER_UNSAFE() macro in that case? Are there possible
endianess issues with that change?

My current version looks like this:


commit 286d45946e235d5fdf2f95bf349b3048e3180392
Author: Sven Schnelle 
Date:   Tue Feb 19 06:59:23 2019 +0100

lsi: use ldn_le_p()/stn_le_p()

Signed-off-by: Sven Schnelle 

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index c493e3c4c7..0f9591016a 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -290,7 +290,7 @@ typedef struct {
 uint32_t adder;
 
 /* Script ram is stored as 32-bit words in host byteorder.  */
-uint32_t script_ram[2048];
+uint8_t script_ram[8192];
 } LSIState;
 
 #define TYPE_LSI53C810  "lsi53c810"
@@ -2078,29 +2078,14 @@ static void lsi_ram_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
 LSIState *s = opaque;
-uint32_t newval;
-uint32_t mask;
-int shift;
-
-newval = s->script_ram[addr >> 2];
-shift = (addr & 3) * 8;
-mask = ((uint64_t)1 << (size * 8)) - 1;
-newval &= ~(mask << shift);
-newval |= val << shift;
-s->script_ram[addr >> 2] = newval;
+stn_le_p(s->script_ram + addr, size, val);
 }
 
 static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
  unsigned size)
 {
 LSIState *s = opaque;
-uint32_t val;
-uint32_t mask;
-
-val = s->script_ram[addr >> 2];
-mask = ((uint64_t)1 << (size * 8)) - 1;
-val >>= (addr & 3) * 8;
-return val & mask;
+return ldn_le_p(s->script_ram + addr, size);
 }
 
 static const MemoryRegionOps lsi_ram_ops = {
@@ -2243,7 +2228,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
 VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)),
 VMSTATE_UINT8(sbr, LSIState),
 
-VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 2048 * 
sizeof(uint32_t)),
+VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 8192),
 VMSTATE_END_OF_LIST()
 }
 };



Re: [PATCH v5 4/6] hppa: add emulation of LASI PS2 controllers

2020-01-19 Thread Sven Schnelle
On Fri, Jan 03, 2020 at 07:15:49AM +0100, Philippe Mathieu-Daudé wrote:
> On 12/20/19 10:15 PM, Sven Schnelle wrote:
> > Signed-off-by: Sven Schnelle 
> > ---
> >   hw/hppa/Kconfig|   1 +
> >   hw/hppa/lasi.c |  10 +-
> >   hw/input/Kconfig   |   3 +
> >   hw/input/Makefile.objs |   1 +
> >   hw/input/lasips2.c | 289 +
> >   hw/input/ps2.c |   5 +
> >   hw/input/trace-events  |   5 +
> >   include/hw/input/lasips2.h |  16 ++
> >   include/hw/input/ps2.h |   1 +
> >   9 files changed, 330 insertions(+), 1 deletion(-)
> >   create mode 100644 hw/input/lasips2.c
> >   create mode 100644 include/hw/input/lasips2.h
> > 
> > diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
> > index 2a7b38d6d6..7f9be7f25c 100644
> > --- a/hw/hppa/Kconfig
> > +++ b/hw/hppa/Kconfig
> > @@ -11,3 +11,4 @@ config DINO
> >   select MC146818RTC
> >   select LSI_SCSI_PCI
> >   select LASI_82596
> > +select LASIPS2
> 
> If these components are part of the LASI chipset, you don't need an specific
> Kconfig entry for each, you can simply use the LASI one.
> 
> Add a LASI entry in hw/hppa/Kconfig such:
> 
> config LASI
> bool
> select I82596_COMMON
> select PS2
> 

I'll send a patch as soon as this series is merged - that's easier than
resending the whole series.

Regards
Sven



Re: [PATCH v4 0/6] HPPA: i82596, PS/2 and graphics emulation

2019-11-23 Thread Sven Schnelle
On Sun, Nov 03, 2019 at 09:56:01PM +0100, Sven Schnelle wrote:
> Hi,
> 
> these series adds quite a lot to the HPPA emulation in QEMU:
> i82596 emulation from Helge, PS/2 and Artist graphics emulation.
> [..]

Ping? :-)

Regards
Sven



Re: [PATCH 3/5] hw/display/artist: Delay some variables initialization

2020-02-15 Thread Sven Schnelle
On Fri, Feb 14, 2020 at 01:13:00AM +0100, Philippe Mathieu-Daudé wrote:
> We want to have an early exit path. Delay some initializations
> before the variables are used.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/display/artist.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/display/artist.c b/hw/display/artist.c
> index 47f0e9f0bc..97c811b35e 100644
> --- a/hw/display/artist.c
> +++ b/hw/display/artist.c
> @@ -557,90 +557,90 @@ static void fill_window(ARTISTState *s, int startx, int 
> starty,
>  static void draw_line(ARTISTState *s, int x1, int y1, int x2, int y2,
>bool update_start, int skip_pix, int max_pix)
>  {
>  struct vram_buffer *buf;
> -uint8_t color = artist_get_color(s);
> +uint8_t color;
>  int dx, dy, t, e, x, y, incy, diago, horiz;
>  bool c1;
>  uint8_t *p;
>  
>  trace_artist_draw_line(x1, y1, x2, y2);
>  
>  if (update_start) {
>  s->vram_start = (x2 << 16) | y2;
>  }
>  
> -buf = &s->vram_buffer[ARTIST_BUFFER_AP];
> -
> -c1 = false;
> -
>  if (x2 > x1) {
>  dx = x2 - x1;
>  } else {
>  dx = x1 - x2;
>  }
>  if (y2 > y1) {
>  dy = y2 - y1;
>  } else {
>  dy = y1 - y2;
>  }
> +
> +c1 = false;
>  if (dy > dx) {
>  t = y2;
>  y2 = x2;
>  x2 = t;
>  
>  t = y1;
>  y1 = x1;
>  x1 = t;
>  
>  t = dx;
>  dx = dy;
>  dy = t;
>  
>  c1 = true;
>  }
>  
>  if (x1 > x2) {
>  t = y2;
>  y2 = y1;
>  y1 = t;
>  
>  t = x1;
>  x1 = x2;
>  x2 = t;
>  }
>  
>  horiz = dy << 1;
>  diago = (dy - dx) << 1;
>  e = (dy << 1) - dx;
>  
>  if (y1 <= y2) {
>  incy = 1;
>  } else {
>  incy = -1;
>  }
>  x = x1;
>  y = y1;
> +color = artist_get_color(s);
> +buf = &s->vram_buffer[ARTIST_BUFFER_AP];
>  
>  do {
>  if (c1) {
>  p = buf->data + x * s->width + y;
>  } else {
>  p = buf->data + y * s->width + x;
>  }
>  
>  if (skip_pix > 0) {
>  skip_pix--;
>  } else {
>  artist_rop8(s, p, color);
>  }
>  
>  if (e > 0) {
>  artist_invalidate_lines(buf, y, 1);
>  y  += incy;
>  e  += diago;
>  } else {
>  e += horiz;
>  }
>  x++;
>  } while (x <= x2 && (max_pix == -1 || --max_pix > 0));
>  }
> -- 
> 2.21.1
> 

Acked-by: Sven Schnelle 



Re: [PATCH 5/5] hw/display/artist: Remove dead code (CID 1419388 & 1419389)

2020-02-15 Thread Sven Schnelle
On Fri, Feb 14, 2020 at 01:13:02AM +0100, Philippe Mathieu-Daudé wrote:
> Coverity reports:
> 
>   *** CID 1419388:  Control flow issues  (DEADCODE)
>   /hw/display/artist.c: 739 in draw_line_xy()
>   733 if (endy < 0) {
>   734 endy = 0;
>   735 }
>   736
>   737
>   738 if (endx < 0) {
>   >>> CID 1419388:  Control flow issues  (DEADCODE)
>   >>> Execution cannot reach this statement: "return;".
>   739 return;
>   740 }
>   741
>   742 if (endy < 0) {
>   743 return;
>   744 }
> 
>   *** CID 1419389:  Control flow issues  (DEADCODE)
>   /hw/display/artist.c: 743 in draw_line_xy()
>   737
>   738 if (endx < 0) {
>   739 return;
>   740 }
>   741
>   742 if (endy < 0) {
>   >>> CID 1419389:  Control flow issues  (DEADCODE)
>   >>> Execution cannot reach this statement: "return;".
>   743 return;
>   744 }
>   745
>   746 trace_artist_draw_line(startx, starty, endx, endy);
>   747 draw_line(s, startx, starty, endx, endy, false, -1, -1);
>   748 }
> 
> Fixes: Covertiy CID 1419388 and 1419389 (commit 4765384ce33)
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/display/artist.c | 9 -
>  1 file changed, 9 deletions(-)
> 
> diff --git a/hw/display/artist.c b/hw/display/artist.c
> index 5492079116..753dbb9a77 100644
> --- a/hw/display/artist.c
> +++ b/hw/display/artist.c
> @@ -690,59 +690,50 @@ static void draw_line_size(ARTISTState *s, bool 
> update_start)
>  static void draw_line_xy(ARTISTState *s, bool update_start)
>  {
>  
>  int startx = artist_get_x(s->vram_start);
>  int starty = artist_get_y(s->vram_start);
>  int sizex = artist_get_x(s->blockmove_size);
>  int sizey = artist_get_y(s->blockmove_size);
>  int linexy = s->line_xy >> 16;
>  int endx, endy;
>  
>  endx = startx;
>  endy = starty;
>  
>  if (sizex > 0) {
>  endx = startx + linexy;
>  }
>  
>  if (sizex < 0) {
>  endx = startx;
>  startx -= linexy;
>  }
>  
>  if (sizey > 0) {
>  endy = starty + linexy;
>  }
>  
>  if (sizey < 0) {
>  endy = starty;
>  starty -= linexy;
>  }
>  
>  if (startx < 0) {
>  startx = 0;
>  }
>  
>  if (endx < 0) {
>      endx = 0;
>  }
>  
>  if (starty < 0) {
>  starty = 0;
>  }
>  
>  if (endy < 0) {
>  endy = 0;
>  }
>  
> -
> -if (endx < 0) {
> -return;
> -}
> -
> -if (endy < 0) {
> -return;
> -}
> -
>  draw_line(s, startx, starty, endx, endy, false, -1, -1);
>  }
>  
> -- 
> 2.21.1
> 

Acked-by: Sven Schnelle 



Re: [PATCH 2/5] hw/display/artist: Remove pointless initialization

2020-02-15 Thread Sven Schnelle
On Fri, Feb 14, 2020 at 01:12:59AM +0100, Philippe Mathieu-Daudé wrote:
> We are initializating incy inconditionally:
> 
> if (y1 <= y2) {
> incy = 1;
> } else {
> incy = -1;
> }
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/display/artist.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/hw/display/artist.c b/hw/display/artist.c
> index abacb0e27d..47f0e9f0bc 100644
> --- a/hw/display/artist.c
> +++ b/hw/display/artist.c
> @@ -557,91 +557,90 @@ static void fill_window(ARTISTState *s, int startx, int 
> starty,
>  static void draw_line(ARTISTState *s, int x1, int y1, int x2, int y2,
>bool update_start, int skip_pix, int max_pix)
>  {
>  struct vram_buffer *buf;
>  uint8_t color = artist_get_color(s);
>  int dx, dy, t, e, x, y, incy, diago, horiz;
>  bool c1;
>  uint8_t *p;
>  
>  trace_artist_draw_line(x1, y1, x2, y2);
>  
>  if (update_start) {
>  s->vram_start = (x2 << 16) | y2;
>  }
>  
>  buf = &s->vram_buffer[ARTIST_BUFFER_AP];
>  
>  c1 = false;
> -incy = 1;
>  
>  if (x2 > x1) {
>  dx = x2 - x1;
>  } else {
>  dx = x1 - x2;
>  }
>  if (y2 > y1) {
>  dy = y2 - y1;
>  } else {
>  dy = y1 - y2;
>  }
>  if (dy > dx) {
>  t = y2;
>  y2 = x2;
>  x2 = t;
>  
>  t = y1;
>  y1 = x1;
>  x1 = t;
>  
>  t = dx;
>  dx = dy;
>  dy = t;
>  
>  c1 = true;
>  }
>  
>  if (x1 > x2) {
>  t = y2;
>  y2 = y1;
>  y1 = t;
>  
>  t = x1;
>  x1 = x2;
>  x2 = t;
>  }
>  
>  horiz = dy << 1;
>  diago = (dy - dx) << 1;
>  e = (dy << 1) - dx;
>  
>  if (y1 <= y2) {
>  incy = 1;
>  } else {
>  incy = -1;
>  }
>  x = x1;
>  y = y1;
>  
>  do {
>  if (c1) {
>  p = buf->data + x * s->width + y;
>  } else {
>  p = buf->data + y * s->width + x;
>  }
>  
>  if (skip_pix > 0) {
>  skip_pix--;
>  } else {
>      artist_rop8(s, p, color);
>  }
>  
>  if (e > 0) {
>  artist_invalidate_lines(buf, y, 1);
>  y  += incy;
>  e  += diago;
>  } else {
>  e += horiz;
>  }
>  x++;
>  } while (x <= x2 && (max_pix == -1 || --max_pix > 0));
>  }
> -- 
> 2.21.1
> 

Acked-by: Sven Schnelle 



Re: [PATCH 1/5] hw/display/artist: Move trace event to draw_line()

2020-02-15 Thread Sven Schnelle
   int sizex = artist_get_x(s->blockmove_size);
>  int sizey = artist_get_y(s->blockmove_size);
>  int linexy = s->line_xy >> 16;
>  int endx, endy;
>  
>  endx = startx;
>  endy = starty;
>  
>  if (sizex > 0) {
>  endx = startx + linexy;
>  }
>  
>  if (sizex < 0) {
>  endx = startx;
>  startx -= linexy;
>  }
>  
>  if (sizey > 0) {
>  endy = starty + linexy;
>  }
>  
>  if (sizey < 0) {
>  endy = starty;
>  starty -= linexy;
>  }
>  
>  if (startx < 0) {
>  startx = 0;
>  }
>  
>  if (endx < 0) {
>  endx = 0;
>  }
>  
>  if (starty < 0) {
>  starty = 0;
>  }
>  
>  if (endy < 0) {
>  endy = 0;
>  }
>  
>  
>  if (endx < 0) {
>  return;
>  }
>  
>  if (endy < 0) {
>  return;
>  }
>  
> -trace_artist_draw_line(startx, starty, endx, endy);
>  draw_line(s, startx, starty, endx, endy, false, -1, -1);
>  }
>  
>  static void draw_line_end(ARTISTState *s, bool update_start)
>  {
>  
>  int startx = artist_get_x(s->vram_start);
>  int starty = artist_get_y(s->vram_start);
>  int endx = artist_get_x(s->line_end);
>  int endy = artist_get_y(s->line_end);
>  
> -trace_artist_draw_line(startx, starty, endx, endy);
>  draw_line(s, startx, starty, endx, endy, update_start, -1, -1);
>  }
>  
> -- 
> 2.21.1
> 

Acked-by: Sven Schnelle 



Re: [PATCH] net: tulip: check frame size and r/w data length

2020-02-15 Thread Sven Schnelle
Hi,

thanks for your patch.

On Tue, Feb 11, 2020 at 01:09:30PM +0530, P J P wrote:
> From: Prasad J Pandit 
> diff --git a/hw/net/tulip.c b/hw/net/tulip.c
> index cfac2719d3..aca2a3f17f 100644
> --- a/hw/net/tulip.c
> +++ b/hw/net/tulip.c
> @@ -164,27 +164,35 @@ static void tulip_copy_rx_bytes(TULIPState *s, struct 
> tulip_descriptor *desc)
>  int len2 = (desc->control >> RDES1_BUF2_SIZE_SHIFT) & 
> RDES1_BUF2_SIZE_MASK;
>  int len;
>  
> -if (s->rx_frame_len && len1) {
> -if (s->rx_frame_len > len1) {
> -len = len1;
> -} else {
> -len = s->rx_frame_len;
> -}
> -pci_dma_write(&s->dev, desc->buf_addr1, s->rx_frame +
> -(s->rx_frame_size - s->rx_frame_len), len);
> -s->rx_frame_len -= len;
> +if (!len1 || !len2 || !s->rx_frame_len) {
> +return;

I haven't tested the patch yet, but would that work if the guest OS passes
only one buffer to the card? I.e. len1 = x, and len2 = 0 because only
buffer 1 is available?

Regards
Sven



[PATCH v2] fdc/i8257: implement verify transfer mode

2019-10-30 Thread Sven Schnelle
While working on the Tulip driver i tried to write some Teledisk images to
a floppy image which didn't work. Turned out that Teledisk checks the written
data by issuing a READ command to the FDC but running the DMA controller
in VERIFY mode. As we ignored the DMA request in that case, the DMA transfer
never finished, and Teledisk reported an error.

The i8257 spec says about verify transfers:

3) DMA verify, which does not actually involve the transfer of data. When an
8257 channel is in the DMA verify mode, it will respond the same as described
for transfer operations, except that no memory or I/O read/write control signals
will be generated.

Hervé proposed to remove all the dma_mode_ok stuff from fdc to have a more
clear boundary between DMA and FDC, so this patch also does that.

Suggested-by: Hervé Poussineau 
Signed-off-by: Sven Schnelle 
---
 hw/block/fdc.c   | 39 +++
 hw/dma/i8257.c   | 20 +---
 include/hw/isa/isa.h |  1 -
 3 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index ac5d31e8c1..18fd22bfb7 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1716,9 +1716,8 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int 
direction)
 if (fdctrl->dor & FD_DOR_DMAEN) {
 IsaDmaTransferMode dma_mode;
 IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
-bool dma_mode_ok;
+
 /* DMA transfer are enabled. Check if DMA channel is well programmed */
-dma_mode = k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann);
 FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
dma_mode, direction,
(128 << fdctrl->fifo[5]) *
@@ -1727,40 +1726,32 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int 
direction)
 case FD_DIR_SCANE:
 case FD_DIR_SCANL:
 case FD_DIR_SCANH:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_VERIFY);
 break;
 case FD_DIR_WRITE:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE);
 break;
 case FD_DIR_READ:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ);
 break;
 case FD_DIR_VERIFY:
-dma_mode_ok = true;
 break;
 default:
-dma_mode_ok = false;
 break;
 }
-if (dma_mode_ok) {
-/* No access is allowed until DMA transfer has completed */
-fdctrl->msr &= ~FD_MSR_RQM;
-if (direction != FD_DIR_VERIFY) {
-/* Now, we just have to wait for the DMA controller to
- * recall us...
- */
-k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
-k->schedule(fdctrl->dma);
-} else {
-/* Start transfer */
-fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
-fdctrl->data_len);
-}
-return;
+
+/* No access is allowed until DMA transfer has completed */
+fdctrl->msr &= ~FD_MSR_RQM;
+if (direction != FD_DIR_VERIFY) {
+/*
+ * Now, we just have to wait for the DMA controller to
+ * recall us...
+ */
+k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
+k->schedule(fdctrl->dma);
 } else {
-FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
-   direction);
+/* Start transfer */
+fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
+fdctrl->data_len);
 }
+return;
 }
 FLOPPY_DPRINTF("start non-DMA transfer\n");
 fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM;
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index 792f617eb4..85dad3d391 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -292,12 +292,6 @@ static uint64_t i8257_read_cont(void *opaque, hwaddr 
nport, unsigned size)
 return val;
 }
 
-static IsaDmaTransferMode i8257_dma_get_transfer_mode(IsaDma *obj, int nchan)
-{
-I8257State *d = I8257(obj);
-return (d->regs[nchan & 3].mode >> 2) & 3;
-}
-
 static bool i8257_dma_has_autoinitialization(IsaDma *obj, int nchan)
 {
 I8257State *d = I8257(obj);
@@ -400,6 +394,11 @@ static void i8257_dma_register_channel(IsaDma *obj, int 
nchan,
 r->opaque = opaque;
 }
 
+static bool i8257_is_verify_transfer(I8257Regs *r)
+{
+return (r->mode & 0x0c) == 0;
+}
+
 static int i8257_dma_read_memory(IsaDma *obj, int nchan, void *buf, int pos,
  int len)
 {
@@ -407,6 +406,10 @@ static int i8257_dma_read_memory(IsaDma *obj, int nchan, 
void *buf, int pos,
 I8257Regs *r = &d->regs[nchan & 3];
 hwaddr ad

[PATCH v3] fdc/i8257: implement verify transfer mode

2019-11-01 Thread Sven Schnelle
While working on the Tulip driver i tried to write some Teledisk images to
a floppy image which didn't work. Turned out that Teledisk checks the written
data by issuing a READ command to the FDC but running the DMA controller
in VERIFY mode. As we ignored the DMA request in that case, the DMA transfer
never finished, and Teledisk reported an error.

The i8257 spec says about verify transfers:

3) DMA verify, which does not actually involve the transfer of data. When an
8257 channel is in the DMA verify mode, it will respond the same as described
for transfer operations, except that no memory or I/O read/write control signals
will be generated.

Hervé proposed to remove all the dma_mode_ok stuff from fdc to have a more
clear boundary between DMA and FDC, so this patch also does that.

Suggested-by: Hervé Poussineau 
Signed-off-by: Sven Schnelle 
---
 hw/block/fdc.c   | 61 +---
 hw/dma/i8257.c   | 20 ++-
 include/hw/isa/isa.h |  1 -
 3 files changed, 31 insertions(+), 51 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index ac5d31e8c1..01812c7553 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1714,53 +1714,28 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int 
direction)
 }
 fdctrl->eot = fdctrl->fifo[6];
 if (fdctrl->dor & FD_DOR_DMAEN) {
-IsaDmaTransferMode dma_mode;
+/* DMA transfer is enabled. */
 IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
-bool dma_mode_ok;
-/* DMA transfer are enabled. Check if DMA channel is well programmed */
-dma_mode = k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann);
-FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
-   dma_mode, direction,
-   (128 << fdctrl->fifo[5]) *
+
+FLOPPY_DPRINTF("direction=%d (%d - %d)\n",
+   direction, (128 << fdctrl->fifo[5]) *
(cur_drv->last_sect - ks + 1), fdctrl->data_len);
-switch (direction) {
-case FD_DIR_SCANE:
-case FD_DIR_SCANL:
-case FD_DIR_SCANH:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_VERIFY);
-break;
-case FD_DIR_WRITE:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE);
-break;
-case FD_DIR_READ:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ);
-break;
-case FD_DIR_VERIFY:
-dma_mode_ok = true;
-break;
-default:
-dma_mode_ok = false;
-break;
-}
-if (dma_mode_ok) {
-/* No access is allowed until DMA transfer has completed */
-fdctrl->msr &= ~FD_MSR_RQM;
-if (direction != FD_DIR_VERIFY) {
-/* Now, we just have to wait for the DMA controller to
- * recall us...
- */
-k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
-k->schedule(fdctrl->dma);
-} else {
-/* Start transfer */
-fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
-fdctrl->data_len);
-}
-return;
+
+/* No access is allowed until DMA transfer has completed */
+fdctrl->msr &= ~FD_MSR_RQM;
+if (direction != FD_DIR_VERIFY) {
+/*
+ * Now, we just have to wait for the DMA controller to
+ * recall us...
+ */
+k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
+k->schedule(fdctrl->dma);
 } else {
-FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
-   direction);
+/* Start transfer */
+fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
+fdctrl->data_len);
 }
+return;
 }
 FLOPPY_DPRINTF("start non-DMA transfer\n");
 fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM;
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index 792f617eb4..85dad3d391 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -292,12 +292,6 @@ static uint64_t i8257_read_cont(void *opaque, hwaddr 
nport, unsigned size)
 return val;
 }
 
-static IsaDmaTransferMode i8257_dma_get_transfer_mode(IsaDma *obj, int nchan)
-{
-I8257State *d = I8257(obj);
-return (d->regs[nchan & 3].mode >> 2) & 3;
-}
-
 static bool i8257_dma_has_autoinitialization(IsaDma *obj, int nchan)
 {
 I8257State *d = I8257(obj);
@@ -400,6 +394,11 @@ static void i8257_dma_register_channel(IsaDma *obj, int 
nchan,
 r->opaque = opaque;
 }
 
+static bool i8257_is_verify_transfer(I8257Regs *r)
+{
+return (r->mode & 0x0c) == 0;
+}
+
 static int i8257_dma_read_memory(IsaDma 

Re: [PATCH v3 5/6] hppa: Add emulation of Artist graphics

2019-11-01 Thread Sven Schnelle
Hi Mark,

On Sat, Oct 26, 2019 at 07:54:40PM +0200, Sven Schnelle wrote:
> Hi Mark,
> 
> On Sat, Oct 26, 2019 at 10:35:20AM +0100, Mark Cave-Ayland wrote:
> 
> > > However, the VRAM in Artist is not really exposed to the Host. Instead,
> > > there's the Chipset inbetween that can do byte swapping (Colormap is LE,
> > > VRAM is BE) and Bit-to-Byte/Word/Dword conversion. For example you could
> > > write 0x55 into that VRAM region, and the chipset would expand that to
> > > VRAM Bytes: 00 01 00 01 00 01 00 01. And to make it even worse emulation
> > > wise it can also do different encodings for Read or Write accesses, and
> > > mask out certain bits of the data. So after trying to convert it to the
> > > "dirty bitmap" API i decided to just leave it as it is. The CPU load
> > > used by the display update code is usually < 1%, so it's ok for me.
> > 
> > Wow that sounds that some interesting hardware(!). Does it make sense to 
> > model the
> > behaviour of the chipset separately using a proxy MemoryRegion similar to 
> > virtio i.e.
> > introduce an intermediate IO MemoryRegion that does the swapping and then 
> > forward it
> > onto the VRAM MemoryRegion?
> 
> Thanks for the pointer, i'll check whether that would work. For now i
> think i'll remove the Artist patch from the series, so we can apply the
> other patches, and i'll re-submit Artist when it's done. I guess the
> rewrite to use a MemRegion is a bit bigger. But i would to get the other
> patches in especially the LASI Stuff as both Helge and i have a lot of
> stuff depending on that.

I've looked into it again and changed my mind. There are at least the following
functions that the Artist chip does before a Read/Write is passed to/from VRAM:

- endianess conversion (actually configurable via some register, but i don't
  know how and hardwired it depending on CMAP / FB access)

- The Address passed on the System bus are the X/Y coordinates added to the FB
  base address in the selected buffer instead of the VRAM offset for pixel data.
  I think that's configurable via the some registers, but i don't know how.
  Unfortunately there's absolutely no documentation about Artist available and
  everything was developed by reverse engineering.

- bitmap to Byte/Word conversion (not implemented yet for the VRAM window, only
  for the I/O register window)

So in my opinion it's way to much effort to squeeze all of that into the memory
space, and it is not really a Memory range that's just behind a bus bridge.

Regards
Sven



[PATCH v4 4/6] hppa: add emulation of LASI PS2 controllers

2019-11-03 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/hppa/Kconfig|   1 +
 hw/hppa/lasi.c |  10 +-
 hw/input/Kconfig   |   3 +
 hw/input/Makefile.objs |   1 +
 hw/input/lasips2.c | 289 +
 hw/input/ps2.c |   5 +
 hw/input/trace-events  |   5 +
 include/hw/input/lasips2.h |  16 ++
 include/hw/input/ps2.h |   1 +
 9 files changed, 330 insertions(+), 1 deletion(-)
 create mode 100644 hw/input/lasips2.c
 create mode 100644 include/hw/input/lasips2.h

diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 2a7b38d6d6..7f9be7f25c 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -11,3 +11,4 @@ config DINO
 select MC146818RTC
 select LSI_SCSI_PCI
 select LASI_82596
+select LASIPS2
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
index 51752589f3..d8d03f95c0 100644
--- a/hw/hppa/lasi.c
+++ b/hw/hppa/lasi.c
@@ -22,6 +22,7 @@
 #include "hw/net/lasi_82596.h"
 #include "hw/char/parallel.h"
 #include "hw/char/serial.h"
+#include "hw/input/lasips2.h"
 #include "exec/address-spaces.h"
 #include "migration/vmstate.h"
 
@@ -324,6 +325,7 @@ DeviceState *lasi_init(MemoryRegion *address_space)
  lpt_irq, parallel_hds[0]);
 
 /* Real time clock (RTC), it's only one 32-bit counter @9000 */
+
 s->rtc = time(NULL);
 s->rtc_ref = 0;
 
@@ -333,8 +335,14 @@ DeviceState *lasi_init(MemoryRegion *address_space)
 lasi_get_irq(LASI_UART_HPA));
 serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0,
 serial_irq, 800 / 16,
-serial_hd(1), DEVICE_NATIVE_ENDIAN);
+serial_hd(0), DEVICE_NATIVE_ENDIAN);
 }
+
+/* PS/2 Keyboard/Mouse */
+qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s,
+lasi_get_irq(LASI_PS2KBD_HPA));
+lasips2_init(address_space, LASI_PS2KBD_HPA,  ps2kbd_irq);
+
 return dev;
 }
 
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
index 287f08887b..25c77a1b87 100644
--- a/hw/input/Kconfig
+++ b/hw/input/Kconfig
@@ -41,3 +41,6 @@ config VHOST_USER_INPUT
 
 config TSC210X
 bool
+
+config LASIPS2
+select PS2
diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
index a1bc502ed0..f98f635685 100644
--- a/hw/input/Makefile.objs
+++ b/hw/input/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VHOST_USER_INPUT) += vhost-user-input.o
 obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_keypad.o
 obj-$(CONFIG_TSC210X) += tsc210x.o
+obj-$(CONFIG_LASIPS2) += lasips2.o
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
new file mode 100644
index 00..1943671d1e
--- /dev/null
+++ b/hw/input/lasips2.c
@@ -0,0 +1,289 @@
+/*
+ * QEMU HP Lasi PS/2 interface emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/hw.h"
+#include "hw/input/ps2.h"
+#include "hw/input/lasips2.h"
+#include "hw/sysbus.h"
+#include "exec/hwaddr.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+struct LASIPS2State;
+typedef struct LASIPS2Port {
+struct LASIPS2State *parent;
+MemoryRegion reg;
+void *dev;
+uint8_t id;
+uint8_t control;
+uint8_t buf;
+bool loopback_rbne;
+bool irq;
+} LASIPS2Port;
+
+typedef struct LASIPS2State {
+LASIPS2Port kbd;
+LASIPS2Port mouse;
+qemu_irq irq;
+} LASIPS2State;
+
+static const VMStateDescription vmstate_lasips2 = {
+.name = "lasips2",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]

[PATCH v4 0/6] HPPA: i82596, PS/2 and graphics emulation

2019-11-03 Thread Sven Schnelle
Hi,

these series adds quite a lot to the HPPA emulation in QEMU:
i82596 emulation from Helge, PS/2 and Artist graphics emulation.

See https://parisc.wiki.kernel.org/index.php/Qemu for a few screenshots
of QEMU running a X11/CDE session in HP-UX.

changes in v4:
 - introduce Artist-internal address space
 - rewrite screen update functions to use the generic framebuffer routines
 - use dirty bitmap code to not always redraw the whole screen

Changes in v3:
 - use BIT() macro in gsc_to_pci_forwarding()
 - fix version id in vm state
 - fix an error in the PS/2 KBD_CMD_SET_MAKE_BREAK implementation

Changes in v2:
 - dropped 'hppa: remove ISA region' as that patch requires some more work
 - added shortlog to seabios update
 - use const and MAKE_64BIT_MASK in dino.c

Regards,
Sven

Helge Deller (2):
  hw/hppa/dino.c: Improve emulation of Dino PCI chip
  hppa: Add support for LASI chip with i82596 NIC

Sven Schnelle (4):
  ps2: accept 'Set Key Make and Break' commands
  hppa: add emulation of LASI PS2 controllers
  hppa: Add emulation of Artist graphics
  seabios-hppa: update to latest version

 MAINTAINERS |4 +-
 hw/display/Kconfig  |4 +
 hw/display/Makefile.objs|1 +
 hw/display/artist.c | 1449 +++
 hw/display/trace-events |9 +
 hw/hppa/Kconfig |3 +
 hw/hppa/Makefile.objs   |2 +-
 hw/hppa/dino.c  |   97 ++-
 hw/hppa/hppa_hardware.h |1 +
 hw/hppa/hppa_sys.h  |2 +
 hw/hppa/lasi.c  |  368 +
 hw/hppa/machine.c   |   17 +-
 hw/hppa/trace-events|   10 +
 hw/input/Kconfig|3 +
 hw/input/Makefile.objs  |1 +
 hw/input/lasips2.c  |  289 +++
 hw/input/ps2.c  |   15 +
 hw/input/trace-events   |5 +
 hw/net/Kconfig  |7 +
 hw/net/Makefile.objs|2 +
 hw/net/i82596.c |  734 ++
 hw/net/i82596.h |   55 ++
 hw/net/lasi_i82596.c|  188 +
 hw/net/trace-events |   14 +
 include/hw/input/lasips2.h  |   16 +
 include/hw/input/ps2.h  |1 +
 include/hw/net/lasi_82596.h |   29 +
 pc-bios/hppa-firmware.img   |  Bin 783724 -> 772876 bytes
 roms/seabios-hppa   |2 +-
 29 files changed, 3310 insertions(+), 18 deletions(-)
 create mode 100644 hw/display/artist.c
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/input/lasips2.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/input/lasips2.h
 create mode 100644 include/hw/net/lasi_82596.h

-- 
2.24.0.rc2




[PATCH v4 5/6] hppa: Add emulation of Artist graphics

2019-11-03 Thread Sven Schnelle
This adds emulation of Artist graphics good enough
to get a Text console on both Linux and HP-UX. The
X11 server from HP-UX also works.

Signed-off-by: Sven Schnelle 
---
 hw/display/Kconfig   |4 +
 hw/display/Makefile.objs |1 +
 hw/display/artist.c  | 1449 ++
 hw/display/trace-events  |9 +
 hw/hppa/Kconfig  |1 +
 hw/hppa/hppa_hardware.h  |1 +
 hw/hppa/machine.c|9 +
 7 files changed, 1474 insertions(+)
 create mode 100644 hw/display/artist.c

diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index c500d1fc6d..15d59e10dc 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -91,6 +91,10 @@ config TCX
 config CG3
 bool
 
+config ARTIST
+bool
+select FRAMEBUFFER
+
 config VGA
 bool
 
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index f2182e3bef..5f03dfdcc4 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -40,6 +40,7 @@ common-obj-$(CONFIG_SM501) += sm501.o
 common-obj-$(CONFIG_TCX) += tcx.o
 common-obj-$(CONFIG_CG3) += cg3.o
 common-obj-$(CONFIG_NEXTCUBE) += next-fb.o
+common-obj-$(CONFIG_ARTIST) += artist.o
 
 obj-$(CONFIG_VGA) += vga.o
 
diff --git a/hw/display/artist.c b/hw/display/artist.c
new file mode 100644
index 00..1d6c7d5d76
--- /dev/null
+++ b/hw/display/artist.c
@@ -0,0 +1,1449 @@
+/*
+ * QEMU HP Artist Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/typedefs.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/loader.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "ui/console.h"
+#include "trace.h"
+#include "hw/display/framebuffer.h"
+
+#define TYPE_ARTIST "artist"
+#define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST)
+
+#ifdef HOST_WORDS_BIGENDIAN
+#define ROP8OFF(_i) (3 - (_i))
+#else
+#define ROP8OFF
+#endif
+
+struct vram_buffer {
+MemoryRegion mr;
+uint8_t *data;
+int size;
+int width;
+int height;
+};
+
+typedef struct ARTISTState {
+SysBusDevice parent_obj;
+
+QemuConsole *con;
+MemoryRegion vram_mem;
+MemoryRegion mem_as_root;
+MemoryRegion reg;
+MemoryRegionSection fbsection;
+
+void *vram_int_mr;
+AddressSpace as;
+
+struct vram_buffer vram_buffer[16];
+
+uint16_t width;
+uint16_t height;
+uint16_t depth;
+
+uint32_t fg_color;
+uint32_t bg_color;
+
+uint32_t vram_char_y;
+uint32_t vram_bitmask;
+
+uint32_t vram_start;
+uint32_t vram_pos;
+
+uint32_t vram_size;
+
+uint32_t blockmove_source;
+uint32_t blockmove_dest;
+uint32_t blockmove_size;
+
+uint32_t line_size;
+uint32_t line_end;
+uint32_t line_xy;
+uint32_t line_pattern_start;
+uint32_t line_pattern_skip;
+
+uint32_t cursor_pos;
+
+uint32_t cursor_height;
+uint32_t cursor_width;
+
+uint32_t plane_mask;
+
+uint32_t reg_100080;
+uint32_t reg_300200;
+uint32_t reg_300208;
+uint32_t reg_300218;
+
+uint32_t cmap_bm_access;
+uint32_t dst_bm_access;
+uint32_t src_bm_access;
+uint32_t control_plane;
+uint32_t transfer_data;
+uint32_t image_bitmap_op;
+
+uint32_t font_write1;
+uint32_t font_write2;
+uint32_t font_write_pos_y;
+
+int draw_line_pattern;
+} ARTISTState;
+
+typedef enum {
+ARTIST_BUFFER_AP = 1,
+ARTIST_BUFFER_OVERLAY = 2,
+ARTIST_BUFFER_CURSOR1 = 6,
+ARTIST_BUFFER_CURSOR2 = 7,
+ARTIST_BUFFER_ATTRIBUTE = 13,
+ARTIST_BUFFER_CMAP = 15,
+} artist_buffer_t;
+
+typedef enum {
+VRAM_IDX = 0x1004a0,
+VRAM_BITMASK = 0x1005a0,
+VRAM_WRITE_INCR_X = 0x100600,
+VRAM_WRITE_INCR_X2 = 0x100604,
+VRAM_WRITE_INCR_Y = 0x100620,
+VRAM_START = 0x100800,
+BLOCK_MOVE_SIZE = 0x100804,
+BLOCK_MOVE_SOURCE = 0x100808,
+TRANSFER_DATA = 0x100820,
+FONT_WRITE_INCR_Y = 0x1008a0,
+VRAM_START_TRIGGER = 0x100a00,
+VRAM_SIZE_TRIGGER = 0x100a04,
+FONT_WRITE_START = 0x100aa0,
+BLOCK_MOVE_DEST_TRIGGER = 0x100b00,
+BLOCK_MOVE_SIZE_TRIGGER = 0x100b04,
+LINE_XY = 0x100ccc,
+PATTERN_LINE_START = 0x100ecc,
+LINE_SIZE = 0x100e04,
+LINE_END = 0x100e44,
+CMAP_BM_ACCESS = 0x118000,
+DST_BM_ACCESS = 0x118004,
+SRC_BM_ACCESS = 0x118008,
+CONTROL_PLANE = 0x11800c,
+FG_COLOR = 0x118010,
+BG_COLOR = 0x118014,
+PLANE_MASK = 0x118018,
+IMAGE_BITMAP_OP = 0x11801c,
+CURSOR_POS = 0x300100,
+CURSOR_CTRL = 0x300104,
+} artist_reg_t;
+
+typedef enum {
+ARTIST_ROP_CLEAR = 0,

[PATCH v4 1/6] hw/hppa/dino.c: Improve emulation of Dino PCI chip

2019-11-03 Thread Sven Schnelle
From: Helge Deller 

The tests of the dino chip with the Online-diagnostics CD
("ODE DINOTEST") now succeeds.
Additionally add some qemu trace events.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
Reviewed-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS  |  2 +-
 hw/hppa/dino.c   | 97 +---
 hw/hppa/trace-events |  5 +++
 3 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 92961faa0e..7f8abbddab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -874,7 +874,7 @@ F: hw/*/etraxfs_*.c
 
 HP-PARISC Machines
 --
-Dino
+HP B160L
 M: Richard Henderson 
 R: Helge Deller 
 S: Odd Fixes
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index ab6969b45f..9797a7f0d9 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -1,7 +1,7 @@
 /*
- * HP-PARISC Dino PCI chipset emulation.
+ * HP-PARISC Dino PCI chipset emulation, as in B160L and similiar machines
  *
- * (C) 2017 by Helge Deller 
+ * (C) 2017-2019 by Helge Deller 
  *
  * This work is licensed under the GNU GPL license version 2 or later.
  *
@@ -21,6 +21,7 @@
 #include "migration/vmstate.h"
 #include "hppa_sys.h"
 #include "exec/address-spaces.h"
+#include "trace.h"
 
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
@@ -82,11 +83,28 @@
 #define DINO_PCI_HOST_BRIDGE(obj) \
 OBJECT_CHECK(DinoState, (obj), TYPE_DINO_PCI_HOST_BRIDGE)
 
+#define DINO800_REGS ((DINO_TLTIM - DINO_GMASK) / 4)
+static const uint32_t reg800_keep_bits[DINO800_REGS] = {
+MAKE_64BIT_MASK(0, 1),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 8),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 9),
+MAKE_64BIT_MASK(0, 32),
+MAKE_64BIT_MASK(0, 8),
+MAKE_64BIT_MASK(0, 30),
+MAKE_64BIT_MASK(0, 25),
+MAKE_64BIT_MASK(0, 22),
+MAKE_64BIT_MASK(0, 9),
+};
+
 typedef struct DinoState {
 PCIHostState parent_obj;
 
 /* PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.  */
+uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
 
 uint32_t iar0;
 uint32_t iar1;
@@ -94,8 +112,12 @@ typedef struct DinoState {
 uint32_t ipr;
 uint32_t icr;
 uint32_t ilr;
+uint32_t io_fbb_en;
 uint32_t io_addr_en;
 uint32_t io_control;
+uint32_t toc_addr;
+
+uint32_t reg800[DINO800_REGS];
 
 MemoryRegion this_mem;
 MemoryRegion pci_mem;
@@ -106,8 +128,6 @@ typedef struct DinoState {
 MemoryRegion bm_ram_alias;
 MemoryRegion bm_pci_alias;
 MemoryRegion bm_cpu_alias;
-
-MemoryRegion cpu0_eir_mem;
 } DinoState;
 
 /*
@@ -122,6 +142,8 @@ static void gsc_to_pci_forwarding(DinoState *s)
 tmp = extract32(s->io_control, 7, 2);
 enabled = (tmp == 0x01);
 io_addr_en = s->io_addr_en;
+/* Mask out first (=firmware) and last (=Dino) areas. */
+io_addr_en &= ~(BIT(31) | BIT(0));
 
 memory_region_transaction_begin();
 for (i = 1; i < 31; i++) {
@@ -142,6 +164,8 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 unsigned size, bool is_write,
 MemTxAttrs attrs)
 {
+bool ret = false;
+
 switch (addr) {
 case DINO_IAR0:
 case DINO_IAR1:
@@ -152,16 +176,22 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 case DINO_ICR:
 case DINO_ILR:
 case DINO_IO_CONTROL:
+case DINO_IO_FBB_EN:
 case DINO_IO_ADDR_EN:
 case DINO_PCI_IO_DATA:
-return true;
+case DINO_TOC_ADDR:
+case DINO_GMASK ... DINO_TLTIM:
+ret = true;
+break;
 case DINO_PCI_IO_DATA + 2:
-return size <= 2;
+ret = (size <= 2);
+break;
 case DINO_PCI_IO_DATA + 1:
 case DINO_PCI_IO_DATA + 3:
-return size == 1;
+ret = (size == 1);
 }
-return false;
+trace_dino_chip_mem_valid(addr, ret);
+return ret;
 }
 
 static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr,
@@ -194,6 +224,9 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, 
hwaddr addr,
 }
 break;
 
+case DINO_IO_FBB_EN:
+val = s->io_fbb_en;
+break;
 case DINO_IO_ADDR_EN:
 val = s->io_addr_en;
 break;
@@ -227,12 +260,28 @@ static MemTxResult dino_chip_read_with_attrs(void 
*opaque, hwaddr addr,
 case DINO_IRR1:
 val = s->ilr & s->imr & s->icr;
 break;
+case DINO_TOC_ADDR:
+val = s->toc_addr;
+break;
+case DINO_GMASK ... DINO_TLTIM:
+val = s->reg800[(addr - DINO_GMASK) / 4];
+if (addr == DINO_PAMR) {
+val &= ~0x01;  /* LSB is hardwired to 0 */
+}
+i

[PATCH v4 3/6] ps2: accept 'Set Key Make and Break' commands

2019-11-03 Thread Sven Schnelle
HP-UX sends both the 'Set key make and break (0xfc) and
'Set all key typematic make and break' (0xfa). QEMU response
with 'Resend' as it doesn't handle these commands. HP-UX than
reports an PS/2 max retransmission exceeded error. Add these
commands and just reply with ACK.

Signed-off-by: Sven Schnelle 
---
 hw/input/ps2.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 67f92f6112..0b671b6339 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -49,6 +49,8 @@
 #define KBD_CMD_RESET_DISABLE  0xF5/* reset and disable scanning */
 #define KBD_CMD_RESET_ENABLE   0xF6/* reset and enable scanning */
 #define KBD_CMD_RESET  0xFF/* Reset */
+#define KBD_CMD_SET_MAKE_BREAK  0xFC/* Set Make and Break mode */
+#define KBD_CMD_SET_TYPEMATIC   0xFA/* Set Typematic Make and Break mode */
 
 /* Keyboard Replies */
 #define KBD_REPLY_POR  0xAA/* Power on reset */
@@ -573,6 +575,7 @@ void ps2_write_keyboard(void *opaque, int val)
 case KBD_CMD_SCANCODE:
 case KBD_CMD_SET_LEDS:
 case KBD_CMD_SET_RATE:
+case KBD_CMD_SET_MAKE_BREAK:
 s->common.write_cmd = val;
 ps2_queue(&s->common, KBD_REPLY_ACK);
 break;
@@ -592,11 +595,18 @@ void ps2_write_keyboard(void *opaque, int val)
 KBD_REPLY_ACK,
 KBD_REPLY_POR);
 break;
+case KBD_CMD_SET_TYPEMATIC:
+ps2_queue(&s->common, KBD_REPLY_ACK);
+break;
 default:
 ps2_queue(&s->common, KBD_REPLY_RESEND);
 break;
 }
 break;
+case KBD_CMD_SET_MAKE_BREAK:
+ps2_queue(&s->common, KBD_REPLY_ACK);
+s->common.write_cmd = -1;
+break;
 case KBD_CMD_SCANCODE:
 if (val == 0) {
 if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
-- 
2.24.0.rc2




[PATCH v4 2/6] hppa: Add support for LASI chip with i82596 NIC

2019-11-03 Thread Sven Schnelle
From: Helge Deller 

LASI is a built-in multi-I/O chip which supports serial, parallel,
network (Intel i82596 Apricot), sound and other functionalities.
LASI has been used in many HP PARISC machines.
This patch adds the necessary parts to allow Linux and HP-UX to detect
LASI and the network card.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
---
 MAINTAINERS |   2 +
 hw/hppa/Kconfig |   1 +
 hw/hppa/Makefile.objs   |   2 +-
 hw/hppa/hppa_sys.h  |   2 +
 hw/hppa/lasi.c  | 360 ++
 hw/hppa/machine.c   |   8 +-
 hw/hppa/trace-events|   5 +
 hw/net/Kconfig  |   7 +
 hw/net/Makefile.objs|   2 +
 hw/net/i82596.c | 734 
 hw/net/i82596.h |  55 +++
 hw/net/lasi_i82596.c| 188 +
 hw/net/trace-events |  14 +
 include/hw/net/lasi_82596.h |  29 ++
 14 files changed, 1407 insertions(+), 2 deletions(-)
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/net/lasi_82596.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7f8abbddab..c4cdd761ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -178,6 +178,8 @@ S: Maintained
 F: target/hppa/
 F: hw/hppa/
 F: disas/hppa.c
+F: hw/net/*i82596*
+F: include/hw/net/lasi_82596.h
 
 LM32 TCG CPUs
 M: Michael Walle 
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 6e5d74a825..2a7b38d6d6 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -10,3 +10,4 @@ config DINO
 select IDE_CMD646
 select MC146818RTC
 select LSI_SCSI_PCI
+select LASI_82596
diff --git a/hw/hppa/Makefile.objs b/hw/hppa/Makefile.objs
index 67838f50a3..eac3467d8a 100644
--- a/hw/hppa/Makefile.objs
+++ b/hw/hppa/Makefile.objs
@@ -1 +1 @@
-obj-$(CONFIG_DINO) += pci.o machine.o dino.o
+obj-$(CONFIG_DINO) += pci.o machine.o dino.o lasi.o
diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h
index 43d25d21fc..d99b5dd87b 100644
--- a/hw/hppa/hppa_sys.h
+++ b/hw/hppa/hppa_sys.h
@@ -11,6 +11,8 @@
 #include "hppa_hardware.h"
 
 PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
+DeviceState *lasi_init(MemoryRegion *);
+#define enable_lasi_lan()   0
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
 
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
new file mode 100644
index 00..51752589f3
--- /dev/null
+++ b/hw/hppa/lasi.c
@@ -0,0 +1,360 @@
+/*
+ * HP-PARISC Lasi chipset emulation.
+ *
+ * (C) 2019 by Helge Deller 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ * Documentation available at:
+ * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "trace.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+#include "hppa_sys.h"
+#include "hw/net/lasi_82596.h"
+#include "hw/char/parallel.h"
+#include "hw/char/serial.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+
+#define TYPE_LASI_CHIP "lasi-chip"
+
+#define LASI_IRR0x00/* RO */
+#define LASI_IMR0x04
+#define LASI_IPR0x08
+#define LASI_ICR0x0c
+#define LASI_IAR0x10
+
+#define LASI_PCR0x0C000 /* LASI Power Control register */
+#define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */
+#define LASI_VER0x0C008 /* LASI Version Control register */
+#define LASI_IORESET0x0C00C /* LASI I/O Reset register */
+#define LASI_AMR0x0C010 /* LASI Arbitration Mask register */
+#define LASI_IO_CONF0x7FFFE /* LASI primary configuration register */
+#define LASI_IO_CONF2   0x7 /* LASI secondary configuration register */
+
+#define LASI_BIT(x) (1ul << (x))
+#define LASI_IRQ_BITS   (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) 
\
+| LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
+| LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
+| LASI_BIT(26))
+
+#define ICR_BUS_ERROR_BIT  LASI_BIT(8)  /* bit 8 in ICR */
+#define ICR_TOC_BITLASI_BIT(1)  /* bit 1 in ICR */
+
+#define LASI_CHIP(obj) \
+OBJECT_CHECK(LasiState, (obj), TYPE_LASI_CHIP)
+
+#define LASI_RTC_HPA(LASI_HPA + 0x9000)
+
+typedef struct LasiState {
+PCIHostState parent_obj;
+
+uint32_t irr;
+uint32_t imr;
+uint32_t ipr;
+uint32_t icr;
+uint32_t iar;
+
+uint32_t errlog;
+uint32_t amr;
+uint32_t rtc;
+time_t rtc_ref;
+
+MemoryRegion this_mem;
+} LasiState;
+
+static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
+unsigned size

Re: [PATCH v3 5/6] hppa: Add emulation of Artist graphics

2019-11-03 Thread Sven Schnelle
Hi Mark,

On Sun, Nov 03, 2019 at 08:56:43PM +, Mark Cave-Ayland wrote:
> On 01/11/2019 21:59, Sven Schnelle wrote:
> 
> > On Sat, Oct 26, 2019 at 07:54:40PM +0200, Sven Schnelle wrote:
> >> Hi Mark,
> >>
> >> On Sat, Oct 26, 2019 at 10:35:20AM +0100, Mark Cave-Ayland wrote:
> >>
> >>>> However, the VRAM in Artist is not really exposed to the Host. Instead,
> >>>> there's the Chipset inbetween that can do byte swapping (Colormap is LE,
> >>>> VRAM is BE) and Bit-to-Byte/Word/Dword conversion. For example you could
> >>>> write 0x55 into that VRAM region, and the chipset would expand that to
> >>>> VRAM Bytes: 00 01 00 01 00 01 00 01. And to make it even worse emulation
> >>>> wise it can also do different encodings for Read or Write accesses, and
> >>>> mask out certain bits of the data. So after trying to convert it to the
> >>>> "dirty bitmap" API i decided to just leave it as it is. The CPU load
> >>>> used by the display update code is usually < 1%, so it's ok for me.
> >>>
> >>> Wow that sounds that some interesting hardware(!). Does it make sense to 
> >>> model the
> >>> behaviour of the chipset separately using a proxy MemoryRegion similar to 
> >>> virtio i.e.
> >>> introduce an intermediate IO MemoryRegion that does the swapping and then 
> >>> forward it
> >>> onto the VRAM MemoryRegion?
> >>
> >> Thanks for the pointer, i'll check whether that would work. For now i
> >> think i'll remove the Artist patch from the series, so we can apply the
> >> other patches, and i'll re-submit Artist when it's done. I guess the
> >> rewrite to use a MemRegion is a bit bigger. But i would to get the other
> >> patches in especially the LASI Stuff as both Helge and i have a lot of
> >> stuff depending on that.
> > 
> > I've looked into it again and changed my mind. There are at least the 
> > following
> > functions that the Artist chip does before a Read/Write is passed to/from 
> > VRAM:
> > 
> > - endianess conversion (actually configurable via some register, but i don't
> >   know how and hardwired it depending on CMAP / FB access)
> > 
> > - The Address passed on the System bus are the X/Y coordinates added to the 
> > FB
> >   base address in the selected buffer instead of the VRAM offset for pixel 
> > data.
> >   I think that's configurable via the some registers, but i don't know how.
> >   Unfortunately there's absolutely no documentation about Artist available 
> > and
> >   everything was developed by reverse engineering.
> > 
> > - bitmap to Byte/Word conversion (not implemented yet for the VRAM window, 
> > only
> >   for the I/O register window)
> > 
> > So in my opinion it's way to much effort to squeeze all of that into the 
> > memory
> > space, and it is not really a Memory range that's just behind a bus bridge.
> 
> Hi Sven,
> 
> Certainly in some cases it isn't possible to model devices in QEMU exactly as 
> real
> hardware, although I think that some of the ideas above could be used to 
> improve the
> implementation without too much extra effort.
> 
> Then again from my work on QEMU I completely understand that sometimes this 
> can be
> difficult with older, more esoteric devices. Ultimately after review that 
> decision
> has to come from the maintainer(s) for the relevant devices/machines, so I 
> guess that
> would be Richard and/or Gerd in this case?

I think that would be Richard. I rewrote the code to at least use the generic
framebuffer functions now, and added dirty memory tracking. I'm still not happy
with all the endianess conversion that are going on, but without any
Documentation about chip it's impossible to say how the chip really works.

Regards
Sven



[PATCH] net: add tulip (dec21143) driver

2019-10-19 Thread Sven Schnelle
This adds the basic functionality to emulate a Tulip NIC.

Implemented are:

- RX and TX functionality
- Perfect Frame Filtering
- Big/Little Endian descriptor support
- 93C46 EEPROM support
- LXT970 PHY

Not implemented, mostly because i had no OS using these functions:

- Imperfect frame filtering
- General Purpose Timer
- Transmit automatic polling
- Boot ROM support
- SIA interface
- Big/Little Endian data buffer conversion

Successfully tested with the following Operating Systems:

- MSDOS with Microsoft Network Client 3.0 and DEC ODI drivers
- HPPA Linux
- Windows XP
- HP-UX

Signed-off-by: Sven Schnelle 
---
 MAINTAINERS  |   6 +
 hw/net/Kconfig   |   5 +
 hw/net/Makefile.objs |   1 +
 hw/net/trace-events  |  14 +
 hw/net/tulip.c   | 992 +++
 hw/net/tulip.h   | 265 +++
 include/hw/pci/pci_ids.h |   1 +
 7 files changed, 1284 insertions(+)
 create mode 100644 hw/net/tulip.c
 create mode 100644 hw/net/tulip.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 250ce8e7a1..a12031c389 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1638,6 +1638,12 @@ M: Stefan Weil 
 S: Maintained
 F: hw/net/eepro100.c
 
+tulip
+M: Sven Schnelle 
+S: Maintained
+F: hw/net/tulip.c
+F: hw/net/tulip.h
+
 Generic Loader
 M: Alistair Francis 
 S: Maintained
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 4ef86dc3a5..3856417d42 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -24,6 +24,11 @@ config PCNET_PCI
 config PCNET_COMMON
 bool
 
+config TULIP
+bool
+default y if PCI_DEVICES
+depends on PCI
+
 config E1000_PCI
 bool
 default y if PCI_DEVICES
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 9904273b06..7907d2c199 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -13,6 +13,7 @@ common-obj-$(CONFIG_E1000E_PCI_EXPRESS) += e1000e.o 
e1000e_core.o e1000x_common.
 common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
 common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o
 common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet3.o
+common-obj-$(CONFIG_TULIP) += tulip.o
 
 common-obj-$(CONFIG_SMC91C111) += smc91c111.o
 common-obj-$(CONFIG_LAN9118) += lan9118.o
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 58665655cc..e70f12bee1 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -367,3 +367,17 @@ virtio_net_announce_notify(void) ""
 virtio_net_announce_timer(int round) "%d"
 virtio_net_handle_announce(int round) "%d"
 virtio_net_post_load_device(void)
+
+# tulip.c
+tulip_reg_write(uint64_t addr, const char *name, int size, uint64_t val) "addr 
0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
+tulip_reg_read(uint64_t addr, const char *name, int size, uint64_t val) "addr 
0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
+tulip_receive(const uint8_t *buf, size_t len) "buf %p size %zu"
+tulip_descriptor(const char *prefix, uint32_t addr, uint32_t status, uint32_t 
control, uint32_t len1, uint32_t len2, uint32_t buf1, uint32_t buf2) "%s 
0x%08x: status 0x%08x control 0x%03x len1 %4d len2 %4d buf1 0x%08x buf2 0x%08x"
+tulip_rx_state(const char *state) "RX %s"
+tulip_tx_state(const char *state) "TX %s"
+tulip_irq(uint32_t mask, uint32_t en, const char *state) "mask 0x%08x ie 
0x%08x %s"
+tulip_mii_write(int phy, int reg, uint16_t data) "phy 0x%x reg 0x%x data 
0x%04x"
+tulip_mii_read(int phy, int reg, uint16_t data) "phy 0x%x, reg 0x%x data 
0x%04x"
+tulip_reset(void) ""
+tulip_setup_frame(void) ""
+tulip_setup_filter(int n, uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t 
e, uint8_t f) "%d: %02x:%02x:%02x:%02x:%02x:%02x"
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
new file mode 100644
index 00..a99b1b81c4
--- /dev/null
+++ b/hw/net/tulip.c
@@ -0,0 +1,992 @@
+/*
+ * QEMU TULIP Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "hw/nvram/eeprom93xx.h"
+#include "migration/vmstate.h"
+#include "sysemu/sysemu.h"
+#include "tulip.h"
+#include "trace.h"
+#include "net/eth.h"
+
+typedef struct TULIPState {
+PCIDevice dev;
+MemoryRegion io;
+MemoryRegion memory;
+NICConf c;
+qemu_irq irq;
+NICState *nic;
+eeprom_t *eeprom;
+uint32_t csr[16];
+
+/* state for MII */
+uint32_t old_csr9;
+uint32_t mii_word;
+uint32_t mii_bitcnt;
+
+hwaddr current_rx_desc;
+hwaddr current_tx_desc;
+
+uint8_t rx_frame[2048];
+uint8_t tx_frame[2048];
+uint16_t tx_frame_len;
+uint16_t rx_frame_len;
+uint16_t rx_frame_size

[PATCH] fdc: support READ command with VERIFY DMA mode

2019-10-19 Thread Sven Schnelle
While working on the Tulip driver i tried to write some Teledisk images to
a floppy image which didn't work. Turned out that Teledisk checks the written
data by issuing a READ command to the FDC but running the DMA controller
in VERIFY mode. As we ignored the DMA request in that case, the DMA transfer
never finished, and Teledisk reported an error.

Signed-off-by: Sven Schnelle 
---
 hw/block/fdc.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index ac5d31e8c1..8a1228df78 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1733,7 +1733,8 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int 
direction)
 dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE);
 break;
 case FD_DIR_READ:
-dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ);
+dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ) ||
+  (dma_mode == ISADMA_TRANSFER_VERIFY);
 break;
 case FD_DIR_VERIFY:
 dma_mode_ok = true;
@@ -1835,8 +1836,11 @@ static int fdctrl_transfer_handler (void *opaque, int 
nchan,
 switch (fdctrl->data_dir) {
 case FD_DIR_READ:
 /* READ commands */
-k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
-fdctrl->data_pos, len);
+if (k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann) !=
+ISADMA_TRANSFER_VERIFY) {
+k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
+fdctrl->data_pos, len);
+}
 break;
 case FD_DIR_WRITE:
 /* WRITE commands */
-- 
2.23.0




[PATCH 3/7] hppa: remove ISA region

2019-10-20 Thread Sven Schnelle
B160L doesn't have an ISA bus, and we no longer need it to
workaround missing hardware, so remove it.

Signed-off-by: Sven Schnelle 
---
 hw/hppa/hppa_hardware.h |  1 -
 hw/hppa/machine.c   | 32 
 2 files changed, 33 deletions(-)

diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h
index 507f91e05d..ce59cbbf94 100644
--- a/hw/hppa/hppa_hardware.h
+++ b/hw/hppa/hppa_hardware.h
@@ -26,7 +26,6 @@
 #define MEMORY_HPA  0xfffbf000
 
 #define PCI_HPA DINO_HPA/* PCI bus */
-#define IDE_HPA 0xf900  /* Boot disc controller */
 
 /* offsets to DINO HPA: */
 #define DINO_PCI_ADDR   0x064
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 65fc20ebed..542faae9be 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -22,30 +22,6 @@
 #include "qapi/error.h"
 #include "qemu/log.h"
 
-#define MAX_IDE_BUS 2
-
-static ISABus *hppa_isa_bus(void)
-{
-ISABus *isa_bus;
-qemu_irq *isa_irqs;
-MemoryRegion *isa_region;
-
-isa_region = g_new(MemoryRegion, 1);
-memory_region_init_io(isa_region, NULL, &hppa_pci_ignore_ops,
-  NULL, "isa-io", 0x800);
-memory_region_add_subregion(get_system_memory(), IDE_HPA,
-isa_region);
-
-isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region,
-  &error_abort);
-isa_irqs = i8259_init(isa_bus,
-  /* qemu_allocate_irq(dino_set_isa_irq, s, 0)); */
-  NULL);
-isa_bus_irqs(isa_bus, isa_irqs);
-
-return isa_bus;
-}
-
 static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr)
 {
 addr &= (0x1000 - 1);
@@ -62,7 +38,6 @@ static void machine_hppa_init(MachineState *machine)
 const char *initrd_filename = machine->initrd_filename;
 DeviceState *dev;
 PCIBus *pci_bus;
-ISABus *isa_bus;
 qemu_irq rtc_irq, serial_irq;
 char *firmware_filename;
 uint64_t firmware_low, firmware_high;
@@ -108,13 +83,6 @@ static void machine_hppa_init(MachineState *machine)
 pci_bus = dino_init(addr_space, &rtc_irq, &serial_irq);
 assert(pci_bus);
 
-/* Create ISA bus. */
-isa_bus = hppa_isa_bus();
-assert(isa_bus);
-
-/* Realtime clock, used by firmware for PDC_TOD call. */
-mc146818_rtc_init(isa_bus, 2000, rtc_irq);
-
 /* Serial code setup.  */
 if (serial_hd(0)) {
 uint32_t addr = DINO_UART_HPA + 0x800;
-- 
2.23.0




[PATCH 0/7] HPPA: i82596, PS/2 and graphics emulation

2019-10-20 Thread Sven Schnelle
Hi,

these series adds quite a lot to the HPPA emulation in QEMU:
i82596 emulation from Helge, PS/2 and Artist graphics emulation.

See https://parisc.wiki.kernel.org/index.php/Qemu for a few screenshots
of QEMU running a X11/CDE session in HP-UX.

Regards,
Sven

Helge Deller (2):
  hw/hppa/dino.c: Improve emulation of Dino PCI chip
  hppa: Add support for LASI chip with i82596 NIC

Sven Schnelle (5):
  hppa: remove ISA region
  ps2: accept 'Set Key Make and Break' commands
  hppa: add emulation of LASI PS2 controllers
  hppa: Add emulation of Artist graphics
  seabios-hppa: update to latest version

 MAINTAINERS |4 +-
 hw/display/Kconfig  |3 +
 hw/display/Makefile.objs|1 +
 hw/display/artist.c | 1336 +++
 hw/display/trace-events |9 +
 hw/hppa/Kconfig |3 +
 hw/hppa/Makefile.objs   |2 +-
 hw/hppa/dino.c  |   82 ++-
 hw/hppa/hppa_hardware.h |2 +-
 hw/hppa/hppa_sys.h  |2 +
 hw/hppa/lasi.c  |  368 ++
 hw/hppa/machine.c   |   50 +-
 hw/hppa/trace-events|   10 +
 hw/input/Kconfig|3 +
 hw/input/Makefile.objs  |1 +
 hw/input/lasips2.c  |  289 
 hw/input/ps2.c  |   11 +
 hw/input/trace-events   |5 +
 hw/net/Kconfig  |7 +
 hw/net/Makefile.objs|2 +
 hw/net/i82596.c |  734 +++
 hw/net/i82596.h |   55 ++
 hw/net/lasi_i82596.c|  188 +
 hw/net/trace-events |   13 +
 include/hw/input/lasips2.h  |   16 +
 include/hw/input/ps2.h  |1 +
 include/hw/net/lasi_82596.h |   29 +
 pc-bios/hppa-firmware.img   |  Bin 783724 -> 772876 bytes
 roms/seabios-hppa   |2 +-
 29 files changed, 3179 insertions(+), 49 deletions(-)
 create mode 100644 hw/display/artist.c
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/input/lasips2.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/input/lasips2.h
 create mode 100644 include/hw/net/lasi_82596.h

-- 
2.23.0




[PATCH 1/7] hw/hppa/dino.c: Improve emulation of Dino PCI chip

2019-10-20 Thread Sven Schnelle
From: Helge Deller 

The tests of the dino chip with the Online-diagnostics CD
("ODE DINOTEST") now succeeds.
Additionally add some qemu trace events.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
---
 MAINTAINERS  |  2 +-
 hw/hppa/dino.c   | 82 +---
 hw/hppa/trace-events |  5 +++
 3 files changed, 76 insertions(+), 13 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 250ce8e7a1..f9541c3305 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -874,7 +874,7 @@ F: hw/*/etraxfs_*.c
 
 HP-PARISC Machines
 --
-Dino
+HP B160L
 M: Richard Henderson 
 R: Helge Deller 
 S: Odd Fixes
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index ab6969b45f..63f6f80203 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -1,7 +1,7 @@
 /*
- * HP-PARISC Dino PCI chipset emulation.
+ * HP-PARISC Dino PCI chipset emulation, as in B160L and similiar machines
  *
- * (C) 2017 by Helge Deller 
+ * (C) 2017-2019 by Helge Deller 
  *
  * This work is licensed under the GNU GPL license version 2 or later.
  *
@@ -21,6 +21,7 @@
 #include "migration/vmstate.h"
 #include "hppa_sys.h"
 #include "exec/address-spaces.h"
+#include "trace.h"
 
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
@@ -82,11 +83,16 @@
 #define DINO_PCI_HOST_BRIDGE(obj) \
 OBJECT_CHECK(DinoState, (obj), TYPE_DINO_PCI_HOST_BRIDGE)
 
+#define DINO800_REGS ((DINO_TLTIM - DINO_GMASK) / 4)
+static uint8_t reg800_keep_bits[DINO800_REGS]
+= { 1, 7, 7, 8, 7, 9, 32, 8, 30, 25, 22, 9 };
+
 typedef struct DinoState {
 PCIHostState parent_obj;
 
 /* PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.  */
+uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
 
 uint32_t iar0;
 uint32_t iar1;
@@ -94,8 +100,12 @@ typedef struct DinoState {
 uint32_t ipr;
 uint32_t icr;
 uint32_t ilr;
+uint32_t io_fbb_en;
 uint32_t io_addr_en;
 uint32_t io_control;
+uint32_t toc_addr;
+
+uint32_t reg800[DINO800_REGS];
 
 MemoryRegion this_mem;
 MemoryRegion pci_mem;
@@ -106,8 +116,6 @@ typedef struct DinoState {
 MemoryRegion bm_ram_alias;
 MemoryRegion bm_pci_alias;
 MemoryRegion bm_cpu_alias;
-
-MemoryRegion cpu0_eir_mem;
 } DinoState;
 
 /*
@@ -122,6 +130,8 @@ static void gsc_to_pci_forwarding(DinoState *s)
 tmp = extract32(s->io_control, 7, 2);
 enabled = (tmp == 0x01);
 io_addr_en = s->io_addr_en;
+/* Mask out first (=firmware) and last (=Dino) areas. */
+io_addr_en &= 0x7ffe;
 
 memory_region_transaction_begin();
 for (i = 1; i < 31; i++) {
@@ -142,6 +152,8 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 unsigned size, bool is_write,
 MemTxAttrs attrs)
 {
+bool ret = false;
+
 switch (addr) {
 case DINO_IAR0:
 case DINO_IAR1:
@@ -152,16 +164,22 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 case DINO_ICR:
 case DINO_ILR:
 case DINO_IO_CONTROL:
+case DINO_IO_FBB_EN:
 case DINO_IO_ADDR_EN:
 case DINO_PCI_IO_DATA:
-return true;
+case DINO_TOC_ADDR:
+case DINO_GMASK ... DINO_TLTIM:
+ret = true;
+break;
 case DINO_PCI_IO_DATA + 2:
-return size <= 2;
+ret = (size <= 2);
+break;
 case DINO_PCI_IO_DATA + 1:
 case DINO_PCI_IO_DATA + 3:
-return size == 1;
+ret = (size == 1);
 }
-return false;
+trace_dino_chip_mem_valid(addr, ret);
+return ret;
 }
 
 static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr,
@@ -194,6 +212,9 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, 
hwaddr addr,
 }
 break;
 
+case DINO_IO_FBB_EN:
+val = s->io_fbb_en;
+break;
 case DINO_IO_ADDR_EN:
 val = s->io_addr_en;
 break;
@@ -227,12 +248,28 @@ static MemTxResult dino_chip_read_with_attrs(void 
*opaque, hwaddr addr,
 case DINO_IRR1:
 val = s->ilr & s->imr & s->icr;
 break;
+case DINO_TOC_ADDR:
+val = s->toc_addr;
+break;
+case DINO_GMASK ... DINO_TLTIM:
+val = s->reg800[(addr - DINO_GMASK) / 4];
+if (addr == DINO_PAMR) {
+val &= ~0x01;  /* LSB is hardwired to 0 */
+}
+if (addr == DINO_MLTIM) {
+val &= ~0x07;  /* 3 LSB are hardwired to 0 */
+}
+if (addr == DINO_BRDG_FEAT) {
+val &= ~(0x10710E0ul | 8); /* bits 5-7, 24 & 15 reserved */
+}
+break;
 
 default:
 /* Controlled by dino_chip_mem_valid above.  */
 g_assert_not_reached();
 }
 
+trace_dino_chip_read(addr, val);
 *data = val;
 return ret;
 }
@@ -245,6 +28

[PATCH 5/7] hppa: add emulation of LASI PS2 controllers

2019-10-20 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/hppa/Kconfig|   1 +
 hw/hppa/lasi.c |  10 +-
 hw/input/Kconfig   |   3 +
 hw/input/Makefile.objs |   1 +
 hw/input/lasips2.c | 289 +
 hw/input/ps2.c |   5 +
 hw/input/trace-events  |   5 +
 include/hw/input/lasips2.h |  16 ++
 include/hw/input/ps2.h |   1 +
 9 files changed, 330 insertions(+), 1 deletion(-)
 create mode 100644 hw/input/lasips2.c
 create mode 100644 include/hw/input/lasips2.h

diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 2a7b38d6d6..7f9be7f25c 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -11,3 +11,4 @@ config DINO
 select MC146818RTC
 select LSI_SCSI_PCI
 select LASI_82596
+select LASIPS2
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
index 51752589f3..d8d03f95c0 100644
--- a/hw/hppa/lasi.c
+++ b/hw/hppa/lasi.c
@@ -22,6 +22,7 @@
 #include "hw/net/lasi_82596.h"
 #include "hw/char/parallel.h"
 #include "hw/char/serial.h"
+#include "hw/input/lasips2.h"
 #include "exec/address-spaces.h"
 #include "migration/vmstate.h"
 
@@ -324,6 +325,7 @@ DeviceState *lasi_init(MemoryRegion *address_space)
  lpt_irq, parallel_hds[0]);
 
 /* Real time clock (RTC), it's only one 32-bit counter @9000 */
+
 s->rtc = time(NULL);
 s->rtc_ref = 0;
 
@@ -333,8 +335,14 @@ DeviceState *lasi_init(MemoryRegion *address_space)
 lasi_get_irq(LASI_UART_HPA));
 serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0,
 serial_irq, 800 / 16,
-serial_hd(1), DEVICE_NATIVE_ENDIAN);
+serial_hd(0), DEVICE_NATIVE_ENDIAN);
 }
+
+/* PS/2 Keyboard/Mouse */
+qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s,
+lasi_get_irq(LASI_PS2KBD_HPA));
+lasips2_init(address_space, LASI_PS2KBD_HPA,  ps2kbd_irq);
+
 return dev;
 }
 
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
index 287f08887b..25c77a1b87 100644
--- a/hw/input/Kconfig
+++ b/hw/input/Kconfig
@@ -41,3 +41,6 @@ config VHOST_USER_INPUT
 
 config TSC210X
 bool
+
+config LASIPS2
+select PS2
diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
index a1bc502ed0..f98f635685 100644
--- a/hw/input/Makefile.objs
+++ b/hw/input/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VHOST_USER_INPUT) += vhost-user-input.o
 obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_keypad.o
 obj-$(CONFIG_TSC210X) += tsc210x.o
+obj-$(CONFIG_LASIPS2) += lasips2.o
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
new file mode 100644
index 00..1943671d1e
--- /dev/null
+++ b/hw/input/lasips2.c
@@ -0,0 +1,289 @@
+/*
+ * QEMU HP Lasi PS/2 interface emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/hw.h"
+#include "hw/input/ps2.h"
+#include "hw/input/lasips2.h"
+#include "hw/sysbus.h"
+#include "exec/hwaddr.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+struct LASIPS2State;
+typedef struct LASIPS2Port {
+struct LASIPS2State *parent;
+MemoryRegion reg;
+void *dev;
+uint8_t id;
+uint8_t control;
+uint8_t buf;
+bool loopback_rbne;
+bool irq;
+} LASIPS2Port;
+
+typedef struct LASIPS2State {
+LASIPS2Port kbd;
+LASIPS2Port mouse;
+qemu_irq irq;
+} LASIPS2State;
+
+static const VMStateDescription vmstate_lasips2 = {
+.name = "lasips2",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]

[PATCH 4/7] ps2: accept 'Set Key Make and Break' commands

2019-10-20 Thread Sven Schnelle
HP-UX sends both the 'Set key make and break (0xfc) and
'Set all key typematic make and break' (0xfa). QEMU response
with 'Resend' as it doesn't handle these commands. HP-UX than
reports an PS/2 max retransmission exceeded error. Add these
commands and just reply with ACK.

Signed-off-by: Sven Schnelle 
---
 hw/input/ps2.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 67f92f6112..6c2c7066a6 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -49,6 +49,8 @@
 #define KBD_CMD_RESET_DISABLE  0xF5/* reset and disable scanning */
 #define KBD_CMD_RESET_ENABLE   0xF6/* reset and enable scanning */
 #define KBD_CMD_RESET  0xFF/* Reset */
+#define KBD_CMD_SET_MAKE_BREAK  0xFC/* Set Make and Break mode */
+#define KBD_CMD_SET_TYPEMATIC   0xFA/* Set Typematic Make and Break mode */
 
 /* Keyboard Replies */
 #define KBD_REPLY_POR  0xAA/* Power on reset */
@@ -592,6 +594,10 @@ void ps2_write_keyboard(void *opaque, int val)
 KBD_REPLY_ACK,
 KBD_REPLY_POR);
 break;
+case KBD_CMD_SET_TYPEMATIC:
+case KBD_CMD_SET_MAKE_BREAK:
+ps2_queue(&s->common, KBD_REPLY_ACK);
+break;
 default:
 ps2_queue(&s->common, KBD_REPLY_RESEND);
 break;
-- 
2.23.0




[PATCH 6/7] hppa: Add emulation of Artist graphics

2019-10-20 Thread Sven Schnelle
This adds emulation of Artist graphics good enough
to get a Text console on both Linux and HP-UX. The
X11 server from HP-UX also works.

Signed-off-by: Sven Schnelle 
---
 hw/display/Kconfig   |3 +
 hw/display/Makefile.objs |1 +
 hw/display/artist.c  | 1336 ++
 hw/display/trace-events  |9 +
 hw/hppa/Kconfig  |1 +
 hw/hppa/hppa_hardware.h  |1 +
 hw/hppa/machine.c|   10 +
 7 files changed, 1361 insertions(+)
 create mode 100644 hw/display/artist.c

diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index cbdf7b1a67..953631afb6 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -91,6 +91,9 @@ config TCX
 config CG3
 bool
 
+config ARTIST
+bool
+
 config VGA
 bool
 
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 5a4066383b..5f63294149 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -39,6 +39,7 @@ common-obj-$(CONFIG_SM501) += sm501.o
 common-obj-$(CONFIG_TCX) += tcx.o
 common-obj-$(CONFIG_CG3) += cg3.o
 common-obj-$(CONFIG_NEXTCUBE) += next-fb.o
+common-obj-$(CONFIG_ARTIST) += artist.o
 
 obj-$(CONFIG_VGA) += vga.o
 
diff --git a/hw/display/artist.c b/hw/display/artist.c
new file mode 100644
index 00..9b285b3993
--- /dev/null
+++ b/hw/display/artist.c
@@ -0,0 +1,1336 @@
+/*
+ * QEMU HP Artist Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/typedefs.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/loader.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "ui/console.h"
+#include "trace.h"
+
+#define TYPE_ARTIST "artist"
+#define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST)
+
+struct vram_buffer {
+uint8_t *data;
+int size;
+int width;
+int height;
+};
+
+typedef struct ARTISTState {
+SysBusDevice parent_obj;
+
+QemuConsole *con;
+MemoryRegion vram_mem;
+MemoryRegion reg;
+uint8_t *vram;
+
+struct vram_buffer vram_buffer[16];
+
+uint16_t width;
+uint16_t height;
+uint16_t depth;
+
+uint32_t fg_color;
+uint32_t bg_color;
+
+uint32_t vram_char_y;
+uint32_t vram_bitmask;
+
+uint32_t vram_start;
+uint32_t vram_pos;
+
+uint32_t vram_size;
+
+uint32_t blockmove_source;
+uint32_t blockmove_dest;
+uint32_t blockmove_size;
+
+uint32_t line_size;
+uint32_t line_end;
+uint32_t line_xy;
+uint32_t line_pattern_start;
+uint32_t line_pattern_skip;
+
+uint32_t cursor_pos;
+
+uint32_t cursor_height;
+uint32_t cursor_width;
+
+uint32_t plane_mask;
+
+uint32_t reg_100080;
+uint32_t reg_300200;
+uint32_t reg_300208;
+uint32_t reg_300218;
+
+uint32_t cmap_bm_access;
+uint32_t dst_bm_access;
+uint32_t src_bm_access;
+uint32_t control_plane;
+uint32_t transfer_data;
+uint32_t image_bitmap_op;
+
+uint32_t font_write1;
+uint32_t font_write2;
+uint32_t font_write_pos_y;
+
+int draw_line_pattern;
+} ARTISTState;
+
+typedef enum {
+ARTIST_BUFFER_AP = 1,
+ARTIST_BUFFER_OVERLAY = 2,
+ARTIST_BUFFER_CURSOR1 = 6,
+ARTIST_BUFFER_CURSOR2 = 7,
+ARTIST_BUFFER_ATTRIBUTE = 13,
+ARTIST_BUFFER_CMAP = 15,
+} artist_buffer_t;
+
+typedef enum {
+VRAM_IDX = 0x1004a0,
+VRAM_BITMASK = 0x1005a0,
+VRAM_WRITE_INCR_X = 0x100600,
+VRAM_WRITE_INCR_X2 = 0x100604,
+VRAM_WRITE_INCR_Y = 0x100620,
+VRAM_START = 0x100800,
+BLOCK_MOVE_SIZE = 0x100804,
+BLOCK_MOVE_SOURCE = 0x100808,
+TRANSFER_DATA = 0x100820,
+FONT_WRITE_INCR_Y = 0x1008a0,
+VRAM_START_TRIGGER = 0x100a00,
+VRAM_SIZE_TRIGGER = 0x100a04,
+FONT_WRITE_START = 0x100aa0,
+BLOCK_MOVE_DEST_TRIGGER = 0x100b00,
+BLOCK_MOVE_SIZE_TRIGGER = 0x100b04,
+LINE_XY = 0x100ccc,
+PATTERN_LINE_START = 0x100ecc,
+LINE_SIZE = 0x100e04,
+LINE_END = 0x100e44,
+CMAP_BM_ACCESS = 0x118000,
+DST_BM_ACCESS = 0x118004,
+SRC_BM_ACCESS = 0x118008,
+CONTROL_PLANE = 0x11800c,
+FG_COLOR = 0x118010,
+BG_COLOR = 0x118014,
+PLANE_MASK = 0x118018,
+IMAGE_BITMAP_OP = 0x11801c,
+CURSOR_POS = 0x300100,
+CURSOR_CTRL = 0x300104,
+} artist_reg_t;
+
+typedef enum {
+ARTIST_ROP_CLEAR = 0,
+ARTIST_ROP_COPY = 3,
+ARTIST_ROP_XOR = 6,
+ARTIST_ROP_NOT_DST = 10,
+ARTIST_ROP_SET = 15,
+} artist_rop_t;
+
+#define REG_NAME(_x) case _x: return " "#_x;
+static const char *artist_reg_name(uint64_t addr)
+{
+switch ((artist_reg_t)addr) {
+REG_NAME(VRAM_IDX);
+REG_NAME(VRAM_BITMASK);

[PATCH 2/7] hppa: Add support for LASI chip with i82596 NIC

2019-10-20 Thread Sven Schnelle
From: Helge Deller 

LASI is a built-in multi-I/O chip which supports serial, parallel,
network (Intel i82596 Apricot), sound and other functionalities.
LASI has been used in many HP PARISC machines.
This patch adds the necessary parts to allow Linux and HP-UX to detect
LASI and the network card.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
---
 MAINTAINERS |   2 +
 hw/hppa/Kconfig |   1 +
 hw/hppa/Makefile.objs   |   2 +-
 hw/hppa/hppa_sys.h  |   2 +
 hw/hppa/lasi.c  | 360 ++
 hw/hppa/machine.c   |   8 +-
 hw/hppa/trace-events|   5 +
 hw/net/Kconfig  |   7 +
 hw/net/Makefile.objs|   2 +
 hw/net/i82596.c | 734 
 hw/net/i82596.h |  55 +++
 hw/net/lasi_i82596.c| 188 +
 hw/net/trace-events |  13 +
 include/hw/net/lasi_82596.h |  29 ++
 14 files changed, 1406 insertions(+), 2 deletions(-)
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/net/lasi_82596.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f9541c3305..91e9e8ceac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -178,6 +178,8 @@ S: Maintained
 F: target/hppa/
 F: hw/hppa/
 F: disas/hppa.c
+F: hw/net/*i82596*
+F: include/hw/net/lasi_82596.h
 
 LM32 TCG CPUs
 M: Michael Walle 
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 6e5d74a825..2a7b38d6d6 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -10,3 +10,4 @@ config DINO
 select IDE_CMD646
 select MC146818RTC
 select LSI_SCSI_PCI
+select LASI_82596
diff --git a/hw/hppa/Makefile.objs b/hw/hppa/Makefile.objs
index 67838f50a3..eac3467d8a 100644
--- a/hw/hppa/Makefile.objs
+++ b/hw/hppa/Makefile.objs
@@ -1 +1 @@
-obj-$(CONFIG_DINO) += pci.o machine.o dino.o
+obj-$(CONFIG_DINO) += pci.o machine.o dino.o lasi.o
diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h
index 43d25d21fc..d99b5dd87b 100644
--- a/hw/hppa/hppa_sys.h
+++ b/hw/hppa/hppa_sys.h
@@ -11,6 +11,8 @@
 #include "hppa_hardware.h"
 
 PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
+DeviceState *lasi_init(MemoryRegion *);
+#define enable_lasi_lan()   0
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
 
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
new file mode 100644
index 00..51752589f3
--- /dev/null
+++ b/hw/hppa/lasi.c
@@ -0,0 +1,360 @@
+/*
+ * HP-PARISC Lasi chipset emulation.
+ *
+ * (C) 2019 by Helge Deller 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ * Documentation available at:
+ * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "trace.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+#include "hppa_sys.h"
+#include "hw/net/lasi_82596.h"
+#include "hw/char/parallel.h"
+#include "hw/char/serial.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+
+#define TYPE_LASI_CHIP "lasi-chip"
+
+#define LASI_IRR0x00/* RO */
+#define LASI_IMR0x04
+#define LASI_IPR0x08
+#define LASI_ICR0x0c
+#define LASI_IAR0x10
+
+#define LASI_PCR0x0C000 /* LASI Power Control register */
+#define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */
+#define LASI_VER0x0C008 /* LASI Version Control register */
+#define LASI_IORESET0x0C00C /* LASI I/O Reset register */
+#define LASI_AMR0x0C010 /* LASI Arbitration Mask register */
+#define LASI_IO_CONF0x7FFFE /* LASI primary configuration register */
+#define LASI_IO_CONF2   0x7 /* LASI secondary configuration register */
+
+#define LASI_BIT(x) (1ul << (x))
+#define LASI_IRQ_BITS   (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) 
\
+| LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
+| LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
+| LASI_BIT(26))
+
+#define ICR_BUS_ERROR_BIT  LASI_BIT(8)  /* bit 8 in ICR */
+#define ICR_TOC_BITLASI_BIT(1)  /* bit 1 in ICR */
+
+#define LASI_CHIP(obj) \
+OBJECT_CHECK(LasiState, (obj), TYPE_LASI_CHIP)
+
+#define LASI_RTC_HPA(LASI_HPA + 0x9000)
+
+typedef struct LasiState {
+PCIHostState parent_obj;
+
+uint32_t irr;
+uint32_t imr;
+uint32_t ipr;
+uint32_t icr;
+uint32_t iar;
+
+uint32_t errlog;
+uint32_t amr;
+uint32_t rtc;
+time_t rtc_ref;
+
+MemoryRegion this_mem;
+} LasiState;
+
+static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
+unsigned size

Re: [PATCH 3/7] hppa: remove ISA region

2019-10-21 Thread Sven Schnelle
Hi Richard,

On Mon, Oct 21, 2019 at 11:17:24AM -0700, Richard Henderson wrote:
> On 10/20/19 1:47 PM, Sven Schnelle wrote:
> > B160L doesn't have an ISA bus, and we no longer need it to
> > workaround missing hardware, so remove it.
> > 
> > Signed-off-by: Sven Schnelle 
> > ---
> >  hw/hppa/hppa_hardware.h |  1 -
> >  hw/hppa/machine.c   | 32 
> >  2 files changed, 33 deletions(-)
> 
> This should remove ISA_BUS from hw/hppa/Kconfig as well.

Right. I thought to do so is easy, but that turned out to reveal a lot
of other issues:

- hppa is using the I8259 code, which relies on ISA
- hw/hppa/pci.c seems to only contain unused stuff
- LASI use hw/char/parallel.c, which relies on ISA. parallel.c could
  propably be split up into a ISA dependent part and a generic part

So it is more work to remove ISA completely, therefore i'll drop that
patch for now and submit it later again.

Thanks
Sven



[PATCH v2 3/6] ps2: accept 'Set Key Make and Break' commands

2019-10-21 Thread Sven Schnelle
HP-UX sends both the 'Set key make and break (0xfc) and
'Set all key typematic make and break' (0xfa). QEMU response
with 'Resend' as it doesn't handle these commands. HP-UX than
reports an PS/2 max retransmission exceeded error. Add these
commands and just reply with ACK.

Signed-off-by: Sven Schnelle 
---
 hw/input/ps2.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 67f92f6112..6c2c7066a6 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -49,6 +49,8 @@
 #define KBD_CMD_RESET_DISABLE  0xF5/* reset and disable scanning */
 #define KBD_CMD_RESET_ENABLE   0xF6/* reset and enable scanning */
 #define KBD_CMD_RESET  0xFF/* Reset */
+#define KBD_CMD_SET_MAKE_BREAK  0xFC/* Set Make and Break mode */
+#define KBD_CMD_SET_TYPEMATIC   0xFA/* Set Typematic Make and Break mode */
 
 /* Keyboard Replies */
 #define KBD_REPLY_POR  0xAA/* Power on reset */
@@ -592,6 +594,10 @@ void ps2_write_keyboard(void *opaque, int val)
 KBD_REPLY_ACK,
 KBD_REPLY_POR);
 break;
+case KBD_CMD_SET_TYPEMATIC:
+case KBD_CMD_SET_MAKE_BREAK:
+ps2_queue(&s->common, KBD_REPLY_ACK);
+break;
 default:
 ps2_queue(&s->common, KBD_REPLY_RESEND);
 break;
-- 
2.23.0




[PATCH v2 5/6] hppa: Add emulation of Artist graphics

2019-10-21 Thread Sven Schnelle
This adds emulation of Artist graphics good enough
to get a Text console on both Linux and HP-UX. The
X11 server from HP-UX also works.

Signed-off-by: Sven Schnelle 
---
 hw/display/Kconfig   |3 +
 hw/display/Makefile.objs |1 +
 hw/display/artist.c  | 1336 ++
 hw/display/trace-events  |9 +
 hw/hppa/Kconfig  |1 +
 hw/hppa/hppa_hardware.h  |1 +
 hw/hppa/machine.c|   10 +
 7 files changed, 1361 insertions(+)
 create mode 100644 hw/display/artist.c

diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index cbdf7b1a67..953631afb6 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -91,6 +91,9 @@ config TCX
 config CG3
 bool
 
+config ARTIST
+bool
+
 config VGA
 bool
 
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 5a4066383b..5f63294149 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -39,6 +39,7 @@ common-obj-$(CONFIG_SM501) += sm501.o
 common-obj-$(CONFIG_TCX) += tcx.o
 common-obj-$(CONFIG_CG3) += cg3.o
 common-obj-$(CONFIG_NEXTCUBE) += next-fb.o
+common-obj-$(CONFIG_ARTIST) += artist.o
 
 obj-$(CONFIG_VGA) += vga.o
 
diff --git a/hw/display/artist.c b/hw/display/artist.c
new file mode 100644
index 00..9b285b3993
--- /dev/null
+++ b/hw/display/artist.c
@@ -0,0 +1,1336 @@
+/*
+ * QEMU HP Artist Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/typedefs.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/loader.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "ui/console.h"
+#include "trace.h"
+
+#define TYPE_ARTIST "artist"
+#define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST)
+
+struct vram_buffer {
+uint8_t *data;
+int size;
+int width;
+int height;
+};
+
+typedef struct ARTISTState {
+SysBusDevice parent_obj;
+
+QemuConsole *con;
+MemoryRegion vram_mem;
+MemoryRegion reg;
+uint8_t *vram;
+
+struct vram_buffer vram_buffer[16];
+
+uint16_t width;
+uint16_t height;
+uint16_t depth;
+
+uint32_t fg_color;
+uint32_t bg_color;
+
+uint32_t vram_char_y;
+uint32_t vram_bitmask;
+
+uint32_t vram_start;
+uint32_t vram_pos;
+
+uint32_t vram_size;
+
+uint32_t blockmove_source;
+uint32_t blockmove_dest;
+uint32_t blockmove_size;
+
+uint32_t line_size;
+uint32_t line_end;
+uint32_t line_xy;
+uint32_t line_pattern_start;
+uint32_t line_pattern_skip;
+
+uint32_t cursor_pos;
+
+uint32_t cursor_height;
+uint32_t cursor_width;
+
+uint32_t plane_mask;
+
+uint32_t reg_100080;
+uint32_t reg_300200;
+uint32_t reg_300208;
+uint32_t reg_300218;
+
+uint32_t cmap_bm_access;
+uint32_t dst_bm_access;
+uint32_t src_bm_access;
+uint32_t control_plane;
+uint32_t transfer_data;
+uint32_t image_bitmap_op;
+
+uint32_t font_write1;
+uint32_t font_write2;
+uint32_t font_write_pos_y;
+
+int draw_line_pattern;
+} ARTISTState;
+
+typedef enum {
+ARTIST_BUFFER_AP = 1,
+ARTIST_BUFFER_OVERLAY = 2,
+ARTIST_BUFFER_CURSOR1 = 6,
+ARTIST_BUFFER_CURSOR2 = 7,
+ARTIST_BUFFER_ATTRIBUTE = 13,
+ARTIST_BUFFER_CMAP = 15,
+} artist_buffer_t;
+
+typedef enum {
+VRAM_IDX = 0x1004a0,
+VRAM_BITMASK = 0x1005a0,
+VRAM_WRITE_INCR_X = 0x100600,
+VRAM_WRITE_INCR_X2 = 0x100604,
+VRAM_WRITE_INCR_Y = 0x100620,
+VRAM_START = 0x100800,
+BLOCK_MOVE_SIZE = 0x100804,
+BLOCK_MOVE_SOURCE = 0x100808,
+TRANSFER_DATA = 0x100820,
+FONT_WRITE_INCR_Y = 0x1008a0,
+VRAM_START_TRIGGER = 0x100a00,
+VRAM_SIZE_TRIGGER = 0x100a04,
+FONT_WRITE_START = 0x100aa0,
+BLOCK_MOVE_DEST_TRIGGER = 0x100b00,
+BLOCK_MOVE_SIZE_TRIGGER = 0x100b04,
+LINE_XY = 0x100ccc,
+PATTERN_LINE_START = 0x100ecc,
+LINE_SIZE = 0x100e04,
+LINE_END = 0x100e44,
+CMAP_BM_ACCESS = 0x118000,
+DST_BM_ACCESS = 0x118004,
+SRC_BM_ACCESS = 0x118008,
+CONTROL_PLANE = 0x11800c,
+FG_COLOR = 0x118010,
+BG_COLOR = 0x118014,
+PLANE_MASK = 0x118018,
+IMAGE_BITMAP_OP = 0x11801c,
+CURSOR_POS = 0x300100,
+CURSOR_CTRL = 0x300104,
+} artist_reg_t;
+
+typedef enum {
+ARTIST_ROP_CLEAR = 0,
+ARTIST_ROP_COPY = 3,
+ARTIST_ROP_XOR = 6,
+ARTIST_ROP_NOT_DST = 10,
+ARTIST_ROP_SET = 15,
+} artist_rop_t;
+
+#define REG_NAME(_x) case _x: return " "#_x;
+static const char *artist_reg_name(uint64_t addr)
+{
+switch ((artist_reg_t)addr) {
+REG_NAME(VRAM_IDX);
+REG_NAME(VRAM_BITMASK);

[PATCH v2 0/6] HPPA: i82596, PS/2 and graphics emulation

2019-10-21 Thread Sven Schnelle
Hi,

these series adds quite a lot to the HPPA emulation in QEMU:
i82596 emulation from Helge, PS/2 and Artist graphics emulation.

See https://parisc.wiki.kernel.org/index.php/Qemu for a few screenshots
of QEMU running a X11/CDE session in HP-UX.

Changes in v2:
 - dropped 'hppa: remove ISA region' as that patch requires some more work
 - added shortlog to seabios update
 - use const and MAKE_64BIT_MASK in dino.c

Regards,
Sven

Helge Deller (2):
  hw/hppa/dino.c: Improve emulation of Dino PCI chip
  hppa: Add support for LASI chip with i82596 NIC

Sven Schnelle (4):
  ps2: accept 'Set Key Make and Break' commands
  hppa: add emulation of LASI PS2 controllers
  hppa: Add emulation of Artist graphics
  seabios-hppa: update to latest version

 MAINTAINERS |4 +-
 hw/display/Kconfig  |3 +
 hw/display/Makefile.objs|1 +
 hw/display/artist.c | 1336 +++
 hw/display/trace-events |9 +
 hw/hppa/Kconfig |3 +
 hw/hppa/Makefile.objs   |2 +-
 hw/hppa/dino.c  |   94 ++-
 hw/hppa/hppa_hardware.h |1 +
 hw/hppa/hppa_sys.h  |2 +
 hw/hppa/lasi.c  |  368 ++
 hw/hppa/machine.c   |   18 +-
 hw/hppa/trace-events|   10 +
 hw/input/Kconfig|3 +
 hw/input/Makefile.objs  |1 +
 hw/input/lasips2.c  |  289 
 hw/input/ps2.c  |   11 +
 hw/input/trace-events   |5 +
 hw/net/Kconfig  |7 +
 hw/net/Makefile.objs|2 +
 hw/net/i82596.c |  734 +++
 hw/net/i82596.h |   55 ++
 hw/net/lasi_i82596.c|  188 +
 hw/net/trace-events |   13 +
 include/hw/input/lasips2.h  |   16 +
 include/hw/input/ps2.h  |1 +
 include/hw/net/lasi_82596.h |   29 +
 pc-bios/hppa-firmware.img   |  Bin 783724 -> 772876 bytes
 roms/seabios-hppa   |2 +-
 29 files changed, 3191 insertions(+), 16 deletions(-)
 create mode 100644 hw/display/artist.c
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/input/lasips2.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/input/lasips2.h
 create mode 100644 include/hw/net/lasi_82596.h

-- 
2.23.0




[PATCH v2 2/6] hppa: Add support for LASI chip with i82596 NIC

2019-10-21 Thread Sven Schnelle
From: Helge Deller 

LASI is a built-in multi-I/O chip which supports serial, parallel,
network (Intel i82596 Apricot), sound and other functionalities.
LASI has been used in many HP PARISC machines.
This patch adds the necessary parts to allow Linux and HP-UX to detect
LASI and the network card.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
---
 MAINTAINERS |   2 +
 hw/hppa/Kconfig |   1 +
 hw/hppa/Makefile.objs   |   2 +-
 hw/hppa/hppa_sys.h  |   2 +
 hw/hppa/lasi.c  | 360 ++
 hw/hppa/machine.c   |   8 +-
 hw/hppa/trace-events|   5 +
 hw/net/Kconfig  |   7 +
 hw/net/Makefile.objs|   2 +
 hw/net/i82596.c | 734 
 hw/net/i82596.h |  55 +++
 hw/net/lasi_i82596.c| 188 +
 hw/net/trace-events |  13 +
 include/hw/net/lasi_82596.h |  29 ++
 14 files changed, 1406 insertions(+), 2 deletions(-)
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/net/lasi_82596.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f9541c3305..91e9e8ceac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -178,6 +178,8 @@ S: Maintained
 F: target/hppa/
 F: hw/hppa/
 F: disas/hppa.c
+F: hw/net/*i82596*
+F: include/hw/net/lasi_82596.h
 
 LM32 TCG CPUs
 M: Michael Walle 
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 6e5d74a825..2a7b38d6d6 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -10,3 +10,4 @@ config DINO
 select IDE_CMD646
 select MC146818RTC
 select LSI_SCSI_PCI
+select LASI_82596
diff --git a/hw/hppa/Makefile.objs b/hw/hppa/Makefile.objs
index 67838f50a3..eac3467d8a 100644
--- a/hw/hppa/Makefile.objs
+++ b/hw/hppa/Makefile.objs
@@ -1 +1 @@
-obj-$(CONFIG_DINO) += pci.o machine.o dino.o
+obj-$(CONFIG_DINO) += pci.o machine.o dino.o lasi.o
diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h
index 43d25d21fc..d99b5dd87b 100644
--- a/hw/hppa/hppa_sys.h
+++ b/hw/hppa/hppa_sys.h
@@ -11,6 +11,8 @@
 #include "hppa_hardware.h"
 
 PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
+DeviceState *lasi_init(MemoryRegion *);
+#define enable_lasi_lan()   0
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
 
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
new file mode 100644
index 00..51752589f3
--- /dev/null
+++ b/hw/hppa/lasi.c
@@ -0,0 +1,360 @@
+/*
+ * HP-PARISC Lasi chipset emulation.
+ *
+ * (C) 2019 by Helge Deller 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ * Documentation available at:
+ * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "trace.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+#include "hppa_sys.h"
+#include "hw/net/lasi_82596.h"
+#include "hw/char/parallel.h"
+#include "hw/char/serial.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+
+#define TYPE_LASI_CHIP "lasi-chip"
+
+#define LASI_IRR0x00/* RO */
+#define LASI_IMR0x04
+#define LASI_IPR0x08
+#define LASI_ICR0x0c
+#define LASI_IAR0x10
+
+#define LASI_PCR0x0C000 /* LASI Power Control register */
+#define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */
+#define LASI_VER0x0C008 /* LASI Version Control register */
+#define LASI_IORESET0x0C00C /* LASI I/O Reset register */
+#define LASI_AMR0x0C010 /* LASI Arbitration Mask register */
+#define LASI_IO_CONF0x7FFFE /* LASI primary configuration register */
+#define LASI_IO_CONF2   0x7 /* LASI secondary configuration register */
+
+#define LASI_BIT(x) (1ul << (x))
+#define LASI_IRQ_BITS   (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) 
\
+| LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
+| LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
+| LASI_BIT(26))
+
+#define ICR_BUS_ERROR_BIT  LASI_BIT(8)  /* bit 8 in ICR */
+#define ICR_TOC_BITLASI_BIT(1)  /* bit 1 in ICR */
+
+#define LASI_CHIP(obj) \
+OBJECT_CHECK(LasiState, (obj), TYPE_LASI_CHIP)
+
+#define LASI_RTC_HPA(LASI_HPA + 0x9000)
+
+typedef struct LasiState {
+PCIHostState parent_obj;
+
+uint32_t irr;
+uint32_t imr;
+uint32_t ipr;
+uint32_t icr;
+uint32_t iar;
+
+uint32_t errlog;
+uint32_t amr;
+uint32_t rtc;
+time_t rtc_ref;
+
+MemoryRegion this_mem;
+} LasiState;
+
+static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
+unsigned size

[PATCH v2 1/6] hw/hppa/dino.c: Improve emulation of Dino PCI chip

2019-10-21 Thread Sven Schnelle
From: Helge Deller 

The tests of the dino chip with the Online-diagnostics CD
("ODE DINOTEST") now succeeds.
Additionally add some qemu trace events.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
---
 MAINTAINERS  |  2 +-
 hw/hppa/dino.c   | 94 ++--
 hw/hppa/trace-events |  5 +++
 3 files changed, 88 insertions(+), 13 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 250ce8e7a1..f9541c3305 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -874,7 +874,7 @@ F: hw/*/etraxfs_*.c
 
 HP-PARISC Machines
 --
-Dino
+HP B160L
 M: Richard Henderson 
 R: Helge Deller 
 S: Odd Fixes
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index ab6969b45f..ec5a71a831 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -1,7 +1,7 @@
 /*
- * HP-PARISC Dino PCI chipset emulation.
+ * HP-PARISC Dino PCI chipset emulation, as in B160L and similiar machines
  *
- * (C) 2017 by Helge Deller 
+ * (C) 2017-2019 by Helge Deller 
  *
  * This work is licensed under the GNU GPL license version 2 or later.
  *
@@ -21,6 +21,7 @@
 #include "migration/vmstate.h"
 #include "hppa_sys.h"
 #include "exec/address-spaces.h"
+#include "trace.h"
 
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
@@ -82,11 +83,28 @@
 #define DINO_PCI_HOST_BRIDGE(obj) \
 OBJECT_CHECK(DinoState, (obj), TYPE_DINO_PCI_HOST_BRIDGE)
 
+#define DINO800_REGS ((DINO_TLTIM - DINO_GMASK) / 4)
+static const uint32_t reg800_keep_bits[DINO800_REGS] = {
+MAKE_64BIT_MASK(0, 1),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 8),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 9),
+MAKE_64BIT_MASK(0, 32),
+MAKE_64BIT_MASK(0, 8),
+MAKE_64BIT_MASK(0, 30),
+MAKE_64BIT_MASK(0, 25),
+MAKE_64BIT_MASK(0, 22),
+MAKE_64BIT_MASK(0, 9),
+};
+
 typedef struct DinoState {
 PCIHostState parent_obj;
 
 /* PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.  */
+uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
 
 uint32_t iar0;
 uint32_t iar1;
@@ -94,8 +112,12 @@ typedef struct DinoState {
 uint32_t ipr;
 uint32_t icr;
 uint32_t ilr;
+uint32_t io_fbb_en;
 uint32_t io_addr_en;
 uint32_t io_control;
+uint32_t toc_addr;
+
+uint32_t reg800[DINO800_REGS];
 
 MemoryRegion this_mem;
 MemoryRegion pci_mem;
@@ -106,8 +128,6 @@ typedef struct DinoState {
 MemoryRegion bm_ram_alias;
 MemoryRegion bm_pci_alias;
 MemoryRegion bm_cpu_alias;
-
-MemoryRegion cpu0_eir_mem;
 } DinoState;
 
 /*
@@ -122,6 +142,8 @@ static void gsc_to_pci_forwarding(DinoState *s)
 tmp = extract32(s->io_control, 7, 2);
 enabled = (tmp == 0x01);
 io_addr_en = s->io_addr_en;
+/* Mask out first (=firmware) and last (=Dino) areas. */
+io_addr_en &= 0x7ffe;
 
 memory_region_transaction_begin();
 for (i = 1; i < 31; i++) {
@@ -142,6 +164,8 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 unsigned size, bool is_write,
 MemTxAttrs attrs)
 {
+bool ret = false;
+
 switch (addr) {
 case DINO_IAR0:
 case DINO_IAR1:
@@ -152,16 +176,22 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 case DINO_ICR:
 case DINO_ILR:
 case DINO_IO_CONTROL:
+case DINO_IO_FBB_EN:
 case DINO_IO_ADDR_EN:
 case DINO_PCI_IO_DATA:
-return true;
+case DINO_TOC_ADDR:
+case DINO_GMASK ... DINO_TLTIM:
+ret = true;
+break;
 case DINO_PCI_IO_DATA + 2:
-return size <= 2;
+ret = (size <= 2);
+break;
 case DINO_PCI_IO_DATA + 1:
 case DINO_PCI_IO_DATA + 3:
-return size == 1;
+ret = (size == 1);
 }
-return false;
+trace_dino_chip_mem_valid(addr, ret);
+return ret;
 }
 
 static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr,
@@ -194,6 +224,9 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, 
hwaddr addr,
 }
 break;
 
+case DINO_IO_FBB_EN:
+val = s->io_fbb_en;
+break;
 case DINO_IO_ADDR_EN:
 val = s->io_addr_en;
 break;
@@ -227,12 +260,28 @@ static MemTxResult dino_chip_read_with_attrs(void 
*opaque, hwaddr addr,
 case DINO_IRR1:
 val = s->ilr & s->imr & s->icr;
 break;
+case DINO_TOC_ADDR:
+val = s->toc_addr;
+break;
+case DINO_GMASK ... DINO_TLTIM:
+val = s->reg800[(addr - DINO_GMASK) / 4];
+if (addr == DINO_PAMR) {
+val &= ~0x01;  /* LSB is hardwired to 0 */
+}
+if (addr == DINO_MLTIM) {
+val &= ~0x07;

[PATCH v2 4/6] hppa: add emulation of LASI PS2 controllers

2019-10-21 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/hppa/Kconfig|   1 +
 hw/hppa/lasi.c |  10 +-
 hw/input/Kconfig   |   3 +
 hw/input/Makefile.objs |   1 +
 hw/input/lasips2.c | 289 +
 hw/input/ps2.c |   5 +
 hw/input/trace-events  |   5 +
 include/hw/input/lasips2.h |  16 ++
 include/hw/input/ps2.h |   1 +
 9 files changed, 330 insertions(+), 1 deletion(-)
 create mode 100644 hw/input/lasips2.c
 create mode 100644 include/hw/input/lasips2.h

diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 2a7b38d6d6..7f9be7f25c 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -11,3 +11,4 @@ config DINO
 select MC146818RTC
 select LSI_SCSI_PCI
 select LASI_82596
+select LASIPS2
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
index 51752589f3..d8d03f95c0 100644
--- a/hw/hppa/lasi.c
+++ b/hw/hppa/lasi.c
@@ -22,6 +22,7 @@
 #include "hw/net/lasi_82596.h"
 #include "hw/char/parallel.h"
 #include "hw/char/serial.h"
+#include "hw/input/lasips2.h"
 #include "exec/address-spaces.h"
 #include "migration/vmstate.h"
 
@@ -324,6 +325,7 @@ DeviceState *lasi_init(MemoryRegion *address_space)
  lpt_irq, parallel_hds[0]);
 
 /* Real time clock (RTC), it's only one 32-bit counter @9000 */
+
 s->rtc = time(NULL);
 s->rtc_ref = 0;
 
@@ -333,8 +335,14 @@ DeviceState *lasi_init(MemoryRegion *address_space)
 lasi_get_irq(LASI_UART_HPA));
 serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0,
 serial_irq, 800 / 16,
-serial_hd(1), DEVICE_NATIVE_ENDIAN);
+serial_hd(0), DEVICE_NATIVE_ENDIAN);
 }
+
+/* PS/2 Keyboard/Mouse */
+qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s,
+lasi_get_irq(LASI_PS2KBD_HPA));
+lasips2_init(address_space, LASI_PS2KBD_HPA,  ps2kbd_irq);
+
 return dev;
 }
 
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
index 287f08887b..25c77a1b87 100644
--- a/hw/input/Kconfig
+++ b/hw/input/Kconfig
@@ -41,3 +41,6 @@ config VHOST_USER_INPUT
 
 config TSC210X
 bool
+
+config LASIPS2
+select PS2
diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
index a1bc502ed0..f98f635685 100644
--- a/hw/input/Makefile.objs
+++ b/hw/input/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VHOST_USER_INPUT) += vhost-user-input.o
 obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_keypad.o
 obj-$(CONFIG_TSC210X) += tsc210x.o
+obj-$(CONFIG_LASIPS2) += lasips2.o
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
new file mode 100644
index 00..1943671d1e
--- /dev/null
+++ b/hw/input/lasips2.c
@@ -0,0 +1,289 @@
+/*
+ * QEMU HP Lasi PS/2 interface emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/hw.h"
+#include "hw/input/ps2.h"
+#include "hw/input/lasips2.h"
+#include "hw/sysbus.h"
+#include "exec/hwaddr.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+struct LASIPS2State;
+typedef struct LASIPS2Port {
+struct LASIPS2State *parent;
+MemoryRegion reg;
+void *dev;
+uint8_t id;
+uint8_t control;
+uint8_t buf;
+bool loopback_rbne;
+bool irq;
+} LASIPS2Port;
+
+typedef struct LASIPS2State {
+LASIPS2Port kbd;
+LASIPS2Port mouse;
+qemu_irq irq;
+} LASIPS2State;
+
+static const VMStateDescription vmstate_lasips2 = {
+.name = "lasips2",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]

Re: [PATCH v2 3/6] ps2: accept 'Set Key Make and Break' commands

2019-10-22 Thread Sven Schnelle
Hi Philippe,

On Tue, Oct 22, 2019 at 11:50:14AM +0200, Philippe Mathieu-Daudé wrote:
> On 10/22/19 7:54 AM, Sven Schnelle wrote:
> > HP-UX sends both the 'Set key make and break (0xfc) and
> > 'Set all key typematic make and break' (0xfa). QEMU response
> > with 'Resend' as it doesn't handle these commands. HP-UX than
> > reports an PS/2 max retransmission exceeded error. Add these
> > commands and just reply with ACK.
> > 
> > Signed-off-by: Sven Schnelle 
> > ---
> >   hw/input/ps2.c | 6 ++
> >   1 file changed, 6 insertions(+)
> > 
> > diff --git a/hw/input/ps2.c b/hw/input/ps2.c
> > index 67f92f6112..6c2c7066a6 100644
> > --- a/hw/input/ps2.c
> > +++ b/hw/input/ps2.c
> > @@ -49,6 +49,8 @@
> >   #define KBD_CMD_RESET_DISABLE 0xF5/* reset and disable scanning */
> >   #define KBD_CMD_RESET_ENABLE  0xF6/* reset and enable scanning */
> >   #define KBD_CMD_RESET 0xFF/* Reset */
> > +#define KBD_CMD_SET_MAKE_BREAK  0xFC/* Set Make and Break mode */
> > +#define KBD_CMD_SET_TYPEMATIC   0xFA/* Set Typematic Make and Break 
> > mode */
> >   /* Keyboard Replies */
> >   #define KBD_REPLY_POR 0xAA/* Power on reset */
> > @@ -592,6 +594,10 @@ void ps2_write_keyboard(void *opaque, int val)
> >   KBD_REPLY_ACK,
> >   KBD_REPLY_POR);
> >   break;
> > +case KBD_CMD_SET_TYPEMATIC:
> > +case KBD_CMD_SET_MAKE_BREAK:
> 
> Shouldn't we reset the write state machine too? I'm not sure.
> 
>s->common.write_cmd = -1;

Looking at this again i think the KBD_CMD_SET_TYPEMATIC case needs to
assign common.write_cmd to properly handle the addtional data byte. For
KBD_CMD_SET_MAKE_BREAK i think that's not neccessary. I'll fix that up.
> 
> > +ps2_queue(&s->common, KBD_REPLY_ACK);
> > +break;
> >   default:
> >   ps2_queue(&s->common, KBD_REPLY_RESEND);
> >   break;
> > 
> 

Thanks
Sven



[PATCH v2] net: add tulip (dec21143) driver

2019-10-22 Thread Sven Schnelle
This adds the basic functionality to emulate a Tulip NIC.

Implemented are:

- RX and TX functionality
- Perfect Frame Filtering
- Big/Little Endian descriptor support
- 93C46 EEPROM support
- LXT970 PHY

Not implemented, mostly because i had no OS using these functions:

- Imperfect frame filtering
- General Purpose Timer
- Transmit automatic polling
- Boot ROM support
- SIA interface
- Big/Little Endian data buffer conversion

Successfully tested with the following Operating Systems:

- MSDOS with Microsoft Network Client 3.0 and DEC ODI drivers
- HPPA Linux
- Windows XP
- HP-UX

Signed-off-by: Sven Schnelle 
---

 Changes in v2:
 - changed tulip_desc_{read,write} to take a struct descriptor *
   and no longer use a single pci DMA write, instead write one
   struct member at a time.

 - fix _tulip_receive function name
 - fix reset function and provide tulip_qdev_reset() for dc->reset.
 - no longer write registers in the default case in tulip_write()
 - set .impl.min_access_size and .impl.max_access_size

 MAINTAINERS  |6 +
 hw/net/Kconfig   |5 +
 hw/net/Makefile.objs |1 +
 hw/net/trace-events  |   14 +
 hw/net/tulip.c   | 1029 ++
 hw/net/tulip.h   |  268 ++
 include/hw/pci/pci_ids.h |1 +
 7 files changed, 1324 insertions(+)
 create mode 100644 hw/net/tulip.c
 create mode 100644 hw/net/tulip.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 250ce8e7a1..a12031c389 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1638,6 +1638,12 @@ M: Stefan Weil 
 S: Maintained
 F: hw/net/eepro100.c
 
+tulip
+M: Sven Schnelle 
+S: Maintained
+F: hw/net/tulip.c
+F: hw/net/tulip.h
+
 Generic Loader
 M: Alistair Francis 
 S: Maintained
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 4ef86dc3a5..3856417d42 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -24,6 +24,11 @@ config PCNET_PCI
 config PCNET_COMMON
 bool
 
+config TULIP
+bool
+default y if PCI_DEVICES
+depends on PCI
+
 config E1000_PCI
 bool
 default y if PCI_DEVICES
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 9904273b06..7907d2c199 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -13,6 +13,7 @@ common-obj-$(CONFIG_E1000E_PCI_EXPRESS) += e1000e.o 
e1000e_core.o e1000x_common.
 common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
 common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o
 common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet3.o
+common-obj-$(CONFIG_TULIP) += tulip.o
 
 common-obj-$(CONFIG_SMC91C111) += smc91c111.o
 common-obj-$(CONFIG_LAN9118) += lan9118.o
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 58665655cc..e70f12bee1 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -367,3 +367,17 @@ virtio_net_announce_notify(void) ""
 virtio_net_announce_timer(int round) "%d"
 virtio_net_handle_announce(int round) "%d"
 virtio_net_post_load_device(void)
+
+# tulip.c
+tulip_reg_write(uint64_t addr, const char *name, int size, uint64_t val) "addr 
0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
+tulip_reg_read(uint64_t addr, const char *name, int size, uint64_t val) "addr 
0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
+tulip_receive(const uint8_t *buf, size_t len) "buf %p size %zu"
+tulip_descriptor(const char *prefix, uint32_t addr, uint32_t status, uint32_t 
control, uint32_t len1, uint32_t len2, uint32_t buf1, uint32_t buf2) "%s 
0x%08x: status 0x%08x control 0x%03x len1 %4d len2 %4d buf1 0x%08x buf2 0x%08x"
+tulip_rx_state(const char *state) "RX %s"
+tulip_tx_state(const char *state) "TX %s"
+tulip_irq(uint32_t mask, uint32_t en, const char *state) "mask 0x%08x ie 
0x%08x %s"
+tulip_mii_write(int phy, int reg, uint16_t data) "phy 0x%x reg 0x%x data 
0x%04x"
+tulip_mii_read(int phy, int reg, uint16_t data) "phy 0x%x, reg 0x%x data 
0x%04x"
+tulip_reset(void) ""
+tulip_setup_frame(void) ""
+tulip_setup_filter(int n, uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t 
e, uint8_t f) "%d: %02x:%02x:%02x:%02x:%02x:%02x"
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
new file mode 100644
index 00..c826d9935c
--- /dev/null
+++ b/hw/net/tulip.c
@@ -0,0 +1,1029 @@
+/*
+ * QEMU TULIP Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "hw/nvram/eeprom93xx.h"
+#include "migration/vmstate.h"
+#include "sysemu/sysemu.h"
+#include "tulip.h"
+#include "trace.h"
+#include "net/eth.h"
+
+typedef struct TULIPState {
+PCIDevice dev;
+MemoryRegion io;
+MemoryRegion memory;
+NI

[PATCH v3 3/6] ps2: accept 'Set Key Make and Break' commands

2019-10-22 Thread Sven Schnelle
HP-UX sends both the 'Set key make and break (0xfc) and
'Set all key typematic make and break' (0xfa). QEMU response
with 'Resend' as it doesn't handle these commands. HP-UX than
reports an PS/2 max retransmission exceeded error. Add these
commands and just reply with ACK.

Signed-off-by: Sven Schnelle 
---
 hw/input/ps2.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 67f92f6112..0b671b6339 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -49,6 +49,8 @@
 #define KBD_CMD_RESET_DISABLE  0xF5/* reset and disable scanning */
 #define KBD_CMD_RESET_ENABLE   0xF6/* reset and enable scanning */
 #define KBD_CMD_RESET  0xFF/* Reset */
+#define KBD_CMD_SET_MAKE_BREAK  0xFC/* Set Make and Break mode */
+#define KBD_CMD_SET_TYPEMATIC   0xFA/* Set Typematic Make and Break mode */
 
 /* Keyboard Replies */
 #define KBD_REPLY_POR  0xAA/* Power on reset */
@@ -573,6 +575,7 @@ void ps2_write_keyboard(void *opaque, int val)
 case KBD_CMD_SCANCODE:
 case KBD_CMD_SET_LEDS:
 case KBD_CMD_SET_RATE:
+case KBD_CMD_SET_MAKE_BREAK:
 s->common.write_cmd = val;
 ps2_queue(&s->common, KBD_REPLY_ACK);
 break;
@@ -592,11 +595,18 @@ void ps2_write_keyboard(void *opaque, int val)
 KBD_REPLY_ACK,
 KBD_REPLY_POR);
 break;
+case KBD_CMD_SET_TYPEMATIC:
+ps2_queue(&s->common, KBD_REPLY_ACK);
+break;
 default:
 ps2_queue(&s->common, KBD_REPLY_RESEND);
 break;
 }
 break;
+case KBD_CMD_SET_MAKE_BREAK:
+ps2_queue(&s->common, KBD_REPLY_ACK);
+s->common.write_cmd = -1;
+break;
 case KBD_CMD_SCANCODE:
 if (val == 0) {
 if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
-- 
2.23.0




[PATCH v3 0/6] HPPA: i82596, PS/2 and graphics emulation

2019-10-22 Thread Sven Schnelle
Hi,

these series adds quite a lot to the HPPA emulation in QEMU:
i82596 emulation from Helge, PS/2 and Artist graphics emulation.

See https://parisc.wiki.kernel.org/index.php/Qemu for a few screenshots
of QEMU running a X11/CDE session in HP-UX.

Changes in v3:
 - use BIT() macro in gsc_to_pci_forwarding()
 - fix version id in vm state
 - fix an error in the PS/2 KBD_CMD_SET_MAKE_BREAK implementation

Changes in v2:
 - dropped 'hppa: remove ISA region' as that patch requires some more work
 - added shortlog to seabios update
 - use const and MAKE_64BIT_MASK in dino.c

Regards,
Sven


Helge Deller (2):
  hw/hppa/dino.c: Improve emulation of Dino PCI chip
  hppa: Add support for LASI chip with i82596 NIC

Sven Schnelle (4):
  ps2: accept 'Set Key Make and Break' commands
  hppa: add emulation of LASI PS2 controllers
  hppa: Add emulation of Artist graphics
  seabios-hppa: update to latest version

 MAINTAINERS |4 +-
 hw/display/Kconfig  |3 +
 hw/display/Makefile.objs|1 +
 hw/display/artist.c | 1336 +++
 hw/display/trace-events |9 +
 hw/hppa/Kconfig |3 +
 hw/hppa/Makefile.objs   |2 +-
 hw/hppa/dino.c  |   97 ++-
 hw/hppa/hppa_hardware.h |1 +
 hw/hppa/hppa_sys.h  |2 +
 hw/hppa/lasi.c  |  368 ++
 hw/hppa/machine.c   |   18 +-
 hw/hppa/trace-events|   10 +
 hw/input/Kconfig|3 +
 hw/input/Makefile.objs  |1 +
 hw/input/lasips2.c  |  289 
 hw/input/ps2.c  |   15 +
 hw/input/trace-events   |5 +
 hw/net/Kconfig  |7 +
 hw/net/Makefile.objs|2 +
 hw/net/i82596.c |  734 +++
 hw/net/i82596.h |   55 ++
 hw/net/lasi_i82596.c|  188 +
 hw/net/trace-events |   13 +
 include/hw/input/lasips2.h  |   16 +
 include/hw/input/ps2.h  |1 +
 include/hw/net/lasi_82596.h |   29 +
 pc-bios/hppa-firmware.img   |  Bin 783724 -> 772876 bytes
 roms/seabios-hppa   |2 +-
 29 files changed, 3196 insertions(+), 18 deletions(-)
 create mode 100644 hw/display/artist.c
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/input/lasips2.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/input/lasips2.h
 create mode 100644 include/hw/net/lasi_82596.h

-- 
2.23.0




[PATCH v3 1/6] hw/hppa/dino.c: Improve emulation of Dino PCI chip

2019-10-22 Thread Sven Schnelle
From: Helge Deller 

The tests of the dino chip with the Online-diagnostics CD
("ODE DINOTEST") now succeeds.
Additionally add some qemu trace events.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
Reviewed-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS  |  2 +-
 hw/hppa/dino.c   | 97 +---
 hw/hppa/trace-events |  5 +++
 3 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 250ce8e7a1..f9541c3305 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -874,7 +874,7 @@ F: hw/*/etraxfs_*.c
 
 HP-PARISC Machines
 --
-Dino
+HP B160L
 M: Richard Henderson 
 R: Helge Deller 
 S: Odd Fixes
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index ab6969b45f..9797a7f0d9 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -1,7 +1,7 @@
 /*
- * HP-PARISC Dino PCI chipset emulation.
+ * HP-PARISC Dino PCI chipset emulation, as in B160L and similiar machines
  *
- * (C) 2017 by Helge Deller 
+ * (C) 2017-2019 by Helge Deller 
  *
  * This work is licensed under the GNU GPL license version 2 or later.
  *
@@ -21,6 +21,7 @@
 #include "migration/vmstate.h"
 #include "hppa_sys.h"
 #include "exec/address-spaces.h"
+#include "trace.h"
 
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
@@ -82,11 +83,28 @@
 #define DINO_PCI_HOST_BRIDGE(obj) \
 OBJECT_CHECK(DinoState, (obj), TYPE_DINO_PCI_HOST_BRIDGE)
 
+#define DINO800_REGS ((DINO_TLTIM - DINO_GMASK) / 4)
+static const uint32_t reg800_keep_bits[DINO800_REGS] = {
+MAKE_64BIT_MASK(0, 1),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 8),
+MAKE_64BIT_MASK(0, 7),
+MAKE_64BIT_MASK(0, 9),
+MAKE_64BIT_MASK(0, 32),
+MAKE_64BIT_MASK(0, 8),
+MAKE_64BIT_MASK(0, 30),
+MAKE_64BIT_MASK(0, 25),
+MAKE_64BIT_MASK(0, 22),
+MAKE_64BIT_MASK(0, 9),
+};
+
 typedef struct DinoState {
 PCIHostState parent_obj;
 
 /* PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.  */
+uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
 
 uint32_t iar0;
 uint32_t iar1;
@@ -94,8 +112,12 @@ typedef struct DinoState {
 uint32_t ipr;
 uint32_t icr;
 uint32_t ilr;
+uint32_t io_fbb_en;
 uint32_t io_addr_en;
 uint32_t io_control;
+uint32_t toc_addr;
+
+uint32_t reg800[DINO800_REGS];
 
 MemoryRegion this_mem;
 MemoryRegion pci_mem;
@@ -106,8 +128,6 @@ typedef struct DinoState {
 MemoryRegion bm_ram_alias;
 MemoryRegion bm_pci_alias;
 MemoryRegion bm_cpu_alias;
-
-MemoryRegion cpu0_eir_mem;
 } DinoState;
 
 /*
@@ -122,6 +142,8 @@ static void gsc_to_pci_forwarding(DinoState *s)
 tmp = extract32(s->io_control, 7, 2);
 enabled = (tmp == 0x01);
 io_addr_en = s->io_addr_en;
+/* Mask out first (=firmware) and last (=Dino) areas. */
+io_addr_en &= ~(BIT(31) | BIT(0));
 
 memory_region_transaction_begin();
 for (i = 1; i < 31; i++) {
@@ -142,6 +164,8 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 unsigned size, bool is_write,
 MemTxAttrs attrs)
 {
+bool ret = false;
+
 switch (addr) {
 case DINO_IAR0:
 case DINO_IAR1:
@@ -152,16 +176,22 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
 case DINO_ICR:
 case DINO_ILR:
 case DINO_IO_CONTROL:
+case DINO_IO_FBB_EN:
 case DINO_IO_ADDR_EN:
 case DINO_PCI_IO_DATA:
-return true;
+case DINO_TOC_ADDR:
+case DINO_GMASK ... DINO_TLTIM:
+ret = true;
+break;
 case DINO_PCI_IO_DATA + 2:
-return size <= 2;
+ret = (size <= 2);
+break;
 case DINO_PCI_IO_DATA + 1:
 case DINO_PCI_IO_DATA + 3:
-return size == 1;
+ret = (size == 1);
 }
-return false;
+trace_dino_chip_mem_valid(addr, ret);
+return ret;
 }
 
 static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr,
@@ -194,6 +224,9 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, 
hwaddr addr,
 }
 break;
 
+case DINO_IO_FBB_EN:
+val = s->io_fbb_en;
+break;
 case DINO_IO_ADDR_EN:
 val = s->io_addr_en;
 break;
@@ -227,12 +260,28 @@ static MemTxResult dino_chip_read_with_attrs(void 
*opaque, hwaddr addr,
 case DINO_IRR1:
 val = s->ilr & s->imr & s->icr;
 break;
+case DINO_TOC_ADDR:
+val = s->toc_addr;
+break;
+case DINO_GMASK ... DINO_TLTIM:
+val = s->reg800[(addr - DINO_GMASK) / 4];
+if (addr == DINO_PAMR) {
+val &= ~0x01;  /* LSB is hardwired to 0 */
+}
+i

[PATCH v3 5/6] hppa: Add emulation of Artist graphics

2019-10-22 Thread Sven Schnelle
This adds emulation of Artist graphics good enough
to get a Text console on both Linux and HP-UX. The
X11 server from HP-UX also works.

Signed-off-by: Sven Schnelle 
---
 hw/display/Kconfig   |3 +
 hw/display/Makefile.objs |1 +
 hw/display/artist.c  | 1336 ++
 hw/display/trace-events  |9 +
 hw/hppa/Kconfig  |1 +
 hw/hppa/hppa_hardware.h  |1 +
 hw/hppa/machine.c|   10 +
 7 files changed, 1361 insertions(+)
 create mode 100644 hw/display/artist.c

diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index cbdf7b1a67..953631afb6 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -91,6 +91,9 @@ config TCX
 config CG3
 bool
 
+config ARTIST
+bool
+
 config VGA
 bool
 
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 5a4066383b..5f63294149 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -39,6 +39,7 @@ common-obj-$(CONFIG_SM501) += sm501.o
 common-obj-$(CONFIG_TCX) += tcx.o
 common-obj-$(CONFIG_CG3) += cg3.o
 common-obj-$(CONFIG_NEXTCUBE) += next-fb.o
+common-obj-$(CONFIG_ARTIST) += artist.o
 
 obj-$(CONFIG_VGA) += vga.o
 
diff --git a/hw/display/artist.c b/hw/display/artist.c
new file mode 100644
index 00..9b285b3993
--- /dev/null
+++ b/hw/display/artist.c
@@ -0,0 +1,1336 @@
+/*
+ * QEMU HP Artist Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/typedefs.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/loader.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "ui/console.h"
+#include "trace.h"
+
+#define TYPE_ARTIST "artist"
+#define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST)
+
+struct vram_buffer {
+uint8_t *data;
+int size;
+int width;
+int height;
+};
+
+typedef struct ARTISTState {
+SysBusDevice parent_obj;
+
+QemuConsole *con;
+MemoryRegion vram_mem;
+MemoryRegion reg;
+uint8_t *vram;
+
+struct vram_buffer vram_buffer[16];
+
+uint16_t width;
+uint16_t height;
+uint16_t depth;
+
+uint32_t fg_color;
+uint32_t bg_color;
+
+uint32_t vram_char_y;
+uint32_t vram_bitmask;
+
+uint32_t vram_start;
+uint32_t vram_pos;
+
+uint32_t vram_size;
+
+uint32_t blockmove_source;
+uint32_t blockmove_dest;
+uint32_t blockmove_size;
+
+uint32_t line_size;
+uint32_t line_end;
+uint32_t line_xy;
+uint32_t line_pattern_start;
+uint32_t line_pattern_skip;
+
+uint32_t cursor_pos;
+
+uint32_t cursor_height;
+uint32_t cursor_width;
+
+uint32_t plane_mask;
+
+uint32_t reg_100080;
+uint32_t reg_300200;
+uint32_t reg_300208;
+uint32_t reg_300218;
+
+uint32_t cmap_bm_access;
+uint32_t dst_bm_access;
+uint32_t src_bm_access;
+uint32_t control_plane;
+uint32_t transfer_data;
+uint32_t image_bitmap_op;
+
+uint32_t font_write1;
+uint32_t font_write2;
+uint32_t font_write_pos_y;
+
+int draw_line_pattern;
+} ARTISTState;
+
+typedef enum {
+ARTIST_BUFFER_AP = 1,
+ARTIST_BUFFER_OVERLAY = 2,
+ARTIST_BUFFER_CURSOR1 = 6,
+ARTIST_BUFFER_CURSOR2 = 7,
+ARTIST_BUFFER_ATTRIBUTE = 13,
+ARTIST_BUFFER_CMAP = 15,
+} artist_buffer_t;
+
+typedef enum {
+VRAM_IDX = 0x1004a0,
+VRAM_BITMASK = 0x1005a0,
+VRAM_WRITE_INCR_X = 0x100600,
+VRAM_WRITE_INCR_X2 = 0x100604,
+VRAM_WRITE_INCR_Y = 0x100620,
+VRAM_START = 0x100800,
+BLOCK_MOVE_SIZE = 0x100804,
+BLOCK_MOVE_SOURCE = 0x100808,
+TRANSFER_DATA = 0x100820,
+FONT_WRITE_INCR_Y = 0x1008a0,
+VRAM_START_TRIGGER = 0x100a00,
+VRAM_SIZE_TRIGGER = 0x100a04,
+FONT_WRITE_START = 0x100aa0,
+BLOCK_MOVE_DEST_TRIGGER = 0x100b00,
+BLOCK_MOVE_SIZE_TRIGGER = 0x100b04,
+LINE_XY = 0x100ccc,
+PATTERN_LINE_START = 0x100ecc,
+LINE_SIZE = 0x100e04,
+LINE_END = 0x100e44,
+CMAP_BM_ACCESS = 0x118000,
+DST_BM_ACCESS = 0x118004,
+SRC_BM_ACCESS = 0x118008,
+CONTROL_PLANE = 0x11800c,
+FG_COLOR = 0x118010,
+BG_COLOR = 0x118014,
+PLANE_MASK = 0x118018,
+IMAGE_BITMAP_OP = 0x11801c,
+CURSOR_POS = 0x300100,
+CURSOR_CTRL = 0x300104,
+} artist_reg_t;
+
+typedef enum {
+ARTIST_ROP_CLEAR = 0,
+ARTIST_ROP_COPY = 3,
+ARTIST_ROP_XOR = 6,
+ARTIST_ROP_NOT_DST = 10,
+ARTIST_ROP_SET = 15,
+} artist_rop_t;
+
+#define REG_NAME(_x) case _x: return " "#_x;
+static const char *artist_reg_name(uint64_t addr)
+{
+switch ((artist_reg_t)addr) {
+REG_NAME(VRAM_IDX);
+REG_NAME(VRAM_BITMASK);

[PATCH v3 4/6] hppa: add emulation of LASI PS2 controllers

2019-10-22 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 hw/hppa/Kconfig|   1 +
 hw/hppa/lasi.c |  10 +-
 hw/input/Kconfig   |   3 +
 hw/input/Makefile.objs |   1 +
 hw/input/lasips2.c | 289 +
 hw/input/ps2.c |   5 +
 hw/input/trace-events  |   5 +
 include/hw/input/lasips2.h |  16 ++
 include/hw/input/ps2.h |   1 +
 9 files changed, 330 insertions(+), 1 deletion(-)
 create mode 100644 hw/input/lasips2.c
 create mode 100644 include/hw/input/lasips2.h

diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 2a7b38d6d6..7f9be7f25c 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -11,3 +11,4 @@ config DINO
 select MC146818RTC
 select LSI_SCSI_PCI
 select LASI_82596
+select LASIPS2
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
index 51752589f3..d8d03f95c0 100644
--- a/hw/hppa/lasi.c
+++ b/hw/hppa/lasi.c
@@ -22,6 +22,7 @@
 #include "hw/net/lasi_82596.h"
 #include "hw/char/parallel.h"
 #include "hw/char/serial.h"
+#include "hw/input/lasips2.h"
 #include "exec/address-spaces.h"
 #include "migration/vmstate.h"
 
@@ -324,6 +325,7 @@ DeviceState *lasi_init(MemoryRegion *address_space)
  lpt_irq, parallel_hds[0]);
 
 /* Real time clock (RTC), it's only one 32-bit counter @9000 */
+
 s->rtc = time(NULL);
 s->rtc_ref = 0;
 
@@ -333,8 +335,14 @@ DeviceState *lasi_init(MemoryRegion *address_space)
 lasi_get_irq(LASI_UART_HPA));
 serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0,
 serial_irq, 800 / 16,
-serial_hd(1), DEVICE_NATIVE_ENDIAN);
+serial_hd(0), DEVICE_NATIVE_ENDIAN);
 }
+
+/* PS/2 Keyboard/Mouse */
+qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s,
+lasi_get_irq(LASI_PS2KBD_HPA));
+lasips2_init(address_space, LASI_PS2KBD_HPA,  ps2kbd_irq);
+
 return dev;
 }
 
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
index 287f08887b..25c77a1b87 100644
--- a/hw/input/Kconfig
+++ b/hw/input/Kconfig
@@ -41,3 +41,6 @@ config VHOST_USER_INPUT
 
 config TSC210X
 bool
+
+config LASIPS2
+select PS2
diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
index a1bc502ed0..f98f635685 100644
--- a/hw/input/Makefile.objs
+++ b/hw/input/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VHOST_USER_INPUT) += vhost-user-input.o
 obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_keypad.o
 obj-$(CONFIG_TSC210X) += tsc210x.o
+obj-$(CONFIG_LASIPS2) += lasips2.o
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
new file mode 100644
index 00..1943671d1e
--- /dev/null
+++ b/hw/input/lasips2.c
@@ -0,0 +1,289 @@
+/*
+ * QEMU HP Lasi PS/2 interface emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/hw.h"
+#include "hw/input/ps2.h"
+#include "hw/input/lasips2.h"
+#include "hw/sysbus.h"
+#include "exec/hwaddr.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+struct LASIPS2State;
+typedef struct LASIPS2Port {
+struct LASIPS2State *parent;
+MemoryRegion reg;
+void *dev;
+uint8_t id;
+uint8_t control;
+uint8_t buf;
+bool loopback_rbne;
+bool irq;
+} LASIPS2Port;
+
+typedef struct LASIPS2State {
+LASIPS2Port kbd;
+LASIPS2Port mouse;
+qemu_irq irq;
+} LASIPS2State;
+
+static const VMStateDescription vmstate_lasips2 = {
+.name = "lasips2",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]

[PATCH v3 2/6] hppa: Add support for LASI chip with i82596 NIC

2019-10-22 Thread Sven Schnelle
From: Helge Deller 

LASI is a built-in multi-I/O chip which supports serial, parallel,
network (Intel i82596 Apricot), sound and other functionalities.
LASI has been used in many HP PARISC machines.
This patch adds the necessary parts to allow Linux and HP-UX to detect
LASI and the network card.

Signed-off-by: Helge Deller 
Signed-off-by: Sven Schnelle 
---
 MAINTAINERS |   2 +
 hw/hppa/Kconfig |   1 +
 hw/hppa/Makefile.objs   |   2 +-
 hw/hppa/hppa_sys.h  |   2 +
 hw/hppa/lasi.c  | 360 ++
 hw/hppa/machine.c   |   8 +-
 hw/hppa/trace-events|   5 +
 hw/net/Kconfig  |   7 +
 hw/net/Makefile.objs|   2 +
 hw/net/i82596.c | 734 
 hw/net/i82596.h |  55 +++
 hw/net/lasi_i82596.c| 188 +
 hw/net/trace-events |  13 +
 include/hw/net/lasi_82596.h |  29 ++
 14 files changed, 1406 insertions(+), 2 deletions(-)
 create mode 100644 hw/hppa/lasi.c
 create mode 100644 hw/net/i82596.c
 create mode 100644 hw/net/i82596.h
 create mode 100644 hw/net/lasi_i82596.c
 create mode 100644 include/hw/net/lasi_82596.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f9541c3305..91e9e8ceac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -178,6 +178,8 @@ S: Maintained
 F: target/hppa/
 F: hw/hppa/
 F: disas/hppa.c
+F: hw/net/*i82596*
+F: include/hw/net/lasi_82596.h
 
 LM32 TCG CPUs
 M: Michael Walle 
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 6e5d74a825..2a7b38d6d6 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -10,3 +10,4 @@ config DINO
 select IDE_CMD646
 select MC146818RTC
 select LSI_SCSI_PCI
+select LASI_82596
diff --git a/hw/hppa/Makefile.objs b/hw/hppa/Makefile.objs
index 67838f50a3..eac3467d8a 100644
--- a/hw/hppa/Makefile.objs
+++ b/hw/hppa/Makefile.objs
@@ -1 +1 @@
-obj-$(CONFIG_DINO) += pci.o machine.o dino.o
+obj-$(CONFIG_DINO) += pci.o machine.o dino.o lasi.o
diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h
index 43d25d21fc..d99b5dd87b 100644
--- a/hw/hppa/hppa_sys.h
+++ b/hw/hppa/hppa_sys.h
@@ -11,6 +11,8 @@
 #include "hppa_hardware.h"
 
 PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
+DeviceState *lasi_init(MemoryRegion *);
+#define enable_lasi_lan()   0
 
 #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
 
diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c
new file mode 100644
index 00..51752589f3
--- /dev/null
+++ b/hw/hppa/lasi.c
@@ -0,0 +1,360 @@
+/*
+ * HP-PARISC Lasi chipset emulation.
+ *
+ * (C) 2019 by Helge Deller 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ * Documentation available at:
+ * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "trace.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+#include "hppa_sys.h"
+#include "hw/net/lasi_82596.h"
+#include "hw/char/parallel.h"
+#include "hw/char/serial.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+
+#define TYPE_LASI_CHIP "lasi-chip"
+
+#define LASI_IRR0x00/* RO */
+#define LASI_IMR0x04
+#define LASI_IPR0x08
+#define LASI_ICR0x0c
+#define LASI_IAR0x10
+
+#define LASI_PCR0x0C000 /* LASI Power Control register */
+#define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */
+#define LASI_VER0x0C008 /* LASI Version Control register */
+#define LASI_IORESET0x0C00C /* LASI I/O Reset register */
+#define LASI_AMR0x0C010 /* LASI Arbitration Mask register */
+#define LASI_IO_CONF0x7FFFE /* LASI primary configuration register */
+#define LASI_IO_CONF2   0x7 /* LASI secondary configuration register */
+
+#define LASI_BIT(x) (1ul << (x))
+#define LASI_IRQ_BITS   (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) 
\
+| LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
+| LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
+| LASI_BIT(26))
+
+#define ICR_BUS_ERROR_BIT  LASI_BIT(8)  /* bit 8 in ICR */
+#define ICR_TOC_BITLASI_BIT(1)  /* bit 1 in ICR */
+
+#define LASI_CHIP(obj) \
+OBJECT_CHECK(LasiState, (obj), TYPE_LASI_CHIP)
+
+#define LASI_RTC_HPA(LASI_HPA + 0x9000)
+
+typedef struct LasiState {
+PCIHostState parent_obj;
+
+uint32_t irr;
+uint32_t imr;
+uint32_t ipr;
+uint32_t icr;
+uint32_t iar;
+
+uint32_t errlog;
+uint32_t amr;
+uint32_t rtc;
+time_t rtc_ref;
+
+MemoryRegion this_mem;
+} LasiState;
+
+static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
+unsigned size

Re: [PATCH v2] net: add tulip (dec21143) driver

2019-10-23 Thread Sven Schnelle
On Tue, Oct 22, 2019 at 05:00:16PM +0100, Peter Maydell wrote:
> 
> There are a couple of minor wrong-indent nits:
> 
> > +static void tulip_update_ts(TULIPState *s, int state)
> > +{
> > +s->csr[5] &= ~(CSR5_TS_MASK << CSR5_TS_SHIFT);
> > +s->csr[5] |= (state & CSR5_TS_MASK) << CSR5_TS_SHIFT;
> > +trace_tulip_tx_state(tulip_tx_state_name(state));
> > +}
> 
> > +struct tulip_descriptor {
> > +uint32_t status;
> > +uint32_t control;
> > +uint32_t buf_addr1;
> > +uint32_t buf_addr2;
> > +};
> 
> but maybe Jason can fix those up when he takes the patch ?

I'll send an updated version soon - there are some other small things
that i need to address.

Thanks
Sven



[PATCH v3] net: add tulip (dec21143) driver

2019-10-23 Thread Sven Schnelle
This adds the basic functionality to emulate a Tulip NIC.

Implemented are:

- RX and TX functionality
- Perfect Frame Filtering
- Big/Little Endian descriptor support
- 93C46 EEPROM support
- LXT970 PHY

Not implemented, mostly because i had no OS using these functions:

- Imperfect frame filtering
- General Purpose Timer
- Transmit automatic polling
- Boot ROM support
- SIA interface
- Big/Little Endian data buffer conversion

Successfully tested with the following Operating Systems:

- MSDOS with Microsoft Network Client 3.0 and DEC ODI drivers
- HPPA Linux
- Windows XP
- HP-UX

Signed-off-by: Sven Schnelle 
Message-Id: <20191022155413.4619-1-sv...@stackframe.org>
Reviewed-by: Peter Maydell 
---

Changes in v3:
 - fix whitespace
 - fix format string in read/write functions

Changes in v2:
 - changed tulip_desc_{read,write} to take a struct descriptor *
   and no longer use a single pci DMA write, instead write one
   struct member at a time.
 - fix _tulip_receive function name 
 - fix reset function and provide tulip_qdev_reset() for dc->reset.
 - no longer write registers in the default case in tulip_write()
 - set .impl.min_access_size and .impl.max_access_size

 MAINTAINERS  |6 +
 hw/net/Kconfig   |5 +
 hw/net/Makefile.objs |1 +
 hw/net/trace-events  |   14 +
 hw/net/tulip.c   | 1029 ++
 hw/net/tulip.h   |  267 ++
 include/hw/pci/pci_ids.h |1 +
 7 files changed, 1323 insertions(+)
 create mode 100644 hw/net/tulip.c
 create mode 100644 hw/net/tulip.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 250ce8e7a1..a12031c389 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1638,6 +1638,12 @@ M: Stefan Weil 
 S: Maintained
 F: hw/net/eepro100.c
 
+tulip
+M: Sven Schnelle 
+S: Maintained
+F: hw/net/tulip.c
+F: hw/net/tulip.h
+
 Generic Loader
 M: Alistair Francis 
 S: Maintained
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 4ef86dc3a5..3856417d42 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -24,6 +24,11 @@ config PCNET_PCI
 config PCNET_COMMON
 bool
 
+config TULIP
+bool
+default y if PCI_DEVICES
+depends on PCI
+
 config E1000_PCI
 bool
 default y if PCI_DEVICES
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 9904273b06..7907d2c199 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -13,6 +13,7 @@ common-obj-$(CONFIG_E1000E_PCI_EXPRESS) += e1000e.o 
e1000e_core.o e1000x_common.
 common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
 common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o
 common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet3.o
+common-obj-$(CONFIG_TULIP) += tulip.o
 
 common-obj-$(CONFIG_SMC91C111) += smc91c111.o
 common-obj-$(CONFIG_LAN9118) += lan9118.o
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 58665655cc..e70f12bee1 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -367,3 +367,17 @@ virtio_net_announce_notify(void) ""
 virtio_net_announce_timer(int round) "%d"
 virtio_net_handle_announce(int round) "%d"
 virtio_net_post_load_device(void)
+
+# tulip.c
+tulip_reg_write(uint64_t addr, const char *name, int size, uint64_t val) "addr 
0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
+tulip_reg_read(uint64_t addr, const char *name, int size, uint64_t val) "addr 
0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
+tulip_receive(const uint8_t *buf, size_t len) "buf %p size %zu"
+tulip_descriptor(const char *prefix, uint32_t addr, uint32_t status, uint32_t 
control, uint32_t len1, uint32_t len2, uint32_t buf1, uint32_t buf2) "%s 
0x%08x: status 0x%08x control 0x%03x len1 %4d len2 %4d buf1 0x%08x buf2 0x%08x"
+tulip_rx_state(const char *state) "RX %s"
+tulip_tx_state(const char *state) "TX %s"
+tulip_irq(uint32_t mask, uint32_t en, const char *state) "mask 0x%08x ie 
0x%08x %s"
+tulip_mii_write(int phy, int reg, uint16_t data) "phy 0x%x reg 0x%x data 
0x%04x"
+tulip_mii_read(int phy, int reg, uint16_t data) "phy 0x%x, reg 0x%x data 
0x%04x"
+tulip_reset(void) ""
+tulip_setup_frame(void) ""
+tulip_setup_filter(int n, uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t 
e, uint8_t f) "%d: %02x:%02x:%02x:%02x:%02x:%02x"
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
new file mode 100644
index 00..f74b08b375
--- /dev/null
+++ b/hw/net/tulip.c
@@ -0,0 +1,1029 @@
+/*
+ * QEMU TULIP Emulation
+ *
+ * Copyright (c) 2019 Sven Schnelle 
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "hw/nvram/eeprom93xx.h"
+#include "migration/vmstate.h"
+#include "sysemu/sysemu.h"
+#include "tulip.h&qu

Re: [PATCH v3 3/6] ps2: accept 'Set Key Make and Break' commands

2019-10-23 Thread Sven Schnelle
Hi Philippe,

On Wed, Oct 23, 2019 at 01:08:35PM +0200, Philippe Mathieu-Daudé wrote:
> Hi Sven,
> 
> (Please Cc reviewers who previously commented your patch)
>
> On 10/22/19 10:59 PM, Sven Schnelle wrote:
> > HP-UX sends both the 'Set key make and break (0xfc) and
> > 'Set all key typematic make and break' (0xfa). QEMU response
> > with 'Resend' as it doesn't handle these commands. HP-UX than
> > reports an PS/2 max retransmission exceeded error. Add these
> > commands and just reply with ACK.
> > 
> > Signed-off-by: Sven Schnelle 
> > ---
> >   hw/input/ps2.c | 10 ++
> >   1 file changed, 10 insertions(+)
> > 
> > diff --git a/hw/input/ps2.c b/hw/input/ps2.c
> > index 67f92f6112..0b671b6339 100644
> > --- a/hw/input/ps2.c
> > +++ b/hw/input/ps2.c
> > @@ -49,6 +49,8 @@
> >   #define KBD_CMD_RESET_DISABLE 0xF5/* reset and disable scanning */
> >   #define KBD_CMD_RESET_ENABLE  0xF6/* reset and enable scanning */
> >   #define KBD_CMD_RESET 0xFF/* Reset */
> > +#define KBD_CMD_SET_MAKE_BREAK  0xFC/* Set Make and Break mode */
> > +#define KBD_CMD_SET_TYPEMATIC   0xFA/* Set Typematic Make and Break 
> > mode */
> >   /* Keyboard Replies */
> >   #define KBD_REPLY_POR 0xAA/* Power on reset */
> > @@ -573,6 +575,7 @@ void ps2_write_keyboard(void *opaque, int val)
> >   case KBD_CMD_SCANCODE:
> >   case KBD_CMD_SET_LEDS:
> >   case KBD_CMD_SET_RATE:
> > +case KBD_CMD_SET_MAKE_BREAK:
> 
> OK
> 
> >   s->common.write_cmd = val;
> >   ps2_queue(&s->common, KBD_REPLY_ACK);
> >   break;
> > @@ -592,11 +595,18 @@ void ps2_write_keyboard(void *opaque, int val)
> >   KBD_REPLY_ACK,
> >   KBD_REPLY_POR);
> >   break;
> > +case KBD_CMD_SET_TYPEMATIC:
> > +ps2_queue(&s->common, KBD_REPLY_ACK);
> 
> I'm not sure, can't this loop?

I don't see how?

> Can you fold it with the '0x00' case?

Ok.

> > +break;
> >   default:
> >   ps2_queue(&s->common, KBD_REPLY_RESEND);
> >   break;
> >   }
> >   break;
> > +case KBD_CMD_SET_MAKE_BREAK:
> 
> We can reorder this one in the same case with:
> 
> case KBD_CMD_SET_LEDS:
> case KBD_CMD_SET_RATE:

Ok.

> > +ps2_queue(&s->common, KBD_REPLY_ACK);
> > +s->common.write_cmd = -1;
> > +break;
> >   case KBD_CMD_SCANCODE:
> >   if (val == 0) {
> >   if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
> > 
> 

Regards
Sven



  1   2   >