From john at baldwin.cx Mon Oct 2 10:24:03 2006 From: john at baldwin.cx (John Baldwin) Date: Mon Oct 2 10:24:16 2006 Subject: Properly managing sub-allocations Message-ID: <200610021323.50997.john@baldwin.cx> I'm trying to cleanup a few things in apci and I ran into what I think is a new-bus architecture issue. Specifically, acpi likes to allocate system resource resources from its parent, and then turn around and sub-alloc those out to children. This mostly works fine except for the bus space details of the bus tag and bus handle. Currently acpi(4) just copies the tag from the corresponding resource from the parent and sets the handle to the start of the resource. This just happens to work currently because i386 and amd64 use the start of the resource for the handle for SYS_RES_IO and overwrite the handle in nexus_activate_resource() for SYS_RES_MEMORY. This does add some ugliness though in that acpi needs to go find the parent resouce to copy the bus tag. However, it's current algorithm wouldn't work in general (PC98 needs to alloc bus handles, and it does so in nexus_alloc_resource() for example). To solve this, I think we need to stop setting bus tags and handles in bus_alloc_resource(). One solution might be to add a new bus method to set those for a resource, but I think the better solution would be to set the bus tags and handles in bus_activate_resource(). It already sort of does this for some cases (SYS_RES_MEMORY on x86 for example) and will work with the existing ACPI model (it already passes up activate_resource to the parent, so we would just have to remove the explicit setting of the bus tag and handle). I actually wonder if this isn't how things are supposed to be in the first place and that the current aberrations are just bugs? -- John Baldwin From imp at bsdimp.com Mon Oct 2 10:42:46 2006 From: imp at bsdimp.com (M. Warner Losh) Date: Mon Oct 2 10:42:52 2006 Subject: Properly managing sub-allocations In-Reply-To: <200610021323.50997.john@baldwin.cx> References: <200610021323.50997.john@baldwin.cx> Message-ID: <20061002.113954.756907493.imp@bsdimp.com> In message: <200610021323.50997.john@baldwin.cx> John Baldwin writes: : I'm trying to cleanup a few things in apci and I ran into what I think is a : new-bus architecture issue. Specifically, acpi likes to allocate system : resource resources from its parent, and then turn around and sub-alloc those : out to children. This mostly works fine except for the bus space details of : the bus tag and bus handle. Currently acpi(4) just copies the tag from the : corresponding resource from the parent and sets the handle to the start of : the resource. This just happens to work currently because i386 and amd64 use : the start of the resource for the handle for SYS_RES_IO and overwrite the : handle in nexus_activate_resource() for SYS_RES_MEMORY. This does add some : ugliness though in that acpi needs to go find the parent resouce to copy the : bus tag. However, it's current algorithm wouldn't work in general (PC98 : needs to alloc bus handles, and it does so in nexus_alloc_resource() for : example). : : To solve this, I think we need to stop setting bus tags and handles in : bus_alloc_resource(). One solution might be to add a new bus method to set : those for a resource, but I think the better solution would be to set the bus : tags and handles in bus_activate_resource(). It already sort of does this : for some cases (SYS_RES_MEMORY on x86 for example) and will work with the : existing ACPI model (it already passes up activate_resource to the parent, so : we would just have to remove the explicit setting of the bus tag and handle). : : I actually wonder if this isn't how things are supposed to be in the first : place and that the current aberrations are just bugs? I think you are right. Thinking about it, you can't access the resources until you've activated them... However, this may break some existing drivers that allocate a BAR, peek at its type and then either activate it or allocate another BAR... The TAG is valid, but the handle isn't. This specific problem will never happen in pc98, since there are no ACPI pc98 machines and can never be. Warner From john at baldwin.cx Mon Oct 2 11:19:58 2006 From: john at baldwin.cx (John Baldwin) Date: Mon Oct 2 11:20:00 2006 Subject: Properly managing sub-allocations In-Reply-To: <20061002.113954.756907493.imp@bsdimp.com> References: <200610021323.50997.john@baldwin.cx> <20061002.113954.756907493.imp@bsdimp.com> Message-ID: <200610021403.50339.john@baldwin.cx> On Monday 02 October 2006 13:39, M. Warner Losh wrote: > In message: <200610021323.50997.john@baldwin.cx> > John Baldwin writes: > : I'm trying to cleanup a few things in apci and I ran into what I think is a > : new-bus architecture issue. Specifically, acpi likes to allocate system > : resource resources from its parent, and then turn around and sub-alloc those > : out to children. This mostly works fine except for the bus space details of > : the bus tag and bus handle. Currently acpi(4) just copies the tag from the > : corresponding resource from the parent and sets the handle to the start of > : the resource. This just happens to work currently because i386 and amd64 use > : the start of the resource for the handle for SYS_RES_IO and overwrite the > : handle in nexus_activate_resource() for SYS_RES_MEMORY. This does add some > : ugliness though in that acpi needs to go find the parent resouce to copy the > : bus tag. However, it's current algorithm wouldn't work in general (PC98 > : needs to alloc bus handles, and it does so in nexus_alloc_resource() for > : example). > : > : To solve this, I think we need to stop setting bus tags and handles in > : bus_alloc_resource(). One solution might be to add a new bus method to set > : those for a resource, but I think the better solution would be to set the bus > : tags and handles in bus_activate_resource(). It already sort of does this > : for some cases (SYS_RES_MEMORY on x86 for example) and will work with the > : existing ACPI model (it already passes up activate_resource to the parent, so > : we would just have to remove the explicit setting of the bus tag and handle). > : > : I actually wonder if this isn't how things are supposed to be in the first > : place and that the current aberrations are just bugs? > > I think you are right. Thinking about it, you can't access the > resources until you've activated them... > > However, this may break some existing drivers that allocate a BAR, > peek at its type and then either activate it or allocate another > BAR... The TAG is valid, but the handle isn't. They generally peak at the BAR register itself though, not the value of rman_get_bustag() though, right? > This specific problem will never happen in pc98, since there are no > ACPI pc98 machines and can never be. Yeah, but I can cleanup the stuff in ACPI a good bit if I can get it to stop peeking at the "real" resource to get the bus tag. Also, I think fixing this would be important for a driver that wanted to sub-alloc its resources out to children (like vgapci, which currently cheats on that). -- John Baldwin From imp at bsdimp.com Mon Oct 2 12:42:14 2006 From: imp at bsdimp.com (M. Warner Losh) Date: Mon Oct 2 12:42:17 2006 Subject: Properly managing sub-allocations In-Reply-To: <200610021403.50339.john@baldwin.cx> References: <200610021323.50997.john@baldwin.cx> <20061002.113954.756907493.imp@bsdimp.com> <200610021403.50339.john@baldwin.cx> Message-ID: <20061002.134204.-749250271.imp@bsdimp.com> In message: <200610021403.50339.john@baldwin.cx> John Baldwin writes: : > However, this may break some existing drivers that allocate a BAR, : > peek at its type and then either activate it or allocate another : > BAR... The TAG is valid, but the handle isn't. : : They generally peak at the BAR register itself though, not the value of : rman_get_bustag() though, right? Some do, some get the resource and look at it. There's a lot of variance here. Do you put knowledge of how to decode PCI bars into every driver, or do you let the pci bus take care of it? Since the knowledge is nearly trivial, different people decide differenly. It is still a technique that has been used, and you'll need to be careful to make sure you don't break anything. After all, 0 is a valid I/O tag and it is also the default value... : > This specific problem will never happen in pc98, since there are no : > ACPI pc98 machines and can never be. : : Yeah, but I can cleanup the stuff in ACPI a good bit if I can get it : to stop peeking at the "real" resource to get the bus tag. Also, I : think fixing this would be important for a driver that wanted to : sub-alloc its resources out to children (like vgapci, which : currently cheats on that). Good point. I don't dispute this is a good thing, just that it will solve a problem we're currently having. Given the push for embedded, this is a problem worth solving. Warner From john at baldwin.cx Mon Oct 2 13:21:42 2006 From: john at baldwin.cx (John Baldwin) Date: Mon Oct 2 13:21:49 2006 Subject: Properly managing sub-allocations In-Reply-To: <20061002.134204.-749250271.imp@bsdimp.com> References: <200610021323.50997.john@baldwin.cx> <200610021403.50339.john@baldwin.cx> <20061002.134204.-749250271.imp@bsdimp.com> Message-ID: <200610021620.44185.john@baldwin.cx> On Monday 02 October 2006 15:42, M. Warner Losh wrote: > In message: <200610021403.50339.john@baldwin.cx> > John Baldwin writes: > : > However, this may break some existing drivers that allocate a BAR, > : > peek at its type and then either activate it or allocate another > : > BAR... The TAG is valid, but the handle isn't. > : > : They generally peak at the BAR register itself though, not the value of > : rman_get_bustag() though, right? > > Some do, some get the resource and look at it. There's a lot of > variance here. Do you put knowledge of how to decode PCI bars into > every driver, or do you let the pci bus take care of it? Since the > knowledge is nearly trivial, different people decide differenly. It > is still a technique that has been used, and you'll need to be careful > to make sure you don't break anything. After all, 0 is a valid I/O > tag and it is also the default value... Err, how can code examine the actual bus tag value of a non-active resource? By definition it's set an opaque MD value. You can't compare it against SYS_RES_MEMORY for example. On i386 systems it happens to be an int, on some other systems (alpha maybe?) I think it can be a pointer to a structure of function pointers for the different bus space operations. I don't think any MI code should ever be examining the bus tag or handle except to pass them as opaque parameters to bus_space_*(). -- John Baldwin From imp at bsdimp.com Mon Oct 2 14:09:18 2006 From: imp at bsdimp.com (M. Warner Losh) Date: Mon Oct 2 14:09:21 2006 Subject: Properly managing sub-allocations In-Reply-To: <200610021620.44185.john@baldwin.cx> References: <200610021403.50339.john@baldwin.cx> <20061002.134204.-749250271.imp@bsdimp.com> <200610021620.44185.john@baldwin.cx> Message-ID: <20061002.150812.151470856.imp@bsdimp.com> In message: <200610021620.44185.john@baldwin.cx> John Baldwin writes: : On Monday 02 October 2006 15:42, M. Warner Losh wrote: : > In message: <200610021403.50339.john@baldwin.cx> : > John Baldwin writes: : > : > However, this may break some existing drivers that allocate a BAR, : > : > peek at its type and then either activate it or allocate another : > : > BAR... The TAG is valid, but the handle isn't. : > : : > : They generally peak at the BAR register itself though, not the value of : > : rman_get_bustag() though, right? : > : > Some do, some get the resource and look at it. There's a lot of : > variance here. Do you put knowledge of how to decode PCI bars into : > every driver, or do you let the pci bus take care of it? Since the : > knowledge is nearly trivial, different people decide differenly. It : > is still a technique that has been used, and you'll need to be careful : > to make sure you don't break anything. After all, 0 is a valid I/O : > tag and it is also the default value... : : Err, how can code examine the actual bus tag value of a non-active resource? : By definition it's set an opaque MD value. You can't compare it against : SYS_RES_MEMORY for example. On i386 systems it happens to be an int, on some : other systems (alpha maybe?) I think it can be a pointer to a structure of : function pointers for the different bus space operations. I don't think any : MI code should ever be examining the bus tag or handle except to pass them as : opaque parameters to bus_space_*(). Actually, you are right. I'm confusing success/failure of allocating a I/O and/or Memory bar with this... Warner From namaskar_alok at yahoo.co.in Fri Oct 6 00:34:38 2006 From: namaskar_alok at yahoo.co.in (Alok Barsode) Date: Fri Oct 6 00:34:39 2006 Subject: Device enumeration process In-Reply-To: <20060930.124334.-432842007.imp@bsdimp.com> Message-ID: <20061006073434.71730.qmail@web8913.mail.in.yahoo.com> Hi, Thanks for ur earliers replies. They helped me a lot in understanding the newbus architecture. I am involved in a freeBSD port to a freescale board. I still had a few doubts: I am looking at the autoconf.c file for the i386 architecture. When i/o configuration is in progress during startup, are the drivers for specific busses alreay assosciated with them or the association happens at run time ? for example : when nexus is being attached to root_bus, the method devclass_find_internal("nexus", 0, TRUE) is invoked(in method make_device).Now does a nexus devclass already exist ( it is created through the macro DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);) or it is created at runtime ? if it is created at runtime how the nexus_driver get assciated with nexus? Thanks, Alok. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From imp at bsdimp.com Fri Oct 6 08:45:21 2006 From: imp at bsdimp.com (M. Warner Losh) Date: Fri Oct 6 08:45:25 2006 Subject: Device enumeration process In-Reply-To: <20061006073434.71730.qmail@web8913.mail.in.yahoo.com> References: <20060930.124334.-432842007.imp@bsdimp.com> <20061006073434.71730.qmail@web8913.mail.in.yahoo.com> Message-ID: <20061006.094231.-1572283957.imp@bsdimp.com> In message: <20061006073434.71730.qmail@web8913.mail.in.yahoo.com> Alok Barsode writes: : Thanks for ur earliers replies. They helped me a lot : in understanding the newbus architecture. : I am involved in a freeBSD port to a freescale board. Cool! Remind me: is the freescale an arm design or a Power PC one? : When i/o configuration is in progress during startup, : are the drivers for specific busses alreay assosciated : with them or the association happens at run time ? The drivers are associated with the busses at compile time (as extended via modules that are loaded). The assignment of specific device nodes to drivers is done at run time. : for example : : when nexus is being attached to root_bus, : the method devclass_find_internal("nexus", 0, TRUE) is : invoked(in method make_device).Now does a nexus : devclass already exist ( it is created through the : macro DRIVER_MODULE(nexus, root, nexus_driver, : nexus_devclass, 0, 0);) or it is created at runtime ? : : if it is created at runtime how the nexus_driver get : assciated with nexus? nexus_driver gets associated with nexus here: /* * Determine i/o configuration for a machine. */ static void configure_first(dummy) void *dummy; { /* nexus0 is the top of the i386 device tree */ device_add_child(root_bus, "nexus", 0); } at least tenatively associated. configure_first is run via the SYSINIT at SI_SUB_CONFIGURE as the first thing. In fact, all the autoconf look similar in this respect. The arm one does the same thing. If you look at sys/arm/at91/at91.c, you'll see code: static void at91_identify(driver_t *drv, device_t parent) { BUS_ADD_CHILD(parent, 0, "atmelarm", 0); } which is how the atmelbus gets added to nexus. Again, the atmelbus is about the best example I can easily find in the tree... Warner From namaskar_alok at yahoo.co.in Thu Oct 26 13:24:56 2006 From: namaskar_alok at yahoo.co.in (Alok Barsode) Date: Thu Oct 26 13:25:03 2006 Subject: Network device driver issues. Message-ID: <20061026132453.48510.qmail@web8904.mail.in.yahoo.com> Hello, I am porting freeBSD 4.10 to a embedded board. The board has 2 Three speed Ethernet Controller and a Cicada PHY. I have implemented a pseudo-bus (called mpcbus) which attaches itself to nexus. i plan to attach all the devices to the mpcbus. (i will be calling the IDENTIFY function for each device-driver).All the devices are memory mapped. Now i have 2 TSEC(Three-Speed Ethernet Controller)on the board(say TSEC0 and TSEC1). During the IDENTIFY routine, should the function BUS_ADD_CHILD() called twice ,once for each TSEC? I also dont what the PHY to be configured sepatately. (I right now dont want any "mii" stuff) I will configure the PHY manually. is this fine with the freeBSD point of view? I dont understand the struct xxx_mii_frame. i am looking at the National Semiconductor DP83820/DP83821 gigabit ethernet driver (i.e /dev/nge/if_nge.c) The frame structure is: struct nge_mii_frame { u_int8_t mii_stdelim; u_int8_t mii_opcode; u_int8_t mii_phyaddr; u_int8_t mii_regaddr; u_int8_t mii_turnaround; u_int16_t mii_data; };All the drivers use this kind of frame structure. Is this a generic one? how does one use it? is there a simple driver i can look at? or a simple tutorial on network drivers? the National Semiconductor driver is a bit complex. Thanks, alok. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From imp at bsdimp.com Thu Oct 26 21:29:42 2006 From: imp at bsdimp.com (M. Warner Losh) Date: Thu Oct 26 21:29:44 2006 Subject: Network device driver issues. In-Reply-To: <20061026132453.48510.qmail@web8904.mail.in.yahoo.com> References: <20061026132453.48510.qmail@web8904.mail.in.yahoo.com> Message-ID: <20061026.130416.1649769670.imp@bsdimp.com> In message: <20061026132453.48510.qmail@web8904.mail.in.yahoo.com> Alok Barsode writes: : Hello, : I am porting freeBSD 4.10 to a embedded board. : The board has 2 Three speed Ethernet Controller and a : Cicada PHY. : I have implemented a pseudo-bus (called mpcbus) which : attaches itself to nexus. : i plan to attach all the devices to the mpcbus. (i : will be calling the IDENTIFY function for each : device-driver).All the devices are memory : mapped. : Now i have 2 TSEC(Three-Speed Ethernet Controller)on : the board(say TSEC0 and TSEC1). : During the IDENTIFY routine, should the function : BUS_ADD_CHILD() called twice ,once for each TSEC? Yes, that would work. Actaully, you need to write a more real bus that adds the children, but short of that, calling bus_add_child would be a short-term workaround. : I also dont what the PHY to be configured sepatately. : (I right now dont want any "mii" stuff) I will : configure the PHY manually. is this fine : with the freeBSD point of view? : I dont understand the : struct xxx_mii_frame. : i am looking at the National Semiconductor : DP83820/DP83821 gigabit : ethernet driver (i.e /dev/nge/if_nge.c) : : The frame structure is: : struct nge_mii_frame { : u_int8_t mii_stdelim; : u_int8_t mii_opcode; : u_int8_t mii_phyaddr; : u_int8_t mii_regaddr; : u_int8_t mii_turnaround; : u_int16_t mii_data; : };All the drivers use this kind of frame structure. : Is this a generic one? how does one use it? That looks like it might be left over from ports to other OSes. What you are seeing in the nge driver is that it is reading/writing the registers and doing the transactions in a rather long way. It is best viewed as bitbanging the information out. : is there a simple driver i can look at? or a simple : tutorial on network drivers? : the National Semiconductor driver is a bit complex. Generally, one just lets the MII bus do its thing. If you look at the if_ate driver, you can see this in operation: #include #include ... #include "miibus_if.h" ... /* in softc */ device_t miibus; /* My child miibus */ ... after allocating the ifp: if (mii_phy_probe(dev, &sc->miibus, ate_ifmedia_upd, ate_ifmedia_sts)) { device_printf(dev, "Cannot find my PHY.\n"); err = ENXIO; goto out; } ... /* * Change media according to request. */ static int ate_ifmedia_upd(struct ifnet *ifp) { struct ate_softc *sc = ifp->if_softc; struct mii_data *mii; mii = device_get_softc(sc->miibus); ATE_LOCK(sc); mii_mediachg(mii); ATE_UNLOCK(sc); return (0); } /* * Notify the world which media we're using. */ static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { struct ate_softc *sc = ifp->if_softc; struct mii_data *mii; mii = device_get_softc(sc->miibus); ATE_LOCK(sc); mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; ATE_UNLOCK(sc); } static void ate_tick(void *xsc) { struct ate_softc *sc = xsc; struct mii_data *mii; int active; /* * The KB920x boot loader tests ETH_SR & ETH_SR_LINK and will ask * the MII if there's a link if this bit is clear. Not sure if we * should do the same thing here or not. */ ATE_ASSERT_LOCKED(sc); if (sc->miibus != NULL) { mii = device_get_softc(sc->miibus); active = mii->mii_media_active; mii_tick(mii); if (mii->mii_media_status & IFM_ACTIVE && active != mii->mii_media_active) { /* * The speed and full/half-duplex state needs * to be reflected in the ETH_CFG register, it * seems. */ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_SPD); else WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_SPD); if (mii->mii_media_active & IFM_FDX) WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_FD); else WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_FD); } } ... /* * Schedule another timeout one second from now. */ callout_reset(&sc->tick_ch, hz, ate_tick, sc); } At the end of the if_init routine, you need to start the ticker: callout_reset(&sc->tick_ch, hz, ate_tick, sc); You also need to implement the read/write regitser stuff Add this to your device's method table: /* MII interface */ DEVMETHOD(miibus_readreg, ate_miibus_readreg), DEVMETHOD(miibus_writereg, ate_miibus_writereg), For comparison, here's the ate read/write routines: /* * MII bus support routines. */ static int ate_miibus_readreg(device_t dev, int phy, int reg) { struct ate_softc *sc; int val; /* * XXX if we implement agressive power savings, then we need * XXX to make sure that the clock to the emac is on here */ if (phy != 0) return (0xffff); sc = device_get_softc(dev); DELAY(1); /* Hangs w/o this delay really 30.5us atm */ WR4(sc, ETH_MAN, ETH_MAN_REG_RD(phy, reg)); while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0) continue; val = RD4(sc, ETH_MAN) & ETH_MAN_VALUE_MASK; return (val); } static void ate_miibus_writereg(device_t dev, int phy, int reg, int data) { struct ate_softc *sc; /* * XXX if we implement agressive power savings, then we need * XXX to make sure that the clock to the emac is on here */ sc = device_get_softc(dev); WR4(sc, ETH_MAN, ETH_MAN_REG_WR(phy, reg, data)); while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0) continue; return; } The ate hardware does the bit-banging for you... FreeBSD doesn't directly program the PHY. Your driver still needs to do that, as illustrated above. This just takes the drudgery out of it. Warner From 0xdead1eaf at gmail.com Sun Oct 29 12:29:36 2006 From: 0xdead1eaf at gmail.com (Mark Eiransen) Date: Sun Oct 29 12:29:37 2006 Subject: Working on new-bus Message-ID: <4ffc39d60610290429q6af16732k5efb847d659cae90@mail.gmail.com> Hi, I would like to know if there are open items about new-bus, where I can find documentation in order to improve it, etc. Thanks for the help! Mark