- added missing files
git-svn-id: http://moon:8086/svn/mips@230 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: board.h
|
||||
* Author: jens
|
||||
*
|
||||
* Created on 8. Januar 2017, 11:33
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#define CPU_FREQ_HZ 100000000
|
||||
#define UART_STDIO 0
|
||||
#define UART_DEBUGGER 1
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// IRQs
|
||||
// ---------------------------------------------------------
|
||||
#define SYS_INT_SOFT_0 0
|
||||
#define SYS_INT_SOFT_1 1
|
||||
#define SYS_INT_TIMER 2
|
||||
#define SYS_INT_UART0 3
|
||||
#define SYS_INT_UART1 4
|
||||
#define SYS_INT_FLASH 5
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Memory-mapped registers
|
||||
// ---------------------------------------------------------
|
||||
#ifndef SYS_IO_BASE
|
||||
#define SYS_IO_BASE 0xA0000000
|
||||
#endif
|
||||
#ifndef SDRAM_BASE
|
||||
#define SDRAM_BASE 0x40000000
|
||||
#endif
|
||||
#ifndef FLASH_BASE_IO
|
||||
#define FLASH_BASE_IO 0xA4000000
|
||||
#endif
|
||||
#ifndef FLASH_BASE_MEM
|
||||
#define FLASH_BASE_MEM 0x00000000
|
||||
#endif
|
||||
|
||||
// Backwards compatibility
|
||||
#define SYS_FLASH_IO FLASH_BASE_IO
|
||||
#define SYS_FLASH_MEM FLASH_BASE_MEM
|
||||
|
||||
// GPIO
|
||||
#define SYS_GPIO_0_BASE (SYS_IO_BASE + 0)
|
||||
#define SYS_GPIO_0_DATA (SYS_GPIO_0_BASE + 0)
|
||||
#define SYS_GPIO_0_DIR (SYS_GPIO_0_BASE + 4)
|
||||
|
||||
#define GPIO_0_DFLT_DIR 0x00000000 // Inputs
|
||||
#define GPIO_0_DFLT_DATA 0x00000000
|
||||
|
||||
#define GPIO_0_MASK_LED 0x000000FF
|
||||
#define GPIO_0_ALIGN_LED 0
|
||||
|
||||
#define GPIO_0_MASK_DIP 0x0000000F
|
||||
#define GPIO_0_ALIGN_DIP 8
|
||||
|
||||
#define GPIO_0_MASK_BTN 0x0000001F
|
||||
#define GPIO_0_ALIGN_BTN 24
|
||||
|
||||
// RTC
|
||||
#define SYS_TIMER_USEC (SYS_IO_BASE + 0x8)
|
||||
#define SYS_TIMER_SEC (SYS_IO_BASE + 0xC)
|
||||
|
||||
// TIMERs
|
||||
#define SYS_ITIM_CTRL (SYS_IO_BASE + 0x18)
|
||||
#define SYS_ITIM_STAT (SYS_IO_BASE + 0x1C)
|
||||
#define SYS_ITIM0_CNT (SYS_IO_BASE + 0x20)
|
||||
#define SYS_ITIM1_CNT (SYS_IO_BASE + 0x24)
|
||||
#define SYS_ITIM2_CNT (SYS_IO_BASE + 0x28)
|
||||
#define SYS_ITIM3_CNT (SYS_IO_BASE + 0x2C)
|
||||
#define SYS_ITIM0_CMP (SYS_IO_BASE + 0x30)
|
||||
#define SYS_ITIM1_CMP (SYS_IO_BASE + 0x34)
|
||||
#define SYS_ITIM2_CMP (SYS_IO_BASE + 0x38)
|
||||
#define SYS_ITIM3_CMP (SYS_IO_BASE + 0x3C)
|
||||
|
||||
// UARTs
|
||||
#define SYS_UART_BIT_TX_HALFFULL 0x00000001
|
||||
#define SYS_UART_BIT_TX_FULL 0x00000002
|
||||
#define SYS_UART_BIT_RX_HALFFULL 0x00000004
|
||||
#define SYS_UART_BIT_RX_FULL 0x00000008
|
||||
#define SYS_UART_BIT_RX_AVAIL 0x00000010
|
||||
#define SYS_UART_BIT_TX_INTEN 0x00000020
|
||||
#define SYS_UART_BIT_RX_INTEN 0x00000040
|
||||
#define SYS_UART_BIT_TX_IRQ 0x00000100
|
||||
#define SYS_UART_BIT_RX_IRQ 0x00000200
|
||||
#define SYS_UART_DATA SYS_UART0_DATA
|
||||
#define SYS_UART_STAT SYS_UART0_STAT
|
||||
#define SYS_UART_BAUD SYS_UART0_BAUD
|
||||
#define SYS_UART0_DATA (SYS_IO_BASE + 0x10000)
|
||||
#define SYS_UART0_STAT (SYS_IO_BASE + 0x10004)
|
||||
#define SYS_UART0_BAUD (SYS_IO_BASE + 0x10008)
|
||||
#define SYS_UART1_DATA (SYS_IO_BASE + 0x30000)
|
||||
#define SYS_UART1_STAT (SYS_IO_BASE + 0x30004)
|
||||
#define SYS_UART1_BAUD (SYS_IO_BASE + 0x30008)
|
||||
|
||||
// SPI
|
||||
#define SYS_SPI_STAT (SYS_IO_BASE + 0x20000)
|
||||
// Read
|
||||
#define SPI_STAT_CMDRDY (0x01)
|
||||
#define SPI_STAT_DINRDY (0x02)
|
||||
#define SPI_STAT_DOUTRDY (0x04)
|
||||
#define SPI_STAT_CMD_FIFO_FULL (0x0100)
|
||||
#define SPI_STAT_CMD_FIFO_EMPTY (0x0200)
|
||||
#define SPI_STAT_WRITE_FIFO_FULL (0x0400)
|
||||
#define SPI_STAT_WRITE_FIFO_EMPTY (0x0800)
|
||||
#define SPI_STAT_READ_FIFO_FULL (0x1000)
|
||||
#define SPI_STAT_READ_FIFO_EMPTY (0x2000)
|
||||
#define SPI_STAT_RX_VALID (0x4000)
|
||||
#define SPI_STAT_SPI_HOLD (0x8000)
|
||||
|
||||
// Write
|
||||
#define SPI_STAT_COMMIT (1)
|
||||
|
||||
#define SYS_SPI_XFER_SIZE (SYS_IO_BASE + 0x20004)
|
||||
#define SYS_SPI_DATA_SIZE (SYS_IO_BASE + 0x20008)
|
||||
#define SYS_SPI_DATA (SYS_IO_BASE + 0x2000C)
|
||||
#define SYS_SPI_CTRL (SYS_IO_BASE + 0x20010)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOARD_H */
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libsys.h"
|
||||
|
||||
UINT8 g_pattern8[] = {0x01, 0x02, 0x03, 0x4, 0x05, 0x06, 0x07, 0x08};
|
||||
UINT16 g_pattern16[sizeof(g_pattern8)/2] = {0};
|
||||
UINT32 g_pattern32[sizeof(g_pattern8)/4] = {0};
|
||||
UINT8 _g_bytes[4] = {0x12, 0x34, 0x56, 0x78};
|
||||
UINT8 _g_bytes2[4] = {0};
|
||||
|
||||
void MakePattern(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
UINT16 *pPat16 = (UINT16*)g_pattern8;
|
||||
UINT32 *pPat32 = (UINT32*)g_pattern8;
|
||||
|
||||
|
||||
for (i=0; i < sizeof(g_pattern16)/2; i++)
|
||||
{
|
||||
g_pattern16[i] = pPat16[i];
|
||||
}
|
||||
|
||||
for (i=0; i < sizeof(g_pattern32)/4; i++)
|
||||
{
|
||||
g_pattern32[i] = pPat32[i];
|
||||
}
|
||||
}
|
||||
|
||||
void PrintPattern(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
printf("Pattern 8bit:\n");
|
||||
for (i=0; i < sizeof(g_pattern8); i++)
|
||||
{
|
||||
printf("%02X ", g_pattern8[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Pattern 16bit:\n");
|
||||
for (i=0; i < sizeof(g_pattern16)/2; i++)
|
||||
{
|
||||
printf("%04X ", g_pattern16[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Pattern 32bit:\n");
|
||||
for (i=0; i < sizeof(g_pattern32)/4; i++)
|
||||
{
|
||||
printf("%08X ", g_pattern32[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int IsEndianBig(void)
|
||||
{
|
||||
int i, result;
|
||||
|
||||
UINT8 *pBuf8;
|
||||
UINT16 *pBuf16;
|
||||
UINT32 *pBuf32;
|
||||
UINT16 halve;
|
||||
UINT32 word;
|
||||
|
||||
|
||||
halve = 0x1234;
|
||||
word = 0x12345678;
|
||||
|
||||
result = -1;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
_g_bytes2[i] = _g_bytes[i];
|
||||
|
||||
pBuf8 = (UINT8*)&word;
|
||||
if (((*pBuf8+0) == 0x12) && (*(pBuf8+1) == 0x34) && (*(pBuf8+2) == 0x56) && (*(pBuf8+3) == 0x78))
|
||||
{
|
||||
pBuf8 = (UINT8*)&halve;
|
||||
if (((*pBuf8+0) == 0x12) && (*(pBuf8+1) == 0x34))
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pBuf8 = (UINT8*)&word;
|
||||
if (((*pBuf8+0) == 0x78) && (*(pBuf8+1) == 0x56) && (*(pBuf8+2) == 0x34) && (*(pBuf8+3) == 0x12))
|
||||
{
|
||||
pBuf8 = (UINT8*)&halve;
|
||||
if (((*pBuf8+0) == 0x34) && (*(pBuf8+1) == 0x12))
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PrintCPUinfo(void)
|
||||
{
|
||||
int result, rev_id;
|
||||
int cache_size, cache_line;
|
||||
int eb;
|
||||
|
||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
||||
|
||||
// Print Status register
|
||||
result = CP0_SR_read();
|
||||
|
||||
printf("--------------------------------------------------\n");
|
||||
printf("Status : %8.8X\n", result);
|
||||
|
||||
// Print Revision
|
||||
result = CP0_PRID_read();
|
||||
rev_id = (result >> 8) & 0xFF;
|
||||
printf("CPU type : MIPS ");
|
||||
if ((rev_id > 0) && (rev_id < 0x07))
|
||||
{
|
||||
printf(cpu_type_str[rev_id]);
|
||||
printf(" Rev. ");
|
||||
rev_id = result & 0xFF;
|
||||
printf("%d", rev_id);
|
||||
}
|
||||
else
|
||||
printf("Unknown");
|
||||
|
||||
eb = IsEndianBig();
|
||||
if (eb > 0)
|
||||
printf(" [Big-endian]\n");
|
||||
if (eb == 0)
|
||||
printf(" [Little-endian]\n");
|
||||
if (eb < 0)
|
||||
printf(" [Unknown endian]\n");
|
||||
|
||||
printf("--------------------------------------------------\n");
|
||||
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int eb;
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
CP0_SR_write(CP0_SR_read() & ~(1 << 25));
|
||||
|
||||
PrintCPUinfo();
|
||||
|
||||
if (IsEndianBig() == 1)
|
||||
printf("Endian is big\n");
|
||||
if (IsEndianBig() == 0)
|
||||
printf("Endian is little\n");
|
||||
|
||||
PrintBuffer8(_g_bytes2, 8, 4);
|
||||
MakePattern();
|
||||
PrintPattern();
|
||||
|
||||
memset(g_pattern16, 0, sizeof(g_pattern16));
|
||||
memset(g_pattern32, 0, sizeof(g_pattern32));
|
||||
|
||||
CP0_SR_write(CP0_SR_read() | (1 << 25));
|
||||
eb = IsEndianBig();
|
||||
|
||||
MakePattern();
|
||||
|
||||
CP0_SR_write(CP0_SR_read() & ~(1 << 25));
|
||||
if (eb == 1)
|
||||
printf("Endian is big\n");
|
||||
if (eb == 0)
|
||||
printf("Endian is little\n");
|
||||
PrintBuffer8(_g_bytes2, 8, 4);
|
||||
|
||||
PrintPattern();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libsys.h"
|
||||
|
||||
#define TEST_SIZE 32768
|
||||
int main (void)
|
||||
{
|
||||
int i;
|
||||
UINT16 *ram16;
|
||||
UINT32 sr;
|
||||
UINT32 volatile *pReg = (UINT32*)SYS_LED_PORT;
|
||||
|
||||
*pReg = 0;
|
||||
|
||||
sr = CP0_SR_read();
|
||||
|
||||
ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16));
|
||||
|
||||
CP0_SR_write(sr | (1 << 25));
|
||||
|
||||
for (i=0; i < TEST_SIZE/2; i++)
|
||||
ram16[i] = (UINT16)i;
|
||||
|
||||
for (i=TEST_SIZE/2-1; i >= 0; i--)
|
||||
if (ram16[i] != (UINT16)i)
|
||||
break;
|
||||
|
||||
i++;
|
||||
if (i)
|
||||
*pReg = 0xFFFFFFFF;
|
||||
else
|
||||
*pReg = 1;
|
||||
|
||||
|
||||
free(ram16);
|
||||
|
||||
ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16));
|
||||
|
||||
*pReg = 0;
|
||||
CP0_SR_write(sr & ~(1 << 25));
|
||||
|
||||
for (i=0; i < TEST_SIZE/2; i++)
|
||||
ram16[i] = (UINT16)i;
|
||||
|
||||
for (i=TEST_SIZE/2-1; i >= 0; i--)
|
||||
if (ram16[i] != (UINT16)i)
|
||||
break;
|
||||
|
||||
i++;
|
||||
if (i)
|
||||
*pReg = 0xFFFFFFFF;
|
||||
else
|
||||
*pReg = 1;
|
||||
|
||||
|
||||
free(ram16);
|
||||
|
||||
|
||||
// sputs("Status : ");print_word(sr);sputs("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <libsys.h>
|
||||
#include <irq.h>
|
||||
#include "xcpt.h"
|
||||
#define MAX_NUM_EXCEPTIONS 10
|
||||
|
||||
void *g_fp_badsubs[MAX_NUM_EXCEPTIONS];
|
||||
|
||||
void _exc_break(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"break 0x9\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_syscall(uint32_t code, uint32_t arg)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
"move $v0, %[code]\n"
|
||||
"move $a0, %[arg]\n"
|
||||
"syscall\n"
|
||||
:
|
||||
: [code] "r" (code), [arg] "r" (arg)
|
||||
: "v0", "a0"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_arith(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x7FFFFFFF\n"
|
||||
" addi $t1, $t0, 2\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_store_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40000000\n"
|
||||
" sw $0, 1($t0)\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_load_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000000\n"
|
||||
" li $t1, 0x80000000\n"
|
||||
" lw $t1, 0($t1)\n"
|
||||
" lw $t0, 2($t0)\n"
|
||||
" lw $t1, 4($t0)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_kaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000000\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_dtlbl_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x00000000\n"
|
||||
" lw $zero, 0($t0)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_dtlbs_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x00000000\n"
|
||||
" sw $zero, 0($t0)\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_itlbl_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000000\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_iaddr_daddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000003\n"
|
||||
" li $t1, 0x80000002\n"
|
||||
" jr $t0\n"
|
||||
" lw $t1, 0($t1)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_daddr_iaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000003\n"
|
||||
" li $t1, 0x80000002\n"
|
||||
" lw $t1, 0($t1)\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_iaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000003\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_ri(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
".word 0x9c563442\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_ibe(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t1, 0x10000000\n"
|
||||
" jr $t1\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_dbe(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t1, 0x10000000\n"
|
||||
" lw $t0, 0($t1)\n"
|
||||
"nop\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void handler0(struct xcptcontext *xcp)
|
||||
{
|
||||
sputs("Interrupt 0\n");
|
||||
interrupt_clr(0);
|
||||
}
|
||||
|
||||
void handler1(struct xcptcontext *xcp)
|
||||
{
|
||||
sputs("Interrupt 1\n");
|
||||
interrupt_clr(1);
|
||||
}
|
||||
|
||||
int xcp_handler(struct xcptcontext * xcp)
|
||||
{
|
||||
sputs("----------------------------------------\n");
|
||||
sputs("Exception Type: ");xcpt_exctype_print(xcp);sputs("\n");
|
||||
sputs("----------------------------------------\n");
|
||||
xcpt_registers_print(xcp);
|
||||
sputs("\n");
|
||||
|
||||
if (xcpt_get_type(xcp) == EXC_INT)
|
||||
{
|
||||
interrupt_disable(0);
|
||||
interrupt_disable(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip instruction that caused exception
|
||||
xcp->epc += 4;
|
||||
if (xcp->cr & 0x80000000)
|
||||
{
|
||||
xcp->epc += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int buf[256];
|
||||
int i, sel;
|
||||
|
||||
xcpt_register(EXC_INT, xcp_handler);
|
||||
xcpt_register(EXC_RI, xcp_handler);
|
||||
xcpt_register(EXC_OV, xcp_handler);
|
||||
xcpt_register(EXC_BP, xcp_handler);
|
||||
xcpt_register(EXC_SYSCALL, xcp_handler);
|
||||
xcpt_register(EXC_TLBL, xcp_handler);
|
||||
xcpt_register(EXC_TLBS, xcp_handler);
|
||||
|
||||
interrupt_register(0, handler0);
|
||||
interrupt_enable(0);
|
||||
interrupt_register(1, handler1);
|
||||
interrupt_enable(1);
|
||||
|
||||
sputs("11 : SW-interrupt 0\n");
|
||||
interrupt_set(0);
|
||||
sputs("12 : SW-interrupt 1\n");
|
||||
interrupt_set(1);
|
||||
|
||||
sputs(" 4 : Syscall\n");
|
||||
_exc_syscall(4, (uint32_t)((char*)"Hallo Syscall ("));
|
||||
_exc_syscall(1, 12345678);
|
||||
_exc_syscall(4, (uint32_t)((char*)")\n"));
|
||||
|
||||
sputs(" 5 : Breakpoint\n");
|
||||
_exc_break();
|
||||
|
||||
sputs(" 3 : Arithmetic overflow\n");
|
||||
_exc_arith();
|
||||
|
||||
sputs(" 1 : Reserved instruction\n");
|
||||
_exc_ri();
|
||||
|
||||
sputs(" 2 : DTLBS (BadVAddr = 0x00000000)\n");
|
||||
_exc_dtlbs_err();
|
||||
|
||||
sputs(" 2 : DTLBL (BadVAddr = 0x00000000)\n");
|
||||
_exc_dtlbl_err();
|
||||
|
||||
return 0;
|
||||
|
||||
sputs(" 2 : Privileged address (BadVAddr = 0x80000000)\n");
|
||||
_exc_kaddr_err();
|
||||
|
||||
sputs(" 6 : Load error on instruction (BadVAddr = 0x40000003)\n");
|
||||
_exc_iaddr_err();
|
||||
|
||||
sputs(" 7 : Load error on data (BadVAddr = 0x40000002)\n");
|
||||
_exc_load_err();
|
||||
|
||||
sputs(" 8 : Store error on data (BadVAddr = 0x40000001)\n");
|
||||
_exc_store_err();
|
||||
|
||||
// sputs(" 9 : Bus error on instruction\n");
|
||||
// sputs("IBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
||||
// _exc_ibe();
|
||||
|
||||
// sputs("10 : Bus error on data\n");
|
||||
// sputs("DBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
||||
// _exc_dbe();
|
||||
|
||||
sputs("13 : Load error on instruction and Load error on data (BadVAddr = 0x40000003)\n");
|
||||
_exc_iaddr_daddr_err();
|
||||
|
||||
sputs("14 : Load error on data and Load error on instruction (BadVAddr = 0x40000002)\n");
|
||||
_exc_daddr_iaddr_err();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "libsys.h"
|
||||
#include "xcpt.h"
|
||||
|
||||
#define MAX_NUM_EXCEPTIONS 10
|
||||
void *g_fp_badsubs[MAX_NUM_EXCEPTIONS];
|
||||
|
||||
void _exc_dtlbl_err(UINT32 vaddr)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" move $v0, %[vaddr]\n"
|
||||
" lw $zero, 0($v0)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
:
|
||||
: [vaddr] "r" (vaddr)
|
||||
: "v0"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_dtlbs_err(UINT32 vaddr, UINT32 data)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" move $a0, %[data]\n"
|
||||
" move $v0, %[vaddr]\n"
|
||||
" sw $a0, 0($v0)\n"
|
||||
".set reorder\n"
|
||||
:
|
||||
: [vaddr] "r" (vaddr), [data] "r" (data)
|
||||
: "v0", "a0"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_itlbl_err(UINT32 vaddr)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" move $v0, %[vaddr]\n"
|
||||
" jr $v0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
:
|
||||
: [vaddr] "r" (vaddr)
|
||||
: "v0"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
int xcp_handler(struct xcptcontext * xcp)
|
||||
{
|
||||
sputs("----------------------------------------\n");
|
||||
sputs("Exception Type: ");xcpt_exctype_print(xcp);sputs("\n");
|
||||
sputs("----------------------------------------\n");
|
||||
xcpt_registers_print(xcp);
|
||||
sputs("\n");
|
||||
|
||||
sputs("CP0(ENTRY_HI) = "); print_word(CP0_read(10)); sputs("\n");
|
||||
sputs("CP0(ENTRY_LO) = "); print_word(CP0_read(2)); sputs("\n");
|
||||
|
||||
xcp->epc += 4;
|
||||
if (xcp->cr & 0x80000000)
|
||||
{
|
||||
xcp->epc += 4;
|
||||
}
|
||||
|
||||
interrupt_clr(0);
|
||||
interrupt_clr(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int buf[256];
|
||||
int i, sel;
|
||||
int *pMem;
|
||||
|
||||
xcpt_register(EXC_MOD, xcp_handler);
|
||||
xcpt_register(EXC_TLBL, xcp_handler);
|
||||
xcpt_register(EXC_TLBS, xcp_handler);
|
||||
|
||||
// Tell CP0 we want to access D-TLB
|
||||
CP0_write(3, 0x00000001);
|
||||
|
||||
// Write 1. TLB entry
|
||||
CP0_write(0, 0x00000800);
|
||||
CP0_write(10, 0x3110A540);
|
||||
CP0_write(2, 0x00008300);
|
||||
CP0_TLBWI;
|
||||
|
||||
// Write 2. TLB entry
|
||||
CP0_write(0, 0x00000900);
|
||||
CP0_write(10, 0x3220B540);
|
||||
CP0_write(2, 0x00009300);
|
||||
CP0_TLBWI;
|
||||
|
||||
CP0_write(0, 0x00000800);
|
||||
CP0_TLBR;
|
||||
sputs("CP0(INDEX) = "); print_word(CP0_read(0)); sputs("\n");
|
||||
sputs("CP0(ENTRY_HI) = "); print_word(CP0_read(10)); sputs("\n");
|
||||
sputs("CP0(ENTRY_LO) = "); print_word(CP0_read(2)); sputs("\n");
|
||||
CP0_write(0, 0x00000900);
|
||||
CP0_TLBR;
|
||||
sputs("CP0(INDEX) = "); print_word(CP0_read(0)); sputs("\n");
|
||||
sputs("CP0(ENTRY_HI) = "); print_word(CP0_read(10)); sputs("\n");
|
||||
sputs("CP0(ENTRY_LO) = "); print_word(CP0_read(2)); sputs("\n");
|
||||
|
||||
|
||||
sputs(" 1 : DTLBS (BadVAddr = 0x3110A234)\n");
|
||||
_exc_dtlbs_err(0x3110A234, 0xDECAFED);
|
||||
|
||||
sputs(" 2 : DTLBL (BadVAddr = 0x3220B234)\n");
|
||||
_exc_dtlbl_err(0x3220B234);
|
||||
|
||||
sputs(" 3 : ITLBL (BadVAddr = 0x3220B234)\n");
|
||||
_exc_itlbl_err(0x3220B234);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user