📄 k64388.s
字号:
/************************************************************** File: k64388.s* Author: Phil Bunce (pjb@carmel.com) Curtis Dahl (cdahl@lsil.com)** Revision History:* 970129 Initial release* 970303 Brought ice port defs upto date. Added RXC etc.* 970306 Changed to word ld and st ops to iceport.* 970306 Added _start entry. Changed old _start to cstartup* 970306 Added IBS to save area* 970311 Changed bne to beq in test of xxRDY* 970311 Added "and" with TXRDY to send_ack* 970421 Change from Int5 to Int4* 970829 Removed call to CpuInit in cstartup.* 971113 Added wakeup banner (ABCD)* 971114 Changed ICEPORT addr to b0ff.0000* 971114 Added USE_NO_INTS switch* 980312 Switched to version2 savearea format* 981110 Built for RAP** This file contains the PROM resident code (the IceKernel) necessary to* permit programs to be debugged using LSI Logic's SerialIce. This* implementation is for the 64388 (RAP) with the SerialIce Port.** The code in this module executes in kseg1 (non cacheable), leaves* BEV=1, and does not initialize the caches. ** This module should be linked with .text section to start at bfc00000,* and with data to start at some out-of-the-way place in RAM. I suggest* 80000100. That way the downloaded programs can start at 80000200 and* still be able to copy an exception handler to 80000080 for use once BEV* has been cleared. Example compile/link command for this file:** pmcc -crt0 -prom -syms -T bfc00000 -D 80000100 -o k64388 k64388.s** To download your application into RAM you should compile/link your * program using the following command.** pmcc -crt0 -T 80000200 -o myprog myprog_files...** This file contains the following blocks of code:* reset_vector - The start of execution* utlb_vector - UTLB exception handler* gen_vector - Handler for all other exceptions* ice_loop - Main loop of ICE* get_word - Get one word from serial interface* put_word - Put one word to serial interface* cpu_init - Perform CPU-specific initialization** This module requires the following areas of RAM:* instr_buffer - This is where the instructions that have been* received from the host are saved.* savearea - This is where I save the context of the* downloaded program.* */#include <mips.h>/* Commands that are sent by the IceController */#define SENDA0 0x12345678 /* execute instr_buffer */#define RUN_MODE 0x87654321 /* run application */#define SENDSAP 0xDEADBEEF /* send savearea pointer */#define ATTN 0x55 /* transfer control to IceKernel */#define ACK 0xaa /* reply to ATTN *//* Offsets into the savearea */#define SA_VERS 2#define ICE_SAV 0 /* save area version */#define ICE_SAH 1 /* save area header size */#define ICE_MAP 2 /* bit-map for savearea */#define ICE_IBS 3 /* size of instr buffer */#define ICE_GWP 4 /* pointer to get_word routine */#define ICE_PWP 5 /* pointer to put_word routine */#define ICE_EPC 6 /* saved so that it can be set */#define ICE_LE 7 /* set if little endian */#define ICE_SAHSIZE 8 /* size of save area header *//* end of header. The remainder is kernel-specific */#define ICE_AT (ICE_SAHSIZE+0) /* v0 is used to hold the value received */#define ICE_V0 (ICE_SAHSIZE+1) /* v0 is used to hold the value received */#define ICE_A0 (ICE_SAHSIZE+2) /* a0 is used to hold the value to be sent */#define ICE_A1 (ICE_SAHSIZE+3) /* a1 is used as a temp */#define ICE_A2 (ICE_SAHSIZE+4) /* a1 is used as a temp */#define ICE_A3 (ICE_SAHSIZE+5) /* a1 is used as a temp */#define ICE_T0 (ICE_SAHSIZE+6) /* t0 is used by the host as a temp */#define ICE_T1 (ICE_SAHSIZE+7) /* t1 is used by the host as a temp */#define ICE_T2 (ICE_SAHSIZE+8) /* t2 temp */#define ICE_T3 (ICE_SAHSIZE+9) /* t3 temp */#define ICE_T4 (ICE_SAHSIZE+10) /* t4 temp */#define ICE_S0 (ICE_SAHSIZE+11) /* pointer to instr_buffer */#define ICE_RA (ICE_SAHSIZE+12) /* ra is needed for bal/jal instrs */#define ICE_SIZE (ICE_SAHSIZE+13)#define REG_MAP 0x80011ff6 /* gp regs in savearea */#define UART_BASE 0xb0008600#define OFFSET_config 0x00 #define OFFSET_divisor 0x08 #define OFFSET_reset 0x10 #define OFFSET_status 0x18 #define OFFSET_rxbuff 0x20 #define OFFSET_txbuff 0x28 #define OFFSET_interval 0x30 #define OFFSET_abrd 0x38 #define OFFSET_channel 0x40 #define UART_INTBIT SR_INT4#define STATUS_DRDY_INT 0x00080000#define STATUS_RDY 0x00008000#define STATUS_TXEMPTY 0x00000002#define STATUS_TXALMOSTFULL 0x01000000#define BRG_PS 0x00100000/************ GPIO***********/#define GPIO_BASE 0xb000ad00#define GPIO_CONFIG GPIO_BASE # Configuration Register#define GPIO_ODR 0xb000ad10 # Output Data Register#define GPIO_IDR 0xb000ad18 # Data Input Register/****************************** GPIO Config Register Bits*****************************/#define GPIO_LB 0x00000100#define GPIO_GPEN 0x00000200#define GPIO_RST 0x00000400/****************************** GPIO EN/OUT LED Bits*****************************/#define GPIO_LED_1 0x00000800#define GPIO_LED_2 0x00000400#define GPIO_LED_3 0x00000200#define GPIO_LED_4 0x00000100#define GPIO_LED_5 0x00000080#define GPIO_LED_ALL GPIO_LED_1|GPIO_LED_2|GPIO_LED_3|GPIO_LED_4|GPIO_LED_5/******************************** GPIO Data Input Register Bits*******************************/#define GPIO_DIP_1 0x00000008 # GPIO 3 is Dipswitch 1#define GPIO_DIP_2 0x00000010 # GPIO 4 is Dipswitch 2#define GPIO_DIP_3 0x00000020 # GPIO 5 is Dipswitch 3#define GPIO_DIP_4 0x00000040 # GPIO 6 is Dipswitch 4#define J_RA_INSTR 0x03e00008#define IBUFSIZE 100 .comm instr_buffer,IBUFSIZE*4 .comm savearea,ICE_SIZE*4/************************************************************** reset_vector:* This is where execution starts.* A maximum of 64 instructions allowed in this section*/ .globl _start_start:reset_vector: # bfc00000 b cpu_init .align 4 .ascii "Serial Ice 1B 12/22/1998"/************************************************************** Start of interrupt-level code **************************************************************/ .set noat .align 8 addiu zero,zero,0 # nop to make the 2nd align work .align 7 .globl gen_vector .ent gen_vectorgen_vector: # bfc00180 # save regs la k0, 1f li k1, 0xa0000000 or k0,k1 j k01: la k0,savearea sw AT,ICE_AT*4(k0) .set at sw v0,ICE_V0*4(k0) sw a0,ICE_A0*4(k0) sw a1,ICE_A1*4(k0) sw a2,ICE_A2*4(k0) sw a3,ICE_A3*4(k0) sw t0,ICE_T0*4(k0) sw t1,ICE_T1*4(k0) sw t2,ICE_T2*4(k0) sw t3,ICE_T3*4(k0) sw t4,ICE_T4*4(k0) sw s0,ICE_S0*4(k0) sw ra,ICE_RA*4(k0) .set noreorder mfc0 t0,C0_EPC nop .set reorder sw t0,ICE_EPC*4(k0) # init s0 (KSEG1) la s0,instr_buffer # Is it my int? # read the CAUSE register .set noreorder mfc0 a0,C0_CAUSE nop .set reorder # hw int? and t0,a0,CAUSE_EXCMASK bne t0,zero,send_ack # br if not hw int and t0,a0,UART_INTBIT beq t0,zero,send_ack # br if not Uart hw int # make sure that this is a *real* attn byte # read the byte li k1,UART_BASE lw k0,OFFSET_status(k1) and k0,STATUS_RDY beq k0,zero,send_ack lw k0,OFFSET_rxbuff(k1) li k1,ATTN bne k0,k1,restore_rfe # br if not an attn byte # fall thru .end gen_vector/**************************************************************/ .globl send_ack .ent send_acksend_ack: li k1,UART_BASE # make sure that the tx is ready1: lw k0,OFFSET_status(k1) and k0,STATUS_TXALMOSTFULL bne k0,zero,1b li k0,ACK sw k0,OFFSET_txbuff(k1) # make sure that r8 and r9 are zero. li t0,0 li t1,0 # fall thru .end send_ack /************************************************************** ice_loop:* This is the main loop. We get words and process them.* There are 3 special types of word. * 1. RUN_MODE - transfer control to the customer's program.* 2. SENDSAP - Send the address of the savearea* 3. SENDA0 - Execute the code in instr_buffer and send* the value of register a0.* All other values are added to the instr_buffer.*/ .globl ice_loop .ent ice_loopice_loop: bal get_cmd # check for SENDA0 li k1,SENDA0 bne k1,v0,1f # It is SENDA0. Execute the code in instr_buffer and send # the value of register a0. # Make sure that the routine ends with a "j ra". sw zero,(s0) li k0,J_RA_INSTR sw k0,4(s0) sw zero,8(s0) # Make sure that the writes complete before the jal. .set noreorder nop nop nop .set reorder # Reset s0 to point to start of instr_buffer. la s0,instr_buffer jal s0 # execute instr_buffer bal put_word # send A0 b ice_loop1: # check for RUN_MODE li k1,RUN_MODE bne k1,v0,1frestore_rfe: # It is RUN_MODE. Transfer control to the client. # restore regs la k0,savearea .set noat lw AT,ICE_AT*4(k0) lw v0,ICE_V0*4(k0) lw a0,ICE_A0*4(k0) lw a1,ICE_A1*4(k0) lw a2,ICE_A2*4(k0) lw a3,ICE_A3*4(k0) lw t0,ICE_T0*4(k0) lw t1,ICE_T1*4(k0) lw t2,ICE_T2*4(k0) lw t3,ICE_T3*4(k0) lw t4,ICE_T4*4(k0) lw s0,ICE_S0*4(k0) lw ra,ICE_RA*4(k0) .set noreorder lw k0,ICE_EPC*4(k0) nop j k0 # jump to client rfe .set reorder .set at
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -