SH4 support. my target is HITACHI PERSONA HPW650PA
This commit is contained in:
parent
dca6104509
commit
4dff96d2d9
|
@ -0,0 +1,82 @@
|
|||
# $NetBSD: HPW650PA,v 1.1 2002/02/11 17:32:35 uch Exp $
|
||||
#
|
||||
# HITACHI PERSONA HPW650PA
|
||||
#
|
||||
|
||||
include "arch/hpcsh/conf/std.hpcsh"
|
||||
|
||||
maxusers 32 # estimated number of users
|
||||
|
||||
options KLOADER_KERNEL_PATH="\"/netbsd\""
|
||||
options KLOADER_DEBUG
|
||||
|
||||
options SH7750
|
||||
options SH4
|
||||
|
||||
options INTERRUPT_MONITOR
|
||||
|
||||
options DDB # in-kernel debugger
|
||||
options DIAGNOSTIC # extra kernel debugging checks
|
||||
options DEBUG # extra kernel debugging support
|
||||
options KTRACE # system call tracing support
|
||||
options MSGBUFSIZE=65534
|
||||
|
||||
options PIPE_SOCKETPAIR # smaller, but slower pipe(2)
|
||||
|
||||
# Executable format options
|
||||
options EXEC_COFF # 32-bit COFF executables
|
||||
options EXEC_ELF32 # 32-bit ELF executables
|
||||
|
||||
# File systems
|
||||
file-system FFS # UFS
|
||||
file-system MSDOSFS # MS-DOS file system
|
||||
file-system NFS # Sun NFS-compatible filesystem client
|
||||
|
||||
# Networking options
|
||||
options INET # IP + ICMP + TCP + UDP
|
||||
options INET6 # IPV6
|
||||
options NFS_BOOT_DHCP
|
||||
|
||||
# Kernel root file system and dump configuration.
|
||||
config netbsd root on ? type ?
|
||||
|
||||
options WSEMUL_VT100
|
||||
options WSDISPLAY_DEFAULTSCREENS=1
|
||||
options FONT_VT220L8x10
|
||||
options WS_KERNEL_FG=WSCOL_BROWN
|
||||
options WS_KERNEL_BG=WSCOL_BLUE
|
||||
|
||||
#
|
||||
# Device configuration
|
||||
#
|
||||
mainbus0 at root
|
||||
|
||||
bivideo* at mainbus0
|
||||
hpcfb* at bivideo?
|
||||
wsdisplay* at hpcfb?
|
||||
|
||||
shb0 at mainbus?
|
||||
|
||||
hd64465if* at shb0 irq 11
|
||||
com* at hd64465if?
|
||||
hd64465pcmcia* at hd64465if?
|
||||
|
||||
# PCMCIA bus support
|
||||
pcmcia* at hd64465pcmcia? controller ? socket ?
|
||||
|
||||
# PCMCIA network interfaces
|
||||
ne* at pcmcia? function ? # NE2000-compatible Ethernet
|
||||
ukphy* at mii? phy ? # generic unknown PHYs
|
||||
|
||||
# PCMCIA IDE disk
|
||||
wdc* at pcmcia? function ?
|
||||
wd* at wdc? channel ? drive ? flags 0x0000
|
||||
|
||||
# Pseudo-Devices
|
||||
pseudo-device biconsdev 1 # build-in console device
|
||||
pseudo-device pty # pseudo-terminals
|
||||
|
||||
pseudo-device bpfilter 1 # Berkeley packet filter
|
||||
pseudo-device loop # network loopback
|
||||
pseudo-device gif 1 # IPv[46] over IPv[46] tunnel (RFC1933)
|
||||
pseudo-device rnd # /dev/random and in-kernel generator
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.hpcsh,v 1.16 2002/01/29 18:44:25 uch Exp $
|
||||
# $NetBSD: files.hpcsh,v 1.17 2002/02/11 17:32:35 uch Exp $
|
||||
#
|
||||
maxpartitions 8
|
||||
|
||||
|
@ -15,6 +15,7 @@ file arch/hpcsh/hpcsh/clock.c
|
|||
file arch/hpcsh/hpcsh/console.c
|
||||
file arch/hpcsh/hpcsh/autoconf.c
|
||||
file arch/hpcsh/hpcsh/bus_space.c
|
||||
#file arch/hpcsh/hpcsh/bus_dma.c
|
||||
file arch/hpcsh/hpcsh/procfs_machdep.c procfs
|
||||
|
||||
file arch/hpc/hpc/kloader.c
|
||||
|
@ -93,11 +94,25 @@ attach hd64461video at hd64461if
|
|||
file arch/hpcsh/dev/hd64461/hd64461video.c hd64461video needs-flag
|
||||
file dev/hpc/video_subr.c hd64461video
|
||||
|
||||
# network devices MII bus
|
||||
include "dev/mii/files.mii"
|
||||
#
|
||||
# HD64465
|
||||
#
|
||||
define hd64465if {}
|
||||
device hd64465if: hd64465if
|
||||
attach hd64465if at shb
|
||||
file arch/hpcsh/dev/hd64465/hd64465.c hd64465if
|
||||
|
||||
#
|
||||
# Workstation Console
|
||||
#
|
||||
attach com at hd64465if with hd64465uart
|
||||
file arch/hpcsh/dev/hd64465/hd64465uart.c hd64465uart
|
||||
|
||||
device hd64465pcmcia: pcmciabus
|
||||
attach hd64465pcmcia at hd64465if
|
||||
file arch/hpcsh/dev/hd64465/hd64465pcmcia.c hd64465pcmcia
|
||||
|
||||
#attach ohci at hd64465if with hd64465ohci
|
||||
#file arch/hpcsh/dev/hd64465/hd64465ohci.c hd64465ohci
|
||||
|
||||
include "dev/mii/files.mii"
|
||||
include "dev/usb/files.usb"
|
||||
include "dev/wscons/files.wscons"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clock.c,v 1.4 2002/02/01 17:52:55 uch Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.5 2002/02/11 17:32:35 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -44,6 +44,7 @@
|
|||
#include <sh3/tmureg.h>
|
||||
|
||||
#include <machine/shbvar.h>
|
||||
#include <machine/debug.h>
|
||||
|
||||
#include <hpcsh/hpcsh/clockvar.h>
|
||||
|
||||
|
@ -139,6 +140,9 @@ clock_init()
|
|||
DELAY_LOOP(10000000);
|
||||
t0 = TMU_ELAPSED(0);
|
||||
__cpuclock = (100000000 / t0) * RTC_CLOCK;
|
||||
#ifdef SH4
|
||||
__cpuclock >>= 1; /* two-issue */
|
||||
#endif
|
||||
__cnt_delay = (RTC_CLOCK * 10) / t0;
|
||||
|
||||
/*
|
||||
|
@ -242,6 +246,7 @@ clockintr(void *arg) /* trap frame */
|
|||
/* clear underflow status */
|
||||
SHREG_TCR1 &= ~TCR_UNF;
|
||||
|
||||
__dbg_heart_beat(HEART_BEAT_WHITE);
|
||||
hardclock(arg);
|
||||
|
||||
return (1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: console.c,v 1.6 2002/01/27 05:15:37 uch Exp $ */
|
||||
/* $NetBSD: console.c,v 1.7 2002/02/11 17:32:35 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -36,14 +36,18 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opt_kgdb.h"
|
||||
|
||||
#include "biconsdev.h"
|
||||
#include "hpcfb.h"
|
||||
#include "pfckbd.h"
|
||||
#include "sci.h"
|
||||
#include "scif.h"
|
||||
#include "com.h"
|
||||
#include "hd64461video.h"
|
||||
|
||||
#include "wskbd.h"
|
||||
#include "pfckbd.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -51,6 +55,12 @@
|
|||
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
#if !defined(NBICONSDEV) || !defined(NHPCFB) || !defined(NPFCKBD) || \
|
||||
!defined(NHD64461VIDEO) || !defined(NSCI) || !defined(NSCIF) || \
|
||||
!defined(NCOM)
|
||||
#error
|
||||
#endif
|
||||
|
||||
#if NBICONSDEV > 0
|
||||
#include <dev/hpc/biconsvar.h>
|
||||
#include <dev/hpc/bicons.h>
|
||||
|
@ -61,6 +71,7 @@
|
|||
#include <dev/rasops/rasops.h>
|
||||
#include <dev/hpc/hpcfbvar.h>
|
||||
#endif
|
||||
|
||||
#if NPFCKBD > 0
|
||||
#include <hpcsh/dev/pfckbdvar.h>
|
||||
#endif
|
||||
|
@ -82,6 +93,7 @@ cons_decl(bicons);
|
|||
#if NHD64461VIDEO > 0
|
||||
cons_decl(hd64461video_);
|
||||
#if NWSKBD > 0
|
||||
#include <dev/wscons/wskbdvar.h>
|
||||
#define hd64461video_cngetc wskbd_cngetc
|
||||
#else
|
||||
int
|
||||
|
@ -110,19 +122,27 @@ struct consdev constab[] = {
|
|||
#if NSCIF > 0
|
||||
cons_init(scif),
|
||||
#endif
|
||||
#if NHD64461IF > 0 && NCOM > 0
|
||||
#if NCOM > 0
|
||||
cons_init(com),
|
||||
#endif
|
||||
{ 0 } /* terminator */
|
||||
};
|
||||
#define CN_ENABLE(x) set_console(x ## cnputc, x ## cnprobe)
|
||||
|
||||
#ifdef KGDB
|
||||
#ifndef KGDB_DEVNAME
|
||||
#define KGDB_DEVNAME "nodev"
|
||||
#endif
|
||||
const char kgdb_devname[] = KGDB_DEVNAME;
|
||||
#endif
|
||||
static int initialized;
|
||||
static int attach_kbd = 1;
|
||||
static int attach_kbd __attribute__((__unused__)) = 1;
|
||||
static void set_console(void (*)(dev_t, int), void (*)(struct consdev *));
|
||||
static void disable_console(void);
|
||||
static void cn_nonprobe(struct consdev *);
|
||||
#if NBICONSDEV > 0
|
||||
static void enable_bicons(void);
|
||||
#endif
|
||||
|
||||
void
|
||||
consinit()
|
||||
|
@ -155,20 +175,24 @@ consinit()
|
|||
CN_ENABLE(scif);
|
||||
#endif
|
||||
break;
|
||||
case BI_CNUSE_HD64465COM:
|
||||
/* FALLTHROUGH */
|
||||
case BI_CNUSE_HD64461COM:
|
||||
#if NHD64461IF > 0 && NCOM > 0
|
||||
#if NCOM > 0
|
||||
CN_ENABLE(com);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#if NBICONSDEV > 0
|
||||
if (!initialized) /* use builtin console instead */
|
||||
if (!initialized) { /* use builtin console instead */
|
||||
enable_bicons();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (initialized)
|
||||
if (initialized) {
|
||||
cninit();
|
||||
}
|
||||
|
||||
#if NPFCKBD > 0
|
||||
if (attach_kbd)
|
||||
|
@ -208,6 +232,7 @@ disable_console()
|
|||
static void
|
||||
cn_nonprobe(struct consdev *cp)
|
||||
{
|
||||
|
||||
cp->cn_pri = CN_DEAD;
|
||||
}
|
||||
|
||||
|
@ -215,9 +240,10 @@ cn_nonprobe(struct consdev *cp)
|
|||
static void
|
||||
enable_bicons()
|
||||
{
|
||||
|
||||
bootinfo->bi_cnuse = BI_CNUSE_BUILTIN;
|
||||
bicons_set_priority(CN_INTERNAL);
|
||||
CN_ENABLE(bicons);
|
||||
attach_kbd = 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* NBICONSDEV > 0 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kloader_machdep.c,v 1.2 2002/02/07 17:05:22 uch Exp $ */
|
||||
/* $NetBSD: kloader_machdep.c,v 1.3 2002/02/11 17:32:35 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -37,56 +37,82 @@
|
|||
#include <sys/systm.h>
|
||||
|
||||
#include <sh3/mmureg.h>
|
||||
#include <sh3/cache.h>
|
||||
#include <sh3/cache_sh3.h>
|
||||
#include <sh3/cache_sh4.h>
|
||||
|
||||
#include <machine/kloader.h>
|
||||
|
||||
#define SH3_CCA 0xf0000000
|
||||
|
||||
#define SH7709A_CACHE_LINESZ 16
|
||||
#define SH7709A_CACHE_ENTRY 256
|
||||
#define SH7709A_CACHE_WAY 4
|
||||
#define SH7709A_CACHE_SIZE \
|
||||
(SH7709A_CACHE_LINESZ * SH7709A_CACHE_ENTRY * SH7709A_CACHE_WAY)
|
||||
|
||||
#define SH7709A_CACHE_ENTRY_SHIFT 4
|
||||
#define SH7709A_CACHE_ENTRY_MASK 0x00000ff0
|
||||
#define SH7709A_CACHE_WAY_SHIFT 12
|
||||
#define SH7709A_CACHE_WAY_MASK 0x00003000
|
||||
|
||||
#define _SH7709A_CACHE_FLUSH() \
|
||||
do { \
|
||||
u_int32_t __e, __w, __wa, __a; \
|
||||
/*
|
||||
* 2nd-bootloader. Make sure that PIC and its size is lower than page size.
|
||||
*/
|
||||
#define KLOADER_SH_BOOT(cpu, product) \
|
||||
void \
|
||||
kloader_sh ## cpu ## _boot(struct kloader_bootinfo *kbi, \
|
||||
struct kloader_page_tag *p) \
|
||||
{ \
|
||||
int tmp; \
|
||||
\
|
||||
for (__w = 0; __w < SH7709A_CACHE_WAY; __w++) { \
|
||||
__wa = SH3_CCA | __w << SH7709A_CACHE_WAY_SHIFT; \
|
||||
for (__e = 0; __e < SH7709A_CACHE_ENTRY; __e++) { \
|
||||
__a = __wa |(__e << SH7709A_CACHE_ENTRY_SHIFT); \
|
||||
(*(__volatile__ u_int32_t *)__a) &= ~0x3; \
|
||||
} \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
/* Disable interrupt. block exception. */ \
|
||||
__asm__ __volatile__( \
|
||||
"stc sr, %1;" \
|
||||
"or %0, %1;" \
|
||||
"ldc %1, sr" : : "r"(0x500000f0), "r"(tmp)); \
|
||||
\
|
||||
/* Now I run on P1, TLB flush. and disable. */ \
|
||||
SHREG_MMUCR = MMUCR_TF; \
|
||||
\
|
||||
do { \
|
||||
u_int32_t *dst =(u_int32_t *)p->dst; \
|
||||
u_int32_t *src =(u_int32_t *)p->src; \
|
||||
u_int32_t sz = p->sz / sizeof (int); \
|
||||
while (sz--) \
|
||||
*dst++ = *src++; \
|
||||
} while ((p = (struct kloader_page_tag *)p->next) != 0); \
|
||||
\
|
||||
SH ## product ## _CACHE_FLUSH(); \
|
||||
\
|
||||
/* jump to kernel entry. */ \
|
||||
__asm__ __volatile__( \
|
||||
"mov %0, r4;" \
|
||||
"mov %1, r5;" \
|
||||
"jmp @%3;" \
|
||||
"mov %2, r6;" \
|
||||
: : \
|
||||
"r"(kbi->argc), \
|
||||
"r"(kbi->argv), \
|
||||
"r"(&kbi->bootinfo), \
|
||||
"r"(kbi->entry)); \
|
||||
/* NOTREACHED */ \
|
||||
}
|
||||
|
||||
void kloader_sh3_jump(kloader_bootfunc_t *, vaddr_t,
|
||||
void kloader_sh_jump(kloader_bootfunc_t *, vaddr_t,
|
||||
struct kloader_bootinfo *, struct kloader_page_tag *);
|
||||
kloader_bootfunc_t kloader_sh3_boot;
|
||||
kloader_bootfunc_t kloader_sh4_boot;
|
||||
|
||||
struct kloader_ops kloader_sh3_ops = {
|
||||
.jump = kloader_sh3_jump,
|
||||
.boot = kloader_sh3_boot
|
||||
struct kloader_ops kloader_sh_ops = {
|
||||
.jump = kloader_sh_jump,
|
||||
.boot = 0
|
||||
};
|
||||
|
||||
void
|
||||
kloader_reboot_setup(const char *filename)
|
||||
{
|
||||
|
||||
__kloader_reboot_setup(&kloader_sh3_ops, filename);
|
||||
#ifdef SH4
|
||||
kloader_sh_ops.boot = kloader_sh4_boot;
|
||||
#else
|
||||
kloader_sh_ops.boot = kloader_sh3_boot;
|
||||
#endif
|
||||
__kloader_reboot_setup(&kloader_sh_ops, filename);
|
||||
}
|
||||
|
||||
void
|
||||
kloader_sh3_jump(kloader_bootfunc_t func, vaddr_t sp,
|
||||
kloader_sh_jump(kloader_bootfunc_t func, vaddr_t sp,
|
||||
struct kloader_bootinfo *info, struct kloader_page_tag *tag)
|
||||
{
|
||||
|
||||
_SH7709A_CACHE_FLUSH();
|
||||
sh_icache_sync_all(); /* also flush d-cache */
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mov %0, r4;"
|
||||
|
@ -97,43 +123,5 @@ kloader_sh3_jump(kloader_bootfunc_t func, vaddr_t sp,
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* 2nd-bootloader. Make sure that PIC and its size is lower than page size.
|
||||
*/
|
||||
void
|
||||
kloader_sh3_boot(struct kloader_bootinfo *kbi, struct kloader_page_tag *p)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/* Disable interrupt. block exception.(TLB exception don't occur) */
|
||||
__asm__ __volatile__(
|
||||
"stc sr, %1;"
|
||||
"or %0, %1;"
|
||||
"ldc %1, sr" : : "r"(0x500000f0), "r"(tmp));
|
||||
|
||||
/* Now I run on P1, TLB flush. and disable. */
|
||||
SHREG_MMUCR = MMUCR_TF;
|
||||
|
||||
do {
|
||||
u_int32_t *dst =(u_int32_t *)p->dst;
|
||||
u_int32_t *src =(u_int32_t *)p->src;
|
||||
u_int32_t sz = p->sz / sizeof (int);
|
||||
while (sz--)
|
||||
*dst++ = *src++;
|
||||
} while ((p = (struct kloader_page_tag *)p->next) != 0);
|
||||
|
||||
_SH7709A_CACHE_FLUSH();
|
||||
|
||||
/* jump to kernel entry. */
|
||||
__asm__ __volatile__(
|
||||
"mov %0, r4;"
|
||||
"mov %1, r5;"
|
||||
"jmp @%3;"
|
||||
"mov %2, r6;"
|
||||
: :
|
||||
"r"(kbi->argc),
|
||||
"r"(kbi->argv),
|
||||
"r"(&kbi->bootinfo),
|
||||
"r"(kbi->entry));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
KLOADER_SH_BOOT(3, 7709A)
|
||||
KLOADER_SH_BOOT(4, 7750)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.s,v 1.10 2001/10/27 03:46:20 msaitoh Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.11 2002/02/11 17:32:35 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994, 1995, 1997
|
||||
|
@ -415,72 +415,6 @@ XXLwhichqs:
|
|||
.long _C_LABEL(sched_whichqs)
|
||||
|
||||
|
||||
#define PUSHALL \
|
||||
mov.l r0, @-r15 ; \
|
||||
mov.l r1, @-r15 ; \
|
||||
mov.l r2, @-r15 ; \
|
||||
mov.l r3, @-r15 ; \
|
||||
mov.l r4, @-r15 ; \
|
||||
mov.l r5, @-r15 ; \
|
||||
mov.l r6, @-r15 ; \
|
||||
mov.l r7, @-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
|
||||
|
||||
#define POPALL \
|
||||
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 ; \
|
||||
mov.l @r15+, r7 ; \
|
||||
mov.l @r15+, r6 ; \
|
||||
mov.l @r15+, r5 ; \
|
||||
mov.l @r15+, r4 ; \
|
||||
mov.l @r15+, r3 ; \
|
||||
mov.l @r15+, r2 ; \
|
||||
mov.l @r15+, r1 ; \
|
||||
mov.l @r15+, r0
|
||||
|
||||
#define PUSHALLBUTR0 \
|
||||
mov.l r1, @-r15 ; \
|
||||
mov.l r2, @-r15 ; \
|
||||
mov.l r3, @-r15 ; \
|
||||
mov.l r4, @-r15 ; \
|
||||
mov.l r5, @-r15 ; \
|
||||
mov.l r6, @-r15 ; \
|
||||
mov.l r7, @-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
|
||||
|
||||
#define POPALLBUTR0 \
|
||||
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 ; \
|
||||
mov.l @r15+, r7 ; \
|
||||
mov.l @r15+, r6 ; \
|
||||
mov.l @r15+, r5 ; \
|
||||
mov.l @r15+, r4 ; \
|
||||
mov.l @r15+, r3 ; \
|
||||
mov.l @r15+, r2 ; \
|
||||
mov.l @r15+, r1
|
||||
|
||||
#define DIAGNOSTIC 1
|
||||
#ifdef DIAGNOSTIC
|
||||
switch_error:
|
||||
|
@ -1349,7 +1283,7 @@ XL_KCSAREA: .long 0x80000000
|
|||
XXL_SHREG_TTB: .long SHREG_TTB
|
||||
XL_P2AREA: .long 0xa0000000
|
||||
#ifdef SH4
|
||||
XL_cacheflush: .long _C_LABEL(sh4_cache_flush)
|
||||
XL_cacheflush: .long _C_LABEL(sh4_icache_sync_all)
|
||||
#endif
|
||||
|
||||
Xrecurse:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.20 2002/02/07 17:06:00 uch Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.21 2002/02/11 17:32:35 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "opt_md.h"
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_kgdb.h"
|
||||
#include "opt_syscall_debug.h"
|
||||
#include "fs_mfs.h"
|
||||
#include "fs_nfs.h"
|
||||
|
@ -55,7 +56,11 @@
|
|||
|
||||
#include <ufs/mfs/mfs_extern.h> /* mfs_initminiroot() */
|
||||
|
||||
#ifdef DDB
|
||||
#ifdef KGDB
|
||||
#include <sys/kgdb.h>
|
||||
#endif
|
||||
|
||||
#if defined(DDB) || defined(KGDB)
|
||||
#include <machine/db_machdep.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_extern.h>
|
||||
|
@ -64,7 +69,7 @@
|
|||
#endif
|
||||
#define ELFSIZE DB_ELFSIZE
|
||||
#include <sys/exec_elf.h>
|
||||
#endif
|
||||
#endif /* DDB || KGDB */
|
||||
|
||||
#include <dev/cons.h> /* consdev */
|
||||
#include <dev/md.h>
|
||||
|
@ -76,6 +81,7 @@
|
|||
#include <machine/kloader.h>
|
||||
|
||||
#include <hpcsh/hpcsh/clockvar.h>
|
||||
#include <hpcsh/dev/hd64465/hd64465var.h>
|
||||
|
||||
#include <sh3/pclock.h>
|
||||
#include <sh3/intcreg.h>
|
||||
|
@ -196,9 +202,13 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi)
|
|||
SHREG_IPRA = 0;
|
||||
SHREG_IPRB = 0;
|
||||
SHREG_IPRC = 0;
|
||||
#if defined(SH7709) || defined(SH7709A) //XXX
|
||||
SHREG_IPRD = 0;
|
||||
SHREG_IPRE = 0;
|
||||
|
||||
#endif
|
||||
#if defined(SH4) //XXX
|
||||
hd64465_intr_disable();
|
||||
#endif
|
||||
/* start to determine heap area */
|
||||
kernend = (vaddr_t)sh3_round_page(end + symbolsize);
|
||||
|
||||
|
@ -250,8 +260,8 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi)
|
|||
*/
|
||||
/* serial console requires PCLOCK. estimate here */
|
||||
clock_init();
|
||||
sh3_pclock = clock_get_pclock();
|
||||
|
||||
sh3_pclock = clock_get_pclock();
|
||||
if (bootinfo->magic == BOOTINFO_MAGIC) {
|
||||
platid.dw.dw0 = bootinfo->platid_cpu;
|
||||
platid.dw.dw1 = bootinfo->platid_machine;
|
||||
|
@ -263,7 +273,7 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi)
|
|||
|
||||
uvm_setpagesize(); /* default page size (4KB) */
|
||||
|
||||
/* find memory cluster */
|
||||
/* find memory cluster (# of pages) */
|
||||
physmem = mem_cluster_init(SH3_P1SEG_TO_PHYS(kernend));
|
||||
nkpde = ptoa(physmem) >> (PDSHIFT - 1);
|
||||
DPRINTF(("physmem= %d, nkpde = %d\n", physmem, nkpde));
|
||||
|
@ -334,10 +344,16 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi)
|
|||
if (symbolsize) {
|
||||
ddb_init(symbolsize, &end, end + symbolsize);
|
||||
DPRINTF(("symbol size = %d byte\n", symbolsize));
|
||||
}
|
||||
if (boothowto & RB_KDB)
|
||||
Debugger();
|
||||
#endif /* DDB */
|
||||
#ifdef KGDB
|
||||
if (boothowto & RB_KDB) {
|
||||
kgdb_debug_init = 1;
|
||||
kgdb_connect(1);
|
||||
}
|
||||
#endif
|
||||
#endif /* KGDB */
|
||||
|
||||
/* setup proc0 stack */
|
||||
proc0_sp = (vaddr_t)p + NBPG + USPACE - 16 - sizeof(struct trapframe);
|
||||
|
@ -369,23 +385,16 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi)
|
|||
void
|
||||
cpu_startup()
|
||||
{
|
||||
platid_t cpu;
|
||||
int cpuclock;
|
||||
|
||||
cpuclock = clock_get_cpuclock();
|
||||
|
||||
sh3_startup();
|
||||
#define CPUIDMATCH(p) \
|
||||
platid_match(&platid, &platid_mask_CPU_##p)
|
||||
|
||||
if (CPUIDMATCH(SH_3_7709))
|
||||
sprintf(cpu_model, "%s Hitachi SH7709",
|
||||
platid_name(&platid));
|
||||
else if (CPUIDMATCH(SH_3_7709A))
|
||||
sprintf(cpu_model, "%s Hitachi SH7709A",
|
||||
platid_name(&platid));
|
||||
else
|
||||
sprintf(cpu_model, "%s Hitachi SH product unknown",
|
||||
platid_name(&platid));
|
||||
memcpy(&cpu, &platid, sizeof(platid_t));
|
||||
cpu.dw.dw1 = 0; /* clear platform */
|
||||
sprintf(cpu_model, "[%s] %s", platid_name(&platid), platid_name(&cpu));
|
||||
|
||||
#define MHZ(x) ((x) / 1000000), (((x) % 1000000) / 1000)
|
||||
printf("%s %d.%02d MHz PCLOCK %d.%02d MHz\n", cpu_model,
|
||||
|
@ -476,6 +485,9 @@ cpu_reboot(int howto, char *bootstr)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef SH4 //XXX
|
||||
hd64465_intr_reboot();
|
||||
#endif
|
||||
goto *(u_int32_t *)0xa0000000;
|
||||
while (1)
|
||||
;
|
||||
|
@ -560,7 +572,7 @@ mem_cluster_load()
|
|||
DPRINTF(("loading 0x%lx,0x%lx\n", start, size));
|
||||
start = SH3_PHYS_TO_P1SEG(start);
|
||||
memset((void *)start, 0, size);
|
||||
cacheflush();
|
||||
sh_dcache_wbinv_all();
|
||||
end = atop(start + size);
|
||||
start = atop(start);
|
||||
uvm_page_physload(start, end, start, end, VM_FREELIST_DEFAULT);
|
||||
|
@ -574,7 +586,6 @@ mem_cluster_load()
|
|||
start = SH3_PHYS_TO_P1SEG(start);
|
||||
end = start + size;
|
||||
memset((void *)start, 0, size);
|
||||
cacheflush();
|
||||
|
||||
avail_start = start;
|
||||
avail_end = end;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mainbus.c,v 1.5 2001/03/20 16:05:43 uch Exp $ */
|
||||
/* $NetBSD: mainbus.c,v 1.6 2002/02/11 17:32:35 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -55,12 +55,14 @@ struct cfattach mainbus_ca = {
|
|||
static int
|
||||
mainbus_match(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
mainbus_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
|
||||
printf("\n");
|
||||
|
||||
config_search(mainbus_search, self, 0);
|
||||
|
@ -86,5 +88,6 @@ mainbus_search(struct device *parent, struct cfdata *cf, void *aux)
|
|||
static int
|
||||
mainbus_print(void *aux, const char *pnp)
|
||||
{
|
||||
|
||||
return (pnp ? QUIET : UNCONF);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: shb.c,v 1.7 2002/01/29 18:53:02 uch Exp $ */
|
||||
/* $NetBSD: shb.c,v 1.8 2002/02/11 17:32:36 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
|
||||
|
@ -31,46 +31,80 @@
|
|||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <sh3/cpufunc.h>
|
||||
#include <net/netisr.h>
|
||||
|
||||
#include <sh3/intcreg.h>
|
||||
#include <sh3/trapreg.h>
|
||||
#include <machine/shbvar.h>
|
||||
|
||||
#include <net/netisr.h>
|
||||
#include <machine/shbvar.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/debug.h>
|
||||
|
||||
int shbmatch __P((struct device *, struct cfdata *, void *));
|
||||
void shbattach __P((struct device *, struct device *, void *));
|
||||
int shbprint __P((void *, const char *));
|
||||
void intr_calculatemasks __P((void));
|
||||
int fakeintr __P((void *));
|
||||
void *shb_intr_establish __P((int irq, int type,
|
||||
int level, int (*ih_fun)(void *), void *ih_arg));
|
||||
int intrhandler __P((int, int, int, int, struct trapframe));
|
||||
int check_ipending __P((int, int, int, int, struct trapframe));
|
||||
void mask_irq __P((int));
|
||||
void unmask_irq __P((int));
|
||||
void Xsoftserial __P((void));
|
||||
void Xsoftnet __P((void));
|
||||
void Xsoftclock __P((void));
|
||||
void init_soft_intr_handler __P((void));
|
||||
#include <hpcsh/dev/hd64465/hd64465var.h>
|
||||
|
||||
int shbmatch(struct device *, struct cfdata *, void *);
|
||||
void shbattach(struct device *, struct device *, void *);
|
||||
int shbprint(void *, const char *);
|
||||
int shbsearch(struct device *, struct cfdata *, void *);
|
||||
|
||||
void intr_calculatemasks(void);
|
||||
int fakeintr(void *);
|
||||
void *shb_intr_establish(int, int, int, int (*_fun)(void *), void *);
|
||||
int intrhandler(int, int, int, int, struct trapframe);
|
||||
int check_ipending(int, int, int, int, struct trapframe);
|
||||
void mask_irq(int);
|
||||
void unmask_irq(int);
|
||||
void Xsoftserial(void);
|
||||
void Xsoftnet(void);
|
||||
void Xsoftclock(void);
|
||||
void __sh3_intr_debug_hook(void);
|
||||
void __set_intr_level(u_int32_t);
|
||||
|
||||
static int __nih;
|
||||
static struct intrhand __intr_handler[ICU_LEN];
|
||||
int intrmask[ICU_LEN], intrlevel[ICU_LEN];
|
||||
struct intrhand *intrhand[ICU_LEN];
|
||||
|
||||
struct cfattach shb_ca = {
|
||||
sizeof(struct shb_softc), shbmatch, shbattach
|
||||
sizeof(struct device), shbmatch, shbattach
|
||||
};
|
||||
|
||||
int shbsearch __P((struct device *, struct cfdata *, void *));
|
||||
#define SH_SR_MD 0x40000000
|
||||
#define SH_SR_RB 0x20000000
|
||||
#define SH_SR_BL 0x10000000
|
||||
#define SH_SR_FD 0x00008000
|
||||
#define SH_SR_M 0x00000200
|
||||
#define SH_SR_IMASK 0x000000f0
|
||||
#define SH_SR_IMASK_SHIFT 4
|
||||
#define SH_SR_S 0x00000002
|
||||
#define SH_SR_T 0x00000001
|
||||
|
||||
void
|
||||
__set_intr_level(u_int32_t m)
|
||||
{
|
||||
u_int32_t sr;
|
||||
|
||||
m &= SH_SR_IMASK;
|
||||
/* set new interrupt priority level */
|
||||
__asm__ __volatile__("stc sr, %0" : "=r"(sr));
|
||||
sr &= ~SH_SR_IMASK;
|
||||
sr |= m;
|
||||
__asm__ __volatile__("ldc %0, sr" :: "r"(sr));
|
||||
}
|
||||
|
||||
void
|
||||
__sh3_intr_debug_hook()
|
||||
{
|
||||
u_int32_t intevt = *(volatile u_int32_t *)0xffffffd8;
|
||||
u_int32_t intevt2 = *(volatile u_int32_t *)0xa4000000;
|
||||
if (intevt < 0xf00 && intevt != 0x420)
|
||||
printf("INTEVT=%08x INTEVT2=%08x\n", intevt, intevt2);
|
||||
}
|
||||
|
||||
int
|
||||
shbmatch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
shbmatch(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct mainbus_attach_args *ma = aux;
|
||||
|
||||
|
@ -81,102 +115,51 @@ shbmatch(parent, cf, aux)
|
|||
}
|
||||
|
||||
void
|
||||
shbattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
shbattach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct shb_softc *sc = (struct shb_softc *)self;
|
||||
|
||||
printf("\n");
|
||||
|
||||
sc->sc_iot = 0;
|
||||
sc->sc_memt = 0;
|
||||
|
||||
TAILQ_INIT(&sc->sc_subdevs);
|
||||
config_search(shbsearch, self, NULL);
|
||||
|
||||
init_soft_intr_handler();
|
||||
#include "sci.h"
|
||||
#include "scif.h"
|
||||
#include "com.h"
|
||||
#if (NSCI > 0) || (NSCIF > 0) || (NCOM > 0)
|
||||
shb_intr_establish(SIR_SERIAL, IST_LEVEL, IPL_SOFTSERIAL,
|
||||
(int (*) (void *))Xsoftserial, NULL);
|
||||
#endif
|
||||
shb_intr_establish(SIR_NET, IST_LEVEL, IPL_SOFTNET,
|
||||
(int (*) (void *))Xsoftnet, NULL);
|
||||
|
||||
shb_intr_establish(SIR_CLOCK, IST_LEVEL, IPL_SOFTCLOCK,
|
||||
(int (*) (void *))Xsoftclock, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
shbprint(aux, isa)
|
||||
void *aux;
|
||||
const char *isa;
|
||||
shbprint(void *aux, const char *isa)
|
||||
{
|
||||
struct shb_attach_args *ia = aux;
|
||||
|
||||
if (ia->ia_iosize)
|
||||
printf(" port 0x%x", ia->ia_iobase);
|
||||
if (ia->ia_iosize > 1)
|
||||
printf("-0x%x", ia->ia_iobase + ia->ia_iosize - 1);
|
||||
if (ia->ia_msize)
|
||||
printf(" iomem 0x%x", ia->ia_maddr);
|
||||
if (ia->ia_msize > 1)
|
||||
printf("-0x%x", ia->ia_maddr + ia->ia_msize - 1);
|
||||
if (ia->ia_irq != IRQUNK)
|
||||
printf(" irq %d", ia->ia_irq);
|
||||
if (ia->ia_drq != DRQUNK)
|
||||
printf(" drq %d", ia->ia_drq);
|
||||
if (ia->ia_drq2 != DRQUNK)
|
||||
printf(" drq2 %d", ia->ia_drq2);
|
||||
|
||||
return (UNCONF);
|
||||
}
|
||||
|
||||
int
|
||||
shbsearch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
shbsearch(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct shb_softc *sc = (struct shb_softc *)parent;
|
||||
struct shb_attach_args ia;
|
||||
int tryagain;
|
||||
|
||||
do {
|
||||
ia.ia_iot = sc->sc_iot;
|
||||
ia.ia_memt = sc->sc_memt;
|
||||
/* ia.ia_dmat = sc->sc_dmat; */
|
||||
/* ia.ia_ic = sc->sc_ic; */
|
||||
ia.ia_iobase = cf->cf_iobase;
|
||||
ia.ia_iosize = 0x666; /* cf->cf_iosize; */
|
||||
ia.ia_maddr = cf->cf_maddr;
|
||||
ia.ia_msize = cf->cf_msize;
|
||||
ia.ia_irq = cf->cf_irq == 2 ? 9 : cf->cf_irq;
|
||||
ia.ia_drq = cf->cf_drq;
|
||||
ia.ia_drq2 = cf->cf_drq2;
|
||||
/* ia.ia_delaybah = sc->sc_delaybah; */
|
||||
ia.ia_irq = cf->cf_irq;
|
||||
|
||||
tryagain = 0;
|
||||
if ((*cf->cf_attach->ca_match)(parent, cf, &ia) > 0) {
|
||||
if ((*cf->cf_attach->ca_match)(parent, cf, &ia) > 0)
|
||||
config_attach(parent, cf, &ia, shbprint);
|
||||
tryagain = (cf->cf_fstate == FSTATE_STAR);
|
||||
}
|
||||
} while (tryagain);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
shb_intr_typename(type)
|
||||
int type;
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case IST_NONE :
|
||||
return ("none");
|
||||
case IST_PULSE:
|
||||
return ("pulsed");
|
||||
case IST_EDGE:
|
||||
return ("edge-triggered");
|
||||
case IST_LEVEL:
|
||||
return ("level-triggered");
|
||||
default:
|
||||
panic("shb_intr_typename: invalid type %d", type);
|
||||
}
|
||||
}
|
||||
int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
|
||||
struct intrhand *intrhand[ICU_LEN];
|
||||
|
||||
/*
|
||||
* Recalculate the interrupt masks from scratch.
|
||||
* We could code special registry and deregistry versions of this function that
|
||||
|
@ -262,21 +245,6 @@ intr_calculatemasks()
|
|||
irqs |= imask[q->ih_level];
|
||||
intrmask[irq] = irqs;
|
||||
}
|
||||
|
||||
#ifdef TODO
|
||||
/* Lastly, determine which IRQs are actually in use. */
|
||||
{
|
||||
int irqs = 0;
|
||||
for (irq = 0; irq < ICU_LEN; irq++)
|
||||
if (intrhand[irq])
|
||||
irqs |= 1 << irq;
|
||||
if (irqs >= 0x100) /* any IRQs >= 8 in use */
|
||||
irqs |= 1 << IRQ_SLAVE;
|
||||
imen = ~irqs;
|
||||
SET_ICUS();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -284,42 +252,26 @@ intr_calculatemasks()
|
|||
* XXX PRONE TO RACE CONDITIONS, UGLY, 'INTERESTING' INSERTION ALGORITHM.
|
||||
*/
|
||||
void *
|
||||
shb_intr_establish(irq, type, level, ih_fun, ih_arg)
|
||||
int irq;
|
||||
int type;
|
||||
int level;
|
||||
int (*ih_fun) __P((void *));
|
||||
void *ih_arg;
|
||||
shb_intr_establish(int irq, int type, int level, int (*ih_fun)(void *),
|
||||
void *ih_arg)
|
||||
{
|
||||
struct intrhand **p, *q, *ih;
|
||||
static struct intrhand fakehand = {fakeintr};
|
||||
int s;
|
||||
|
||||
/* no point in sleeping unless someone can free memory. */
|
||||
ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
|
||||
if (ih == NULL)
|
||||
panic("shb_intr_establish: can't malloc handler info");
|
||||
if (__nih == ICU_LEN)
|
||||
panic("%s:: can't allocate handler info", __FUNCTION__);
|
||||
ih = &__intr_handler[__nih++];
|
||||
|
||||
/*
|
||||
* Figure out where to put the handler.
|
||||
* This is O(N^2), but we want to preserve the order, and N is
|
||||
* generally small.
|
||||
*/
|
||||
s = splhigh();
|
||||
for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
|
||||
;
|
||||
|
||||
/*
|
||||
* Actually install a fake handler momentarily, since we might be doing
|
||||
* this with interrupts enabled and don't want the real routine called
|
||||
* until masking is set up.
|
||||
*/
|
||||
fakehand.ih_level = level;
|
||||
*p = &fakehand;
|
||||
|
||||
intr_calculatemasks();
|
||||
|
||||
/*
|
||||
* Poke the real handler in now.
|
||||
*/
|
||||
ih->ih_fun = ih_fun;
|
||||
ih->ih_arg = ih_arg;
|
||||
ih->ih_count = 0;
|
||||
|
@ -328,9 +280,12 @@ shb_intr_establish(irq, type, level, ih_fun, ih_arg)
|
|||
ih->ih_irq = irq;
|
||||
*p = ih;
|
||||
|
||||
intr_calculatemasks();
|
||||
|
||||
/* unmask H/W interrupt mask register */
|
||||
if (irq < SHB_MAX_HARDINTR)
|
||||
unmask_irq(irq);
|
||||
splx(s);
|
||||
|
||||
return (ih);
|
||||
}
|
||||
|
@ -343,34 +298,16 @@ fakeintr(arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define IRQ_BIT(irq_num) (1 << (irq_num))
|
||||
|
||||
/*ARGSUSED*/
|
||||
int /* 1 = check ipending on return, 0 = fast intr return */
|
||||
intrhandler(p1, p2, p3, p4, frame)
|
||||
int p1, p2, p3, p4; /* dummy param */
|
||||
struct trapframe frame;
|
||||
intrhandler(int p1, int p2, int p3, int p4, /* dummy param */
|
||||
struct trapframe frame)
|
||||
{
|
||||
unsigned int irl;
|
||||
struct intrhand *ih;
|
||||
unsigned int irq_num;
|
||||
int ocpl;
|
||||
|
||||
#if 0
|
||||
u_int32_t intevt = *(volatile u_int32_t *)0xffffffd8;
|
||||
u_int32_t intevt2 = *(volatile u_int32_t *)0xa4000000;
|
||||
if (intevt < 0xf00 && intevt != 0x420)
|
||||
printf("INTEVT=%08x INTEVT2=%08x\n", intevt, intevt2);
|
||||
#endif
|
||||
__dbg_heart_beat(HEART_BEAT_WHITE);
|
||||
|
||||
#if 0
|
||||
printf("intr_handler:int_no %x spc %x ssr %x r15 %x curproc %x\n",
|
||||
frame.tf_trapno, frame.tf_spc, frame.tf_ssr, frame.tf_r15,
|
||||
(int)curproc);
|
||||
#endif
|
||||
|
||||
irl = (unsigned int)frame.tf_trapno;
|
||||
|
||||
if (irl >= INTEVT_SOFT) {
|
||||
|
@ -390,26 +327,22 @@ intrhandler(p1, p2, p3, p4, frame)
|
|||
|
||||
mask_irq(irq_num);
|
||||
|
||||
if (cpl & IRQ_BIT(irq_num)) {
|
||||
ipending |= IRQ_BIT(irq_num);
|
||||
return 0;
|
||||
if (cpl & (1 << irq_num)) {
|
||||
ipending |= (1 << irq_num);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ocpl = cpl;
|
||||
cpl |= intrmask[irq_num];
|
||||
ih = intrhand[irq_num];
|
||||
if (ih == NULL) {
|
||||
|
||||
/* this is stray interrupt */
|
||||
cpl = ocpl;
|
||||
|
||||
#if 0 /* This is commented by T.Horiuchi */
|
||||
unmask_irq(irq_num);
|
||||
#endif
|
||||
return 1;
|
||||
printf("stray interrupt. INTEVT=0x%x\n", frame.tf_trapno);
|
||||
return (1);
|
||||
}
|
||||
|
||||
enable_ext_intr();
|
||||
__set_intr_level(0);
|
||||
while (ih) {
|
||||
if (ih->ih_arg)
|
||||
(*ih->ih_fun)(ih->ih_arg);
|
||||
|
@ -417,40 +350,28 @@ intrhandler(p1, p2, p3, p4, frame)
|
|||
(*ih->ih_fun)(&frame);
|
||||
ih = ih->ih_next;
|
||||
}
|
||||
disable_ext_intr();
|
||||
__set_intr_level(15);
|
||||
|
||||
cpl = ocpl;
|
||||
|
||||
unmask_irq(irq_num);
|
||||
|
||||
#if 0
|
||||
printf("intr_handler:end\n");
|
||||
#endif
|
||||
return 1;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int /* 1 = resume ihandler on return, 0 = go to fast intr return */
|
||||
check_ipending(p1, p2, p3, p4, frame)
|
||||
int p1, p2, p3, p4; /* dummy param */
|
||||
struct trapframe frame;
|
||||
check_ipending(int p1, int p2, int p3, int p4, /* dummy param */
|
||||
struct trapframe frame)
|
||||
{
|
||||
int ir;
|
||||
int i;
|
||||
int mask;
|
||||
#define MASK_LEN 32
|
||||
|
||||
restart:
|
||||
ir = (~cpl) & ipending;
|
||||
if (ir == 0)
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
mask = 1;
|
||||
for (i = 0; i < MASK_LEN; i++, mask <<= 1) {
|
||||
if (ir & mask)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
mask = 1 << IRQ_LOW;
|
||||
for (i = IRQ_LOW; i <= IRQ_HIGH; i++, mask <<= 1) {
|
||||
if (ir & mask)
|
||||
|
@ -463,7 +384,6 @@ check_ipending(p1, p2, p3, p4, frame)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((mask & ipending) == 0)
|
||||
goto restart;
|
||||
|
@ -481,21 +401,65 @@ check_ipending(p1, p2, p3, p4, frame)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef SH7709A_BROKEN_IPR /* broken IPR patch */
|
||||
#ifdef SH4
|
||||
void
|
||||
mask_irq(irq)
|
||||
int irq;
|
||||
{
|
||||
switch (irq) {
|
||||
case TMU1_IRQ:
|
||||
SHREG_IPRA &= ~((15)<<8);
|
||||
break;
|
||||
case SCI_IRQ:
|
||||
SHREG_IPRB &= ~((15)<<4);
|
||||
break;
|
||||
case SCIF_IRQ:
|
||||
SHREG_IPRC &= ~((15)<<4);
|
||||
break;
|
||||
case 11:
|
||||
hd64465_intr_mask();
|
||||
break;
|
||||
default:
|
||||
if (irq < SHB_MAX_HARDINTR)
|
||||
printf("masked unknown irq(%d)!\n", irq);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unmask_irq(irq)
|
||||
int irq;
|
||||
{
|
||||
|
||||
switch (irq) {
|
||||
case TMU1_IRQ:
|
||||
SHREG_IPRA |= ((15 - irq)<<8);
|
||||
break;
|
||||
case SCI_IRQ:
|
||||
SHREG_IPRB |= ((15 - irq)<<4);
|
||||
break;
|
||||
case SCIF_IRQ:
|
||||
SHREG_IPRC |= ((15 - irq)<<4);
|
||||
break;
|
||||
case 11:
|
||||
hd64465_intr_unmask();
|
||||
break;
|
||||
default:
|
||||
if (irq < SHB_MAX_HARDINTR)
|
||||
printf("unmasked unknown irq(%d)!\n", irq);
|
||||
}
|
||||
}
|
||||
#else /* SH4 */
|
||||
#ifdef SH7709A_BROKEN_IPR /* broken IPR patch */
|
||||
#define IPRA 0
|
||||
#define IPRB 1
|
||||
#define IPRC 2
|
||||
#define IPRD 3
|
||||
#define IPRE 4
|
||||
|
||||
static unsigned short ipr[ 5 ];
|
||||
|
||||
#endif /* SH7709A_BROKEN_IPR */
|
||||
|
||||
void
|
||||
mask_irq(irq)
|
||||
int irq;
|
||||
mask_irq(int irq)
|
||||
{
|
||||
switch (irq) {
|
||||
case TMU1_IRQ:
|
||||
|
@ -583,34 +547,16 @@ unmask_irq(irq)
|
|||
printf("unmasked unknown irq(%d)!\n", irq);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init_soft_intr_handler(void)
|
||||
{
|
||||
#include "sci.h"
|
||||
#include "scif.h"
|
||||
#include "com.h"
|
||||
#if (NSCI > 0) || (NSCIF > 0) || (NCOM > 0)
|
||||
shb_intr_establish(SIR_SERIAL, IST_LEVEL, IPL_SOFTSERIAL,
|
||||
(int (*) (void *))Xsoftserial, NULL);
|
||||
#endif
|
||||
|
||||
shb_intr_establish(SIR_NET, IST_LEVEL, IPL_SOFTNET,
|
||||
(int (*) (void *))Xsoftnet, NULL);
|
||||
|
||||
shb_intr_establish(SIR_CLOCK, IST_LEVEL, IPL_SOFTCLOCK,
|
||||
(int (*) (void *))Xsoftclock, NULL);
|
||||
}
|
||||
#endif /* SH4 */
|
||||
|
||||
#if (NSCI > 0) || (NSCIF > 0) || (NCOM > 0)
|
||||
void scisoft __P((void *));
|
||||
void scifsoft __P((void *));
|
||||
void comsoft __P((void *));
|
||||
void scisoft(void *);
|
||||
void scifsoft(void *);
|
||||
void comsoft(void *);
|
||||
|
||||
void
|
||||
Xsoftserial(void)
|
||||
{
|
||||
__dbg_heart_beat(HEART_BEAT_BLUE);
|
||||
|
||||
#if (NSCI > 0)
|
||||
scisoft(NULL);
|
||||
|
@ -629,8 +575,6 @@ Xsoftnet(void)
|
|||
{
|
||||
int s, ni;
|
||||
|
||||
__dbg_heart_beat(HEART_BEAT_RED);
|
||||
|
||||
s = splhigh();
|
||||
ni = netisr;
|
||||
netisr = 0;
|
||||
|
@ -649,107 +593,6 @@ Xsoftnet(void)
|
|||
void
|
||||
Xsoftclock(void)
|
||||
{
|
||||
__dbg_heart_beat(HEART_BEAT_GREEN);
|
||||
|
||||
softclock(NULL);
|
||||
}
|
||||
|
||||
#define LEGAL_IRQ(x) ((x) >= 0 && (x) < SHB_MAX_HARDINTR && (x) != 2)
|
||||
|
||||
int
|
||||
sh_intr_alloc(mask, type, irq)
|
||||
int mask;
|
||||
int type;
|
||||
int *irq;
|
||||
{
|
||||
int i, tmp, bestirq, count;
|
||||
struct intrhand **p, *q;
|
||||
|
||||
if (type == IST_NONE)
|
||||
panic("intr_alloc: bogus type");
|
||||
|
||||
bestirq = -1;
|
||||
count = -1;
|
||||
|
||||
/* some interrupts should never be dynamically allocated */
|
||||
mask &= 0xdef8;
|
||||
|
||||
/*
|
||||
* XXX some interrupts will be used later (6 for fdc, 12 for pms).
|
||||
* the right answer is to do "breadth-first" searching of devices.
|
||||
*/
|
||||
mask &= 0xefbf;
|
||||
|
||||
for (i = 0; i < SHB_MAX_HARDINTR; i++) {
|
||||
if (LEGAL_IRQ(i) == 0 || (mask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
switch(intrtype[i]) {
|
||||
case IST_NONE:
|
||||
/*
|
||||
* if nothing's using the irq, just return it
|
||||
*/
|
||||
*irq = i;
|
||||
return (0);
|
||||
|
||||
case IST_EDGE:
|
||||
case IST_LEVEL:
|
||||
if (type != intrtype[i])
|
||||
continue;
|
||||
/*
|
||||
* if the irq is shareable, count the number of other
|
||||
* handlers, and if it's smaller than the last irq like
|
||||
* this, remember it
|
||||
*
|
||||
* XXX We should probably also consider the
|
||||
* interrupt level and stick IPL_TTY with other
|
||||
* IPL_TTY, etc.
|
||||
*/
|
||||
for (p = &intrhand[i], tmp = 0; (q = *p) != NULL;
|
||||
p = &q->ih_next, tmp++)
|
||||
;
|
||||
if ((bestirq == -1) || (count > tmp)) {
|
||||
bestirq = i;
|
||||
count = tmp;
|
||||
}
|
||||
break;
|
||||
|
||||
case IST_PULSE:
|
||||
/* this just isn't shareable */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestirq == -1)
|
||||
return (1);
|
||||
|
||||
*irq = bestirq;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deregister an interrupt handler.
|
||||
*/
|
||||
void
|
||||
shb_intr_disestablish(ic, arg)
|
||||
void *ic;
|
||||
void *arg;
|
||||
{
|
||||
struct intrhand *ih = arg;
|
||||
int irq = ih->ih_irq;
|
||||
struct intrhand **p, *q;
|
||||
|
||||
mask_irq(irq);
|
||||
|
||||
/*
|
||||
* Remove the handler from the chain.
|
||||
* This is O(n^2), too.
|
||||
*/
|
||||
for (p = &intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
|
||||
;
|
||||
if (q)
|
||||
*p = q->ih_next;
|
||||
else
|
||||
panic("shb_intr_disestablish: handler not registered");
|
||||
free(ih, M_DEVBUF);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: bus.h,v 1.5 2001/07/19 15:32:13 thorpej Exp $ */
|
||||
/* $NetBSD: bus.h,v 1.6 2002/02/11 17:32:36 uch Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2000, 2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997, 1998, 2000, 2001, 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -605,6 +605,11 @@ void bus_space_destroy(bus_space_tag_t);
|
|||
#define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
|
||||
#define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
|
||||
|
||||
/*
|
||||
* Private flags stored in the DMA map.
|
||||
*/
|
||||
#define HPCSH_DMAMAP_COHERENT 0x100 /* no cache flush necessary on sync */
|
||||
|
||||
/* Forwards needed by prototypes below. */
|
||||
struct mbuf;
|
||||
struct uio;
|
||||
|
@ -629,6 +634,7 @@ typedef struct hpcsh_bus_dmamap *bus_dmamap_t;
|
|||
struct hpcsh_bus_dma_segment {
|
||||
bus_addr_t ds_addr; /* DMA address */
|
||||
bus_size_t ds_len; /* length of transfer */
|
||||
bus_addr_t _ds_vaddr; /* virtual address, 0 if invalid */
|
||||
};
|
||||
typedef struct hpcsh_bus_dma_segment bus_dma_segment_t;
|
||||
|
||||
|
@ -642,6 +648,10 @@ typedef struct hpcsh_bus_dma_segment bus_dma_segment_t;
|
|||
struct hpcsh_bus_dma_tag {
|
||||
void *_cookie; /* cookie used in the guts */
|
||||
|
||||
bus_addr_t _wbase; /* DMA window base */
|
||||
bus_addr_t _physbase; /* physical base of the window */
|
||||
bus_size_t _wsize; /* size of the window */
|
||||
|
||||
/*
|
||||
* DMA mapping methods.
|
||||
*/
|
||||
|
@ -717,15 +727,55 @@ struct hpcsh_bus_dmamap {
|
|||
bus_size_t _dm_maxsegsz; /* largest possible segment */
|
||||
bus_size_t _dm_boundary; /* don't cross this */
|
||||
int _dm_flags; /* misc. flags */
|
||||
struct proc *_dm_proc; /* proc that owns the mapping */
|
||||
|
||||
void *_dm_cookie; /* cookie for bus-specific functions */
|
||||
/*
|
||||
* Private cookie to be used by the DMA back-end.
|
||||
*/
|
||||
void *_dm_cookie;
|
||||
|
||||
/*
|
||||
* PUBLIC MEMBERS: these are used by machine-independent code.
|
||||
*/
|
||||
bus_size_t dm_mapsize; /* size of the mapping */
|
||||
int dm_nsegs; /* # valid segments in mapping */
|
||||
bus_dma_segment_t dm_segs[1]; /* segments; variable length */
|
||||
bus_size_t dm_mapsize; /* size of the mapping */
|
||||
};
|
||||
|
||||
#ifdef _HPCSH_BUS_DMA_PRIVATE
|
||||
int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
|
||||
bus_size_t, int, bus_dmamap_t *);
|
||||
void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
|
||||
int _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
|
||||
bus_size_t, struct proc *, int);
|
||||
int _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
|
||||
struct mbuf *, int);
|
||||
int _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
|
||||
struct uio *, int);
|
||||
int _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
|
||||
bus_dma_segment_t *, int, bus_size_t, int);
|
||||
void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
|
||||
void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
|
||||
bus_size_t, int);
|
||||
|
||||
int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
|
||||
bus_size_t alignment, bus_size_t boundary,
|
||||
bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
|
||||
void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
|
||||
int nsegs);
|
||||
int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
|
||||
int nsegs, size_t size, caddr_t *kvap, int flags);
|
||||
void _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
|
||||
size_t size);
|
||||
paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
|
||||
int nsegs, off_t off, int prot, int flags);
|
||||
|
||||
int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
|
||||
bus_size_t alignment, bus_size_t boundary,
|
||||
bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
|
||||
vaddr_t low, vaddr_t high);
|
||||
|
||||
extern struct playstation2_bus_dma_tag playstation2_default_bus_dma_tag;
|
||||
#endif /* _HPCSH_BUS_DMA_PRIVATE */
|
||||
|
||||
#endif /* _HPCSH_BUS_H_ */
|
||||
|
|
Loading…
Reference in New Issue