> > "Gonglei (Arei)" <arei.gong...@huawei.com> wrote: > >> Hi, > >> > >> > Anything bigger than 16bytes, no? And that is the whole point that we > >> > are talking about? Or the 16bytes that we are using can be at any place > >> > on the buffer? > >> > >> Yes. It's a ring buffer, with rptr pointing to the first used element > >> and wptr pointing to the first free element. > >> > >> So, what we need is a function to move the content we are interested > >> (between rptr and wptr) in to the head of the ring buffer, set rptr to > >> 0, set wptr to count. We obviously need to do that in post_load(), but > >> as I've noticed meanwhile also in pre_save, otherwise old qemu will get > >> things wrong in case the buffer is wrapped (rptr > wptr). > >> > > Hi, Gerd. Maybe we just need to do in post_load(). Such as the follow code: > > > > static int ps2_kbd_post_load(void* opaque, int version_id) > > { > > PS2KbdState *s = (PS2KbdState*)opaque; > > cast not needed. This is the original code, I don't change it. Maybe I should post the diff file, Sorry.
> > > PS2State *ps2 = &s->common; > > PS2Queue *q = &ps2->queue; > > int size; > > int i; > > > > if (version_id == 2) > > s->scancode_set=2; > > /* the new version id for this patch */ > > if (version_id == 4) { > > return 0; > > } > > /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ > > size = MIN(q->count, PS2_QUEUE_SIZE); > > printf(" ==kbd: rptr: %d, wptr: %d, count: %d, size: %d\n", q->rptr, > q->wptr, q->count, size); > > for (i = 0; i < size; i++) { > > /* move the queue elements to the start of data array */ > > q->data[i] = q->data[q->rptr]; > > It is me, or this don't work if the destination and source regions > overlap? Yes, it depens on how it overlaps. Good catch, Juan, Thanks. It should use a temp data array to save the q->data[] value, Such as below: int size; int i; int tmp_data[PS2_QUEUE_SIZE]; /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ size = MIN(q->count, PS2_QUEUE_SIZE); printf(" ==kbd: rptr: %d, wptr: %d, count: %d, size: %d\n", q->rptr, q->wptr, q->count, size); for (i = 0; i < size; i++) { /* move the queue elements to the tmp data array */ tmp_data[i] = q->data[q->rptr]; if (++q->rptr == 256) { q->rptr = 0; } } for (i = 0; i < size; i++) { /* move the queue elements to the start of data array */ q->data[i] = tmp_data[i]; } /* reset rptr/wptr/count */ q->rptr = 0; q->wptr = size; q->count = size; s->update_irq(s->update_arg, q->count != 0); return 0; } Best regards, -Gonglei