Re: [Qemu-devel] Coroutines and ucontext
On Fri, Jan 27, 2012 at 15:39, Paolo Bonzini wrote: >> I have a patch that uses sigsetjmp and siglongjmp instead of >> makecontext and getcontext (and all the ucontext stuff), and it >> *seems* to work... but I'm not sure if it works "by accident" (not >> sure what I'm doing to the stack, not sure what I should be doing to >> the stack). > > You can post it, don't worry. I'm curious how you are switching stacks when > creating the coroutine. > I think that I'm not switching, so at first I didn't understand why could it run at all. Now I think that qemu-img is too simple and a new stack is not really needed (probably only one coroutine and straightforward, I'll check it). So it doesn't crash. Thank you very much for the advice and comments. I'll do some more tests, I expect to achieve something useful ^^ On Fri, Jan 27, 2012 at 15:48, Daniel P. Berrange wrote: >(...) > If you're curious about this kind of thing you might also want to > take a look at the GNU Pth code. In particular its pth_mctx.c > file which has several different implementations of userspace thread > switching, one using makecontext, another with sigstck/altstack > and some others doing something fugly I don't understand :-) Thanks! I will definetely look at it/them.
Re: [Qemu-devel] [PATCH] sdl: Do not grab mouse on mode switch while in background
On 2012-01-27 23:41, Jan Kiszka wrote: > From: Jan Kiszka > > When the mouse mode changes to absolute while the SDL windows is not in > focus, refrain from grabbing the input. It would steal from some other > window. I'll send out a SDL series with fixes and will include this. So forget about it for trivial. Thanks, Jan > > Signed-off-by: Jan Kiszka > --- > > I bet this makes no difference for your problem, Erik, but I came > across this while trying to reproduce the issue. > > ui/sdl.c | 30 -- > 1 files changed, 16 insertions(+), 14 deletions(-) > > diff --git a/ui/sdl.c b/ui/sdl.c > index 8cafc44..384276d 100644 > --- a/ui/sdl.c > +++ b/ui/sdl.c > @@ -483,12 +483,27 @@ static void sdl_grab_end(void) > sdl_update_caption(); > } > > +static void absolute_mouse_grab(void) > +{ > +int mouse_x, mouse_y; > + > +if (SDL_GetAppState() & SDL_APPINPUTFOCUS) { > +SDL_GetMouseState(&mouse_x, &mouse_y); > +if (mouse_x > 0 && mouse_x < real_screen->w - 1 && > +mouse_y > 0 && mouse_y < real_screen->h - 1) { > +sdl_grab_start(); > +} > +} > +} > + > static void sdl_mouse_mode_change(Notifier *notify, void *data) > { > if (kbd_mouse_is_absolute()) { > if (!absolute_enabled) { > -sdl_grab_start(); > absolute_enabled = 1; > +if (is_graphic_console()) { > +absolute_mouse_grab(); > +} > } > } else if (absolute_enabled) { > if (!gui_fullscreen) { > @@ -571,19 +586,6 @@ static void toggle_full_screen(DisplayState *ds) > vga_hw_update(); > } > > -static void absolute_mouse_grab(void) > -{ > -int mouse_x, mouse_y; > - > -if (SDL_GetAppState() & SDL_APPINPUTFOCUS) { > -SDL_GetMouseState(&mouse_x, &mouse_y); > -if (mouse_x > 0 && mouse_x < real_screen->w - 1 && > -mouse_y > 0 && mouse_y < real_screen->h - 1) { > -sdl_grab_start(); > -} > -} > -} > - > static void handle_keydown(DisplayState *ds, SDL_Event *ev) > { > int mod_state; signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] git bisect results
On 2012-01-27 23:52, Jan Kiszka wrote: > On 2012-01-26 14:10, Erik Rull wrote: >> I assume from these results that the gui_grab is never set to 1 when having >> entered the window in windowed mode with the cursor. >> >> Maybe that's why the sdl_grab_start() is called so often. >> >> It seems that the condition in sdl_grab_start() >> (SDL_WM_GrabInput(SDL_GRAB_ON) >> == SDL_GRAB_ON) is never fulfilled, otherwise the gui_grab would be set to >> 1. >> But the cursor is actually grabbed in windowed mode, otherwise I would not >> be >> able to click somewhere with the guest-windows-cursor. > > This might be a SDL limitation which does not show up everywhere. Here > it's fine e.g. > > The logic dates back to "Handle SDL grabs failing (Mark McLoughlin)", > 6bb816031f. Maybe we can solve that issue without relying on the > obviously unreliable return value. Need to reproduce that one as well, > though. Please check if git://git.kiszka.org/qemu.git queues/sdl fixes the issue for you. Namely reverting the above commit should do the trick. I obsoleted that fragile patch in my series. Thanks, Jan signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH V2] GRLIB UART: Add RX channel
On Thu, Jan 26, 2012 at 17:03, Fabien Chouteau wrote: > This patch implements the RX channel of GRLIB UART with a FIFO to > improve data rate. > > Signed-off-by: Fabien Chouteau > --- > hw/grlib_apbuart.c | 106 +++ > trace-events | 1 + > 2 files changed, 90 insertions(+), 17 deletions(-) > > diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c > index f8a64e1..51406c6 100644 > --- a/hw/grlib_apbuart.c > +++ b/hw/grlib_apbuart.c > @@ -24,7 +24,6 @@ > > #include "sysbus.h" > #include "qemu-char.h" > -#include "ptimer.h" > > #include "trace.h" > > @@ -66,6 +65,8 @@ > #define SCALER_OFFSET 0x0C /* not supported */ > #define FIFO_DEBUG_OFFSET 0x10 /* not supported */ > > +#define FIFO_LENGTH 1024 > + > typedef struct UART { > SysBusDevice busdev; > MemoryRegion iomem; > @@ -77,21 +78,67 @@ typedef struct UART { > uint32_t receive; > uint32_t status; > uint32_t control; > + > + /* FIFO */ > + char buffer[FIFO_LENGTH]; > + int len; > + int current; > } UART; > > +static int uart_data_to_read(UART *uart) > +{ > + return uart->current < uart->len; > +} > + > +static char uart_pop(UART *uart) > +{ > + char ret; > + > + if (uart->len == 0) { > + uart->status &= ~UART_DATA_READY; > + return 0; > + } > + > + ret = uart->buffer[uart->current++]; > + > + if (uart->current >= uart->len) { > + /* Flush */ > + uart->len = 0; > + uart->current = 0; > + } > + > + if (!uart_data_to_read(uart)) { > + uart->status &= ~UART_DATA_READY; > + } > + > + return ret; > +} > + > +static void uart_add_to_fifo(UART *uart, > + const uint8_t *buffer, > + int length) > +{ > + if (uart->len + length > FIFO_LENGTH) { > + abort(); A guest could trigger this abort(), which is not OK. I think you can just return. > + } > + memcpy(uart->buffer + uart->len, buffer, length); > + uart->len += length; > +} > + > static int grlib_apbuart_can_receive(void *opaque) > { > UART *uart = opaque; > > - return !!(uart->status & UART_DATA_READY); > + return FIFO_LENGTH - uart->len; > } > > static void grlib_apbuart_receive(void *opaque, const uint8_t *buf, int size) > { > UART *uart = opaque; > > - uart->receive = *buf; > - uart->status |= UART_DATA_READY; > + uart_add_to_fifo(uart, buf, size); > + > + uart->status |= UART_DATA_READY; > > if (uart->control & UART_RECEIVE_INTERRUPT) { > qemu_irq_pulse(uart->irq); > @@ -103,9 +150,39 @@ static void grlib_apbuart_event(void *opaque, int event) > trace_grlib_apbuart_event(event); > } > > -static void > -grlib_apbuart_write(void *opaque, target_phys_addr_t addr, > - uint64_t value, unsigned size) > + > +static uint64_t grlib_apbuart_read(void *opaque, target_phys_addr_t addr, > + unsigned size) > +{ > + UART *uart = opaque; > + > + addr &= 0xff; > + > + /* Unit registers */ > + switch (addr) { > + case DATA_OFFSET: > + case DATA_OFFSET + 3: /* when only one byte read */ > + return uart_pop(uart); > + > + case STATUS_OFFSET: > + /* Read Only */ > + return uart->status; > + > + case CONTROL_OFFSET: > + return uart->control; > + > + case SCALER_OFFSET: > + /* Not supported */ > + return 0; > + > + default: > + trace_grlib_apbuart_readl_unknown(addr); > + return 0; > + } > +} > + > +static void grlib_apbuart_write(void *opaque, target_phys_addr_t addr, > + uint64_t value, unsigned size) > { > UART *uart = opaque; > unsigned char c = 0; > @@ -115,6 +192,7 @@ grlib_apbuart_write(void *opaque, target_phys_addr_t addr, > /* Unit registers */ > switch (addr) { > case DATA_OFFSET: > + case DATA_OFFSET + 3: /* When only one byte write */ > c = value & 0xFF; > qemu_chr_fe_write(uart->chr, &c, 1); > return; > @@ -124,7 +202,7 @@ grlib_apbuart_write(void *opaque, target_phys_addr_t addr, > return; > > case CONTROL_OFFSET: > - /* Not supported */ > + uart->control = value; > return; > > case SCALER_OFFSET: > @@ -138,21 +216,15 @@ grlib_apbuart_write(void *opaque, target_phys_addr_t > addr, > trace_grlib_apbuart_writel_unknown(addr, value); > } > > -static bool grlib_apbuart_accepts(void *opaque, target_phys_addr_t addr, > - unsigned size, bool is_write) > -{ > - return is_write && size == 4; > -} > - > static const MemoryRegionOps grlib_apbuart_ops = { > - .write = grlib_apbuart_write, > - .valid.accepts = grlib_apbuart_accepts, > + .write = grlib_apbuart_write, > + .read = grlib_apbuart_read, > .endianness = DEVICE_NATIVE_ENDIAN, > }; > > static int
Re: [Qemu-devel] suspend/resume not working on tip due to 59abb06
On Fri, Jan 27, 2012 at 21:27, Stefan Berger wrote: > On 01/27/2012 04:10 PM, Stefan Berger wrote: >> >> After bisecting the following commit seems to be the culprit for the >> suspend/resume problems that I am seeing with the current tip >> (73093354418602a2ff5e43cb91a21b17fbf047d8). >> >> commit 59abb06198ee9471e29c970f294eae80c0b39be1 >> Author: Blue Swirl >> Date: Sun Jan 22 11:00:44 2012 + >> >> Once I revert this patch on the tip everything works fine again... >> >> Stefan >> >> > And this patch here gets it to work: > > diff --git a/exec-obsolete.h b/exec-obsolete.h > index 03cf35e..a673386 100644 > --- a/exec-obsolete.h > +++ b/exec-obsolete.h > @@ -101,7 +101,7 @@ static inline void > cpu_physical_memory_mask_dirty_range(ram_ > end = start + length; > mask = ~dirty_flags; > p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); > - for (addr = start; addr <= end; addr += TARGET_PAGE_SIZE) { > + for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) { > *p++ &= mask; > } > } Nice. Please add a description (something like "Fix suspend/resume broken by off-by-one error in 7309...") and Signed-off-by: line.
Re: [Qemu-devel] git bisect results
Jan Kiszka wrote: On 2012-01-27 23:52, Jan Kiszka wrote: On 2012-01-26 14:10, Erik Rull wrote: I assume from these results that the gui_grab is never set to 1 when having entered the window in windowed mode with the cursor. Maybe that's why the sdl_grab_start() is called so often. It seems that the condition in sdl_grab_start() (SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) is never fulfilled, otherwise the gui_grab would be set to 1. But the cursor is actually grabbed in windowed mode, otherwise I would not be able to click somewhere with the guest-windows-cursor. This might be a SDL limitation which does not show up everywhere. Here it's fine e.g. The logic dates back to "Handle SDL grabs failing (Mark McLoughlin)", 6bb816031f. Maybe we can solve that issue without relying on the obviously unreliable return value. Need to reproduce that one as well, though. Please check if git://git.kiszka.org/qemu.git queues/sdl fixes the issue for you. Namely reverting the above commit should do the trick. I obsoleted that fragile patch in my series. Thanks, Jan Hi Jan, I will test this on monday. Can you tell me how I can merge that into my cloned main qemu repository? I'm quite new to git. Thanks. Best regards, Erik
Re: [Qemu-devel] git bisect results
On 2012-01-28 13:39, Erik Rull wrote: > Jan Kiszka wrote: >> On 2012-01-27 23:52, Jan Kiszka wrote: >>> On 2012-01-26 14:10, Erik Rull wrote: I assume from these results that the gui_grab is never set to 1 when having entered the window in windowed mode with the cursor. Maybe that's why the sdl_grab_start() is called so often. It seems that the condition in sdl_grab_start() (SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) is never fulfilled, otherwise the gui_grab would be set to 1. But the cursor is actually grabbed in windowed mode, otherwise I would not be able to click somewhere with the guest-windows-cursor. >>> >>> This might be a SDL limitation which does not show up everywhere. Here >>> it's fine e.g. >>> >>> The logic dates back to "Handle SDL grabs failing (Mark McLoughlin)", >>> 6bb816031f. Maybe we can solve that issue without relying on the >>> obviously unreliable return value. Need to reproduce that one as well, >>> though. >> >> Please check if >> >> git://git.kiszka.org/qemu.git queues/sdl >> >> fixes the issue for you. Namely reverting the above commit should do the >> trick. I obsoleted that fragile patch in my series. >> >> Thanks, >> Jan >> >> > > Hi Jan, > > I will test this on monday. Can you tell me how I can merge that into my > cloned main qemu repository? I'm quite new to git. # git remote add kiszka git://git.kiszka.org/qemu.git # git fetch kiszka # git checkout kiszka/queues/sdl That way you will have what I have. Or do you need additional patches for your tests? Jan signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] git bisect results
Jan Kiszka wrote: On 2012-01-28 13:39, Erik Rull wrote: Jan Kiszka wrote: On 2012-01-27 23:52, Jan Kiszka wrote: On 2012-01-26 14:10, Erik Rull wrote: I assume from these results that the gui_grab is never set to 1 when having entered the window in windowed mode with the cursor. Maybe that's why the sdl_grab_start() is called so often. It seems that the condition in sdl_grab_start() (SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) is never fulfilled, otherwise the gui_grab would be set to 1. But the cursor is actually grabbed in windowed mode, otherwise I would not be able to click somewhere with the guest-windows-cursor. This might be a SDL limitation which does not show up everywhere. Here it's fine e.g. The logic dates back to "Handle SDL grabs failing (Mark McLoughlin)", 6bb816031f. Maybe we can solve that issue without relying on the obviously unreliable return value. Need to reproduce that one as well, though. Please check if git://git.kiszka.org/qemu.git queues/sdl fixes the issue for you. Namely reverting the above commit should do the trick. I obsoleted that fragile patch in my series. Thanks, Jan Hi Jan, I will test this on monday. Can you tell me how I can merge that into my cloned main qemu repository? I'm quite new to git. # git remote add kiszka git://git.kiszka.org/qemu.git # git fetch kiszka # git checkout kiszka/queues/sdl That way you will have what I have. Or do you need additional patches for your tests? Jan No I think this will be sufficient. Will this work if I will add it to the qemu-kvm-1.0 tagged version? I have further issues when using the current master because this version does not boot up Windows XP at the moment. I was not able to bisect up to now where this issue was added. Best regards, Erik
Re: [Qemu-devel] [PULL 0/5] target-arm queue
On Wed, Jan 25, 2012 at 15:27, Peter Maydell wrote: > Here's the latest target-arm pullreq. It includes Mark's fix for > config_base_register, which is in turn a dependency of the arm-devs > pullreq I'm about to send out, and which I'd like to get in before > Anthony's QOM patchset lands and invalidates it :-) > > Please pull. Thanks, pulled. > -- PMM > > > The following changes since commit 5b4448d27d7c6ff6e18a1edc8245cb1db783e37c: > > Merge remote-tracking branch 'qemu-kvm/uq/master' into staging (2012-01-23 > 11:00:26 -0600) > > are available in the git repository at: > > git://git.linaro.org/people/pmaydell/qemu-arm.git target-arm.for-upstream > > Mark Langsdorf (1): > arm: store the config_base_register during cpu_reset > > Peter Maydell (4): > target-arm: Fix implementation of TLB invalidate operations > target-arm/helper.c: Don't assume softfloat int32 is 32 bits only > Add dummy implementation of generic timer cp15 registers > Add Cortex-A15 CPU definition > > target-arm/cpu.h | 2 + > target-arm/helper.c | 86 > ++- > 2 files changed, 73 insertions(+), 15 deletions(-)
Re: [Qemu-devel] git bisect results
On 2012-01-28 14:01, Erik Rull wrote: > Jan Kiszka wrote: >> On 2012-01-28 13:39, Erik Rull wrote: >>> Jan Kiszka wrote: On 2012-01-27 23:52, Jan Kiszka wrote: > On 2012-01-26 14:10, Erik Rull wrote: >> I assume from these results that the gui_grab is never set to 1 when >> having >> entered the window in windowed mode with the cursor. >> >> Maybe that's why the sdl_grab_start() is called so often. >> >> It seems that the condition in sdl_grab_start() >> (SDL_WM_GrabInput(SDL_GRAB_ON) >> == SDL_GRAB_ON) is never fulfilled, otherwise the gui_grab would be >> set to 1. >> But the cursor is actually grabbed in windowed mode, otherwise I >> would not be >> able to click somewhere with the guest-windows-cursor. > > This might be a SDL limitation which does not show up everywhere. Here > it's fine e.g. > > The logic dates back to "Handle SDL grabs failing (Mark McLoughlin)", > 6bb816031f. Maybe we can solve that issue without relying on the > obviously unreliable return value. Need to reproduce that one as well, > though. Please check if git://git.kiszka.org/qemu.git queues/sdl fixes the issue for you. Namely reverting the above commit should do the trick. I obsoleted that fragile patch in my series. Thanks, Jan >>> >>> Hi Jan, >>> >>> I will test this on monday. Can you tell me how I can merge that into my >>> cloned main qemu repository? I'm quite new to git. >> >> # git remote add kiszka git://git.kiszka.org/qemu.git >> # git fetch kiszka >> # git checkout kiszka/queues/sdl >> >> That way you will have what I have. Or do you need additional patches >> for your tests? >> >> Jan >> > > No I think this will be sufficient. Will this work if I will add it to > the qemu-kvm-1.0 tagged version? For your test, you can focus on applying http://git.kiszka.org/?p=qemu.git;a=commitdiff;h=0109c860ca59fddbecb47651be3cbf5135d8e82e on the target branch. > I have further issues when using the > current master because this version does not boot up Windows XP at the > moment. I was not able to bisect up to now where this issue was added. Hmm, works here. Which command line? Jan signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH 0/4] malta: Code updates for BIOS memory (flash) and LED array
Here are some Malta patches from my local repository. The first three patches try to clean the code for the flash based BIOS memory. I wrote them because my local Malta test environment runs the Malta emulation with a -kernel parameter, and testing of flash code was not possible. Patch 4 is independant of the other patches. Regards, Stefan [PATCH 1/4] malta: Clean allocation of bios region alias [PATCH 2/4] malta: Always allocate flash memory [PATCH 3/4] malta: Use symbolic hardware addresses [PATCH 4/4] malta: Fix display for LED array
[Qemu-devel] [PATCH 2/4] malta: Always allocate flash memory
There is no reason why there should not be a flash memory when the Malta emulation is started with a Linux kernel. When flash memory is always available, the code is simpler, and it can be better tested. Signed-off-by: Stefan Weil --- hw/mips_malta.c | 54 ++ 1 files changed, 22 insertions(+), 32 deletions(-) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 7586971..e874efe 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -777,7 +777,7 @@ void mips_malta_init (ram_addr_t ram_size, MemoryRegion *system_memory = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1); -target_long bios_size; +target_long bios_size = 0x40; int64_t kernel_entry; PCIBus *pci_bus; ISABus *isa_bus; @@ -791,7 +791,7 @@ void mips_malta_init (ram_addr_t ram_size, DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; int fl_idx = 0; -int fl_sectors = 0; +int fl_sectors = bios_size >> 16; int be; DeviceState *dev = qdev_create(NULL, "mips-malta"); @@ -849,14 +849,24 @@ void mips_malta_init (ram_addr_t ram_size, /* FPGA */ malta_fpga_init(system_memory, 0x1f00LL, env->irq[2], serial_hds[2]); -/* Load firmware in flash / BIOS unless we boot directly into a kernel. */ +/* Load firmware in flash / BIOS. */ +dinfo = drive_get(IF_PFLASH, 0, fl_idx); +#ifdef DEBUG_BOARD_INIT +if (dinfo) { +printf("Register parallel flash %d size " TARGET_FMT_lx " at " + "addr %08llx '%s' %x\n", + fl_idx, bios_size, 0x1e00LL, + bdrv_get_device_name(dinfo->bdrv), fl_sectors); +} +#endif +fl = pflash_cfi01_register(0x1e00LL, NULL, "mips_malta.bios", + BIOS_SIZE, dinfo ? dinfo->bdrv : NULL, + 65536, fl_sectors, + 4, 0x, 0x, 0x, 0x, be); +bios = pflash_cfi01_get_memory(fl); +fl_idx++; if (kernel_filename) { /* Write a small bootloader to the flash location. */ -bios = g_new(MemoryRegion, 1); -memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE); -vmstate_register_ram_global(bios); -memory_region_set_readonly(bios, true); -memory_region_add_subregion(system_memory, 0x1e00LL, bios); loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; @@ -864,32 +874,12 @@ void mips_malta_init (ram_addr_t ram_size, kernel_entry = load_kernel(); write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { -dinfo = drive_get(IF_PFLASH, 0, fl_idx); -if (dinfo) { -/* Load firmware from flash. */ -bios_size = 0x40; -fl_sectors = bios_size >> 16; -#ifdef DEBUG_BOARD_INIT -printf("Register parallel flash %d size " TARGET_FMT_lx " at " - "addr %08llx '%s' %x\n", - fl_idx, bios_size, 0x1e00LL, - bdrv_get_device_name(dinfo->bdrv), fl_sectors); -#endif -fl = pflash_cfi01_register(0x1e00LL, - NULL, "mips_malta.bios", BIOS_SIZE, - dinfo->bdrv, 65536, fl_sectors, - 4, 0x, 0x, 0x, 0x, be); -bios = pflash_cfi01_get_memory(fl); -fl_idx++; -} else { -bios = g_new(MemoryRegion, 1); -memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE); -vmstate_register_ram_global(bios); -memory_region_set_readonly(bios, true); -memory_region_add_subregion(system_memory, 0x1e00LL, bios); +/* Load firmware from flash. */ +if (!dinfo) { /* Load a BIOS image. */ -if (bios_name == NULL) +if (bios_name == NULL) { bios_name = BIOS_FILENAME; +} filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = load_image_targphys(filename, 0x1e00LL, -- 1.7.2.5
[Qemu-devel] [PATCH 4/4] malta: Fix display for LED array
The 8-LED array was already implemented in the first commit to Malta, but this implementation was incomplete. Signed-off-by: Stefan Weil --- hw/mips_malta.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index ce25690..90cfc9b 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -338,9 +338,9 @@ static void malta_fpga_write(void *opaque, target_phys_addr_t addr, break; /* LEDBAR Register */ -/* XXX: implement a 8-LED array */ case 0x00408: s->leds = val & 0xff; +malta_fpga_update_display(s); break; /* ASCIIWORD Register */ -- 1.7.2.5
[Qemu-devel] [PATCH 1/4] malta: Clean allocation of bios region alias
It is sufficient to define the region alias once for all code branches. Signed-off-by: Stefan Weil --- hw/mips_malta.c | 21 ++--- 1 files changed, 6 insertions(+), 15 deletions(-) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 64603ce..7586971 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -856,10 +856,7 @@ void mips_malta_init (ram_addr_t ram_size, memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE); vmstate_register_ram_global(bios); memory_region_set_readonly(bios, true); -memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); -/* Map the bios at two physical locations, as on the real board. */ memory_region_add_subregion(system_memory, 0x1e00LL, bios); -memory_region_add_subregion(system_memory, 0x1fc0LL, bios_alias); loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; @@ -883,29 +880,19 @@ void mips_malta_init (ram_addr_t ram_size, dinfo->bdrv, 65536, fl_sectors, 4, 0x, 0x, 0x, 0x, be); bios = pflash_cfi01_get_memory(fl); -/* Map the bios at two physical locations, as on the real board. */ -memory_region_init_alias(bios_alias, "bios.1fc", - bios, 0, BIOS_SIZE); -memory_region_add_subregion(system_memory, 0x1fc0LL, -bios_alias); - fl_idx++; +fl_idx++; } else { bios = g_new(MemoryRegion, 1); memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE); vmstate_register_ram_global(bios); memory_region_set_readonly(bios, true); -memory_region_init_alias(bios_alias, "bios.1fc", - bios, 0, BIOS_SIZE); -/* Map the bios at two physical locations, as on the real board. */ memory_region_add_subregion(system_memory, 0x1e00LL, bios); -memory_region_add_subregion(system_memory, 0x1fc0LL, -bios_alias); /* Load a BIOS image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { -bios_size = load_image_targphys(filename, 0x1fc0LL, +bios_size = load_image_targphys(filename, 0x1e00LL, BIOS_SIZE); g_free(filename); } else { @@ -932,6 +919,10 @@ void mips_malta_init (ram_addr_t ram_size, #endif } +/* Map the BIOS at a 2nd physical location, as on the real board. */ +memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); +memory_region_add_subregion(system_memory, 0x1fc0LL, bios_alias); + /* Board ID = 0x420 (Malta Board with CoreLV) XXX: theoretically 0x1e10 should map to flash and 0x1fc00010 should map to the board ID. */ -- 1.7.2.5
[Qemu-devel] [PATCH 3/4] malta: Use symbolic hardware addresses
The patch adds definitions of some hardware addresses and uses these definitions. It also replaces the type of all addresses from signed to unsigned values. This is only a cosmetic change because addresses are unsigned values, the functions called also expect unsigned values, and we need no sign extension here. Signed-off-by: Stefan Weil --- hw/mips_malta.c | 19 +-- 1 files changed, 13 insertions(+), 6 deletions(-) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index e874efe..ce25690 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -55,6 +55,13 @@ #define ENVP_NB_ENTRIES16 #define ENVP_ENTRY_SIZE256 +/* Hardware addresses */ +#define FLASH_ADDRESS 0x1e00ULL +#define FPGA_ADDRESS 0x1f00ULL +#define RESET_ADDRESS 0x1fc0ULL + +#define FLASH_SIZE0x40 + #define MAX_IDE_BUS 2 typedef struct { @@ -777,7 +784,7 @@ void mips_malta_init (ram_addr_t ram_size, MemoryRegion *system_memory = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1); -target_long bios_size = 0x40; +target_long bios_size = FLASH_SIZE; int64_t kernel_entry; PCIBus *pci_bus; ISABus *isa_bus; @@ -847,7 +854,7 @@ void mips_malta_init (ram_addr_t ram_size, be = 0; #endif /* FPGA */ -malta_fpga_init(system_memory, 0x1f00LL, env->irq[2], serial_hds[2]); +malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]); /* Load firmware in flash / BIOS. */ dinfo = drive_get(IF_PFLASH, 0, fl_idx); @@ -855,11 +862,11 @@ void mips_malta_init (ram_addr_t ram_size, if (dinfo) { printf("Register parallel flash %d size " TARGET_FMT_lx " at " "addr %08llx '%s' %x\n", - fl_idx, bios_size, 0x1e00LL, + fl_idx, bios_size, FLASH_ADDRESS, bdrv_get_device_name(dinfo->bdrv), fl_sectors); } #endif -fl = pflash_cfi01_register(0x1e00LL, NULL, "mips_malta.bios", +fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios", BIOS_SIZE, dinfo ? dinfo->bdrv : NULL, 65536, fl_sectors, 4, 0x, 0x, 0x, 0x, be); @@ -882,7 +889,7 @@ void mips_malta_init (ram_addr_t ram_size, } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { -bios_size = load_image_targphys(filename, 0x1e00LL, +bios_size = load_image_targphys(filename, FLASH_ADDRESS, BIOS_SIZE); g_free(filename); } else { @@ -911,7 +918,7 @@ void mips_malta_init (ram_addr_t ram_size, /* Map the BIOS at a 2nd physical location, as on the real board. */ memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); -memory_region_add_subregion(system_memory, 0x1fc0LL, bios_alias); +memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_alias); /* Board ID = 0x420 (Malta Board with CoreLV) XXX: theoretically 0x1e10 should map to flash and 0x1fc00010 should -- 1.7.2.5
[Qemu-devel] [PATCH] qom: Fix object_class_foreach()
The TypeImpl was passed as ObjectClass and the ObjectClass as opaque, leading to segfault when dereferencing the caller-supplied opaque. Signed-off-by: Andreas Färber Cc: Anthony Liguori --- qom/object.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qom/object.c b/qom/object.c index a12895f..57cc592 100644 --- a/qom/object.c +++ b/qom/object.c @@ -478,7 +478,7 @@ static void object_class_foreach_tramp(gpointer key, gpointer value, type_class_init(type); -data->fn(value, type->class); +data->fn(type->class, data->opaque); } void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), -- 1.7.7
[Qemu-devel] [PATCH] qom: Introduce object_class_is_abstract()
Since struct TypeImpl is not public, this is useful for enumerating available types. Signed-off-by: Andreas Färber --- include/qemu/object.h |8 qom/object.c |5 + 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/include/qemu/object.h b/include/qemu/object.h index ba37850..8ec45f2 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -428,6 +428,14 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass, */ const char *object_class_get_name(ObjectClass *klass); +/** + * object_class_is_abstract: + * @klass: The class to obtain the abstractness for. + * + * Returns: Whether @klass is an abstract class or not. + */ +bool object_class_is_abstract(ObjectClass *klass); + ObjectClass *object_class_by_name(const char *typename); void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), diff --git a/qom/object.c b/qom/object.c index 57cc592..1821959 100644 --- a/qom/object.c +++ b/qom/object.c @@ -451,6 +451,11 @@ const char *object_class_get_name(ObjectClass *klass) return klass->type->name; } +bool object_class_is_abstract(ObjectClass *klass) +{ +return klass->type->abstract; +} + ObjectClass *object_class_by_name(const char *typename) { TypeImpl *type = type_get_by_name(typename); -- 1.7.7
Re: [Qemu-devel] suspend/resume not working on tip due to 59abb06
On Sat, Jan 28, 2012 at 12:23, Blue Swirl wrote: > On Fri, Jan 27, 2012 at 21:27, Stefan Berger > wrote: >> On 01/27/2012 04:10 PM, Stefan Berger wrote: >>> >>> After bisecting the following commit seems to be the culprit for the >>> suspend/resume problems that I am seeing with the current tip >>> (73093354418602a2ff5e43cb91a21b17fbf047d8). >>> >>> commit 59abb06198ee9471e29c970f294eae80c0b39be1 >>> Author: Blue Swirl >>> Date: Sun Jan 22 11:00:44 2012 + >>> >>> Once I revert this patch on the tip everything works fine again... >>> >>> Stefan >>> >>> >> And this patch here gets it to work: >> >> diff --git a/exec-obsolete.h b/exec-obsolete.h >> index 03cf35e..a673386 100644 >> --- a/exec-obsolete.h >> +++ b/exec-obsolete.h >> @@ -101,7 +101,7 @@ static inline void >> cpu_physical_memory_mask_dirty_range(ram_ >> end = start + length; >> mask = ~dirty_flags; >> p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); >> - for (addr = start; addr <= end; addr += TARGET_PAGE_SIZE) { >> + for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) { >> *p++ &= mask; >> } >> } > > Nice. Please add a description (something like "Fix suspend/resume > broken by off-by-one error in 7309...") and Signed-off-by: line. On second thought, the code is also broken for case start = (ram_addr_t)-TARGET_PAGE_SIZE, length = TARGET_PAGE_SIZE. I'll make another patch.
[Qemu-devel] [PATCH] exec-obsolete: fix length handling
Fix suspend/resume broken by off-by-one error in 59abb06198ee9471e29c970f294eae80c0b39be1. Adjust the loop so that it handles correctly the case start = (ram_addr_t)-TARGET_PAGE_SIZE, length = TARGET_PAGE_SIZE. Reported-by: Stefan Berger Signed-off-by: Blue Swirl --- exec-obsolete.h | 10 -- 1 files changed, 4 insertions(+), 6 deletions(-) diff --git a/exec-obsolete.h b/exec-obsolete.h index 03cf35e..1bba970 100644 --- a/exec-obsolete.h +++ b/exec-obsolete.h @@ -81,11 +81,10 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, int dirty_flags) { uint8_t *p; -ram_addr_t addr, end; +ram_addr_t cur; -end = start + length; p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); -for (addr = start; addr <= end; addr += TARGET_PAGE_SIZE) { +for (cur = 0; cur < length; cur += TARGET_PAGE_SIZE) { *p++ |= dirty_flags; } } @@ -96,12 +95,11 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, { int mask; uint8_t *p; -ram_addr_t addr, end; +ram_addr_t cur; -end = start + length; mask = ~dirty_flags; p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); -for (addr = start; addr <= end; addr += TARGET_PAGE_SIZE) { +for (cur = 0; cur < length; cur += TARGET_PAGE_SIZE) { *p++ &= mask; } } -- 1.7.9.rc0 From fb378616b9aeab9032fa3c2341724529002fcea9 Mon Sep 17 00:00:00 2001 Message-Id: From: Blue Swirl Date: Sat, 28 Jan 2012 18:02:08 + Subject: [PATCH] exec-obsolete: fix length handling Fix suspend/resume broken by off-by-one error in 59abb06198ee9471e29c970f294eae80c0b39be1. Adjust the loop so that it handles correctly the case start = (ram_addr_t)-TARGET_PAGE_SIZE, length = TARGET_PAGE_SIZE. Reported-by: Stefan Berger Signed-off-by: Blue Swirl --- exec-obsolete.h | 10 -- 1 files changed, 4 insertions(+), 6 deletions(-) diff --git a/exec-obsolete.h b/exec-obsolete.h index 03cf35e..1bba970 100644 --- a/exec-obsolete.h +++ b/exec-obsolete.h @@ -81,11 +81,10 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, int dirty_flags) { uint8_t *p; -ram_addr_t addr, end; +ram_addr_t cur; -end = start + length; p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); -for (addr = start; addr <= end; addr += TARGET_PAGE_SIZE) { +for (cur = 0; cur < length; cur += TARGET_PAGE_SIZE) { *p++ |= dirty_flags; } } @@ -96,12 +95,11 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, { int mask; uint8_t *p; -ram_addr_t addr, end; +ram_addr_t cur; -end = start + length; mask = ~dirty_flags; p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); -for (addr = start; addr <= end; addr += TARGET_PAGE_SIZE) { +for (cur = 0; cur < length; cur += TARGET_PAGE_SIZE) { *p++ &= mask; } } -- 1.7.2.5
Re: [Qemu-devel] [PATCH] qom: Introduce object_class_is_abstract()
Am 28.01.2012 18:51, schrieb Andreas Färber: > Since struct TypeImpl is not public, this is useful for enumerating > available types. > > Signed-off-by: Andreas Färber BTW Anthony, this cc-less patch shows that an entry is missing in MAINTAINERS. Could you please add an appropriate one? Thanks! Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [Bug 524447] Re: virsh save is very slow
@Serge @Chris - So it sounds like this _could_ make it into Lucid? Anyone I can bribe to make that happen? As an aside, I have been running LTS versions for 8 years and I must say it seems we need a different priority scale for LTS. This bug renders the use of kvm in 10.04 very painful and the plan would be to let that exist for 5 years? Feels like a lot of key improvements are overlooked because they don't make your machine explode, but from a sys admins perspective, it feels like the risks of running the latest versions so bug fixes trickle in outweighs the missing bits in an unmaintained LTS :/ This issue + this one (https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/555981) makes for a sad day. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/524447 Title: virsh save is very slow Status in libvirt virtualization API: Unknown Status in QEMU: Fix Released Status in “libvirt” package in Ubuntu: Invalid Status in “qemu-kvm” package in Ubuntu: Fix Released Status in “libvirt” source package in Lucid: Won't Fix Status in “qemu-kvm” source package in Lucid: Won't Fix Status in “libvirt” source package in Maverick: Won't Fix Status in “qemu-kvm” source package in Maverick: Won't Fix Status in “qemu-kvm” package in Debian: Fix Released Bug description: == SRU Justification: 1. impact: 'qemu save' is slow 2. how addressed: a patch upstream fixes the case when a file does not announce when it is ready. 3. patch: see the patch in linked bzr trees 4. TEST CASE: see comment #4 for a specific recipe 5. regression potential: this patch only touches the vm save path. == As reported here: http://www.redhat.com/archives/libvir- list/2009-December/msg00203.html "virsh save" is very slow - it writes the image at around 1MB/sec on my test system. (I think I saw a bug report for this issue on Fedora's bugzilla, but I can't find it now...) Confirmed under Karmic. To manage notifications about this bug go to: https://bugs.launchpad.net/libvirt/+bug/524447/+subscriptions
[Qemu-devel] Proper way to walk through all vpcus
What is the proper way to iterate over all vcpus in qemu ? below is what i use in my code. Not sure whether it is the best way, also is a a macro is qemu to do this ? CPUState *curr_cpu = first_cpu; for(; curr_cpu != NULL; curr_cpu = curr_cpu->next_cpu) { ... } Thanks Xin
[Qemu-devel] longjmp in qemu
I am investigating what longjmp is used for in qemu. longjmp is used in a couple of places. 1. void cpu_loop_exit(void) { env->current_tb = NULL; longjmp(env->jmp_env, 1); } cpu_loop_exit is called when there is an interrupt_request or exit_request pending 2. void cpu_resume_from_signal(CPUState *env1, void *puc) { ... longjmp(env->jmp_env, 1); } cpu_resume_from_signal is called in a couple of places, each of which suggests something faulty has happened. my guess is that it will get call when exceptions have occurred in the code cache. Am I right ? Thanks Xin
Re: [Qemu-devel] [PATCH v9 3/3] pc: Support system flash memory with pflash
On Mon, Jan 9, 2012 at 01:28, Kevin Wolf wrote: > Am 19.12.2011 23:19, schrieb Anthony Liguori: >> On 12/19/2011 03:25 PM, Jordan Justen wrote: >>> On Mon, Dec 19, 2011 at 11:41, Anthony Liguori wrote: On 12/15/2011 02:51 PM, Jordan Justen wrote: > +static void pc_system_rom_init(MemoryRegion *rom_memory, > + DriveInfo *pflash_drv) > +{ > + BlockDriverState *bdrv; > + int64_t size; > + target_phys_addr_t phys_addr; > + int sector_bits, sector_size; > + MemoryRegion *sys_rom; > + void *buffer; > + int ret; > + > + bdrv = pflash_drv->bdrv; > + size = bdrv_getlength(pflash_drv->bdrv); > + sector_bits = 9; > + sector_size = 1<< sector_bits; > + > + if ((size % sector_size) != 0) { > + fprintf(stderr, > + "qemu: PC system rom (pflash) must be a multiple of > 0x%x\n", > + sector_size); > + exit(1); > + } > + > + phys_addr = 0x1ULL - size; > + sys_rom = g_malloc(sizeof(*sys_rom)); > + memory_region_init_ram(sys_rom, NULL, "system.rom", size); > + buffer = memory_region_get_ram_ptr(sys_rom); > + memory_region_add_subregion(rom_memory, phys_addr, sys_rom); > + > + /* read the rom content */ > + ret = bdrv_read(bdrv, 0, buffer, size>> sector_bits); I think we're trying to get rid of synchronous block I/O in machine initialization for a number of reasons. Kevin/Stefan, care to comment? Will this be problematic in the future? >>> >>> I was hoping pc-1.1 with and without kvm could be as close as >>> possible, but I guess I can make pc-1.1 with kvm behave the same as >>> pc-1.0. Then I can delete pc_system_rom_init. >> >> I think your general approach is right, I'm just not sure what we're going >> to do >> short term about synchronous I/O in the machine init routines. It may just >> be a >> matter of structuring this in such a way that you can use an async interface. > > I don't think there is a problem with using the synchronous interface > here. But I'm not sure if having any I/O in the machine init is a good > idea with respect to migration. Didn't we already have to move some code > there to a later stage to make sure that the destination doesn't use > outdated data? The pc_system_rom_init function is only used when kvm is enabled. Since kvm cannot currently execute code from device memory, we have to create a ram region, and transfer the pflash contents into the ram region. Instead of bdrv_read, should I get the pflash memory region buffer, and use memcpy? Or, would still suffer from the same issue of getting outdated data? Thanks, -Jordan
Re: [Qemu-devel] [PATCH] arm: add device tree support
On Fri, Jan 27, 2012 at 10:34:01PM +, Paul Brook wrote: > > If compiled with CONFIG_FDT, allow user to specify a device tree file using > > the -dtb argument. If the machine supports it then the dtb will be loaded > > into memory and passed to the kernel on boot. > > Adding annother machine feels wrong. Why does the board specific code need to > know about this at all? You already going it via a global variable, so can't > this be entirely contained within arm_boot.c? Mostly because the infrastructure isn't yet in place to pass the .dtb file through to the arm_boot code (or maybe it is; what is the best way to pass command line data through to the arm_boot.c code (or similar for other architectures)? > If the board file is involved, why is it asking the user? There is a lot of configuration in the .dts file that the QEMU user may want to manipulate; particularly when using QEMU for testing embedded platforms. The direction I want to go is to select the machine model based on the top level DT compatible property (making -M optional), and then also allow a lot of the machine layout to be driven by DT data. ie. populate emulated devices from DT data. I believe this is how Edgar is using the microblaze model, but I don't think those patches have been upstreamed yet. I hope that microblaze, ARM and powerpc can all use the same model here. > > > +versatile_init(ram_size, > > + boot_device, > > + kernel_filename, kernel_cmdline, > > + initrd_filename, cpu_model, 0x); > > This only works because we're currently too dumb to emulate the differences > between the two board variants. Yeah, this is a hack so I could play with forcing the machine id. I'll remove it. > What we probably want to be doing is shipping/constructing device trees for > the boards we implement, with an option to turn this on/off. Requiring a > user > to invent their own seems deeply sub-optimal given we know exactly what > hardware we're emulating. A user that needs to provide their own FDT seems > like a fairly rare corner case. I disagree. QEMU may want to ship stock .dts files, but it will absolutely be a common use case for embedded developers to pass in their own .dtb file. > This gets slightly more interesting when you have custom machine variants > (i.e. once we fix the object model, and have proper dynamic machine > construction). Even then I'd expect the FDT to be derived from/specificed by > the machine description, not a separate option. I started with going down that route, but switched to this model after playing with it and noticing that it doesn't seem to fit as well for embedded development as providing a .dtb file and having QEMU construct a machine that matches the data. g.
[Qemu-devel] [PATCH] target-xtensa: fetch 3rd opcode byte only when needed
According to ISA, 3.5.4, third opcode byte should not be fetched for 2-byte instructions. Signed-off-by: Max Filippov --- target-xtensa/translate.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index c81450d..6a0177f 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -749,7 +749,7 @@ static void disas_xtensa_insn(DisasContext *dc) uint8_t b0 = ldub_code(dc->pc); uint8_t b1 = ldub_code(dc->pc + 1); -uint8_t b2 = ldub_code(dc->pc + 2); +uint8_t b2 = 0; static const uint32_t B4CONST[] = { 0x, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256 @@ -764,6 +764,7 @@ static void disas_xtensa_insn(DisasContext *dc) HAS_OPTION(XTENSA_OPTION_CODE_DENSITY); } else { dc->next_pc = dc->pc + 3; +b2 = ldub_code(dc->pc + 2); } switch (OP0) { -- 1.7.7.6
[Qemu-devel] [RFC 0/9] target-xtensa: implement debug option
This patch series implements Xtensa debug option: debug interrupt, breakpoint opcodes, instruction breakpoint SRs, instruction counting SR, data breakpoint SRs. This option enables native debugging, e.g. now guest linux GDB is functional. Three exec.c patches fixe watchpoints bits that nobody seems to use currently. There are still unresolved issue with data breakpoints on unmapped memory: Xtensa ISA says that data breakpoint exception has higher priority than TLB exception and thus accessing unmapped address that hits data breakpoint will raise debug exception. Watchpoint mapping is performed in the tlb_set_page, but it is not called in case of guest TLB miss. Any idea on how to resolve it is welcome. Max Filippov (9): target-xtensa: add DEBUGCAUSE SR and configuration target-xtensa: implement instruction breakpoints target-xtensa: add ICOUNT SR and debug exception exec: add missing breaks to the watch_mem_write exec: fix check_watchpoint exiting cpu_loop exec: let cpu_watchpoint_insert accept larger watchpoints target-xtensa: add DBREAK data breakpoints target-xtensa: add DEBUG_SECTION to overlay tool target-xtensa: add breakpoint tests exec.c| 18 +++- target-xtensa/core-dc232b.c |1 + target-xtensa/core-fsf.c |1 + target-xtensa/cpu.h | 42 target-xtensa/helper.c| 43 target-xtensa/helpers.h |7 ++ target-xtensa/op_helper.c | 100 ++ target-xtensa/overlay_tool.h |5 + target-xtensa/translate.c | 153 +++- tests/tcg/xtensa/Makefile |1 + tests/tcg/xtensa/test_break.S | 223 + 11 files changed, 585 insertions(+), 9 deletions(-) create mode 100644 tests/tcg/xtensa/test_break.S -- 1.7.7.6
[Qemu-devel] [RFC 4/9] exec: add missing breaks to the watch_mem_write
Signed-off-by: Max Filippov --- exec.c | 12 +--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/exec.c b/exec.c index 5b9eb9a..0e93e0e 100644 --- a/exec.c +++ b/exec.c @@ -3279,9 +3279,15 @@ static void watch_mem_write(void *opaque, target_phys_addr_t addr, { check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_WRITE); switch (size) { -case 1: stb_phys(addr, val); -case 2: stw_phys(addr, val); -case 4: stl_phys(addr, val); +case 1: +stb_phys(addr, val); +break; +case 2: +stw_phys(addr, val); +break; +case 4: +stl_phys(addr, val); +break; default: abort(); } } -- 1.7.7.6
[Qemu-devel] [RFC 9/9] target-xtensa: add breakpoint tests
Signed-off-by: Max Filippov --- tests/tcg/xtensa/Makefile |1 + tests/tcg/xtensa/test_break.S | 223 + 2 files changed, 224 insertions(+), 0 deletions(-) create mode 100644 tests/tcg/xtensa/test_break.S diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile index 8713af1..7e1e619 100644 --- a/tests/tcg/xtensa/Makefile +++ b/tests/tcg/xtensa/Makefile @@ -23,6 +23,7 @@ CRT= crt.o vectors.o TESTCASES += test_b.tst TESTCASES += test_bi.tst #TESTCASES += test_boolean.tst +TESTCASES += test_break.tst TESTCASES += test_bz.tst TESTCASES += test_clamps.tst TESTCASES += test_fail.tst diff --git a/tests/tcg/xtensa/test_break.S b/tests/tcg/xtensa/test_break.S new file mode 100644 index 000..8a8db80 --- /dev/null +++ b/tests/tcg/xtensa/test_break.S @@ -0,0 +1,223 @@ +.include "macros.inc" + +#define debug_level 6 +#define debug_vector level6 + +test_suite break + +test break +set_vector debug_vector, 0 +rsila2, debug_level +_break 0, 0 + +set_vector debug_vector, 2f +rsila2, debug_level - 1 +1: +_break 0, 0 +test_fail +2: +rsr a2, ps +movia3, 0x1f +and a2, a2, a3 +movia3, 0x10 | debug_level +assert eq, a2, a3 +rsr a2, epc6 +movia3, 1b +assert eq, a2, a3 +rsr a2, debugcause +movia3, 0x8 +assert eq, a2, a3 +test_end + +test breakn +set_vector debug_vector, 0 +rsila2, debug_level +_break.n 0 + +set_vector debug_vector, 2f +rsila2, debug_level - 1 +1: +_break.n 0 +test_fail +2: +rsr a2, ps +movia3, 0x1f +and a2, a2, a3 +movia3, 0x10 | debug_level +assert eq, a2, a3 +rsr a2, epc6 +movia3, 1b +assert eq, a2, a3 +rsr a2, debugcause +movia3, 0x10 +assert eq, a2, a3 +test_end + +test ibreak +set_vector debug_vector, 0 +rsila2, debug_level +movia2, 1f +wsr a2, ibreaka0 +movia2, 1 +wsr a2, ibreakenable +isync +1: +rsila2, debug_level - 1 +movia2, 1f +wsr a2, ibreaka0 +movia2, 0 +wsr a2, ibreakenable +isync +1: +set_vector debug_vector, 2f +movia2, 1f +wsr a2, ibreaka0 +movia2, 1 +wsr a2, ibreakenable +isync +1: +test_fail +2: +rsr a2, ps +movia3, 0x1f +and a2, a2, a3 +movia3, 0x10 | debug_level +assert eq, a2, a3 +rsr a2, epc6 +movia3, 1b +assert eq, a2, a3 +rsr a2, debugcause +movia3, 0x2 +assert eq, a2, a3 +test_end + +test ibreak_priority +set_vector debug_vector, 2f +rsila2, debug_level - 1 +movia2, 1f +wsr a2, ibreaka0 +movia2, 1 +wsr a2, ibreakenable +isync +1: +break 0, 0 +test_fail +2: +rsr a2, debugcause +movia3, 0x2 +assert eq, a2, a3 +test_end + +test icount +set_vector debug_vector, 2f +rsila2, debug_level - 1 +movia2, -2 +wsr a2, icount +movia2, 1 +wsr a2, icountlevel +isync +rsila2, 0 +nop +1: +break 0, 0 +test_fail +2: +movia2, 0 +wsr a2, icountlevel +rsr a2, epc6 +movia3, 1b +assert eq, a2, a3 +rsr a2, debugcause +movia3, 0x1 +assert eq, a2, a3 +test_end + +.macro check_dbreak dr +rsr a2, epc6 +movia3, 1b +assert eq, a2, a3 +rsr a2, debugcause +movia3, 0x4 | (\dr << 8) +assert eq, a2, a3 +movia2, 0 +wsr a2, dbreakc\dr +.endm + +.macro dbreak_test dr, ctl, break, access, op +set_vector debug_vector, 2f +rsila2, debug_level - 1 +movia2, \ctl +wsr a2, dbreakc\dr +movia2, \break +wsr a2, dbreaka\dr +movia2, \access +isync +1: +\op a3, a2, 0 +test_fail +2: +check_dbreak \dr +reset_ps +.endm + +test dbreak_exact +dbreak_test 0, 0x403f, 0xd07f, 0xd07f, l8ui +dbreak_test 1, 0x403e, 0xd07e, 0xd07e, l16ui +dbreak_test 0, 0x403c, 0xd07c, 0xd07c, l32i + +dbreak_test 1, 0x803f, 0xd07f, 0xd07f, s8i +dbreak_test 0, 0x803e, 0xd07e, 0xd07e, s16i +dbreak_test 1, 0x803c, 0xd07c, 0xd07c, s32i +test_end + +test dbreak_overlap +dbreak_test 0, 0x403f, 0xd07d, 0xd07c, l16ui +dbreak_test 1, 0x403f, 0xd07d, 0xd07c, l32i + +dbreak_test 0, 0x403e, 0xd07e, 0xd07f, l8ui +dbreak_test 1, 0x403e, 0xd07e, 0xd07c, l32i + +dbreak_test 0, 0x403c, 0xd07c, 0xd07d, l8ui +dbreak_test 1, 0x403c, 0xd07c, 0xd07c, l16ui + +dbreak_test 0, 0x4038, 0xd078, 0xd07b, l8ui +dbreak_test 1, 0x4038, 0xd078, 0xd07a, l16ui +dbreak_test 0, 0x4038, 0xd078, 0xd07c, l32i + +dbre
[Qemu-devel] [RFC 3/9] target-xtensa: add ICOUNT SR and debug exception
ICOUNT SR gets incremented on every instruction completion provided that CINTLEVEL at the beginning of the instruction execution is lower than ICOUNTLEVEL. When ICOUNT would increment to 0 a debug exception is raised if CINTLEVEL is lower than DEBUGLEVEL. See ISA, 4.7.7.5 for more details. Signed-off-by: Max Filippov --- target-xtensa/cpu.h |6 + target-xtensa/translate.c | 49 - 2 files changed, 54 insertions(+), 1 deletions(-) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 2875197..fbe5d15 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -142,6 +142,8 @@ enum { DEBUGCAUSE = 233, CCOUNT = 234, PRID = 235, +ICOUNT = 236, +ICOUNTLEVEL = 237, EXCVADDR = 238, CCOMPARE = 240, }; @@ -428,6 +430,7 @@ static inline int cpu_mmu_index(CPUState *env) #define XTENSA_TBFLAG_EXCM 0x4 #define XTENSA_TBFLAG_LITBASE 0x8 #define XTENSA_TBFLAG_DEBUG 0x10 +#define XTENSA_TBFLAG_ICOUNT 0x20 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, target_ulong *cs_base, int *flags) @@ -447,6 +450,9 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, if (xtensa_get_cintlevel(env) < env->config->debug_level) { *flags |= XTENSA_TBFLAG_DEBUG; } +if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) { +*flags |= XTENSA_TBFLAG_ICOUNT; +} } } diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 71fbf34..85f41a7 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -63,6 +63,8 @@ typedef struct DisasContext { unsigned used_window; bool debug; +bool icount; +TCGv_i32 next_icount; } DisasContext; static TCGv_ptr cpu_env; @@ -127,6 +129,8 @@ static const char * const sregnames[256] = { [DEBUGCAUSE] = "DEBUGCAUSE", [CCOUNT] = "CCOUNT", [PRID] = "PRID", +[ICOUNT] = "ICOUNT", +[ICOUNTLEVEL] = "ICOUNTLEVEL", [EXCVADDR] = "EXCVADDR", [CCOMPARE] = "CCOMPARE0", [CCOMPARE + 1] = "CCOMPARE1", @@ -313,10 +317,13 @@ static void gen_check_privilege(DisasContext *dc) static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) { tcg_gen_mov_i32(cpu_pc, dest); +gen_advance_ccount(dc); +if (dc->icount) { +tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); +} if (dc->singlestep_enabled) { gen_exception(dc, EXCP_DEBUG); } else { -gen_advance_ccount(dc); if (slot >= 0) { tcg_gen_goto_tb(slot); tcg_gen_exit_tb((tcg_target_long)dc->tb + slot); @@ -580,6 +587,22 @@ static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v) { } +static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v) +{ +if (dc->icount) { +tcg_gen_mov_i32(dc->next_icount, v); +} else { +tcg_gen_mov_i32(cpu_SR[sr], v); +} +} + +static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v) +{ +tcg_gen_andi_i32(cpu_SR[sr], v, 0xf); +/* This can change tb->flags, so exit tb */ +gen_jumpi_check_loop_end(dc, -1); +} + static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v) { uint32_t id = sr - CCOMPARE; @@ -617,6 +640,8 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) [PS] = gen_wsr_ps, [DEBUGCAUSE] = gen_wsr_debugcause, [PRID] = gen_wsr_prid, +[ICOUNT] = gen_wsr_icount, +[ICOUNTLEVEL] = gen_wsr_icountlevel, [CCOMPARE] = gen_wsr_ccompare, [CCOMPARE + 1] = gen_wsr_ccompare, [CCOMPARE + 2] = gen_wsr_ccompare, @@ -2492,10 +2517,14 @@ static void gen_intermediate_code_internal( dc.is_jmp = DISAS_NEXT; dc.ccount_delta = 0; dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG; +dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT; init_litbase(&dc); init_sar_tracker(&dc); reset_used_window(&dc); +if (dc.icount) { +dc.next_icount = tcg_temp_local_new_i32(); +} gen_icount_start(); @@ -2531,12 +2560,27 @@ static void gen_intermediate_code_internal( gen_io_start(); } +if (dc.icount) { +int label = gen_new_label(); + +tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1); +tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label); +tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]); +if (dc.debug) { +gen_debug_exception(&dc, DEBUGCAUSE_IC); +} +gen_set_label(label); +} + if (dc.debug) { gen_ibreak_check(env, &dc); } disas_xtensa_insn(&dc); ++insn_count; +if (dc.icount) { +tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount); +} if (env->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, dc.pc); gen_excep
[Qemu-devel] [RFC 1/9] target-xtensa: add DEBUGCAUSE SR and configuration
DEBUGCAUSE SR holds information about the most recent debug exception. See ISA, 4.7.7 for more details. Signed-off-by: Max Filippov --- target-xtensa/cpu.h | 15 +++ target-xtensa/translate.c |6 ++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 0db83a6..25245d8 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -137,6 +137,7 @@ enum { PS = 230, VECBASE = 231, EXCCAUSE = 232, +DEBUGCAUSE = 233, CCOUNT = 234, PRID = 235, EXCVADDR = 238, @@ -161,6 +162,15 @@ enum { #define PS_WOE 0x4 +#define DEBUGCAUSE_IC 0x1 +#define DEBUGCAUSE_IB 0x2 +#define DEBUGCAUSE_DB 0x4 +#define DEBUGCAUSE_BI 0x8 +#define DEBUGCAUSE_BN 0x10 +#define DEBUGCAUSE_DI 0x20 +#define DEBUGCAUSE_DBNUM 0xf00 +#define DEBUGCAUSE_DBNUM_SHIFT 8 + #define MAX_NAREG 64 #define MAX_NINTERRUPT 32 #define MAX_NLEVEL 6 @@ -279,6 +289,11 @@ typedef struct XtensaConfig { uint32_t timerint[MAX_NCCOMPARE]; unsigned nextint; unsigned extint[MAX_NINTERRUPT]; + +unsigned debug_level; +unsigned nibreak; +unsigned ndbreak; + uint32_t clock_freq_khz; xtensa_tlb itlb; diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index c81450d..0786dd1 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -119,6 +119,7 @@ static const char * const sregnames[256] = { [PS] = "PS", [VECBASE] = "VECBASE", [EXCCAUSE] = "EXCCAUSE", +[DEBUGCAUSE] = "DEBUGCAUSE", [CCOUNT] = "CCOUNT", [PRID] = "PRID", [EXCVADDR] = "EXCVADDR", @@ -535,6 +536,10 @@ static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) gen_jumpi_check_loop_end(dc, -1); } +static void gen_wsr_debugcause(DisasContext *dc, uint32_t sr, TCGv_i32 v) +{ +} + static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v) { } @@ -571,6 +576,7 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) [INTCLEAR] = gen_wsr_intclear, [INTENABLE] = gen_wsr_intenable, [PS] = gen_wsr_ps, +[DEBUGCAUSE] = gen_wsr_debugcause, [PRID] = gen_wsr_prid, [CCOMPARE] = gen_wsr_ccompare, [CCOMPARE + 1] = gen_wsr_ccompare, -- 1.7.7.6
[Qemu-devel] [RFC 6/9] exec: let cpu_watchpoint_insert accept larger watchpoints
Make cpu_watchpoint_insert accept watchpoints of any power-of-two size up to the target page size. Signed-off-by: Max Filippov --- exec.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/exec.c b/exec.c index bc6c185..39a5497 100644 --- a/exec.c +++ b/exec.c @@ -1443,7 +1443,8 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len, CPUWatchpoint *wp; /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */ -if ((len != 1 && len != 2 && len != 4 && len != 8) || (addr & ~len_mask)) { +if ((len & (len - 1)) || (addr & ~len_mask) || +len == 0 || len > TARGET_PAGE_SIZE) { fprintf(stderr, "qemu: tried to set invalid watchpoint at " TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len); return -EINVAL; -- 1.7.7.6
[Qemu-devel] [RFC 8/9] target-xtensa: add DEBUG_SECTION to overlay tool
Fill debug configuration from overlay definitions in the DEBUG_SECTION. Add DEBUG_SECTION to DC232B and FSF cores. Signed-off-by: Max Filippov --- target-xtensa/core-dc232b.c |1 + target-xtensa/core-fsf.c |1 + target-xtensa/overlay_tool.h |5 + 3 files changed, 7 insertions(+), 0 deletions(-) diff --git a/target-xtensa/core-dc232b.c b/target-xtensa/core-dc232b.c index 4d9bd55..b723c4c 100644 --- a/target-xtensa/core-dc232b.c +++ b/target-xtensa/core-dc232b.c @@ -22,6 +22,7 @@ static const XtensaConfig dc232b = { EXCEPTIONS_SECTION, INTERRUPTS_SECTION, TLB_SECTION, +DEBUG_SECTION, .clock_freq_khz = 1, }; diff --git a/target-xtensa/core-fsf.c b/target-xtensa/core-fsf.c index 7650462..88de4dd 100644 --- a/target-xtensa/core-fsf.c +++ b/target-xtensa/core-fsf.c @@ -16,6 +16,7 @@ static const XtensaConfig fsf = { EXCEPTIONS_SECTION, INTERRUPTS_SECTION, TLB_SECTION, +DEBUG_SECTION, .clock_freq_khz = 1, }; diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h index df19cc9..cbb4aa6 100644 --- a/target-xtensa/overlay_tool.h +++ b/target-xtensa/overlay_tool.h @@ -114,6 +114,7 @@ [EXC_KERNEL] = XCHAL_KERNEL_VECTOR_VADDR, \ [EXC_USER] = XCHAL_USER_VECTOR_VADDR, \ [EXC_DOUBLE] = XCHAL_DOUBLEEXC_VECTOR_VADDR, \ +[EXC_DEBUG] = XCHAL_DEBUG_VECTOR_VADDR, \ } #define INTERRUPT_VECTORS { \ @@ -288,6 +289,10 @@ #define REGISTER_CORE(core) #endif +#define DEBUG_SECTION \ +.debug_level = XCHAL_DEBUGLEVEL, \ +.nibreak = XCHAL_NUM_IBREAK, \ +.ndbreak = XCHAL_NUM_DBREAK #if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 2 #define XCHAL_INTLEVEL2_VECTOR_VADDR 0 -- 1.7.7.6
[Qemu-devel] [RFC 7/9] target-xtensa: add DBREAK data breakpoints
Add DBREAKA/DBREAKC SRs and implement DBREAK breakpoints as debug watchpoints. This implementation is not fully compliant to ISA: when a breakpoint is set to an unmapped/inaccessible memory address it generates TLB/memory protection exception instead of debug exception. See ISA, 4.7.7.3, 4.7.7.6 for more details. Signed-off-by: Max Filippov --- target-xtensa/cpu.h | 12 target-xtensa/helper.c| 41 + target-xtensa/helpers.h |2 + target-xtensa/op_helper.c | 62 + target-xtensa/translate.c | 30 + 5 files changed, 147 insertions(+), 0 deletions(-) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index fbe5d15..4dbd7b7 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -128,6 +128,8 @@ enum { DTLBCFG = 92, IBREAKENABLE = 96, IBREAKA = 128, +DBREAKA = 144, +DBREAKC = 160, EPC1 = 177, DEPC = 192, EPS2 = 194, @@ -175,12 +177,18 @@ enum { #define DEBUGCAUSE_DBNUM 0xf00 #define DEBUGCAUSE_DBNUM_SHIFT 8 +#define DBREAKC_SB 0x8000 +#define DBREAKC_LB 0x4000 +#define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB) +#define DBREAKC_MASK 0x3f + #define MAX_NAREG 64 #define MAX_NINTERRUPT 32 #define MAX_NLEVEL 6 #define MAX_NNMI 1 #define MAX_NCCOMPARE 3 #define MAX_TLB_WAY_SIZE 8 +#define MAX_NDBREAK 2 #define REGION_PAGE_MASK 0xe000 @@ -330,6 +338,9 @@ typedef struct CPUXtensaState { int exception_taken; +/* Watchpoints for DBREAK registers */ +CPUWatchpoint *cpu_watchpoint[MAX_NDBREAK]; + CPU_COMMON } CPUXtensaState; @@ -364,6 +375,7 @@ void xtensa_tlb_set_entry(CPUState *env, bool dtlb, int xtensa_get_physical_addr(CPUState *env, uint32_t vaddr, int is_write, int mmu_idx, uint32_t *paddr, uint32_t *page_size, unsigned *access); +void debug_exception_env(CPUState *new_env, uint32_t cause); #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt)) diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index b7e67b7..a0bf697 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -58,9 +58,44 @@ void xtensa_register_core(XtensaConfigList *node) xtensa_cores = node; } +static uint32_t check_hw_breakpoints(CPUState *env) +{ +unsigned i; + +for (i = 0; i < env->config->ndbreak; ++i) { +if (env->cpu_watchpoint[i] && +env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) { +return DEBUGCAUSE_DB | (i << DEBUGCAUSE_DBNUM_SHIFT); +} +} +return 0; +} + +static CPUDebugExcpHandler *prev_debug_excp_handler; + +static void breakpoint_handler(CPUState *env) +{ +if (env->watchpoint_hit) { +if (env->watchpoint_hit->flags & BP_CPU) { +uint32_t cause; + +env->watchpoint_hit = NULL; +cause = check_hw_breakpoints(env); +if (cause) { +debug_exception_env(env, cause); +} +cpu_resume_from_signal(env, NULL); +} +} +if (prev_debug_excp_handler) { +prev_debug_excp_handler(env); +} +} + CPUXtensaState *cpu_xtensa_init(const char *cpu_model) { static int tcg_inited; +static int debug_handler_inited; CPUXtensaState *env; const XtensaConfig *config = NULL; XtensaConfigList *core = xtensa_cores; @@ -84,6 +119,12 @@ CPUXtensaState *cpu_xtensa_init(const char *cpu_model) xtensa_translate_init(); } +if (!debug_handler_inited && tcg_enabled()) { +debug_handler_inited = 1; +prev_debug_excp_handler = +cpu_set_debug_excp_handler(breakpoint_handler); +} + xtensa_irq_init(env); qemu_init_vcpu(env); return env; diff --git a/target-xtensa/helpers.h b/target-xtensa/helpers.h index afe39d4..48a741e 100644 --- a/target-xtensa/helpers.h +++ b/target-xtensa/helpers.h @@ -33,5 +33,7 @@ DEF_HELPER_3(wtlb, void, i32, i32, i32) DEF_HELPER_1(wsr_ibreakenable, void, i32) DEF_HELPER_2(wsr_ibreaka, void, i32, i32) +DEF_HELPER_2(wsr_dbreaka, void, i32, i32) +DEF_HELPER_2(wsr_dbreakc, void, i32, i32) #include "def-helper.h" diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 1feaaee..e184cf6 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -134,6 +134,14 @@ void HELPER(exception_cause_vaddr)(uint32_t pc, uint32_t cause, uint32_t vaddr) HELPER(exception_cause)(pc, cause); } +void debug_exception_env(CPUState *new_env, uint32_t cause) +{ +if (xtensa_get_cintlevel(new_env) < new_env->config->debug_level) { +env = new_env; +HELPER(debug_exception)(env->pc, cause); +} +} + void HELPER(debug_exception)(uint32_t pc, uint32_t cause) { unsigned level = env->config->debug_level; @@ -700,3 +708,57 @@ void HELPER(wsr_ibreaka)(uint32_t i, uint32_t v) } env->sregs[IBREAKA + i] = v; } + +static void set_dbreak(unsigned i, uint32_t dbreaka, u
[Qemu-devel] [RFC 2/9] target-xtensa: implement instruction breakpoints
Add IBREAKA/IBREAKENABLE SRs and implement debug exception, BREAK and BREAK.N instructions and IBREAK breakpoints. IBREAK breakpoint address is considered constant for TB lifetime. On IBREAKA/IBREAKENABLE change corresponding TBs are invalidated. Signed-off-by: Max Filippov --- target-xtensa/cpu.h |9 ++ target-xtensa/helper.c|2 + target-xtensa/helpers.h |5 +++ target-xtensa/op_helper.c | 38 + target-xtensa/translate.c | 68 +++-- 5 files changed, 119 insertions(+), 3 deletions(-) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 25245d8..2875197 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -126,6 +126,8 @@ enum { RASID = 90, ITLBCFG = 91, DTLBCFG = 92, +IBREAKENABLE = 96, +IBREAKA = 128, EPC1 = 177, DEPC = 192, EPS2 = 194, @@ -196,6 +198,7 @@ enum { EXC_KERNEL, EXC_USER, EXC_DOUBLE, +EXC_DEBUG, EXC_MAX }; @@ -424,6 +427,7 @@ static inline int cpu_mmu_index(CPUState *env) #define XTENSA_TBFLAG_RING_MASK 0x3 #define XTENSA_TBFLAG_EXCM 0x4 #define XTENSA_TBFLAG_LITBASE 0x8 +#define XTENSA_TBFLAG_DEBUG 0x10 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, target_ulong *cs_base, int *flags) @@ -439,6 +443,11 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, (env->sregs[LITBASE] & 1)) { *flags |= XTENSA_TBFLAG_LITBASE; } +if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) { +if (xtensa_get_cintlevel(env) < env->config->debug_level) { +*flags |= XTENSA_TBFLAG_DEBUG; +} +} } #include "cpu-all.h" diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 2a0cb1a..b7e67b7 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -44,6 +44,7 @@ void cpu_reset(CPUXtensaState *env) env->sregs[PS] = xtensa_option_enabled(env->config, XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10; env->sregs[VECBASE] = env->config->vecbase; +env->sregs[IBREAKENABLE] = 0; env->pending_irq_level = 0; reset_mmu(env); @@ -193,6 +194,7 @@ void do_interrupt(CPUState *env) case EXC_KERNEL: case EXC_USER: case EXC_DOUBLE: +case EXC_DEBUG: qemu_log_mask(CPU_LOG_INT, "%s(%d) " "pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n", __func__, env->exception_index, diff --git a/target-xtensa/helpers.h b/target-xtensa/helpers.h index 09ab332..afe39d4 100644 --- a/target-xtensa/helpers.h +++ b/target-xtensa/helpers.h @@ -3,6 +3,8 @@ DEF_HELPER_1(exception, void, i32) DEF_HELPER_2(exception_cause, void, i32, i32) DEF_HELPER_3(exception_cause_vaddr, void, i32, i32, i32) +DEF_HELPER_2(debug_exception, void, i32, i32) + DEF_HELPER_1(nsa, i32, i32) DEF_HELPER_1(nsau, i32, i32) DEF_HELPER_1(wsr_windowbase, void, i32) @@ -29,4 +31,7 @@ DEF_HELPER_2(itlb, void, i32, i32) DEF_HELPER_2(ptlb, i32, i32, i32) DEF_HELPER_3(wtlb, void, i32, i32, i32) +DEF_HELPER_1(wsr_ibreakenable, void, i32) +DEF_HELPER_2(wsr_ibreaka, void, i32, i32) + #include "def-helper.h" diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 0605611..1feaaee 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -134,6 +134,19 @@ void HELPER(exception_cause_vaddr)(uint32_t pc, uint32_t cause, uint32_t vaddr) HELPER(exception_cause)(pc, cause); } +void HELPER(debug_exception)(uint32_t pc, uint32_t cause) +{ +unsigned level = env->config->debug_level; + +env->pc = pc; +env->sregs[DEBUGCAUSE] = cause; +env->sregs[EPC1 + level - 1] = pc; +env->sregs[EPS2 + level - 2] = env->sregs[PS]; +env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | PS_EXCM | +(level << PS_INTLEVEL_SHIFT); +HELPER(exception)(EXC_DEBUG); +} + uint32_t HELPER(nsa)(uint32_t v) { if (v & 0x8000) { @@ -662,3 +675,28 @@ void HELPER(wtlb)(uint32_t p, uint32_t v, uint32_t dtlb) split_tlb_entry_spec(v, dtlb, &vpn, &wi, &ei); xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, p); } + + +void HELPER(wsr_ibreakenable)(uint32_t v) +{ +uint32_t change = v ^ env->sregs[IBREAKENABLE]; +unsigned i; + +for (i = 0; i < env->config->nibreak; ++i) { +if (change & (1 << i)) { +tb_invalidate_phys_page_range( +env->sregs[IBREAKA + i], env->sregs[IBREAKA + i] + 1, 0); +} +} +env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1); +} + +void HELPER(wsr_ibreaka)(uint32_t i, uint32_t v) +{ +if (env->sregs[IBREAKENABLE] & (1 << i) && env->sregs[IBREAKA + i] != v) { +tb_invalidate_phys_page_range( +env->sregs[IBREAKA + i], env->sregs[IBREAKA + i] + 1, 0); +tb_invalidate_phys_page_range(v, v + 1, 0); +} +env->sregs[IBREAKA + i] = v; +} diff --git a/target-xtensa/translate.c b/target-xtensa/t
[Qemu-devel] [RFC 5/9] exec: fix check_watchpoint exiting cpu_loop
In case of BP_STOP_BEFORE_ACCESS watchpoint check_watchpoint intends to signal EXCP_DEBUG exception on exit from cpu loop, but later overwrites exception code by the cpu_resume_from_signal call. Use cpu_loop_exit with BP_STOP_BEFORE_ACCESS watchpoints. Signed-off-by: Max Filippov --- exec.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/exec.c b/exec.c index 0e93e0e..bc6c185 100644 --- a/exec.c +++ b/exec.c @@ -3247,11 +3247,12 @@ static void check_watchpoint(int offset, int len_mask, int flags) tb_phys_invalidate(tb, -1); if (wp->flags & BP_STOP_BEFORE_ACCESS) { env->exception_index = EXCP_DEBUG; +cpu_loop_exit(env); } else { cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags); tb_gen_code(env, pc, cs_base, cpu_flags, 1); +cpu_resume_from_signal(env, NULL); } -cpu_resume_from_signal(env, NULL); } } else { wp->flags &= ~BP_WATCHPOINT_HIT; -- 1.7.7.6
[Qemu-devel] [Bug 899140] Re: Problem with Linux Kernel Traffic Control
Hi guys, I'm having the same problem with a ubuntu 11.04 (natty) host. I tried to set the rate controllers using tc both at the host and inside the guest i.e.: tc qdisc add vnic0 root tbf rate 20mbit burst 20480 latency 50ms (host - to control the traffic going to the guest vm) and tc qdisc add eth0 root tbf rate 20mbit burst 20480 latency 50ms (guest) And the results are the same reported initially: ~140kbit/sec. I also tried to use policing filters at the host but I got the same results. However, if I use htb I can get reasonable throughputs (~20mbit). I used these commands (both for host and guest): tc qdisc add dev root handle 1: htb default 255 tc class add dev parent 1: classid 1:1 htb rate 20mbit burst 20480 tc filter add dev parent 1: prio 255 proto ip u32 match ip src 0.0.0.0/0 flowid 1:1 It seems that the problem is related with the root qdisc only. Have you guys found an answer for this? -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/899140 Title: Problem with Linux Kernel Traffic Control Status in QEMU: New Bug description: Hi, The last main versions of QEMU (0.14.1, 0.15 and 1.0) have an important problem when running on a Linux distribution which running itself a Traffic Control (TC) instance. Indeed, when TC is configured with a Token Bucket Filter (TBF) with a particular rate, the effective rate is very slower than the desired one. For instance, lets consider the following configuration : # tc qdisc add dev eth0 root tbf rate 20mbit burst 20k latency 50ms The effective rate will be about 100kbit/s ! (verified with iperf) I've encountered this problem on versions 0.14.1, 0.15 and 1.0 but not with the 0.14.0... In the 0.14.0, we have a rate of 19.2 mbit/s which is quiet normal. I've done the experimentation on several hosts : - Debian 32bit core i7, 4GB RAM - Debian 64bit core i7, 8GB RAM - 3 different high performance servers : Ubuntu 64 bits, 48 AMD Opteron, 128GB of RAM The problem is always the same... The problem is also seen with a Class Based Queuing (CBQ) in TC. Thanks To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/899140/+subscriptions
Re: [Qemu-devel] [RFC PATCH 5/7] vl.c: added -kerndtb option
Hi All, So on the topic of these command line arguments for initrd, dtb and friends, another related issue we have encountered (and have hacked around in our tree) is not being able to relocate the initrd or kernel. Currently these memory locations are hardcoded in arm_boot.c: #define KERNEL_ARGS_ADDR 0x100 #define KERNEL_LOAD_ADDR 0x0001 #define INITRD_LOAD_ADDR 0x00d0 If you see patch 6/7 in this same series I put in place a hack to override the initrd location in memory, but I wonder if instead this should go up to the command line interface as a parameter. Currently the machine model (or arm_boot.c) defines exactly where kernels/initrds/command-line-args line in memory, but since these are software properties should perhaps they go up to the command line as -kernel,foo=bar options? E.G: qemu-system-arm -kernel,kernel-image=/foo/zImage,kernel-addr=0x0001,initrd=/foo/initrd,initrd_addr=0x00d0 It strikes me as broken that a machine model specifies where in memory a kernel has to live. Something similar would apply to the dtb argument, this patch introduces. For the next revision of this patch series I am going to put in the mollyguard and just use -kernel-dtb foo for the moment. So with the greater issue of linux specific command line arguments, what is the consensus here on how this is going to be handled with regards to: -Passing all this command line stuff in a struct -nesting initrd and friends under the -kernel option. And do either of these act as a blocker on this patch series? Regards, Peter On Fri, Jan 27, 2012 at 6:25 PM, Markus Armbruster wrote: > Eric Blake writes: > > > On 01/26/2012 12:34 PM, Scott Wood wrote: > >> On 01/24/2012 12:23 PM, Stefan Weil wrote: > >>> I'd prefer a different solution. As far as I have understood, > >>> the dtb is only useful with a kernel, so it could be handled > >>> as an optional attribute to the -kernel parameter: > >>> > >>> -kernel IMAGE[,dtb=DTB] > >>> > >>> Of course the same applies to -append, but that's a different issue. > >> > >> -initrd as well. > >> > >> This would mean you couldn't have a comma in a filename (shouldn't come > >> up often, but still ugly). > > > > In other instances where you use a comma to separate arguments and also > > want to accept commas in arbitrary file names, qemu has used the notion > > of a double comma as being the escape sequence for a single comma in the > > intended file name, rather than a separator for later arguments. > > Use QemuOpts for NAME=VALUE,... arguments. Common code, common > syntactic conventions. >
Re: [Qemu-devel] [PATCH v3 1/2] ./configure: request pkg-config to provide private libs when static linking
On Mon, 23 Jan 2012 21:33:49 +0300 Sergei Trofimovich wrote: > From: Sergei Trofimovich > > Added wrapper around pkg-config to allow: > - safe options injection via ${QEMU_PKG_CONFIG_FLAGS} > - spaces in path to pkg-config > > Signed-off-by: Sergei Trofimovich > --- > configure | 11 --- > 1 files changed, 8 insertions(+), 3 deletions(-) ping -- Sergei signature.asc Description: PGP signature
Re: [Qemu-devel] [PATCH] arm: add device tree support
Hi Grant, The patch series for dts driven machine creation we (myself and Edgar) use that you are referring to was rejected a few months ago on the grounds that it conflicted with QOM: http://lists.gnu.org/archive/html/qemu-devel/2011-08/msg02953.html I am maintaining it our of tree, although I have not fast forwarded that branch for a while, so I cant recreate that series quickly. But now that QOM is immenent, can we get another review on the original series, and comments on what needs to happen to make this play nice with QOM? There is nothing in this series that is target specific, Adaption for arm should be fairly trivial. Peter On Fri, Jan 27, 2012 at 10:34:01PM +, Paul Brook wrote: > > > If compiled with CONFIG_FDT, allow user to specify a device tree file > using > > > the -dtb argument. If the machine supports it then the dtb will be > loaded > > > into memory and passed to the kernel on boot. > > > > Adding annother machine feels wrong. Why does the board specific code > need to > > know about this at all? You already going it via a global variable, so > can't > > this be entirely contained within arm_boot.c? > > Mostly because the infrastructure isn't yet in place to pass the .dtb file > through to the arm_boot code (or maybe it is; what is the best way to pass > command line data through to the arm_boot.c code (or similar for other > architectures)? > > > If the board file is involved, why is it asking the user? > > There is a lot of configuration in the .dts file that the QEMU user may > want > to manipulate; particularly when using QEMU for testing embedded platforms. > The direction I want to go is to select the machine model based on the top > level DT compatible property (making -M optional), and then also allow a > lot > of the machine layout to be driven by DT data. ie. populate emulated > devices > from DT data. > > I believe this is how Edgar is using the microblaze model, but I don't > think those patches have been upstreamed yet. I hope that microblaze, > ARM and powerpc can all use the same model here. > > > > > > +versatile_init(ram_size, > > > + boot_device, > > > + kernel_filename, kernel_cmdline, > > > + initrd_filename, cpu_model, 0x); > > > > This only works because we're currently too dumb to emulate the > differences > > between the two board variants. > > Yeah, this is a hack so I could play with forcing the machine id. > I'll remove it. > > > What we probably want to be doing is shipping/constructing device trees > for > > the boards we implement, with an option to turn this on/off. Requiring > a user > > to invent their own seems deeply sub-optimal given we know exactly what > > hardware we're emulating. A user that needs to provide their own FDT > seems > > like a fairly rare corner case. > > I disagree. QEMU may want to ship stock .dts files, but it will > absolutely be a common use case for embedded developers to pass in > their own .dtb file. > > > This gets slightly more interesting when you have custom machine variants > > (i.e. once we fix the object model, and have proper dynamic machine > > construction). Even then I'd expect the FDT to be derived > from/specificed by > > the machine description, not a separate option. > > I started with going down that route, but switched to this model after > playing with it and noticing that it doesn't seem to fit as well for > embedded development as providing a .dtb file and having QEMU > construct a machine that matches the data. > > g. > >
Re: [Qemu-devel] [PATCH 2/2] ./configure: add link check for nss-smartcard
On Mon, 23 Jan 2012 10:41:38 +0300 Sergei Trofimovich wrote: > From: Sergei Trofimovich > > Current './configure --static && make' fails for me: > > LINK qemu-nbd > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lssl3 > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lsmime3 > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lnssutil3 > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lnss3 > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lplds4 > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lplc4 > > /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/bin/ld: > cannot find -lnspr4 > > My system does not provide static libraries for nss, so > fix autoconfiguration by link checking. > > Signed-off-by: Sergei Trofimovich > --- > configure | 13 + > 1 files changed, 9 insertions(+), 4 deletions(-) ping -- Sergei signature.asc Description: PGP signature
[Qemu-devel] [PATCH] hw/arm: Remove redundant arguments from set_kernel_args*
The parameters initrd_size and base are already included in the info parameter, so there is no need to pass them separately. Signed-off-by: Stefan Weil --- hw/arm_boot.c | 17 - 1 files changed, 8 insertions(+), 9 deletions(-) diff --git a/hw/arm_boot.c b/hw/arm_boot.c index 5f163fd..34a8739 100644 --- a/hw/arm_boot.c +++ b/hw/arm_boot.c @@ -81,9 +81,10 @@ static void default_reset_secondary(CPUState *env, p += 4; \ } while (0) -static void set_kernel_args(const struct arm_boot_info *info, -int initrd_size, target_phys_addr_t base) +static void set_kernel_args(const struct arm_boot_info *info) { +int initrd_size = info->initrd_size; +target_phys_addr_t base = info->loader_start; target_phys_addr_t p; p = base + KERNEL_ARGS_ADDR; @@ -134,12 +135,12 @@ static void set_kernel_args(const struct arm_boot_info *info, WRITE_WORD(p, 0); } -static void set_kernel_args_old(const struct arm_boot_info *info, -int initrd_size, target_phys_addr_t base) +static void set_kernel_args_old(const struct arm_boot_info *info) { target_phys_addr_t p; const char *s; - +int initrd_size = info->initrd_size; +target_phys_addr_t base = info->loader_start; /* see linux/include/asm-arm/setup.h */ p = base + KERNEL_ARGS_ADDR; @@ -222,11 +223,9 @@ static void do_cpu_reset(void *opaque) if (env == first_cpu) { env->regs[15] = info->loader_start; if (old_param) { -set_kernel_args_old(info, info->initrd_size, -info->loader_start); +set_kernel_args_old(info); } else { -set_kernel_args(info, info->initrd_size, -info->loader_start); +set_kernel_args(info); } } else { info->secondary_cpu_reset_hook(env, info); -- 1.7.7.3