Path: blob/master/arch/cris/arch-v32/kernel/kgdb_asm.S
15125 views
/*1* Copyright (C) 2004 Axis Communications AB2*3* Code for handling break 8, hardware breakpoint, single step, and serial4* port exceptions for kernel debugging purposes.5*/67#include <hwregs/intr_vect.h>89;; Exported functions.10.globl kgdb_handle_exception1112kgdb_handle_exception:1314;; Create a register image of the caller.15;;16;; First of all, save the ACR on the stack since we need it for address calculations.17;; We put it into the register struct later.1819subq 4, $sp20move.d $acr, [$sp]2122;; Now we are free to use ACR all we want.23;; If we were running this handler with interrupts on, we would have to be careful24;; to save and restore CCS manually, but since we aren't we treat it like every other25;; register.2627move.d reg, $acr28move.d $r0, [$acr] ; Save R0 (start of register struct)29addq 4, $acr30move.d $r1, [$acr] ; Save R131addq 4, $acr32move.d $r2, [$acr] ; Save R233addq 4, $acr34move.d $r3, [$acr] ; Save R335addq 4, $acr36move.d $r4, [$acr] ; Save R437addq 4, $acr38move.d $r5, [$acr] ; Save R539addq 4, $acr40move.d $r6, [$acr] ; Save R641addq 4, $acr42move.d $r7, [$acr] ; Save R743addq 4, $acr44move.d $r8, [$acr] ; Save R845addq 4, $acr46move.d $r9, [$acr] ; Save R947addq 4, $acr48move.d $r10, [$acr] ; Save R1049addq 4, $acr50move.d $r11, [$acr] ; Save R1151addq 4, $acr52move.d $r12, [$acr] ; Save R1253addq 4, $acr54move.d $r13, [$acr] ; Save R1355addq 4, $acr56move.d $sp, [$acr] ; Save SP (R14)57addq 4, $acr5859;; The ACR register is already saved on the stack, so pop it from there.60move.d [$sp],$r061move.d $r0, [$acr]62addq 4, $acr6364move $bz, [$acr]65addq 1, $acr66move $vr, [$acr]67addq 1, $acr68move $pid, [$acr]69addq 4, $acr70move $srs, [$acr]71addq 1, $acr72move $wz, [$acr]73addq 2, $acr74move $exs, [$acr]75addq 4, $acr76move $eda, [$acr]77addq 4, $acr78move $mof, [$acr]79addq 4, $acr80move $dz, [$acr]81addq 4, $acr82move $ebp, [$acr]83addq 4, $acr84move $erp, [$acr]85addq 4, $acr86move $srp, [$acr]87addq 4, $acr88move $nrp, [$acr]89addq 4, $acr90move $ccs, [$acr]91addq 4, $acr92move $usp, [$acr]93addq 4, $acr94move $spc, [$acr]95addq 4, $acr9697;; Skip the pseudo-PC.98addq 4, $acr99100;; Save the support registers in bank 0 - 3.101clear.d $r1 ; Bank counter102move.d sreg, $acr103104;; Bank 0105move $r1, $srs106nop107nop108nop109move $s0, $r0110move.d $r0, [$acr]111addq 4, $acr112move $s1, $r0113move.d $r0, [$acr]114addq 4, $acr115move $s2, $r0116move.d $r0, [$acr]117addq 4, $acr118move $s3, $r0119move.d $r0, [$acr]120addq 4, $acr121move $s4, $r0122move.d $r0, [$acr]123addq 4, $acr124move $s5, $r0125move.d $r0, [$acr]126addq 4, $acr127move $s6, $r0128move.d $r0, [$acr]129addq 4, $acr130move $s7, $r0131move.d $r0, [$acr]132addq 4, $acr133move $s8, $r0134move.d $r0, [$acr]135addq 4, $acr136move $s9, $r0137move.d $r0, [$acr]138addq 4, $acr139move $s10, $r0140move.d $r0, [$acr]141addq 4, $acr142move $s11, $r0143move.d $r0, [$acr]144addq 4, $acr145move $s12, $r0146move.d $r0, [$acr]147addq 4, $acr148149;; Nothing in S13 - S15, bank 0150clear.d [$acr]151addq 4, $acr152clear.d [$acr]153addq 4, $acr154clear.d [$acr]155addq 4, $acr156157;; Bank 1 and bank 2 have the same layout, hence the loop.158addq 1, $r11591:160move $r1, $srs161nop162nop163nop164move $s0, $r0165move.d $r0, [$acr]166addq 4, $acr167move $s1, $r0168move.d $r0, [$acr]169addq 4, $acr170move $s2, $r0171move.d $r0, [$acr]172addq 4, $acr173move $s3, $r0174move.d $r0, [$acr]175addq 4, $acr176move $s4, $r0177move.d $r0, [$acr]178addq 4, $acr179move $s5, $r0180move.d $r0, [$acr]181addq 4, $acr182move $s6, $r0183move.d $r0, [$acr]184addq 4, $acr185186;; Nothing in S7 - S15, bank 1 and 2187clear.d [$acr]188addq 4, $acr189clear.d [$acr]190addq 4, $acr191clear.d [$acr]192addq 4, $acr193clear.d [$acr]194addq 4, $acr195clear.d [$acr]196addq 4, $acr197clear.d [$acr]198addq 4, $acr199clear.d [$acr]200addq 4, $acr201clear.d [$acr]202addq 4, $acr203clear.d [$acr]204addq 4, $acr205206addq 1, $r1207cmpq 3, $r1208bne 1b209nop210211;; Bank 3212move $r1, $srs213nop214nop215nop216move $s0, $r0217move.d $r0, [$acr]218addq 4, $acr219move $s1, $r0220move.d $r0, [$acr]221addq 4, $acr222move $s2, $r0223move.d $r0, [$acr]224addq 4, $acr225move $s3, $r0226move.d $r0, [$acr]227addq 4, $acr228move $s4, $r0229move.d $r0, [$acr]230addq 4, $acr231move $s5, $r0232move.d $r0, [$acr]233addq 4, $acr234move $s6, $r0235move.d $r0, [$acr]236addq 4, $acr237move $s7, $r0238move.d $r0, [$acr]239addq 4, $acr240move $s8, $r0241move.d $r0, [$acr]242addq 4, $acr243move $s9, $r0244move.d $r0, [$acr]245addq 4, $acr246move $s10, $r0247move.d $r0, [$acr]248addq 4, $acr249move $s11, $r0250move.d $r0, [$acr]251addq 4, $acr252move $s12, $r0253move.d $r0, [$acr]254addq 4, $acr255move $s13, $r0256move.d $r0, [$acr]257addq 4, $acr258move $s14, $r0259move.d $r0, [$acr]260addq 4, $acr261;; Nothing in S15, bank 3262clear.d [$acr]263addq 4, $acr264265;; Check what got us here: get IDX field of EXS.266move $exs, $r10267and.d 0xff00, $r10268lsrq 8, $r10269#if defined(CONFIG_ETRAX_KGDB_PORT0)270cmp.d SER0_INTR_VECT, $r10 ; IRQ for serial port 0271beq sigint272nop273#elif defined(CONFIG_ETRAX_KGDB_PORT1)274cmp.d SER1_INTR_VECT, $r10 ; IRQ for serial port 1275beq sigint276nop277#elif defined(CONFIG_ETRAX_KGDB_PORT2)278cmp.d SER2_INTR_VECT, $r10 ; IRQ for serial port 2279beq sigint280nop281#elif defined(CONFIG_ETRAX_KGDB_PORT3)282cmp.d SER3_INTR_VECT, $r10 ; IRQ for serial port 3283beq sigint284nop285#endif286;; Multiple interrupt must be due to serial break.287cmp.d 0x30, $r10 ; Multiple interrupt288beq sigint289nop290;; Neither of those? Then it's a sigtrap.291ba handle_comm292moveq 5, $r10 ; Set SIGTRAP (delay slot)293294sigint:295;; Serial interrupt; get character296jsr getDebugChar297nop ; Delay slot298cmp.b 3, $r10 ; \003 (Ctrl-C)?299bne return ; No, get out of here300nop301moveq 2, $r10 ; Set SIGINT302303;;304;; Handle the communication305;;306handle_comm:307move.d internal_stack+1020, $sp ; Use the internal stack which grows upwards308jsr handle_exception ; Interactive routine309nop310311;;312;; Return to the caller313;;314return:315316;; First of all, write the support registers.317clear.d $r1 ; Bank counter318move.d sreg, $acr319320;; Bank 0321move $r1, $srs322nop323nop324nop325move.d [$acr], $r0326move $r0, $s0327addq 4, $acr328move.d [$acr], $r0329move $r0, $s1330addq 4, $acr331move.d [$acr], $r0332move $r0, $s2333addq 4, $acr334move.d [$acr], $r0335move $r0, $s3336addq 4, $acr337move.d [$acr], $r0338move $r0, $s4339addq 4, $acr340move.d [$acr], $r0341move $r0, $s5342addq 4, $acr343344;; Nothing in S6 - S7, bank 0.345addq 4, $acr346addq 4, $acr347348move.d [$acr], $r0349move $r0, $s8350addq 4, $acr351move.d [$acr], $r0352move $r0, $s9353addq 4, $acr354move.d [$acr], $r0355move $r0, $s10356addq 4, $acr357move.d [$acr], $r0358move $r0, $s11359addq 4, $acr360move.d [$acr], $r0361move $r0, $s12362addq 4, $acr363364;; Nothing in S13 - S15, bank 0365addq 4, $acr366addq 4, $acr367addq 4, $acr368369;; Bank 1 and bank 2 have the same layout, hence the loop.370addq 1, $r13712:372move $r1, $srs373nop374nop375nop376move.d [$acr], $r0377move $r0, $s0378addq 4, $acr379move.d [$acr], $r0380move $r0, $s1381addq 4, $acr382move.d [$acr], $r0383move $r0, $s2384addq 4, $acr385386;; S3 (MM_CAUSE) is read-only.387addq 4, $acr388389move.d [$acr], $r0390move $r0, $s4391addq 4, $acr392393;; FIXME: Actually write S5/S6? (Affects MM_CAUSE.)394addq 4, $acr395addq 4, $acr396397;; Nothing in S7 - S15, bank 1 and 2398addq 4, $acr399addq 4, $acr400addq 4, $acr401addq 4, $acr402addq 4, $acr403addq 4, $acr404addq 4, $acr405addq 4, $acr406addq 4, $acr407408addq 1, $r1409cmpq 3, $r1410bne 2b411nop412413;; Bank 3414move $r1, $srs415nop416nop417nop418move.d [$acr], $r0419move $r0, $s0420addq 4, $acr421move.d [$acr], $r0422move $r0, $s1423addq 4, $acr424move.d [$acr], $r0425move $r0, $s2426addq 4, $acr427move.d [$acr], $r0428move $r0, $s3429addq 4, $acr430move.d [$acr], $r0431move $r0, $s4432addq 4, $acr433move.d [$acr], $r0434move $r0, $s5435addq 4, $acr436move.d [$acr], $r0437move $r0, $s6438addq 4, $acr439move.d [$acr], $r0440move $r0, $s7441addq 4, $acr442move.d [$acr], $r0443move $r0, $s8444addq 4, $acr445move.d [$acr], $r0446move $r0, $s9447addq 4, $acr448move.d [$acr], $r0449move $r0, $s10450addq 4, $acr451move.d [$acr], $r0452move $r0, $s11453addq 4, $acr454move.d [$acr], $r0455move $r0, $s12456addq 4, $acr457move.d [$acr], $r0458move $r0, $s13459addq 4, $acr460move.d [$acr], $r0461move $r0, $s14462addq 4, $acr463464;; Nothing in S15, bank 3465addq 4, $acr466467;; Now, move on to the regular register restoration process.468469move.d reg, $acr ; Reset ACR to point at the beginning of the register image470move.d [$acr], $r0 ; Restore R0471addq 4, $acr472move.d [$acr], $r1 ; Restore R1473addq 4, $acr474move.d [$acr], $r2 ; Restore R2475addq 4, $acr476move.d [$acr], $r3 ; Restore R3477addq 4, $acr478move.d [$acr], $r4 ; Restore R4479addq 4, $acr480move.d [$acr], $r5 ; Restore R5481addq 4, $acr482move.d [$acr], $r6 ; Restore R6483addq 4, $acr484move.d [$acr], $r7 ; Restore R7485addq 4, $acr486move.d [$acr], $r8 ; Restore R8487addq 4, $acr488move.d [$acr], $r9 ; Restore R9489addq 4, $acr490move.d [$acr], $r10 ; Restore R10491addq 4, $acr492move.d [$acr], $r11 ; Restore R11493addq 4, $acr494move.d [$acr], $r12 ; Restore R12495addq 4, $acr496move.d [$acr], $r13 ; Restore R13497498;;499;; We restore all registers, even though some of them probably haven't changed.500;;501502addq 4, $acr503move.d [$acr], $sp ; Restore SP (R14)504505;; ACR cannot be restored just yet.506addq 8, $acr507508;; Skip BZ, VR.509addq 2, $acr510511move [$acr], $pid ; Restore PID512addq 4, $acr513move [$acr], $srs ; Restore SRS514nop515nop516nop517addq 1, $acr518519;; Skip WZ.520addq 2, $acr521522move [$acr], $exs ; Restore EXS.523addq 4, $acr524move [$acr], $eda ; Restore EDA.525addq 4, $acr526move [$acr], $mof ; Restore MOF.527528;; Skip DZ.529addq 8, $acr530531move [$acr], $ebp ; Restore EBP.532addq 4, $acr533move [$acr], $erp ; Restore ERP.534addq 4, $acr535move [$acr], $srp ; Restore SRP.536addq 4, $acr537move [$acr], $nrp ; Restore NRP.538addq 4, $acr539move [$acr], $ccs ; Restore CCS like an ordinary register.540addq 4, $acr541move [$acr], $usp ; Restore USP542addq 4, $acr543move [$acr], $spc ; Restore SPC544; No restoration of pseudo-PC of course.545546move.d reg, $acr ; Reset ACR to point at the beginning of the register image547add.d 15*4, $acr548move.d [$acr], $acr ; Finally, restore ACR.549rete ; Same as jump ERP550rfe ; Shifts CCS551552553