diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-09-29 21:37:04 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-09-29 21:37:04 +0000 |
commit | 2b973049de2355df47d511a1636b501618d4ae27 (patch) | |
tree | b14ca04ad15fb5015d47afdbccbfef67e231168a /sys/arch/mips64/include | |
parent | 46f18ef0a87684c975e693f1aa36b587114d7a35 (diff) |
Basic R8000 processor support. R8000 processors require MMU-specific code,
exception-specific code, clock-specific code, and L1 cache-specific code. L2
cache is per-design, of which only two exist: SGI Power Indigo2 (IP26) and SGI
Power Challenge (IP21) and are not covered by this commit.
R8000 processors also are 64-bit only processors with 64-bit coprocessor 0
registers, and lack so-called ``compatibility'' memory spaces allowing 32-bit
code to run with sign-extended addresses and registers.
The intrusive changes are covered by #ifdef CPU_R8000 stanzas. However,
trap() is split into a high-level wrapper and a new function, itsa(),
responsible for the actual trap servicing (which name couldn't be helped
because I'm an incorrigible punster). While an R8000 exception may cause
(via trap() ) multiple exceptions to be serviced, non-R8000 processors will
always service one exception in trap(), but they are nevertheless affected
by this code split.
Diffstat (limited to 'sys/arch/mips64/include')
-rw-r--r-- | sys/arch/mips64/include/asm.h | 35 | ||||
-rw-r--r-- | sys/arch/mips64/include/cache.h | 9 | ||||
-rw-r--r-- | sys/arch/mips64/include/cpu.h | 77 | ||||
-rw-r--r-- | sys/arch/mips64/include/mips_opcode.h | 3 | ||||
-rw-r--r-- | sys/arch/mips64/include/pte.h | 29 |
5 files changed, 143 insertions, 10 deletions
diff --git a/sys/arch/mips64/include/asm.h b/sys/arch/mips64/include/asm.h index 8de2128eb92..127ad53528b 100644 --- a/sys/arch/mips64/include/asm.h +++ b/sys/arch/mips64/include/asm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asm.h,v 1.17 2012/09/29 19:02:25 miod Exp $ */ +/* $OpenBSD: asm.h,v 1.18 2012/09/29 21:37:03 miod Exp $ */ /* * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -174,12 +174,29 @@ #define PTR_VAL .dword #endif +/* + * The following macros are here to benefit the R8000 processor: + * - all coprocessor 0 control registers are 64-bit + * - the regular nop (sll zero, zero, 0) has the drawback of using the + * shifter, potentially breaking instruction dispatch if occuring after + * another instruction using the shifter. + */ +#ifdef CPU_R8000 +#define SSNOP sll zero, zero, 1 /* ``ssnop'' */ +#define NOP PTR_ADDU zero, zero, zero /* real nop for R8000 */ +#define DMFC0 SSNOP; dmfc0 +#define DMTC0 SSNOP; dmtc0 +#define MFC0 SSNOP; dmfc0 +#define MTC0 SSNOP; dmtc0 +#define ERET eret; mul k0, k0; mflo k0 +#else #define NOP nop #define DMFC0 dmfc0 #define DMTC0 dmtc0 #define MFC0 mfc0 #define MTC0 mtc0 #define ERET sync; eret +#endif /* * Define -pg profile entry code. @@ -330,6 +347,22 @@ x: ; \ #define TLB_HAZARD NOP; NOP; NOP; NOP #endif +#ifdef CPU_R8000 +/* + * The R8000 needs a lot of care inserting proper superscalar dispatch breaks + * to prevent unwanted side-effects or avoid collisions on the internal MiscBus + * and the E and W stages of the pipelines. + * + * The following settings are a bit pessimistic, but better run safely than + * not at all. + */ +#define PRE_MFC0_ADDR_HAZARD .align 5; SSNOP +#define MFC0_HAZARD SSNOP +#define MTC0_HAZARD SSNOP; SSNOP; SSNOP +#define MTC0_SR_IE_HAZARD MTC0_HAZARD; SSNOP +#define MTC0_SR_CU_HAZARD MTC0_HAZARD; SSNOP +#endif + /* Hazard between {d,}mfc0 of COP_0_VADDR */ #ifndef PRE_MFC0_ADDR_HAZARD #define PRE_MFC0_ADDR_HAZARD /* nothing */ diff --git a/sys/arch/mips64/include/cache.h b/sys/arch/mips64/include/cache.h index 300b6b4d00f..7942cd9838b 100644 --- a/sys/arch/mips64/include/cache.h +++ b/sys/arch/mips64/include/cache.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cache.h,v 1.4 2012/06/24 20:20:37 miod Exp $ */ +/* $OpenBSD: cache.h,v 1.5 2012/09/29 21:37:03 miod Exp $ */ /* * Copyright (c) 2012 Miodrag Vallat. @@ -66,6 +66,11 @@ CACHE_PROTOS(Mips4k) CACHE_PROTOS(Mips5k) /* + * MIPS (SGI, really) R8000. + */ +CACHE_PROTOS(tfp) + +/* * MIPS/NEC R10000/R120000/R140000/R16000. */ CACHE_PROTOS(Mips10k) @@ -75,7 +80,7 @@ CACHE_PROTOS(Mips10k) * bus_dmamap_sync()]. */ #define CACHE_SYNC_R 0 /* WB invalidate, WT invalidate */ -#define CACHE_SYNC_W 1 /* WB writeback + invalidate, WT unaffected */ +#define CACHE_SYNC_W 1 /* WB writeback, WT unaffected */ #define CACHE_SYNC_X 2 /* WB writeback + invalidate, WT invalidate */ extern vaddr_t cache_valias_mask; diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h index 8ca4a8fe90b..7e7a17e89d1 100644 --- a/sys/arch/mips64/include/cpu.h +++ b/sys/arch/mips64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.88 2012/09/29 19:42:30 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.89 2012/09/29 21:37:03 miod Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -149,16 +149,37 @@ #define SR_INT_MASK_4 0x00004000 #define SR_INT_MASK_5 0x00008000 +/* R8000-specific bits */ +#define SR_SERIALIZE_FPU 0x0000010000000000 +#define SR_KPGSZ_SHIFT 36 +#define SR_UPGSZ_SHIFT 32 +#define SR_PGSZ_4K 0 +#define SR_PGSZ_8K 1 +#define SR_PGSZ_16K 2 +#define SR_PGSZ_64K 3 +#define SR_PGSZ_1M 4 +#define SR_PGSZ_4M 5 +#define SR_PGSZ_16M 6 +#define SR_PGSZ_MASK 0x0f + #define SR_INT_MASK_6 0x00010000 #define SR_INT_MASK_7 0x00020000 #define SR_INT_MASK_8 0x00040000 +#ifdef CPU_R8000 +#define SR_XX 0x00000040 +#define SR_KSU_MASK 0x00000010 +#define SR_KSU_USER 0x00000010 +#define SR_KSU_KERNEL 0x00000000 +#define SR_INT_MASK 0x0007ff00 +#else #define SR_XX 0x80000000 #define SR_KSU_MASK 0x00000018 #define SR_KSU_USER 0x00000010 #define SR_KSU_SUPER 0x00000008 #define SR_KSU_KERNEL 0x00000000 #define SR_INT_MASK 0x0000ff00 +#endif /* * Interrupt control register in RM7000. Expansion of interrupts. @@ -179,10 +200,17 @@ * Cause register. */ +#ifdef CPU_R8000 +#define CR_BR_DELAY 0x8000000000000000 +#define CR_EXC_CODE 0x000000f8 +#define CR_EXC_CODE_SHIFT 3 +#define CR_COP_ERR 0x10000000 +#else #define CR_BR_DELAY 0x80000000 #define CR_EXC_CODE 0x0000007c #define CR_EXC_CODE_SHIFT 2 #define CR_COP_ERR 0x30000000 +#endif #define CR_COP1_ERR 0x10000000 #define CR_COP2_ERR 0x20000000 #define CR_COP3_ERR 0x20000000 @@ -194,16 +222,26 @@ #define CR_INT_3 0x00002000 #define CR_INT_4 0x00004000 #define CR_INT_5 0x00008000 -/* Following on RM7000 */ +/* Following on RM7000 and R8000 */ #define CR_INT_6 0x00010000 #define CR_INT_7 0x00020000 #define CR_INT_8 0x00040000 +/* Following on RM7000 */ #define CR_INT_9 0x00080000 #define CR_INT_HARD 0x000ffc00 #define CR_INT_TIMR 0x00100000 /* 12 Timer */ #define CR_INT_PERF 0x00200000 /* 13 Performance counter */ - +/* R8000 specific */ +#define CR_FPE 0x01000000 +#define CR_VCE 0x02000000 +#define CR_BERR 0x04000000 +#define CR_NMI 0x08000000 + +#ifdef CPU_R8000 +#define CR_INT_MASK 0x0407ff00 /* contains CR_BERR */ +#else #define CR_INT_MASK 0x003fff00 +#endif /* * Config register. @@ -218,11 +256,20 @@ * Location of exception vectors. */ +#ifdef CPU_R8000 +#define RESET_EXC_VEC PHYS_TO_XKPHYS(0x1fc00000, CCA_NC) +/* all the others are relative to COP_0_TRAPBASE */ +/* #define UTLB_MISS_EXC_VEC 0x00000000 */ +/* #define KV1TLB_MISS_EXC_VEC 0x00000400 */ +/* #define KV0TLB_MISS_EXC_VEC 0x00000800 */ +/* #define GEN_EXC_VEC 0x00000c00 */ +#else #define RESET_EXC_VEC (CKSEG1_BASE + 0x1fc00000) #define TLB_MISS_EXC_VEC (CKSEG1_BASE + 0x00000000) #define XTLB_MISS_EXC_VEC (CKSEG1_BASE + 0x00000080) #define CACHE_ERR_EXC_VEC (CKSEG1_BASE + 0x00000100) #define GEN_EXC_VEC (CKSEG1_BASE + 0x00000180) +#endif /* * Coprocessor 0 registers @@ -257,6 +304,22 @@ #define COP_0_TAG_HI $29 #define COP_0_ERROR_PC $30 +/* R8000 specific */ +#define COP_0_TLB_SET $0 +#define COP_0_TLB_LO $2 +#define COP_0_UBASE $4 +#define COP_0_SHIFTAMT $5 +#define COP_0_TRAPBASE $6 +#define COP_0_BAD_PADDR $7 +#define COP_0_VADDR $8 +#define COP_0_WORK0 $18 +#define COP_0_WORK1 $19 +#define COP_0_PBASE $20 +#define COP_0_GBASE $21 +#define COP_0_TFP_TLB_WIRED $24 +#define COP_0_DCACHE $28 +#define COP_0_ICACHE $29 + /* RM7000 specific */ #define COP_0_WATCH_1 $18 #define COP_0_WATCH_2 $19 @@ -281,7 +344,7 @@ /* * COP_0_COUNT speed divider. */ -#if defined(CPU_OCTEON) +#if defined(CPU_OCTEON) || defined(CPU_R8000) #define CP0_CYCLE_DIVIDER 1 #else #define CP0_CYCLE_DIVIDER 2 @@ -499,7 +562,12 @@ void cp0_calibrate(struct cpu_info *); #define aston(p) p->p_md.md_astpending = 1 +#ifdef CPU_R8000 +#define mips_sync() __asm__ __volatile__ ("lw $0, 0(%0)" :: \ + "r" (PHYS_TO_XKPHYS(0, CCA_NC)) : "memory") +#else #define mips_sync() __asm__ __volatile__ ("sync" ::: "memory") +#endif #endif /* _KERNEL && !_LOCORE */ @@ -562,6 +630,7 @@ void tlb_asid_wrap(struct cpu_info *); void tlb_flush(int); void tlb_flush_addr(vaddr_t); void tlb_init(unsigned int); +void tlb_set_gbase(vaddr_t, vsize_t); void tlb_set_page_mask(uint32_t); void tlb_set_pid(u_int); void tlb_set_wired(uint32_t); diff --git a/sys/arch/mips64/include/mips_opcode.h b/sys/arch/mips64/include/mips_opcode.h index 816fcd6eb23..cf04aa23a43 100644 --- a/sys/arch/mips64/include/mips_opcode.h +++ b/sys/arch/mips64/include/mips_opcode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mips_opcode.h,v 1.7 2012/04/21 19:13:14 miod Exp $ */ +/* $OpenBSD: mips_opcode.h,v 1.8 2012/09/29 21:37:03 miod Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -306,6 +306,7 @@ typedef union { #define OP_MTH 007 #define OP_BC 010 #define OP_C0MISC 020 /* cop0 only */ +#define OP_TFP_C0MISC 030 /* cop0 only on R8000 */ /* * Values for the 'rt' field when 'op' == OP_COPz. diff --git a/sys/arch/mips64/include/pte.h b/sys/arch/mips64/include/pte.h index 7f329e4983d..377ea98fd28 100644 --- a/sys/arch/mips64/include/pte.h +++ b/sys/arch/mips64/include/pte.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pte.h,v 1.14 2012/09/29 19:11:08 miod Exp $ */ +/* $OpenBSD: pte.h,v 1.15 2012/09/29 21:37:03 miod Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -38,7 +38,7 @@ */ /* - * R4000 hardware page table entries + * R4000 and R8000 hardware page table entries */ #ifndef _LOCORE @@ -62,22 +62,40 @@ typedef u_int32_t pt_entry_t; /* Mips page table entry */ #endif /* _LOCORE */ /* entryhi values */ +#ifndef CPU_R8000 #define PG_HVPN (-2 * PAGE_SIZE) /* Hardware page number mask */ #define PG_ODDPG PAGE_SIZE +#endif /* !R8000 */ /* Address space ID */ +#ifdef CPU_R8000 +#define PG_ASID_MASK 0x0000000000000ff0 +#define PG_ASID_SHIFT 4 +#define ICACHE_ASID_SHIFT 40 +#define MIN_USER_ASID 0 +#else #define PG_ASID_MASK 0x00000000000000ff #define PG_ASID_SHIFT 0 #define MIN_USER_ASID 1 +#endif #define PG_ASID_COUNT 256 /* Number of available ASID */ /* entrylo values */ +#ifdef CPU_R8000 +#define PG_WIRED 0x00000010 /* SW */ +#define PG_RO 0x00000020 /* SW */ +#define PG_G 0x00000000 /* no such concept for R8000 */ +#define PG_V 0x00000080 +#define PG_M 0x00000100 +#define PG_CCA_SHIFT 9 +#else #define PG_WIRED 0x80000000 /* SW */ #define PG_RO 0x40000000 /* SW */ #define PG_G 0x00000001 /* HW */ #define PG_V 0x00000002 #define PG_M 0x00000004 #define PG_CCA_SHIFT 3 +#endif #define PG_NV 0x00000000 #define PG_UNCACHED (CCA_NC << PG_CCA_SHIFT) @@ -93,13 +111,19 @@ typedef u_int32_t pt_entry_t; /* Mips page table entry */ #define PG_CWPAGE (PG_V | PG_CACHED) /* Not w-prot but clean */ #define PG_IOPAGE (PG_G | PG_V | PG_M | PG_UNCACHED) +#ifdef CPU_R8000 +#define PG_FRAME 0xfffff000 +#define PG_SHIFT 0 +#else #define PG_FRAME 0x3fffffc0 #define PG_FRAMEBITS 30 #define PG_SHIFT 6 +#endif #define pfn_to_pad(pa) ((((paddr_t)pa) & PG_FRAME) << PG_SHIFT) #define vad_to_pfn(va) (((va) >> PG_SHIFT) & PG_FRAME) +#ifndef CPU_R8000 #define PG_SIZE_4K 0x00000000 #define PG_SIZE_16K 0x00006000 #define PG_SIZE_64K 0x0001e000 @@ -112,6 +136,7 @@ typedef u_int32_t pt_entry_t; /* Mips page table entry */ #elif PAGE_SHIFT == 14 #define TLB_PAGE_MASK PG_SIZE_16K #endif +#endif /* !R8000 */ #if defined(_KERNEL) && !defined(_LOCORE) |