diff options
author | imp <imp@FreeBSD.org> | 2010-01-10 19:50:24 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2010-01-10 19:50:24 +0000 |
commit | 6e3a5d426c5122a7b7d87af88b49b98148906b74 (patch) | |
tree | 4f25124352c606904a7e0ca13039d221f6445446 | |
parent | 6ebe36097bb2819ae55919926e17d6d04a4a8778 (diff) | |
download | FreeBSD-src-6e3a5d426c5122a7b7d87af88b49b98148906b74.zip FreeBSD-src-6e3a5d426c5122a7b7d87af88b49b98148906b74.tar.gz |
Merge from projects/mips to head by hand:
r201881 | imp | 2010-01-08 20:08:22 -0700 (Fri, 08 Jan 2010) | 3 lines
Rename mips_pcpu_init to mips_pcpu0_init since it applies only to the
BSP. Provide a missing prototype.
r200343 | imp | 2009-12-09 18:44:11 -0700 (Wed, 09 Dec 2009) | 4 lines
Get the sense of this right. We use uintpr_t for bus_addr_t when
we're building everything except octeon && 32-bit. As note before, we
need a clearner way, but at least now the hack is right.
r199760 | imp | 2009-11-24 10:15:22 -0700 (Tue, 24 Nov 2009) | 2 lines
Add in Cavium's CID. Report what the unknown CID is.
r199754 | imp | 2009-11-24 09:32:31 -0700 (Tue, 24 Nov 2009) | 6 lines
Include opt_cputype.h for all .c and .S files referencing TARGET_OCTEON.
Spell ld script name right.
r199599 | imp | 2009-11-20 09:32:26 -0700 (Fri, 20 Nov 2009) | 2 lines
Another kludge for 64-bit bus_addr_t with 32-bit pointers...
r199496 | gonzo | 2009-11-18 15:52:05 -0700 (Wed, 18 Nov 2009) | 5 lines
- Add cpu_init_interrupts function that is supposed to
prepeare stuff required for spinning out interrupts later
- Add API for managing intrcnt/intrnames arrays
- Some minor style(9) fixes
r198958 | rrs | 2009-11-05 11:15:47 -0700 (Thu, 05 Nov 2009) | 2 lines
For XLR adds extern for its bus space routines
r198669 | rrs | 2009-10-30 02:53:11 -0600 (Fri, 30 Oct 2009) | 5 lines
With this commit our friend RMI will now compile. I have
not tested it and the chances of it running yet are about
ZERO.. but it will now compile. The hard part now begins,
making it run ;-)
r198666 | imp | 2009-10-29 18:37:50 -0600 (Thu, 29 Oct 2009) | 2 lines
Add some newer MIPS CO cores.
r198665 | imp | 2009-10-29 18:37:04 -0600 (Thu, 29 Oct 2009) | 4 lines
db_expr_t is really closer to a register_t.
Submitted by: bde@
r198531 | gonzo | 2009-10-27 18:01:20 -0600 (Tue, 27 Oct 2009) | 3 lines
- Remove bunch of declared but not defined cach-related variables
- Add mips_picache_linesize and mips_pdcache_linesize variables
r198354 | neel | 2009-10-21 20:51:31 -0600 (Wed, 21 Oct 2009) | 9 lines
Get rid of the hardcoded constants to define cacheable memory:
SDRAM_ADDR_START, SDRAM_ADDR_END and SDRAM_MEM_SIZE
Instead we now keep a copy of the memory regions enumerated by
platform-specific code and use that to determine whether an address
is cacheable or not.
r198310 | gonzo | 2009-10-20 17:13:08 -0600 (Tue, 20 Oct 2009) | 5 lines
- Commit missing part of "bt" fix: store PC register in pcb_context struct
in cpu_switch and use it in stack_trace function later. pcb_regs contains
state of the process stored by exception handler and therefor is not
valid for sleeping processes.
r198207 | imp | 2009-10-18 08:57:04 -0600 (Sun, 18 Oct 2009) | 2 lines
Undo spamage of last MFC.
r198206 | imp | 2009-10-18 08:56:33 -0600 (Sun, 18 Oct 2009) | 3 lines
_ALIGN has to return u_long, since pointers don't fit into u_int in
64-bit mips.
r198182 | gonzo | 2009-10-16 18:22:07 -0600 (Fri, 16 Oct 2009) | 11 lines
- Use PC/RA/SP values as arguments for stacktrace_subr instead of trapframe.
Context info could be obtained from other sources (see below) no only from
td_pcb field
- Do not show a0..a3 values unless they're obtained from the stack. These
are only confirmed values.
- Fix bt command in DDB. Previous implementation used thread's trapframe
structure as a source info for trace unwinding, but this structure
is filled only when exception occurs. Valid register values for sleeping
processes are in pcb_context array. For curthread use pc/sp/ra for current
frame
r198181 | gonzo | 2009-10-16 16:52:18 -0600 (Fri, 16 Oct 2009) | 2 lines
- Get rid of label_t. It came from NetBSD and was used only in one place
r198154 | rrs | 2009-10-15 15:03:32 -0600 (Thu, 15 Oct 2009) | 10 lines
Does 4 things:
1) Adds future RMI directories
2) Places intr_machdep.c in specfic files.arch pointing to the generic
intr_machdep.c. This allows us to have an architecture dependant
intr_machdep.c (which we will need for RMI) in the machine specific
directory
3) removes intr_machdep.c from files.mips
4) Adds some TARGET_XLR_XLS ifdef's for the machine specific intra_machdep.h. We
may need to look at finding a better place to put this. But first I want to
get this thing compiling.
r198066 | gonzo | 2009-10-13 19:43:53 -0600 (Tue, 13 Oct 2009) | 5 lines
- Move stack tracing function to db_trace.c
- Axe unused extern MipsXXX declarations
- Move all declarations for functions in exceptions.S/swtch.S
from trap.c to respective headers
r197685 | gonzo | 2009-10-01 14:05:36 -0600 (Thu, 01 Oct 2009) | 2 lines
- Sync caches properly when dealing with sf_buf
r196215 | imp | 2009-08-14 10:15:18 -0600 (Fri, 14 Aug 2009) | 6 lines
(u_int) is the wrong type here. Use unsigned long instead, even
though that's only less wrong...
r196199 | imp | 2009-08-13 13:47:13 -0600 (Thu, 13 Aug 2009) | 7 lines
Use unsigned long instead of unsigned for the integer casts here. The
former works for both ILP32 and LP64 programming models, while the
latter fails LP64.
r196089 | gonzo | 2009-08-09 19:49:59 -0600 (Sun, 09 Aug 2009) | 4 lines
- Make i/d cache size field 32-bit to prevent overflow
Submited by: Neelkanth Natu
r195582 | imp | 2009-07-10 13:07:07 -0600 (Fri, 10 Jul 2009) | 2 lines
fix prototype for MipsEmulateBranch.
r195581 | imp | 2009-07-10 13:06:43 -0600 (Fri, 10 Jul 2009) | 2 lines
Better definitions for a few types for n32/n64.
r195580 | imp | 2009-07-10 13:06:15 -0600 (Fri, 10 Jul 2009) | 5 lines
Fixed aligned macros...
r195478 | gonzo | 2009-07-08 16:28:36 -0600 (Wed, 08 Jul 2009) | 5 lines
- Port busdma code from FreeBSD/arm. This is more mature version
that takes into account all limitation to DMA memory (boundaries,
alignment) and implements bounce pages.
- Add BUS_DMASYNC_POSTREAD case to bus_dmamap_sync_buf
r195440 | imp | 2009-07-08 00:01:37 -0600 (Wed, 08 Jul 2009) | 2 lines
Fix atomic_store_64 prototype for 64-bit systems.
r195392 | imp | 2009-07-05 20:27:03 -0600 (Sun, 05 Jul 2009) | 3 lines
The MCOUNT macro isn't going to work in 64-bit mode. Add a note to
this effect.
r195391 | imp | 2009-07-05 20:22:51 -0600 (Sun, 05 Jul 2009) | 3 lines
Provide a macro for PTR_ADDU as well. We may need to implement this
differently for N32... Use PTR_ADDU in DO_AST macro.
r195390 | imp | 2009-07-05 20:22:06 -0600 (Sun, 05 Jul 2009) | 4 lines
Change the addu here to daddu.
addu paranoina prodded by: jmallet@
r195382 | imp | 2009-07-05 15:16:26 -0600 (Sun, 05 Jul 2009) | 5 lines
addu and subu are special. We need to use daddu and dsubu here to get
proper behavior.
Submitted by: jmallet@
r195370 | imp | 2009-07-05 09:20:16 -0600 (Sun, 05 Jul 2009) | 6 lines
The SB1 has cohernet memory, so add it.
Also, Maxmem is better as a long.
Submitted by: Neelkanth Natu
r195369 | imp | 2009-07-05 09:19:28 -0600 (Sun, 05 Jul 2009) | 4 lines
The SB1 needs a special value for the cache field of the pte.
Submitted by: Neelkanth Natu
r195368 | imp | 2009-07-05 09:18:06 -0600 (Sun, 05 Jul 2009) | 2 lines
compute the areas to save registers in for 64-bit access correctly.
r195367 | imp | 2009-07-05 09:17:11 -0600 (Sun, 05 Jul 2009) | 3 lines
First cut at 64-bit types. not 100% sure these are all correct for
N32 ABI.
r195366 | imp | 2009-07-05 09:16:27 -0600 (Sun, 05 Jul 2009) | 3 lines
Trim unreferenced goo. SDRAM likely should be next, but it is still
referenced.
r195365 | imp | 2009-07-05 09:13:24 -0600 (Sun, 05 Jul 2009) | 9 lines
First cut at atomics for 64-bit machines and SMP machines.
# Note: Cavium provided a port that has atomics similar to these, but
# that does a syncw; sync; atomic; sync; syncw where we just do the classic
# mips 'atomic' operation (eg ll; frob; sc). It is unclear to me why
# the extra is needed. Since my initial target is one core, I'll defer
# investigation until I bring up multiple cores. syncw is an octeon specific
# instruction.
r195359 | imp | 2009-07-05 02:14:00 -0600 (Sun, 05 Jul 2009) | 4 lines
Bring in cdefs.h from NetBSD to define ABI goo.
Obtained from: NetBSD
r195358 | imp | 2009-07-05 02:13:19 -0600 (Sun, 05 Jul 2009) | 4 lines
Pull in machine/cdefs.h for the ABI definitions. Provide a PTR_LA,
ala sgi, and use it in preference to a bare 'la' so that it gets
translated to a 'dla' for the 64-bit pointer ABIs.
r195357 | imp | 2009-07-05 01:01:34 -0600 (Sun, 05 Jul 2009) | 2 lines
Use uintptr_t rather than unsigned here for 64-bit correctness.
r195356 | imp | 2009-07-05 01:00:51 -0600 (Sun, 05 Jul 2009) | 6 lines
Define __ELF_WORD_SIZE appropriately for n64. Note for N32 I believe
this is correct. While registers are 64-bit, n32 is a 32-bit ABI and
lives in a 32-bit world (with explicit 64-bit registers, however).
Change an 8, which was 4 + 4 or sizeof(int) + SZREG to be a simple '4
+ SZREG' to reflect the actual offset of the structure in question.
r195355 | imp | 2009-07-05 00:56:51 -0600 (Sun, 05 Jul 2009) | 7 lines
(1) Use uintptr_t in preference to unsigned. The latter isn't right for
64-bit case, while the former is.
(2) include a SB1 specific coherency mapping
Submitted by: Neelkanth Nath (2)
r195352 | imp | 2009-07-05 00:44:37 -0600 (Sun, 05 Jul 2009) | 3 lines
db_expr_t should be a intptr_t, not an int. These expressions can be
addresses or numbers, and that's a intptr_t if I ever saw one.
r195351 | imp | 2009-07-05 00:43:01 -0600 (Sun, 05 Jul 2009) | 4 lines
Define COP0_SYNC for SB1 CPU.
Submitted by: Neelkanth Natu
r195350 | imp | 2009-07-05 00:39:37 -0600 (Sun, 05 Jul 2009) | 7 lines
Switch to ABI agnostic ta0-ta3. Provide defs for this in the right
places. Provide n32/n64 register name defintions. This should have
no effect for the O32 builds that everybody else uses, but should help
make N64 builds possible (lots of other changes are needed for that).
Obtained from: NetBSD (for the regdef.h changes)
r195128 | gonzo | 2009-06-27 17:27:41 -0600 (Sat, 27 Jun 2009) | 4 lines
- Add support for handling TLS area address in kernel space.
From the userland point of view get/set operations are
performed using sysarch(2) call.
r195076 | gonzo | 2009-06-26 13:54:06 -0600 (Fri, 26 Jun 2009) | 2 lines
- Add guards to ensure that these files are included only once
r194469 | gonzo | 2009-06-18 22:43:49 -0600 (Thu, 18 Jun 2009) | 16 lines
- Mark temp variable as "earlyclobber" in assembler inline in
atomic_fetchadd_32. Without it gcc would use it as input
register for v and sometimes generate following code for
function call like atomic_fetchadd_32(&(fp)->f_count, -1):
801238b4: 2402ffff li v0,-1
801238b8: c2230018 ll v1,24(s1)
801238bc: 00431021 addu v0,v0,v1
801238c0: e2220018 sc v0,24(s1)
801238c4: 1040fffc beqz v0,801238b8 <dupfdopen+0x2e8>
801238c8: 00000000 nop
Which is definitly wrong because if sc fails v0 is set to 0
and previous value of -1 is overriden hence whole operation
turns to bogus
r194164 | imp | 2009-06-14 00:14:25 -0600 (Sun, 14 Jun 2009) | 3 lines
bye bye. This is no longer referenced, but much code from it will
resurface for a bus-space implementation.
r194160 | imp | 2009-06-14 00:10:36 -0600 (Sun, 14 Jun 2009) | 3 lines
Cavium-specific goo is no longer necessary here. Of course, I now
have to write a bus space for cavium, but that shouldn't be too hard.
r194157 | imp | 2009-06-14 00:01:46 -0600 (Sun, 14 Jun 2009) | 2 lines
Move this to a more approrpiate plae.
r194156 | imp | 2009-06-13 23:29:13 -0600 (Sat, 13 Jun 2009) | 2 lines
Bring this in from the cavium port.
r193487 | gonzo | 2009-06-05 02:37:11 -0600 (Fri, 05 Jun 2009) | 2 lines
- Use restoreintr instead of enableint while accessing pcpu in DO_AST
r192864 | gonzo | 2009-05-26 16:40:12 -0600 (Tue, 26 May 2009) | 4 lines
- Replace CPU_NOFPU and SOFTFLOAT options with CPU_FPU. By default
we assume that there is no FPU, because majority of SoC does
not have it.
r192817 | gonzo | 2009-05-26 10:35:05 -0600 (Tue, 26 May 2009) | 2 lines
- Add type cast for atomic_cmpset_acq_ptr arguments
r192792 | gonzo | 2009-05-26 00:01:17 -0600 (Tue, 26 May 2009) | 2 lines
- Remove now unused NetBSDism intr.h
r192177 | gonzo | 2009-05-15 20:39:13 -0600 (Fri, 15 May 2009) | 4 lines
- Add MIPS_IS_KSEG0_ADDR, MIPS_IS_KSEG1_ADDR and MIPS_IS_VALID_PTR
macroses thet check if address belongs to KSEG0, KSEG1 or both
of them respectively.
r191589 | gonzo | 2009-04-27 13:18:55 -0600 (Mon, 27 Apr 2009) | 3 lines
- Cast argument to proper type in order to avoid warnings like
"shift value is too large for given type"
r191577 | gonzo | 2009-04-27 12:29:59 -0600 (Mon, 27 Apr 2009) | 4 lines
- Use naming convention the same as MIPS spec does: eliminate _sel1 sufix
and just use selector number. e.g. mips_rd_config_sel1 -> mips_rd_config1
- Add WatchHi/WatchLo accessors for selctors 1..3 (for debug purposes)
r191451 | gonzo | 2009-04-23 22:17:21 -0600 (Thu, 23 Apr 2009) | 4 lines
- Define accessor functions for CP0 Config(16) register selects 1, 2, 3.
Content of these registers is defined in MIPS spec and can be used
for obtaining info about CPU capabilities.
r191282 | gonzo | 2009-04-19 16:02:14 -0600 (Sun, 19 Apr 2009) | 3 lines
- Make mips_bus_space_generic be of type bus_space_tag_t instead of
struct bus_space and update all relevant places.
r191084 | gonzo | 2009-04-14 20:28:26 -0600 (Tue, 14 Apr 2009) | 6 lines
Use FreeBSD/arm approach for handling bus space access: space tag is a pointer
to bus_space structure that defines access methods and hence every bus can
define own accessors. Default space is mips_bus_space_generic. It's a simple
interface to physical memory, values are read with regard to host system
byte order.
32 files changed, 508 insertions, 183 deletions
diff --git a/sys/mips/include/_align.h b/sys/mips/include/_align.h index 4484a28..f945164 100644 --- a/sys/mips/include/_align.h +++ b/sys/mips/include/_align.h @@ -44,10 +44,10 @@ /* * Round p (pointer or byte index) up to a correctly-aligned value for all - * data types (int, long, ...). The result is u_int and must be cast to + * data types (int, long, ...). The result is u_long and must be cast to * any desired pointer type. */ #define _ALIGNBYTES 7 -#define _ALIGN(p) (((u_int)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) +#define _ALIGN(p) (((u_long)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) #endif /* !_MIPS_INCLUDE__ALIGN_H_ */ diff --git a/sys/mips/include/_bus.h b/sys/mips/include/_bus.h index 74865da..54b0cbb 100644 --- a/sys/mips/include/_bus.h +++ b/sys/mips/include/_bus.h @@ -31,19 +31,20 @@ #ifndef MIPS_INCLUDE__BUS_H #define MIPS_INCLUDE__BUS_H -#ifdef TARGET_OCTEON -#include "_bus_octeon.h" -#else /* * Bus address and size types */ +#include "opt_cputype.h" +#if !(defined(TARGET_OCTEON) && defined(ISA_MIPS32)) typedef uintptr_t bus_addr_t; +#else +typedef uint64_t bus_addr_t; +#endif typedef uintptr_t bus_size_t; /* * Access methods for bus resources and address space. */ -typedef long bus_space_tag_t; -typedef u_long bus_space_handle_t; -#endif +typedef struct bus_space *bus_space_tag_t; +typedef bus_addr_t bus_space_handle_t; #endif /* MIPS_INCLUDE__BUS_H */ diff --git a/sys/mips/include/_types.h b/sys/mips/include/_types.h index ec94439..1fd760f 100644 --- a/sys/mips/include/_types.h +++ b/sys/mips/include/_types.h @@ -54,7 +54,7 @@ typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; -#ifdef __mips64 +#ifdef __mips_n64 typedef long __int64_t; typedef unsigned long __uint64_t; #else @@ -79,14 +79,14 @@ typedef unsigned long long __uint64_t; */ typedef __int32_t __clock_t; /* clock()... */ typedef unsigned int __cpumask_t; -#ifdef __mips64 +#ifdef __mips_n64 typedef __int64_t __critical_t; #else typedef __int32_t __critical_t; #endif typedef double __double_t; typedef double __float_t; -#ifdef __mips64 +#ifdef __mips_n64 typedef __int64_t __intfptr_t; typedef __int64_t __intptr_t; #else @@ -102,14 +102,14 @@ typedef __int8_t __int_least8_t; typedef __int16_t __int_least16_t; typedef __int32_t __int_least32_t; typedef __int64_t __int_least64_t; -#if defined(__mips64) || defined(ISA_MIPS64) +#if defined(__mips_n64) || defined(__mips_n32) typedef __int64_t __register_t; typedef __int64_t f_register_t; #else typedef __int32_t __register_t; typedef __int32_t f_register_t; #endif -#ifdef __mips64 +#ifdef __mips_n64 typedef __int64_t __ptrdiff_t; typedef __int64_t __segsz_t; typedef __uint64_t __size_t; @@ -134,13 +134,16 @@ typedef __uint8_t __uint_least8_t; typedef __uint16_t __uint_least16_t; typedef __uint32_t __uint_least32_t; typedef __uint64_t __uint_least64_t; -#if defined(__mips64) || defined(ISA_MIPS64) +#if defined(__mips_n64) || defined(__mips_n32) typedef __uint64_t __u_register_t; +#else +typedef __uint32_t __u_register_t; +#endif +#if defined(__mips_n64) typedef __uint64_t __vm_offset_t; typedef __uint64_t __vm_paddr_t; typedef __uint64_t __vm_size_t; #else -typedef __uint32_t __u_register_t; typedef __uint32_t __vm_offset_t; typedef __uint32_t __vm_paddr_t; typedef __uint32_t __vm_size_t; @@ -162,8 +165,4 @@ typedef char * __va_list; typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/ #endif -typedef struct label_t { - __register_t val[13]; -} label_t; - #endif /* !_MACHINE__TYPES_H_ */ diff --git a/sys/mips/include/asm.h b/sys/mips/include/asm.h index 0df221e..db6929d 100644 --- a/sys/mips/include/asm.h +++ b/sys/mips/include/asm.h @@ -60,6 +60,7 @@ #include <machine/regdef.h> #endif #include <machine/endian.h> +#include <machine/cdefs.h> #undef __FBSDID #if !defined(lint) && !defined(STRIP_FBSDID) @@ -281,7 +282,7 @@ _C_LABEL(x): * Macros to panic and printf from assembly language. */ #define PANIC(msg) \ - la a0, 9f; \ + PTR_LA a0, 9f; \ jal _C_LABEL(panic); \ nop; \ MSG(msg) @@ -289,7 +290,7 @@ _C_LABEL(x): #define PANIC_KSEG0(msg, reg) PANIC(msg) #define PRINTF(msg) \ - la a0, 9f; \ + PTR_LA a0, 9f; \ jal _C_LABEL(printf); \ nop; \ MSG(msg) @@ -308,23 +309,24 @@ _C_LABEL(x): */ #define DO_AST \ 44: \ - la s0, _C_LABEL(disableintr) ;\ + PTR_LA s0, _C_LABEL(disableintr) ;\ jalr s0 ;\ nop ;\ + move a0, v0 ;\ GET_CPU_PCPU(s1) ;\ lw s3, PC_CURPCB(s1) ;\ lw s1, PC_CURTHREAD(s1) ;\ lw s2, TD_FLAGS(s1) ;\ li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\ and s2, s0 ;\ - la s0, _C_LABEL(enableintr) ;\ + PTR_LA s0, _C_LABEL(restoreintr) ;\ jalr s0 ;\ nop ;\ beq s2, zero, 4f ;\ nop ;\ - la s0, _C_LABEL(ast) ;\ + PTR_LA s0, _C_LABEL(ast) ;\ jalr s0 ;\ - addu a0, s3, U_PCB_REGS ;\ + PTR_ADDU a0, s3, U_PCB_REGS ;\ j 44b ;\ nop ;\ 4: @@ -361,12 +363,15 @@ _C_LABEL(x): */ #if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32 +/* #if !defined(__mips_n64) */ #define REG_L lw #define REG_S sw #define REG_LI li #define REG_PROLOGUE .set push #define REG_EPILOGUE .set pop #define SZREG 4 +#define PTR_LA la +#define PTR_ADDU addu #else #define REG_L ld #define REG_S sd @@ -374,6 +379,8 @@ _C_LABEL(x): #define REG_PROLOGUE .set push ; .set mips3 #define REG_EPILOGUE .set pop #define SZREG 8 +#define PTR_LA dla +#define PTR_ADDU daddu #endif /* _MIPS_BSD_API */ #define mfc0_macro(data, spr) \ diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 9f800cd..4b87738 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -34,6 +34,17 @@ #error this file needs sys/cdefs.h as a prerequisite #endif +/* + * Note: All the 64-bit atomic operations are only atomic when running + * in 64-bit mode. It is assumed that code compiled for n32 and n64 + * fits into this definition and no further safeties are needed. + * + * It is also assumed that the add, subtract and other arithmetic is + * done on numbers not pointers. The special rules for n32 pointers + * do not have atomic operations defined for them, but generally shouldn't + * need atomic operations. + */ + static __inline void mips_sync(void) { @@ -126,7 +137,7 @@ atomic_subtract_32(__volatile uint32_t *p, uint32_t v) "1:\tll %0, %3\n\t" /* load old value */ "subu %0, %2\n\t" /* calculate new value */ "sc %0, %1\n\t" /* attempt to store */ - "beqz %0, 1b\n\t" /* spin if failed */ + "beqz %0, 1b\n\t" /* spin if failed */ : "=&r" (temp), "=m" (*p) : "r" (v), "m" (*p) : "memory"); @@ -166,6 +177,110 @@ atomic_readandset_32(__volatile uint32_t *addr, uint32_t value) return result; } +#if defined(__mips_n64) || defined(__mips_n32) +static __inline void +atomic_set_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "or %0, %2, %0\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); + +} + +static __inline void +atomic_clear_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + v = ~v; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "and %0, %2, %0\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); +} + +static __inline void +atomic_add_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "daddu %0, %2, %0\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); +} + +static __inline void +atomic_subtract_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "dsubu %0, %2\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); +} + +static __inline uint64_t +atomic_readandclear_64(__volatile uint64_t *addr) +{ + uint64_t result,temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "li %1, 0\n\t" /* value to store */ + "scd %1, %2\n\t" /* attempt to store */ + "beqz %1, 1b\n\t" /* if the store failed, spin */ + : "=&r"(result), "=&r"(temp), "=m" (*addr) + : "m" (*addr) + : "memory"); + + return result; +} + +static __inline uint64_t +atomic_readandset_64(__volatile uint64_t *addr, uint64_t value) +{ + uint64_t result,temp; + + __asm __volatile ( + "1:\n\t" + "lld %0,%3\n\t" /* Load old value*/ + "or %1,$0,%4\n\t" + "scd %1,%2\n\t" /* attempt to store */ + "beqz %1, 1b\n\t" /* if the store failed, spin */ + : "=&r"(result), "=&r"(temp), "=m" (*addr) + : "m" (*addr), "r" (value) + : "memory"); + + return result; +} +#endif + #define ATOMIC_ACQ_REL(NAME, WIDTH) \ static __inline void \ atomic_##NAME##_acq_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ @@ -194,7 +309,7 @@ ATOMIC_ACQ_REL(set, 32) ATOMIC_ACQ_REL(clear, 32) ATOMIC_ACQ_REL(add, 32) ATOMIC_ACQ_REL(subtract, 32) -#if 0 +#if defined(__mips_n64) || defined(__mips_n32) ATOMIC_ACQ_REL(set, 64) ATOMIC_ACQ_REL(clear, 64) ATOMIC_ACQ_REL(add, 64) @@ -226,8 +341,22 @@ atomic_store_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ ATOMIC_STORE_LOAD(32) ATOMIC_STORE_LOAD(64) -void atomic_store_64 (__volatile uint64_t *, uint64_t *); -void atomic_load_64 (__volatile uint64_t *, uint64_t *); +#if !defined(__mips_n64) && !defined(__mips_n32) +void atomic_store_64(__volatile uint64_t *, uint64_t *); +void atomic_load_64(__volatile uint64_t *, uint64_t *); +#else +static __inline void +atomic_store_64(__volatile uint64_t *p, uint64_t *v) +{ + *p = *v; +} + +static __inline void +atomic_load_64(__volatile uint64_t *p, uint64_t *v) +{ + *v = *p; +} +#endif #undef ATOMIC_STORE_LOAD @@ -294,11 +423,83 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) "addu %2, %3, %0\n\t" /* calculate new value */ "sc %2, %1\n\t" /* attempt to store */ "beqz %2, 1b\n\t" /* spin if failed */ - : "=&r" (value), "=m" (*p), "=r" (temp) + : "=&r" (value), "=m" (*p), "=&r" (temp) : "r" (v), "m" (*p)); return (value); } +#if defined(__mips_n64) || defined(__mips_n32) +/* + * Atomically compare the value stored at *p with cmpval and if the + * two values are equal, update the value of *p with newval. Returns + * zero if the compare failed, nonzero otherwise. + */ +static __inline uint64_t +atomic_cmpset_64(__volatile uint64_t* p, uint64_t cmpval, uint64_t newval) +{ + uint64_t ret; + + __asm __volatile ( + "1:\n\t" + "lld %0, %4\n\t" /* load old value */ + "bne %0, %2, 2f\n\t" /* compare */ + "move %0, %3\n\t" /* value to store */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* if it failed, spin */ + "j 3f\n\t" + "2:\n\t" + "li %0, 0\n\t" + "3:\n" + : "=&r" (ret), "=m" (*p) + : "r" (cmpval), "r" (newval), "m" (*p) + : "memory"); + + return ret; +} + +/* + * Atomically compare the value stored at *p with cmpval and if the + * two values are equal, update the value of *p with newval. Returns + * zero if the compare failed, nonzero otherwise. + */ +static __inline uint64_t +atomic_cmpset_acq_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) +{ + int retval; + + retval = atomic_cmpset_64(p, cmpval, newval); + mips_sync(); + return (retval); +} + +static __inline uint64_t +atomic_cmpset_rel_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) +{ + mips_sync(); + return (atomic_cmpset_64(p, cmpval, newval)); +} + +/* + * Atomically add the value of v to the integer pointed to by p and return + * the previous value of *p. + */ +static __inline uint64_t +atomic_fetchadd_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t value, temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %1\n\t" /* load old value */ + "daddu %2, %3, %0\n\t" /* calculate new value */ + "scd %2, %1\n\t" /* attempt to store */ + "beqz %2, 1b\n\t" /* spin if failed */ + : "=&r" (value), "=m" (*p), "=&r" (temp) + : "r" (v), "m" (*p)); + return (value); +} +#endif + /* Operations on chars. */ #define atomic_set_char atomic_set_8 #define atomic_set_acq_char atomic_set_acq_8 @@ -349,7 +550,13 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) #define atomic_readandset_int atomic_readandset_32 #define atomic_fetchadd_int atomic_fetchadd_32 -#ifdef __mips64 +/* + * I think the following is right, even for n32. For n32 the pointers + * are still 32-bits, so we need to operate on them as 32-bit quantities, + * even though they are sign extended in operation. For longs, there's + * no question because they are always 32-bits. + */ +#ifdef __mips_n64 /* Operations on longs. */ #define atomic_set_long atomic_set_64 #define atomic_set_acq_long atomic_set_acq_64 @@ -371,27 +578,7 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) #define atomic_fetchadd_long atomic_fetchadd_64 #define atomic_readandclear_long atomic_readandclear_64 -/* Operations on pointers. */ -#define atomic_set_ptr atomic_set_64 -#define atomic_set_acq_ptr atomic_set_acq_64 -#define atomic_set_rel_ptr atomic_set_rel_64 -#define atomic_clear_ptr atomic_clear_64 -#define atomic_clear_acq_ptr atomic_clear_acq_64 -#define atomic_clear_rel_ptr atomic_clear_rel_64 -#define atomic_add_ptr atomic_add_64 -#define atomic_add_acq_ptr atomic_add_acq_64 -#define atomic_add_rel_ptr atomic_add_rel_64 -#define atomic_subtract_ptr atomic_subtract_64 -#define atomic_subtract_acq_ptr atomic_subtract_acq_64 -#define atomic_subtract_rel_ptr atomic_subtract_rel_64 -#define atomic_cmpset_ptr atomic_cmpset_64 -#define atomic_cmpset_acq_ptr atomic_cmpset_acq_64 -#define atomic_cmpset_rel_ptr atomic_cmpset_rel_64 -#define atomic_load_acq_ptr atomic_load_acq_64 -#define atomic_store_rel_ptr atomic_store_rel_64 -#define atomic_readandclear_ptr atomic_readandclear_64 - -#else /* __mips64 */ +#else /* !__mips_n64 */ /* Operations on longs. */ #define atomic_set_long atomic_set_32 @@ -421,25 +608,26 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) atomic_fetchadd_32((volatile u_int *)(p), (u_int)(v)) #define atomic_readandclear_long atomic_readandclear_32 +#endif /* __mips_n64 */ + /* Operations on pointers. */ -#define atomic_set_ptr atomic_set_32 -#define atomic_set_acq_ptr atomic_set_acq_32 -#define atomic_set_rel_ptr atomic_set_rel_32 -#define atomic_clear_ptr atomic_clear_32 -#define atomic_clear_acq_ptr atomic_clear_acq_32 -#define atomic_clear_rel_ptr atomic_clear_rel_32 -#define atomic_add_ptr atomic_add_32 -#define atomic_add_acq_ptr atomic_add_acq_32 -#define atomic_add_rel_ptr atomic_add_rel_32 -#define atomic_subtract_ptr atomic_subtract_32 -#define atomic_subtract_acq_ptr atomic_subtract_acq_32 -#define atomic_subtract_rel_ptr atomic_subtract_rel_32 -#define atomic_cmpset_ptr atomic_cmpset_32 -#define atomic_cmpset_acq_ptr atomic_cmpset_acq_32 -#define atomic_cmpset_rel_ptr atomic_cmpset_rel_32 -#define atomic_load_acq_ptr atomic_load_acq_32 -#define atomic_store_rel_ptr atomic_store_rel_32 -#define atomic_readandclear_ptr atomic_readandclear_32 -#endif /* __mips64 */ +#define atomic_set_ptr atomic_set_long +#define atomic_set_acq_ptr atomic_set_acq_long +#define atomic_set_rel_ptr atomic_set_rel_long +#define atomic_clear_ptr atomic_clear_long +#define atomic_clear_acq_ptr atomic_clear_acq_long +#define atomic_clear_rel_ptr atomic_clear_rel_long +#define atomic_add_ptr atomic_add_long +#define atomic_add_acq_ptr atomic_add_acq_long +#define atomic_add_rel_ptr atomic_add_rel_long +#define atomic_subtract_ptr atomic_subtract_long +#define atomic_subtract_acq_ptr atomic_subtract_acq_long +#define atomic_subtract_rel_ptr atomic_subtract_rel_long +#define atomic_cmpset_ptr atomic_cmpset_long +#define atomic_cmpset_acq_ptr atomic_cmpset_acq_long +#define atomic_cmpset_rel_ptr atomic_cmpset_rel_long +#define atomic_load_acq_ptr atomic_load_acq_long +#define atomic_store_rel_ptr atomic_store_rel_long +#define atomic_readandclear_ptr atomic_readandclear_long #endif /* ! _MACHINE_ATOMIC_H_ */ diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h index 92557d7..63b295d 100644 --- a/sys/mips/include/bus.h +++ b/sys/mips/include/bus.h @@ -1,8 +1,7 @@ -/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ +/* $NetBSD: bus.h,v 1.11 2003/07/28 17:35:54 thorpej Exp $ */ + /*- - * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $ - * - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. + * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -38,7 +37,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* +/*- * Copyright (c) 1996 Charles M. Hannum. All rights reserved. * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. * diff --git a/sys/mips/include/cache.h b/sys/mips/include/cache.h index 8f22cdb..d73daa2 100644 --- a/sys/mips/include/cache.h +++ b/sys/mips/include/cache.h @@ -37,6 +37,9 @@ * $FreeBSD$ */ +#ifndef _MACHINE_CACHE_H_ +#define _MACHINE_CACHE_H_ + /* * Cache operations. * @@ -156,50 +159,8 @@ struct mips_cache_ops { extern struct mips_cache_ops mips_cache_ops; /* PRIMARY CACHE VARIABLES */ -extern u_int mips_picache_size; -extern u_int mips_picache_line_size; -extern u_int mips_picache_ways; -extern u_int mips_picache_way_size; -extern u_int mips_picache_way_mask; - -extern u_int mips_pdcache_size; /* and unified */ -extern u_int mips_pdcache_line_size; -extern u_int mips_pdcache_ways; -extern u_int mips_pdcache_way_size; -extern u_int mips_pdcache_way_mask; -extern int mips_pdcache_write_through; - -extern int mips_pcache_unified; - -/* SECONDARY CACHE VARIABLES */ -extern u_int mips_sicache_size; -extern u_int mips_sicache_line_size; -extern u_int mips_sicache_ways; -extern u_int mips_sicache_way_size; -extern u_int mips_sicache_way_mask; - -extern u_int mips_sdcache_size; /* and unified */ -extern u_int mips_sdcache_line_size; -extern u_int mips_sdcache_ways; -extern u_int mips_sdcache_way_size; -extern u_int mips_sdcache_way_mask; -extern int mips_sdcache_write_through; - -extern int mips_scache_unified; - -/* TERTIARY CACHE VARIABLES */ -extern u_int mips_tcache_size; /* always unified */ -extern u_int mips_tcache_line_size; -extern u_int mips_tcache_ways; -extern u_int mips_tcache_way_size; -extern u_int mips_tcache_way_mask; -extern int mips_tcache_write_through; - -extern u_int mips_dcache_align; -extern u_int mips_dcache_align_mask; - -extern u_int mips_cache_alias_mask; -extern u_int mips_cache_prefer_mask; +extern int mips_picache_linesize; +extern int mips_pdcache_linesize; #define __mco_noargs(prefix, x) \ do { \ @@ -259,3 +220,4 @@ void mips_config_cache(struct mips_cpuinfo *); void mips_dcache_compute_align(void); #include <machine/cache_mipsNN.h> +#endif /* _MACHINE_CACHE_H_ */ diff --git a/sys/mips/include/cache_mipsNN.h b/sys/mips/include/cache_mipsNN.h index e44746a..9933e74 100644 --- a/sys/mips/include/cache_mipsNN.h +++ b/sys/mips/include/cache_mipsNN.h @@ -36,6 +36,8 @@ * * $FreeBSD$ */ +#ifndef _MACHINE_CACHE_MIPSNN_H_ +#define _MACHINE_CACHE_MIPSNN_H_ void mipsNN_cache_init(struct mips_cpuinfo *); @@ -65,3 +67,5 @@ void mipsNN_pdcache_wbinv_range_index_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_inv_range_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_wb_range_128(vm_offset_t, vm_size_t); #endif + +#endif /* _MACHINE_CACHE_MIPSNN_H_ */ diff --git a/sys/mips/include/cpu.h b/sys/mips/include/cpu.h index 20b41e2..3e939a0 100644 --- a/sys/mips/include/cpu.h +++ b/sys/mips/include/cpu.h @@ -56,21 +56,30 @@ #define MIPS_RESERVED_ADDR 0xbfc80000 #define MIPS_KSEG0_LARGEST_PHYS 0x20000000 -#define MIPS_CACHED_TO_PHYS(x) ((unsigned)(x) & 0x1fffffff) -#define MIPS_PHYS_TO_CACHED(x) ((unsigned)(x) | MIPS_CACHED_MEMORY_ADDR) -#define MIPS_UNCACHED_TO_PHYS(x) ((unsigned)(x) & 0x1fffffff) -#define MIPS_PHYS_TO_UNCACHED(x) ((unsigned)(x) | MIPS_UNCACHED_MEMORY_ADDR) +#define MIPS_CACHED_TO_PHYS(x) ((uintptr_t)(x) & 0x1fffffff) +#define MIPS_PHYS_TO_CACHED(x) ((uintptr_t)(x) | MIPS_CACHED_MEMORY_ADDR) +#define MIPS_UNCACHED_TO_PHYS(x) ((uintptr_t)(x) & 0x1fffffff) +#define MIPS_PHYS_TO_UNCACHED(x) ((uintptr_t)(x) | MIPS_UNCACHED_MEMORY_ADDR) #define MIPS_PHYS_MASK (0x1fffffff) #define MIPS_PA_2_K1VA(x) (MIPS_KSEG1_START | ((x) & MIPS_PHYS_MASK)) -#define MIPS_VA_TO_CINDEX(x) ((unsigned)(x) & 0xffffff | MIPS_CACHED_MEMORY_ADDR) +#define MIPS_VA_TO_CINDEX(x) ((uintptr_t)(x) & 0xffffff | MIPS_CACHED_MEMORY_ADDR) #define MIPS_CACHED_TO_UNCACHED(x) (MIPS_PHYS_TO_UNCACHED(MIPS_CACHED_TO_PHYS(x))) -#define MIPS_PHYS_TO_KSEG0(x) ((unsigned)(x) | MIPS_KSEG0_START) -#define MIPS_PHYS_TO_KSEG1(x) ((unsigned)(x) | MIPS_KSEG1_START) -#define MIPS_KSEG0_TO_PHYS(x) ((unsigned)(x) & MIPS_PHYS_MASK) -#define MIPS_KSEG1_TO_PHYS(x) ((unsigned)(x) & MIPS_PHYS_MASK) +#define MIPS_PHYS_TO_KSEG0(x) ((uintptr_t)(x) | MIPS_KSEG0_START) +#define MIPS_PHYS_TO_KSEG1(x) ((uintptr_t)(x) | MIPS_KSEG1_START) +#define MIPS_KSEG0_TO_PHYS(x) ((uintptr_t)(x) & MIPS_PHYS_MASK) +#define MIPS_KSEG1_TO_PHYS(x) ((uintptr_t)(x) & MIPS_PHYS_MASK) + +#define MIPS_IS_KSEG0_ADDR(x) \ + (((vm_offset_t)(x) >= MIPS_KSEG0_START) && \ + ((vm_offset_t)(x) <= MIPS_KSEG0_END)) +#define MIPS_IS_KSEG1_ADDR(x) \ + (((vm_offset_t)(x) >= MIPS_KSEG1_START) && \ + ((vm_offset_t)(x) <= MIPS_KSEG1_END)) +#define MIPS_IS_VALID_PTR(x) (MIPS_IS_KSEG0_ADDR(x) || \ + MIPS_IS_KSEG1_ADDR(x)) /* * Status register. @@ -154,7 +163,11 @@ * The bits in the CONFIG register */ #define CFG_K0_UNCACHED 2 +#if defined(CPU_SB1) +#define CFG_K0_COHERENT 5 /* cacheable coherent */ +#else #define CFG_K0_CACHED 3 +#endif /* * The bits in the context register. diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index f3aa5a4..cd4d3e5 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -183,20 +183,46 @@ mips_wr_ ## n (uint32_t a0) \ mips_barrier(); \ } struct __hack +#define MIPS_RDRW32_COP0_SEL(n,r,s) \ +static __inline uint32_t \ +mips_rd_ ## n ## s(void) \ +{ \ + int v0; \ + __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ + : [v0] "=&r"(v0)); \ + mips_barrier(); \ + return (v0); \ +} \ +static __inline void \ +mips_wr_ ## n ## s(uint32_t a0) \ +{ \ + __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ + __XSTRING(COP0_SYNC)";" \ + "nop;" \ + "nop;" \ + : \ + : [a0] "r"(a0)); \ + mips_barrier(); \ +} struct __hack + #ifdef TARGET_OCTEON static __inline void mips_sync_icache (void) { - __asm __volatile ( - ".set mips64\n" - ".word 0x041f0000\n" - "nop\n" - ".set mips0\n" - : : ); + __asm __volatile ( + ".set push\n" + ".set mips64\n" + ".word 0x041f0000\n" /* xxx ICACHE */ + "nop\n" + ".set pop\n" + : : ); } #endif MIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE); MIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG); +MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 1); +MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 2); +MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 3); MIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT); MIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX); MIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED); @@ -211,18 +237,13 @@ MIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI); MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); +MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1); +MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2); +MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 3); MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); - -static __inline uint32_t -mips_rd_config_sel1(void) -{ - int v0; - __asm __volatile("mfc0 %[v0], $16, 1 ;" - : [v0] "=&r" (v0)); - mips_barrier(); - return (v0); -} - +MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 1); +MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 2); +MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 3); #undef MIPS_RDRW32_COP0 static __inline register_t diff --git a/sys/mips/include/cpuinfo.h b/sys/mips/include/cpuinfo.h index bf32086..4378c6a 100644 --- a/sys/mips/include/cpuinfo.h +++ b/sys/mips/include/cpuinfo.h @@ -57,11 +57,11 @@ struct mips_cpuinfo { u_int16_t tlb_nentries; u_int8_t icache_virtual; struct { - u_int8_t ic_size; + u_int32_t ic_size; u_int8_t ic_linesize; u_int8_t ic_nways; u_int16_t ic_nsets; - u_int8_t dc_size; + u_int32_t dc_size; u_int8_t dc_linesize; u_int8_t dc_nways; u_int16_t dc_nsets; diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index e590c9d..e3070ba 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -103,6 +103,8 @@ /* CPU dependent mtc0 hazard hook */ #ifdef TARGET_OCTEON #define COP0_SYNC nop; nop; nop; nop; nop; +#elif defined(CPU_SB1) +#define COP0_SYNC ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop #else #define COP0_SYNC /* nothing */ #endif @@ -848,6 +850,10 @@ #define MIPS_4KEc_R2 0x90 /* MIPS 4KEc_R2 ISA 32 Rel 2 */ #define MIPS_4KEmp_R2 0x91 /* MIPS 4KEm/4KEp_R2 ISA 32 Rel 2 */ #define MIPS_4KSd 0x92 /* MIPS 4KSd ISA 32 Rel 2 */ +#define MIPS_24K 0x93 /* MIPS 24Kc/24Kf ISA 32 Rel 2 */ +#define MIPS_34K 0x95 /* MIPS 34K ISA 32 R2 MT */ +#define MIPS_24KE 0x96 /* MIPS 24KEc ISA 32 Rel 2 */ +#define MIPS_74K 0x97 /* MIPS 74Kc/74Kf ISA 32 Rel 2 */ /* * AMD (company ID 3) use the processor ID field to donote the CPU core diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h index 989f05c..ea97120 100644 --- a/sys/mips/include/db_machdep.h +++ b/sys/mips/include/db_machdep.h @@ -46,7 +46,7 @@ typedef struct trapframe db_regs_t; extern db_regs_t ddb_regs; /* register state */ typedef vm_offset_t db_addr_t; /* address - unsigned */ -typedef int db_expr_t; /* expression - signed */ +typedef register_t db_expr_t; /* expression - signed */ #if BYTE_ORDER == _BIG_ENDIAN #define BYTE_MSF (1) @@ -94,6 +94,7 @@ db_addr_t next_instr_address(db_addr_t, boolean_t); int db_inst_type(int); void db_dump_tlb(int, int); db_addr_t branch_taken(int inst, db_addr_t pc); -void stacktrace_subr(db_regs_t *, int (*)(const char *, ...)); +void stacktrace_subr(register_t pc, register_t sp, register_t ra, int (*)(const char *, ...)); +int kdbpeek(int *); #endif /* !_MIPS_DB_MACHDEP_H_ */ diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h index 995862c..de12b5b 100644 --- a/sys/mips/include/elf.h +++ b/sys/mips/include/elf.h @@ -41,8 +41,12 @@ /* Information taken from MIPS ABI supplemental */ #ifndef __ELF_WORD_SIZE +#if defined(__mips_n64) +#define __ELF_WORD_SIZE 64 /* Used by <sys/elf_generic.h> */ +#else #define __ELF_WORD_SIZE 32 /* Used by <sys/elf_generic.h> */ #endif +#endif #include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */ #include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */ #include <sys/elf_generic.h> diff --git a/sys/mips/include/endian.h b/sys/mips/include/endian.h index 1d2b4fe..b43b1e9 100644 --- a/sys/mips/include/endian.h +++ b/sys/mips/include/endian.h @@ -108,12 +108,12 @@ __bswap64_var(__uint64_t _x) ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56))); } -#define __bswap16(x) (__uint16_t)(__is_constant(x) ? __bswap16_const(x) : \ - __bswap16_var(x)) -#define __bswap32(x) (__uint32_t)(__is_constant(x) ? __bswap32_const(x) : \ - __bswap32_var(x)) -#define __bswap64(x) (__uint64_t)(__is_constant(x) ? __bswap64_const(x) : \ - __bswap64_var(x)) +#define __bswap16(x) (__uint16_t)(__is_constant(x) ? \ + __bswap16_const((__uint16_t)x) : __bswap16_var((__uint16_t)x)) +#define __bswap32(x) (__uint32_t)(__is_constant(x) ? \ + __bswap32_const((__uint32_t)x) : __bswap32_var((__uint32_t)x)) +#define __bswap64(x) (__uint64_t)(__is_constant(x) ? \ + __bswap64_const((__uint64_t)x) : __bswap64_var((__uint64_t)x)) #ifdef __MIPSEB__ #define __htonl(x) ((__uint32_t)(x)) diff --git a/sys/mips/include/float.h b/sys/mips/include/float.h index 750feb0..ff7e65c 100644 --- a/sys/mips/include/float.h +++ b/sys/mips/include/float.h @@ -42,10 +42,10 @@ extern int __flt_rounds(void); __END_DECLS #define FLT_RADIX 2 /* b */ -#ifdef SOFTFLOAT -#define FLT_ROUNDS -1 -#else +#ifdef CPU_HAVEFPU #define FLT_ROUNDS __flt_rounds() /* FP addition rounds to nearest */ +#else +#define FLT_ROUNDS -1 #endif /* * XXXMIPS: MIPS32 has both float and double type, so set FLT_EVAL_METHOD diff --git a/sys/mips/include/hwfunc.h b/sys/mips/include/hwfunc.h index ef5088c..16b1439 100644 --- a/sys/mips/include/hwfunc.h +++ b/sys/mips/include/hwfunc.h @@ -29,7 +29,7 @@ #define _MACHINE_HWFUNC_H_ struct trapframe; - +struct timecounter; /* * Hooks downward into hardware functionality. */ @@ -39,4 +39,12 @@ void platform_intr(struct trapframe *); void platform_reset(void); void platform_start(__register_t, __register_t, __register_t, __register_t); +/* For clocks and ticks and such */ +void platform_initclocks(void); +uint64_t platform_get_frequency(void); +unsigned platform_get_timecount(struct timecounter *); + +/* For hardware specific CPU initialization */ +void platform_cpu_init(void); +void platform_secondary_init(void); #endif /* !_MACHINE_HWFUNC_H_ */ diff --git a/sys/mips/include/intr_machdep.h b/sys/mips/include/intr_machdep.h index d5f26d9..d72828e 100644 --- a/sys/mips/include/intr_machdep.h +++ b/sys/mips/include/intr_machdep.h @@ -29,15 +29,48 @@ #ifndef _MACHINE_INTR_MACHDEP_H_ #define _MACHINE_INTR_MACHDEP_H_ +#ifdef TARGET_XLR_XLS +/* + * XLR/XLS uses its own intr_machdep.c and has + * a different number of interupts. This probably + * should be placed somewhere else. + */ + +struct mips_intrhand { + struct intr_event *mih_event; + driver_intr_t *mih_disable; + volatile long *cntp; /* interrupt counter */ +}; + +extern struct mips_intrhand mips_intr_handlers[]; +#define XLR_MAX_INTR 64 + +#else #define NHARD_IRQS 6 #define NSOFT_IRQS 2 +#endif struct trapframe; -void cpu_establish_hardintr(const char *, int (*)(void*), void (*)(void*), +void cpu_init_interrupts(void); +void cpu_establish_hardintr(const char *, driver_filter_t *, driver_intr_t *, void *, int, int, void **); -void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*), +void cpu_establish_softintr(const char *, driver_filter_t *, void (*)(void*), void *, int, int, void **); void cpu_intr(struct trapframe *); +/* + * Opaque datatype that represents intr counter + */ +typedef unsigned long* mips_intrcnt_t; + +mips_intrcnt_t mips_intrcnt_create(const char *); +void mips_intrcnt_setname(mips_intrcnt_t, const char *); + +static __inline void +mips_intrcnt_inc(mips_intrcnt_t counter) +{ + if (counter) + atomic_add_long(counter, 1); +} #endif /* !_MACHINE_INTR_MACHDEP_H_ */ diff --git a/sys/mips/include/kdb.h b/sys/mips/include/kdb.h index 7be4ecb..cd8c618 100644 --- a/sys/mips/include/kdb.h +++ b/sys/mips/include/kdb.h @@ -47,4 +47,8 @@ kdb_cpu_trap(int vector, int _) { } +static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} #endif /* _MACHINE_KDB_H_ */ diff --git a/sys/mips/include/locore.h b/sys/mips/include/locore.h index ce60353..b1b9f59 100644 --- a/sys/mips/include/locore.h +++ b/sys/mips/include/locore.h @@ -60,6 +60,7 @@ typedef int mips_prid_t; /* 0x09 unannounced */ /* 0x0a unannounced */ #define MIPS_PRID_CID_LEXRA 0x0b /* Lexra */ +#define MIPS_PRID_CID_CAVIUM 0x0d /* Cavium */ #define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */ #ifdef _KERNEL diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index 3b8d0a7..a523851 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -39,7 +39,7 @@ /* * Miscellaneous machine-dependent declarations. */ -extern int Maxmem; +extern long Maxmem; extern char sigcode[]; extern int szsigcode, szosigcode; @@ -48,10 +48,12 @@ extern vm_offset_t kstack0; void MipsSaveCurFPState(struct thread *); void fork_trampoline(void); void cpu_swapin(struct proc *); -u_int MipsEmulateBranch(struct trapframe *, int, int, u_int); +uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); +void MipsSwitchFPState(struct thread *, struct trapframe *); u_long kvtop(void *addr); int is_physical_memory(vm_offset_t addr); -int is_cacheable_mem(vm_offset_t pa); + +#define is_cacheable_mem(pa) is_physical_memory((pa)) #define MIPS_DEBUG 0 @@ -64,9 +66,13 @@ int is_cacheable_mem(vm_offset_t pa); void mips_vector_init(void); void cpu_identify(void); void mips_cpu_init(void); +void mips_pcpu0_init(void); void mips_proc0_init(void); /* Platform call-downs. */ void platform_identify(void); +extern int busdma_swi_pending; +void busdma_swi(void); + #endif /* !_MACHINE_MD_VAR_H_ */ diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index b818649..8edd48e 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -93,7 +93,7 @@ * This does not reflect the optimal alignment, just the possibility * (within reasonable limits). */ -#define ALIGNED_POINTER(p, t) ((((unsigned)(p)) & (sizeof (t) - 1)) == 0) +#define ALIGNED_POINTER(p, t) ((((unsigned long)(p)) & (sizeof (t) - 1)) == 0) /* * CACHE_LINE_SIZE is the compile-time maximum cache line size for an @@ -154,10 +154,10 @@ /* * Conversion macros */ -#define mips_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1)) -#define mips_trunc_page(x) ((unsigned)(x) & ~(NBPG-1)) -#define mips_btop(x) ((unsigned)(x) >> PGSHIFT) -#define mips_ptob(x) ((unsigned)(x) << PGSHIFT) +#define mips_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1)) +#define mips_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1)) +#define mips_btop(x) ((unsigned long)(x) >> PGSHIFT) +#define mips_ptob(x) ((unsigned long)(x) << PGSHIFT) #define round_page mips_round_page #define trunc_page mips_trunc_page #define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) diff --git a/sys/mips/include/pcb.h b/sys/mips/include/pcb.h index f54f2d7..f95ef4d 100644 --- a/sys/mips/include/pcb.h +++ b/sys/mips/include/pcb.h @@ -50,7 +50,7 @@ struct pcb { struct trapframe pcb_regs; /* saved CPU and registers */ - label_t pcb_context; /* kernel context for resume */ + __register_t pcb_context[14]; /* kernel context for resume */ int pcb_onfault; /* for copyin/copyout faults */ register_t pcb_tpc; }; @@ -71,6 +71,7 @@ struct pcb #define PCB_REG_RA 10 #define PCB_REG_SR 11 #define PCB_REG_GP 12 +#define PCB_REG_PC 13 #ifdef _KERNEL diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h index 4546cff..eedd4f3 100644 --- a/sys/mips/include/pmap.h +++ b/sys/mips/include/pmap.h @@ -145,7 +145,21 @@ typedef struct pv_entry { #define PMAP_DIAGNOSTIC #endif -extern vm_offset_t phys_avail[]; +/* + * physmem_desc[] is a superset of phys_avail[] and describes all the + * memory present in the system. + * + * phys_avail[] is similar but does not include the memory stolen by + * pmap_steal_memory(). + * + * Each memory region is described by a pair of elements in the array + * so we can describe up to (PHYS_AVAIL_ENTRIES / 2) distinct memory + * regions. + */ +#define PHYS_AVAIL_ENTRIES 10 +extern vm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2]; +extern vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; + extern char *ptvmmap; /* poor name! */ extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; @@ -172,6 +186,7 @@ void *pmap_kenter_temporary(vm_paddr_t pa, int i); void pmap_kenter_temporary_free(vm_paddr_t pa); int pmap_compute_pages_to_dump(void); void pmap_update_page(pmap_t pmap, vm_offset_t va, pt_entry_t pte); +void pmap_flush_pvcache(vm_page_t m); /* * floating virtual pages (FPAGES) diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h index 6a0ce7d..d09620a 100644 --- a/sys/mips/include/proc.h +++ b/sys/mips/include/proc.h @@ -54,6 +54,7 @@ struct mdthread { int md_pc_count; /* performance counter */ int md_pc_spill; /* performance counter spill */ vm_offset_t md_realstack; + void *md_tls; }; /* md_flags */ diff --git a/sys/mips/include/profile.h b/sys/mips/include/profile.h index 9659d1f..728a468 100644 --- a/sys/mips/include/profile.h +++ b/sys/mips/include/profile.h @@ -41,6 +41,8 @@ /*XXX The cprestore instruction is a "dummy" to shut up as(1). */ +/*XXX This is not MIPS64 safe. */ + #define MCOUNT \ __asm(".globl _mcount;" \ ".type _mcount,@function;" \ diff --git a/sys/mips/include/psl.h b/sys/mips/include/psl.h index 9d05d13..f02a1a9 100644 --- a/sys/mips/include/psl.h +++ b/sys/mips/include/psl.h @@ -47,8 +47,4 @@ #define USERMODE(ps) (((ps) & SR_KSU_MASK) == SR_KSU_USER) #define BASEPRI(ps) (((ps) & (INT_MASK | SR_INT_ENA_PREV)) \ == (INT_MASK | SR_INT_ENA_PREV)) - -#ifdef _KERNEL -#include <machine/intr.h> -#endif #endif /* _MACHINE_PSL_H_ */ diff --git a/sys/mips/include/pte.h b/sys/mips/include/pte.h index aa7e839..db26cbb 100644 --- a/sys/mips/include/pte.h +++ b/sys/mips/include/pte.h @@ -105,7 +105,11 @@ typedef pt_entry_t *pd_entry_t; #define PTE_ODDPG 0x00001000 /*#define PG_ATTR 0x0000003f Not Used */ #define PTE_UNCACHED 0x00000010 +#ifdef CPU_SB1 +#define PTE_CACHE 0x00000028 /* cacheable coherent */ +#else #define PTE_CACHE 0x00000018 +#endif /*#define PG_CACHEMODE 0x00000038 Not Used*/ #define PTE_ROPAGE (PTE_V | PTE_RO | PTE_CACHE) /* Write protected */ #define PTE_RWPAGE (PTE_V | PTE_M | PTE_CACHE) /* Not wr-prot not clean */ diff --git a/sys/mips/include/regdef.h b/sys/mips/include/regdef.h index bb9eb3d..7efdd95 100644 --- a/sys/mips/include/regdef.h +++ b/sys/mips/include/regdef.h @@ -12,6 +12,8 @@ #ifndef _MACHINE_REGDEF_H_ #define _MACHINE_REGDEF_H_ +#include <machine/cdefs.h> /* For API selection */ + #if defined(__ASSEMBLER__) /* General purpose CPU register names */ #define zero $0 /* wired zero */ @@ -22,6 +24,16 @@ #define a1 $5 #define a2 $6 #define a3 $7 +#if defined(__mips_n32) || defined(__mips_n64) +#define a4 $8 +#define a5 $9 +#define a6 $10 +#define a7 $11 +#define t0 $12 /* Temp regs, not saved accross subroutine calls */ +#define t1 $13 +#define t2 $14 +#define t3 $15 +#else #define t0 $8 /* caller saved */ #define t1 $9 #define t2 $10 @@ -30,6 +42,7 @@ #define t5 $13 #define t6 $14 #define t7 $15 +#endif #define s0 $16 /* callee saved */ #define s1 $17 #define s2 $18 @@ -48,6 +61,26 @@ #define s8 $30 /* callee saved */ #define ra $31 /* return address */ +/* + * These are temp registers whose names can be used in either the old + * or new ABI, although they map to different physical registers. In + * the old ABI, they map to t4-t7, and in the new ABI, they map to a4-a7. + * + * Because they overlap with the last 4 arg regs in the new ABI, ta0-ta3 + * should be used only when we need more than t0-t3. + */ +#if defined(__mips_n32) || defined(__mips_n64) +#define ta0 $8 +#define ta1 $9 +#define ta2 $10 +#define ta3 $11 +#else +#define ta0 $12 +#define ta1 $13 +#define ta2 $14 +#define ta3 $15 +#endif /* __mips_n32 || __mips_n64 */ + #endif /* __ASSEMBLER__ */ #endif /* !_MACHINE_REGDEF_H_ */ diff --git a/sys/mips/include/regnum.h b/sys/mips/include/regnum.h index 1e3f2c8..baa60bd 100644 --- a/sys/mips/include/regnum.h +++ b/sys/mips/include/regnum.h @@ -63,8 +63,7 @@ #define PREG_RA 10 #define PREG_SR 11 #define PREG_GP 12 - - +#define PREG_PC 13 /* * Location of the saved registers relative to ZERO. @@ -82,10 +81,10 @@ #define T1 9 #define T2 10 #define T3 11 -#define T4 12 -#define T5 13 -#define T6 14 -#define T7 15 +#define TA0 12 +#define TA1 13 +#define TA2 14 +#define TA3 15 #define S0 16 #define S1 17 #define S2 18 diff --git a/sys/mips/include/trap.h b/sys/mips/include/trap.h index a00ca90..3d0470e 100644 --- a/sys/mips/include/trap.h +++ b/sys/mips/include/trap.h @@ -108,6 +108,18 @@ void trapDump(char *msg); #endif +void MipsFPTrap(u_int, u_int, u_int); +void MipsKernGenException(void); +void MipsKernIntr(void); +void MipsKernTLBInvalidException(void); +void MipsTLBInvalidException(void); +void MipsTLBMissException(void); +void MipsUserGenException(void); +void MipsUserIntr(void); +void MipsUserTLBInvalidException(void); + +u_int trap(struct trapframe *); + #ifndef LOCORE /* XXX */ int check_address(void *); void platform_trap_enter(void); diff --git a/sys/mips/include/ucontext.h b/sys/mips/include/ucontext.h index d9dfe4e..c360a65 100644 --- a/sys/mips/include/ucontext.h +++ b/sys/mips/include/ucontext.h @@ -53,14 +53,19 @@ typedef struct __mcontext { int mc_fpused; /* fp has been used */ f_register_t mc_fpregs[33]; /* fp regs 0 to 31 and csr */ register_t mc_fpc_eir; /* fp exception instruction reg */ + void *mc_tls; /* pointer to TLS area */ int __spare__[8]; /* XXX reserved */ } mcontext_t; #endif +#if defined(__mips_n64) || defined(__mips_n32) +#define SZREG 8 +#else #define SZREG 4 +#endif /* offsets into mcontext_t */ -#define UCTX_REG(x) (8 + (x)*SZREG) +#define UCTX_REG(x) (4 + SZREG + (x)*SZREG) #define UCR_ZERO UCTX_REG(0) #define UCR_AT UCTX_REG(1) |