UKSWIV and cmhg
Colin (478) 2433 posts |
Is it possible for cmhg to create a vector handler for UKSWIV. This requires access to R11 for the swi number and _kernel_swi_regs only store r0-r9. I don’t think it is possible but someone may know better. |
Jeffrey Lee (213) 6048 posts |
For anything with special requirements like that, I tend to create a custom pre-veneer which shuffles registers around and then calls a CMHG generic veneer. E.g. if your routine doesn’t care about R9: STMFD R13!,{R9,LR} MOV R9,R11 BL cmhg_veneer LDMFD R13!,{R9,PC} |
Richard Walker (2090) 431 posts |
I’ve been trying this out, and have a couple of issues. I have a normal C module ‘project’ (copying from the DDE’s shared makefiles example) with a couple of tweaks for CMHG headers. I stuck a file with the above ASM code into the ’s’ directory, added it to my OBJS in Makefile, and I use OSLib’s xos_claim to register my handler on module init. Problem 1: MkRam complains aout an invalid pointer type cast with my xos_claim parameter – I suspect it cannot see the code. If I run MkRam again, then it finds it OK, which makes me think it’s my bad linker setup. I looked at EtherUSB and SCSIFS for inspiration, but am not sure what I’m missing. Problem 2: When I run my module, if I return 0 (to pass on) from my C vector handler, everything carries on as normal (’SWI blah not known’). If I test for the SWI number (now in R9), and return 1 (to claim), then I get an abort on data transfer at &00004. I suspect I’m missing something important here in the way to set up and use a handler for UKSWIV. I have a handler for UpCallV which works absolutely fine. I’ll try and copy some code in here later – my Pi isn’t on at the moment. |
Colin (478) 2433 posts |
This worked for me recently. I used it to enable swis during module finalisation.
C file.
ObjAsm file
|
Richard Walker (2090) 431 posts |
So I added this (ukswiv) to my Makefile: OBJS = ${COMPONENT} ukswiv In my ’s’ directory, I placed a file called ‘ukswiv’ which looks like this: AREA |C$$Code|,CODE,PIC,READONLY EXPORT ukswiv_pre_hook IMPORT ukswiv_hook ukswiv_pre_hook STMFD R13!,{R9,LR} MOV R9,R11 BL ukswiv_hook LDMFD R13!,{R9,PC} END I wasn’t sure about the stuff in the ASM header – maybe I’ve wrote nonsense there. CMHG header: vector-handlers: ukswiv_hook/ukswiv_hook_handler My C code: extern void ukswiv_pre_hook(void*); // snip error = xos_claim(UKSWIV, &ukswiv_pre_hook, pw); // snip int ukswiv_hook_handler(_kernel_swi_regs *r, void *pw); // if I return 1 (passion) it os ok, but 0 (claim) crashes It’s the xos_claim line which struggles on the first build attempt (it doesn’t seem to understand the type of ukswiv_pre_hook – presumably can’t find it?) If I return 0 (claim) from the ukswiv_hook_handler, then I get the ‘abort on data transfer’ error. Returning 1 (pass on) is fine. |
Richard Walker (2090) 431 posts |
Ah-ha. I’ve just spotted your reply, Colin. I was delayed due to an urgent requirement for sledging (!) and then the forum started going slow. I shall look again, thanks. Seems like the key differences between our code are: 1. You pass the ‘pre-veneer’ straight into the os_claim, whereas I used the address operator – I’m sure I tried without, though, and it didn’t work. I’ll give it a blast later, thanks. Hopefully I can then progress to the next problem. :) |
Richard Walker (2090) 431 posts |
Works nicely, thanks Colin. I also had a redundant extern in my C code, which is now gone. My odd pointer casting problem went away when I explicitly casted the pre-veneer to asm_routine. |
Colin (478) 2433 posts |
Just in case you are just modifying your own code, you can’t use a vector-handler if your unknown swi returns errors. The reason the vector-handler crashed when you claimed it is that it uses the top of the stack to find the return address when you claim and because of the preveneer the top of the stack doesn’t contain the return address. If asm_routine is
to avoid the need to cast
It should do
is the same as
|
Richard Walker (2090) 431 posts |
That makes sense. I had updated my code to follow your pattern of using a generic veneer, and it’s working reasonably well. If I do: SYS &123 TO r0% (123 isn’t the number, but the code isn’t in front of me now!) from BASIC, then I get the expected response in r0%. However… if I do: SYS "ChunkName_SWIName" TO r0% Then I get the highly-predictable, ‘SWI name not known’ error. Of course – at no point have I wired this up. But how would I? (assuming the SWI is outside my own module’s chunk) It looks like OS_NumberFromString is the key SWI, but I cannot see how to add a random entry to its list. The only other thing I could see was replacing the SWI vector, but that seems to be advised against. |
Rick Murray (539) 13850 posts |
I think the safest thing to do is create your own SWIs. Once known to the OS, they’ll be available. |
Richard Walker (2090) 431 posts |
Yeah, I will be honest and admit to hoping to avoid that. I was aiming for totally dynamic replacement of a couple of SWIs. Maybe it’s the only way? Fair enough. I shall have a bash at creating two more modules. Makes the UKSWIV seem a tad silly… |
Colin (478) 2433 posts |
I think OS_SWINumberToString and OS_SWINumberFromString should call the UKSWIV (ie pretend to be an unknown swi) if they can’t find the swi string or number. That way your UKSWIV handler can handle finding swi names and numbers. |
Richard Walker (2090) 431 posts |
I shall try and investigate UKSWIV a bit more, as that would be helpful. From glancing over the source for those SWIs, I don’t see any pointers. https://github.com/TimothyEBaldwin/RISC_OS_Dev/blob/815ce45918997c06295bbf698803125f249fff30/castle/RiscOS/Sources/Kernel/s/SWINaming |
nemo (145) 2552 posts |
Erm, no. SWIs work with numbers. If a SWI number is between 0 and &1FF, the kernel deals with it. Otherwise it trawls through its module lists to find a module with the appropriate SWI base number. If that fails, it calls UKSWIV… a desperate measure that, perhaps, was intended to allow modules to be found on disc and loaded automatically. Quite separately OS_SWINumberToString and OS_SWINumberFromString use a kernel table and those module lists to convert between numbers and names, but this is a (rather extravagant) aid to the programmer (where’s OS_VectorNumberFromString, OS_FSControlNumberFromString etc) and nothing at all to do with SWI dispatch. So no. They will not be calling UKSWIV. I have a lovely little module called VectorExtend that allows any SWI to be vectored, so one could This is a weird way to do SWIs though, and rather inefficient (and SWIs aren’t famed for speed at the best of times). Make a module, or a number of modules. And remember these salient words:
|
Colin (478) 2433 posts |
I know OS_SWINumberToString and OS_SWINumberFromString don’t call UKSWIV I just think they should. There may well be better ways but there is little point in having a UKSWIV if you can’t convert to and from swi names. |
nemo (145) 2552 posts |
UKSWIV allows SWIs to be executed. OS_SWINumberFromString allows names to be resolved. These are not the same thing, and the latter can’t be forced down the former. You may well argue that there ought to be (another) vector… but vectors used to be in very short supply (eyes UserV accusingly) so far too many things got turned into Service Calls instead, when they clearly should have been a vector. This is why VectorExtend was part of the Cerilica/Millipede strategy for RISC OS 4 when we were going to buy it. |
Rick Murray (539) 13850 posts |
Uh, because in the API (mostly BASIC) the SWIs are available by both name or number? Modules define a table of SWI names and a base number… |
nemo (145) 2552 posts |
And that rebuts my point how? You can resolve SWI numbers by name. Anyway, I’m not sure this is helping Colin understand why name resolution doesn’t go down UKSWIV. |
Rick Murray (539) 13850 posts |
You can refer to SWIs by name or number (depending upon language), and the current list of SWIs changes depending upon what is loaded. When are ServiceCalls ever referred to by name in the OS? When are they likely to change and need name resolution? You can’t look up ServiceCalls because there’s no need to, a bunch of defines in a file will suffice. |
Colin (478) 2433 posts |
You are right I’ve not seen any reason why it can’t yet.
Yes and it will allow OS_SWINumberFromString to be executed when it fails with an unknown swi error. You say it can’t do this when I think you mean it shouldn’t – is that right? It looks simple enough to add to me you just |
Steve Pampling (1551) 8172 posts |
Still not helping Colin but a useful point:
Never, because you can’t resolve the a name to a number “because” Which I think is rather the point Nemo was attempting to get over. |
Richard Walker (2090) 431 posts |
Colin, I presume you are talking about a mod to the RISC OS source I posted a link to? Not some blindingly obvious thing I should have done in my module?! I think my scenario is even more complex. I want to ‘emulate’ SWIs Thing_Test (number 200) and Thing_Blah (number 600). So the module names would clash, but the chunk numbers and individual SWI names are different. Ho hum. I shall focus on another problem for a bit! |
nemo (145) 2552 posts |
Don’t confuse Module name with SWI prefix, they’re different namespaces. You can have Thing_Test implemented by module Thing and Thing_Blah implemented by module ThingSupport or whatever. See Sound_* as a concrete example. |
nemo (145) 2552 posts |
Colin asked
I understand your point. You are asserting that UKSWIV can be overloaded because OS_SWINumberFromString can never be unimplemented… if it were, your suggestion would be ambiguous. However, this argument is equivalent to suggesting that OS_File should call UKSWIV if it fails to find a file, or OS_GSTrans calls UKSWIV if it fails to understand the syntax of a string. UKSWIV exists to implement missing SWIs, not to tidy up after the failure of a SWI that is present and working correctly. Your linkage of OS_SNFS to UKSWIV is specious. There is a good argument for there being a mechanism to extend OS_SNFS (and I would prefer a vector to a service call in general, though it’s Too Late Now™) but it would have to be a new mechanism. Under RO4 that mechanism would be OS_ClaimOSSWI, the general solution is VectorExtend (which I have still not got around to releasing, sorry). I understand your suggestion, but I disagree strongly because it conflates two separate functionalities that are only linked by the acronym “SWI”. |
nemo (145) 2552 posts |
Rick mumbled while eating his own tail
In every bit of documentation ever. You are using the lack of a bit of convenience functionality to defend the lack of the convenience functionality. This is very similar to early aviators being opposed to parachutes because they didn’t already have parachutes. |