Simon-Willcocks / RISC-OS-Kernel-in-C

A multiprocessing RISC OS kernel in C
Apache License 2.0
17 stars 2 forks source link

GSTrans implementation isn't compatible with original, yet. #13

Open Simon-Willcocks opened 2 years ago

Simon-Willcocks commented 2 years ago

I thought I could convince the original code to do the work for me, but it requires workspace at 0xfaff0000+, and simply providing zeroed memory at that address doesn't allow it to work (see below).

Simple tests show that GSTrans will, given sufficient buffer space:

Return the exact length of the resultant string in R2, but also set the following byte (R1?R2) to '\0'.

Without sufficient buffer space:

Leaves the value of R2 unchanged (the size of the buffer) and update each of those bytes, without writing a terminator character.

I think it's better to work on the C implementation than more tightly couple the ROM to the C kernel.

Notes on calling the ROM code direct: I get a prefetch abort at 0xfb00004. Some code, a branch at fc020734 is jumping out of the ROM, to faff3360.

fc020734: eabf4b09 b faff3360

// GSInit, from Kernel/s/Arthur2 can be found using 'push>[^\n]\n[^\n]ldrb\tr1, [r0], #1[^\n]\n[^\n]cmp' // fc0206c4 // GSRead, 'bne>[^\n]\n[^\n]ldrb\tr1, [r0], #1[^\n]\n[^\n]cmp' (then look back to the cpsie before the bic // fc02073c // GSTrans, the following 'bic\tlr, lr, #.*0x20000000' // fc020a50

// They access memory around faff3364, as do a number of modules. // See hack in ./memory/simple/memory_manager.c // Kernel/Docs/HAL/Notes has a memory map: / 00000000 16K Kernel workspace 00004000 16K Scratch space 00008000 Mem-32K Application memory 0xxxxxxx 3840M-Mem Dynamic areas F0000000 160M I/O space (growing downwards if necessary) FA000000 1M HAL workspace FA100000 8K IRQ stack FA200000 32K SVC stack FA300000 8K ABT stack FA400000 8K UND stack FAE00000 1M Reserved for physical memory accesses FAF00000 256k reserved for DCache cleaner address space (eg. StrongARM) FAF40000 64k kernel buffers (for long command lines, size defined by KbuffsMaxSize) FAFE8000 32K HAL workspace FAFF0000 32K "Cursor/System/Sound" block (probably becoming just "System") FAFF8000 32K "Nowhere" FB000000 4M L2PT FB400000 16K L1PT FB404000 4M-16K System heap FB800000 8M Soft CAM FC000000 64M ROM /

static bool do_OS_GSInit( svc_registers *regs ) { return run_risos_code( regs, 0xfc0206c4 ); } etc.

Simon-Willcocks commented 2 years ago

Further investigation finds that that address is SLVK, the address that modules and kernel components jump to to return from a SWI. (And also the value returned from ReadSysVal 6, 27.) It looks to be there in order to cope with 26-bit modules.

There are a few words at fc0100a8 that come from Kernel/s/Kernel.

Search rom.dump for "orr\tlr, lr, #268435456[^\n]\n[^\n]orrvs\tlr, lr, #268435456"

Since we'll need that for every ROM module SWI (and possibly soft-loaded ones as well), I'll go for the hack, instead, until I start modifying the RO code (which should simply be a macro change.

I'll have to modify run_swi_handler_code, lr on entry is not the return address, it's the caller's flags. The return address, as I'll implement it, is on the stack.

Simon-Willcocks commented 2 years ago

OK, next problem. Calling the GSTRANS... routines from the kernel using the magic numbers works fine until there's a variable that needs to be expanded. The legacy code uses the variable management routines directly. i.e. GSREAD_AngledThingAintNumber uses VarFindIt instead of SVC OS_ReadVarVal. Not unreasonable, that's what I want to do... Looks like I'm back to re-implementing the code in C, but at least legacy SWIs can return properly now.

Simon-Willcocks commented 2 years ago

I've gone with letting the legacy code deal with this area again, but that uses memory at or around 0xfa600000. I've fed the kernel another MiB of memory to keep it happy, but that's not a long-term solution.