41#define LZ4STREAM_TRUSTED 1
43#define MON_CAPS_LZ4 MON_CAP_LZ4
50#ifdef LINK_RX_STAT_ADDR
51#define MON_CAPS_STOP MON_CAP_STOP
53#define MON_CAPS_STOP 0
56#define MON_CAPS (MON_CAPS_LZ4 | MON_CAPS_STOP)
62#define MON_CHUNK_BYTES 8192
63#define MON_CMD_WORDS 16
98#define MON_RUN_SR 0x40000404u
102static struct Registers *currentRegs(
void) {
return &
__globals.processes[0].thread->registers; }
106static inline __attribute__((noreturn))
void monitorResume(
void) {
108 if (s_mon.memWritten) {
109 s_mon.memWritten = 0;
110 syscall_flushCache();
112 syscall_returnFromException();
124#define MON_REPLIED (-1)
126static void sendStatus(
int code) {
127 uint16_t
c = (uint16_t)code;
145static void emitIdentity(uint16_t type) {
167static int cmdReadMem(
const uint16_t *p) {
170 const uint8_t *
src = (
const uint8_t *)addr;
182 uint8_t b0 =
src[bi];
183 uint8_t b1 = (2 *
i + 1 < chunk) ?
src[bi + 1] : 0;
195 return lo | (
hi << 16);
203static int streamWriteMem(uint16_t frameWords) {
204 if (frameWords < 4) {
212 uint8_t *dst = (uint8_t *)addr;
213 s_mon.memWritten = 1;
215 for (uint16_t w = consumed;
w < frameWords;
w++) {
218 if (bi < nbytes) dst[bi] = (uint8_t)(word & 0xff);
219 if (bi + 1 < nbytes) dst[bi + 1] = (uint8_t)(word >> 8);
233static int streamWriteMemLz4(uint16_t frameWords) {
235 uint32_t rawLen = 0, clen = 0, nbytes = 0;
238 s_mon.memWritten = 1;
250 s_mon.lzConsumed = 0;
252 }
else if (!s_mon.lzActive || off != s_mon.lzConsumed) {
255 if (!bad && (nbytes > words * 2 || off + nbytes > clen)) bad =
MON_EBADLEN;
262 for (
uint32_t bi = w * 2; bi < w * 2 + 2 && bi < nbytes; bi++, word >>= 8) {
268 s_mon.lzConsumed += nbytes;
269 if (s_mon.lzConsumed == clen) {
274 if (bad) s_mon.lzActive = 0;
283 static const uint8_t special[] = {
287 if (idx < 32)
return &
r->GPR.r[
idx];
288 if (idx == 35)
return &s_mon.badVaddr;
289 return (
uint32_t *)((uint8_t *)
r + special[idx - 32]);
294static int cmdGetRegs(
void) {
297 for (
unsigned i = 0;
i < 38;
i++) sendWord32((
r ||
i == 35) ? *regSlot(
r,
i) : 0);
303static int cmdSetReg(
const uint16_t *p) {
310 if (idx != 0) *regSlot(
r, idx) =
val;
316static int cmdSetBp(
const uint16_t *p) {
317 uint16_t kind = p[0];
325 }
else if (kind <= 3) {
328 s_mon.watchAddr = addr;
334 writeDCIC(s_mon.dcic);
339static int cmdClrBp(
const uint16_t *p) {
340 uint16_t kind = p[0];
342 s_mon.dcic &= ~DCIC_PCE;
347 writeDCIC(s_mon.dcic);
353static __attribute__((noreturn))
void cmdRun(
const uint16_t *p) {
373static int cmdCont(
void) {
382static int cmdSetBaud(
const uint16_t *p) {
383 uint16_t reload = p[0];
395static int dispatchCommand(uint16_t type,
const uint16_t *payload) {
422static __attribute__((noreturn))
void monitorCommandLoop(
void) {
429 uint16_t
base = type & ~MON_LZ4;
432 reply = streamWriteMem(len);
435 reply = streamWriteMemLz4(len);
443 for (uint16_t
i = 0;
i < len;
i++) {
452 reply = dispatchCommand(type, s_mon.cmd);
465 emitStopped(reason,
r->returnPC, a,
b);
466 monitorCommandLoop();
481 if ((insn & 0x3f) == 0x0d) {
486 if (insn == ((4u << 16) | (1u << 6) | 0x0d)) {
489 monitorCommandLoop();
530static int monitorVerifier(
void) {
531 monitorTake(currentRegs());
538 .verifier = monitorVerifier,
556#ifndef MONITOR_SLOT_STACK_WORDS
557#define MONITOR_SLOT_STACK_WORDS 256
561void __attribute__((used, noinline)) monitorSlotDispatch(
void) { monitorTake(currentRegs()); }
564#define MON_SLOT_EXCMASK 0x1ef0
566#define MON_STR_(x) #x
567#define MON_STR(x) MON_STR_(x)
569#ifdef LINK_RX_STAT_ADDR
570#define MON_SLOT_RX_TEST \
571 " li $v1, " MON_STR(LINK_RX_STAT_ADDR) "\n" \
572 " " LINK_RX_STAT_LOAD " $v1, 0($v1)\n" \
574 " andi $v1, $v1, " MON_STR(LINK_RX_STAT_BIT) "\n" \
578#define MON_SLOT_RX_TEST
582 " .section .text.monitorSlotEntry, \"ax\", @progbits\n"
584 " .global monitorSlotEntry\n"
585 " .type monitorSlotEntry, @function\n"
589 "monitorSlotEntry:\n"
593 " andi $v0, $v0, 0x7c\n"
597 " srlv $v1, $v1, $v0\n"
598 " andi $v1, $v1, 1\n"
609 " sw $a0, 0x10($k0)\n"
610 " sw $a1, 0x14($k0)\n"
611 " sw $a2, 0x18($k0)\n"
612 " sw $a3, 0x1c($k0)\n"
615 " sw $a0, 0x8c($k0)\n"
618 " sw $a1, 0x90($k0)\n"
619 " sw $k1, 0x6c($k0)\n"
620 " sw $s0, 0x40($k0)\n"
621 " sw $s1, 0x44($k0)\n"
622 " sw $s2, 0x48($k0)\n"
623 " sw $s3, 0x4c($k0)\n"
624 " sw $s4, 0x50($k0)\n"
625 " sw $s5, 0x54($k0)\n"
626 " sw $s6, 0x58($k0)\n"
627 " sw $s7, 0x5c($k0)\n"
628 " sw $t0, 0x20($k0)\n"
629 " sw $t1, 0x24($k0)\n"
630 " sw $t2, 0x28($k0)\n"
631 " sw $t3, 0x2c($k0)\n"
632 " sw $t4, 0x30($k0)\n"
633 " sw $t5, 0x34($k0)\n"
634 " sw $t6, 0x38($k0)\n"
635 " sw $t7, 0x3c($k0)\n"
636 " sw $t8, 0x60($k0)\n"
637 " sw $t9, 0x64($k0)\n"
638 " sw $gp, 0x70($k0)\n"
639 " sw $sp, 0x74($k0)\n"
640 " sw $fp, 0x78($k0)\n"
643 " sw $a0, 0x84($k0)\n"
646 " sw $a0, 0x88($k0)\n"
651 " jal monitorSlotDispatch\n"
655 " lw $k0, 0x108($zero)\n"
659 " addiu $k0, $k0, 8\n"
660 " lw $a0, 0x84($k0)\n"
661 " lw $a1, 0x88($k0)\n"
664 " lw $a0, 0x10($k0)\n"
665 " lw $a1, 0x14($k0)\n"
666 " lw $a2, 0x18($k0)\n"
667 " lw $a3, 0x1c($k0)\n"
668 " lw $t0, 0x20($k0)\n"
669 " lw $t1, 0x24($k0)\n"
670 " lw $t2, 0x28($k0)\n"
671 " lw $t3, 0x2c($k0)\n"
672 " lw $t4, 0x30($k0)\n"
673 " lw $t5, 0x34($k0)\n"
674 " lw $t6, 0x38($k0)\n"
675 " lw $t7, 0x3c($k0)\n"
676 " lw $t8, 0x60($k0)\n"
677 " lw $t9, 0x64($k0)\n"
678 " lw $s0, 0x40($k0)\n"
679 " lw $sp, 0x74($k0)\n"
683 " .size monitorSlotEntry, . - monitorSlotEntry\n"
__attribute__((weak))
Definition clz.c:56
#define DCIC_UD
Definition cop0dbg.h:83
#define EXCCODE_OVF
Definition cop0dbg.h:97
#define DCIC_DA
Definition cop0dbg.h:76
#define DCIC_DR
Definition cop0dbg.h:80
#define EXCCODE_ADEL
Definition cop0dbg.h:89
#define EXCCODE_DBE
Definition cop0dbg.h:92
#define EXCCODE_INT
Definition cop0dbg.h:88
#define DCIC_DE
Definition cop0dbg.h:77
#define DCIC_TR
Definition cop0dbg.h:84
#define DCIC_KD
Definition cop0dbg.h:82
#define CAUSE_EXCCODE(cause)
Definition cop0dbg.h:87
#define EXCCODE_BP
Definition cop0dbg.h:94
#define EXCCODE_ADES
Definition cop0dbg.h:90
#define DCIC_DAE
Definition cop0dbg.h:79
#define EXCCODE_IBE
Definition cop0dbg.h:91
#define DCIC_DW
Definition cop0dbg.h:81
#define EXCCODE_CPU
Definition cop0dbg.h:96
#define EXCCODE_RI
Definition cop0dbg.h:95
#define DCIC_PCE
Definition cop0dbg.h:78
int32_t hi
Definition cpu.c:154
uint32_t r
Definition cpu.c:222
int32_t lo
Definition cpu.c:154
volatile uint32_t * sp
Definition dcache.c:524
uint8_t b
Definition gte-depthcue.c:39
int i
Definition gte-regio.c:297
int psxprintf(const char *msg,...)
Definition stdio.c:332
void lz4StreamInit(struct Lz4Stream *s, void *dest)
Definition lz4stream.c:38
int lz4StreamFeed(struct Lz4Stream *s, uint8_t b)
Definition lz4stream.c:43
int lz4StreamEndBlock(struct Lz4Stream *s)
Definition lz4stream.c:106
uint16_t cmd[MON_CMD_WORDS]
Definition monitor.c:69
uint32_t * s_monitorSlot
Definition monitor.c:141
#define MON_CMD_WORDS
Definition monitor.c:63
#define MON_CHUNK_BYTES
Definition monitor.c:62
int memWritten
Definition monitor.c:81
int running
Definition monitor.c:84
uint32_t s_biosChecksum
Definition monitor.c:137
struct Registers * ctx
Definition monitor.c:73
__asm__(" .section .text.monitorSlotEntry, \"ax\", @progbits\n" " .align 2\n" " .global monitorSlotEntry\n" " .type monitorSlotEntry, @function\n" " .set push\n" " .set noreorder\n" " .set noat\n" "monitorSlotEntry:\n" " mfc0 $v0, $13\n" " nop\n" " andi $v0, $v0, 0x7c\n" " beqz $v0, 1f\n" " srl $v0, $v0, 2\n" " li $v1, " MON_STR(MON_SLOT_EXCMASK) "\n" " srlv $v1, $v1, $v0\n" " andi $v1, $v1, 1\n" " bnez $v1, 2f\n" " nop\n" " jr $ra\n" " nop\n" "1:\n" MON_SLOT_RX_TEST " jr $ra\n" " nop\n" "2:\n" " sw $a0, 0x10($k0)\n" " sw $a1, 0x14($k0)\n" " sw $a2, 0x18($k0)\n" " sw $a3, 0x1c($k0)\n" " mfc0 $a0, $12\n" " nop\n" " sw $a0, 0x8c($k0)\n" " mfc0 $a1, $13\n" " nop\n" " sw $a1, 0x90($k0)\n" " sw $k1, 0x6c($k0)\n" " sw $s0, 0x40($k0)\n" " sw $s1, 0x44($k0)\n" " sw $s2, 0x48($k0)\n" " sw $s3, 0x4c($k0)\n" " sw $s4, 0x50($k0)\n" " sw $s5, 0x54($k0)\n" " sw $s6, 0x58($k0)\n" " sw $s7, 0x5c($k0)\n" " sw $t0, 0x20($k0)\n" " sw $t1, 0x24($k0)\n" " sw $t2, 0x28($k0)\n" " sw $t3, 0x2c($k0)\n" " sw $t4, 0x30($k0)\n" " sw $t5, 0x34($k0)\n" " sw $t6, 0x38($k0)\n" " sw $t7, 0x3c($k0)\n" " sw $t8, 0x60($k0)\n" " sw $t9, 0x64($k0)\n" " sw $gp, 0x70($k0)\n" " sw $sp, 0x74($k0)\n" " sw $fp, 0x78($k0)\n" " mfhi $a0\n" " nop\n" " sw $a0, 0x84($k0)\n" " mflo $a0\n" " nop\n" " sw $a0, 0x88($k0)\n" " move $s0, $ra\n" " la $sp, monitorSlotStack + " MON_STR(MONITOR_SLOT_STACK_WORDS) " * 4 - 16\n" " jal monitorSlotDispatch\n" " nop\n" " lw $k0, 0x108($zero)\n" " move $ra, $s0\n" " lw $k0, 0($k0)\n" " nop\n" " addiu $k0, $k0, 8\n" " lw $a0, 0x84($k0)\n" " lw $a1, 0x88($k0)\n" " mthi $a0\n" " mtlo $a1\n" " lw $a0, 0x10($k0)\n" " lw $a1, 0x14($k0)\n" " lw $a2, 0x18($k0)\n" " lw $a3, 0x1c($k0)\n" " lw $t0, 0x20($k0)\n" " lw $t1, 0x24($k0)\n" " lw $t2, 0x28($k0)\n" " lw $t3, 0x2c($k0)\n" " lw $t4, 0x30($k0)\n" " lw $t5, 0x34($k0)\n" " lw $t6, 0x38($k0)\n" " lw $t7, 0x3c($k0)\n" " lw $t8, 0x60($k0)\n" " lw $t9, 0x64($k0)\n" " lw $s0, 0x40($k0)\n" " lw $sp, 0x74($k0)\n" " jr $ra\n" " nop\n" " .set pop\n" " .size monitorSlotEntry, . - monitorSlotEntry\n" " .previous\n")
struct HandlerInfo s_monitorHandler
Definition monitor.c:535
#define MON_SLOT_EXCMASK
Definition monitor.c:564
void monitorMain(void)
Definition monitor.c:686
#define MON_STR(x)
Definition monitor.c:567
uint32_t dcic
Definition monitor.c:78
#define MON_RUN_SR
Definition monitor.c:98
uint32_t badVaddr
Definition monitor.c:75
#define MON_CAPS
Definition monitor.c:56
#define MON_REPLIED
Definition monitor.c:124
uint32_t watchAddr
Definition monitor.c:79
#define MON_SLOT_RX_TEST
Definition monitor.c:578
#define MONITOR_SLOT_STACK_WORDS
Definition monitor.c:557
#define MON_READ_MEM
Definition monitor.h:38
#define MON_PROTO_VER
Definition monitor.h:95
#define MON_STOP_BREAKPOINT
Definition monitor.h:90
#define MON_STOPPED
Definition monitor.h:77
#define MON_ACK
Definition monitor.h:71
#define MON_SET_BAUD
Definition monitor.h:49
#define MON_ECKSUM
Definition monitor.h:85
#define MON_ERROR
Definition monitor.h:75
#define MON_SET_REG
Definition monitor.h:41
#define MON_DATA
Definition monitor.h:72
#define MON_HELLO
Definition monitor.h:76
#define MON_CAP_SLOT
Definition monitor.h:62
#define MON_STOP_DATA_WATCH
Definition monitor.h:92
#define MON_STOP_FAULT
Definition monitor.h:93
#define MON_LZ4
Definition monitor.h:52
#define MON_EDECODE
Definition monitor.h:87
#define MON_SET_BP
Definition monitor.h:42
#define MON_EBADREG
Definition monitor.h:83
#define MON_REGS
Definition monitor.h:73
#define MON_EBADLEN
Definition monitor.h:84
#define MON_WRITE_MEM
Definition monitor.h:39
#define MON_EBADSTATE
Definition monitor.h:81
#define MON_PING
Definition monitor.h:37
#define MON_EBADCMD
Definition monitor.h:80
#define MON_CLR_BP
Definition monitor.h:43
#define MON_STOP
Definition monitor.h:47
#define MON_GET_REGS
Definition monitor.h:40
#define MON_CONT
Definition monitor.h:46
#define MON_LOAD
Definition monitor.h:44
#define MON_PONG
Definition monitor.h:74
#define MON_RUN
Definition monitor.h:45
#define MON_STOP_INTERRUPT
Definition monitor.h:91
list w
Definition gentable.py:108
tuple idx
Definition gentable.py:117
int base
Definition gentable.py:114
int off
Definition mkimage.py:49
list words
Definition mktest.py:123
struct HandlerInfo * next
Definition handlers.h:34
void(* handler)(int)
Definition handlers.h:35
Definition lz4stream.h:37
uint32_t SR
Definition threads.h:43
uint32_t Cause
Definition threads.h:44
uint32_t gp
Definition threads.h:37
uint32_t returnPC
Definition threads.h:41
static int c
Definition syscalls.h:122
static const char * src
Definition syscalls.h:80
void uint32_t(classId, spec)
uint16_t val
Definition timers.c:319
uint16_t transportRecvWord(void)
Definition transport.c:159
void transportSendWord(uint16_t w)
Definition transport.c:61
int transportRecvEnd(void)
Definition transport.c:165
void transportRecvBegin(uint16_t *type, uint16_t *len)
Definition transport.c:114
void transportSendEnd(void)
Definition transport.c:66
int transportStopPending(void)
Definition transport.c:156
int transportTryRate(uint16_t reload, uint16_t pongType, uint16_t pongWord)
Definition transport.c:225
int transportHasRate(void)
Definition transport.c:224
void transportInit(void)
Definition transport.c:46
void transportSendBegin(uint16_t type, uint16_t len)
Definition transport.c:51
void transportSendFrame(uint16_t type, const uint16_t *payload, uint16_t len)
Definition transport.c:72
#define TRANSPORT_OK
Definition transport.h:41