sys.h File Reference

This file contains system dependents definitions. More...

Go to the source code of this file.

MIPS R400 Exception indexes

They are stored in the exccode field of the Cause register. See the exception handler in the exc.c file for more information.

#define EXC_INT   0
#define EXC_MOD   1
#define EXC_TLBL   2
#define EXC_TLBS   3
#define EXC_ADEL   4
#define EXC_ADES   5
#define EXC_IBE   6
#define EXC_DBE   7
#define EXC_SYS   8
#define EXC_BP   9
#define EXC_RI   10
#define EXC_CPU   11
#define EXC_OV   12
#define EXC_TR   13
#define EXC_WATCH   23

MIPS R4000 CP0 Registers

read_cp0_*() and write_cp0_*()

These functions are used to manipulate the special system registers of the MIPS R4000 processor. These are accessed via special instructions - there is no standard way of doing that in the C language.

Functions are implemented as in-line assembler macros.

#define read_cp0_reg(regno)
#define read_cp0_badvaddr()   read_cp0_reg(8)
#define read_cp0_count()   read_cp0_reg(9)
#define read_cp0_compare()   read_cp0_reg(11)
#define read_cp0_status()   read_cp0_reg(12)
#define read_cp0_cause()   read_cp0_reg(13)
#define read_cp0_epc()   read_cp0_reg(14)
#define read_cp0_xcontext()   read_cp0_reg(20)
#define read_cp0_eepc()   read_cp0_reg(30)
#define write_cp0_reg(regno, i)
#define write_cp0_index(val)   write_cp0_reg(0, val)
#define write_cp0_entrylo0(val)   write_cp0_reg(2, val)
#define write_cp0_entrylo1(val)   write_cp0_reg(3, val)
#define write_cp0_pagemask(val)   write_cp0_reg(5, val)
#define write_cp0_wired(val)   write_cp0_reg(6, val)
#define write_cp0_count(val)   write_cp0_reg(9, val)
#define write_cp0_entryhi(val)   write_cp0_reg(10, val)
#define write_cp0_compare(val)   write_cp0_reg(11, val)
#define write_cp0_status(val)   write_cp0_reg(12, val)
#define write_cp0_cause(val)   write_cp0_reg(13, val)
#define write_cp0_epc(val)   write_cp0_reg(14, val)
#define write_cp0_eepc(val)   write_cp0_reg(30, val)
#define TLBWI()
#define TLBWR()

Index register

Index register (read-write) is used as a pointer to the TLB for the TLBWI instruction

#define cp0_index_index_mask   0x0000003f
#define cp0_index_res_mask   0x7fffffc0
#define cp0_index_p_mask   0x80000000
#define cp0_index_index_shift   0
#define cp0_index_res_shift   6
#define cp0_index_p_shift   31
#define cp0_index_index(r)   (((r) & cp0_index_index_mask) >> cp0_index_index_shift)
#define cp0_index_res(r)   (((r) & cp0_index_res_mask) >> cp0_index_res_shift)
#define cp0_index_p(r)   (((r) & cp0_index_p_mask) >> cp0_index_p_shift)

Random register

Random register is a read-only 6bit pseudo-random index into the TLB used by the TLBWR instruction. This register decrements every cycle. The upper bound is 47 which is the TLB size, the lower bound is defined by the value of Wired register. The Random register is set to its upper bound whenever the Wired register is changed.

#define cp0_random_random_mask   0x0000003f
#define cp0_random_res_mask   0xffffffc0
#define cp0_random_random_shift   0
#define cp0_random_res_shift   6
#define cp0_random_random(r)   (((r) & cp0_random_random_mask) >> cp0_random_random_shift)
#define cp0_random_res(r)   (((r) & cp0_random_res_mask) >> cp0_random_res_shift)

Status register

Status register (read-write) contains system-relevant configuration flags. This register is one of the most important for proper functionality. Relevant fields are listed below.

Interrupt Enable (ie) masks all interrupts. Interrupt Mask, im - 8 bits, 1 = interrupt enabled Coprocessor Usability, cu - 4 bits, 1 = usable Kernel-Supervisor-User, ksu - 2 bits 10 user, 01 supervisor, 00 kernel This field selects the processor address mode and privileges. Exception Level, exl 0 - normal, 1 - error The processor sets this field when an exception occurs. The exception level starts at concrete address. When this field is set, interrupts are disabled. Error Level, erl 0 - normal, 1 - error The processor sets this field when an Reset, Soft Reset or NMI exception occurs.

#define cp0_status_ie_mask   0x00000001
#define cp0_status_exl_mask   0x00000002
#define cp0_status_erl_mask   0x00000004
#define cp0_status_ksu_mask   0x00000018
#define cp0_status_ux_mask   0x00000020
#define cp0_status_sx_mask   0x00000040
#define cp0_status_kx_mask   0x00000080
#define cp0_status_im_mask   0x0000ff00
#define cp0_status_im0_mask   0x00000100
#define cp0_status_im1_mask   0x00000200
#define cp0_status_im2_mask   0x00000400
#define cp0_status_im3_mask   0x00000800
#define cp0_status_im4_mask   0x00001000
#define cp0_status_im5_mask   0x00002000
#define cp0_status_im6_mask   0x00004000
#define cp0_status_im7_mask   0x00008000
#define cp0_status_de_mask   0x00010000
#define cp0_status_ce_mask   0x00020000
#define cp0_status_ch_mask   0x00040000
#define cp0_status_res1_mask   0x00080000
#define cp0_status_sr_mask   0x00100000
#define cp0_status_ts_mask   0x00200000
#define cp0_status_bev_mask   0x00400000
#define cp0_status_res2_mask   0x01800000
#define cp0_status_re_mask   0x02000000
#define cp0_status_fr_mask   0x04000000
#define cp0_status_rp_mask   0x08000000
#define cp0_status_cu0_mask   0x10000000
#define cp0_status_cu1_mask   0x20000000
#define cp0_status_cu2_mask   0x40000000
#define cp0_status_cu3_mask   0x80000000
#define cp0_status_cu_mask   0xf0000000
#define cp0_status_ie_shift   0
#define cp0_status_exl_shift   1
#define cp0_status_erl_shift   2
#define cp0_status_ksu_shift   3
#define cp0_status_ux_shift   5
#define cp0_status_sx_shift   6
#define cp0_status_kx_shift   7
#define cp0_status_im_shift   8
#define cp0_status_de_shift   16
#define cp0_status_ce_shift   17
#define cp0_status_ch_shift   18
#define cp0_status_res1_shift   19
#define cp0_status_sr_shift   20
#define cp0_status_ts_shift   21
#define cp0_status_bev_shift   22
#define cp0_status_res2_shift   23
#define cp0_status_re_shift   25
#define cp0_status_fr_shift   26
#define cp0_status_rp_shift   27
#define cp0_status_cu0_shift   28
#define cp0_status_cu1_shift   29
#define cp0_status_cu2_shift   30
#define cp0_status_cu3_shift   31
#define cp0_status_cu_shift   28
#define cp0_status_ie(r)   (((r) & cp0_status_ie_mask) >> cp0_status_ie_shift)
#define cp0_status_exl(r)   (((r) & cp0_status_exl_mask) >> cp0_status_exl_shift)
#define cp0_status_erl(r)   (((r) & cp0_status_erl_mask) >> cp0_status_erl_shift)
#define cp0_status_ksu(r)   (((r) & cp0_status_ksu_mask) >> cp0_status_ksu_shift)
#define cp0_status_ux(r)   (((r) & cp0_status_ux_mask) >> cp0_status_ux_shift)
#define cp0_status_sx(r)   (((r) & cp0_status_sx_mask) >> cp0_status_sx_shift)
#define cp0_status_kx(r)   (((r) & cp0_status_kx_mask) >> cp0_status_kx_shift)
#define cp0_status_im(r)   (((r) & cp0_status_im_mask) >> cp0_status_im_shift)
#define cp0_status_de(r)   (((r) & cp0_status_de_mask) >> cp0_status_de_shift)
#define cp0_status_ce(r)   (((r) & cp0_status_ce_mask) >> cp0_status_ce_shift)
#define cp0_status_ch(r)   (((r) & cp0_status_ch_mask) >> cp0_status_ch_shift)
#define cp0_status_res1(r)   (((r) & cp0_status_res1_mask) >> cp0_status_res1_shift)
#define cp0_status_sr(r)   (((r) & cp0_status_sr_mask) >> cp0_status_sr_shift)
#define cp0_status_ts(r)   (((r) & cp0_status_ts_mask) >> cp0_status_ts_shift)
#define cp0_status_bev(r)   (((r) & cp0_status_bev_mask) >> cp0_status_bev_shift)
#define cp0_status_res2(r)   (((r) & cp0_status_res2_mask) >> cp0_status_res2_shift)
#define cp0_status_re(r)   (((r) & cp0_status_re_mask) >> cp0_status_re_shift)
#define cp0_status_fr(r)   (((r) & cp0_status_fr_mask) >> cp0_status_fr_shift)
#define cp0_status_rp(r)   (((r) & cp0_status_rp_mask) >> cp0_status_rp_shift)
#define cp0_status_cu0(r)   (((r) & cp0_status_cu0_mask) >> cp0_status_cu0_shift)
#define cp0_status_cu1(r)   (((r) & cp0_status_cu1_mask) >> cp0_status_cu1_shift)
#define cp0_status_cu2(r)   (((r) & cp0_status_cu2_mask) >> cp0_status_cu2_shift)
#define cp0_status_cu3(r)   (((r) & cp0_status_cu3_mask) >> cp0_status_cu3_shift)
#define cp0_status_cu(r)   (((r) & cp0_status_cu_mask) >> cp0_status_cu_shift)

EntryHi

EntryHi register (read-write) is a part of the TLB entry description. It consists of the vitrual page number (high bits) field and the 8-bit address space identification.

#define cp0_entryhi_asid_mask   0x000000ff
#define cp0_entryhi_res1_mask   0x00001f00
#define cp0_entryhi_vpn2_mask   0xffffe000
#define cp0_entryhi_asid_shift   0
#define cp0_entryhi_res1_shift   8
#define cp0_entryhi_vpn2_shift   13
#define cp0_entryhi_asid(r)   (((r) & cp0_entryhi_asid_mask) >> cp0_entryhi_asid_shift)
#define cp0_entryhi_res1(r)   (((r) & cp0_entryhi_res1_mask) >> cp0_entryhi_res1_shift)
#define cp0_entryhi_vpn2(r)   (((r) & cp0_entryhi_vpn2_mask) >> cp0_entryhi_vpn2_shift)

EntryLo

EntryLo(0/1) registers (read/write) consists of the physical page number field and dirty, valid and global bits.

#define cp0_entrylo_g_mask   0x00000001
#define cp0_entrylo_v_mask   0x00000002
#define cp0_entrylo_d_mask   0x00000004
#define cp0_entrylo_c_mask   0x00000038
#define cp0_entrylo_pfn_mask   0x3fffffc0
#define cp0_entrylo_res1_mask   0xc0000000
#define cp0_entrylo_g_shift   0
#define cp0_entrylo_v_shift   1
#define cp0_entrylo_d_shift   2
#define cp0_entrylo_c_shift   3
#define cp0_entrylo_pfn_shift   6
#define cp0_entrylo_res1_shift   30
#define cp0_entrylo0_g(r)   (((r) & cp0_entrylo_g_mask) >> cp0_entrylo_g_shift)
#define cp0_entrylo0_v(r)   (((r) & cp0_entrylo_v_mask) >> cp0_entrylo_v_shift)
#define cp0_entrylo0_d(r)   (((r) & cp0_entrylo_d_mask) >> cp0_entrylo_d_shift)
#define cp0_entrylo0_c(r)   (((r) & cp0_entrylo_c_mask) >> cp0_entrylo_c_shift)
#define cp0_entrylo0_pfn(r)   (((r) & cp0_entrylo_pfn_mask) >> cp0_entrylo_pfn_shift)
#define cp0_entrylo0_res1(r)   (((r) & cp0_entrylo_res1_mask) >> cp0_entrylo_res1_shift)
#define cp0_entrylo1_g   (((r) & cp0_entrylo_g_mask) >> cp0_entrylo_g_shift)
#define cp0_entrylo1_v   (((r) & cp0_entrylo_v_mask) >> cp0_entrylo_v_shift)
#define cp0_entrylo1_d   (((r) & cp0_entrylo_d_mask) >> cp0_entrylo_d_shift)
#define cp0_entrylo1_c   (((r) & cp0_entrylo_c_mask) >> cp0_entrylo_c_shift)
#define cp0_entrylo1_pfn   (((r) & cp0_entrylo_pfn_mask) >> cp0_entrylo_pfn_shift)
#define cp0_entrylo1_res1   (((r) & cp0_entrylo_res1_mask) >> cp0_entrylo_res1_shift)

Wired Register

Wired Register (read-write) specifies the limit of the TLBWR random pool. Page entries may be loaded into random TLB slots using the TLBWR instruction. A kernel designer may specify via Wired Register a set of pages which could not be replaced randomly. This is typically useful for heavily used or system pages.

#define cp0_wired_w_mask   0x0000001f
#define cp0_wired_res1_mask   0xffffffe0
#define cp0_wired_w_shift   0
#define cp0_wired_res1_shift   6
#define cp0_wired_w(r)   (((r) & cp0_wired_w_mask) >> cp0_wired_w_shift)
#define cp0_wired_res1(r)   (((r) & cp0_wired_res1_mask) >> cp0_wired_res1_shift)

Context register

Context is a read-write register which is filled after the TLB exception with a pointer into the page table entry array - this is a operating system structure. This register is similar to BadVAddr except that it is more useful for a software exception handler.

BadVPN2 is filled by the hardware when a TBL miss occurs. PTEBase is filled by the operating system.

#define cp0_context_res1_mask   0x0000000f
#define cp0_context_badvpn2_mask   0x007ffff0
#define cp0_context_ptebase_mask   0xff800000
#define cp0_context_res1_shift   0
#define cp0_context_badvpn2_shift   4
#define cp0_context_ptebase_shift   23
#define cp0_context_res1(r)   (((r) & cp0_context_res1_mask) >> cp0_context_res1_shift)
#define cp0_context_badvpn2(r)   (((r) & cp0_context_badvpn2_mask) >> cp0_context_badvpn2_shift)
#define cp0_context_ptebase(r)   (((r) & cp0_context_ptebase_mask) >> cp0_context_ptebase_shift)

Pagemask register

Pagemask register is a read-write register used for work with TLB. Typically, the Pagemask register is loaded with appropriate value as a page size of a new TLB item.

#define cp0_pagemask_res1_mask   0x00001fff
#define cp0_pagemask_mask_mask   0x01ffe000
#define cp0_pagemask_res2_mask   0xfe000000
#define cp0_pagemask_res1_shift   0
#define cp0_pagemask_mask_shift   13
#define cp0_pagemask_res2_shift   25
#define cp0_pagemask_res1(r)   (((r) & cp0_pagemask_res1_mask) >> cp0_pagemask_res1_shift)
#define cp0_pagemask_mask(r)   (((r) & cp0_pagemask_mask_mask) >> cp0_pagemask_mask_shift)
#define cp0_pagemask_res2(r)   (((r) & cp0_pagemask_res2_mask) >> cp0_pagemask_res2_shift)
#define PAGEMASK_4K   (0x000 << cp0_pagemask_mask_shift)
#define PAGEMASK_16K   (0x003 << cp0_pagemask_mask_shift)
#define PAGEMASK_64K   (0x00f << cp0_pagemask_mask_shift)
#define PAGEMASK_256K   (0x03f << cp0_pagemask_mask_shift)
#define PAGEMASK_1M   (0x0ff << cp0_pagemask_mask_shift)
#define PAGEMASK_4M   (0x3ff << cp0_pagemask_mask_shift)
#define PAGEMASK_16M   (0xfff << cp0_pagemask_mask_shift)

Count register

Count Register (read-write) is a counter of system ticks. It is also used for timing purposes.

#define cp0_count_count_mask   0xffffffff
#define cp0_count_count_shift   0
#define cp0_count_count(r)   (((r) & cp0_count_count_mask) >> cp0_count_count_shift)
#define cp0_badvaaddr_badvaaddr_mask   0xffffffff
#define cp0_badvaaddr_badvaaddr_shift   0
#define cp0_badvaaddr_badvaaddr(r)   (((r) & cp0_badvaaddr_badvaaddr_mask) >> cp0_badvaaddr_badvaaddr_shift)

Compare register

Compare is a read-write register which stores the value of ticks.

When the values of Compare and Count registers are equal, an interrupt pending no. 7 is assured. These two registers are used as an internal timer.

The timer interrupt is deasserted when a new value is written.

#define cp0_compare_compare_mask   0xffffffff
#define cp0_compare_compare_shift   0
#define cp0_compare_compare(r)   (((r) & cp0_compare_compare_mask) >> cp0_compare_compare_shift)

Exception Program Counter

read-write

Displays the address at which the exception occurs. If the instruction was in the branch delay, epc points to the jump/branch instruction and the bd field in the Cause register is set to 1.

This register is used by the RET instruction.

#define cp0_epc_epc_mask   0xffffffff
#define cp0_epc_epc_shift   0
#define cp0_epc_epc(r)   (((r) & cp0_epc_epc_mask) >> cp0_epc_epc_shift)

Cause Register

read-write

The Cause Register contains general information about the last exception. It consists of four fields - exccode, ip, ce and bd.

exccode stores the exception type - see exception() in exc.c for more information. The ip field is a bit mask, each bit corresponds to an interrupt specified. It is valid only when the interrupt exception occurs. The ce field stores the coprocessor index which was addressed when the Coprocessor unusable exception occurs. At last, the bd field indicates that the exception occurs at the branch delay. In such a case, the Error Program Counter stores the address of the jump/branch instruction.

#define cp0_cause_res1_mask   0x00000003
#define cp0_cause_exccode_mask   0x0000007c
#define cp0_cause_res2_mask   0x00000080
#define cp0_cause_ip_mask   0x0000ff00
#define cp0_cause_ip0_mask   0x00000100
#define cp0_cause_ip1_mask   0x00000200
#define cp0_cause_ip2_mask   0x00000400
#define cp0_cause_ip3_mask   0x00000800
#define cp0_cause_ip4_mask   0x00001000
#define cp0_cause_ip5_mask   0x00002000
#define cp0_cause_ip6_mask   0x00004000
#define cp0_cause_ip7_mask   0x00008000
#define cp0_cause_res3_mask   0x0fff0000
#define cp0_cause_ce_mask   0x30000000
#define cp0_cause_bd_mask   0x80000000
#define cp0_cause_res4_mask   0x40000000
#define cp0_cause_ce_cu1   0x10000000
#define cp0_cause_ce_cu2   0x20000000
#define cp0_cause_ce_cu3   0x30000000
#define cp0_cause_res1_shift   0
#define cp0_cause_exccode_shift   2
#define cp0_cause_res2_shift   7
#define cp0_cause_ip_shift   8
#define cp0_cause_ip0_shift   8
#define cp0_cause_ip1_shift   9
#define cp0_cause_ip2_shift   10
#define cp0_cause_ip3_shift   11
#define cp0_cause_ip4_shift   12
#define cp0_cause_ip5_shift   13
#define cp0_cause_ip6_shift   14
#define cp0_cause_ip7_shift   15
#define cp0_cause_res3_shift   16
#define cp0_cause_ce_shift   28
#define cp0_cause_res4_shift   30
#define cp0_cause_bd_shift   31
#define cp0_cause_res1(r)   (((r) & cp0_cause_res1_mask) >> cp0_cause_res1_shift)
#define cp0_cause_exccode(r)   (((r) & cp0_cause_exccode_mask) >> cp0_cause_exccode_shift)
#define cp0_cause_res2(r)   (((r) & cp0_cause_res2_mask) >> cp0_cause_res2_shift)
#define cp0_cause_ip(r)   (((r) & cp0_cause_ip_mask) >> cp0_cause_ip_shift)
#define cp0_cause_res3(r)   (((r) & cp0_cause_res3_mask) >> cp0_cause_res3_shift)
#define cp0_cause_ce(r)   (((r) & cp0_cause_ce_mask) >> cp0_cause_ce_shift)
#define cp0_cause_res4(r)   (((r) & cp0_cause_res4_mask) >> cp0_cause_res4_shift)
#define cp0_cause_bd(r)   (((r) & cp0_cause_bd_mask) >> cp0_cause_bd_shift)
#define cp0_lladdr_lladdr   cp0_lladdr

MIPS R4000 Memory Operating Modes

The CPU uses the three highest bits of a virtual address to choose the type of the address.

#define OM_USER   0x00000000
#define OM_KSEG0   0x80000000
#define OM_KSEG1   0xa0000000
#define OM_KSSEG   0xc0000000
#define OM_KSEG3   0xe0000000
void switch_cpu_context (void **kst1, void *kst2)
 Switch_cpu_context.


Detailed Description

This file contains system dependents definitions.


Define Documentation

#define cp0_badvaaddr_badvaaddr_mask   0xffffffff

@ Bad Virtual Address Register

Bad Virtual Address Register contains the virtual address that causes a TLB exception. BadVAddr is read-only.

#define cp0_lladdr_lladdr   cp0_lladdr

LLAddr register stores an address that was passed by the LL instruction. This address is controlled by the hardware. When the context of the address has been changed, the SC instruction will fail.

#define read_cp0_reg ( regno   ) 

Value:

({ int __res;                                   \
        asm volatile (                                  \
                "       .set    push\n"                 \
                "       .set    noreorder\n"            \
                "       nop\n"                          \
                "       mfc0    %0, $"#regno"\n"        \
                "       .set    pop\n"                  \
                : "=r" (__res));                        \
        __res; })

 
#define TLBWI (  ) 

Value:

asm volatile (                  \
                "       tlbwi\n"        \
                );
Inline function write_tlb writes the page specified by entryhi, entrylo0, entrylo1 and pagemask into the TLB. The position is specified by the Index register.

 
#define TLBWR (  ) 

Value:

asm volatile (                  \
                "       tlbwr\n"        \
                );
Inline function write_tlb writes the page specified by entryhi, entrylo0, entrylo1 and pagemask into the TLB. The position is specified by the Random register.

#define write_cp0_reg ( regno,
 ) 

Value:

asm volatile (                                  \
                "       .set    push\n"                 \
                "       .set    noreorder\n"            \
                "       nop\n"                          \
                "       mtc0    %0, $"#regno"\n"        \
                "       .set    pop\n"                  \
                :: "r" (i) );


Function Documentation

void switch_cpu_context ( void **  kst1,
void *  kst2 
)

Switch_cpu_context.

Switches processor context from one thread to another. The first argument points to a pointer to the top of the stack of the current thread, the second argument points to a kernel stack of the target thread.


Generated on Wed Nov 15 17:25:44 2006 for Kalisto by  doxygen 1.4.7