Miscellaneous HAL/kernel improvements
Jeffrey Lee (213) 6048 posts |
Here’s a bunch of little things which have been sitting on my todo list for a while: OS_ReadSysInfo 10 – Read extended machine ID In: R0=10 R1=Buffer pointer, or 0 to read size Out: R0=Machine ID length, or 0 if not present/corrupt. Machine ID written to buffer if R1 was given on entry. This new reason code will allow people to access the full 128bit OMAP machine ID. I think it’s best if the old methods of reading the machine ID (OS_ReadSysInfo 2 & 5) are deprecated and that this method is used in preference. With regards to OS_ReadSysInfo 2/5, do people think it’s worth the kernel containing code to generate a valid looking old-style machine ID from the extended ID, or should the calls just return 0? (Which is what’s currently happening on the OMAP port because the machine ID that the HAL is returning fails the CRC check that the kernel performs on the ID). Also, how do people think the kernel should get the new ID from the HAL? We could add a new HAL call, or we could update the existing HAL_MachineID call. Obviously the current call doesn’t take any parameters, so there’s no easy way of overloading its functionality in a backwards-compatible manner. Personally I’m of the opinion that the HAL API is a very private API which user software shouldn’t use (except for the APIs where there is no equivalent OS interface – like the HAL timer API). So I don’t think making a backwards-incompatible change to HAL_MachineID would be a bad thing to do. OS_Hardware 5 – Claim hardware timer In: R0=HAL timer number R8=5 (reason code) Out: Error on failure to claim, no error on success. OS_Hardware 6 – Release hardware timer In: R0=HAL timer number R8=6 (reason code) Out: Timer will be stopped, interrupts disabled/cancelled, and the timer will be released back into the free pool. OS_Hardware 7 – Enquire timer ownership state In: R0=HAL timer number R8=7 (reason code) Out: R0=0 if timer free, nonzero if claimed. These new calls provide a way for programs to claim ownership of the HAL timers, to ensure conflicts don’t occur if two programs attempt to use the same timer at once. Obviously this is an “opt-in” system, since there’s no way of stopping programs from going behind the kernel’s back and talking to the HAL directly. This API is also rather naive in that it doesn’t provide any way to guard against programs releasing timers which are owned by other programs. But in the absense of anyone offering any better ideas, this one will do. OS_IICOp The current version of OS_IICOp only allows you to access the main IIC bus. To extend the API to support multiple buses, I think the simplest option is to use the top byte of R1 to store the bus number (Currently R0 is the pointer to the list of transfers, and R1 is the number of transfers – see Kernel.s.PMF.IIC line 143). Reporting the HAL/machine type At the moment all versions of RISC OS 5 will report a platform class of 5 (HAL) for OS_ReadSysInfo 8. This isn’t particularly useful, as RISC OS 5 runs on a number of wildly different pieces of hardware (Three IOMD based machines, Iyonix, six or so OMAP3 based machines, assorted Castle/Pace/etc. devices, mini2440, and perhaps future stuff like the EFIKA MX and Netbook Pro, A9home, etc.). So I think it’s about time that we added some more detailed information. Since one HAL/ROM image can support multiple machine types, I think we should provide two pieces of information: The HAL type and the machine type. But we need to decide whether this should be done entirely via new reason codes or whether we should allow values other than 5 to be returned by OS_ReadSysInfo 8 (Presumably this would mean that OS_ReadSysInfo 8 would return the machine type, while a new call – perhaps a subreason code of OS_ReadSysInfo 9, or a new OS_Hardware call – would return the HAL type). Thoughts? |
Andrew Conroy (370) 725 posts |
OS_ReadSysInfo 10 – Read extended machine ID Personally, I’d say continue returning 0 for OS_SysReadInfo 2/5 as then this will encourage people to use the correct method for the OMAP of using the extended ID from OS_ReadSysInfo 10. I’m probably not technical enough to comment fully on your other proposed changes, but they sound perfectly sensible to me! |
W P Blatchley (147) 247 posts |
If you do that, then you won’t get the functionality in IIC_Control. I’m not sure if that’s a good or bad thing. New software could always use OS_IICOp to access the other buses, so it probably doesn’t matter – just an observation. If you put the bus number in each transfer in the list (in say word 0, at bits 16:23), you could transparently get IIC_Control support, too. But then you’d have to put the bus number in every transfer in the list, which might be tiresome. Also, it might cause tricky-to-track bugs if a bus number got left out. And I’m not sure what would happen if the bus number changed from one transfer to the next with a continued transfer (bit 31 set)! On balance, I think I agree with you that using R1 of OS_IICOp is the best option. Just thinking “out loud”! And here is an old forum discussion about this issue for reference. |
Dave Higton (281) 668 posts |
I would suggest that it should generate a valid old-style ID. Not to do so looks like a bug that could prevent client programmes from working. To be practical, though, I don’t know how many such programmes there are, either that work now or will be ported so that they work. |
Ben Avison (25) 445 posts |
AFAIK, the machine unique ID is used for two main things:
So I think we really want APIs to read both 64-bit and 128-bit UIDs in order to cater for both the above. On machines where the hardware UID is 128 bits, the old APIs will need to use some sort of hash of the true value, an although that will no longer be guaranteed unique, would probably be “good enough” for legacy software. Deprecating the old APIs is fine, but I think they should still function – the fact that they’ve been returning 0 is a result of the fact that the ports aren’t fully polished. On the sharing of timers, I’d like to see a more general API for sharing general-purpose hardware blocks between different modules. This first occurred to me in regards to the XScale’s Application Accelerator, and I proposed it to Adrian Lees when he was working on Geminus, but I don’t think it ever got implemented. The general idea was to model it on Service_ClaimFIQ(inBackground)/Service_ReleaseFIQ, since the CPU FIQ interrupt line is also modelled by RISC OS as a hardware resource that can only be used by one module at once. One thing that would have to be decided is how you identify which hardware resource it is that you’re trying to claim/release – perhaps the answer to this is to use a HAL device pointer? Your proposals for IIC look fine to me. I wouldn’t worry too much about the IIC module, it’s a bit of a legacy interface already and can remain fixed to IIC bus 0. On OS_ReadSysInfo 8, I’m not quite sure what this is trying to achieve. I’m a bit nervous about the current HAL/hardware type just being presented as a big enum, as history has shown that programmers often end up comparing them against a list of specific platforms whose attributes are known at authoring time, when they should be using a specific API to test for that attribute instead. |
Andrew Conroy (370) 725 posts |
I would suggest that it should generate a valid old-style ID. Not to do so looks like a bug that could prevent client programmes from working. Returning 0 is a valid response, and is what happens on earlier Acorn machines without the UID chip. Software should accept a value of 0. I can see a downside of all BBs returning 0 from that part of the SWI though. I believe that Photodesk uses the UID as copy protection, but that currently works ok with a value of 0 (although presumably you can then copy it to another BB and it will still work!). I guess so far the only BB specific software that uses the UID is the battery charging plug-in. |
Jeffrey Lee (213) 6048 posts |
OK, fair enough – I’ll stick some code in there to generate fake 64bit UID’s from whatever data the ‘extended’ ID provides. With regards to the HAL API - are you OK with me making a backwards-incompatible change to HAL_MachineID, or should I just add a new entry point? (The main reason that I ask is because I know that we don’t want the list of HAL entry points to keep growing and growing)
Using HAL device pointers sounds sensible to me. You’ve mentioned the FIQ claim/release service calls – so would you prefer the new claim/release APIs to be service calls or SWIs? I guess one advantage of service calls is that if the owner of the device dies unexpectedly, the device will automatically go back into the free pool. Out of the things the HAL exposes, I think the timers, UARTs and HAL devices are the ones that are in need of access controls. So do you think we should have three different variants of the API, or should we make the kernel translate the timers & UARTs into HAL devices? (Or alternatively make it so that the HAL exposes the timers/UARTs as devices itself, apart from the vital 100Hz system timer).
Understood. I was a bit hesitant about suggesting it, for that very reason. Perhaps we should focus on adding new APIs to give people legitimate ways of testing for things, and worry about OS_ReadSysInfo 8 later. The only legitimate use I can think of for reading the HAL/machine type would be for a “system information” utility – but for that use it would probably make more sense for the information to be exposed as a string via OS_ReadSysInfo 9 rather than as an enum. |
Jeffrey Lee (213) 6048 posts |
Scratch that – I’ve just spotted that the DualSerial module claims all the HAL UARTs for itself. So really it’s just the timers and the HAL devices that we need to worry about. |
Dave Higton (281) 668 posts |
Machines without an ID chip have a valid excuse for returning 0. BBs do have the functional equivalent of an ID chip, though, and they commonly have client programmes that need a valid ID, so I think the full functionality should be present. |
Andrew Conroy (370) 725 posts |
Fair enough, and it looks like Jeffrey’s going to do that anyway. |
Jeffrey Lee (213) 6048 posts |
The OS_IICOp changes are now checked in (for the Cortex branch, at least). As far as I can tell I haven’t broken anything! The next thing on my list is the machine ID interface. For the HAL side, I think I’ll just do the sensible thing and add a new HAL call rather than play with fire by modifying HAL_MachineID. |
Jeffrey Lee (213) 6048 posts |
It looks like RISC OS Select already uses reason codes 10 and 11 for OS_ReadSysInfo (see here for docs). OS_ReadSysInfo 11 should be easy enough to implement (just hook into HAL_DebugTX/HAL_DebugRX), but OS_ReadSysInfo 10 looks a bit trickier. I’m guessing that the Kernel version number is effectively just the major version number from their VersionNum file. But that approach won’t work so well for us, since srccommit won’t increment the major version number of branched components (plus we have the fact that the we’re currently using two kernel branches in parallel). So for now I think I’ll just leave OS_ReadSysInfo 10 unimplemented. |
Jeffrey Lee (213) 6048 posts |
It also looks like they’ve got their own timer reservation API, although they don’t list the SWI numbers: http://select.riscos.com/prm/hardware/timer.html Does anyone know if the Timer module actually exists, and if so, what the SWI base is? It should be pretty trivial for us to implement our own version of the module to manage the HAL timers, even if we decide to add another API layer beneath it (i.e. service call based method). Anyway, I’ve just checked in the OS_ReadSysInfo 11 implementation, and the machine ID changes:
|
Trevor Johnson (329) 1645 posts |
1024 posts, Jeffrey! |
Andreas Walter (450) 6 posts |
Does anyone know if the Timer module actually exists, and if so, what the SWI base is? In RISC OS Six the module does exist. The name of the module is “TimerManager” and that is also the SWI group prefix. The SWI base is &58B80. |
Ben Avison (25) 445 posts |
I know you later said you wouldn’t, but I wouldn’t worry about it too much – most of the HAL entry points are really a private API for the kernel (or certain other modules). The exceptions would be the interrupt, timer and counter APIs (i.e. the bits that were documented before source release began) and the HAL Device APIs (because third parties can theoretically supply drivers for additional devices). Since all the HALs that are likely to see ongoing use have now been published, it should be possible to keep things like the UID APIs in step, even if they change.
I can confirm this is the SWI base that has been registered. I hadn’t looked at ROL’s Timer API before, it’s not great is it?
|
Ben Avison (25) 445 posts |
Here’s another thought, I wonder how this fits in with Acorn’s TimeCode stuff? IIRC, it used Timer1 on IOMD. |