1 Commits
wip/fat ... dc

Author SHA1 Message Date
Travis Geiselbrecht
1c8d7b4268 start of a SH port 2008-09-01 02:45:04 -07:00
19 changed files with 1306 additions and 1 deletions

43
arch/sh/arch.c Executable file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <arch.h>
#include <arch/ops.h>
void arch_early_init(void)
{
#if 0
/* turn off the cache */
arch_disable_cache();
#if ARM_WITH_MMU
arm_mmu_init();
#endif
arch_enable_cache();
#endif
}
void arch_init(void)
{
}

245
arch/sh/asm.S Normal file
View File

@@ -0,0 +1,245 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define FUNCTION(name) .align 2 ; .globl _##name ; .type _##name,@function ; _##name
FUNCTION(arch_restore_ints):
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_enable_ints):
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_disable_ints):
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 */
.align 2
imask_bit_mask: .long 0x000000f0
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_disable_ints
restore_interrupts_addr: .long _arch_restore_ints
// 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(arch_idle):
rts
nop

31
arch/sh/crt0.S Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.globl _start
_start:
mov.l _kmain_addr,r0
jsr @r0
nop
.align 2
_kmain_addr:
.long _kmain

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __SH_ARCH_THREAD_H
#define __SH_ARCH_THREAD_H
struct arch_thread {
vaddr_t sp;
};
#endif

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __ARCH_SH4_H
#define __ARCH_SH4_H
#endif

46
arch/sh/rules.mk Normal file
View File

@@ -0,0 +1,46 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
#CFLAGS += -mcpu=$(ARM_CPU) -finline
CFLAGS += -ml -m4-single-only -mhitachi
DEFINES += \
ARM_CPU_$(ARM_CPU)=1
INCLUDES += \
-I$(LOCAL_DIR)/include
BOOTOBJS += \
$(LOCAL_DIR)/crt0.o
OBJS += \
$(LOCAL_DIR)/asm.o \
$(LOCAL_DIR)/arch.o \
$(LOCAL_DIR)/thread.o
# $(LOCAL_DIR)/arch.o \
$(LOCAL_DIR)/asm.o \
$(LOCAL_DIR)/cache.o \
$(LOCAL_DIR)/ops.o \
$(LOCAL_DIR)/exceptions.o \
$(LOCAL_DIR)/faults.o \
$(LOCAL_DIR)/mmu.o \
$(LOCAL_DIR)/thread.o
# potentially generated files that should be cleaned out with clean make rule
GENERATED += \
$(BUILDDIR)/system-onesegment.ld \
$(BUILDDIR)/system-twosegment.ld
# rules for generating the linker scripts
$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@

View File

@@ -0,0 +1,77 @@
OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
OUTPUT_ARCH(sh)
ENTRY(_start)
SECTIONS
{
. = %MEMBASE%;
.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 .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
___commands_start = .;
KEEP (*(.commands))
___commands_end = .;
. = ALIGN(4);
___rodata_end = . ;
}
/* writable data */
___data_start_rom = .; /* in one segment binaries, the rom data address is on top of the ram data address */
___data_start = .;
.data : { *(.data .data.* .gnu.linkonce.d.*) }
___ctor_list = .;
.ctors : { *(.ctors) }
___ctor_end = .;
___dtor_list = .;
.dtors : { *(.dtors) }
___dtor_end = .;
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
___data_end = .;
/* unintialized data (in same segment as writable data) */
. = ALIGN(4);
___bss_start = .;
.bss : { *(.bss .bss.*) }
. = ALIGN(4);
__end = .;
. = %MEMBASE% + %MEMSIZE%;
__end_of_ram = .;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note .eh_frame) }
}

View File

@@ -0,0 +1,80 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = %ROMBASE%;
.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 .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
__commands_start = .;
KEEP (*(.commands))
__commands_end = .;
. = ALIGN(4);
__rodata_end = . ;
}
/* writable data */
__data_start_rom = .;
. = %MEMBASE%;
__data_start = .;
.data :
AT ( ADDR (.rodata) + SIZEOF (.rodata) )
{ *(.data .data.* .gnu.linkonce.d.*) }
__ctor_list = .;
.ctors : { *(.ctors) }
__ctor_end = .;
__dtor_list = .;
.dtors : { *(.dtors) }
__dtor_end = .;
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
__data_end = .;
/* unintialized data (in same segment as writable data) */
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss .bss.*) }
. = ALIGN(4);
_end = . ;
. = %MEMBASE% + %MEMSIZE%;
_end_of_ram = . ;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note .eh_frame) }
}

86
arch/sh/thread.c Normal file
View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include <debug.h>
#include <kernel/thread.h>
#include <arch/sh4.h>
struct context_switch_frame {
addr_t pr;
addr_t r14;
addr_t r13;
addr_t r12;
addr_t r11;
addr_t r10;
addr_t r9;
addr_t r8;
addr_t macl;
addr_t mach;
addr_t fpscr;
addr_t fr15;
addr_t fr14;
addr_t fr13;
addr_t fr12;
};
extern void sh4_context_switch(addr_t *old_sp, addr_t new_sp);
static void initial_thread_func(void) __NO_RETURN;
static void initial_thread_func(void)
{
int ret;
// dprintf("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
// dump_thread(current_thread);
/* exit the implicit critical section we're within */
exit_critical_section();
ret = current_thread->entry(current_thread->arg);
dprintf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret);
thread_exit(ret);
}
void arch_thread_initialize(thread_t *t)
{
// create a default stack frame on the stack
struct context_switch_frame *frame = (struct context_switch_frame *)((vaddr_t)t->stack + t->stack_size);
frame--;
// fill it in
memset(frame, 0, sizeof(*frame));
frame->pr = (vaddr_t)&initial_thread_func;
// set the stack pointer
t->arch.sp = (vaddr_t)frame;
}
void arch_context_switch(thread_t *oldthread, thread_t *newthread)
{
// dprintf("arch_context_switch: old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
sh4_context_switch(&oldthread->arch.sp, newthread->arch.sp);
}

View File

@@ -42,7 +42,7 @@ typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned long size_t;
//typedef unsigned long size_t;
typedef long ssize_t;
typedef long long off_t;

139
platform/sh4/debug.c Normal file
View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdarg.h>
#include <reg.h>
#include <debug.h>
#include <kernel/thread.h>
#include <platform/debug.h>
#include <lib/printf.h>
#include <arch/ops.h>
#if 0
static void write_uart_reg(int uart, int reg, unsigned char data)
{
unsigned long base;
int mul = 4;
switch(uart) {
case 0: base = UART0_BASE; break;
case 1: base = UART1_BASE; break;
case 2: base = UART2_BASE; break;
default: return;
}
*(volatile unsigned char *)(base + reg * mul) = data;
}
static unsigned char read_uart_reg(int uart, int reg)
{
unsigned long base;
int mul = 4;
switch(uart) {
case 0: base = UART0_BASE; break;
case 1: base = UART1_BASE; break;
case 2: base = UART2_BASE; break;
default: return 0;
}
return *(volatile unsigned char *)(base + reg * mul);
}
#endif
static int uart_init(void)
{
/* clear the tx & rx fifo and disable */
// write_uart_reg(0, UART_FCR, 0x6);
return 0;
}
static int uart_putc(int port, char c )
{
#if 0
while (!(read_uart_reg(port, UART_LSR) & (1<<6))) // wait for the shift register to empty
;
write_uart_reg(port, UART_THR, c);
return 0;
#endif
}
static int uart_getc(int port, bool wait) /* returns -1 if no data available */
{
#if 0
if (wait) {
while (!(read_uart_reg(port, UART_LSR) & (1<<0))) // wait for data to show up in the rx fifo
;
} else {
if (!(read_uart_reg(port, UART_LSR) & (1<<0)))
return -1;
}
return read_uart_reg(port, UART_RHR);
#endif
}
int dgetc(char *c)
{
return -1;
}
void dputc(char c)
{
// uart_putc(0, c);
}
void debug_dump_regs(void)
{
PANIC_UNIMPLEMENTED;
}
void debug_halt(void)
{
dprintf("HALT: spinning forever...\n");
for(;;);
}
void debug_dump_memory_bytes(void *mem, int len)
{
PANIC_UNIMPLEMENTED;
}
void debug_dump_memory_halfwords(void *mem, int len)
{
PANIC_UNIMPLEMENTED;
}
void debug_dump_memory_words(void *mem, int len)
{
PANIC_UNIMPLEMENTED;
}
void debug_set_trace_level(int trace_type, int level)
{
PANIC_UNIMPLEMENTED;
}
uint32_t debug_cycle_count()
{
PANIC_UNIMPLEMENTED;
}

243
platform/sh4/interrupts.c Normal file
View File

@@ -0,0 +1,243 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <err.h>
#include <sys/types.h>
#include <debug.h>
#include <reg.h>
#include <kernel/thread.h>
#include <platform/interrupts.h>
#include <arch/ops.h>
#include "platform_p.h"
#define INT_VECTORS 16
struct int_handler_struct {
int_handler handler;
void *arg;
};
static struct int_handler_struct int_handler_table[INT_VECTORS];
#if 0
static const uint32_t icBase[5] = {
INTCON0_BASE, INTCON1_BASE, INTCON2_BASE, INTCON3_BASE, INTCON4_BASE };
/* a bitmap of the level triggered interrupt vectors */
static uint32_t level_trigger[5] = {
0xb3fefe8f, // level 1 0-31
0xfdb3c1fd, // level 2 0-31
0xfffff7ff, // level 2 32-63
0xbfffffff, // level 2 64-95
0xffffffff // level 2 96-128
};
inline volatile uint32_t *ICReg(uint controller, uint reg)
{
return (volatile uint32_t *)(icBase[controller] + reg);
}
inline uint32_t readICReg(uint controller, uint reg)
{
return *ICReg(controller, reg);
}
inline void writeICReg(uint controller, uint reg, uint val)
{
*ICReg(controller, reg) = val;
}
inline uint vectorToController(uint vector)
{
return vector / 32;
}
#endif
void platform_init_interrupts(void)
{
#if 0
unsigned int i;
// mask all interrupts
*ICReg(0, INTCON_MIR) = 0xfffffffa;
*ICReg(1, INTCON_MIR) = 0xffffffff;
*ICReg(2, INTCON_MIR) = 0xffffffff;
*ICReg(3, INTCON_MIR) = 0xffffffff;
*ICReg(4, INTCON_MIR) = 0xffffffff;
// set up each of the interrupts
for (i = 0; i < INT_VECTORS; i++) {
// set each vector up as high priority, IRQ, and default edge/level sensitivity
*ICReg(i / 32, INTCON_ILR_BASE + 4*(i%32)) = ((level_trigger[i/32] & (1<<(i%32))) ? (1<<1) : (0<<1)) | 0;
}
// clear any pending interrupts
*ICReg(0, INTCON_ITR) = 0;
*ICReg(1, INTCON_ITR) = 0;
*ICReg(2, INTCON_ITR) = 0;
*ICReg(3, INTCON_ITR) = 0;
*ICReg(4, INTCON_ITR) = 0;
// globally unmask interrupts
*ICReg(1, INTCON_CONTROL) = 3;
*ICReg(0, INTCON_CONTROL) = 3;
*ICReg(0, INTCON_GMR) = 0;
dprintf("end of platform_init_interrupts\n");
#if 0
arch_enable_ints();
dprintf("&ITR0 0x%x\n", (uint32_t)ICReg(0, INTCON_ITR));
dprintf("ITR0 0x%x\n", *ICReg(0, INTCON_ITR));
dprintf("MIR0 0x%x\n", *ICReg(0, INTCON_MIR));
dprintf("SIR_IRQ0 0x%x\n", *ICReg(0, INTCON_SIR_IRQ));
*ICReg(0, INTCON_ILR_BASE + 4*7) = 0;
*ICReg(0, INTCON_MIR) &= ~0x80;
dprintf("triggering int\n");
*ICReg(0, INTCON_SISR) = 0x80;
dprintf("ITR0 0x%x\n", *ICReg(0, INTCON_ITR));
dprintf("MIR0 0x%x\n", *ICReg(0, INTCON_MIR));
dprintf("SIR_IRQ0 0x%x\n", *ICReg(0, INTCON_SIR_IRQ));
for(;;);
#endif
#endif
}
status_t mask_interrupt(unsigned int vector, bool *oldstate)
{
PANIC_UNIMPLEMENTED;
#if 0
if (vector >= INT_VECTORS)
return ERR_INVALID_ARGS;
// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector);
enter_critical_section();
if (oldstate)
*oldstate = false;
volatile uint32_t *mir = ICReg(vectorToController(vector), INTCON_MIR);
*mir = *mir | (1<<(vector % 32));
exit_critical_section();
return NO_ERROR;
#endif
}
status_t unmask_interrupt(unsigned int vector, bool *oldstate)
{
PANIC_UNIMPLEMENTED;
#if 0
if (vector >= INT_VECTORS)
return ERR_INVALID_ARGS;
// dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector);
enter_critical_section();
if (oldstate)
*oldstate = false;
volatile uint32_t *mir = ICReg(vectorToController(vector), INTCON_MIR);
*mir = *mir & ~(1<<(vector % 32));
exit_critical_section();
return NO_ERROR;
#endif
}
void platform_irq(/* struct arm_iframe *frame */)
{
PANIC_UNIMPLEMENTED;
#if 0
// get the current vector
unsigned int vector;
inc_critical_section();
// read from the first level int handler
vector = *ICReg(0, INTCON_SIR_IRQ);
// see if it's coming from the second level handler
if (vector == 0) {
vector = *ICReg(1, INTCON_SIR_IRQ) + 32;
}
// dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector);
// deliver the interrupt
enum handler_return ret;
ret = INT_NO_RESCHEDULE;
if (int_handler_table[vector].handler)
ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
// ack the interrupt
if (vector >= 32) {
// interrupt is chained, so ack the second level first, and then the first
*ICReg(vector / 32, INTCON_ITR) = ~(1 << (vector % 32));
*ICReg(1, INTCON_CONTROL) |= 1;
vector = 0; // force the following code to ack the chained first level vector
}
*ICReg(0, INTCON_ITR) = ~(1 << vector);
*ICReg(0, INTCON_CONTROL) = 1;
if (ret == INT_RESCHEDULE)
thread_preempt();
dec_critical_section();
// dprintf("platform_irq: exit\n");
#endif
}
void platform_fiq(/* struct arm_iframe *frame */)
{
PANIC_UNIMPLEMENTED;
}
void register_int_handler(unsigned int vector, int_handler handler, void *arg)
{
PANIC_UNIMPLEMENTED;
#if 0
if (vector >= INT_VECTORS)
panic("register_int_handler: vector out of range %d\n", vector);
enter_critical_section();
int_handler_table[vector].handler = handler;
int_handler_table[vector].arg = arg;
exit_critical_section();
#endif
}

50
platform/sh4/platform.c Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <err.h>
#include <debug.h>
#include <platform.h>
#include "platform_p.h"
//#include <arch/arm/mmu.h>
void platform_early_init(void)
{
#if 0
/* do some memory map initialization */
addr_t addr;
arm_mmu_map_section(SDRAM_BASE, 0, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED);
for (addr = SDRAM_BASE; addr < SDRAM_BASE + SDRAM_SIZE; addr += (1024*1024)) {
arm_mmu_map_section(addr, addr, MMU_FLAG_CACHED|MMU_FLAG_BUFFERED|MMU_FLAG_READWRITE);
}
#endif
/* initialize the interrupt controller */
platform_init_interrupts();
/* initialize the timer block */
platform_init_timer();
}
void platform_init(void)
{
}

30
platform/sh4/platform_p.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __PLATFORM_P_H
#define __PLATFORM_P_H
void platform_init_interrupts(void);
void platform_init_timer(void);
#endif

24
platform/sh4/rules.mk Normal file
View File

@@ -0,0 +1,24 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
ARCH := sh
SH_CPU := sh4
CPU := generic
INCLUDES += \
-I$(LOCAL_DIR)/include
OBJS += \
$(LOCAL_DIR)/debug.o \
$(LOCAL_DIR)/interrupts.o \
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/timer.o
# $(LOCAL_DIR)/console.o \
MEMBASE := 0x80c00000
MEMSIZE := 0x01000000 # 16MB
LINKER_SCRIPT += \
$(BUILDDIR)/system-onesegment.ld

99
platform/sh4/timer.c Normal file
View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <sys/types.h>
#include <err.h>
#include <kernel/thread.h>
#include <debug.h>
#include <platform.h>
#include <platform/interrupts.h>
#include <platform/timer.h>
#include "platform_p.h"
static time_t system_time = 0;
static time_t tick_interval;
static uint32_t ticks_per_interval;
static platform_timer_callback t_callback;
static void *callback_arg;
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval)
{
PANIC_UNIMPLEMENTED;
#if 0
enter_critical_section();
t_callback = callback;
callback_arg = arg;
tick_interval = interval;
ticks_per_interval = interval * 32768 / 1000; // interval is in ms
OS_TIMER_CTRL_REG = 0; // stop it
OS_TIMER_TICK_VALUE_REG = ticks_per_interval;
OS_TIMER_CTRL_REG = (1<<3) | (1<<2) | (1<<1) | (1<<0);
exit_critical_section();
return NO_ERROR;
#endif
}
time_t current_time(void)
{
PANIC_UNIMPLEMENTED;
#if 0
time_t t;
uint32_t delta_ticks;
uint32_t delta_ticks2;
retry:
delta_ticks = OS_TIMER_TICK_COUNTER_REG;
t = system_time;
delta_ticks2 = OS_TIMER_TICK_COUNTER_REG;
if (delta_ticks2 > delta_ticks)
goto retry;
t += ((ticks_per_interval - delta_ticks2) * tick_interval) / ticks_per_interval;
return t;
#endif
}
static enum handler_return os_timer_tick(void *arg)
{
system_time += tick_interval;
// dprintf("os_timer_tick %d\n", system_time);
return t_callback(callback_arg, system_time);
}
void platform_init_timer(void)
{
PANIC_UNIMPLEMENTED;
#if 0
OS_TIMER_CTRL_REG = 0; // stop the timer if it's already running
register_int_handler(IRQ_OS_TIMER, &os_timer_tick, NULL);
unmask_interrupt(IRQ_OS_TIMER, NULL);
#endif
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <app/tests.h>
#include <app/console.h>
void project_init(void)
{
console_init();
tests_init();
console_run_command("printf_tests");
console_run_command("thread_tests");
console_start();
}

View File

@@ -0,0 +1,12 @@
# top level project rules for the armemu-test project
#
LOCAL_DIR := $(GET_LOCAL_DIR)
TARGET := dreamcast
APPS := tests \
console
OBJS += \
$(LOCAL_DIR)/init.o

View File

@@ -0,0 +1,4 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
PLATFORM := sh4