Initial Spring 2016 commit.

This commit is contained in:
Geoffrey Challen
2015-12-23 00:50:04 +00:00
commit cafa9f5690
732 changed files with 92195 additions and 0 deletions

301
kern/arch/mips/thread/cpu.c Normal file
View File

@@ -0,0 +1,301 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* CPU control functions.
*/
#include <types.h>
#include <lib.h>
#include <mips/specialreg.h>
#include <mips/trapframe.h>
#include <platform/maxcpus.h>
#include <cpu.h>
#include <thread.h>
////////////////////////////////////////////////////////////
/*
* Startup and exception-time stack hook.
*
* The MIPS lacks a good way to find the current CPU, current thread,
* or current thread stack upon trap entry from user mode. To deal
* with this, we store the CPU number (our number, not the hardware
* number) in a nonessential field in the MMU, which is about the only
* place possible, and then use that to index cpustacks[]. This gets
* us the value to load as the stack pointer. We can then also load
* curthread from cputhreads[] by parallel indexing.
*
* These arrays are also used to start up new CPUs, for roughly the
* same reasons.
*/
vaddr_t cpustacks[MAXCPUS];
vaddr_t cputhreads[MAXCPUS];
/*
* Do machine-dependent initialization of the cpu structure or things
* associated with a new cpu. Note that we're not running on the new
* cpu when this is called.
*/
void
cpu_machdep_init(struct cpu *c)
{
vaddr_t stackpointer;
KASSERT(c->c_number < MAXCPUS);
if (c->c_curthread->t_stack == NULL) {
/* boot cpu; don't need to do anything here */
}
else {
/*
* Stick the stack in cpustacks[], and thread pointer
* in cputhreads[].
*/
/* stack base address */
stackpointer = (vaddr_t) c->c_curthread->t_stack;
/* since stacks grow down, get the top */
stackpointer += STACK_SIZE;
cpustacks[c->c_number] = stackpointer;
cputhreads[c->c_number] = (vaddr_t)c->c_curthread;
}
}
////////////////////////////////////////////////////////////
/*
* Return the type name of the currently running CPU.
*
* For now, assume we're running on System/161 so we can use the
* System/161 processor-ID values.
*/
#define SYS161_PRID_ORIG 0x000003ff
#define SYS161_PRID_2X 0x000000a1
static inline
uint32_t
cpu_getprid(void)
{
uint32_t prid;
__asm volatile("mfc0 %0,$15" : "=r" (prid));
return prid;
}
static inline
uint32_t
cpu_getfeatures(void)
{
uint32_t features;
__asm volatile(".set push;" /* save assembler mode */
".set mips32;" /* allow mips32 instructions */
"mfc0 %0,$15,1;" /* get cop0 reg 15 sel 1 */
".set pop" /* restore assembler mode */
: "=r" (features));
return features;
}
static inline
uint32_t
cpu_getifeatures(void)
{
uint32_t features;
__asm volatile(".set push;" /* save assembler mode */
".set mips32;" /* allow mips32 instructions */
"mfc0 %0,$15,2;" /* get cop0 reg 15 sel 2 */
".set pop" /* restore assembler mode */
: "=r" (features));
return features;
}
void
cpu_identify(char *buf, size_t max)
{
uint32_t prid;
uint32_t features;
prid = cpu_getprid();
switch (prid) {
case SYS161_PRID_ORIG:
snprintf(buf, max, "MIPS/161 (System/161 1.x and pre-2.x)");
break;
case SYS161_PRID_2X:
features = cpu_getfeatures();
snprintf(buf, max, "MIPS/161 (System/161 2.x) features 0x%x",
features);
features = cpu_getifeatures();
if (features != 0) {
kprintf("WARNING: unknown CPU incompatible features "
"0x%x\n", features);
}
break;
default:
snprintf(buf, max, "32-bit MIPS (unknown type, CPU ID 0x%x)",
prid);
break;
}
}
////////////////////////////////////////////////////////////
/*
* Interrupt control.
*
* While the mips actually has on-chip interrupt priority masking, in
* the interests of simplicity, we don't use it. Instead we use
* coprocessor 0 register 12 (the system coprocessor "status"
* register) bit 0, IEc, which is the global interrupt enable flag.
* (IEc stands for interrupt-enable-current.)
*/
/*
* gcc inline assembly to get at the status register.
*
* Pipeline hazards:
* - there must be at least one cycle between GET_STATUS
* and SET_STATUS;
* - it may take up to three cycles after SET_STATUS for the
* interrupt state to really change.
*
* These considerations do not (currently) apply to System/161,
* however.
*/
#define GET_STATUS(x) __asm volatile("mfc0 %0,$12" : "=r" (x))
#define SET_STATUS(x) __asm volatile("mtc0 %0,$12" :: "r" (x))
/*
* Interrupts on.
*/
void
cpu_irqon(void)
{
uint32_t x;
GET_STATUS(x);
x |= CST_IEc;
SET_STATUS(x);
}
/*
* Interrupts off.
*/
void
cpu_irqoff(void)
{
uint32_t x;
GET_STATUS(x);
x &= ~(uint32_t)CST_IEc;
SET_STATUS(x);
}
/*
* Used below.
*/
static
void
cpu_irqonoff(void)
{
uint32_t x, xon, xoff;
GET_STATUS(x);
xon = x | CST_IEc;
xoff = x & ~(uint32_t)CST_IEc;
SET_STATUS(xon);
__asm volatile("nop; nop; nop; nop");
SET_STATUS(xoff);
}
////////////////////////////////////////////////////////////
/*
* Idling.
*/
/*
* gcc inline assembly for the WAIT instruction.
*
* mips r2k/r3k has no idle instruction at all.
*
* However, to avoid completely overloading the computing cluster, we
* appropriate the mips32 WAIT instruction.
*/
static
inline
void
wait(void)
{
/*
* The WAIT instruction goes into powersave mode until an
* interrupt is trying to occur.
*
* Then switch interrupts on and off again, so we actually
* take the interrupt.
*
* Note that the precise behavior of this instruction in the
* System/161 simulator is partly guesswork. This code may not
* work on a real mips.
*/
__asm volatile(
".set push;" /* save assembler mode */
".set mips32;" /* allow MIPS32 instructions */
".set volatile;" /* avoid unwanted optimization */
"wait;" /* suspend until interrupted */
".set pop" /* restore assembler mode */
);
}
/*
* Idle the processor until something happens.
*/
void
cpu_idle(void)
{
wait();
cpu_irqonoff();
}
/*
* Halt the CPU permanently.
*/
void
cpu_halt(void)
{
cpu_irqoff();
while (1) {
wait();
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Assembly language context switch code.
*/
#include <kern/mips/regdefs.h>
.text
.set noreorder
.globl switchframe_switch
.type switchframe_switch,@function
.ent switchframe_switch
switchframe_switch:
/*
* a0 contains the address of the switchframe pointer in the old thread.
* a1 contains the address of the switchframe pointer in the new thread.
*
* The switchframe pointer is really the stack pointer. The other
* registers get saved on the stack, namely:
*
* s0-s6, s8
* gp, ra
*
* The order must match <mips/switchframe.h>.
*
* Note that while we'd ordinarily need to save s7 too, because we
* use it to hold curthread saving it would interfere with the way
* curthread is managed by thread.c. So we'll just let thread.c
* manage it.
*/
/* Allocate stack space for saving 10 registers. 10*4 = 40 */
addi sp, sp, -40
/* Save the registers */
sw ra, 36(sp)
sw gp, 32(sp)
sw s8, 28(sp)
sw s6, 24(sp)
sw s5, 20(sp)
sw s4, 16(sp)
sw s3, 12(sp)
sw s2, 8(sp)
sw s1, 4(sp)
sw s0, 0(sp)
/* Store the old stack pointer in the old thread */
sw sp, 0(a0)
/* Get the new stack pointer from the new thread */
lw sp, 0(a1)
nop /* delay slot for load */
/* Now, restore the registers */
lw s0, 0(sp)
lw s1, 4(sp)
lw s2, 8(sp)
lw s3, 12(sp)
lw s4, 16(sp)
lw s5, 20(sp)
lw s6, 24(sp)
lw s8, 28(sp)
lw gp, 32(sp)
lw ra, 36(sp)
nop /* delay slot for load */
/* and return. */
j ra
addi sp, sp, 40 /* in delay slot */
.end switchframe_switch

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <types.h>
#include <lib.h>
#include <thread.h>
#include <threadprivate.h>
#include "switchframe.h"
/* in threadstart.S */
extern void mips_threadstart(/* arguments are in unusual registers */);
/*
* Function to initialize the switchframe of a new thread, which is
* *not* the one that is currently running.
*
* The new thread should, when it is run the first time, end up calling
* thread_startup(entrypoint, data1, data2).
*
* We arrange for this by creating a phony switchframe for
* switchframe_switch() to switch to. The only trouble is that the
* switchframe doesn't include the argument registers a0-a3. So we
* store the arguments in the s* registers, and use a bit of asm
* (mips_threadstart) to move them and then jump to thread_startup.
*/
void
switchframe_init(struct thread *thread,
void (*entrypoint)(void *data1, unsigned long data2),
void *data1, unsigned long data2)
{
vaddr_t stacktop;
struct switchframe *sf;
/*
* MIPS stacks grow down. t_stack is just a hunk of memory, so
* get the other end of it. Then set up a switchframe on the
* top of the stack.
*/
stacktop = ((vaddr_t)thread->t_stack) + STACK_SIZE;
sf = ((struct switchframe *) stacktop) - 1;
/* Zero out the switchframe. */
bzero(sf, sizeof(*sf));
/*
* Now set the important parts: pass through the three arguments,
* and set the return address register to the place we want
* execution to begin.
*
* Thus, when switchframe_switch does its "j ra", it will
* actually jump to mips_threadstart, which will move the
* arguments into the right register and jump to
* thread_startup().
*
* Note that this means that when we call switchframe_switch()
* in thread_switch(), we may not come back out the same way
* in the next thread. (Though we will come back out the same
* way when we later come back to the same thread again.)
*
* This has implications for code at the bottom of
* thread_switch, described in thread.c.
*/
sf->sf_s0 = (uint32_t)entrypoint;
sf->sf_s1 = (uint32_t)data1;
sf->sf_s2 = (uint32_t)data2;
sf->sf_ra = (uint32_t)mips_threadstart;
/* Set ->t_context, and we're done. */
thread->t_context = sf;
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _MIPS_SWITCHFRAME_H_
#define _MIPS_SWITCHFRAME_H_
/*
* Structure describing what is saved on the stack during a context switch.
*
* This must agree with the code in switch.S.
*/
struct switchframe {
uint32_t sf_s0;
uint32_t sf_s1;
uint32_t sf_s2;
uint32_t sf_s3;
uint32_t sf_s4;
uint32_t sf_s5;
uint32_t sf_s6;
uint32_t sf_s8;
uint32_t sf_gp;
uint32_t sf_ra;
};
#endif /* _MIPS_SWITCHFRAME_H_ */

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Functions for handling struct thread_machdep.
*/
#include <types.h>
#include <lib.h>
#include <thread.h>
#include <threadprivate.h>
void
thread_machdep_init(struct thread_machdep *tm)
{
tm->tm_badfaultfunc = NULL;
}
void
thread_machdep_cleanup(struct thread_machdep *tm)
{
KASSERT(tm->tm_badfaultfunc == NULL);
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Assembler-level thread startup trampoline.
*/
#include <kern/mips/regdefs.h>
.text
.set noreorder
.globl mips_threadstart
.type mips_threadstart,@function
.ent mips_threadstart
mips_threadstart:
/*
* This code doesn't take normal arguments. It's reached when
* switchframe_switch switches to a new thread. switchframe_switch
* does "j ra"; ra gets preloaded in switchframe_init to come here.
*
* Our arguments are in callee-save registers, as follows:
*
* s0 entrypoint
* s1 data1
* s2 data2
*
* We need to rearrange these so as to call the normal C function
* thread_startup(void (*entrypoint)(), void *data1, unsigned long data2).
*/
addiu sp, sp, -16 /* make our stack frame */
move ra, $0 /* clear return addr so we're top of the call stack */
move a0, s0 /* load arguments and call */
move a1, s1
j thread_startup
move a2, s2 /* (in delay slot) */
.end mips_threadstart