Removed unsupported architectures.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32071 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-08-03 11:32:08 +00:00
parent 3d65021d98
commit 885b7b4a85
17 changed files with 0 additions and 2039 deletions
-69
View File
@@ -1,69 +0,0 @@
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
OUTPUT_ARCH(sh)
ENTRY(__start)
SEARCH_DIR("libgcc");
SECTIONS
{
. = 0xc0000000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
.rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
.rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
.rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
.rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
.rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) } =0x9090
.plt : { *(.plt) }
/* text/read-only data */
.text : { *(.text .gnu.linkonce.t.*) } =0x9090
.rodata :
{
*(.rodata)
. = ALIGN(0x1000);
} =0x9000
/* writable data */
. = ALIGN(0x1000) + (. & (0x1000 - 1));
___data_start = .;
.data : { *(.data .gnu.linkonce.d.*) }
___ctor_list = .;
.ctors : { *(.ctors) }
___ctor_end = .;
___dtor_list = .;
.dtors : { *(.dtors) }
___dtor_end = .;
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
/* unintialized data (in same segment as writable data) */
___bss_start = .;
.bss : { *(.bss) }
. = ALIGN(0x1000);
_end = . ;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note .eh_frame) }
}
-312
View File
@@ -1,312 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#define FUNCTION(name) .align 2 ; .globl _##name ; .type _##name,@function ; _##name
.text
FUNCTION(reboot):
mov.l disable_exceptions_addr,r1
jsr @r1
nop
mov.l reboot_vector,r0
jmp @r0
nop
FUNCTION(dbg_save_registers):
rts
nop
.align 2
reboot_vector: .long 0xa0000000
disable_exceptions_addr: .long _disable_exceptions
FUNCTION(atomic_add):
mov.l r8,@-r15
sts.l pr,@-r15
/* disable interrupts */
mov.l disable_interrupts_addr,r1
jsr @r1
nop
/* load the value, save it, add to it, and store it back */
mov.l @r4,r3
mov r3,r8
add r5,r3
mov.l r3,@r4
/* restore interrupts */
mov.l restore_interrupts_addr,r1
jsr @r1
mov r0,r4
/* return value will be old value */
mov r8,r0
/* restore the stack */
lds.l @r15+,pr
rts
mov.l @r15+,r8
FUNCTION(atomic_and):
mov.l r8,@-r15
sts.l pr,@-r15
/* disable interrupts */
mov.l disable_interrupts_addr,r1
jsr @r1
nop
/* load the value, save it, and it, and store it back */
mov.l @r4,r3
mov r3,r8
and r5,r3
mov.l r3,@r4
/* restore interrupts */
mov.l restore_interrupts_addr,r1
jsr @r1
mov r0,r4
/* return value will be old value */
mov r8,r0
/* restore the stack */
lds.l @r15+,pr
rts
mov.l @r15+,r8
FUNCTION(atomic_or):
mov.l r8,@-r15
sts.l pr,@-r15
/* disable interrupts */
mov.l disable_interrupts_addr,r1
jsr @r1
nop
/* load the value, save it, or it, and store it back */
mov.l @r4,r3
mov r3,r8
or r5,r3
mov.l r3,@r4
/* restore interrupts */
mov.l restore_interrupts_addr,r1
jsr @r1
mov r0,r4
/* return value will be old value */
mov r8,r0
/* restore the stack */
lds.l @r15+,pr
rts
mov.l @r15+,r8
FUNCTION(atomic_set):
mov.l r8,@-r15
sts.l pr,@-r15
/* disable interrupts */
mov.l disable_interrupts_addr,r1
jsr @r1
nop
/* load the value, save it, and store the new value */
mov.l @r4,r8
mov.l r5,@r4
/* restore interrupts */
mov.l restore_interrupts_addr,r1
jsr @r1
mov r0,r4
/* return value will be old value */
mov r8,r0
/* restore the stack */
lds.l @r15+,pr
rts
mov.l @r15+,r8
/* int test_and_set(int *val, int set_to, int test_val) */
FUNCTION(test_and_set):
mov.l r8,@-r15
sts.l pr,@-r15
/* disable interrupts */
mov.l disable_interrupts_addr,r1
jsr @r1
nop
/* load the value, save it, and store the new value */
mov.l @r4,r8 /* load the dest, it will be the return value */
cmp/eq r8,r6 /* compare against the test_val */
bf _not_equal
mov.l r5,@r4 /* put the set_to value into the target */
_not_equal:
/* restore interrupts */
mov.l restore_interrupts_addr,r1
jsr @r1
mov r0,r4
/* return value will be old value */
mov r8,r0
/* restore the stack */
lds.l @r15+,pr
rts
mov.l @r15+,r8
.align 2
disable_interrupts_addr: .long _arch_int_disable_interrupts
restore_interrupts_addr: .long _arch_int_restore_interrupts
FUNCTION(disable_exceptions):
mov.l bl_bit_mask,r0
stc sr,r1
or r0,r1
ldc r1,sr /* turn off interrupts/exceptions */
rts
nop
FUNCTION(enable_exceptions):
mov.l bl_bit_mask,r0
not r0,r0
stc sr,r1
and r0,r1
ldc r1,sr
rts
nop
.align 2
bl_bit_mask: .long 0x10000000
FUNCTION(arch_int_restore_interrupts):
mov.l inverse_imask_bit_mask,r0
stc sr,r1 /* get the sr register */
and r0,r1 /* zero out the imask part */
or r4,r1 /* or in the passed in imask, should only contain imask bits */
ldc r1,sr /* put the new status into the sr register */
rts
nop
FUNCTION(arch_int_enable_interrupts):
mov.l inverse_imask_bit_mask,r0
stc sr,r1 /* load the sr register */
and r0,r1 /* set the imask to 0 */
ldc r1,sr /* put the new status into the sr register */
rts
nop
.align 2
inverse_imask_bit_mask: .long 0xffffff0f
FUNCTION(arch_int_disable_interrupts):
mov.l imask_bit_mask,r2
stc sr,r1 /* load the sr register */
mov r1,r0 /* save the old sr register */
or r2,r1 /* or in 0xf for the imask */
ldc r1,sr /* set the new sr register with the interrupts masked */
rts
and r2,r0 /* make sure the return value contains only the imask part */
FUNCTION(arch_int_is_interrupts_enabled):
mov.l imask_bit_mask,r2
stc sr,r0 /* load the sr register */
and r2,r0 /* mask out just the interrupt level */
cmp/eq #0,r0 /* check for zero */
bt _ints_is_enabled
nop
rts
mov #0,r0 /* return false */
_ints_is_enabled:
rts
mov #1,r0 /* return true */
.align 2
imask_bit_mask: .long 0x000000f0
FUNCTION(get_sr):
stc sr,r0
rts
nop
FUNCTION(get_fpscr):
sts fpscr,r0
rts
nop
// void sh4_context_switch(unsigned int **old_esp, unsigned int *new_esp);
FUNCTION(sh4_context_switch):
fmov.s fr12,@-r15
fmov.s fr13,@-r15
fmov.s fr14,@-r15
fmov.s fr15,@-r15
sts.l fpscr,@-r15
sts.l mach,@-r15
sts.l macl,@-r15
mov.l r8,@-r15
mov.l r9,@-r15
mov.l r10,@-r15
mov.l r11,@-r15
mov.l r12,@-r15
mov.l r13,@-r15
mov.l r14,@-r15
sts.l pr,@-r15
mov.l r15,@r4
mov r5,r15
lds.l @r15+,pr
mov.l @r15+,r14
mov.l @r15+,r13
mov.l @r15+,r12
mov.l @r15+,r11
mov.l @r15+,r10
mov.l @r15+,r9
mov.l @r15+,r8
lds.l @r15+,macl
lds.l @r15+,mach
lds.l @r15+,fpscr
fmov.s @r15+,fr15
fmov.s @r15+,fr14
fmov.s @r15+,fr13
fmov.s @r15+,fr12
rts
nop
FUNCTION(sh4_function_caller):
_fc_loop:
mov.l @r15+,r2
jsr @r2
nop
bra _fc_loop
nop
// void sh4_switch_stack_and_call(addr stack, void (*func)(void *), void *arg);
FUNCTION(sh4_switch_stack_and_call):
mov r4,r15
jsr @r5
mov r6,r4
// void sh4_enter_uspace(addr entry, void *args, addr ustack_top);
FUNCTION(sh4_enter_uspace):
ldc r4,spc // load the program counter it will switch to
mov r5,r4 // load the args
mov r6,r15 // restore the user stack
mov.l uspace_sr,r0
ldc r0,ssr
rte
nop
uspace_sr: .long 0x00000000
-142
View File
@@ -1,142 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <SupportDefs.h>
#include <ktypes.h>
#include <user_atomic.h>
// The code below does only work on single CPU SH4 systems.
// Interrupts must be disabled during execution, too.
int32
_user_atomic_add(vint32 *uval, int32 incr)
{
int32 val;
int32 ret;
if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP)
goto error;
if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0)
goto error;
ret = val;
val += incr;
if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0)
goto error;
return ret;
error:
// XXX kill the app
return -1;
}
int32
_user_atomic_and(vint32 *uval, int32 incr)
{
int val;
int ret;
if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP)
goto error;
if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0)
goto error;
ret = val;
val &= incr;
if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0)
goto error;
return ret;
error:
// XXX kill the app
return -1;
}
int32
_user_atomic_or(vint32 *uval, int32 incr)
{
int val;
int ret;
if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP)
goto error;
if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0)
goto error;
ret = val;
val |= incr;
if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0)
goto error;
return ret;
error:
// XXX kill the app
return -1;
}
int32
_user_atomic_set(vint32 *uval, int32 set_to)
{
int val;
int ret;
if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP)
goto error;
if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0)
goto error;
ret = val;
val = set_to;
if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0)
goto error;
return ret;
error:
// XXX kill the app
return -1;
}
int32
_user_atomic_test_and_set(vint32 *uval, int32 set_to, int32 test_val)
{
int val;
int ret;
if ((addr)uval >= KERNEL_BASE && (addr)uval <= KERNEL_TOP)
goto error;
if (user_memcpy(&val, (int32 *)uval, sizeof(val)) < 0)
goto error;
ret = val;
if (val == test_val) {
val = set_to;
if (user_memcpy((int32 *)uval, &val, sizeof(val)) < 0)
goto error;
}
return ret;
error:
// XXX kill the app
return -1;
}
-173
View File
@@ -1,173 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/arch/cpu.h>
#include <kernel/debug.h>
#include <kernel/int.h>
#include <boot/stage2.h>
static vcpu_struct *vcpu;
int
arch_cpu_preboot_init(kernel_args *ka)
{
return 0;
}
int
arch_cpu_init(kernel_args *ka)
{
vcpu = ka->arch_args.vcpu;
vcpu->kernel_asid = 0;
vcpu->user_asid = 0;
return 0;
}
int
arch_cpu_init2(kernel_args *ka)
{
return 0;
}
void
sh4_set_kstack(addr kstack)
{
// dprintf("sh4_set_kstack: setting kstack to 0x%x\n", kstack);
vcpu->kstack = (unsigned int *)kstack;
}
void
sh4_set_user_pgdir(addr pgdir)
{
// dprintf("sh4_set_user_pgdir: setting pgdir to 0x%x\n", pgdir);
if((addr)vcpu->user_pgdir != pgdir)
arch_cpu_global_TLB_invalidate();
vcpu->user_pgdir = (unsigned int *)pgdir;
}
void
sh4_invl_page(addr va)
{
int state;
int i;
va = ROUNDOWN(va, PAGE_SIZE);
state = int_disable_interrupts();
// wipe it out of the data tlbs
for(i=0; i<UTLB_COUNT; i++) {
struct utlb_addr_array *ua = (struct utlb_addr_array *)(UTLB + (i << UTLB_ADDR_SHIFT));
if(ua->vpn == (va >> 10))
ua->valid = 0;
}
// wipe it out of the instruction tlbs
for(i=0; i<ITLB_COUNT; i++) {
struct itlb_addr_array *ia = (struct itlb_addr_array *)(ITLB + (i << ITLB_ADDR_SHIFT));
if(ia->vpn == (va >> 10))
ia->valid = 0;
}
int_restore_interrupts(state);
}
void
arch_cpu_invalidate_TLB_range(addr start, addr end)
{
int num_pages = end/PAGE_SIZE - start/PAGE_SIZE;
while ( num_pages-- >= 0 ) {
sh4_invl_page(start);
start += PAGE_SIZE;
}
}
void
arch_cpu_invalidate_TLB_list(addr pages[], int num_pages)
{
int i;
for(i=0; i<num_pages; i++) {
sh4_invl_page(pages[i]);
}
}
void
arch_cpu_global_TLB_invalidate()
{
int state;
int i;
state = int_disable_interrupts();
// wipe out the data tlbs
for(i=0; i<UTLB_COUNT; i++) {
struct utlb_addr_array *ua = (struct utlb_addr_array *)(UTLB + (i << UTLB_ADDR_SHIFT));
ua->valid = 0;
}
// wipe out the instruction tlbs
for(i=0; i<ITLB_COUNT; i++) {
struct itlb_addr_array *ia = (struct itlb_addr_array *)(ITLB + (i << ITLB_ADDR_SHIFT));
ia->valid = 0;
}
int_restore_interrupts(state);
}
int
arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr *fault_handler)
{
char *tmp = (char *)to;
char *s = (char *)from;
*fault_handler = (addr)&&error;
while(size--)
*tmp++ = *s++;
*fault_handler = 0;
return 0;
error:
*fault_handler = 0;
return ERR_VM_BAD_USER_MEMORY;
}
int
arch_cpu_user_memset(void *s, char c, size_t count, addr *fault_handler)
{
char *xs = (char *) s;
*fault_handler = (addr)&&error;
while (count--)
*xs++ = c;
*fault_handler = 0;
return 0;
error:
*fault_handler = 0;
return ERR_VM_BAD_USER_MEMORY;
}
void
arch_cpu_idle(void)
{
}
@@ -1,115 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <boot/stage2.h>
#include <kernel/arch/dbg_console.h>
int arch_dbg_con_init(kernel_args *ka)
{
volatile uint16 *scif16 = (uint16*)0xffe80000;
volatile uint8 *scif8 = (uint8*)0xffe80000;
int x;
/* Disable interrupts, transmit/receive, and use internal clock */
scif16[8/2] = 0;
/* 8N1, use P0 clock */
scif16[0] = 0;
/* Set baudrate, N = P0/(32*B)-1 */
// scif8[4] = (50000000 / (32 * baud_rate)) - 1;
// scif8[4] = 80; // 19200
// scif8[4] = 40; // 38400
// scif8[4] = 26; // 57600
scif8[4] = 13; // 115200
/* Reset FIFOs, enable hardware flow control */
scif16[24/2] = 4; //12;
for(x = 0; x < 100000; x++);
scif16[24/2] = 0; //8;
/* Disable manual pin control */
scif16[32/2] = 0;
/* Clear status */
scif16[16/2] = 0x60;
scif16[36/2] = 0;
/* Enable transmit/receive */
scif16[8/2] = 0x30;
for(x = 0; x < 100000; x++);
arch_dbg_con_puts("serial initted\n");
return 0;
}
char arch_dbg_con_read()
{
volatile uint16 *status = (uint16*)0xffe8001c;
volatile uint16 *ack = (uint16*)0xffe80010;
volatile uint8 *fifo = (uint8*)0xffe80014;
char c;
/* Check input FIFO */
while ((*status & 0x1f) == 0);
/* Get the input char */
c = *fifo;
/* Ack */
*ack &= 0x6d;
return c;
}
/* Flush all FIFO'd bytes out of the serial port buffer */
static void arch_dbg_con_flush() {
volatile uint16 *ack = (uint16*)0xffe80010;
*ack &= 0xbf;
while (!(*ack & 0x40))
;
*ack &= 0xbf;
}
static void _arch_dbg_con_putch(const char c)
{
volatile uint16 *ack = (uint16*)0xffe80010;
volatile uint8 *fifo = (uint8*)0xffe8000c;
/* Wait until the transmit buffer has space */
while (!(*ack & 0x20))
;
/* Send the char */
*fifo = c;
/* Clear status */
*ack &= 0x9f;
}
char arch_dbg_con_putch(const char c)
{
if (c == '\n') {
_arch_dbg_con_putch('\r');
_arch_dbg_con_putch('\n');
} else if (c != '\r')
_arch_dbg_con_putch(c);
return c;
}
void arch_dbg_con_puts(const char *s)
{
while(*s != '\0') {
arch_dbg_con_putch(*s);
s++;
}
}
-8
View File
@@ -1,8 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <kernel/debug.h>
#include <kernel/arch/debug.h>
-11
View File
@@ -1,11 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <boot/stage2.h>
int arch_faults_init(kernel_args *ka)
{
return 0;
}
-176
View File
@@ -1,176 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <boot/stage2.h>
#include <arch/sh4/vcpu.h>
#include <arch/sh4/sh4.h>
#include <kernel/debug.h>
#include <kernel/int.h>
#include <kernel/thread.h>
#include <kernel/vm_priv.h>
#include <kernel/faults_priv.h>
#include <kernel/syscalls.h>
#include <kernel/arch/sh4/cpu.h>
#define MAX_ARGS 16
struct vector *vector_table;
void arch_int_enable_io_interrupt(int irq)
{
return;
}
void arch_int_disable_io_interrupt(int irq)
{
return;
}
static int sh4_handle_exception(void *_frame)
//static int sh4_handle_exception(unsigned int code, unsigned int pc, unsigned int trap, unsigned int page_fault_addr)
{
struct iframe *frame = (struct iframe *)_frame;
int ret;
// NOTE: not safe to do anything that may involve the FPU before
// it is certain it is not an fpu exception
// dprintf("sh4_handle_exception: frame 0x%x code 0x%x, pc 0x%x, ssr 0x%x, sr 0x%x, pr 0x%x\n",
// frame, frame->excode, frame->spc, frame->ssr, get_sr(), frame->pr);
// dprintf("regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
// frame->r0, frame->r1, frame->r2, frame->r3, frame->r4, frame->r5, frame->r6, frame->r7,
// frame->r8, frame->r9, frame->r10, frame->r11, frame->r12, frame->r13, frame->r14, frame->sgr);
switch(frame->excode) {
case 0: // reset
case 1: // manual reset
case 5: // TLB protection violation (read)
case 6: // TLB protection violation (write)
case 7: // data address error (read)
case 8: // data address error (write)
case 10: // TLB multi hit
case 12: // illegal instruction
case 13: // slot illegal instruction
dprintf("about to gpf at pc 0x%x, excode %d\n", frame->spc, frame->excode);
ret = general_protection_fault(frame->excode);
break;
case 11: { // TRAPA
/*
** arg layout:
** r4-r7: arg 1 - 4
** r0-r3: arg 5 - 8
** r8-r13: arg 8 - 13
*/
unsigned int *trap = (unsigned int *)0xff000020;
uint64 retcode;
unsigned int args[MAX_ARGS];
int_enable_interrupts();
thread_atkernel_entry();
// XXX redo this to be stack-based
args[0] = frame->r4;
args[1] = frame->r5;
args[2] = frame->r6;
args[3] = frame->r7;
args[4] = frame->r0;
args[5] = frame->r1;
args[6] = frame->r2;
args[7] = frame->r3;
args[8] = frame->r8;
ret = syscall_dispatcher(*trap >> 2, args, &retcode);
frame->r0 = retcode & 0xffffffff;
frame->r1 = retcode >> 32;
break;
}
case 9: { // FPU exception
int fpu_fault_code;
switch(frame->fpscr & 0x0003f000) {
case 0x1000:
fpu_fault_code = FPU_FAULT_CODE_INEXACT;
break;
case 0x2000:
fpu_fault_code = FPU_FAULT_CODE_UNDERFLOW;
break;
case 0x4000:
fpu_fault_code = FPU_FAULT_CODE_OVERFLOW;
break;
case 0x8000:
fpu_fault_code = FPU_FAULT_CODE_DIVBYZERO;
break;
case 0x10000:
fpu_fault_code = FPU_FAULT_CODE_INVALID_OP;
break;
case 0x20000:
fpu_fault_code = FPU_FAULT_CODE_UNKNOWN;
break;
default:
// XXX handle better
fpu_fault_code = FPU_FAULT_CODE_UNKNOWN;
}
ret = fpu_fault(fpu_fault_code);
break;
}
case 64: // FPU disable exception
case 65: // Slot FPU disable exception
ret = fpu_disable_fault();
break;
case EXCEPTION_PAGE_FAULT_READ:
case EXCEPTION_PAGE_FAULT_WRITE: {
addr newip;
if((frame->ssr & 0x000000f0) == 0) {
// dprintf("page_fault: enabling interrupts\n");
int_enable_interrupts();
}
ret = vm_page_fault(frame->page_fault_addr, frame->spc,
frame->excode == EXCEPTION_PAGE_FAULT_WRITE, (frame->ssr & 0x40000000) == 0, &newip);
if(newip != 0)
frame->spc = newip;
break;
}
default:
ret = int_io_interrupt_handler(frame->excode);
}
if(ret == INT_RESCHEDULE) {
int state = int_disable_interrupts();
GRAB_THREAD_LOCK();
thread_resched();
RELEASE_THREAD_LOCK();
int_restore_interrupts(state);
}
if(!(frame->ssr & 0x40000000) || (frame->excode == 11)) {
thread_atkernel_exit();
}
// dprintf("sh4_handle_exception: exit\n");
return 0;
}
int arch_int_init(kernel_args *ka)
{
int i;
dprintf("arch_int_init: entry\n");
vector_table = (struct vector *)ka->arch_args.vcpu->vt;
dprintf("arch_int_init: vector table 0x%x\n", vector_table);
// set up the vectors
// handle all of them
for(i=0; i<256; i++)
vector_table[i].func = &sh4_handle_exception;
return 0;
}
int arch_int_init2(kernel_args *ka)
{
return 0;
}
-151
View File
@@ -1,151 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <kernel/vm.h>
#include <kernel/vm_priv.h>
#include <kernel/debug.h>
#include <kernel/arch/pmap.h>
#include <boot/stage2.h>
#include <arch/sh4/sh4.h>
#include <arch/sh4/vcpu.h>
#include <nulibc/string.h>
#define CHATTY_PMAP 0
static vcpu_struct *vcpu;
#define PHYS_TO_P1(x) ((x) + P1_AREA)
int arch_pmap_init(kernel_args *ka)
{
dprintf("arch_pmap_init: entry\n");
vcpu = ka->arch_args.vcpu;
dprintf("examining vcpu structure @ 0x%x:\n", vcpu);
dprintf("kernel_pgdir = 0x%x\n", vcpu->kernel_pgdir);
dprintf("user_pgdir = 0x%x\n", vcpu->user_pgdir);
dprintf("kernel_asid = 0x%x\n", vcpu->kernel_asid);
dprintf("user_asid = 0x%x\n", vcpu->user_asid);
return 0;
}
int arch_pmap_init2(kernel_args *ka)
{
return 0;
}
int pmap_map_page(addr paddr, addr vaddr, int lock)
{
struct pdent *pd = NULL;
struct ptent *pt;
unsigned int index = 0;
#if CHATTY_PMAP
dprintf("pmap_map_page: entry paddr 0x%x vaddr 0x%x lock 0x%x\n", paddr, vaddr, lock);
#endif
if(vaddr < P1_AREA) {
pd = (struct pdent *)vcpu->user_pgdir;
index = vaddr >> 22;
} else if(vaddr >= P3_AREA && vaddr < P4_AREA) {
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (vaddr & 0x7fffffff) >> 22;
} else {
// invalid area to map pages
panic("pmap_map_page: invalid vaddr 0x%x\n", vaddr);
}
if(pd[index].v == 0) {
// need to allocate a pagetable
unsigned int pgtable;
// get a free page for a pagetable
vm_get_free_page(&pgtable);
pgtable *= PAGE_SIZE;
// zero out the page
memset((void *)PHYS_TO_P1(pgtable), 0, PAGE_SIZE);
// stick it in the page dir
pd[index].ppn = pgtable >> 12;
pd[index].v = 1;
}
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (vaddr >> 12) & 0x000003ff;
// insert the mapping
pt[index].wt = 0;
pt[index].pr = (lock & LOCK_KERNEL) ? (lock & 0x1) : (lock | 0x2);
pt[index].ppn = paddr >> 12;
pt[index].tlb_ent = 0;
pt[index].c = 1;
pt[index].sz = 0x1; // 4k page
pt[index].sh = 0; // XXX shared?
pt[index].d = 0;
pt[index].v = 1;
arch_pmap_invl_page(vaddr);
return 0;
}
int pmap_unmap_page(addr vaddr)
{
panic("pmap_unmap_page unimplemented!\n");
return 0;
}
void arch_pmap_invl_page(addr vaddr)
{
#if CHATTY_PMAP
dprintf("arch_pmap_invl_page: vaddr 0x%x\n", vaddr);
#endif
return;
}
int pmap_get_page_mapping(addr vaddr, addr *paddr)
{
struct pdent *pd = NULL;
struct ptent *pt;
unsigned int index = 0;
if(vaddr < P1_AREA) {
pd = (struct pdent *)vcpu->user_pgdir;
index = vaddr >> 22;
} else if(vaddr >= P3_AREA && vaddr < P4_AREA) {
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (vaddr & 0x7fffffff) >> 22;
} else if(vaddr >= P1_AREA && vaddr < P2_AREA) {
// this region is identity mapped with a shift
*paddr = vaddr - P1_AREA;
return 0;
} else if(vaddr >= P2_AREA && vaddr < P3_AREA) {
// this region is identity mapped with a shift
*paddr = vaddr - P2_AREA;
return 0;
}
if(pd[index].v == 0) {
return -1;
}
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (vaddr >> 12) & 0x000003ff;
if(pt[index].v == 0) {
return -1;
}
*paddr = pt[index].ppn << 12;
return 0;
}
-27
View File
@@ -1,27 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/debug.h>
#include <kernel/arch/smp.h>
int arch_smp_init(kernel_args *ka)
{
return 0;
}
int arch_smp_get_current_cpu()
{
return 0;
}
void arch_smp_send_ici(int target_cpu)
{
panic("called arch_smp_send_ici!\n");
}
void arch_smp_send_broadcast_ici()
{
panic("called arch_smp_send_broadcast_ici\n");
}
-134
View File
@@ -1,134 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <kernel/thread.h>
#include <kernel/debug.h>
#include <kernel/int.h>
#include <kernel/vm_priv.h>
#include <kernel/arch/cpu.h>
#include <nulibc/string.h>
static struct thread *curr_thread = NULL;
int arch_proc_init_proc_struct(struct proc *p, bool kernel)
{
#if 0
if(!kernel) {
unsigned int page;
if(vm_get_free_page(&page) < 0) {
panic("arch_proc_init_proc_struct: could not find free frame for page dir\n");
}
p->arch_info.pgdir = (unsigned int *)PHYS_ADDR_TO_P1(page * PAGE_SIZE);
memset(p->arch_info.pgdir, 0, PAGE_SIZE);
} else {
p->arch_info.pgdir = NULL;
}
#endif
return 0;
}
int arch_thread_init_thread_struct(struct thread *t)
{
t->arch_info.sp = NULL;
return 0;
}
int arch_thread_initialize_kthread_stack(struct thread *t, int (*start_func)(void), void (*entry_func)(void), void (*exit_func)(void))
{
unsigned int *kstack = (unsigned int *)t->kernel_stack_base;
unsigned int kstack_size = KSTACK_SIZE;
unsigned int *kstack_top = kstack + kstack_size / sizeof(unsigned int);
int i;
// clear the kernel stack
memset(kstack, 0, kstack_size);
// set the final return address to be thread_kthread_exit
kstack_top--;
*kstack_top = (unsigned int)exit_func;
// set the return address to be the start of the first function
kstack_top--;
*kstack_top = (unsigned int)start_func;
// set the return address to be the start of the entry (thread setup) function
kstack_top--;
*kstack_top = (unsigned int)entry_func;
// simulate the important registers being pushed
for(i=0; i<7+2+5; i++) {
kstack_top--;
*kstack_top = 0;
}
// set the address of the function caller function
// that will in turn call all of the above functions
// pushed onto the stack
kstack_top--;
*kstack_top = (unsigned int)sh4_function_caller;
// save the sp
t->arch_info.sp = kstack_top;
return 0;
}
void arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
{
#if 0
int i;
dprintf("arch_thread_context_switch: 0x%x->0x%x to sp 0x%x\n",
t_from->id, t_to->id, t_to->arch_info.sp);
#endif
#if 0
for(i=0; i<8; i++) {
dprintf("sp[%d] = 0x%x\n", i, t_to->arch_info.sp[i]);
}
#endif
sh4_set_kstack(t_to->kernel_stack_base + KSTACK_SIZE);
if(t_to->proc->aspace != NULL) {
sh4_set_user_pgdir(vm_translation_map_get_pgdir(&t_to->proc->aspace->translation_map));
} else {
sh4_set_user_pgdir(NULL);
}
sh4_context_switch(&t_from->arch_info.sp, t_to->arch_info.sp);
}
void arch_thread_dump_info(void *info)
{
struct arch_thread *at = (struct arch_thread *)info;
dprintf("\tsp: 0x%x\n", at->sp);
}
void arch_thread_enter_uspace(addr entry, void *args, addr ustack_top)
{
dprintf("arch_thread_entry_uspace: entry 0x%x, ustack_top 0x%x\n",
entry, ustack_top);
int_disable_interrupts();
sh4_set_kstack(thread_get_current_thread()->kernel_stack_base + KSTACK_SIZE);
sh4_enter_uspace(entry, args, ustack_top - 4);
// never get to here
}
void arch_thread_switch_kstack_and_call(struct thread *t, addr new_kstack, void (*func)(void *), void *arg)
{
sh4_switch_stack_and_call(new_kstack, func, arg);
}
struct thread *arch_thread_get_current_thread(void)
{
return curr_thread;
}
void arch_thread_set_current_thread(struct thread *t)
{
curr_thread = t;
}
-147
View File
@@ -1,147 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <boot/stage2.h>
#include <arch/sh4/sh4.h>
#include <kernel/int.h>
#include <kernel/debug.h>
#include <kernel/timer.h>
#include <kernel/arch/cpu.h>
#define timer_rate 12500000
#define max_timer_interval ((bigtime_t)0xffffffff * 1000000 / timer_rate)
#define min_timer_interval ((bigtime_t)0x1000)
#define SYSTEM_TIME_TIMER_QUANTA 0xffffffff
static const bigtime_t system_time_timer_period = (bigtime_t)SYSTEM_TIME_TIMER_QUANTA * timer_rate / 1000000;
static volatile bigtime_t base_system_time = 0;
bigtime_t system_time()
{
bigtime_t outtime;
uint32 timer_val;
int state = int_disable_interrupts();
restart:
timer_val = SYSTEM_TIME_TIMER_QUANTA - *(uint32 *)TCNT1;
if(*(uint16 *)TCR1 & 0x0100) {
// underflow has occurred already
outtime = base_system_time + system_time_timer_period + (bigtime_t)timer_val * 1000000 / timer_rate;
} else {
outtime = base_system_time + (bigtime_t)timer_val * 1000000 / timer_rate;
if(*(uint16 *)TCR1 & 0x0100) {
// an underflow must have happened since we checked last, redo
goto restart;
}
}
int_restore_interrupts(state);
return outtime;
}
static void start_timer(int timer)
{
uint8 old_val = *(uint8 *)TSTR;
*(uint8 *)TSTR = old_val | (0x1 << timer % 3);
}
static void stop_timer(int timer)
{
uint8 old_val = *(uint8 *)TSTR;
*(uint8 *)TSTR = old_val & ~(0x1 << timer %3);
}
static void setup_timer(int timer, bigtime_t relative_timeout)
{
uint32 timer_val;
if(relative_timeout < min_timer_interval) {
timer_val = min_timer_interval * timer_rate / 1000000;
} else if(relative_timeout < max_timer_interval) {
timer_val = relative_timeout * timer_rate / 1000000;
} else {
timer_val = 0xffffffff;
}
switch(timer) {
case 0:
*(uint16 *)TCR0 = 0x0020;
*(uint32 *)TCNT0 = timer_val;
*(uint32 *)TCOR0 = timer_val;
break;
case 1:
*(uint16 *)TCR1 = 0x0020;
*(uint32 *)TCNT1 = timer_val;
*(uint32 *)TCOR1 = timer_val;
break;
case 2:
*(uint16 *)TCR2 = 0x0020;
*(uint32 *)TCNT2 = timer_val;
*(uint32 *)TCOR2 = timer_val;
break;
default:
break;
}
}
void arch_timer_set_hardware_timer(bigtime_t timeout)
{
stop_timer(0);
setup_timer(0, timeout);
start_timer(0);
}
void arch_timer_clear_hardware_timer()
{
stop_timer(0);
}
static int timer_interrupt0()
{
stop_timer(0);
return timer_interrupt();
}
static void setup_system_time_timer()
{
*(uint16 *)TCR1 = 0x0020;
*(uint32 *)TCNT1 = SYSTEM_TIME_TIMER_QUANTA;
*(uint32 *)TCOR1 = SYSTEM_TIME_TIMER_QUANTA;
}
static int timer_interrupt1()
{
base_system_time += system_time_timer_period;
*(uint16 *)TCR1 = 0x0020; // mask out the underflow bit
return INT_NO_RESCHEDULE;
}
int arch_init_timer(kernel_args *ka)
{
int i;
uint8 old_val8;
uint16 old_val16;
dprintf("arch_init_timer: entry\n");
int_set_io_interrupt_handler(32, &timer_interrupt0, NULL);
int_set_io_interrupt_handler(33, &timer_interrupt1, NULL);
// stop all of the timers
*(uint8 *)TSTR = 0;
// enable the interrupt on timer 0 & 1 & disable 2
old_val16 = *(uint16 *)IPRA;
*(uint16 *)IPRA = (old_val16 & 0x000f) | 0xef00;
// start timer 1 counting forever
base_system_time = 0;
setup_system_time_timer();
start_timer(1);
return 0;
}
-33
View File
@@ -1,33 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <kernel/debug.h>
#include <kernel/arch/vm.h>
#include <kernel/arch/sh4/cpu.h>
#include <boot/stage2.h>
int arch_vm_init(kernel_args *ka)
{
return 0;
}
int arch_vm_init2(kernel_args *ka)
{
return 0;
}
int arch_vm_init_endvm(kernel_args *ka)
{
dprintf("arch_vm_init_endvm: entry\n");
return 0;
}
void arch_vm_aspace_swap(vm_address_space *aspace)
{
sh4_set_user_pgdir(vm_translation_map_get_pgdir(&aspace->translation_map));
}
@@ -1,424 +0,0 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel/kernel.h>
#include <kernel/arch/vm_translation_map.h>
#include <kernel/heap.h>
#include <kernel/int.h>
#include <kernel/smp.h>
#include <kernel/vm.h>
#include <kernel/vm_page.h>
#include <kernel/vm_priv.h>
#include <kernel/arch/cpu.h>
#include <kernel/debug.h>
#include <nulibc/string.h>
#include <boot/stage2.h>
#include <arch/sh4/sh4.h>
#include <arch/sh4/vcpu.h>
typedef struct vm_translation_map_arch_info_struct {
addr pgdir_virt;
addr pgdir_phys;
bool is_user;
} vm_translation_map_arch_info;
static vcpu_struct *vcpu;
#define CHATTY_TMAP 0
#define PHYS_TO_P1(x) ((x) + P1_AREA)
static void destroy_tmap(vm_translation_map *map)
{
int state;
vm_translation_map *entry;
vm_translation_map *last = NULL;
if(map == NULL)
return;
if(map->arch_data->pgdir_virt != NULL)
kfree((void *)map->arch_data->pgdir_virt);
kfree(map->arch_data);
}
static int lock_tmap(vm_translation_map *map)
{
// dprintf("lock_tmap: map 0x%x\n", map);
if(recursive_lock_lock(&map->lock) == true) {
// we were the first one to grab the lock
// dprintf("clearing invalidated page count\n");
// map->arch_data->num_invalidate_pages = 0;
}
return 0;}
static int unlock_tmap(vm_translation_map *map)
{
if(recursive_lock_get_recursion(&map->lock) == 1) {
// XXX flush any TLB ents we wanted to
}
recursive_lock_unlock(&map->lock);
return -1;
}
static int map_tmap(vm_translation_map *map, addr va, addr pa, unsigned int lock)
{
struct pdent *pd = NULL;
struct ptent *pt;
unsigned int index;
#if CHATTY_TMAP
dprintf("map_tmap: va 0x%x pa 0x%x lock 0x%x\n", va, pa, lock);
#endif
if(map->arch_data->is_user) {
if(va >= P1_AREA) {
// invalid
panic("map_tmap: asked to map va 0x%x in user space aspace\n", va);
}
pd = (struct pdent *)map->arch_data->pgdir_phys;
index = va >> 22;
} else {
if(va < P3_AREA && va >= P4_AREA) {
panic("map_tmap: asked to map va 0x%x in kernel space aspace\n", va);
}
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (va & 0x7fffffff) >> 22;
}
if(pd[index].v == 0) {
vm_page *page;
unsigned int pgtable;
page = vm_page_allocate_page(PAGE_STATE_CLEAR);
pgtable = page->ppn * PAGE_SIZE;
// XXX remove when real clear pages support is there
memset((void *)PHYS_TO_P1(pgtable), 0, PAGE_SIZE);
pd[index].ppn = pgtable >> 12;
pd[index].v = 1;
}
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (va >> 12) & 0x000003ff;
if(pt[index].v)
panic("map_tmap: va 0x%x already mapped to pa 0x%x\n", va, pt[index].ppn << 12);
// insert the mapping
pt[index].wt = 0;
pt[index].pr = (lock & LOCK_KERNEL) ? (lock & 0x1) : (lock | 0x2);
pt[index].ppn = pa >> 12;
pt[index].tlb_ent = 0;
pt[index].c = 1;
pt[index].sz = 0x1; // 4k page
pt[index].sh = 0;
pt[index].d = 0;
pt[index].v = 1;
sh4_invl_page(va);
return 0;
}
static int unmap_tmap(vm_translation_map *map, addr start, addr end)
{
struct pdent *pd;
struct ptent *pt;
unsigned int index;
start = ROUNDOWN(start, PAGE_SIZE);
end = ROUNDUP(end, PAGE_SIZE);
#if CHATTY_TMAP
dprintf("unmap_tmap: asked to free pages 0x%x to 0x%x\n", start, end);
#endif
for(; start < end; start += PAGE_SIZE) {
if(map->arch_data->is_user) {
if(start >= P1_AREA) {
// invalid
panic("unmap_tmap: asked to unmap va 0x%x in user space aspace\n", start);
}
pd = (struct pdent *)map->arch_data->pgdir_phys;
index = start >> 22;
} else {
if(start < P3_AREA && start >= P4_AREA) {
panic("unmap_tmap: asked to unmap va 0x%x in kernel space aspace\n", start);
}
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (start & 0x7fffffff) >> 22;
}
if(pd[index].v == 0)
continue;
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (start >> 12) & 0x000003ff;
if(pt[index].v == 0)
continue;
pt[index].v = 0;
sh4_invl_page(start);
}
return 0;
}
static int query_tmap(vm_translation_map *map, addr va, addr *out_physical, unsigned int *out_flags)
{
struct pdent *pd;
struct ptent *pt;
unsigned int index;
// default the flags to not present
*out_flags = 0;
*out_physical = 0;
if(map->arch_data->is_user) {
if(va >= P1_AREA) {
// invalid
return ERR_VM_GENERAL;
}
pd = (struct pdent *)map->arch_data->pgdir_phys;
index = va >> 22;
} else {
if(va < P3_AREA && va >= P4_AREA) {
return ERR_VM_GENERAL;
}
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (va & 0x7fffffff) >> 22;
}
if(pd[index].v == 0) {
return NO_ERROR;
}
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (va >> 12) & 0x000003ff;
*out_physical = pt[index].ppn << 12;
// read in the page state flags, clearing the modified and accessed flags in the process
*out_flags = 0;
*out_flags |= (pt[index].pr & 0x1) ? LOCK_RW : LOCK_RO;
*out_flags |= (pt[index].pr & 0x2) ? 0 : LOCK_KERNEL;
*out_flags |= pt[index].d ? PAGE_MODIFIED : 0;
// *out_flags |= pt[index].accessed ? PAGE_ACCESSED : 0; // not emulating the accessed bit yet
*out_flags |= pt[index].v ? PAGE_PRESENT : 0;
return 0;
}
static addr get_mapped_size_tmap(vm_translation_map *map)
{
return map->map_count;
}
static int protect_tmap(vm_translation_map *map, addr base, addr top, unsigned int attributes)
{
// XXX finish
return -1;
}
static int clear_flags_tmap(vm_translation_map *map, addr va, unsigned int flags)
{
struct pdent *pd;
struct ptent *pt;
unsigned int index;
int tlb_flush = false;
if(map->arch_data->is_user) {
if(va >= P1_AREA) {
// invalid
return ERR_VM_GENERAL;
}
pd = (struct pdent *)map->arch_data->pgdir_phys;
index = va >> 22;
} else {
if(va < P3_AREA && va >= P4_AREA) {
return ERR_VM_GENERAL;
}
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (va & 0x7fffffff) >> 22;
}
if(pd[index].v == 0) {
return NO_ERROR;
}
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (va >> 12) & 0x000003ff;
// clear out the flags we've been requested to clear
if(flags & PAGE_MODIFIED) {
pt[index].d = 0;
tlb_flush = true;
}
if(flags & PAGE_ACCESSED) {
// pt[index].accessed = 0;
// tlb_flush = true;
}
if(tlb_flush)
sh4_invl_page(va);
return 0;
}
static void flush_tmap(vm_translation_map *map)
{
// no-op, we aren't caching any tlb invalidations
}
static int get_physical_page_tmap(addr pa, addr *va, int flags)
{
if(pa >= PHYS_ADDR_SIZE)
panic("get_physical_page_tmap: passed invalid address 0x%x\n", pa);
*va = PHYS_ADDR_TO_P1(pa);
return NO_ERROR;
}
static int put_physical_page_tmap(addr va)
{
if(va < P1_AREA && va >= P2_AREA)
panic("put_physical_page_tmap: bad address passed 0x%x\n", va);
return NO_ERROR;
}
static vm_translation_map_ops tmap_ops = {
destroy_tmap,
lock_tmap,
unlock_tmap,
map_tmap,
unmap_tmap,
query_tmap,
get_mapped_size_tmap,
protect_tmap,
clear_flags_tmap,
flush_tmap,
get_physical_page_tmap,
put_physical_page_tmap
};
int vm_translation_map_create(vm_translation_map *new_map, bool kernel)
{
if(new_map == NULL)
return -1;
// initialize the new object
new_map->ops = &tmap_ops;
new_map->map_count = 0;
if(recursive_lock_create(&new_map->lock) < 0)
return ERR_NO_MEMORY;
new_map->arch_data = kmalloc(sizeof(vm_translation_map_arch_info));
if(new_map == NULL)
panic("error allocating translation map object!\n");
if(!kernel) {
// user
// allocate a pgdir
new_map->arch_data->pgdir_virt = (addr)kmalloc(PAGE_SIZE);
if(new_map->arch_data->pgdir_virt == NULL) {
kfree(new_map->arch_data);
return -1;
}
if(((addr)new_map->arch_data->pgdir_virt % PAGE_SIZE) != 0)
panic("vm_translation_map_create: malloced pgdir and found it wasn't aligned!\n");
vm_get_page_mapping(vm_get_kernel_aspace_id(), (addr)new_map->arch_data->pgdir_virt, (addr *)&new_map->arch_data->pgdir_phys);
new_map->arch_data->pgdir_phys = PHYS_TO_P1(new_map->arch_data->pgdir_phys);
// zero out the new pgdir
memset((void *)new_map->arch_data->pgdir_virt, 0, PAGE_SIZE);
new_map->arch_data->is_user = true;
} else {
// kernel
// we already know the kernel pgdir mapping
(addr)new_map->arch_data->pgdir_virt = NULL;
(addr)new_map->arch_data->pgdir_phys = vcpu->kernel_pgdir;
new_map->arch_data->is_user = false;
}
return 0;
}
int vm_translation_map_module_init(kernel_args *ka)
{
vcpu = ka->arch_args.vcpu;
return 0;
}
int vm_translation_map_module_init2(kernel_args *ka)
{
return 0;
}
void vm_translation_map_module_init_post_sem(kernel_args *ka)
{
}
// XXX horrible back door to map a page quickly regardless of translation map object, etc.
// used only during VM setup
int vm_translation_map_quick_map(kernel_args *ka, addr va, addr pa, unsigned int lock, addr (*get_free_page)(kernel_args *))
{
struct pdent *pd = NULL;
struct ptent *pt;
unsigned int index;
#if CHATTY_TMAP
dprintf("quick_tmap: va 0x%x pa 0x%x lock 0x%x\n", va, pa, lock);
#endif
if(va < P3_AREA && va >= P4_AREA) {
panic("quick_tmap: asked to map invalid va 0x%x\n", va);
}
pd = (struct pdent *)vcpu->kernel_pgdir;
index = (va & 0x7fffffff) >> 22;
if(pd[index].v == 0) {
vm_page *page;
unsigned int pgtable;
pgtable = (*get_free_page)(ka) * PAGE_SIZE;
memset((void *)PHYS_TO_P1(pgtable), 0, PAGE_SIZE);
pd[index].ppn = pgtable >> 12;
pd[index].v = 1;
}
// get the pagetable
pt = (struct ptent *)PHYS_TO_P1(pd[index].ppn << 12);
index = (va >> 12) & 0x000003ff;
// insert the mapping
pt[index].wt = 0;
pt[index].pr = (lock & LOCK_KERNEL) ? (lock & 0x1) : (lock | 0x2);
pt[index].ppn = pa >> 12;
pt[index].tlb_ent = 0;
pt[index].c = 1;
pt[index].sz = 0x1; // 4k page
pt[index].sh = 0;
pt[index].d = 0;
pt[index].v = 1;
sh4_invl_page(va);
return 0;
}
addr vm_translation_map_get_pgdir(vm_translation_map *map)
{
return (addr)map->arch_data->pgdir_phys;
}
-69
View File
@@ -1,69 +0,0 @@
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
OUTPUT_ARCH(sh)
ENTRY(__start)
SEARCH_DIR("libgcc");
SECTIONS
{
. = 0xc0000000 + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
.rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
.rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
.rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
.rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
.rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) } =0x9090
.plt : { *(.plt) }
/* text/read-only data */
.text : { *(.text .gnu.linkonce.t.*) } =0x9090
.rodata :
{
*(.rodata)
. = ALIGN(0x1000);
} =0x9000
/* writable data */
. = ALIGN(0x1000);
___data_start = .;
.data : { *(.data .gnu.linkonce.d.*) }
___ctor_list = .;
.ctors : { *(.ctors) }
___ctor_end = .;
___dtor_list = .;
.dtors : { *(.dtors) }
___dtor_end = .;
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
/* unintialized data (in same segment as writable data) */
___bss_start = .;
.bss : { *(.bss) }
. = ALIGN(0x1000);
_end = . ;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note .eh_frame) }
}
@@ -1,24 +0,0 @@
# sparc kernel makefile
# included from kernel.mk
KERNEL_ARCH_OBJ_DIR = $(KERNEL_ARCH_DIR)/$(OBJ_DIR)
KERNEL_OBJS += \
KERNEL_ARCH_INCLUDES = $(KERNEL_INCLUDES)
$(KERNEL_ARCH_OBJ_DIR)/%.o: $(KERNEL_ARCH_DIR)/%.c
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
$(CC) -c $< $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -o $@
$(KERNEL_ARCH_OBJ_DIR)/%.d: $(KERNEL_ARCH_DIR)/%.c
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
@echo "making deps for $<..."
@(echo -n $(dir $@); $(CC) $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -M -MG $<) > $@
$(KERNEL_ARCH_OBJ_DIR)/%.d: $(KERNEL_ARCH_DIR)/%.S
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
@echo "making deps for $<..."
@(echo -n $(dir $@);$(CC) $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -M -MG $<) > $@
$(KERNEL_ARCH_OBJ_DIR)/%.o: $(KERNEL_ARCH_DIR)/%.S
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
$(CC) -c $< $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -o $@
@@ -1,24 +0,0 @@
# sparc64 kernel makefile
# included from kernel.mk
KERNEL_ARCH_OBJ_DIR = $(KERNEL_ARCH_DIR)/$(OBJ_DIR)
KERNEL_OBJS += \
KERNEL_ARCH_INCLUDES = $(KERNEL_INCLUDES)
$(KERNEL_ARCH_OBJ_DIR)/%.o: $(KERNEL_ARCH_DIR)/%.c
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
$(CC) -c $< $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -o $@
$(KERNEL_ARCH_OBJ_DIR)/%.d: $(KERNEL_ARCH_DIR)/%.c
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
@echo "making deps for $<..."
@($(ECHO) -n $(dir $@); $(CC) $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -M -MG $<) > $@
$(KERNEL_ARCH_OBJ_DIR)/%.d: $(KERNEL_ARCH_DIR)/%.S
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
@echo "making deps for $<..."
@($(ECHO) -n $(dir $@);$(CC) $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -M -MG $<) > $@
$(KERNEL_ARCH_OBJ_DIR)/%.o: $(KERNEL_ARCH_DIR)/%.S
@mkdir -p $(KERNEL_ARCH_OBJ_DIR)
$(CC) -c $< $(GLOBAL_CFLAGS) $(KERNEL_ARCH_INCLUDES) -o $@