Exit on reset for armv7-m
PATCH 1/1 Exit on reset for armv7-m
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3).
A small patch to see if I have the submission process figured out.
Michael Davidsaver (1):
armv7-m: exit on external reset request
hw/intc/armv7m_nvic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Signature · 1 line
2.1.4
PATCH 1/1 armv7-m: exit on external reset request
--- hw/intc/armv7m_nvic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
hw/intc/armv7m_nvic.c +5 -1
@@ -15,6 +15,7 @@#include "hw/arm/arm.h" #include "exec/address-spaces.h" #include "gic_internal.h" +#include "sysemu/sysemu.h" typedef struct { GICState gic;
@@ -348,10 +349,13 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)break ;case 0xd0c :/* Application Interrupt/Reset Control. */ if ((value >>16 ) ==0x05fa ) { +if (value &4 ) { +qemu_system_reset_request (); + }if (value &2 ) {qemu_log_mask (LOG_UNIMP ,"VECTCLRACTIVE unimplemented\n" ); } -if (value &5 ) { +if (value &1 ) {qemu_log_mask (LOG_UNIMP ,"AIRCR system reset unimplemented\n" ); }if (value &0x700 ) {
Signature · 1 line
2.1.4
Quoted 3 lines · Michael Davidsaver
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3).
This would serve better as the commit message to the patch (which I notice is missing a commit blurb).
Quoted 2 lines
A small patch to see if I have the submission process figured out.
It is usual for the cover and patches to be enumerated together with the cover being patch 0, e.g. the subject would read [PATCH 0/1]. the --cover-letter switch of git format-patch does this for you.
Quoted 1 line
Michael Davidsaver (1):
When sending a single, a cover is not required. You could just send the patch on it's own. This will all be useful when you come to send multi-patch series however.
Regards,
Peter
Quoted 9 lines
armv7-m: exit on external reset request
hw/intc/armv7m_nvic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)--
2.1.4
Quoted 8 lines · Peter Crosthwaite
Quoted 3 lines · Michael Davidsaver
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3).
This would serve better as the commit message to the patch (which I notice is missing a commit blurb).
Does this warrant sending an updated patch? I would have no objection to whomever applies the patch simply changing the commit message.
Quoted 6 lines
Quoted 2 lines
A small patch to see if I have the submission process figured out.
It is usual for the cover and patches to be enumerated together with the cover being patch 0, e.g. the subject would read [PATCH 0/1]. the --cover-letter switch of git format-patch does this for you.
Alas in this case it did not. Probably because I omitted '--numbered'.
Quoted 5 lines
Quoted 1 line
Michael Davidsaver (1):
When sending a single, a cover is not required. You could just send the patch on it's own. This will all be useful when you come to send multi-patch series however.
Noted.
Thanks for the feedback Peter.
Michael
Quoted 12 lines · Michael Davidsaver
Quoted 8 lines · Peter Crosthwaite
Quoted 3 lines · Michael Davidsaver
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3).
This would serve better as the commit message to the patch (which I notice is missing a commit blurb).
Does this warrant sending an updated patch? I would have no objection to whomever applies the patch simply changing the commit message.
I would resend as a single. But I am yet to get around to a proper review of the patch proper, as I need to dig out relavent docs. So if you want a day or two I might have more comments.
Regards,
Peter
Quoted 21 lines
Quoted 6 lines
Quoted 2 lines
A small patch to see if I have the submission process figured out.
It is usual for the cover and patches to be enumerated together with the cover being patch 0, e.g. the subject would read [PATCH 0/1]. the --cover-letter switch of git format-patch does this for you.
Alas in this case it did not. Probably because I omitted '--numbered'.
Quoted 5 lines
Quoted 1 line
Michael Davidsaver (1):
When sending a single, a cover is not required. You could just send the patch on it's own. This will all be useful when you come to send multi-patch series however.
Noted.
Thanks for the feedback Peter.
Michael
Re: [Qemu-devel] [PATCH] armv7-m: exit on external reset request
In reply to Michael DavidsaverQuoted 22 lines · Michael Davidsaver
Signed-off-by Michael Davidsaver <[email protected]>--- hw/intc/armv7m_nvic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)hw/intc/armv7m_nvic.c +2
-0@@ -15,6 +15,7 @@#include "hw/arm/arm.h" #include "exec/address-spaces.h" #include "gic_internal.h" +#include "sysemu/sysemu.h" typedef struct { GICState gic;@@ -348,10 +349,13 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)break ;case 0xd0c :/* Application Interrupt/Reset Control. */ if ((value >>16 ) ==0x05fa ) { +if (value &4 ) {
hw/intc/armv7m_nvic.c static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value) · line 361
Quoted 10 lines
hw/intc/armv7m_nvic.c +3
-1+qemu_system_reset_request (); + }if (value &2 ) {qemu_log_mask (LOG_UNIMP ,"VECTCLRACTIVE unimplemented\n" ); } -if (value &5 ) { +if (value &1 ) {qemu_log_mask (LOG_UNIMP ,"AIRCR system reset unimplemented\n" ); }if (value &0x700 ) {
Strictly speaking what this bit does is assert a signal out of the CPU to some external power management or similar device in the SoC, which then is responsible for doing the reset. So just calling qemu_system_reset_request() here is a bit of a shortcut. But maybe it's a pragmatic shortcut?
thanks
-- PMM
Re: [Qemu-devel] [PATCH] armv7-m: exit on external reset request
Quoted 7 lines · Peter Maydell
Quoted 6 lines · Michael Davidsaver
...
case 0xd0c: /* Application Interrupt/Reset Control. */ if ((value >> 16) == 0x05fa) {hw/intc/armv7m_nvic.c +3
-0+if (value &4 ) { +qemu_system_reset_request (); + }
...
Quoted 6 lines
Strictly speaking what this bit does is assert a signal out of the CPU to some external power management or similar device in the SoC, which then is responsible for doing the reset. So just calling
qemu_system_reset_request()here is a bit of a shortcut. But maybe it's a pragmatic shortcut?
I'm not sure what you mean by shortcut? Most targets have some way to trigger qemu to exit. I actually compiled a list recently (see below). I couldn't find one for the lm3s6965evb machine, thus this patch.
FYI, one of my interests in QEMU is to automate testing of low level code. Being able to cause the qemu process to exit when the tests complete is quite helpful (simplifies the test runner)
qemu_system_reset_request()
highbank.c -> register write
integratorcp.c -> register write
musicpal.c -> register write (musicpal board)
omap1.c -> register write
omap2.c -> register write
pc.c -> register write (port 92)
pckbd.c -> register write (two different registers)
lpc_ich9.c -> register write
arm_sysctl.c -> register write (vexpress only or board_ids 0x100, 0x178, 0x182 only, ) cuda.c -> register write
slavio_misc.c -> register write
zynq_slcr.c -> register write (xilinx-zynq-a9 board)
apb.c -> register write
bonito.c -> register write
piix.c -> register write
mpc8544_guts.c -> register write
ppc.c -> e500 only ppce500_irq_init() w/ PPCE500_INPUT_MCK
ppc405_uc.c -> store_40x_dbcr0()
spapr_hcall.c -> KVM only
spapr_rtas.c -> register RTAS_SYSTEM_REBOOT
etraxfs_timer.c -> watchdog timer expire
m48t59.c -> watchdog timer expire
milkymist-sysctl.c -> register write
pxa2xx_timer.c -> watchdog timer expire (bsp option)
watchdog.c -> generic watchdog timer expire
xtfpga.c -> register write
cpu_exit()
pc.c -> DMA_init
prep.c -> DMA_init (broken)
spapr_rtas.c -> register RTAS_STOP_SELF
Re: [Qemu-devel] [PATCH] armv7-m: exit on external reset request
Quoted 12 lines · Michael Davidsaver
Quoted 7 lines · Peter Maydell
Quoted 6 lines · Michael Davidsaver
...
case 0xd0c: /* Application Interrupt/Reset Control. */ if ((value >> 16) == 0x05fa) {hw/intc/armv7m_nvic.c +3
-0+if (value &4 ) { +qemu_system_reset_request (); + }...
Quoted 1 line
Quoted 8 lines
Quoted 5 lines
Strictly speaking what this bit does is assert a signal out of the CPU to some external power management or similar device in the SoC, which then is responsible for doing the reset. So just calling
qemu_system_reset_request()here is a bit of a shortcut. But maybe it's a pragmatic shortcut?I'm not sure what you mean by shortcut? Most targets have some way to trigger qemu to exit. I actually compiled a list recently (see below). I couldn't find one for the lm3s6965evb machine, thus this patch.
We should check the lm3s docs to see what the implementation of this signal is. I think it would be better for SoC (or board) level to install the GPIO handler to do the reset. As far as target-arm is concerned this is then just a GPIO.
Quoted 2 lines
FYI, one of my interests in QEMU is to automate testing of low level code. Being able to cause the qemu process to exit when the tests complete is quite helpful (simplifies the test runner)
Nice!
Regards,
Peter
Quoted 34 lines
qemu_system_reset_request()
highbank.c-> register write
integratorcp.c-> register write
musicpal.c-> register write (musicpal board)
omap1.c-> register write
omap2.c-> register write
pc.c-> register write (port 92)
pckbd.c-> register write (two different registers)
lpc_ich9.c-> register write
arm_sysctl.c-> register write (vexpress only orboard_ids0x100,0x178,0x182only, )cuda.c-> register write
slavio_misc.c-> register write
zynq_slcr.c-> register write (xilinx-zynq-a9 board)
apb.c-> register write
bonito.c-> register write
piix.c-> register write
mpc8544_guts.c-> register write
ppc.c-> e500 onlyppce500_irq_init()w/PPCE500_INPUT_MCK
ppc405_uc.c->store_40x_dbcr0()
spapr_hcall.c-> KVM only
spapr_rtas.c-> registerRTAS_SYSTEM_REBOOT
etraxfs_timer.c-> watchdog timer expire
m48t59.c-> watchdog timer expire
milkymist-sysctl.c-> register write
pxa2xx_timer.c-> watchdog timer expire (bsp option)
watchdog.c-> generic watchdog timer expire
xtfpga.c-> register write
cpu_exit()
pc.c->DMA_init
prep.c->DMA_init(broken)
spapr_rtas.c-> registerRTAS_STOP_SELF
Re: [Qemu-devel] [PATCH] armv7-m: exit on external reset request
Quoted 23 lines · Peter Crosthwaite
Quoted 20 lines · Michael Davidsaver
Quoted 7 lines · Peter Maydell
Quoted 6 lines · Michael Davidsaver
...
case 0xd0c: /* Application Interrupt/Reset Control. */ if ((value >> 16) == 0x05fa) {hw/intc/armv7m_nvic.c +3
-0+if (value &4 ) { +qemu_system_reset_request (); + }...
Quoted 6 lines
Strictly speaking what this bit does is assert a signal out of the CPU to some external power management or similar device in the SoC, which then is responsible for doing the reset. So just calling
qemu_system_reset_request()here is a bit of a shortcut. But maybe it's a pragmatic shortcut?I'm not sure what you mean by shortcut? Most targets have some way to trigger qemu to exit. I actually compiled a list recently (see below). I couldn't find one for the lm3s6965evb machine, thus this patch.
...
Quoted 3 lines
I think it would be better for SoC (or board) level to install the GPIO handler to do the reset. As far as target-arm is concerned this is then just a GPIO.
I don't think I'm well versed enough in qemu lingo to parse this sentence :)
Are you concerned about adding this function to AIRCR (which would effect every armv7-m board), or about directly calling qemu_system_reset_request() in armv7m_nvic.c?
Quoted 2 lines
We should check the lm3s docs to see what the implementation of this signal is.
To quote page 129 of http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
Quoted 9 lines
System Reset Request
Value Description
0
No effect.
1
Resets the core and all on-chip peripherals except the Debug
interface.
This bit is automatically cleared during the reset of the core and reads as 0.
There is also mention of a board specific watchdog timer.
I also looked at the TI MSP432P4xx (I have one), which give a similar definition for this bit (along with a dozen board specific ways to do different reset levels...)
Re: [Qemu-devel] [PATCH] armv7-m: exit on external reset request
Quoted 24 lines · Michael Davidsaver
Quoted 14 lines · Peter Crosthwaite
Quoted 12 lines · Michael Davidsaver
Quoted 7 lines · Peter Maydell
Quoted 6 lines · Michael Davidsaver
...
case 0xd0c: /* Application Interrupt/Reset Control. */ if ((value >> 16) == 0x05fa) {hw/intc/armv7m_nvic.c +3
-0+if (value &4 ) { +qemu_system_reset_request (); + }...
Quoted 1 line
Quoted 9 lines
Quoted 8 lines
Quoted 5 lines
Strictly speaking what this bit does is assert a signal out of the CPU to some external power management or similar device in the SoC, which then is responsible for doing the reset. So just calling
qemu_system_reset_request()here is a bit of a shortcut. But maybe it's a pragmatic shortcut?I'm not sure what you mean by shortcut? Most targets have some way to trigger qemu to exit. I actually compiled a list recently (see below). I couldn't find one for the lm3s6965evb machine, thus this patch.
Quoted 8 lines
...
Quoted 3 lines
I think it would be better for SoC (or board) level to install the GPIO handler to do the reset. As far as target-arm is concerned this is then just a GPIO.
I don't think I'm well versed enough in qemu lingo to parse this sentence :)
Are you concerned about adding this function to AIRCR (which would effect every armv7-m board), or about directly callingqemu_system_reset_request()inarmv7m_nvic.c?
I think I've answered my own question. You mean to replace the call to qemu_system_reset_request() with something like qemu_irq_pulse()?
I think I see how to do this. The simplest (adding another named GPIO to the NVIC devices) is complicated by the fact that the armv7m_init() doesn't return the nvic object, but rather an array of qemu_irq. Is it reasonable to change armv7m_init() to return DeviceState*?
PATCH v2 1/1 armv7-m: exit on external reset request
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3) to trigger a GPIO out.
Change armv7m_init to return the DeviceState* for the NVIC. This allows access to all GPIO blocks, not just the IRQ inputs. Move qdev_get_gpio_in() calls out of armv7m_init() into board code for stellaris and stm32f205 boards.
Add GPIO in for the stellaris board which callsqemu_system_reset_request() on reset request.
--- hw/arm/armv7m.c | 9 ++------- hw/arm/stellaris.c | 36 +++++++++++++++++++++++++----------- hw/arm/stm32f205_soc.c | 13 ++++++------- hw/intc/armv7m_nvic.c | 7 ++++++- include/hw/arm/arm.h | 2 +- 5 files changed, 40 insertions(+), 27 deletions(-)
hw/arm/armv7m.c +2 -7
@@ -166,17 +166,15 @@ static void armv7m_reset(void *opaque)mem_size is in bytes. Returns the NVIC array. */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model) {ARMCPU *cpu;CPUARMState *env;DeviceState *nvic; -qemu_irq *pic =g_new (qemu_irq, num_irq);int image_size;uint64_t entry;uint64_t lowaddr; -int i;int big_endian;MemoryRegion *hack =g_new (MemoryRegion,1 );
@@ -198,9 +196,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,qdev_init_nofail (nvic);sysbus_connect_irq (SYS_BUS_DEVICE (nvic),0 ,qdev_get_gpio_in (DEVICE (cpu),ARM_CPU_IRQ )); -for (i =0 ; i < num_irq; i++) { - pic[i] =qdev_get_gpio_in (nvic, i); - }#ifdef TARGET_WORDS_BIGENDIAN big_endian =1 ;
@@ -234,7 +229,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,memory_region_add_subregion (system_memory,0xfffff000 , hack);qemu_register_reset (armv7m_reset, cpu); -return pic; +return nvic; }static Property bitband_properties[] = {
hw/arm/stellaris.c +25 -11
@@ -16,6 +16,7 @@#include "net/net.h" #include "hw/boards.h" #include "exec/address-spaces.h" +#include "sysemu/sysemu.h" #define GPIO_A 0#define GPIO_B 1
@@ -1176,6 +1177,13 @@ static int stellaris_adc_init(SysBusDevice *sbd)return 0 ; } +static +void do_sys_reset (void *opaque,int n,int level) +{ +if (level) +qemu_system_reset_request (); +} +/* Board init. */ static stellaris_board_info stellaris_boards[] = { {"LM3S811EVB" ,
@@ -1210,8 +1218,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, 0x40024000, 0x40025000, 0x40026000};static const int gpio_irq[7 ] = {0 ,1 ,2 ,3 ,4 ,30 ,31 }; -qemu_irq *pic; -DeviceState *gpio_dev[7 ]; +DeviceState *gpio_dev[7 ], *nvic;qemu_irq gpio_in[7 ][8 ];qemu_irq gpio_out[7 ][8 ];qemu_irq adc;
@@ -1241,12 +1248,19 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,0x20000000 , sram); - pic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , + nvic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , kernel_filename, cpu_model); +qdev_connect_gpio_out_named (nvic,"SYSRESETREQ" ,0 , +qemu_allocate_irq (&do_sys_reset,NULL ,0 )); +if (board->dc1 & (1 <<16 )) { dev =sysbus_create_varargs (TYPE_STELLARIS_ADC ,0x40038000 , - pic[14 ], pic[15 ], pic[16 ], pic[17 ],NULL ); +qdev_get_gpio_in (nvic,14 ), +qdev_get_gpio_in (nvic,15 ), +qdev_get_gpio_in (nvic,16 ), +qdev_get_gpio_in (nvic,17 ), +NULL ); adc =qdev_get_gpio_in (dev,0 ); }else { adc =NULL ;
@@ -1255,19 +1269,19 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,if (board->dc2 & (0x10000 << i)) { dev =sysbus_create_simple (TYPE_STELLARIS_GPTM ,0x40030000 + i *0x1000 , - pic[timer_irq[i]]); +qdev_get_gpio_in (nvic, timer_irq[i]));/* TODO: This is incorrect, but we get away with it because the ADC output is only ever pulsed. */ qdev_connect_gpio_out (dev,0 , adc); } } -stellaris_sys_init (0x400fe000 , pic[28 ], board, nd_table[0 ].macaddr.a); +stellaris_sys_init (0x400fe000 ,qdev_get_gpio_in (nvic,28 ), board, nd_table[0 ].macaddr.a);for (i =0 ; i <7 ; i++) {if (board->dc4 & (1 << i)) { gpio_dev[i] =sysbus_create_simple ("pl061_luminary" , gpio_addr[i], - pic[gpio_irq[i]]); +qdev_get_gpio_in (nvic, gpio_irq[i]));for (j =0 ; j <8 ; j++) { gpio_in[i][j] =qdev_get_gpio_in (gpio_dev[i], j); gpio_out[i][j] =NULL ;
@@ -1276,7 +1290,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, }if (board->dc2 & (1 <<12 )) { - dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , pic[8 ]); + dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 ,qdev_get_gpio_in (nvic,8 )); i2c = (I2CBus *)qdev_get_child_bus (dev,"i2c" );if (board->peripherals &BP_OLED_I2C ) {i2c_create_slave (i2c,"ssd0303" ,0x3d );
@@ -1286,11 +1300,11 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,for (i =0 ; i <4 ; i++) {if (board->dc2 & (1 << i)) {sysbus_create_simple ("pl011_luminary" ,0x4000c000 + i *0x1000 , - pic[uart_irq[i]]); +qdev_get_gpio_in (nvic, uart_irq[i])); } }if (board->dc2 & (1 <<4 )) { - dev =sysbus_create_simple ("pl022" ,0x40008000 , pic[7 ]); + dev =sysbus_create_simple ("pl022" ,0x40008000 ,qdev_get_gpio_in (nvic,7 ));if (board->peripherals &BP_OLED_SSI ) {void *bus;DeviceState *sddev;
@@ -1326,7 +1340,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,qdev_set_nic_properties (enet, &nd_table[0 ]);qdev_init_nofail (enet);sysbus_mmio_map (SYS_BUS_DEVICE (enet),0 ,0x40048000 ); -sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 , pic[42 ]); +sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 ,qdev_get_gpio_in (nvic,42 )); }if (board->peripherals &BP_GAMEPAD ) {qemu_irq gpad_irq[5 ];
hw/arm/stm32f205_soc.c +6 -7
@@ -59,9 +59,8 @@ static void stm32f205_soc_initfn(Object *obj)static void stm32f205_soc_realize (DeviceState *dev_soc,Error **errp) {STM32F205State *s =STM32F205_SOC (dev_soc); -DeviceState *syscfgdev, *usartdev, *timerdev; +DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; -qemu_irq *pic;Error *err =NULL ;int i;
@@ -88,8 +87,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,SRAM_BASE_ADDRESS , sram); - pic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , - s->kernel_filename, s->cpu_model); + nvic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , + s->kernel_filename, s->cpu_model);/* System configuration controller */ syscfgdev =DEVICE (&s->syscfg);
@@ -100,7 +99,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } syscfgbusdev =SYS_BUS_DEVICE (syscfgdev);sysbus_mmio_map (syscfgbusdev,0 ,0x40013800 ); -sysbus_connect_irq (syscfgbusdev,0 , pic[71 ]); +sysbus_connect_irq (syscfgbusdev,0 ,qdev_get_gpio_in (nvic,71 ));/* Attach UART (uses USART registers) and USART controllers */ for (i =0 ; i <STM_NUM_USARTS ; i++) {
@@ -112,7 +111,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } usartbusdev =SYS_BUS_DEVICE (usartdev);sysbus_mmio_map (usartbusdev,0 , usart_addr[i]); -sysbus_connect_irq (usartbusdev,0 , pic[usart_irq[i]]); +sysbus_connect_irq (usartbusdev,0 ,qdev_get_gpio_in (nvic, usart_irq[i])); }/* Timer 2 to 5 */
@@ -126,7 +125,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } timerbusdev =SYS_BUS_DEVICE (timerdev);sysbus_mmio_map (timerbusdev,0 , timer_addr[i]); -sysbus_connect_irq (timerbusdev,0 , pic[timer_irq[i]]); +sysbus_connect_irq (timerbusdev,0 ,qdev_get_gpio_in (nvic, timer_irq[i])); } }
hw/intc/armv7m_nvic.c +6 -1
@@ -28,6 +28,7 @@ typedef struct {MemoryRegion gic_iomem_alias;MemoryRegion container;uint32_t num_irq; +qemu_irq sysresetreq; } nvic_state;#define TYPE_NVIC "armv7m_nvic"
@@ -348,10 +349,13 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)break ;case 0xd0c :/* Application Interrupt/Reset Control. */ if ((value >>16 ) ==0x05fa ) { +if (value &4 ) { +qemu_irq_pulse (s->sysresetreq); + }if (value &2 ) {qemu_log_mask (LOG_UNIMP ,"VECTCLRACTIVE unimplemented\n" ); } -if (value &5 ) { +if (value &1 ) {qemu_log_mask (LOG_UNIMP ,"AIRCR system reset unimplemented\n" ); }if (value &0x700 ) {
@@ -540,6 +544,7 @@ static void armv7m_nvic_instance_init(Object *obj)* set the num-irq property appropriately. */ s->num_irq =64 ; +qdev_init_gpio_out_named (DEVICE (obj), &NVIC (obj)->sysresetreq,"SYSRESETREQ" ,1 ); }static void armv7m_nvic_class_init (ObjectClass *klass,void *data)
include/hw/arm/arm.h +1 -1
@@ -17,7 +17,7 @@#include "cpu.h" /* armv7m.c */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model);/*
Signature · 1 line
2.1.4
Re: [Qemu-devel] [PATCH v2] armv7-m: exit on external reset request
Looks great. But I think you want to split this into staged patches. Use git reset HEAD^ to undo the git commit (but keep the file changes) then git add -p to select hunks to stage. Then commit the logically sequential groups of changes as indiv. patches. A general rule is you should try and avoid commiting refactorings along with new features. I see 3 patches here.
Quoted 3 lines · Michael Davidsaver
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3) to trigger a GPIO out.
This is probably the second patch (your new self-contained feature).
Quoted 5 lines
Change
armv7m_initto return the DeviceState* for the NVIC. This allows access to all GPIO blocks, not just the IRQ inputs. Moveqdev_get_gpio_in()calls out ofarmv7m_init()into board code for stellaris and stm32f205 boards.
This is the first patch (refactorings).
Ideally we do this in a more QOM-correct way like with the A-class MPCores but this rework actually gets us closer to that, so I see the value in taking this as the first step. The function that now returns a DeviceState is easily reworked to be a QOM object construction.
Quoted 2 lines
Add GPIO in for the stellaris board which calls
qemu_system_reset_request()on reset request.
Third patch (connect it all up).
Regards,
Peter
Quoted 8 lines
--- hw/arm/armv7m.c | 9 ++------- hw/arm/stellaris.c | 36 +++++++++++++++++++++++++----------- hw/arm/stm32f205_soc.c | 13 ++++++------- hw/intc/armv7m_nvic.c | 7 ++++++- include/hw/arm/arm.h | 2 +- 5 files changed, 40 insertions(+), 27 deletions(-)
PATCH v3 2/3 armv7-m: Implement SYSRESETREQ
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3) to trigger a GPIO out.
--- hw/intc/armv7m_nvic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
hw/intc/armv7m_nvic.c +8 -1
@@ -28,6 +28,7 @@ typedef struct {MemoryRegion gic_iomem_alias;MemoryRegion container;uint32_t num_irq; +qemu_irq sysresetreq; } nvic_state;#define TYPE_NVIC "armv7m_nvic"
@@ -348,10 +349,13 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)break ;case 0xd0c :/* Application Interrupt/Reset Control. */ if ((value >>16 ) ==0x05fa ) { +if (value &4 ) { +qemu_irq_pulse (s->sysresetreq); + }if (value &2 ) {qemu_log_mask (LOG_UNIMP ,"VECTCLRACTIVE unimplemented\n" ); } -if (value &5 ) { +if (value &1 ) {qemu_log_mask (LOG_UNIMP ,"AIRCR system reset unimplemented\n" ); }if (value &0x700 ) {
@@ -535,11 +539,14 @@ static void armv7m_nvic_instance_init(Object *obj)* value in the GICState struct. */ GICState *s =ARM_GIC_COMMON (obj); +DeviceState *dev =DEVICE (obj); +nvic_state *nvic =NVIC (obj);/* The ARM v7m may have anything from 0 to 496 external interrupt * IRQ lines. We default to 64. Other boards may differ and should * set the num-irq property appropriately. */ s->num_irq =64 ; +qdev_init_gpio_out_named (dev, &nvic->sysresetreq,"SYSRESETREQ" ,1 ); }static void armv7m_nvic_class_init (ObjectClass *klass,void *data)
Signature · 1 line
2.1.4
PATCH v3 3/3 stellaris: exit on external reset request
In reply to Peter CrosthwaiteAdd GPIO in for the stellaris board which callsqemu_system_reset_request() on reset request.
--- hw/arm/stellaris.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
hw/arm/stellaris.c +12 -0
@@ -16,6 +16,7 @@#include "net/net.h" #include "hw/boards.h" #include "exec/address-spaces.h" +#include "sysemu/sysemu.h" #define GPIO_A 0#define GPIO_B 1
@@ -1176,6 +1177,14 @@ static int stellaris_adc_init(SysBusDevice *sbd)return 0 ; } +static +void do_sys_reset (void *opaque,int n,int level) +{ +if (level) { +qemu_system_reset_request (); + } +} +/* Board init. */ static stellaris_board_info stellaris_boards[] = { {"LM3S811EVB" ,
@@ -1243,6 +1252,9 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, nvic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , kernel_filename, cpu_model); +qdev_connect_gpio_out_named (nvic,"SYSRESETREQ" ,0 , +qemu_allocate_irq (&do_sys_reset,NULL ,0 )); +if (board->dc1 & (1 <<16 )) { dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, qdev_get_gpio_in(nvic, 14),
Signature · 1 line
2.1.4
PATCH v3 1/3 armv7-m: Return DeviceState* from armv7m_init()
In reply to Peter CrosthwaiteChange armv7m_init to return the DeviceState* for the NVIC. This allows access to all GPIO blocks, not just the IRQ inputs. Move qdev_get_gpio_in() calls out of armv7m_init() into board code for stellaris and stm32f205 boards.
--- hw/arm/armv7m.c | 9 ++------- hw/arm/stellaris.c | 29 ++++++++++++++++++----------- hw/arm/stm32f205_soc.c | 15 ++++++++------- include/hw/arm/arm.h | 2 +- 4 files changed, 29 insertions(+), 26 deletions(-)
hw/arm/armv7m.c +2 -7
@@ -166,17 +166,15 @@ static void armv7m_reset(void *opaque)mem_size is in bytes. Returns the NVIC array. */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model) {ARMCPU *cpu;CPUARMState *env;DeviceState *nvic; -qemu_irq *pic =g_new (qemu_irq, num_irq);int image_size;uint64_t entry;uint64_t lowaddr; -int i;int big_endian;MemoryRegion *hack =g_new (MemoryRegion,1 );
@@ -198,9 +196,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,qdev_init_nofail (nvic);sysbus_connect_irq (SYS_BUS_DEVICE (nvic),0 ,qdev_get_gpio_in (DEVICE (cpu),ARM_CPU_IRQ )); -for (i =0 ; i < num_irq; i++) { - pic[i] =qdev_get_gpio_in (nvic, i); - }#ifdef TARGET_WORDS_BIGENDIAN big_endian =1 ;
@@ -234,7 +229,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,memory_region_add_subregion (system_memory,0xfffff000 , hack);qemu_register_reset (armv7m_reset, cpu); -return pic; +return nvic; }static Property bitband_properties[] = {
hw/arm/stellaris.c +18 -11
@@ -1210,8 +1210,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, 0x40024000, 0x40025000, 0x40026000};static const int gpio_irq[7 ] = {0 ,1 ,2 ,3 ,4 ,30 ,31 }; -qemu_irq *pic; -DeviceState *gpio_dev[7 ]; +DeviceState *gpio_dev[7 ], *nvic;qemu_irq gpio_in[7 ][8 ];qemu_irq gpio_out[7 ][8 ];qemu_irq adc;
@@ -1241,12 +1240,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,0x20000000 , sram); - pic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , + nvic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , kernel_filename, cpu_model);if (board->dc1 & (1 <<16 )) { dev =sysbus_create_varargs (TYPE_STELLARIS_ADC ,0x40038000 , - pic[14 ], pic[15 ], pic[16 ], pic[17 ],NULL ); +qdev_get_gpio_in (nvic,14 ), +qdev_get_gpio_in (nvic,15 ), +qdev_get_gpio_in (nvic,16 ), +qdev_get_gpio_in (nvic,17 ), +NULL ); adc =qdev_get_gpio_in (dev,0 ); }else { adc =NULL ;
@@ -1255,19 +1258,21 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,if (board->dc2 & (0x10000 << i)) { dev =sysbus_create_simple (TYPE_STELLARIS_GPTM ,0x40030000 + i *0x1000 , - pic[timer_irq[i]]); +qdev_get_gpio_in (nvic, timer_irq[i]));/* TODO: This is incorrect, but we get away with it because the ADC output is only ever pulsed. */ qdev_connect_gpio_out (dev,0 , adc); } } -stellaris_sys_init (0x400fe000 , pic[28 ], board, nd_table[0 ].macaddr.a); +stellaris_sys_init (0x400fe000 ,qdev_get_gpio_in (nvic,28 ), + board, nd_table[0 ].macaddr.a);for (i =0 ; i <7 ; i++) {if (board->dc4 & (1 << i)) { gpio_dev[i] =sysbus_create_simple ("pl061_luminary" , gpio_addr[i], - pic[gpio_irq[i]]); +qdev_get_gpio_in (nvic, + gpio_irq[i]));for (j =0 ; j <8 ; j++) { gpio_in[i][j] =qdev_get_gpio_in (gpio_dev[i], j); gpio_out[i][j] =NULL ;
@@ -1276,7 +1281,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, }if (board->dc2 & (1 <<12 )) { - dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , pic[8 ]); + dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , +qdev_get_gpio_in (nvic,8 )); i2c = (I2CBus *)qdev_get_child_bus (dev,"i2c" );if (board->peripherals &BP_OLED_I2C ) {i2c_create_slave (i2c,"ssd0303" ,0x3d );
@@ -1286,11 +1292,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,for (i =0 ; i <4 ; i++) {if (board->dc2 & (1 << i)) {sysbus_create_simple ("pl011_luminary" ,0x4000c000 + i *0x1000 , - pic[uart_irq[i]]); +qdev_get_gpio_in (nvic, uart_irq[i])); } }if (board->dc2 & (1 <<4 )) { - dev =sysbus_create_simple ("pl022" ,0x40008000 , pic[7 ]); + dev =sysbus_create_simple ("pl022" ,0x40008000 , +qdev_get_gpio_in (nvic,7 ));if (board->peripherals &BP_OLED_SSI ) {void *bus;DeviceState *sddev;
@@ -1326,7 +1333,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,qdev_set_nic_properties (enet, &nd_table[0 ]);qdev_init_nofail (enet);sysbus_mmio_map (SYS_BUS_DEVICE (enet),0 ,0x40048000 ); -sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 , pic[42 ]); +sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 ,qdev_get_gpio_in (nvic,42 )); }if (board->peripherals &BP_GAMEPAD ) {qemu_irq gpad_irq[5 ];
hw/arm/stm32f205_soc.c +8 -7
@@ -59,9 +59,8 @@ static void stm32f205_soc_initfn(Object *obj)static void stm32f205_soc_realize (DeviceState *dev_soc,Error **errp) {STM32F205State *s =STM32F205_SOC (dev_soc); -DeviceState *syscfgdev, *usartdev, *timerdev; +DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; -qemu_irq *pic;Error *err =NULL ;int i;
@@ -88,8 +87,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,SRAM_BASE_ADDRESS , sram); - pic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , - s->kernel_filename, s->cpu_model); + nvic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , + s->kernel_filename, s->cpu_model);/* System configuration controller */ syscfgdev =DEVICE (&s->syscfg);
@@ -100,7 +99,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } syscfgbusdev =SYS_BUS_DEVICE (syscfgdev);sysbus_mmio_map (syscfgbusdev,0 ,0x40013800 ); -sysbus_connect_irq (syscfgbusdev,0 , pic[71 ]); +sysbus_connect_irq (syscfgbusdev,0 ,qdev_get_gpio_in (nvic,71 ));/* Attach UART (uses USART registers) and USART controllers */ for (i =0 ; i <STM_NUM_USARTS ; i++) {
@@ -112,7 +111,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } usartbusdev =SYS_BUS_DEVICE (usartdev);sysbus_mmio_map (usartbusdev,0 , usart_addr[i]); -sysbus_connect_irq (usartbusdev,0 , pic[usart_irq[i]]); +sysbus_connect_irq (usartbusdev,0 , +qdev_get_gpio_in (nvic, usart_irq[i])); }/* Timer 2 to 5 */
@@ -126,7 +126,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } timerbusdev =SYS_BUS_DEVICE (timerdev);sysbus_mmio_map (timerbusdev,0 , timer_addr[i]); -sysbus_connect_irq (timerbusdev,0 , pic[timer_irq[i]]); +sysbus_connect_irq (timerbusdev,0 , +qdev_get_gpio_in (nvic, timer_irq[i])); } }
include/hw/arm/arm.h +1 -1
@@ -17,7 +17,7 @@#include "cpu.h" /* armv7m.c */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model);/*
Signature · 1 line
2.1.4
Re: [Qemu-devel] [PATCH v3 3/3] stellaris: exit on external reset request
In reply to Michael Davidsaver"arm: stellaris: " prefix in subject line.
Quoted 4 lines · Michael Davidsaver
Add GPIO in for the stellaris board which calls
qemu_system_reset_request()on reset request.Signed-off-by Michael Davidsaver <[email protected]>
Otherwise,
Regards,
Peter
Quoted 44 lines
--- hw/arm/stellaris.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)hw/arm/stellaris.c +12
-1@@ -16,6 +16,7 @@#include "net/net.h" #include "hw/boards.h" #include "exec/address-spaces.h" +#include "sysemu/sysemu.h" #define GPIO_A 0#define GPIO_B 1@@ -1176,6 +1177,14 @@ static int stellaris_adc_init(SysBusDevice *sbd)return 0 ; } +static +void do_sys_reset (void *opaque,int n,int level) +{ +if (level) { +qemu_system_reset_request (); + } +} +/* Board init. */ static stellaris_board_info stellaris_boards[] = { {"LM3S811EVB" ,@@ -1243,6 +1252,9 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, nvic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , kernel_filename, cpu_model); +qdev_connect_gpio_out_named (nvic,"SYSRESETREQ" ,0 , +qemu_allocate_irq (&do_sys_reset,NULL ,0 )); +if (board->dc1 & (1 <<16 )) { dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, qdev_get_gpio_in(nvic, 14), --2.1.4
Re: [Qemu-devel] [PATCH v3 1/3] armv7-m: Return DeviceState* from armv7m_init()
In reply to Michael DavidsaverMissing CC of Alistair for STM32F205.
Quoted 6 lines · Michael Davidsaver
Change
armv7m_initto return the DeviceState* for the NVIC. This allows access to all GPIO blocks, not just the IRQ inputs. Moveqdev_get_gpio_in()calls out ofarmv7m_init()into board code for stellaris and stm32f205 boards.Signed-off-by Michael Davidsaver <[email protected]>
This is a good step towards QOMification, and I like it in its own right.
Regards,
Peter
Quoted 212 lines
--- hw/arm/armv7m.c | 9 ++------- hw/arm/stellaris.c | 29 ++++++++++++++++++----------- hw/arm/stm32f205_soc.c | 15 ++++++++------- include/hw/arm/arm.h | 2 +- 4 files changed, 29 insertions(+), 26 deletions(-)hw/arm/armv7m.c +2
-7@@ -166,17 +166,15 @@ static void armv7m_reset(void *opaque)mem_size is in bytes. Returns the NVIC array. */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model) {ARMCPU *cpu;CPUARMState *env;DeviceState *nvic; -qemu_irq *pic =g_new (qemu_irq, num_irq);int image_size;uint64_t entry;uint64_t lowaddr; -int i;int big_endian;MemoryRegion *hack =g_new (MemoryRegion,1 );@@ -198,9 +196,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,qdev_init_nofail (nvic);sysbus_connect_irq (SYS_BUS_DEVICE (nvic),0 ,qdev_get_gpio_in (DEVICE (cpu),ARM_CPU_IRQ )); -for (i =0 ; i < num_irq; i++) { - pic[i] =qdev_get_gpio_in (nvic, i); - }#ifdef TARGET_WORDS_BIGENDIAN big_endian =1 ;@@ -234,7 +229,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,memory_region_add_subregion (system_memory,0xfffff000 , hack);qemu_register_reset (armv7m_reset, cpu); -return pic; +return nvic; }static Property bitband_properties[] = {hw/arm/stellaris.c +18
-11@@ -1210,8 +1210,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, 0x40024000, 0x40025000, 0x40026000};static const int gpio_irq[7 ] = {0 ,1 ,2 ,3 ,4 ,30 ,31 }; -qemu_irq *pic; -DeviceState *gpio_dev[7 ]; +DeviceState *gpio_dev[7 ], *nvic;qemu_irq gpio_in[7 ][8 ];qemu_irq gpio_out[7 ][8 ];qemu_irq adc;@@ -1241,12 +1240,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,0x20000000 , sram); - pic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , + nvic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , kernel_filename, cpu_model);if (board->dc1 & (1 <<16 )) { dev =sysbus_create_varargs (TYPE_STELLARIS_ADC ,0x40038000 , - pic[14 ], pic[15 ], pic[16 ], pic[17 ],NULL ); +qdev_get_gpio_in (nvic,14 ), +qdev_get_gpio_in (nvic,15 ), +qdev_get_gpio_in (nvic,16 ), +qdev_get_gpio_in (nvic,17 ), +NULL ); adc =qdev_get_gpio_in (dev,0 ); }else { adc =NULL ;@@ -1255,19 +1258,21 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,if (board->dc2 & (0x10000 << i)) { dev =sysbus_create_simple (TYPE_STELLARIS_GPTM ,0x40030000 + i *0x1000 , - pic[timer_irq[i]]); +qdev_get_gpio_in (nvic, timer_irq[i]));/* TODO: This is incorrect, but we get away with it because the ADC output is only ever pulsed. */ qdev_connect_gpio_out (dev,0 , adc); } } -stellaris_sys_init (0x400fe000 , pic[28 ], board, nd_table[0 ].macaddr.a); +stellaris_sys_init (0x400fe000 ,qdev_get_gpio_in (nvic,28 ), + board, nd_table[0 ].macaddr.a);for (i =0 ; i <7 ; i++) {if (board->dc4 & (1 << i)) { gpio_dev[i] =sysbus_create_simple ("pl061_luminary" , gpio_addr[i], - pic[gpio_irq[i]]); +qdev_get_gpio_in (nvic, + gpio_irq[i]));for (j =0 ; j <8 ; j++) { gpio_in[i][j] =qdev_get_gpio_in (gpio_dev[i], j); gpio_out[i][j] =NULL ;@@ -1276,7 +1281,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, }if (board->dc2 & (1 <<12 )) { - dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , pic[8 ]); + dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , +qdev_get_gpio_in (nvic,8 )); i2c = (I2CBus *)qdev_get_child_bus (dev,"i2c" );if (board->peripherals &BP_OLED_I2C ) {i2c_create_slave (i2c,"ssd0303" ,0x3d );@@ -1286,11 +1292,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,for (i =0 ; i <4 ; i++) {if (board->dc2 & (1 << i)) {sysbus_create_simple ("pl011_luminary" ,0x4000c000 + i *0x1000 , - pic[uart_irq[i]]); +qdev_get_gpio_in (nvic, uart_irq[i])); } }if (board->dc2 & (1 <<4 )) { - dev =sysbus_create_simple ("pl022" ,0x40008000 , pic[7 ]); + dev =sysbus_create_simple ("pl022" ,0x40008000 , +qdev_get_gpio_in (nvic,7 ));if (board->peripherals &BP_OLED_SSI ) {void *bus;DeviceState *sddev;@@ -1326,7 +1333,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,qdev_set_nic_properties (enet, &nd_table[0 ]);qdev_init_nofail (enet);sysbus_mmio_map (SYS_BUS_DEVICE (enet),0 ,0x40048000 ); -sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 , pic[42 ]); +sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 ,qdev_get_gpio_in (nvic,42 )); }if (board->peripherals &BP_GAMEPAD ) {qemu_irq gpad_irq[5 ];hw/arm/stm32f205_soc.c +8
-7@@ -59,9 +59,8 @@ static void stm32f205_soc_initfn(Object *obj)static void stm32f205_soc_realize (DeviceState *dev_soc,Error **errp) {STM32F205State *s =STM32F205_SOC (dev_soc); -DeviceState *syscfgdev, *usartdev, *timerdev; +DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; -qemu_irq *pic;Error *err =NULL ;int i;@@ -88,8 +87,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,SRAM_BASE_ADDRESS , sram); - pic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , - s->kernel_filename, s->cpu_model); + nvic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , + s->kernel_filename, s->cpu_model);/* System configuration controller */ syscfgdev =DEVICE (&s->syscfg);@@ -100,7 +99,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } syscfgbusdev =SYS_BUS_DEVICE (syscfgdev);sysbus_mmio_map (syscfgbusdev,0 ,0x40013800 ); -sysbus_connect_irq (syscfgbusdev,0 , pic[71 ]); +sysbus_connect_irq (syscfgbusdev,0 ,qdev_get_gpio_in (nvic,71 ));/* Attach UART (uses USART registers) and USART controllers */ for (i =0 ; i <STM_NUM_USARTS ; i++) {@@ -112,7 +111,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } usartbusdev =SYS_BUS_DEVICE (usartdev);sysbus_mmio_map (usartbusdev,0 , usart_addr[i]); -sysbus_connect_irq (usartbusdev,0 , pic[usart_irq[i]]); +sysbus_connect_irq (usartbusdev,0 , +qdev_get_gpio_in (nvic, usart_irq[i])); }/* Timer 2 to 5 */ @@ -126,7 +126,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } timerbusdev =SYS_BUS_DEVICE (timerdev);sysbus_mmio_map (timerbusdev,0 , timer_addr[i]); -sysbus_connect_irq (timerbusdev,0 , pic[timer_irq[i]]); +sysbus_connect_irq (timerbusdev,0 , +qdev_get_gpio_in (nvic, timer_irq[i])); } }include/hw/arm/arm.h +1
-2@@ -17,7 +17,7 @@#include "cpu.h" /* armv7m.c */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model);/* -- 2.1.4
Re: [Qemu-devel] [PATCH v3 2/3] armv7-m: Implement SYSRESETREQ
In reply to Michael DavidsaverQuoted 4 lines · Michael Davidsaver
Implement the SYSRESETREQ bit of the AIRCR register for armv7-m (ie. cortex-m3) to trigger a GPIO out.
Signed-off-by Michael Davidsaver <[email protected]>
Quoted 49 lines
--- hw/intc/armv7m_nvic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)hw/intc/armv7m_nvic.c +8
-2@@ -28,6 +28,7 @@ typedef struct {MemoryRegion gic_iomem_alias;MemoryRegion container;uint32_t num_irq; +qemu_irq sysresetreq; } nvic_state;#define TYPE_NVIC "armv7m_nvic"@@ -348,10 +349,13 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)break ;case 0xd0c :/* Application Interrupt/Reset Control. */ if ((value >>16 ) ==0x05fa ) { +if (value &4 ) { +qemu_irq_pulse (s->sysresetreq); + }if (value &2 ) {qemu_log_mask (LOG_UNIMP ,"VECTCLRACTIVE unimplemented\n" ); } -if (value &5 ) { +if (value &1 ) {qemu_log_mask (LOG_UNIMP ,"AIRCR system reset unimplemented\n" ); }if (value &0x700 ) {@@ -535,11 +539,14 @@ static void armv7m_nvic_instance_init(Object *obj)* value in the GICState struct. */ GICState *s =ARM_GIC_COMMON (obj); +DeviceState *dev =DEVICE (obj); +nvic_state *nvic =NVIC (obj);/* The ARM v7m may have anything from 0 to 496 external interrupt * IRQ lines. We default to 64. Other boards may differ and should * set the num-irq property appropriately. */ s->num_irq =64 ; +qdev_init_gpio_out_named (dev, &nvic->sysresetreq,"SYSRESETREQ" ,1 ); }static void armv7m_nvic_class_init (ObjectClass *klass,void *data) --2.1.4
Re: [Qemu-devel] [PATCH v3 1/3] armv7-m: Return DeviceState* from armv7m_init()
In reply to Peter CrosthwaiteThis series looks good, up to Peter if is qualifies for 2.5. It was clearly on list well before soft freeze and really my tardiness as to why it is late with review. So I'll make a case for inclusion.
It does seem to be missing a cover, and/or the in-reply-to looks a bit strange. Maybe patches missed it? Can you try an all-in-one resend with git-generated cover?
Regards,
Peter
Quoted 230 lines · Peter Crosthwaite
Missing CC of Alistair for STM32F205.
Quoted 6 lines · Michael Davidsaver
Change
armv7m_initto return the DeviceState* for the NVIC. This allows access to all GPIO blocks, not just the IRQ inputs. Moveqdev_get_gpio_in()calls out ofarmv7m_init()into board code for stellaris and stm32f205 boards.Signed-off-by Michael Davidsaver <[email protected]>This is a good step towards QOMification, and I like it in its own right.
Reviewed-by Peter Crosthwaite <[email protected]>Regards,
PeterQuoted 212 lines
--- hw/arm/armv7m.c | 9 ++------- hw/arm/stellaris.c | 29 ++++++++++++++++++----------- hw/arm/stm32f205_soc.c | 15 ++++++++------- include/hw/arm/arm.h | 2 +- 4 files changed, 29 insertions(+), 26 deletions(-)hw/arm/armv7m.c +2
-7@@ -166,17 +166,15 @@ static void armv7m_reset(void *opaque)mem_size is in bytes. Returns the NVIC array. */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model) {ARMCPU *cpu;CPUARMState *env;DeviceState *nvic; -qemu_irq *pic =g_new (qemu_irq, num_irq);int image_size;uint64_t entry;uint64_t lowaddr; -int i;int big_endian;MemoryRegion *hack =g_new (MemoryRegion,1 );@@ -198,9 +196,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,qdev_init_nofail (nvic);sysbus_connect_irq (SYS_BUS_DEVICE (nvic),0 ,qdev_get_gpio_in (DEVICE (cpu),ARM_CPU_IRQ )); -for (i =0 ; i < num_irq; i++) { - pic[i] =qdev_get_gpio_in (nvic, i); - }#ifdef TARGET_WORDS_BIGENDIAN big_endian =1 ;@@ -234,7 +229,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,memory_region_add_subregion (system_memory,0xfffff000 , hack);qemu_register_reset (armv7m_reset, cpu); -return pic; +return nvic; }static Property bitband_properties[] = {hw/arm/stellaris.c +18
-11@@ -1210,8 +1210,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, 0x40024000, 0x40025000, 0x40026000};static const int gpio_irq[7 ] = {0 ,1 ,2 ,3 ,4 ,30 ,31 }; -qemu_irq *pic; -DeviceState *gpio_dev[7 ]; +DeviceState *gpio_dev[7 ], *nvic;qemu_irq gpio_in[7 ][8 ];qemu_irq gpio_out[7 ][8 ];qemu_irq adc;@@ -1241,12 +1240,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,0x20000000 , sram); - pic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , + nvic =armv7m_init (system_memory, flash_size,NUM_IRQ_LINES , kernel_filename, cpu_model);if (board->dc1 & (1 <<16 )) { dev =sysbus_create_varargs (TYPE_STELLARIS_ADC ,0x40038000 , - pic[14 ], pic[15 ], pic[16 ], pic[17 ],NULL ); +qdev_get_gpio_in (nvic,14 ), +qdev_get_gpio_in (nvic,15 ), +qdev_get_gpio_in (nvic,16 ), +qdev_get_gpio_in (nvic,17 ), +NULL ); adc =qdev_get_gpio_in (dev,0 ); }else { adc =NULL ;@@ -1255,19 +1258,21 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,if (board->dc2 & (0x10000 << i)) { dev =sysbus_create_simple (TYPE_STELLARIS_GPTM ,0x40030000 + i *0x1000 , - pic[timer_irq[i]]); +qdev_get_gpio_in (nvic, timer_irq[i]));/* TODO: This is incorrect, but we get away with it because the ADC output is only ever pulsed. */ qdev_connect_gpio_out (dev,0 , adc); } } -stellaris_sys_init (0x400fe000 , pic[28 ], board, nd_table[0 ].macaddr.a); +stellaris_sys_init (0x400fe000 ,qdev_get_gpio_in (nvic,28 ), + board, nd_table[0 ].macaddr.a);for (i =0 ; i <7 ; i++) {if (board->dc4 & (1 << i)) { gpio_dev[i] =sysbus_create_simple ("pl061_luminary" , gpio_addr[i], - pic[gpio_irq[i]]); +qdev_get_gpio_in (nvic, + gpio_irq[i]));for (j =0 ; j <8 ; j++) { gpio_in[i][j] =qdev_get_gpio_in (gpio_dev[i], j); gpio_out[i][j] =NULL ;@@ -1276,7 +1281,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, }if (board->dc2 & (1 <<12 )) { - dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , pic[8 ]); + dev =sysbus_create_simple (TYPE_STELLARIS_I2C ,0x40020000 , +qdev_get_gpio_in (nvic,8 )); i2c = (I2CBus *)qdev_get_child_bus (dev,"i2c" );if (board->peripherals &BP_OLED_I2C ) {i2c_create_slave (i2c,"ssd0303" ,0x3d );@@ -1286,11 +1292,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,for (i =0 ; i <4 ; i++) {if (board->dc2 & (1 << i)) {sysbus_create_simple ("pl011_luminary" ,0x4000c000 + i *0x1000 , - pic[uart_irq[i]]); +qdev_get_gpio_in (nvic, uart_irq[i])); } }if (board->dc2 & (1 <<4 )) { - dev =sysbus_create_simple ("pl022" ,0x40008000 , pic[7 ]); + dev =sysbus_create_simple ("pl022" ,0x40008000 , +qdev_get_gpio_in (nvic,7 ));if (board->peripherals &BP_OLED_SSI ) {void *bus;DeviceState *sddev;@@ -1326,7 +1333,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,qdev_set_nic_properties (enet, &nd_table[0 ]);qdev_init_nofail (enet);sysbus_mmio_map (SYS_BUS_DEVICE (enet),0 ,0x40048000 ); -sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 , pic[42 ]); +sysbus_connect_irq (SYS_BUS_DEVICE (enet),0 ,qdev_get_gpio_in (nvic,42 )); }if (board->peripherals &BP_GAMEPAD ) {qemu_irq gpad_irq[5 ];hw/arm/stm32f205_soc.c +8
-7@@ -59,9 +59,8 @@ static void stm32f205_soc_initfn(Object *obj)static void stm32f205_soc_realize (DeviceState *dev_soc,Error **errp) {STM32F205State *s =STM32F205_SOC (dev_soc); -DeviceState *syscfgdev, *usartdev, *timerdev; +DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; -qemu_irq *pic;Error *err =NULL ;int i;@@ -88,8 +87,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)vmstate_register_ram_global (sram);memory_region_add_subregion (system_memory,SRAM_BASE_ADDRESS , sram); - pic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , - s->kernel_filename, s->cpu_model); + nvic =armv7m_init (get_system_memory (),FLASH_SIZE ,96 , + s->kernel_filename, s->cpu_model);/* System configuration controller */ syscfgdev =DEVICE (&s->syscfg);@@ -100,7 +99,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } syscfgbusdev =SYS_BUS_DEVICE (syscfgdev);sysbus_mmio_map (syscfgbusdev,0 ,0x40013800 ); -sysbus_connect_irq (syscfgbusdev,0 , pic[71 ]); +sysbus_connect_irq (syscfgbusdev,0 ,qdev_get_gpio_in (nvic,71 ));/* Attach UART (uses USART registers) and USART controllers */ for (i =0 ; i <STM_NUM_USARTS ; i++) {@@ -112,7 +111,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } usartbusdev =SYS_BUS_DEVICE (usartdev);sysbus_mmio_map (usartbusdev,0 , usart_addr[i]); -sysbus_connect_irq (usartbusdev,0 , pic[usart_irq[i]]); +sysbus_connect_irq (usartbusdev,0 , +qdev_get_gpio_in (nvic, usart_irq[i])); }/* Timer 2 to 5 */ @@ -126,7 +126,8 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } timerbusdev =SYS_BUS_DEVICE (timerdev);sysbus_mmio_map (timerbusdev,0 , timer_addr[i]); -sysbus_connect_irq (timerbusdev,0 , pic[timer_irq[i]]); +sysbus_connect_irq (timerbusdev,0 , +qdev_get_gpio_in (nvic, timer_irq[i])); } }include/hw/arm/arm.h +1
-2@@ -17,7 +17,7 @@#include "cpu.h" /* armv7m.c */ -qemu_irq *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq, +DeviceState *armv7m_init (MemoryRegion *system_memory,int mem_size,int num_irq,const char *kernel_filename,const char *cpu_model);/* -- 2.1.4
Re: [Qemu-devel] [PATCH v3 1/3] armv7-m: Return DeviceState* from armv7m_init()
Quoted 7 lines · Peter Crosthwaite
This series looks good, up to Peter if is qualifies for 2.5. It was clearly on list well before soft freeze and really my tardiness as to why it is late with review. So I'll make a case for inclusion.
It does seem to be missing a cover, and/or the in-reply-to looks a bit strange. Maybe patches missed it? Can you try an all-in-one resend with git-generated cover?
There's no cover letter in my mail archive either (which meant that I didn't look at this earlier, since I thought it was in the same set as the "add MPU" patch, which definitely is not 2.3 material). Anyway, I think these patches look good and we may as well put them in for 2.5 (it only affects M profile). I've made the tweak to the commit subject you suggest for 3/3.
thanks
-- PMM