RISC OS on IGEPv2
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ... 20
Trevor Johnson (329) 1645 posts |
I reckon it’s probably this IEEE 802.3 LAN/MAN CSMA/CD (Ethernet) Access Method (which you may have already tracked down by now).
The contents for all five sections are listed in section one. Good luck! |
Jeffrey Lee (213) 6048 posts |
Yes, there’s a fair chance that U-Boot will set up the GPMC bus for us.
Yeah, that’s the one. I think the MII specification should be somewhere in the 802.3 documentation available here – if not then I should (hopefully) be able to track down where I found the spec when I get home. Or if you’re lucky the NIC datasheet will describe all you need to know about the specific MII that’s in use.
Just to add some more reading to your list – there’s this post where I answered some of Tank’s questions about writing a driver for the DevKit NIC. Also, you may know this already, but if you’re going to structure the driver “properly” then you’d want the HAL to expose it to RISC OS as a HAL device. This means the HAL would do the board-specific bits like configuring the GPMC bus & GPIO controller, and typically only expose to the driver the logical address of the chip, the IRQ (aka device) number, and the TestIRQ function for checking if the shared IRQ actually came from the NIC. The HAL device would also have to be tied into the board config system used by the OMAP HAL, so that it only initialises the hardware and exposes it to RISC OS if the ROM is running on an IGEP board. Once you’ve serviced the IRQ I think the GPIO controller needs to be explicitly told to clear its IRQ line – which means it might be a good time for us to add a ClearIRQ function pointer to the base HAL device struct so that we have a standard way of handling devices that are on latching IRQ multiplexers. |
W P Blatchley (147) 247 posts |
I just had a brief look at EtherK (can anyone explain or point me to an explanation of the various ‘Ether*’ names used for all Ethernet-related RISC OS modules?). There seems to be a lot of code in there that’s presumably the same (or nearly the same) for all NIC drivers – things like the user-facing star command handlers and loopback code, etc. Is this just duplicated in every NIC driver, or is there some more subtle separation of the code that I haven’t spotted? Perhaps the HAL device implementation would achieve that sort of code separation? I’m right in thinking that the Iyonix NIC driver (i.e. EtherK) doesn’t have a HAL device back-end, aren’t I? Oh, and thanks again Jeffrey and Trevor for the pointers! |
Jeffrey Lee (213) 6048 posts |
I suspect it’s just duplicated – although I believe different drivers do provide subtley different * commands.
Perhaps – EtherUSB has shown that it is possible to provide a standard frontend for multiple NIC drivers. It shouldn’t be too much work to do a similar thing, but with HAL devices instead.
Correct, there’s no HAL backend. The Iyonix NIC is on the PCI bus, so all the driver has to do is probe that for the known vendor & device IDs. Also, I’ve checked my copy of the 802.3 docs – the MII documentation is in the “section 2” PDF, from page 9 onwards. But the interesting bit for you is likely to start on page 24, where they talk about the control registers. Although the registers are standard, the method of accessing them isn’t – it should be covered somewhere in the NIC docs. |
James Peacock (318) 129 posts |
EtherUSB is built around driving USB devices and there are some currently some performance compromises which I’ve not managed to resolve because of this [1]. As such, a more traditional ethernet driver such as EtherK might provide a better model to work from. In addition, EtherUSB’s MII and DCI code both do enough to work, but could be improved. MII is definitely a candidate for moving into a separate module, probably providing a APCS compatible entry point to which callback function pointers can be passed to read and write to a specific device. Beyond this there is a litte bit of DCI related faffing, for example registering and deregistering protocol modules, which could be put in a library. Whether EtherUSB’s implementation is 100% correct, I’m not sure, I should probably compare it with that of EtherK now the source is available. As an aside, I’ve had success building EtherUSB into an Iyonix ROM image after a few minor changes to includes, though whether there is a need for this I don’t know. It doesn’t use MessageTrans at present and there is some wasteful use of static const data I’d like to resolve at some point to make the binary smaller. [1] FIQProf and profanal have been useful here (thanks Jeffrey), once I managed to create a GPA file. I’ve got a few minor additions to profanal to calculate things like the ‘hits’ in each function matching the filters. Work in progress. |
Jeffrey Lee (213) 6048 posts |
I don’t think there’ll be enough space to include EtherUSB in a ROM image. The softloadable version of the module is 45k, but there’s only 15k of spare space in the Iyonix 5.16 ROM. At the moment there’s about 170k space in the OMAP ROM, but that will be needed for the SD/MMC & NAND drivers (and hopefully leave enough space for the IGEP/DevKit NIC drivers). Admittedly we could increase the ROM size (and use compressed ROMs on the Iyonix), but since EtherUSB is likely to receive regular updates to add support for new devices I think it’s a component that’s better suited to being distributed on disc rather than trying to shoehorn it into already full ROM images.
Glad someone else is able to make use of the code and not just me :) With regards to optimising EtherUSB – have you taken a look at the changes I made to SCSISoftUSB? Basically, listening out for buffer filling/emptying upcalls, and using them as a cue to wake up a routine that had been registered with RTSupport. The routine would then pass the data onto the SCSI driver and start another USB transfer if appropriate. Previously the module was just using the centisecond timer to trigger processing, but the buffer size was so small that the USB controller would fill/empty it in around 3 milliseconds – leaving the other 7 to go to waste. Admittedly I don’t have much of an idea of how easy this would be to adapt for a DCI driver (e.g. whether DCI allows packets to be sent & received from an execution context that’s essentially the same as an IRQ handler), but at the moment I think it’s the only way to get the best performance out of the USB stack. |
W P Blatchley (147) 247 posts |
Thanks James and Jeffrey. Looks like the driver could be distilled down into some fairly separable parts. I’ll make a plan and then get back to you. |
W P Blatchley (147) 247 posts |
James, are the EtherUSB sources on your website the most up-to-date, including the Pegasus chipset additions? Or are the sources now held here with ROOL? |
Jeffrey Lee (213) 6048 posts |
The sources on James’s website should be up to date. Also, I’ve realised that I might have been a bit misleading with this bit:
What I meant to say was that the HAL would expose the presence of the NIC to RISC OS via a HAL device – not expose a fully-fledged NIC driver as a HAL device. That way the HAL device can worry about all the board-specific stuff (deciding if the NIC is present, configuring the GPIO controller to enable the IRQ, etc.) while the NIC driver can just concentrate on interacting with the NIC in a board-agnostic manner. |
Uwe Kall (215) 120 posts |
WPB, I have tried to implement the EtherUSB driver for a DM9601 USB Device, but it responded only to some commands – if you start work on any EtherUSB drivers I would like to contact you. I also took the sources from James’s website. They contained Jeffrey’s additions. |
Jan Rinze (235) 368 posts |
Uwe, I had not noticed any changes in the Ether USB sources. Do you have a pointer where I can get these updated sources? |
Jeffrey Lee (213) 6048 posts |
Jan/WPB: James’s website has moved around a bit recently – the new (and hopefully permanent) home is here. The source available there contains my Pegasus driver. |
James Peacock (318) 129 posts |
I have some local changes here, one being an uninitialised variable fix, there is also some improvements for anyone with multiple USB ethernet adaptors. None of this affects the backends. I’ll see about releasing this over the weekend. 0.07 is the latest public version available from:
|
James Peacock (318) 129 posts |
EtherUSB uses the UpCalls and reads/writes to the USB pipe using the buffer manager service routine so it doesn’t need to be done on callback. This works well for rx, but I found that EtherUSB isn’t able to reliably detect when it can write the next tx packet to the USB pipe’s buffer. This led to EtherUSB’s tx packet queue filling up so I ended up with a callback to prod it every so often. I remember spending a long time trying to get this to work without this hack but never found the right incantation. |
Jan Rinze (235) 368 posts |
James, you seem to have implemented a circular buffer. I have a feeling the error is in the implementation of that circular buffer. Both in and out indices are updated before the data is written. I will take a look at the code again and see if i am right about the circular buffer. |
W P Blatchley (147) 247 posts |
It’s okay – I think I got what you were driving at! How will the different board setups work in respect to presence/absence of NIC? The HAL documentation suggests that HAL devices should be set up inside HAL_InitDevices. Does each board get its own incantation of HAL_InitDevices, or should some board-sensing conditional code go in there? And (sorry for the dumb question), how do HAL device implementations manifest themselves – as modules? How would the OS-side driver (let’s call it EtherHAL?) get a handle on the HAL device? Would it just assume a HAL device number (i.e. a new number would be assigned for on-board NICs)? Wow, that was many more questions than I thought were in my head! Sorry! Here’s one more for the road: Does anyone know where I can find DCI4 documented? |
James Peacock (318) 129 posts |
The DCI docs aren’t publicly available AFAIK, it would be good if they could be put up on the wiki. I suggest asking ROOL in the first case. |
James Peacock (318) 129 posts |
Can you point me at the problem, I couldn’t find it. |
Jeffrey Lee (213) 6048 posts |
I suspect the easiest method would be to add an extra word to the board config struct (see board.s and board.hdr) that gets used as a pointer to some code which will set up any board-specific HAL devices. The HAL_InitDevices implementation (if you ignore my hacky FIQ debugger code) can then jump to the additional code after it’s set up all the common devices.
No, they don’t manifest as modules. Instead, programs use OS_Hardware 4 to search the device list. Usually they should also listen out for Service_Hardware as well, to allow them to detect any hot-pluggable devices, or to cope with situations where the device is briefly unavailable (e.g. if a RISC OS module added the device, but then the module gets reinitialised) Although to be honest I don’t think you have to worry too much about dealing with unexpected device removals (I know none of the code that I’ve written does!).
There’s a list of all the HAL device IDs and types in Kernel.hdr.HALDevice. You’d have to add a new device type for NICs, along with a device ID for the 9221. And then the driver would use OS_Hardware 4 to search for that device type and check the results for any 9221’s. Of course, this is assuming your driver only targets the 9221 – if you wanted to support multiple NIC types then you’d have several choices:
So, the moral of the story is: Ask lots of questions, get verbose answers ;) |
Jan Rinze (235) 368 posts |
James, sorry for my blunt post. I had been reading through the code and the circular buffer seemed ‘odd’ to me. Also the other reason was that even under heavy load ‘ejinfo’ would always show ‘tx queue length’ 0. The load was generated using !Sunfish and copying a large file to a NFS mount. This could easily be an issue with !Sunfish and not the EtherUSB module. I could not login on the ROOL site to reply to your message. So that is why it took so long to reply. Sorry. Jan Rinze. |
W P Blatchley (147) 247 posts |
Hi, Uwe. My interest in EtherUSB is really just to understand more about Ethernet drivers. I’m hoping to avoid anything to do with USB at this point, as my feeble understanding of Ethernet itself is quite enough to slow me down! However, by all means get in touch (willblatchley AT yahoo DOT com). |
W P Blatchley (147) 247 posts |
Of course, code for HAL devices just sits inside the 64k (?) of HAL ‘space’ in the ROM image, right? Silly me. But how is new code added into the build system. What resides where within the HAL?
In terms of HAL/OS implementation, I was imagining a generic RISC OS module that handled all the most common Ethernet communication in a completely non-specific way, and the HAL-side device would do all the abstraction. Probably providing a flag word of ‘features’ that the particular NIC it was written for offered (10baseT, 100baseT, etc.). I haven’t understood the rationale behind the two-fold HAL device approach above. Is it just to overcome the problems of data transfer really? Sorry to be slow!
I like stories with morals almost as much as I like verbose answers ;) Thanks! |
James Peacock (318) 129 posts |
No worries, I was just curious. If you want to see the queue in action comment out the callback for attempt transmit in net.c. |
Jeffrey Lee (213) 6048 posts |
Yes and no :) It’s true that all the HAL devices that have been implemented so far have had their code placed within the 64k HAL space. But as you can see both the HAL and RISC OS are able to register devices, so there’s no reason why a HAL device (and its implementation) couldn’t be provided as a standard RISC OS module. This is how option 2 would have worked – with the simple “here is an NIC” HAL device within the HAL, and a more complex HAL device in a module that implements the bulk of the NIC driver and allows the EtherHAL module to interact with it in a generic manner.
To add a new component (i.e. a module) you’d need to add an entry to BuildSys.ModuleDB to give the build system some basic information about it (i.e. where the source code is!). Then you’d add its name to the right components file for the product that you’re interested in (i.e. the OMAP3 ROM - although the products files also cover other stuff like the “disc” product for the HardDisc4 image). On the other hand, if you’re just interested in adding new source files to an existing component, all you’d need to do is track down its source folder, add the files, and update the makefile.
Here’s a “brief” rundown of the different source files in the OMAP3 HAL:
1 At the moment there’s no defined way for the HAL to generate some data, call RISCOS_Init, and then access that data once RISC OS has initialised (i.e. when HAL_Init gets called). Which means that (unless I was to add that functionality) the easiest way of getting the HAL to remember what board config is in use is if it gets copied into the 64K of SRAM, which RISC OS currently has no knowledge of and thus doesn’t touch. HAL_Init actually copies the data back out of SRAM and into the HAL workspace pointed to by the sb register – this makes it slightly easier for the HAL to get at the data, since all the HAL entry points get called with sb pointing at the HAL workspace. 2 board.s is included directly mainly just to make sure it’s kept within range of ADR. It also makes it slightly easier to check that the ROM entry point table contains the right number of entries. 3 The OMAP HAL was based around a stripped down version of the Iyonix (aka Tungsten) HAL, which contains the ROM entry point & RAM initialisation code within the first 8K of ROM, along with code which performs a checksum of the ROM image. If the checksum fails it flashes the floppy light and allows a new ROM image to be uploaded & programmed via the serial port. The recovery code (and I assume the official flash programmer) avoids overwriting the first 8K of flash, so this code (in theory) makes an Iyonix unbrickable. So although it’s now clear that this recovery code is unlikely to be needed by the OMAP ROM, some remnants of its existence still remain. There are a few reasons behind using option 2 (or option 4) over option 1. It all comes down to the advantages of implementing the driver as a module as opposed to within the HAL:
|
W P Blatchley (147) 247 posts |
Jeffrey, you’re a star. Thanks so much for taking the time to spell all this out. It’s actually starting to make some kind of sense to me! I can’t believe you figured most of this stuff out yourself from the sources, and I can’t believe you have time to do as much coding as you do AND keep the forums and wiki going! Speaking of which, I think the above post would be really valuable information to add to the wiki. I’ve got a lot to be thinking about for now. I’m sure to have more questions before long, but for now, I’ll leave you in peace. Thanks again. |
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ... 20