提交 9ecd8465 编写于 作者: Nameless-Y's avatar Nameless-Y

[libcpu] remove xburst

上级 1e786a5d
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.S')
CPPPATH = [cwd]
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "../xburst/cache.h"
#include <board.h>
#define CACHE_SIZE 16*1024
#define CACHE_LINE_SIZE 32
#define KSEG0 0x80000000
#define K0_TO_K1() \
do { \
unsigned long __k0_addr; \
\
__asm__ __volatile__( \
"la %0, 1f\n\t" \
"or %0, %0, %1\n\t" \
"jr %0\n\t" \
"nop\n\t" \
"1: nop\n" \
: "=&r"(__k0_addr) \
: "r" (0x20000000) ); \
} while(0)
#define K1_TO_K0() \
do { \
unsigned long __k0_addr; \
__asm__ __volatile__( \
"nop;nop;nop;nop;nop;nop;nop\n\t" \
"la %0, 1f\n\t" \
"jr %0\n\t" \
"nop\n\t" \
"1: nop\n" \
: "=&r" (__k0_addr)); \
} while (0)
#define INVALIDATE_BTB() \
do { \
unsigned long tmp; \
__asm__ __volatile__( \
".set mips32\n\t" \
"mfc0 %0, $16, 7\n\t" \
"nop\n\t" \
"ori %0, 2\n\t" \
"mtc0 %0, $16, 7\n\t" \
"nop\n\t" \
".set mips2\n\t" \
: "=&r" (tmp)); \
} while (0)
#define SYNC_WB() __asm__ __volatile__ ("sync")
#define cache_op(op,addr) \
__asm__ __volatile__( \
" .set noreorder \n" \
" .set mips32\n\t \n" \
" cache %0, %1 \n" \
" .set mips0 \n" \
" .set reorder" \
: \
: "i" (op), "m" (*(unsigned char *)(addr)))
void __icache_invalidate_all(void)
{
unsigned int i;
K0_TO_K1();
asm volatile (".set noreorder\n"
".set mips32\n\t"
"mtc0\t$0,$28\n\t"
"mtc0\t$0,$29\n"
".set mips0\n"
".set reorder\n");
for (i=KSEG0;i<KSEG0+CACHE_SIZE;i+=CACHE_LINE_SIZE)
cache_op(Index_Store_Tag_I, i);
K1_TO_K0();
INVALIDATE_BTB();
}
void __dcache_writeback_all(void)
{
unsigned int i;
for (i=KSEG0;i<KSEG0+CACHE_SIZE;i+=CACHE_LINE_SIZE)
cache_op(Index_Writeback_Inv_D, i);
SYNC_WB();
}
void rt_hw_cache_init(void)
{
__dcache_writeback_all();
__icache_invalidate_all();
}
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __CACHE_H__
#define __CACHE_H__
/*
* Cache Operations
*/
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define Index_Invalidate_SI 0x02
#define Index_Writeback_Inv_SD 0x03
#define Index_Load_Tag_I 0x04
#define Index_Load_Tag_D 0x05
#define Index_Load_Tag_SI 0x06
#define Index_Load_Tag_SD 0x07
#define Index_Store_Tag_I 0x08
#define Index_Store_Tag_D 0x09
#define Index_Store_Tag_SI 0x0A
#define Index_Store_Tag_SD 0x0B
#define Create_Dirty_Excl_D 0x0d
#define Create_Dirty_Excl_SD 0x0f
#define Hit_Invalidate_I 0x10
#define Hit_Invalidate_D 0x11
#define Hit_Invalidate_SI 0x12
#define Hit_Invalidate_SD 0x13
#define Fill 0x14
#define Hit_Writeback_Inv_D 0x15
/* 0x16 is unused */
#define Hit_Writeback_Inv_SD 0x17
#define Hit_Writeback_I 0x18
#define Hit_Writeback_D 0x19
/* 0x1a is unused */
#define Hit_Writeback_SD 0x1b
/* 0x1c is unused */
/* 0x1e is unused */
#define Hit_Set_Virtual_SI 0x1e
#define Hit_Set_Virtual_SD 0x1f
void rt_hw_cache_init(void);
#endif
/*
* File : cache_init.S
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
*/
#include "../common/mips.inc"
#include "../common/mipsregs.h"
#include "../common/stackframe.h"
.text
.set noreorder
.globl cache_init
.ent cache_init
cache_init:
.set noreorder
mtc0 zero, CP0_TAGLO
move t0, a0 // cache total size
move t1, a1 // cache line size
li t2, 0x80000000
addu t3, t0, t2
_cache_init_loop:
cache 8, 0(t2) // icache_index_store_tag
cache 9, 0(t2) // dcache_index_store_tag
addu t2, t1
bne t2, t3, _cache_init_loop
nop
mfc0 t0, CP0_CONFIG
li t1, 0x7
not t1
and t0, t0, t1
or t0, 0x3 // cacheable, noncoherent, write-back, write allocate
mtc0 t0, CP0_CONFIG
jr ra
nop
.set reorder
.end cache_init
/*
* File : context_gcc.S
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
* 2010-09-11 bernard port to Jz4755
*/
#include "../common/mips.inc"
#include "../common/stackframe.h"
#include "stack.h"
.section ".text", "ax"
.set noreorder
/*
* rt_base_t rt_hw_interrupt_disable()
*/
.globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
mfc0 v0, CP0_STATUS
and v1, v0, 0xfffffffe
mtc0 v1, CP0_STATUS
jr ra
nop
/*
* void rt_hw_interrupt_enable(rt_base_t level)
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
mtc0 a0, CP0_STATUS
jr ra
nop
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
* a0 --> from
* a1 --> to
*/
.globl rt_hw_context_switch
rt_hw_context_switch:
mtc0 ra, CP0_EPC
SAVE_ALL
sw sp, 0(a0) /* store sp in preempted tasks TCB */
lw sp, 0(a1) /* get new task stack pointer */
RESTORE_ALL_AND_RET
/*
* void rt_hw_context_switch_to(rt_uint32 to)/*
* a0 --> to
*/
.globl rt_hw_context_switch_to
rt_hw_context_switch_to:
lw sp, 0(a0) /* get new task stack pointer */
RESTORE_ALL_AND_RET
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
*/
.globl rt_thread_switch_interrupt_flag
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
la t0, rt_thread_switch_interrupt_flag
lw t1, 0(t0)
nop
bnez t1, _reswitch
nop
li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
sw t1, 0(t0)
la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
sw a0, 0(t0)
_reswitch:
la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
sw a1, 0(t0)
jr ra
nop
.globl system_dump
/*
* void rt_hw_context_switch_interrupt_do(rt_base_t flag)
*/
.globl rt_interrupt_enter
.globl rt_interrupt_leave
.globl mips_irq_handle
mips_irq_handle:
SAVE_ALL
mfc0 t0, CP0_CAUSE
mfc0 t1, CP0_STATUS
and t0, t1
andi t0, 0xff00
beqz t0, spurious_interrupt
nop
/* let k0 keep the current context sp */
move k0, sp
/* switch to kernel stack */
li sp, SYSTEM_STACK
jal rt_interrupt_enter
nop
jal rt_interrupt_dispatch
nop
jal rt_interrupt_leave
nop
/* switch sp back to thread's context */
move sp, k0
/*
* if rt_thread_switch_interrupt_flag set, jump to
* rt_hw_context_switch_interrupt_do and don't return
*/
la k0, rt_thread_switch_interrupt_flag
lw k1, 0(k0)
beqz k1, spurious_interrupt
nop
sw zero, 0(k0) /* clear flag */
nop
/*
* switch to the new thread
*/
la k0, rt_interrupt_from_thread
lw k1, 0(k0)
nop
sw sp, 0(k1) /* store sp in preempted tasks's TCB */
la k0, rt_interrupt_to_thread
lw k1, 0(k0)
nop
lw sp, 0(k1) /* get new task's stack pointer */
j spurious_interrupt
nop
spurious_interrupt:
RESTORE_ALL_AND_RET
.set reorder
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-07-09 Bernard first version
* 2010-09-11 Bernard add CPU reset implementation
*/
#include <rtthread.h>
#include <board.h>
/**
* @addtogroup Ingenic
*/
/*@{*/
/**
* this function will reset CPU
*
*/
void rt_hw_cpu_reset()
{
/* open the watch-dog */
REG_WDT_TCSR = WDT_TCSR_EXT_EN;
REG_WDT_TCSR |= WDT_TCSR_PRESCALE_1024;
REG_WDT_TDR = 0x03;
REG_WDT_TCNT = 0x00;
REG_WDT_TCER |= WDT_TCER_TCEN;
rt_kprintf("reboot system...\n");
while (1);
}
/**
* this function will shutdown CPU
*
*/
void rt_hw_cpu_shutdown()
{
rt_kprintf("shutdown...\n");
while (1);
}
/**
* This function finds the first bit set (beginning with the least significant bit)
* in value and return the index of that bit.
*
* Bits are numbered starting at 1 (the least significant bit). A return value of
* zero from any of these functions means that the argument was zero.
*
* @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
int __rt_ffs(int value)
{
return __builtin_ffs(value);
}
/*@}*/
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
*/
#include <rtthread.h>
#include <rthw.h>
#include "../common/exception.h"
#include "../common/mipsregs.h"
/**
* @addtogroup Ingenic
*/
/*@{*/
/**
* exception handle table
*/
exception_func_t sys_exception_handlers[33];
/**
* setup the exception handle
*/
exception_func_t rt_set_except_vector(int n, exception_func_t func)
{
exception_func_t old_handler = sys_exception_handlers[n];
if ((n == 0) || (n > 32) || (!func))
{
return 0;
}
sys_exception_handlers[n] = func;
return old_handler;
}
void tlb_refill_handler(void)
{
rt_kprintf("tlb-miss happens, epc: 0x%08x\n", read_c0_epc());
rt_hw_cpu_shutdown();
}
void cache_error_handler(void)
{
rt_kprintf("cache exception happens, epc: 0x%08x\n", read_c0_epc());
rt_hw_cpu_shutdown();
}
static void unhandled_exception_handle(pt_regs_t *regs)
{
rt_kprintf("exception happens, epc: 0x%08x\n", regs->cp0_epc);
}
void install_default_execpt_handle(void)
{
rt_int32_t i;
for (i=0; i<33; i++)
sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle;
}
/*@}*/
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* 2010-07-09 Bernard first version
* 2013-03-29 aozima Modify the interrupt interface implementations.
*/
#include <rtthread.h>
#include <rthw.h>
#include <board.h>
#if defined(RT_USING_JZ4770) || defined(RT_USING_JZ4775) || defined(RT_USING_JZ_M150) || defined(RT_USING_JZ_X1000)
#define INTERRUPTS_MAX 64
#else
#define INTERRUPTS_MAX 32
#endif
extern rt_uint32_t rt_interrupt_nest;
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
static struct rt_irq_desc isr_table[INTERRUPTS_MAX];
/**
* @addtogroup Ingenic
*/
/*@{*/
static void rt_hw_interrupt_handler(int vector, void *param)
{
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
}
/**
* This function will initialize hardware interrupt
*/
void rt_hw_interrupt_init(void)
{
rt_int32_t idx;
rt_memset(isr_table, 0x00, sizeof(isr_table));
for (idx = 0; idx < INTERRUPTS_MAX; idx ++)
{
isr_table[idx].handler = rt_hw_interrupt_handler;
}
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = 0;
rt_thread_switch_interrupt_flag = 0;
}
/**
* This function will mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_mask(int vector)
{
/* mask interrupt */
__intc_mask_irq(vector);
}
/**
* This function will un-mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_umask(int vector)
{
__intc_unmask_irq(vector);
}
/**
* This function will install a interrupt service routine to a interrupt.
* @param vector the interrupt number
* @param handler the interrupt service routine to be installed
* @param param the interrupt service function parameter
* @param name the interrupt name
* @return old handler
*/
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name)
{
rt_isr_handler_t old_handler = RT_NULL;
if(vector < INTERRUPTS_MAX)
{
old_handler = isr_table[vector].handler;
#ifdef RT_USING_INTERRUPT_INFO
rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
#endif /* RT_USING_INTERRUPT_INFO */
isr_table[vector].handler = handler;
isr_table[vector].param = param;
}
return old_handler;
}
#if defined(RT_USING_JZ4770) || defined(RT_USING_JZ4775) || defined(RT_USING_JZ_M150) || defined(RT_USING_JZ_X1000)
/*
* fls - find last bit set.
* @word: The word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
rt_inline int fls(int x)
{
__asm__("clz %0, %1" : "=r" (x) : "r" (x));
return 32 - x;
}
#endif
#include <mipsregs.h>
void rt_interrupt_dispatch(void *ptreg)
{
int i;
void *param;
rt_isr_handler_t irq_func;
#if defined(RT_USING_JZ4770) || defined(RT_USING_JZ4775) || defined(RT_USING_JZ_M150) || defined(RT_USING_JZ_X1000)
int irq = 0, group;
rt_uint32_t intc_ipr0 = 0, intc_ipr1 = 0, vpu_pending = 0;
rt_uint32_t c0_status, c0_cause;
rt_uint32_t pending_im;
/* check os timer */
c0_status = read_c0_status();
c0_cause = read_c0_cause();
pending_im = (c0_cause & ST0_IM) & (c0_status & ST0_IM);
if (pending_im & CAUSEF_IP3)
{
extern void rt_hw_ost_handler(void);
rt_hw_ost_handler();
return;
}
if (pending_im & CAUSEF_IP2)
{
intc_ipr0 = REG_INTC_IPR(0);
intc_ipr1 = REG_INTC_IPR(1);
if (intc_ipr0)
{
irq = fls(intc_ipr0) - 1;
intc_ipr0 &= ~(1<<irq);
}
else if(intc_ipr1)
{
irq = fls(intc_ipr1) - 1;
intc_ipr1 &= ~(1<<irq);
irq += 32;
}
#ifndef RT_USING_JZ_X1000 /* X1000 has no VPU */
else
{
__asm__ __volatile__ (
"mfc0 %0, $13, 0 \n\t"
"nop \n\t"
:"=r"(vpu_pending)
:);
if(vpu_pending & 0x800)
irq = IRQ_VPU;
else
return;
}
#endif
if (irq >= INTERRUPTS_MAX)
rt_kprintf("max interrupt, irq=%d\n", irq);
/* do interrupt */
irq_func = isr_table[irq].handler;
param = isr_table[irq].param;
(*irq_func)(irq, param);
#ifdef RT_USING_INTERRUPT_INFO
isr_table[i].counter++;
#endif /* RT_USING_INTERRUPT_INFO */
/* ack interrupt */
__intc_ack_irq(irq);
}
if (pending_im & CAUSEF_IP0)
rt_kprintf("CAUSEF_IP0\n");
if (pending_im & CAUSEF_IP1)
rt_kprintf("CAUSEF_IP1\n");
if (pending_im & CAUSEF_IP4)
rt_kprintf("CAUSEF_IP4\n");
if (pending_im & CAUSEF_IP5)
rt_kprintf("CAUSEF_IP5\n");
if (pending_im & CAUSEF_IP6)
rt_kprintf("CAUSEF_IP6\n");
if (pending_im & CAUSEF_IP7)
rt_kprintf("CAUSEF_IP7\n");
#else
static rt_uint32_t pending = 0;
/* the hardware interrupt */
pending |= REG_INTC_IPR;
if (!pending) return;
for (i = INTERRUPTS_MAX; i > 0; --i)
{
if ((pending & (1<<i)))
{
pending &= ~(1<<i);
/* do interrupt */
irq_func = isr_table[i].handler;
param = isr_table[i].param;
(*irq_func)(i, param);
#ifdef RT_USING_INTERRUPT_INFO
isr_table[i].counter++;
#endif /* RT_USING_INTERRUPT_INFO */
/* ack interrupt */
__intc_ack_irq(i);
}
}
#endif
}
/*@}*/
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-05-27 swkyer first version
*/
#include <rtthread.h>
#include "../common/mipsregs.h"
#include "../common/mipscfg.h"
mips32_core_cfg_t g_mips_core =
{
16, /* icache_line_size */
256, /* icache_lines_per_way */
4, /* icache_ways */
16, /* dcache_line_size */
256, /* dcache_lines_per_way */
4, /* dcache_ways */
16, /* max_tlb_entries */
};
static rt_uint16_t m_pow(rt_uint16_t b, rt_uint16_t n)
{
rt_uint16_t rets = 1;
while (n--)
rets *= b;
return rets;
}
/**
* read core attribute
*/
void mips32_cfg_init(void)
{
rt_uint16_t val;
rt_uint32_t cp0_config1;
cp0_config1 = read_c0_config();
if (cp0_config1 & 0x80000000)
{
cp0_config1 = read_c0_config1();
val = (cp0_config1 & (7<<22))>>22;
g_mips_core.icache_lines_per_way = 64 * m_pow(2, val);
val = (cp0_config1 & (7<<19))>>19;
g_mips_core.icache_line_size = 2 * m_pow(2, val);
val = (cp0_config1 & (7<<16))>>16;
g_mips_core.icache_ways = val + 1;
val = (cp0_config1 & (7<<13))>>13;
g_mips_core.dcache_lines_per_way = 64 * m_pow(2, val);
val = (cp0_config1 & (7<<10))>>10;
g_mips_core.dcache_line_size = 2 * m_pow(2, val);
val = (cp0_config1 & (7<<7))>>7;
g_mips_core.dcache_ways = val + 1;
val = (cp0_config1 & (0x3F<<25))>>25;
g_mips_core.max_tlb_entries = val + 1;
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
static void CP0_status_analyze(unsigned long value)
{
if(value & (1<<26))
rt_kprintf(" FR");
if(value & (1<<23))
rt_kprintf(" PX");
if(value & (1<<22))
rt_kprintf(" BEV");
if(value & (1<<20))
rt_kprintf(" SR");
if(value & (1<<19))
rt_kprintf(" NMI");
if(value & (1<<20))
rt_kprintf(" SR");
if(value & (0xFF<<8))
rt_kprintf(" IM:0x%02X", (value >> 8) & 0xFF);
if(value & (1<<7))
rt_kprintf(" KX");
if(value & (1<<6))
rt_kprintf(" SX");
if(value & (1<<5))
rt_kprintf(" UX");
if(value & (0x03<<3))
rt_kprintf(" KSU:0x%02X", (value >> 3) & 0x03);
if(value & (1<<2))
rt_kprintf(" ERL");
if(value & (1<<1))
rt_kprintf(" EXL");
if(value & (1<<0))
rt_kprintf(" IE");
}
static void CP0_config0_analyze(unsigned long value)
{
/* [31] M */
if(value & (1UL<<31))
rt_kprintf(" M");
/* [15] BE */
if(value & (1<<15))
rt_kprintf(" big-endian");
else
rt_kprintf(" little-endian");
/* [14:13] AT */
{
int AT = (value >> 13) & 0x03;
if(AT == 0)
{
rt_kprintf(" MIPS32");
}
else if(AT == 1)
{
rt_kprintf(" MIPS64/A32");
}
else if(AT == 2)
{
rt_kprintf(" MIPS64/A64");
}
else
{
rt_kprintf(" unkown");
}
}
/* [12:10] AR */
{
int AR = (value >> 10) & 0x07;
if(AR == 0)
{
rt_kprintf(" R1");
}
else if(AR == 1)
{
rt_kprintf(" R2");
}
else
{
rt_kprintf(" reserve");
}
}
/* [3] VI */
if(value & (1UL<<31))
rt_kprintf(" VI");
/* [2:0] K0 */
{
int K0 = value & 0x07;
if(K0 == 2)
{
rt_kprintf(" uncached");
}
else if(K0 == 3)
{
rt_kprintf(" cacheable");
}
else
{
rt_kprintf(" K0:reserve");
}
}
}
static void CP0_config1_analyze(unsigned long value)
{
/* [31] M */
if(value & (1UL<<31))
rt_kprintf(" M");
/* [30:25] MMU size */
{
int MMU_size = (value >> 25) & 0x3F;
rt_kprintf(" TLB:%d", MMU_size + 1);
}
/* [24:22] IS, [21:19] IL, [18:16] IA */
{
int IS = (value >> 22) & 0x07;
int IL = (value >> 19) & 0x07;
int IA = (value >> 16) & 0x07;
IA = IA + 1;
IS = 64 << IS;
IL = 2 << IL;
rt_kprintf(" Icache-%dKB:%dway*%dset*%dbyte",
(IA*IS*IL) >> 10, IA, IS, IL);
}
/* [15:13] DS, [12:10] DL, [9:7] DA */
{
int DS = (value >> 13) & 0x07;
int DL = (value >> 10) & 0x07;
int DA = (value >> 7) & 0x07;
DA = DA + 1;
DS = 64 << DS;
DL = 2 << DL;
rt_kprintf(" Dcache-%dKB:%dway*%dset*%dbyte",
(DA*DS*DL) >> 10, DA, DS, DL);
}
/* [6] C2 */
if(value & (1UL<<6))
rt_kprintf(" CP2");
/* [5] MD */
if(value & (1UL<<5))
rt_kprintf(" MDMX-ASE");
/* [4] PC */
if(value & (1UL<<4))
rt_kprintf(" performa-count");
/* [3] WR */
if(value & (1UL<<3))
rt_kprintf(" Watch");
/* [2] CA */
if(value & (1UL<<2))
rt_kprintf(" MIPS16e");
/* [1] EP */
if(value & (1UL<<1))
rt_kprintf(" EJTAG");
/* [0] FP */
if(value & (1UL<<0))
rt_kprintf(" FPU");
}
static void CP0_config2_analyze(unsigned long value)
{
/* [31] M */
if(value & (1UL<<31))
rt_kprintf(" M");
}
static void CP0_config3_analyze(unsigned long value)
{
/* [31] M */
if(value & (1UL<<31))
rt_kprintf(" M");
}
static void list_mips(void)
{
unsigned long value;
unsigned long num = 0;
rt_kprintf("MIPS coprocessor register:\r\n");
rt_kprintf("( 0,0) INDEX : 0x%08X\r\n", read_c0_index());
rt_kprintf("( 1,0) RANDOM : 0x%08X\r\n", read_c0_random());
rt_kprintf("( 2,0) ENTRYLO0 : 0x%08X\r\n", read_c0_entrylo0());
rt_kprintf("( 3,0) ENTRYLO1 : 0x%08X\r\n", read_c0_entrylo1());
rt_kprintf("( 4,0) CONTEXT : 0x%08X\r\n", read_c0_context());
rt_kprintf("( 5,0) PAGEMASK : 0x%08X\r\n", read_c0_pagemask());
rt_kprintf("( 6,0) WIRED : 0x%08X\r\n", read_c0_wired());
rt_kprintf("( 7,0) INFO : 0x%08X\r\n", read_c0_info());
rt_kprintf("( 8,0) BADVADDR : 0x%08X\r\n", read_c0_badvaddr());
rt_kprintf("( 9,0) COUNT : 0x%08X\r\n", read_c0_count());
rt_kprintf("(10,0) ENTRYHI : 0x%08X\r\n", read_c0_entryhi());
rt_kprintf("(11,0) COMPARE : 0x%08X\r\n", read_c0_compare());
value = read_c0_status();
rt_kprintf("(12,0) STATUS : 0x%08X", value);
CP0_status_analyze(value);
rt_kprintf("\r\n");
/*
rt_kprintf("(12,1) INTCTL : 0x%08X\r\n", __read_32bit_c0_register(12, 1));
rt_kprintf("(12,2) SRSCTL : 0x%08X\r\n", __read_32bit_c0_register(12, 2));
*/
rt_kprintf("(13,0) CAUSE : 0x%08X\r\n", read_c0_cause());
rt_kprintf("(14,0) EPC : 0x%08X\r\n", read_c0_epc());
rt_kprintf("(15,0) PRID : 0x%08X\r\n", read_c0_prid());
rt_kprintf("(15,1) EBASE : 0x%08X\r\n", read_c0_ebase());
value = read_c0_config();
rt_kprintf("(16,0) CONFIG : 0x%08X", value);
CP0_config0_analyze(value);
rt_kprintf("\r\n");
if(value & (1UL << 31))
{
value = read_c0_config1();
rt_kprintf("(16,1) CONFIG1 : 0x%08X", value);
CP0_config1_analyze(value);
rt_kprintf("\r\n");
if(value & (1UL << 31))
{
value = read_c0_config2();
rt_kprintf("(16,2) CONFIG2 : 0x%08X\r\n", value);
CP0_config2_analyze(value);
rt_kprintf("\r\n");
if(value & (1UL << 31))
{
value = read_c0_config3();
rt_kprintf("(16,3) CONFIG3 : 0x%08X\r\n", value);
CP0_config3_analyze(value);
rt_kprintf("\r\n");
}
}
}
rt_kprintf("(17,0) LLADDR : 0x%08X\r\n", __read_32bit_c0_register($17, 0));
rt_kprintf("(18,0) WATCHLO : 0x%08X\r\n", __read_32bit_c0_register($18, 0));
rt_kprintf("(19,0) WATCHHI : 0x%08X\r\n", __read_32bit_c0_register($19, 0));
rt_kprintf("(20,0) XCONTEXT : 0x%08X\r\n", __read_32bit_c0_register($20, 0));
rt_kprintf("(21,0) FRAMEMASK : 0x%08X\r\n", __read_32bit_c0_register($21, 0));
rt_kprintf("(22,0) DIAGNOSTIC: 0x%08X\r\n", __read_32bit_c0_register($22, 0));
rt_kprintf("(23,0) DEBUG : 0x%08X\r\n", __read_32bit_c0_register($23, 0));
rt_kprintf("(24,0) DEPC : 0x%08X\r\n", __read_32bit_c0_register($24, 0));
rt_kprintf("(25,0) PERFCTL0 : 0x%08X\r\n", __read_32bit_c0_register($25, 0));
rt_kprintf("(26,0) ECC : 0x%08X\r\n", __read_32bit_c0_register($26, 0));
rt_kprintf("(27,0) CACHEERR : 0x%08X\r\n", __read_32bit_c0_register($27, 0));
rt_kprintf("(28,0) TAGLO : 0x%08X\r\n", __read_32bit_c0_register($28, 0));
rt_kprintf("(29,0) TAGHI : 0x%08X\r\n", __read_32bit_c0_register($29, 0));
/*
rt_kprintf("(30,0) ERROREPC : 0x%08X\r\n", __read_32bit_c0_register($30, 0));
rt_kprintf("(31,0) DESAVE : 0x%08X\r\n", __read_32bit_c0_register($31, 0));
*/
rt_kprintf("\r\n");
}
FINSH_FUNCTION_EXPORT(list_mips, list CPU info)
#endif /* RT_USING_FINSH */
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
* 2010-07-07 Bernard porting to Ingenic CPU
*/
#include <rtthread.h>
/**
* @addtogroup Ingenic
*/
/*@{*/
extern rt_uint32_t cp0_get_cause(void);
extern rt_uint32_t cp0_get_status(void);
extern rt_uint32_t cp0_get_hi(void);
extern rt_uint32_t cp0_get_lo(void);
/**
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
{
rt_uint32_t *stk;
static rt_uint32_t g_sr = 0;
if (g_sr == 0)
{
g_sr = cp0_get_status();
g_sr &= 0xfffffffe;
g_sr |= 0x0403;
}
/** Start at stack top */
stk = (rt_uint32_t *)stack_addr;
*(stk) = (rt_uint32_t) tentry; /* pc: Entry Point */
*(--stk) = (rt_uint32_t) 0xeeee; /* c0_cause */
*(--stk) = (rt_uint32_t) 0xffff; /* c0_badvaddr */
*(--stk) = (rt_uint32_t) cp0_get_lo(); /* lo */
*(--stk) = (rt_uint32_t) cp0_get_hi(); /* hi */
*(--stk) = (rt_uint32_t) g_sr; /* C0_SR: HW2 = En, IE = En */
*(--stk) = (rt_uint32_t) texit; /* ra */
*(--stk) = (rt_uint32_t) 0x0000001e; /* s8 */
*(--stk) = (rt_uint32_t) stack_addr; /* sp */
*(--stk) = (rt_uint32_t) 0x0000001c; /* gp */
*(--stk) = (rt_uint32_t) 0x0000001b; /* k1 */
*(--stk) = (rt_uint32_t) 0x0000001a; /* k0 */
*(--stk) = (rt_uint32_t) 0x00000019; /* t9 */
*(--stk) = (rt_uint32_t) 0x00000018; /* t8 */
*(--stk) = (rt_uint32_t) 0x00000017; /* s7 */
*(--stk) = (rt_uint32_t) 0x00000016; /* s6 */
*(--stk) = (rt_uint32_t) 0x00000015; /* s5 */
*(--stk) = (rt_uint32_t) 0x00000014; /* s4 */
*(--stk) = (rt_uint32_t) 0x00000013; /* s3 */
*(--stk) = (rt_uint32_t) 0x00000012; /* s2 */
*(--stk) = (rt_uint32_t) 0x00000011; /* s1 */
*(--stk) = (rt_uint32_t) 0x00000010; /* s0 */
*(--stk) = (rt_uint32_t) 0x0000000f; /* t7 */
*(--stk) = (rt_uint32_t) 0x0000000e; /* t6 */
*(--stk) = (rt_uint32_t) 0x0000000d; /* t5 */
*(--stk) = (rt_uint32_t) 0x0000000c; /* t4 */
*(--stk) = (rt_uint32_t) 0x0000000b; /* t3 */
*(--stk) = (rt_uint32_t) 0x0000000a; /* t2 */
*(--stk) = (rt_uint32_t) 0x00000009; /* t1 */
*(--stk) = (rt_uint32_t) 0x00000008; /* t0 */
*(--stk) = (rt_uint32_t) 0x00000007; /* a3 */
*(--stk) = (rt_uint32_t) 0x00000006; /* a2 */
*(--stk) = (rt_uint32_t) 0x00000005; /* a1 */
*(--stk) = (rt_uint32_t) parameter; /* a0 */
*(--stk) = (rt_uint32_t) 0x00000003; /* v1 */
*(--stk) = (rt_uint32_t) 0x00000002; /* v0 */
*(--stk) = (rt_uint32_t) 0x00000001; /* at */
*(--stk) = (rt_uint32_t) 0x00000000; /* zero */
/* return task's current stack address */
return (rt_uint8_t *)stk;
}
/*@}*/
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __STACK_H__
#define __STACK_H__
#define SYSTEM_STACK 0x80003fe8 /* the kernel system stack address */
#endif
/*
* File : start_gcc.S
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
* 2010-09-04 bernard porting to Jz47xx
*/
#include "../common/mips.inc"
#include "../common/stackframe.h"
#include "stack.h"
.section ".start", "ax"
.set noreorder
/* the program entry */
.globl _start
_start:
.set noreorder
la ra, _start
li t1, 0x00800000
mtc0 t1, CP0_CAUSE
/* init cp0 registers. */
li t0, 0x0000FC00 /* BEV = 0 and mask all interrupt */
mtc0 t0, CP0_STATUS
/* setup stack pointer */
li sp, SYSTEM_STACK
la gp, _gp
/* init caches, assumes a 4way * 128set * 32byte I/D cache */
mtc0 zero, CP0_TAGLO /* TAGLO reg */
mtc0 zero, CP0_TAGHI /* TAGHI reg */
li t0, 3 /* enable cache for kseg0 accesses */
mtc0 t0, CP0_CONFIG /* CONFIG reg */
la t0, 0x80000000 /* an idx op should use an unmappable address */
ori t1, t0, 0x4000 /* 16kB cache */
_cache_loop:
cache 0x8, 0(t0) /* index store icache tag */
cache 0x9, 0(t0) /* index store dcache tag */
bne t0, t1, _cache_loop
addiu t0, t0, 0x20 /* 32 bytes per cache line */
nop
/* invalidate BTB */
mfc0 t0, CP0_CONFIG
nop
ori t0, 2
mtc0 t0, CP0_CONFIG
nop
/* copy IRAM section */
la t0, _iramcopy
la t1, _iramstart
la t2, _iramend
_iram_loop:
lw t3, 0(t0)
sw t3, 0(t1)
addiu t1, 4
bne t1, t2, _iram_loop
addiu t0, 4
/* clear bss */
la t0, __bss_start
la t1, __bss_end
_clr_bss_loop:
sw zero, 0(t0)
bne t0, t1, _clr_bss_loop
addiu t0, t0, 4
/* jump to RT-Thread RTOS */
jal rtthread_startup
nop
/* restart, never die */
j _start
nop
.set reorder
.globl cp0_get_cause
cp0_get_cause:
mfc0 v0, CP0_CAUSE
jr ra
nop
.globl cp0_get_status
cp0_get_status:
mfc0 v0, CP0_STATUS
jr ra
nop
.globl cp0_get_hi
cp0_get_hi:
mfhi v0
jr ra
nop
.globl cp0_get_lo
cp0_get_lo:
mflo v0
jr ra
nop
.extern tlb_refill_handler
.extern cache_error_handler
/* Exception Handler */
/* 0x0 - TLB refill handler */
.section .vectors.1, "ax", %progbits
j tlb_refill_handler
nop
/* 0x100 - Cache error handler */
.section .vectors.2, "ax", %progbits
j cache_error_handler
nop
/* 0x180 - Exception/Interrupt handler */
.section .vectors.3, "ax", %progbits
j _general_exception_handler
nop
/* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */
.section .vectors.4, "ax", %progbits
j _irq_handler
nop
.section .vectors, "ax", %progbits
.extern mips_irq_handle
/* general exception handler */
_general_exception_handler:
.set noreorder
mfc0 k1, CP0_CAUSE
andi k1, k1, 0x7c
srl k1, k1, 2
lw k0, sys_exception_handlers(k1)
jr k0
nop
.set reorder
/* interrupt handler */
_irq_handler:
.set noreorder
la k0, mips_irq_handle
jr k0
nop
.set reorder
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-11-19 Urey the first version
*/
#ifndef X1000_H__
#define X1000_H__
#ifndef __ASSEMBLY__
// typedef unsigned int size_t;
#define u64 unsigned long long
#define u32 unsigned int
#define u16 unsigned short
#define u8 unsigned char
#define U64 unsigned long long
#define U32 unsigned int
#define U16 unsigned short
#define U8 unsigned char
#define S64 signed long long
#define S32 int
#define S16 short int
#define S8 signed char
#define cache_unroll(base,op) \
__asm__ __volatile__(" \
.set noreorder; \
.set mips3; \
cache %1, (%0); \
.set mips0; \
.set reorder" \
: \
: "r" (base), \
"i" (op));
/* cpu pipeline flush */
static inline void jz_sync(void)
{
__asm__ volatile ("sync");
}
static inline void writeb(u8 value, u32 address)
{
*((volatile u8 *) address) = value;
}
static inline void writew( u16 value, u32 address)
{
*((volatile u16 *) address) = value;
}
static inline void writel(u32 value, u32 address)
{
*((volatile u32 *) address) = value;
}
static inline u8 readb(u32 address)
{
return *((volatile u8 *)address);
}
static inline u16 readw(u32 address)
{
return *((volatile u16 *)address);
}
static inline u32 readl(u32 address)
{
return *((volatile u32 *)address);
}
static inline void jz_writeb(u32 address, u8 value)
{
*((volatile u8 *)address) = value;
}
static inline void jz_writew(u32 address, u16 value)
{
*((volatile u16 *)address) = value;
}
static inline void jz_writel(u32 address, u32 value)
{
*((volatile u32 *)address) = value;
}
static inline u8 jz_readb(u32 address)
{
return *((volatile u8 *)address);
}
static inline u16 jz_readw(u32 address)
{
return *((volatile u16 *)address);
}
static inline u32 jz_readl(u32 address)
{
return *((volatile u32 *)address);
}
#define REG8(addr) *((volatile u8 *)(addr))
#define REG16(addr) *((volatile u16 *)(addr))
#define REG32(addr) *((volatile u32 *)(addr))
#define BIT(n) (0x01u << (n))
#else
#define REG8(addr) (addr)
#define REG16(addr) (addr)
#define REG32(addr) (addr)
#endif /* !ASSEMBLY */
//----------------------------------------------------------------------
// Register Definitions
//
/* AHB0 BUS Devices Base */
#define HARB0_BASE 0xB3000000
#define EMC_BASE 0xB3010000
#define DDRC_BASE 0xB3020000
#define MDMAC_BASE 0xB3030000
#define LCD_BASE 0xB3050000
#define TVE_BASE 0xB3050000
#define SLCD_BASE 0xB3050000
#define CIM_BASE 0xB3060000
#define IPU_BASE 0xB3080000
/* AHB1 BUS Devices Base */
#define HARB1_BASE 0xB3200000
#define DMAGP0_BASE 0xB3210000
#define DMAGP1_BASE 0xB3220000
#define DMAGP2_BASE 0xB3230000
#define MC_BASE 0xB3250000
#define ME_BASE 0xB3260000
#define DEBLK_BASE 0xB3270000
#define IDCT_BASE 0xB3280000
#define CABAC_BASE 0xB3290000
#define TCSM0_BASE 0xB32B0000
#define TCSM1_BASE 0xB32C0000
#define SRAM_BASE 0xB32D0000
/* AHB2 BUS Devices Base */
#define HARB2_BASE 0xB3400000
#define NEMC_BASE 0xB3410000
#define DMAC_BASE 0xB3420000
#define UHC_BASE 0xB3430000
#define UDC_BASE 0xB3440000
#define GPS_BASE 0xB3480000
#define ETHC_BASE 0xB34B0000
#define BCH_BASE 0xB34D0000
#define MSC0_BASE 0xB3450000
#define MSC1_BASE 0xB3460000
#define MSC2_BASE 0xB3470000
/* APB BUS Devices Base */
#define CPM_BASE 0xB0000000
#define INTC_BASE 0xB0001000
#define TCU_BASE 0xB0002000
#define WDT_BASE 0xB0002000
#define OST_BASE 0xB2000000 /* OS Timer */
#define RTC_BASE 0xB0003000
#define GPIO_BASE 0xB0010000
#define AIC_BASE 0xB0020000
#define DMIC_BASE 0xB0021000
#define ICDC_BASE 0xB0020000
#define UART0_BASE 0xB0030000
#define UART1_BASE 0xB0031000
#define UART2_BASE 0xB0032000
#define UART3_BASE 0xB0033000
#define SCC_BASE 0xB0040000
#define SSI0_BASE 0xB0043000
#define SSI1_BASE 0xB0044000
#define SSI2_BASE 0xB0045000
#define I2C0_BASE 0xB0050000
#define I2C1_BASE 0xB0051000
#define PS2_BASE 0xB0060000
#define SADC_BASE 0xB0070000
#define OWI_BASE 0xB0072000
#define TSSI_BASE 0xB0073000
/* NAND CHIP Base Address*/
#define NEMC_CS1_IOBASE 0Xbb000000
#define NEMC_CS2_IOBASE 0Xba000000
#define NEMC_CS3_IOBASE 0Xb9000000
#define NEMC_CS4_IOBASE 0Xb8000000
#define NEMC_CS5_IOBASE 0Xb7000000
#define NEMC_CS6_IOBASE 0Xb6000000
/*********************************************************************************************************
** WDT
*********************************************************************************************************/
#define WDT_TDR (WDT_BASE + 0x00)
#define WDT_TCER (WDT_BASE + 0x04)
#define WDT_TCNT (WDT_BASE + 0x08)
#define WDT_TCSR (WDT_BASE + 0x0C)
#define REG_WDT_TDR REG16(WDT_TDR)
#define REG_WDT_TCER REG8(WDT_TCER)
#define REG_WDT_TCNT REG16(WDT_TCNT)
#define REG_WDT_TCSR REG16(WDT_TCSR)
#define WDT_TSCR_WDTSC (1 << 16)
#define WDT_TCSR_PRESCALE_1 (0 << 3)
#define WDT_TCSR_PRESCALE_4 (1 << 3)
#define WDT_TCSR_PRESCALE_16 (2 << 3)
#define WDT_TCSR_PRESCALE_64 (3 << 3)
#define WDT_TCSR_PRESCALE_256 (4 << 3)
#define WDT_TCSR_PRESCALE_1024 (5 << 3)
#define WDT_TCSR_EXT_EN (1 << 2)
#define WDT_TCSR_RTC_EN (1 << 1)
#define WDT_TCSR_PCK_EN (1 << 0)
#define WDT_TCER_TCEN (1 << 0)
/*********************************************************************************************************
** 中断源
*********************************************************************************************************/
/* INTC (Interrupt Controller) */
#define INTC_ISR(n) (INTC_BASE + 0x00 + (n) * 0x20)
#define INTC_IMR(n) (INTC_BASE + 0x04 + (n) * 0x20)
#define INTC_IMSR(n) (INTC_BASE + 0x08 + (n) * 0x20)
#define INTC_IMCR(n) (INTC_BASE + 0x0c + (n) * 0x20)
#define INTC_IPR(n) (INTC_BASE + 0x10 + (n) * 0x20)
#define REG_INTC_ISR(n) REG32(INTC_ISR((n)))
#define REG_INTC_IMR(n) REG32(INTC_IMR((n)))
#define REG_INTC_IMSR(n) REG32(INTC_IMSR((n)))
#define REG_INTC_IMCR(n) REG32(INTC_IMCR((n)))
#define REG_INTC_IPR(n) REG32(INTC_IPR((n)))
// interrupt controller interrupts
#define IRQ_DMIC 0
#define IRQ_AIC0 1
#define IRQ_RESERVED2 2
#define IRQ_RESERVED3 3
#define IRQ_RESERVED4 4
#define IRQ_RESERVED5 5
#define IRQ_RESERVED6 6
#define IRQ_SFC 7
#define IRQ_SSI0 8
#define IRQ_RESERVED9 9
#define IRQ_PDMA 10
#define IRQ_PDMAD 11
#define IRQ_RESERVED12 12
#define IRQ_RESERVED13 13
#define IRQ_GPIO3 14
#define IRQ_GPIO2 15
#define IRQ_GPIO1 16
#define IRQ_GPIO0 17
#define IRQ_RESERVED18 18
#define IRQ_RESERVED19 19
#define IRQ_RESERVED20 20
#define IRQ_OTG 21
#define IRQ_RESERVED22 22
#define IRQ_AES 23
#define IRQ_RESERVED24 24
#define IRQ_TCU2 25
#define IRQ_TCU1 26
#define IRQ_TCU0 27
#define IRQ_RESERVED28 28
#define IRQ_RESERVED29 29
#define IRQ_CIM 30
#define IRQ_LCD 31
#define IRQ_RTC 32
#define IRQ_RESERVED33 33
#define IRQ_RESERVED34 34
#define IRQ_RESERVED35 35
#define IRQ_MSC1 36
#define IRQ_MSC0 37
#define IRQ_SCC 38
#define IRQ_RESERVED39 39
#define IRQ_PCM0 40
#define IRQ_RESERVED41 41
#define IRQ_RESERVED42 42
#define IRQ_RESERVED43 43
#define IRQ_HARB2 44
#define IRQ_RESERVED45 45
#define IRQ_HARB0 46
#define IRQ_CPM 47
#define IRQ_RESERVED48 48
#define IRQ_UART2 49
#define IRQ_UART1 50
#define IRQ_UART0 51
#define IRQ_DDR 52
#define IRQ_RESERVED53 53
#define IRQ_EFUSE 54
#define IRQ_MAC 55
#define IRQ_RESERVED56 56
#define IRQ_RESERVED57 57
#define IRQ_I2C2 58
#define IRQ_I2C1 59
#define IRQ_I2C0 60
#define IRQ_PDMAM 61
#define IRQ_JPEG 62
#define IRQ_RESERVED63 63
#define IRQ_INTC_MAX 63
#ifndef __ASSEMBLY__
#define __intc_unmask_irq(n) (REG_INTC_IMCR((n)/32) = (1 << ((n)%32)))
#define __intc_mask_irq(n) (REG_INTC_IMSR((n)/32) = (1 << ((n)%32)))
#define __intc_ack_irq(n) (REG_INTC_IPR((n)/32) = (1 << ((n)%32))) /* A dummy ack, as the Pending Register is Read Only. Should we remove __intc_ack_irq() */
#endif /* !__ASSEMBLY__ */
#endif /* _JZ_M150_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册