e1000: CTRL.RST emulation
PATCH 1/1 e1000: CTRL.RST emulation
e1000 spec says CTRL.RST write should have the same effect as bus reset, except that is preserves PCI Config. Reset device registers and interrupts.
Fix suggested by Andy Gospodarek <[email protected]>
--- hw/e1000.c | 97 +++++++++++++++++++++++++++++++---------------------------- 1 files changed, 51 insertions(+), 46 deletions(-)
hw/e1000.c +51 -46
@@ -151,6 +151,40 @@ static const char phy_regcap[0x20] = { [PHY_ID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R }; +static const uint16_t e1000_eeprom_template[64 ] = { +0x0000 ,0x0000 ,0x0000 ,0x0000 ,0xffff ,0x0000 ,0x0000 ,0x0000 , +0x3000 ,0x1000 ,0x6403 ,E1000_DEVID ,0x8086 ,E1000_DEVID ,0x8086 ,0x3040 , +0x0008 ,0x2000 ,0x7e14 ,0x0048 ,0x1000 ,0x00d8 ,0x0000 ,0x2700 , +0x6cc9 ,0x3150 ,0x0722 ,0x040b ,0x0984 ,0x0000 ,0xc000 ,0x0706 , +0x1008 ,0x0000 ,0x0f04 ,0x7fff ,0x4d01 ,0xffff ,0xffff ,0xffff , +0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff , +0x0100 ,0x4000 ,0x121c ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff , +0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0x0000 , +}; + +static const uint16_t phy_reg_init[] = { + [PHY_CTRL ] =0x1140 , [PHY_STATUS ] =0x796d ,// link initially up + [PHY_ID1 ] =0x141 , [PHY_ID2 ] =PHY_ID2_INIT , + [PHY_1000T_CTRL ] =0x0e00 , [M88E1000_PHY_SPEC_CTRL ] =0x360 , + [M88E1000_EXT_PHY_SPEC_CTRL ] =0x0d60 , [PHY_AUTONEG_ADV ] =0xde1 , + [PHY_LP_ABILITY ] =0x1e0 , [PHY_1000T_STATUS ] =0x3c00 , + [M88E1000_PHY_SPEC_STATUS ] =0xac00 , +}; + +static const uint32_t mac_reg_init[] = { + [PBA ] =0x00100030 , + [LEDCTL ] =0x602 , + [CTRL ] =E1000_CTRL_SWDPIN2 |E1000_CTRL_SWDPIN0 | +E1000_CTRL_SPD_1000 |E1000_CTRL_SLU , + [STATUS ] =0x80000000 |E1000_STATUS_GIO_MASTER_ENABLE | +E1000_STATUS_ASDV |E1000_STATUS_MTXCKOK | +E1000_STATUS_SPEED_1000 |E1000_STATUS_FD | +E1000_STATUS_LU , + [MANC ] =E1000_MANC_EN_MNG2HOST |E1000_MANC_RCV_TCO_EN | +E1000_MANC_ARP_EN |E1000_MANC_0298_EN | +E1000_MANC_RMCP_EN , +}; +static void set_interrupt_cause (E1000State *s,int index,uint32_t val) {
@@ -192,9 +226,26 @@ rxbufsize(uint32_t v)return 2048 ; } +static void e1000_reset (void *opaque) +{ +E1000State *d = opaque; + +memset (d->phy_reg,0 ,sizeof d->phy_reg); +memmove (d->phy_reg, phy_reg_init,sizeof phy_reg_init); +memset (d->mac_reg,0 ,sizeof d->mac_reg); +memmove (d->mac_reg, mac_reg_init,sizeof mac_reg_init); + d->rxbuf_min_shift =1 ; +memset (&d->tx,0 ,sizeof d->tx); +} +static void set_ctrl (E1000State *s,int index,uint32_t val) { +if (val &E1000_CTRL_RST ) { +e1000_reset (s); +qemu_set_irq (s->dev.irq[0 ],0 ); + } +/* RST is self clearing */ s->mac_reg[CTRL ] = val & ~E1000_CTRL_RST ; }
@@ -1047,40 +1098,6 @@ static const VMStateDescription vmstate_e1000 = { } }; -static const uint16_t e1000_eeprom_template[64 ] = { -0x0000 ,0x0000 ,0x0000 ,0x0000 ,0xffff ,0x0000 ,0x0000 ,0x0000 , -0x3000 ,0x1000 ,0x6403 ,E1000_DEVID ,0x8086 ,E1000_DEVID ,0x8086 ,0x3040 , -0x0008 ,0x2000 ,0x7e14 ,0x0048 ,0x1000 ,0x00d8 ,0x0000 ,0x2700 , -0x6cc9 ,0x3150 ,0x0722 ,0x040b ,0x0984 ,0x0000 ,0xc000 ,0x0706 , -0x1008 ,0x0000 ,0x0f04 ,0x7fff ,0x4d01 ,0xffff ,0xffff ,0xffff , -0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff , -0x0100 ,0x4000 ,0x121c ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff , -0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0xffff ,0x0000 , -}; - -static const uint16_t phy_reg_init[] = { - [PHY_CTRL ] =0x1140 , [PHY_STATUS ] =0x796d ,// link initially up - [PHY_ID1 ] =0x141 , [PHY_ID2 ] =PHY_ID2_INIT , - [PHY_1000T_CTRL ] =0x0e00 , [M88E1000_PHY_SPEC_CTRL ] =0x360 , - [M88E1000_EXT_PHY_SPEC_CTRL ] =0x0d60 , [PHY_AUTONEG_ADV ] =0xde1 , - [PHY_LP_ABILITY ] =0x1e0 , [PHY_1000T_STATUS ] =0x3c00 , - [M88E1000_PHY_SPEC_STATUS ] =0xac00 , -}; - -static const uint32_t mac_reg_init[] = { - [PBA ] =0x00100030 , - [LEDCTL ] =0x602 , - [CTRL ] =E1000_CTRL_SWDPIN2 |E1000_CTRL_SWDPIN0 | -E1000_CTRL_SPD_1000 |E1000_CTRL_SLU , - [STATUS ] =0x80000000 |E1000_STATUS_GIO_MASTER_ENABLE | -E1000_STATUS_ASDV |E1000_STATUS_MTXCKOK | -E1000_STATUS_SPEED_1000 |E1000_STATUS_FD | -E1000_STATUS_LU , - [MANC ] =E1000_MANC_EN_MNG2HOST |E1000_MANC_RCV_TCO_EN | -E1000_MANC_ARP_EN |E1000_MANC_0298_EN | -E1000_MANC_RMCP_EN , -}; -/* PCI interface */ static void
@@ -1120,18 +1137,6 @@ pci_e1000_uninit(PCIDevice *dev)return 0 ; } -static void e1000_reset (void *opaque) -{ -E1000State *d = opaque; - -memset (d->phy_reg,0 ,sizeof d->phy_reg); -memmove (d->phy_reg, phy_reg_init,sizeof phy_reg_init); -memset (d->mac_reg,0 ,sizeof d->mac_reg); -memmove (d->mac_reg, mac_reg_init,sizeof mac_reg_init); - d->rxbuf_min_shift =1 ; -memset (&d->tx,0 ,sizeof d->tx); -} -static NetClientInfo net_e1000_info = { .type =NET_CLIENT_TYPE_NIC , .size =sizeof (NICState),
Signature · 1 line
1.7.5.53.gc233e
Quoted 5 lines · Michael S. Tsirkin
e1000 spec says CTRL.RST write should have the same effect as bus reset, except that is preserves PCI Config. Reset device registers and interrupts.
Fix suggested by Andy Gospodarek <[email protected]>
Doesn't this have the same effect as this patch:
http://patchwork.ozlabs.org/patch/108673/
except that it's harder to read because it's moved a lot of code around in the file?
(I think you have an extra qemu_set_irq() call in there, actually. But it was hard to find. Also your code has the bug that was in earlier revisions of Anthony's patch where after doing the reset you fall through and allow other bits in the ctrl register to be set.)
-- PMM
Quoted 9 lines · Peter Maydell
Quoted 5 lines · Michael S. Tsirkin
e1000 spec says CTRL.RST write should have the same effect as bus reset, except that is preserves PCI Config. Reset device registers and interrupts.
Fix suggested by Andy Gospodarek <[email protected]>
Doesn't this have the same effect as this patch:
http://patchwork.ozlabs.org/patch/108673/
Right except mine clears the interrupts as well. I missed that patch - what happened to it in the end?
Quoted 4 lines
except that it's harder to read because it's moved a lot of code around in the file?
(I think you have an extra
qemu_set_irq()call in there,
The device spec says we should reset the interrupts. So it seems necessary.
Quoted 1 line
actually. But it was hard to find.
I probably should split the patch out
1. code movement
2. code change
Forward declarations just to work around random placement of functions in file seem wrong - why not order the functions sensibly instead?
Quoted 6 lines
Also your code has the
bug that was in earlier revisions of Anthony's patch where after doing the reset you fall through and allow other bits in the ctrl register to be set.)-- PMM
True.
Signature · 1 line
MST
Quoted 6 lines · Michael S. Tsirkin
Quoted 5 lines · Peter Maydell
Quoted 4 lines · Michael S. Tsirkin
e1000 spec says CTRL.RST write should have the same effect as bus reset, except that is preserves PCI Config. Reset device registers and interrupts.
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Fix suggested by Andy Gospodarek <[email protected]>
Doesn't this have the same effect as this patch:
http://patchwork.ozlabs.org/patch/108673/Right except mine clears the interrupts as well.
I agree that's required, but why doesn't it belong in e1000_reset() ? Surely a qdev reset ought also to clear the output irq signals...
[Disclaimer: this is fishing for somebody to explain to me what the semantics of qdev reset actually are :-)]
Quoted 1 line
I missed that patch - what happened to it in the end?
I think it just got lost in the shuffle (Anthony L never did come back and actually produce a compiler that gave a warning on it, so I think that was just a misremembering on his part.)
-- PMM
Quoted 9 lines · Peter Maydell
Quoted 8 lines · Michael S. Tsirkin
Quoted 7 lines · Peter Maydell
Quoted 5 lines · Michael S. Tsirkin
e1000 spec says CTRL.RST write should have the same effect as bus reset, except that is preserves PCI Config. Reset device registers and interrupts.
Fix suggested by Andy Gospodarek <[email protected]>
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Doesn't this have the same effect as this patch:
http://patchwork.ozlabs.org/patch/108673/Right except mine clears the interrupts as well.
I agree that's required, but why doesn't it belong in
e1000_reset()?
I think not, because pci core resets interrupts for us.
Quoted 4 lines
Surely a qdev reset ought also to clear
the output irq signals...
[Disclaimer: this is fishing for somebody to explain to me what the semantics of qdev reset actually are :-)]
AFAIK what happens is that the qdev is only involved until we get to the pci root. From then on pci_bus_reset calls pci_device_reset to reset the device.
Quoted 8 lines
Quoted 1 line
I missed that patch - what happened to it in the end?
I think it just got lost in the shuffle (Anthony L never did come back and actually produce a compiler that gave a warning on it, so I think that was just a misremembering on his part.)
-- PMM
Yes, that just looks strange. So I intend to just stick this patch in my tree, unless someone NACKs. Then it'll get merged in due course.
Signature · 1 line
MST
Quoted 10 lines · Peter Maydell
Quoted 5 lines · Michael S. Tsirkin
e1000 spec says CTRL.RST write should have the same effect as bus reset, except that is preserves PCI Config. Reset device registers and interrupts.
Fix suggested by Andy Gospodarek<[email protected]>
Doesn't this have the same effect as this patch:
http://patchwork.ozlabs.org/patch/108673/
Quoted 8 lines
except that it's harder to read because it's moved a lot of code around in the file?
(I think you have an extra
qemu_set_irq()call in there, actually. But it was hard to find. Also your code has the bug that was in earlier revisions of Anthony's patch where after doing the reset you fall through and allow other bits in the ctrl register to be set.)
I didn't see your note which said not to rend the patch unless I produce a compiler that issues a warning. Since Anthony P. was going to resubmit, I never looked into it further.
I honestly don't care at this point which patch gets merged.
Regards,
Anthony Liguori
Quoted 2 lines
-- PMM