Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to have a full KhiCAS port fails to boot #89

Open
parisseb opened this issue Dec 1, 2022 · 7 comments
Open

Trying to have a full KhiCAS port fails to boot #89

parisseb opened this issue Dec 1, 2022 · 7 comments

Comments

@parisseb
Copy link
Contributor

parisseb commented Dec 1, 2022

My attempt to have a full port of KhiCAS in ExistOS is currently failing.

I get a system size a little less than 6M. This requires modifying OSLoader/Config/SystemConfig.h (VM_ROM). The qemu emulator must also be recompiled with 6M in
hw/arm/existvm.c
#define SYSROM_BASE (0x00100000)
#define SYSROM_SIZE (6 * 1048576)

Boot currently fails on the calculator when OSLoader starts System at the end of OSLoader/start.c/System(void *par). I do not know why. I tried to add in System/init.c/_init() after r13 is set
if (1){
api_vram_initialize(0x02000000);
api_vram_clear(255);
// api_vram_put_string(0,0,"System/init.c",0,255,16);
Sleep(2000);
}
but the calculator screen is not cleared.
None of my failure hypothesis are convincing: incomplete flash by the updater? Too small delay in OSLoader/start.c/System()? Something failing in the virtual memory manager for 6M instead of 4M of ROM (but I could not see anything obvious) ?

Here is my understanding of how the 39gii boot works.

RAM is only 512K, the flash is not mapped in memory. Physical memory is accessed directly only by osloader code and tasks from osloader. Memory is virtualized in 3 areas: VM_ROM (system ROM), VM_RAM (virtual RAM) and VM_SYS_ROM (for Casio-like addins).

Flash 128M is divided in blocks of 128K each, each block in 64 sectors of 2K each. OSLoader is flashed at block 22 (sector 2264=1408), System is flashed at block 31 (sector 3164=1984). These parameters are the default values in the Updater. I don't know where block 22 is specified, probably in a first bootloader code that is not part of ExistOS and is also responsible for flashing if one presses ON during boot.

Virtual memory manager handles page of size 1K (tiny config) or 4K. The swapdisk is at block 160, size 4096 sectors (size 8M).

OSLoader boot starts at
OSLoader/boot.c
_init()
_boot() (set stacks)
OSLoader/start.c:
_startup()
create tasks vTask1, vMTDSvc, vFLTSvc, vDispSvc, TaskUSBLog, vTaskTinyUSB, vVMMgrSvc, vKeysSvc, vLLAPISvc, LLIRQ_task, System, vBatteryMon, vMainThread
run vTaskStartScheduler (FreeRTOS)
System :
bootAddr=VM_ROM_BASE, VM_ROM_BASE and next 32 bit integers are used to determine if System is present),
wait a small delay (100ms, virtual memory manager must be ready!),
check for ON-F2 (USB MSC mode) and ON-F3 (force No System)
bootAddr += 0x10 (4*sizeof(int))
the code sets r2=atagsAddr = VM_ROM_BASE + (4234 - 1984) * 2048 ?? (1984 is the system page,but what is 4234?). Anyway r2 value seems not to be used.
sets r13 (related to stack pointer) at 0x023fa000 (that's near the end of 4M of ram size), sets r0 at 0, sets r1 at 0x02323000 (??). This value is perhaps only used once, at the begin of init() during the call to set_r13, if not inlined by the compiler.
then set pc to bootAddr value, that's
System/init.c in init()
will set r13 to normal stack addr (overwrites previous value of r13 and r0), set bss to 0 and initialize data (__data_start .. __data_end -> __init_data), calls constructors, then calls
System/main.c main()

I can't see why the calc boots with a 4M system while it does not with a 6M system.

@parisseb
Copy link
Contributor Author

parisseb commented Dec 2, 2022

I made some progress understanding what happens.
The set_r13 function is declared naked in System/init.c. This is wrong because it seems that it does in fact not return... According to ghidra on the ExistOS.sys binary, it is followed by constructors calls, and they are done before initialization of bss/data. This does not crash with the stripped version of KhiCAS that is used in System because this version of KhiCAS does not have constructors calls.

I can now boot if I used code like in OSLoader/start.c
__asm volatile("mov r13,#0x02200000");
__asm volatile("add r13,#0x000FA000");
This is not quite correct because it should use NORMAL_STACK_ADDR but I don't know how to enter this value in the r13 register.

Note that the stack configuration in System/Config/Sysconf.h is wrong, I mean it does not reserve enough room for the normal stack, 400 bytes is much too small, KhiCAS requires at least 16K, 24 is probably safer, this is not really a constraint since RAM is virtual. It should instead use something like:
#define IRQ_STACK_ADDR (RAM_BASE + RAM_SIZE - 8) #define SWI_STACK_ADDR (IRQ_STACK_ADDR - 100 * 4) #define NORMAL_STACK_ADDR (SWI_STACK_ADDR - 100 * 4) #define KERNEL_HEAP_END (NORMAL_STACK_ADDR - 1024*24)

@Repeerc
Copy link
Collaborator

Repeerc commented Dec 3, 2022

In fact, the stack of KhiCAS is located in the heap. KhiCAS thread startup by xTaskCreate function and the third parameter of this function is the stack size (in words (4-byte units)). For IRQ_STACK_ADDR SWI_STACK_ADDR and NORMAL_STACK_ADDR , these stacks are mainly used for scheduling purposes by the RTOS.

In OSLoader/start.c:

__asm volatile("mov r13,#0x02200000");
__asm volatile("add r13,#0x000FA000");

just for setting up a temporary stacks. If set_r13 is working properly, it seems to be possible not to write these two lines....

I committed the latest code to move the three stacks to the ld script, redesigned memory layout and removed some heavy components.

@parisseb
Copy link
Contributor Author

parisseb commented Dec 3, 2022

set_r13 does not work properly as explained before, because the compiler insert the asm code inside another function (this is expected with -Os compile flag), here it's the C++ constructor call. The asm code to set r13 must be inlined,

@parisseb
Copy link
Contributor Author

parisseb commented Dec 3, 2022

I tested the latest release on the hardware. It boots and the new start screen seems much more like a calculator. Unfortunately the integrate benchmark is much slower now (4s).

I could not run the latest release from emulator.
set tmr irq Add serial. Set PC:00000000 Booting... test1 16:03:57 set irq stack:02009f40 set irq vector:0010027c set svc stack:02009a40 set svc vector:00100398 ERROR! Unhandle swi:0000ee64 ===================SYSTEM ERROR================== Fault address:00000000 FSR:00000000 Unknown ERROR! CPSR:000001d0 R0 = 02009f2c R1 = 02009f28 R2 = 00f5d29a R3 = 82f5d29a R4 = 020040a4 R5 = 00100278 R6 = 00000000 R7 = 00000000 R8 = 00000000 R9 = 00000000 R10 = 00000000 R11 = 00000000 R12 = 00000060 R13 = 02009f20 R14 = 0011ee0c R15 = 00105b8c CUR_MODE: USER_MODE ================================================= Rebooting...

@Repeerc
Copy link
Collaborator

Repeerc commented Dec 3, 2022

Oh... I forgot to turn on the CPU cache...
OSLoader\Config\SystemConfig.h: line 118 and 119

I split the CACHEPAGE into two parts in order to achieve the compression function, the original configuration is automatically mixed.

Configurations like this can reduce the elapsed time to 1 second.It seems that the cache size of VROM has a greater impact on the running speed.

#define NUM_CACHEPAGE_VROM             ( 128 )  
#define NUM_CACHEPAGE_VRAM             ( 64 ) 
#define ZRAM_SIZE                      ( 96 * 1024 )
#define ZRAM_COMPRESSED_SIZE           ( 320 * 1024 )

@Repeerc
Copy link
Collaborator

Repeerc commented Dec 3, 2022

The simulator needs to be updated with OSLoader, I have uploaded the latest version (VROM has been configured to 6MB).
https://github.com/ExistOS-Team/ExistOS-Emulator/releases/tag/Latest-2.2

The source code needs to be compiled in MingW32 environment, the UI is written in VB, after I have time I will rewrite a new one...

@parisseb
Copy link
Contributor Author

parisseb commented Dec 3, 2022

Could you insert in OSLoader/start.c
if ((k == KEY_F3 && kp) || ((*bootAddr != 0xEF5AE0EF) && *(bootAddr + 1) != 0xFECDAFDE)) {
so that recovering from a wrong System is easier (press F3 during boot).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants