hoglet67 / PiTubeDirect

Bare-metal Raspberry Pi project that attaches to the Acorn TUBE interface and emulates many BBC Micro Co Processors
GNU General Public License v3.0
188 stars 23 forks source link

Native ARM: This is not a language causes hard crash on Ctrl-BREAK #205

Closed hoglet67 closed 1 year ago

hoglet67 commented 1 year ago

To reproduce:

You get this:

New Copro = 15
             cycle counter = 28910240960
              I_CACHE_MISS = 2962008
              D_CACHE_MISS = 130926
tube reset - copro 15
Raspberry Pi Direct 15 ARM Native Client
emulator speed 0
Copro Memory size 0
             cycle counter = 35703997312
              I_CACHE_MISS = 2972473
              D_CACHE_MISS = 147139
tube reset - copro 15
Undefined Instruction at A4A22FFC
Registers:
  r[00]=00000001
  r[01]=000000AA
  r[02]=00000000
  r[03]=0D973F98
  r[04]=000000AA
  r[05]=000000AA
  r[06]=AAAAAAAA
  r[07]=AAAAAAAA
  r[08]=AAAAAAAA
  r[09]=AAAAAAAA
  r[10]=AAAAAAAA
  r[11]=AAAAAAAA
  r[12]=AAAAAAAA
  r[14]=A4A23000
Memory:
  A4A22FEC=55555555
  A4A22FF0=55555555
  A4A22FF4=55555555
  A4A22FF8=55555555
  A4A22FFC=5D555555 <<<<<< 
  A4A23000=55555555
  A4A23004=55555555
  A4A23008=55555555
  A4A2300C=55555555
Flags: 
  NZCV--------------------IFTMMMMM
  00100000000000000000000100010011 (Supervisor Mode)
Halted waiting for reset
Data Abort at 0D4C3FE0
Registers:
  r[00]=00001000
  r[01]=0D974490
  r[02]=0D97448F
  r[03]=00000000
  r[04]=20000113
  r[05]=A4A23010
  r[06]=0D50FB5C
  r[07]=0D4F3AA0
  r[08]=00000000
  r[09]=0D4F3A98
  r[10]=00000005
  r[11]=00000000
  r[12]=00000000
  r[14]=0D4C3FEC
Memory:
  0D4C3FD0=EBFD37E6
  0D4C3FD4=E2001004
  0D4C3FD8=E1880501
  0D4C3FDC=EBFF0651
  0D4C3FE0=E8FD800F <<<<<< 
  0D4C3FE4=E92D5FFF
  0D4C3FE8=E1A0100D
  0D4C3FEC=E14F0000
  0D4C3FF0=E92D0009
Flags: 
  NZCV--------------------IFTMMMMM
  00000000000000000000000111010011 (Supervisor Mode)
Halted waiting for reset

This happens on Hognose but not Gecko.

Also, it only happens when first entering Co Pro 15.

hoglet67 commented 1 year ago

Here's a trace with DEBUG_ARM 1

New Copro = 15
             cycle counter = 33520808960
              I_CACHE_MISS = 3279139
              D_CACHE_MISS = 131018
tube reset - copro 15
Raspberry Pi Direct 15 ARM Native Client
emulator speed 0
Copro Memory size 0
             cycle counter = 39112425024
              I_CACHE_MISS = 3279782
              D_CACHE_MISS = 132409
tube reset - copro 15
Sending banner
Banner sent, awaiting response
Error = 0 00 This is not a language
SWI 00000002 called from 0d4764d0 cpsr=40000113
SWI 00000002 complete cpsr=60000113
SWI 00000000 called from 0d4764d8 cpsr=40000113
SWI 00000000 complete cpsr=80000113
SWI 00000000 called from 0d4764e0 cpsr=40000113
SWI 00000000 complete cpsr=60000113
SWI 00000011 called from 0d4764e4 cpsr=40000113
Calling exit handler at 0d478fb8 with r12 aaaaaaaa
Invoking default exit handler
SWI 00000016 called from 0d478fd0 cpsr=40000113
SWI 00000016 complete cpsr=20000113
Undefined Instruction at 000000F0
Registers:
Registers:
  r[00]=55555555
  r[01]=00000001
  r[02]=00000000
  r[03]=0D8C82AC
  r[04]=000000AA
  r[05]=700000AA
  r[06]=9D1E27FE
  r[07]=AAAAAA00
  r[08]=AAAAAAAA
  r[09]=AAAAAAAA
  r[10]=AAAAAAAA
  r[11]=AAAAAAAA
  r[12]=0D973018
  r[14]=000000F4
Memory:
  000000E0=00000000
  000000E4=00000000
  000000E8=00000000
  000000EC=00000000
  000000F0=F8000000 <<<<<< 
  000000F4=00000000
  000000F8=F87BF95D
  000000FC=00023700
  00000100=58FEF8AD
Flags: 
  NZCV--------------------IFTMMMMM
  00000000000000000000000100010011 (Supervisor Mode)
Halted waiting for reset

It looks like the default exit handler is crashing after SWI_OS_EnterOS (SWI 16):

// This should be called in USR mode whenever OS_Exit or OS_ExitAndDie is called.
static void defaultExitHandler() {
  if (DEBUG_ARM) {
    printf("Invoking default exit handler\r\n");
  }
  // Avoid re-entering ARM Basic
  armbasic = 0;
  // Move back to supervisor mode
  swi(SWI_OS_EnterOS);
  // Jump back to the command prompt
  longjmp(enterOS, 1);
}

I think the bug is the "This is not a language" error is received asynchronously and early in the first invocation of the reset handler, before setjmp(enterOS); has ever been called.