Commit 19ad546a authored by Yoshinori Sato's avatar Yoshinori Sato Committed by Linus Torvalds

[PATCH] h8300: interrupt management update

interrupt management update
target-support file update
gcc-3.3 support
blkdev location cleanup
parent 4f7a28bb
#
# h8300h/Makefile
#
# This file is included by the global makefile so that you can add your own
# platform-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (c) 2001 Lineo, Inc, <www.lineo.com>
# Copyright (c) 2000,2001 D. Jeff Dionne <jeff@lineo.ca>
# Copyright (c) 1998,1999 D. Jeff Dionne <jeff@uclinux.org>
# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
# Copyright (C) 1994 Hamish Macdonald
#
# 68VZ328 Fixes By Evan Stawnyczy <e@lineo.ca>
# H8/300H Modify By Yoshinori Sato <ysato@users.sourceforge.jp>
CROSS_COMPILE = h8300-elf-
GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
INCGCC = $(GCC_DIR)/include
LIBGCC = $(GCC_DIR)/h8300h/int32/libgcc.a
CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -mint32 -malign-300 -D__ELF__ -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__ -DTARGET=$(BOARD)
AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -D__ELF__ -DUTS_SYSNAME=\"uClinux\"
LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
LDFLAGS := $(LDFLAGS) -mh8300helf
HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
arch/$(ARCH)/platform/$(PLATFORM) \
arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD) \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
arch/$(ARCH)/platform/$(PLATFORM)/platform.o \
arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(BOARD).o \
$(CORE_FILES)
LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
linux.bin: linux
$(OBJCOPY) -O binary linux linux.bin
archclean:
rm -f linux
......@@ -6,8 +6,7 @@
# unless it's something special (ie not a .c file).
#
all: $(BOARD).o
O_TARGET := $(BOARD).o
extra-y := crt0_ram.o
obj-y := timer.o
timer.o: timer.c
......
......@@ -3,7 +3,7 @@
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup for uClinux-2.4.x
* Platform depend startup
* Target Archtecture: AE-3068 (aka. aki3068net)
* Memory Layout : RAM
*/
......@@ -13,6 +13,16 @@
#include <linux/config.h>
#include <asm/linkage.h>
#if !defined(CONFIG_BLKDEV_RESERVE)
#if defined(CONFIG_GDB_DEBUG)
#define RAMEND (__ramend - 0xc000)
#else
#define RAMEND __ramend
#endif
#else
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
#endif
.global SYMBOL_NAME(_start)
.global SYMBOL_NAME(command_line)
.global SYMBOL_NAME(_platform_gpio_table)
......@@ -25,23 +35,28 @@
/* CPU Reset entry */
SYMBOL_NAME_LABEL(_start)
mov.l #__ramend,sp
mov.l #RAMEND,sp
ldc #0x80,ccr
/* Peripheral Setup */
#if defined(CONFIG_BLK_DEV_BLKMEM)
/* move romfs image */
jsr @__move_romfs
#endif
/* .bss clear */
mov.l #__sbss,er5
mov.l er5,er6
inc.l #1,er6
mov.l #__ebss,er4
sub.l er5,er4
sub.w r0,r0
mov.b r0l,@er5
shlr er4
shlr er4
sub.l er0,er0
1:
eepmov.w
dec.w #1,e4
bpl 1b
mov.l er0,@er5
adds #4,er5
dec.l #1,er4
bne 1b
/* copy kernel commandline */
mov.l #COMMAND_START,er5
......@@ -49,22 +64,9 @@ SYMBOL_NAME_LABEL(_start)
mov.w #512,r4
eepmov.w
/* RAM Interrupt Vector Table Setup */
#if defined(CONFIG_GDB_DEBUG)
mov.l @SYMBOL_NAME(interrupt_redirect_table)+11*4,er0
#endif
mov.l #SYMBOL_NAME(_vector_lma),er5
mov.l #SYMBOL_NAME(interrupt_redirect_table),er6
mov.w #0x100,r4
eepmov.w
#if defined(CONFIG_GDB_DEBUG)
mov.l er0,@SYMBOL_NAME(interrupt_redirect_table)+11*4
#endif
/* uClinux kernel start */
ldc #0x90,ccr /* running kernel */
mov.l #SYMBOL_NAME(init_task_union),sp
mov.l sp,@SYMBOL_NAME(_current_task)
mov.l #SYMBOL_NAME(init_thread_union),sp
add.l #0x2000,sp
jsr @_start_kernel
_exit:
......
......@@ -5,86 +5,7 @@ ENTRY("__start")
MEMORY
{
ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000-0x80000
disk : ORIGIN = 0x600000-0x80000, LENGTH = 0x60000
ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000
eram : ORIGIN = 0x600000, LENGTH = 0
iram : ORIGIN = 0xffbf20, LENGTH = 0x4000
}
SECTIONS
{
.bootvec :
{
*(.bootvec)
} > ram
.text :
{
__stext = . ;
*(.text)
. = ALIGN(0x4) ;
*(.text.*)
. = ALIGN(0x4) ;
*(.kstrtab)
. = ALIGN(0x4) ;
*(.rodata*)
. = ALIGN(16); /* Exception table */
___start___ex_table = .;
*(__ex_table)
___stop___ex_table = .;
___start___ksymtab = .; /* Kernel symbol table */
*(__ksymtab)
___stop___ksymtab = .;
. = ALIGN(0x4) ;
__etext = . ;
} > ram
.data :
{
__sdata = . ;
___data_start = . ;
*(.data)
*(.data.*)
*(.exitcall.exit)
. = ALIGN(0x2000) ;
*(.data.init_task)
. = ALIGN(0x2000) ;
___init_begin = .;
*(.text.init)
*(.data.init)
. = ALIGN(16);
___setup_start = .;
*(.setup.init)
___setup_end = .;
___initcall_start = .;
*(.initcall.init)
. = ALIGN(4) ;
___initcall_end = .;
___init_end = .;
__edata = . ;
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss)
. = ALIGN(0x4) ;
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
__ramstart = .;
} > ram
.blkimg :
{
__ramend = . ;
__blkimg = . ;
} > disk
.ram_vec : AT(ADDR(.data) + SIZEOF(.data))
{
*(.int_redirect)
} > iram
__vector_lma = LOADADDR(.ram_vec);
.dummy2 :
{
COMMAND_START = . - 0x200 ;
} > eram
}
......@@ -14,29 +14,32 @@
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/timex.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/regs306x.h>
#include <linux/timex.h>
#define TMR8CMA2 0x00ffff94
#define TMR8TCSR2 0x00ffff92
#define TMR8TCNT2 0x00ffff90
#define CMFA 6
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
extern int request_irq_boot(unsigned int,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
{
outb(CONFIG_CLK_FREQ*10/8192,TMR8CMA2);
outb(0x00,TMR8TCSR2);
request_irq(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,TMR8TCNT2);
outb(H8300_TIMER_COUNT_DATA,TCORA2);
outb(0x00,_8TCSR2);
request_irq_boot(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,_8TCR2);
}
void platform_timer_eoi(void)
{
*(unsigned char *)TMR8TCSR2 &= ~(1 << CMFA);
*(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
}
void platform_gettod(int *year, int *mon, int *day, int *hour,
......
......@@ -3,6 +3,7 @@
* linux/arch/h8300/platform/h8300h/entry.S
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
* David McCullough <davidm@snapgear.com>
*
*/
......@@ -29,14 +30,17 @@ SOFTIRQ_PENDING = 0
/* the following macro is used when enabling interrupts */
LER3 = 0
LER2 = 4
LER1 = 8
LORIG = 12
LCCR = 16
LER0 = 18
LVEC = 22
LRET = 24
LER4 = 0
LER5 = 4
LER6 = 8
LER3 = 12
LER2 = 16
LER1 = 20
LORIG = 24
LCCR = 28
LER0 = 30
LVEC = 34
LRET = 38
.h8300h
......@@ -44,100 +48,123 @@ LRET = 24
.macro SAVE_ALL
mov.l er0,@-sp
stc ccr,r0l
stc ccr,r0l /* check kernel mode */
orc #0x10,ccr
btst #4,r0l
bne 1f
mov.l sp,@SYMBOL_NAME(sw_usp)
bne 5f
mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
mov.l @sp,er0
mov.l @SYMBOL_NAME(sw_ksp),sp
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
mov.l er0,@-sp
stc ccr,r0l
and #0xef,r0l
mov.w r0,@-sp
mov.l @(2:16,sp),er0
bra 2f
1:
mov.l @sp,er0
stc ccr,@-sp
2:
mov.l er1,@-sp
mov.l @SYMBOL_NAME(sw_usp),er0
mov.l @(8:16,er0),er1 /* copy the RET addr */
mov.l er1,@(LRET-LER1:16,sp)
mov.w e1,r1 /* e1 highbyte = ccr */
and #0xef,r1h /* mask mode? flag */
sub.w r0,r0
mov.b r1h,r0l
mov.w r0,@(LCCR-LER1:16,sp) /* copy ccr */
mov.l @(LORIG-LER1:16,sp),er0
mov.l er0,@(LER0-LER1:16,sp) /* copy ER0 */
bra 6f
5:
mov.l @sp,er0 /* kernel mode */
subs #2,sp /* dummy ccr */
mov.l er0,@-sp
mov.l er1,@-sp
mov.w @(LRET-LER1:16,sp),r1 /* copy old ccr */
mov.b r1h,r1l
mov.b #0,r1h
mov.w r1,@(LCCR-LER1:16,sp) /* set ccr */
6:
mov.l er2,@-sp
mov.l er3,@-sp
mov.l er6,@-sp /* syscall arg #6 */
mov.l er5,@-sp /* syscall arg #5 */
mov.l er4,@-sp /* syscall arg #4 */
.endm
.macro RESTORE_REGS
mov.w @(LCCR:16,sp),r0
.macro RESTORE_ALL
mov.l @sp+,er4
mov.l @sp+,er5
mov.l @sp+,er6
mov.l @sp+,er3
mov.l @sp+,er2
mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
btst #4,r0l
bne 1f
bne 7f
orc #0x80,ccr
mov.l @SYMBOL_NAME(sw_usp),er0
mov.l @(LER0:16,sp),er1
mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
mov.l er1,@er0
mov.l @sp+,er3
mov.l @sp+,er2
mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
mov.b r1l,r1h
mov.b @(LRET+1-LER1:16,sp),r1l
mov.w r1,e1
mov.w @(LRET+2-LER1:16,sp),r1
mov.l er1,@(8:16,er0)
mov.l @sp+,er1
add.l #10,sp
add.l #(LRET-LORIG),sp /* remove LORIG - LRET */
mov.l sp,@SYMBOL_NAME(sw_ksp)
mov.l er0,sp
bra 2f
1:
mov.l @sp+,er3
mov.l @sp+,er2
bra 8f
7:
mov.l @sp+,er1
adds #4,sp
adds #2,sp
2:
8:
mov.l @sp+,er0
adds #4,sp
.endm
.macro RESTORE_ALL
RESTORE_REGS
adds #4,sp /* remove the sw created LVEC */
rte
.endm
#define SWITCH_STACK_SIZE (3*4+12) /* includes return address */
.macro SAVE_SWITCH_STACK
mov.l er4,@-sp
mov.l er5,@-sp
mov.l er6,@-sp
.endm
.macro RESTORE_SWITCH_STACK
mov.l @sp+,er6
mov.l @sp+,er5
mov.l @sp+,er4
.endm
.globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(ret_from_exception)
.globl SYMBOL_NAME(ret_from_fork)
.globl SYMBOL_NAME(ret_from_signal)
.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
.globl SYMBOL_NAME(ret_from_interrupt)
.globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
.globl SYMBOL_NAME(resume)
.globl SYMBOL_NAME(sys_vfork)
.globl SYMBOL_NAME(syscall_trampoline)
.globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(interrupt_entry)
.globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(trace_break)
#if defined(CONFIG_ROMKERNEL)
INTERRUPTS = 64
.section .int_redirect,"ax"
SYMBOL_NAME_LABEL(interrupt_redirect_table)
.rept 7
.long 0
.endr
jsr @interrupt_entry /* NMI */
jsr @SYMBOL_NAME(interrupt_entry) /* NMI */
jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */
.long 0
.long 0
jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */
.rept 64-12
jsr @interrupt_entry
.rept INTERRUPTS-12
jsr @SYMBOL_NAME(interrupt_entry)
.endr
#endif
#if defined(CONFIG_RAMKERNEL)
.globl SYMBOL_NAME(interrupt_redirect_table)
.section .bss
SYMBOL_NAME_LABEL(interrupt_redirect_table)
.space 4
#endif
.section .text
.align 2
interrupt_entry:
SYMBOL_NAME_LABEL(interrupt_entry)
SAVE_ALL
mov.w @(LCCR,sp),r0
btst #4,r0l
......@@ -148,114 +175,91 @@ interrupt_entry:
1:
mov.l @(LVEC,sp),er0
2:
#if defined(CONFIG_ROMKERNEL)
sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
#endif
#if defined(CONFIG_RAMKERNEL)
mov.l @SYMBOL_NAME(interrupt_redirect_table),er1
sub.l er1,er0
#endif
shlr.l er0
shlr.l er0
dec.l #1,er0
mov.l sp,er1
subs #4,er1 /* adjust ret_pc */
jsr @SYMBOL_NAME(process_int)
mov.l @SYMBOL_NAME(irq_stat)+SOFTIRQ_PENDING,er0
beq 1f
jsr @SYMBOL_NAME(do_softirq)
1:
jmp @SYMBOL_NAME(ret_from_exception)
SYMBOL_NAME_LABEL(system_call)
subs #4,sp
subs #4,sp /* dummy LVEC */
SAVE_ALL
mov.l er0,er3
mov.w @(LCCR:16,sp),r1
bset #4,r1l
ldc r1l,ccr
mov.l er0,er4
mov.l #-ENOSYS,er0
mov.l er0,@(LER0:16,sp)
/* save top of frame */
mov.l sp,er0
mov.l er3,@-sp
jsr @SYMBOL_NAME(set_esp0)
mov.l @sp+,er3
cmp.l #NR_syscalls,er3
cmp.l #NR_syscalls,er4
bcc SYMBOL_NAME(ret_from_exception):16
shll.l er3
shll.l er3
shll.l er4
shll.l er4
mov.l #SYMBOL_NAME(sys_call_table),er0
add.l er3,er0
mov.l @er0,er0
mov.l er0,er3
add.l er4,er0
mov.l @er0,er4
beq SYMBOL_NAME(ret_from_exception):16
mov.l @SYMBOL_NAME(_current_task),er2
mov.l sp,er2
and.w #0xe000,r2
mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
btst #(TIF_SYSCALL_TRACE & 7),r2l
bne 1f
mov.l @(LER1:16,sp),er0
mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2
mov.l er5,@-sp
mov.l er4,@-sp
jsr @er3
adds #4,sp
adds #4,sp
mov.l er0,@(LER0,sp) /* save the return value */
jsr @er4
mov.l er0,@(LER0,sp) /* save the return value */
#if defined(CONFIG_SYSCALL_PRINT)
jsr @SYMBOL_NAME(syscall_print)
#endif
jmp @SYMBOL_NAME(ret_from_exception)
1:
SAVE_SWITCH_STACK
mov.l er3,er5 /* save syscall entry */
jsr SYMBOL_NAME(syscall_trace)
mov.l er5,er3
RESTORE_SWITCH_STACK
mov.l @(LER1:16,sp),er0
mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2
mov.l er5,@-sp
mov.l er4,@-sp
jsr @er3
adds #4,sp
adds #4,sp
jsr @er4
mov.l er0,@(LER0:16,sp) /* save the return value */
SAVE_SWITCH_STACK
jsr SYMBOL_NAME(syscall_trace)
SYMBOL_NAME_LABEL(ret_from_signal)
RESTORE_SWITCH_STACK
SYMBOL_NAME_LABEL(ret_from_exception)
mov.b @(LCCR+1:16,sp),r0l
btst #4,r0l /* check if returning to kernel */
bne 3f /* if so, skip resched, signals */
andc #0x7f,ccr
mov.l @SYMBOL_NAME(_current_task),er0
mov.l sp,er2
and.w #0xe000,r2
mov.l @(TI_FLAGS:16,er2),er1
and.l #_TIF_WORK_MASK,er1
bne 1f
mov.l @((TASK_THREAD+THREAD_VFORK):16,er0),er1
bne Lvfork_return
3:
RESTORE_ALL /* Does RTE */
beq 3f
1:
mov.l @(TI_FLAGS:16,er2),er1
btst #TIF_NEED_RESCHED,r1l
bne @SYMBOL_NAME(reschedule):16
Lsignal_return:
SAVE_SWITCH_STACK
mov.l sp,er1
add #12,er1
mov.l er2,er0
jsr @SYMBOL_NAME(do_signal)
RESTORE_SWITCH_STACK
mov.l @SYMBOL_NAME(_current_task),er0
mov.l @((TASK_THREAD+THREAD_VFORK):16,er0),er1
bne Lvfork_return
RESTORE_ALL
3:
RESTORE_ALL /* Does RTE */
Lvfork_return:
sub.l er2,er2
mov.l er2,@((TASK_THREAD+THREAD_VFORK):16,er0)
mov.l @SYMBOL_NAME(sw_usp),er0
mov.l er1,@(8:16,er0)
RESTORE_ALL
SYMBOL_NAME_LABEL(reschedule)
/* save top of frame */
mov.l sp,er0
......@@ -265,6 +269,11 @@ SYMBOL_NAME_LABEL(reschedule)
mov.l er0,@-sp
jmp @SYMBOL_NAME(schedule)
SYMBOL_NAME_LABEL(ret_from_fork)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
jmp @SYMBOL_NAME_LABEL(ret_from_exception)
SYMBOL_NAME_LABEL(resume)
/*
* Beware - when entering resume, offset of tss is in d1,
......@@ -277,17 +286,13 @@ SYMBOL_NAME_LABEL(resume)
/* save sr */
sub.w r3,r3
stc ccr,r3l
mov.w r3,@(THREAD_CCR:16,er0)
SAVE_SWITCH_STACK
mov.w r3,@(THREAD_CCR+2:16,er0)
/* disable interrupts */
orc #0x80,ccr
mov.l @SYMBOL_NAME(sw_usp),er3
mov.l er3,@(THREAD_USP:16,er0)
mov.l sp,@(THREAD_KSP:16,er0)
/* get pointer to tss struct (a1 contains new task) */
mov.l er1,@SYMBOL_NAME(_current_task)
/* Skip address space switching if they are the same. */
/* FIXME: what did we hack out of here, this does nothing! */
......@@ -295,23 +300,13 @@ SYMBOL_NAME_LABEL(resume)
mov.l @(THREAD_USP:16,er1),er0
mov.l er0,@SYMBOL_NAME(sw_usp)
mov.l @(THREAD_KSP:16,er1),sp
RESTORE_SWITCH_STACK
/* restore status register */
mov.w @(THREAD_CCR:16,er1),r3
mov.w @(THREAD_CCR+2:16,er1),r3
ldc r3l,ccr
rts
/* Handler for uninitialized and spurious interrupts */
SYMBOL_NAME_LABEL(bad_interrupt)
mov.l @SYMBOL_NAME(num_spurious),er0
inc.l #1,er0
mov.l er0,@SYMBOL_NAME(num_spurious)
rts
SYMBOL_NAME_LABEL(trace_break)
subs #4,sp
SAVE_ALL
......@@ -329,26 +324,10 @@ SYMBOL_NAME_LABEL(trace_break)
jsr @SYMBOL_NAME(trace_trap)
jmp @SYMBOL_NAME(ret_from_exception)
SYMBOL_NAME_LABEL(sys_vfork)
SAVE_SWITCH_STACK
mov.l @SYMBOL_NAME(sw_usp),er6
mov.l @(8:16,er6),er6
mov.l sp,er0
add.l #SWITCH_STACK_SIZE,er0
jsr @SYMBOL_NAME(h8300_vfork)
mov.l @SYMBOL_NAME(_current_task),er5
mov.l er6,@((TASK_THREAD+THREAD_VFORK):16,er5)
RESTORE_SWITCH_STACK
rts
SYMBOL_NAME_LABEL(syscall_trampoline)
SAVE_SWITCH_STACK
mov.l er0,er6
mov.l sp,er0
add.l #SWITCH_STACK_SIZE,er0
jsr @er6
RESTORE_SWITCH_STACK
rts
jmp @er6
.section .bss
SYMBOL_NAME_LABEL(sw_ksp)
......
......@@ -6,7 +6,8 @@
# unless it's something special (ie not a .c file).
#
obj-y := timer.o crt0_$(MODEL).o
obj-y := timer.o
extra-y = crt0_$(MODEL).o
clean:
rm -f *.[oa]
/*
* linux/arch/h8300/platform/h8300h/generic/crt0_ram.S
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup
* Target Archtecture: AE-3068 (aka. aki3068net)
* Memory Layout : RAM
*/
#define ASSEMBLY
#include <linux/config.h>
#include <asm/linkage.h>
#if !defined(CONFIG_BLKDEV_RESERVE)
#if defined(CONFIG_GDB_DEBUG)
#define RAMEND (__ramend - 0xc000)
#else
#define RAMEND __ramend
#endif
#else
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
#endif
.global SYMBOL_NAME(_start)
.global SYMBOL_NAME(command_line)
.global SYMBOL_NAME(_platform_gpio_table)
.global SYMBOL_NAME(_target_name)
.h8300h
.section .text
.file "crt0_ram.S"
/* CPU Reset entry */
SYMBOL_NAME_LABEL(_start)
mov.l #RAMEND,sp
ldc #0x80,ccr
/* Peripheral Setup */
#if defined(CONFIG_BLK_DEV_BLKMEM)
/* move romfs image */
jsr @__move_romfs
#endif
/* .bss clear */
mov.l #__sbss,er5
mov.l #__ebss,er4
sub.l er5,er4
shlr er4
shlr er4
sub.l er0,er0
1:
mov.l er0,@er5
adds #4,er5
dec.l #1,er4
bne 1b
/* copy kernel commandline */
mov.l #COMMAND_START,er5
mov.l #SYMBOL_NAME(command_line),er6
mov.w #512,r4
eepmov.w
/* uClinux kernel start */
ldc #0x90,ccr /* running kernel */
mov.l #SYMBOL_NAME(init_thread_union),sp
add.l #0x2000,sp
jsr @_start_kernel
_exit:
jmp _exit
rts
/* I/O port assign information */
__platform_gpio_table:
mov.l #gpio_table,er0
rts
gpio_table:
;; P1DDR
.byte 0x00,0x00
;; P2DDR
.byte 0x00,0x00
;; P3DDR
.byte 0x00,0x00
;; P4DDR
.byte 0x00,0x00
;; P5DDR
.byte 0x00,0x00
;; P6DDR
.byte 0x00,0x00
;; dummy
.byte 0x00,0x00
;; P8DDR
.byte 0x00,0x00
;; P9DDR
.byte 0x00,0x00
;; PADDR
.byte 0x00,0x00
;; PBDDR
.byte 0x00,0x00
__target_name:
.asciz "generic"
......@@ -3,7 +3,7 @@
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup for uClinux-2.4.x
* Platform depend startup
* Target Archtecture: generic
* Memory Layout : ROM
*/
......@@ -31,16 +31,16 @@ SYMBOL_NAME_LABEL(_start)
/* .bss clear */
mov.l #__sbss,er5
mov.l er5,er6
inc.l #1,er6
mov.l #__ebss,er4
sub.l er5,er4
sub.w r0,r0
mov.b r0l,@er5
shlr er4
shlr er4
sub.l er0,er0
1:
eepmov.w
dec.w #1,e4
bpl 1b
mov.l er0,@er5
adds #4,er5
dec.l #1,er4
bne 1b
/* copy .data */
#if !defined(CONFIG_H8300H_SIM)
......@@ -60,10 +60,9 @@ SYMBOL_NAME_LABEL(_start)
mov.w #512,r4
eepmov.w
/* uClinux kernel start */
/* linux kernel start */
ldc #0x90,ccr /* running kernel */
mov.l #SYMBOL_NAME(init_thread_union),sp
mov.l sp,@SYMBOL_NAME(_current_task)
add.l #0x2000,sp
jsr @_start_kernel
_exit:
......
/* AKI3068NET RAM */
/* Generic RAM */
OUTPUT_ARCH(h8300h)
ENTRY("__start")
MEMORY
{
ram : ORIGIN = 0x400000, LENGTH = 0xA0000
/* rdisk : ORIGIN = 0x4A0000, LENGTH = 0x70000 */
/* uram : ORIGIN = 0x510000, LENGTH = 0xF0000 */
uram : ORIGIN = 0x4A0000, LENGTH = 0x160000
ram : ORIGIN = 0x400000, LENGTH = 0x200000
eram : ORIGIN = 0x600000, LENGTH = 0
iram : ORIGIN = 0xffbf20, LENGTH = 0x4000
}
SECTIONS
{
.bootvec :
{
*(.bootvec)
} > ram
.text :
{
__stext = . ;
*(.text)
__etext = . ;
} > ram
.rodata :
{
___data_rom_start = ALIGN ( 4 ) ;
} > ram
.erom :
{
__erom = . ;
} > ram
.data :
{
__ramstart = . ;
__sdata = . ;
___data_start = . ;
*(.data)
__edata = . ;
edata = ALIGN( 0x10 ) ;
___data_end = ALIGN( 0x10 ) ;
} > ram
.bss :
{
__sbss = . ;
___bss_start = . ;
*(.bss)
*(COMMON)
__ebss = . ;
___bss_end = . ;
} > ram
/*
.rootimg :
{
__rootimage = . ;
} > rdisk
*/
.dummy1 :
{
end = ALIGN( 0x10 ) ;
__end = ALIGN( 0x10 ) ;
} > uram
.ram_vec : AT(___bss_end)
{
__ram_vector = . ;
} > iram
__ram_vector_image = LOADADDR(.ram_vec) ;
.dummy2 :
{
_COMMAND_START = . - 0x200 ;
__ramend = . ;
} > eram
}
OUTPUT_ARCH(h8300h)
ENTRY("__start")
/*INPUT(rootimage.o)*/
_jiffies = _jiffies_64 + 4;
MEMORY
{
vector : ORIGIN = 0x000000, LENGTH = 0x000100
rom : ORIGIN = 0x000100, LENGTH = 0x200000-0x000100
erom : ORIGIN = 0x200000, LENGTH = 1
ram : ORIGIN = 0x200000, LENGTH = 0x100000
eram : ORIGIN = 0x2fa000, LENGTH = 1
erom : ORIGIN = 0x200000, LENGTH = 0
ram : ORIGIN = 0x200000, LENGTH = 0x400000
eram : ORIGIN = 0x600000, LENGTH = 0
}
SECTIONS
{
.vectors :
{
__vector = . ;
*(.vectors*)
} > vector
.text :
{
*(.int_redirect)
__stext = . ;
*(.text)
. = ALIGN(0x4) ;
*(.exit.text)
*(.text.*)
. = ALIGN(0x4) ;
*(.exitcall.exit)
. = ALIGN(0x4) ;
*(.kstrtab)
. = ALIGN(0x4) ;
*(.rodata*)
. = ALIGN(16); /* Exception table */
___start___ex_table = .;
*(__ex_table)
___stop___ex_table = .;
___start___ksymtab = .; /* Kernel symbol table */
*(__ksymtab)
___stop___ksymtab = .;
. = ALIGN(0x4) ;
__etext = . ;
} > rom
.data : AT( ADDR(.text)+SIZEOF(.text))
{
__sdata = . ;
___data_start = . ;
. = ALIGN(0x2000) ;
*(.data.init_task)
. = ALIGN(0x4) ;
*(.data)
. = ALIGN(0x4) ;
*(.data.*)
. = ALIGN(0x4) ;
___init_begin = .;
*(.init.text)
*(.init.data)
. = ALIGN(0x4) ;
___setup_start = .;
*(.init.setup)
. = ALIGN(0x4) ;
___setup_end = .;
___start___param = .;
*(__param)
___stop___param = .;
___initcall_start = .;
*(.initcall1.init)
*(.initcall2.init)
*(.initcall3.init)
*(.initcall4.init)
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
___initcall_end = .;
___con_initcall_start = .;
*(.con_initcall.init)
___con_initcall_end = .;
SECURITY_INIT
. = ALIGN(4);
___initramfs_start = .;
*(.init.ramfs)
___initramfs_end = .;
. = ALIGN(0x4) ;
___init_end = .;
__edata = . ;
} > ram
__begin_data = LOADADDR(.data) ;
.blkimg : AT( LOADADDR(.data) + SIZEOF(.data))
{
__blkimg = . ;
*(.rootimg*)
} > rom
.erom :
{
__erom = . ;
} > erom
.bss :
{
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss)
. = ALIGN(0x4) ;
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
__ramstart = .;
} > ram
.dummy :
{
COMMAND_START = . - 0x200 ;
__ramend = . ;
} > eram
}
/*
* linux/arch/h8300/platform/h8300h/generic/timer.c
*
* Yoshinori Sato <qzb04471@nifty.ne.jp>
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend Timer Handler
*
......@@ -22,27 +22,31 @@
#include <linux/timex.h>
extern int request_irq_boot(unsigned int,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
#define TMR8CMA2 0x00ffff94
#define TMR8TCSR2 0x00ffff92
#define TMR8TCNT2 0x00ffff90
#include <asm/regs306x.h>
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
{
outb(H8300_TIMER_COUNT_DATA,TMR8CMA2);
outb(0x00,TMR8TCSR2);
request_irq(40,timer_int,0,"timer",0);
request_irq_boot(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,TMR8TCNT2);
return 0;
}
void platform_timer_eoi(void)
{
__asm__("bclr #6,@0xffff92:8");
*(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
}
#endif
#if defined(H8_3002) || defined(CONFIG_H83048)
/* FIXME! */
#define TSTR 0x00ffff60
#define TSNC 0x00ffff61
#define TMDR 0x00ffff62
......@@ -63,7 +67,7 @@ int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
*(unsigned short *)TCNT=0;
outb(0x23,TCR);
outb(0x00,TIOR);
request_irq(26,timer_int,0,"timer",0);
request_timer_irq(26,timer_int,0,"timer",0);
outb(inb(TIER) | 0x01,TIER);
outb(inb(TSNC) & ~0x01,TSNC);
outb(inb(TMDR) & ~0x01,TMDR);
......
......@@ -6,8 +6,7 @@
# unless it's something special (ie not a .c file).
#
all: $(BOARD).o
O_TARGET := $(BOARD).o
extra-y := crt0_ram.o
obj-y := timer.o
timer.o: timer.c
......
......@@ -3,7 +3,7 @@
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup for uClinux-2.4.x
* Platform depend startup
* Target Archtecture: H8MAX
* Memory Layout : RAM
*/
......@@ -13,6 +13,16 @@
#include <linux/config.h>
#include <asm/linkage.h>
#if !defined(CONFIG_BLKDEV_RESERVE)
#if defined(CONFIG_GDB_DEBUG)
#define RAMEND (__ramend - 0xc000)
#else
#define RAMEND __ramend
#endif
#else
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
#endif
.global SYMBOL_NAME(_start)
.global SYMBOL_NAME(command_line)
.global SYMBOL_NAME(_platform_gpio_table)
......@@ -25,23 +35,28 @@
/* CPU Reset entry */
SYMBOL_NAME_LABEL(_start)
mov.l #__ramend,sp
mov.l #RAMEND,sp
ldc #0x80,ccr
/* Peripheral Setup */
#if defined(CONFIG_BLK_DEV_BLKMEM)
/* move romfs image */
jsr @__move_romfs
#endif
/* .bss clear */
mov.l #__sbss,er5
mov.l er5,er6
inc.l #1,er6
mov.l #__ebss,er4
sub.l er5,er4
sub.w r0,r0
mov.b r0l,@er5
shlr er4
shlr er4
sub.l er0,er0
1:
eepmov.w
dec.w #1,e4
bpl 1b
mov.l er0,@er5
adds #4,er5
dec.l #1,er4
bne 1b
/* copy kernel commandline */
mov.l #COMMAND_START,er5
......@@ -49,22 +64,9 @@ SYMBOL_NAME_LABEL(_start)
mov.w #512,r4
eepmov.w
/* RAM Interrupt Vector Table Setup */
#if defined(CONFIG_GDB_DEBUG)
mov.l @SYMBOL_NAME(interrupt_redirect_table)+11*4,er0
#endif
mov.l #SYMBOL_NAME(_vector_lma),er5
mov.l #SYMBOL_NAME(interrupt_redirect_table),er6
mov.w #0x100,r4
eepmov.w
#if defined(CONFIG_GDB_DEBUG)
mov.l er0,@SYMBOL_NAME(interrupt_redirect_table)+11*4
#endif
/* uClinux kernel start */
ldc #0x90,ccr /* running kernel */
mov.l #SYMBOL_NAME(init_task_union),sp
mov.l sp,@SYMBOL_NAME(_current_task)
mov.l #SYMBOL_NAME(init_thread_union),sp
add.l #0x2000,sp
jsr @_start_kernel
_exit:
......
......@@ -5,86 +5,7 @@ ENTRY("__start")
MEMORY
{
ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000-0xc000
disk : ORIGIN = 0x600000-0xc000, LENGTH = 0xc000
ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000
eram : ORIGIN = 0x600000, LENGTH = 0
iram : ORIGIN = 0xfffd20, LENGTH = 0x100
}
SECTIONS
{
.bootvec :
{
*(.bootvec)
} > ram
.text :
{
__stext = . ;
*(.text)
. = ALIGN(0x4) ;
*(.text.*)
. = ALIGN(0x4) ;
*(.kstrtab)
. = ALIGN(0x4) ;
*(.rodata*)
. = ALIGN(16); /* Exception table */
___start___ex_table = .;
*(__ex_table)
___stop___ex_table = .;
___start___ksymtab = .; /* Kernel symbol table */
*(__ksymtab)
___stop___ksymtab = .;
. = ALIGN(0x4) ;
__etext = . ;
} > ram
.data :
{
__sdata = . ;
___data_start = . ;
*(.data)
*(.data.*)
*(.exitcall.exit)
. = ALIGN(0x2000) ;
*(.data.init_task)
. = ALIGN(0x2000) ;
___init_begin = .;
*(.text.init)
*(.data.init)
. = ALIGN(16);
___setup_start = .;
*(.setup.init)
___setup_end = .;
___initcall_start = .;
*(.initcall.init)
. = ALIGN(4) ;
___initcall_end = .;
___init_end = .;
__edata = . ;
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss)
. = ALIGN(0x4) ;
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
__ramstart = .;
} > ram
.blkimg :
{
__ramend = . ;
__blkimg = . ;
} > disk
.ram_vec : AT(ADDR(.data) + SIZEOF(.data))
{
*(.int_redirect)
} > iram
__vector_lma = LOADADDR(.ram_vec);
.dummy2 :
{
COMMAND_START = . - 0x200 ;
} > eram
}
......@@ -14,29 +14,32 @@
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/timex.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/regs306x.h>
#include <linux/timex.h>
#define TMR8CMA2 0x00ffff94
#define TMR8TCSR2 0x00ffff92
#define TMR8TCNT2 0x00ffff90
#define CMFA 6
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
extern int request_irq_boot(unsigned int,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
{
outb(CONFIG_CLK_FREQ*10/8192,TMR8CMA2);
outb(0x00,TMR8TCSR2);
request_irq(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,TMR8TCNT2);
outb(H8300_TIMER_COUNT_DATA,TCORA2);
outb(0x00,_8TCSR2);
request_irq_boot(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,_8TCR2);
}
void platform_timer_eoi(void)
{
*(unsigned char *)TMR8TCSR2 &= ~(1 << CMFA);
*(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
}
void platform_gettod(int *year, int *mon, int *day, int *hour,
......@@ -44,3 +47,4 @@ void platform_gettod(int *year, int *mon, int *day, int *hour,
{
*year = *mon = *day = *hour = *min = *sec = 0;
}
......@@ -18,6 +18,9 @@
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/bootmem.h>
#include <asm/system.h>
#include <asm/irq.h>
......@@ -27,8 +30,7 @@
#include <asm/gpio.h>
#include <asm/hardirq.h>
#include <asm/regs306x.h>
#define INTERNAL_IRQS (64)
#include <asm/errno.h>
#define EXT_IRQ0 12
#define EXT_IRQ1 13
......@@ -39,75 +41,144 @@
#define EXT_IRQ6 18
#define EXT_IRQ7 19
#define WDT_IRQ 20
/*
* This structure has only 4 elements for speed reasons
*/
typedef struct irq_handler {
irqreturn_t (*handler)(int, void *, struct pt_regs *);
int flags;
int count;
void *dev_id;
const char *devname;
} irq_handler_t;
/* table for system interrupt handlers */
static irq_handler_t irq_list[SYS_IRQS];
irq_handler_t *irq_list[NR_IRQS];
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
extern unsigned long *interrupt_redirect_table;
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void bad_interrupt(void);
static inline unsigned long *get_vector_address(void)
{
unsigned long *rom_vector = (unsigned long *)0x000000;
unsigned long base,tmp;
int vec_no;
base = rom_vector[EXT_IRQ0];
/* check romvector format */
for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ5; vec_no++) {
if ((base+(vec_no - EXT_IRQ0)*4) != rom_vector[vec_no])
return NULL;
}
/* irq node variables for the 32 (potential) on chip sources */
/*static irq_node_t *int_irq_list[INTERNAL_IRQS];*/
static int int_irq_count[INTERNAL_IRQS];
/* ramvector base address */
base -= EXT_IRQ0*4;
#if 0
static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
{
num_spurious += 1;
/* writerble check */
tmp = ~(*(volatile unsigned long *)base);
(*(volatile unsigned long *)base) = tmp;
if ((*(volatile unsigned long *)base) != tmp)
return NULL;
return (unsigned long *)base;
}
#endif
void init_IRQ(void)
void __init init_IRQ(void)
{
#if defined(CONFIG_RAMKERNEL)
int i;
unsigned long *ramvec,*ramvec_p;
unsigned long break_vec;
for (i = 0; i < SYS_IRQS; i++) {
irq_list[i].handler = NULL;
irq_list[i].flags = 0;
irq_list[i].devname = NULL;
irq_list[i].dev_id = NULL;
#if defined(CONFIG_GDB_DEBUG)
break_vec = ramvec[TRAP3_VEC];
#else
break_vec = VECTOR(trace_break);
#endif
ramvec = get_vector_address();
if (ramvec == NULL)
panic("interrupt vector serup failed.");
else
printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec);
for (ramvec_p = ramvec, i = 0; i < NR_IRQS; i++)
*ramvec_p++ = REDIRECT(interrupt_entry);
ramvec[TRAP0_VEC] = VECTOR(system_call);
ramvec[TRAP3_VEC] = break_vec;
interrupt_redirect_table = ramvec;
#ifdef DUMP_VECTOR
ramvec_p = interrupt_redirect_table;
for (i = 0; i < NR_IRQS; i++) {
if ((i % 8) == 0)
printk("\n%p: ",ramvec_p);
printk("%p ",*ramvec_p);
ramvec_p++;
}
printk("\n");
#endif
#endif
}
void __init request_irq_boot(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
irq_handler_t *irq_handle;
irq_handle = alloc_bootmem(sizeof(irq_handler_t));
irq_handle->handler = handler;
irq_handle->flags = flags;
irq_handle->count = 0;
irq_handle->dev_id = dev_id;
irq_handle->devname = devname;
irq_list[irq] = irq_handle;
}
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
irq_handler_t *irq_handle;
if (irq < 0 || irq >= NR_IRQS) {
printk("Incorrect IRQ %d from %s\n", irq, devname);
return -EINVAL;
}
if (irq_list[irq])
return -EBUSY;
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ3) {
if (H8300_GPIO_RESERVE(H8300_GPIO_P8, 1 << (irq - EXT_IRQ0)) == 0)
return 1;
return -EBUSY;
H8300_GPIO_DDR(H8300_GPIO_P8, (irq - EXT_IRQ0), 0);
}
if (irq >= EXT_IRQ4 && irq <= EXT_IRQ5) {
if (H8300_GPIO_RESERVE(H8300_GPIO_P9, 1 << (irq - EXT_IRQ0)) == 0)
return 1;
return -EBUSY;
H8300_GPIO_DDR(H8300_GPIO_P9, (irq - EXT_IRQ0), 0);
}
irq_list[irq].handler = handler;
irq_list[irq].flags = flags;
irq_list[irq].devname = devname;
irq_list[irq].dev_id = dev_id;
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5)
*(volatile unsigned char *)IER |= 1 << (irq - EXT_IRQ0);
irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
if (irq_handle == NULL)
return -ENOMEM;
irq_handle->handler = handler;
irq_handle->flags = flags;
irq_handle->count = 0;
irq_handle->dev_id = dev_id;
irq_handle->devname = devname;
irq_list[irq] = irq_handle;
return 0;
}
void free_irq(unsigned int irq, void *dev_id)
{
if (irq_list[irq].dev_id != dev_id)
printk("%s: Removing probably wrong IRQ %d from %s\n",
__FUNCTION__, irq, irq_list[irq].devname);
if (irq >= NR_IRQS) {
return;
}
if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id)
printk("Removing probably wrong IRQ %d from %s\n",
irq, irq_list[irq]->devname);
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5)
*(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0));
irq_list[irq].handler = NULL;
irq_list[irq].flags = 0;
irq_list[irq].dev_id = NULL;
irq_list[irq].devname = NULL;
kfree(irq_list[irq]);
irq_list[irq] = NULL;
}
/*
......@@ -123,115 +194,36 @@ int probe_irq_off (unsigned long irqs)
return 0;
}
struct int_regs {
unsigned long ier;
unsigned long isr;
unsigned char mask;
};
#define REGS_DEF(ier,isr,mask) {ier,isr,mask}
const struct int_regs interrupt_registers[]= {
REGS_DEF(IER,ISR,0x01),
REGS_DEF(IER,ISR,0x02),
REGS_DEF(IER,ISR,0x04),
REGS_DEF(IER,ISR,0x08),
REGS_DEF(IER,ISR,0x10),
REGS_DEF(IER,ISR,0x20),
REGS_DEF(IER,ISR,0x40),
REGS_DEF(IER,ISR,0x80),
REGS_DEF(TCSR,TCSR,0x20),
REGS_DEF(RTMCSR,RTMCSR,0x40),
REGS_DEF(0,0,0),
REGS_DEF(ADCSR,ADCSR,0x40),
REGS_DEF(TISRA,TISRA,0x10),
REGS_DEF(TISRB,TISRB,0x10),
REGS_DEF(TISRC,TISRC,0x10),
REGS_DEF(0,0,0),
REGS_DEF(TISRA,TISRA,0x20),
REGS_DEF(TISRB,TISRB,0x20),
REGS_DEF(TISRC,TISRC,0x20),
REGS_DEF(0,0,0),
REGS_DEF(TISRA,TISRA,0x40),
REGS_DEF(TISRB,TISRB,0x40),
REGS_DEF(TISRC,TISRC,0x40),
REGS_DEF(0,0,0),
REGS_DEF(_8TCR0,_8TCSR0,0x40),
REGS_DEF(_8TCR0,_8TCSR0,0x80),
REGS_DEF(_8TCR1,_8TCSR1,0xC0),
REGS_DEF(_8TCR0,_8TCSR0,0x20),
REGS_DEF(_8TCR2,_8TCSR2,0x40),
REGS_DEF(_8TCR2,_8TCSR2,0x80),
REGS_DEF(_8TCR3,_8TCSR3,0xC0),
REGS_DEF(_8TCR2,_8TCSR2,0x20),
REGS_DEF(DTCR0A,DTCR0A,0x0),
REGS_DEF(DTCR0B,DTCR0B,0x0),
REGS_DEF(DTCR1A,DTCR1A,0x0),
REGS_DEF(DTCR1B,DTCR1B,0x0),
REGS_DEF(0,0,0),
REGS_DEF(0,0,0),
REGS_DEF(0,0,0),
REGS_DEF(0,0,0),
REGS_DEF(SCR0,SSR0,0x40),
REGS_DEF(SCR0,SSR0,0x40),
REGS_DEF(SCR0,SSR0,0x80),
REGS_DEF(SCR0,SSR0,0x04),
REGS_DEF(SCR1,SSR1,0x40),
REGS_DEF(SCR1,SSR1,0x40),
REGS_DEF(SCR1,SSR1,0x80),
REGS_DEF(SCR1,SSR1,0x04),
REGS_DEF(SCR2,SSR2,0x40),
REGS_DEF(SCR2,SSR2,0x40),
REGS_DEF(SCR2,SSR2,0x80),
REGS_DEF(SCR2,SSR2,0x04)
};
void enable_irq(unsigned int irq)
{
unsigned char ier;
const struct int_regs *regs=&interrupt_registers[irq - 12];
if (irq == WDT_IRQ) {
ier = ctrl_inb(TCSR);
ier |= 0x20;
ctrl_outb((0xa500 | ier),TCSR);
} else {
if ((irq > 12) && regs->ier) {
ier = ctrl_inb(regs->ier);
ier |= regs->mask;
ctrl_outb(ier, regs->ier);
} else
panic("Unknown interrupt vector");
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) {
*(volatile unsigned char *)IER |= (1 << (irq - EXT_IRQ0));
*(volatile unsigned char *)ISR &= ~(1 << (irq - EXT_IRQ0));
}
}
void disable_irq(unsigned int irq)
{
unsigned char ier;
const struct int_regs *regs=&interrupt_registers[irq - 12];
if (irq == WDT_IRQ) {
ier = ctrl_inb(TCSR);
ier &= ~0x20;
ctrl_outb((0xa500 | ier),TCSR);
} else {
if ((irq > 12) && regs->ier) {
ier = ctrl_inb(regs->ier);
ier &= ~(regs->mask);
ctrl_outb(ier, regs->ier);
} else
panic("Unknown interrupt vector");
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) {
*(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0));
}
}
asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
asmlinkage void process_int(int vec, struct pt_regs *fp)
{
irq_enter();
if (irq_list[vec].handler) {
irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
int_irq_count[vec]++;
} else
panic("No interrupt handler for %ld\n", vec);
if (vec >= EXT_IRQ0 && vec <= EXT_IRQ5)
*(volatile unsigned char *)ISR &= ~(1 << (vec - EXT_IRQ0));
if (vec < NR_IRQS) {
if (irq_list[vec]) {
irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp);
irq_list[vec]->count++;
if (irq_list[vec]->flags & SA_SAMPLE_RANDOM)
add_interrupt_randomness(vec);
}
} else {
BUG();
}
irq_exit();
}
......@@ -240,8 +232,10 @@ int show_interrupts(struct seq_file *p, void *v)
int i;
for (i = 0; i < NR_IRQS; i++) {
seq_printf(p, "%3d: %10u ",i,int_irq_count[i]);
seq_printf(p, "%s\n", irq_list[i].devname);
if (irq_list[i]) {
seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
seq_printf(p, "%s\n", irq_list[i]->devname);
}
}
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment