Unfortunately, several changes that are intermingled:
- Add initial IOP support. ADB doesn't work yet for me, but it's here so that others will be encouraged to work on it. ADB_HW_IOP basically is configured as a NOP so that serial consoles will continue to work. - Roll via1_intr and via2_intr into the intr.c scheme--this also required changing rtclock_intr to grovel the stack differently so that hardclock gets the right arguments and softclock() doesn't get all reentrant. - Make via1 interrupts parallel to via2 interrupts--handlers get a pass- through pointer and we can register handlers. Register via1 interrupt with intr_establish()--normally level 1, level 6 for A/UX scheme. - Use intr_establish() to set real via2 interrupt handler instead of the hacked function pointer. - Reorganize adb-direct interrupts so that a function call is removed. - Implement A/UX interrupts for all Quadras right now. We may need to special case some Quadras, but Linux folks are reporting success on several models. - Fix intrnames to be accurate for the normal, PSC, and A/UX interrupt configurations.
This commit is contained in:
parent
f9de07203c
commit
71a4446b04
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.mac68k,v 1.90 1999/06/07 20:31:31 thorpej Exp $
|
||||
# $NetBSD: files.mac68k,v 1.91 1999/06/28 01:56:55 briggs Exp $
|
||||
|
||||
# mac68k-specific configuration info
|
||||
|
||||
@ -136,6 +136,7 @@ file arch/mac68k/mac68k/clock.c
|
||||
file arch/mac68k/mac68k/conf.c
|
||||
file arch/mac68k/mac68k/disksubr.c disk
|
||||
file arch/mac68k/mac68k/intr.c
|
||||
file arch/mac68k/mac68k/iop.c
|
||||
file arch/mac68k/mac68k/kgdb_machdep.c kgdb
|
||||
file arch/mac68k/mac68k/machdep.c
|
||||
file arch/mac68k/mac68k/macrom.c
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: adb_direct.c,v 1.23 1999/05/15 19:29:12 scottr Exp $ */
|
||||
/* $NetBSD: adb_direct.c,v 1.24 1999/06/28 01:56:56 briggs Exp $ */
|
||||
|
||||
/* From: adb_direct.c 2.02 4/18/97 jpw */
|
||||
|
||||
@ -70,6 +70,7 @@
|
||||
#include <machine/param.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/adbsys.h> /* required for adbvar.h */
|
||||
#include <machine/iopreg.h> /* required for IOP support */
|
||||
|
||||
#include <mac68k/mac68k/macrom.h>
|
||||
#include <mac68k/dev/adbvar.h>
|
||||
@ -100,6 +101,7 @@
|
||||
#define ADB_ACTION_OUT 0x3 /* sending out a command */
|
||||
#define ADB_ACTION_IN 0x4 /* receiving data */
|
||||
#define ADB_ACTION_POLLING 0x5 /* polling - II only */
|
||||
#define ADB_ACTION_RUNNING 0x6 /* running - IOP only */
|
||||
|
||||
/*
|
||||
* These describe the state of the ADB bus itself, although they
|
||||
@ -210,6 +212,7 @@ char *adbHardwareDescr[MAX_ADB_HW + 1] = {
|
||||
"IIsi series",
|
||||
"PowerBook",
|
||||
"Cuda",
|
||||
"IOP",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -265,8 +268,9 @@ extern struct mac68k_machine_S mac68k_machine;
|
||||
extern int ite_polling; /* Are we polling? (Debugger mode) */
|
||||
|
||||
void pm_setup_adb __P((void));
|
||||
void pm_hw_setup __P((void));
|
||||
void pm_check_adb_devices __P((int));
|
||||
void pm_intr __P((void));
|
||||
void pm_intr __P((void *));
|
||||
int pm_adb_op __P((u_char *, void *, void *, int));
|
||||
void pm_init_adb_device __P((void));
|
||||
|
||||
@ -276,10 +280,10 @@ void pm_init_adb_device __P((void));
|
||||
#ifdef ADB_DEBUG
|
||||
void print_single __P((u_char *));
|
||||
#endif
|
||||
void adb_intr __P((void));
|
||||
void adb_intr_II __P((void));
|
||||
void adb_intr_IIsi __P((void));
|
||||
void adb_intr_cuda __P((void));
|
||||
void adb_intr __P((void *));
|
||||
void adb_intr_II __P((void *));
|
||||
void adb_intr_IIsi __P((void *));
|
||||
void adb_intr_cuda __P((void *));
|
||||
void adb_soft_intr __P((void));
|
||||
int send_adb_II __P((u_char *, u_char *, void *, void *, int));
|
||||
int send_adb_IIsi __P((u_char *, u_char *, void *, void *, int));
|
||||
@ -307,6 +311,8 @@ int adb_prog_switch_enable __P((void));
|
||||
int adb_prog_switch_disable __P((void));
|
||||
/* we should create this and it will be the public version */
|
||||
int send_adb __P((u_char *, void *, void *));
|
||||
void adb_iop_recv __P((IOP *, struct iop_msg *));
|
||||
int send_adb_iop __P((int, u_char *, void *, void *));
|
||||
|
||||
#ifdef ADB_DEBUG
|
||||
/*
|
||||
@ -374,7 +380,7 @@ adb_cuda_tickle(void)
|
||||
* grab serial interrupts?
|
||||
*/
|
||||
void
|
||||
adb_intr_cuda(void)
|
||||
adb_intr_cuda(void *arg)
|
||||
{
|
||||
volatile int i, ending;
|
||||
volatile unsigned int s;
|
||||
@ -682,7 +688,7 @@ send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
|
||||
while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
|
||||
|| (adbWaiting == 1))
|
||||
if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
|
||||
adb_intr_cuda(); /* process it */
|
||||
adb_intr_cuda(NULL); /* process it */
|
||||
adb_soft_intr();
|
||||
}
|
||||
|
||||
@ -691,7 +697,7 @@ send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
|
||||
|
||||
|
||||
void
|
||||
adb_intr_II(void)
|
||||
adb_intr_II(void *arg)
|
||||
{
|
||||
struct adbCommand packet;
|
||||
int i, intr_on = 0;
|
||||
@ -706,6 +712,8 @@ adb_intr_II(void)
|
||||
ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
|
||||
|
||||
delay(ADB_DELAY); /* yuck (don't remove) */
|
||||
|
||||
if (!mac68k_machine.aux_interrupts)
|
||||
(void)intr_dispatch(0x70); /* grab any serial interrupts */
|
||||
|
||||
if (ADB_INTR_IS_ON)
|
||||
@ -753,6 +761,7 @@ switch_start:
|
||||
adbActionState = ADB_ACTION_IN;
|
||||
}
|
||||
delay(ADB_DELAY);
|
||||
if (!mac68k_machine.aux_interrupts)
|
||||
(void)intr_dispatch(0x70); /* grab any serial interrupts */
|
||||
goto switch_start;
|
||||
break;
|
||||
@ -1123,7 +1132,7 @@ send_adb_II(u_char * in, u_char * buffer, void *compRout, void *data, int comman
|
||||
while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
|
||||
|| (adbWaiting == 1))
|
||||
if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
|
||||
adb_intr_II(); /* go process "interrupt" */
|
||||
adb_intr_II(NULL); /* go process "interrupt" */
|
||||
adb_soft_intr();
|
||||
}
|
||||
|
||||
@ -1187,22 +1196,25 @@ adb_guess_next_device(void)
|
||||
* code for the machine we are running on.
|
||||
*/
|
||||
void
|
||||
adb_intr(void)
|
||||
adb_intr(void *arg)
|
||||
{
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_II:
|
||||
adb_intr_II();
|
||||
adb_intr_II(arg);
|
||||
break;
|
||||
|
||||
case ADB_HW_IISI:
|
||||
adb_intr_IIsi();
|
||||
adb_intr_IIsi(arg);
|
||||
break;
|
||||
|
||||
case ADB_HW_PB:
|
||||
case ADB_HW_PB: /* Should not come through here. */
|
||||
break;
|
||||
|
||||
case ADB_HW_CUDA:
|
||||
adb_intr_cuda();
|
||||
adb_intr_cuda(arg);
|
||||
break;
|
||||
|
||||
case ADB_HW_IOP: /* Should not come through here. */
|
||||
break;
|
||||
|
||||
case ADB_HW_UNKNOWN:
|
||||
@ -1218,7 +1230,7 @@ adb_intr(void)
|
||||
*
|
||||
*/
|
||||
void
|
||||
adb_intr_IIsi(void)
|
||||
adb_intr_IIsi(void *arg)
|
||||
{
|
||||
struct adbCommand packet;
|
||||
int i, ending;
|
||||
@ -1502,13 +1514,77 @@ send_adb_IIsi(u_char * in, u_char * buffer, void *compRout, void *data, int
|
||||
while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
|
||||
|| (adbWaiting == 1))
|
||||
if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
|
||||
adb_intr_IIsi(); /* process it */
|
||||
adb_intr_IIsi(NULL); /* process it */
|
||||
adb_soft_intr();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* send_adb_IIsi */
|
||||
|
||||
void
|
||||
adb_iop_recv(IOP *iop, struct iop_msg *msg)
|
||||
{
|
||||
struct adbCommand pkt;
|
||||
unsigned flags;
|
||||
|
||||
if (adbActionState != ADB_ACTION_RUNNING)
|
||||
return;
|
||||
|
||||
switch (msg->status) {
|
||||
case IOP_MSGSTAT_SENT:
|
||||
if (0 == adb_cmd_result(msg->msg + 1)) {
|
||||
adbWaiting = 1;
|
||||
adbWaitingCmd = msg->msg[2];
|
||||
}
|
||||
break;
|
||||
case IOP_MSGSTAT_RECEIVED:
|
||||
case IOP_MSGSTAT_UNEXPECTED:
|
||||
flags = msg->msg[0];
|
||||
if (flags != 0) {
|
||||
printf("ADB FLAGS 0x%x", flags);
|
||||
break;
|
||||
}
|
||||
if (adbWaiting &&
|
||||
(msg->msg[2] == adbWaitingCmd)) {
|
||||
pkt.saveBuf = msg->msg + 1;
|
||||
pkt.compRout = adbCompRout;
|
||||
pkt.compData = adbCompData;
|
||||
pkt.unsol = 0;
|
||||
pkt.ack_only = 0;
|
||||
adb_pass_up(&pkt);
|
||||
|
||||
adbWaitingCmd = 0;
|
||||
adbWaiting = 0;
|
||||
} else {
|
||||
pkt.unsol = 1;
|
||||
pkt.ack_only = 0;
|
||||
adb_pass_up(&pkt);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
send_adb_iop(int cmd, u_char * buffer, void *compRout, void *data)
|
||||
{
|
||||
u_char buff[32];
|
||||
int i, cnt;
|
||||
|
||||
if (adbActionState != ADB_ACTION_RUNNING)
|
||||
return -1;
|
||||
|
||||
buff[0] = IOP_ADB_FL_EXPLICIT;
|
||||
buff[1] = buffer[0];
|
||||
buff[2] = cmd;
|
||||
cnt = (int) buff[1];
|
||||
for (i=0; i<cnt ; i++) {
|
||||
buff[i+3] = buffer[i+1];
|
||||
}
|
||||
return iop_send_msg(ISM_IOP, IOP_CHAN_ADB, buff, cnt+3,
|
||||
adb_iop_recv, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* adb_pass_up is called by the interrupt-time routines.
|
||||
@ -1559,6 +1635,7 @@ adb_pass_up(struct adbCommand *in)
|
||||
start = 0;
|
||||
} else {
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_IOP:
|
||||
case ADB_HW_II:
|
||||
cmd = in->data[1];
|
||||
if (in->data[0] < 2)
|
||||
@ -1776,6 +1853,17 @@ adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case ADB_HW_IOP:
|
||||
#if 0
|
||||
result = send_adb_iop((int)command, (u_char *)buffer,
|
||||
(void *)compRout, (void *)data);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
else
|
||||
#endif
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case ADB_HW_IISI:
|
||||
result = send_adb_IIsi((u_char *)0, (u_char *)buffer,
|
||||
(void *)compRout, (void *)data, (int)command);
|
||||
@ -1831,6 +1919,8 @@ adb_hw_setup(void)
|
||||
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_II:
|
||||
via1_register_irq(2, adb_intr_II, NULL);
|
||||
|
||||
via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
|
||||
* outputs */
|
||||
via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
|
||||
@ -1847,7 +1937,14 @@ adb_hw_setup(void)
|
||||
ADB_VIA_CLR_INTR(); /* clear interrupt */
|
||||
break;
|
||||
|
||||
case ADB_HW_IOP:
|
||||
/* adbActionState = ADB_ACTION_RUNNING; */
|
||||
via_reg(VIA1, vIER) = 0x84;
|
||||
via_reg(VIA1, vIFR) = 0x04;
|
||||
break;
|
||||
|
||||
case ADB_HW_IISI:
|
||||
via1_register_irq(2, adb_intr_IIsi, NULL);
|
||||
via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
|
||||
* outputs */
|
||||
via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
|
||||
@ -1882,10 +1979,11 @@ adb_hw_setup(void)
|
||||
* XXX - really PM_VIA_CLR_INTR - should we put it in
|
||||
* pm_direct.h?
|
||||
*/
|
||||
via_reg(VIA1, vIFR) = 0x90; /* clear interrupt */
|
||||
pm_hw_setup();
|
||||
break;
|
||||
|
||||
case ADB_HW_CUDA:
|
||||
via1_register_irq(2, adb_intr_cuda, NULL);
|
||||
via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
|
||||
* outputs */
|
||||
via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
|
||||
@ -2013,7 +2111,8 @@ adb_reinit(void)
|
||||
(void)(&s); /* work around lame GCC bug */
|
||||
|
||||
/* Make sure we are not interrupted while building the table. */
|
||||
if (adbHardware != ADB_HW_PB) /* ints must be on for PB? */
|
||||
/* ints must be on for PB & IOP (at least, for now) */
|
||||
if (adbHardware != ADB_HW_PB && adbHardware != ADB_HW_IOP)
|
||||
s = splhigh();
|
||||
|
||||
ADBNumDevices = 0; /* no devices yet */
|
||||
@ -2034,7 +2133,7 @@ adb_reinit(void)
|
||||
|
||||
/* send an ADB reset first */
|
||||
adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
|
||||
delay(3000);
|
||||
delay(4000);
|
||||
|
||||
/*
|
||||
* Probe for ADB devices. Probe devices 1-15 quickly to determine
|
||||
@ -2198,7 +2297,8 @@ adb_reinit(void)
|
||||
if (adbHardware == ADB_HW_CUDA)
|
||||
timeout((void *)adb_cuda_tickle, 0, ADB_TICKLE_TICKS);
|
||||
|
||||
if (adbHardware != ADB_HW_PB) /* ints must be on for PB? */
|
||||
/* ints must be on for PB & IOP (at least, for now) */
|
||||
if (adbHardware != ADB_HW_PB && adbHardware != ADB_HW_IOP)
|
||||
splx(s);
|
||||
|
||||
return;
|
||||
@ -2255,6 +2355,7 @@ int
|
||||
adb_cmd_result(u_char *in)
|
||||
{
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_IOP:
|
||||
case ADB_HW_II:
|
||||
/* was it an ADB talk command? */
|
||||
if ((in[1] & 0x0c) == 0x0c)
|
||||
@ -2294,7 +2395,8 @@ int
|
||||
adb_cmd_extra(u_char *in)
|
||||
{
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_II:
|
||||
case ADB_HW_II:
|
||||
case ADB_HW_IOP:
|
||||
if ((in[1] & 0x0c) == 0x08) /* was it a listen command? */
|
||||
return 0;
|
||||
return 1;
|
||||
@ -2401,8 +2503,6 @@ adb_setup_hw_type(void)
|
||||
case MACH_MACIIVX: /* IIvx */
|
||||
case MACH_MACP460: /* Performa 460/465/467 */
|
||||
case MACH_MACP600: /* Performa 600 */
|
||||
case MACH_MACQ900: /* Quadra 900 - XXX not sure */
|
||||
case MACH_MACQ950: /* Quadra 950 - XXX not sure */
|
||||
adbHardware = ADB_HW_IISI;
|
||||
#ifdef ADB_DEBUG
|
||||
if (adb_debug)
|
||||
@ -2461,6 +2561,18 @@ adb_setup_hw_type(void)
|
||||
printf_intr("adb: using Cuda series hardware support\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MACH_MACQ900: /* Quadra 900 */
|
||||
case MACH_MACQ950: /* Quadra 950 */
|
||||
case MACH_MACIIFX: /* Mac IIfx */
|
||||
adbHardware = ADB_HW_IOP;
|
||||
iop_register_listener(ISM_IOP, IOP_CHAN_ADB, adb_iop_recv, NULL);
|
||||
#ifdef ADB_DEBUG
|
||||
if (adb_debug)
|
||||
printf_intr("adb: using IOP-based ADB\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
adbHardware = ADB_HW_UNKNOWN;
|
||||
#ifdef ADB_DEBUG
|
||||
@ -2488,8 +2600,6 @@ adb_setup_hw_type(void)
|
||||
case MACH_MACP600: /* Performa 600 */
|
||||
case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
|
||||
case MACH_MACQ840AV: /* Quadra 840AV */
|
||||
case MACH_MACQ900: /* Quadra 900 - XXX not sure */
|
||||
case MACH_MACQ950: /* Quadra 950 - XXX not sure */
|
||||
adbSoftPower = 1;
|
||||
break;
|
||||
}
|
||||
@ -2576,14 +2686,14 @@ set_adb_info(ADBSetInfoBlock * info, int adbAddr)
|
||||
long
|
||||
mrg_adbintr(void)
|
||||
{
|
||||
adb_intr();
|
||||
adb_intr(NULL);
|
||||
return 1; /* mimic mrg_adbintr in macrom.h just in case */
|
||||
}
|
||||
|
||||
long
|
||||
mrg_pmintr(void)
|
||||
{
|
||||
pm_intr();
|
||||
pm_intr(NULL);
|
||||
return 1; /* mimic mrg_pmintr in macrom.h just in case */
|
||||
}
|
||||
|
||||
@ -2600,6 +2710,9 @@ adb_read_date_time(unsigned long *time)
|
||||
case ADB_HW_II:
|
||||
return -1;
|
||||
|
||||
case ADB_HW_IOP:
|
||||
return -1;
|
||||
|
||||
case ADB_HW_IISI:
|
||||
output[0] = 0x02; /* 2 byte message */
|
||||
output[1] = 0x01; /* to pram/rtc device */
|
||||
@ -2652,6 +2765,9 @@ adb_set_date_time(unsigned long time)
|
||||
case ADB_HW_II:
|
||||
return -1;
|
||||
|
||||
case ADB_HW_IOP:
|
||||
return -1;
|
||||
|
||||
case ADB_HW_IISI:
|
||||
output[0] = 0x06; /* 6 byte message */
|
||||
output[1] = 0x01; /* to pram/rtc device */
|
||||
@ -2738,6 +2854,7 @@ adb_poweroff(void)
|
||||
return 0;
|
||||
|
||||
case ADB_HW_II: /* II models don't do ADB soft power */
|
||||
case ADB_HW_IOP: /* IOP models don't do ADB soft power */
|
||||
case ADB_HW_UNKNOWN:
|
||||
default:
|
||||
return -1;
|
||||
@ -2771,6 +2888,7 @@ adb_prog_switch_enable(void)
|
||||
return -1;
|
||||
|
||||
case ADB_HW_II: /* II models don't do prog. switch */
|
||||
case ADB_HW_IOP: /* IOP models don't do prog. switch */
|
||||
case ADB_HW_CUDA: /* cuda doesn't do prog. switch TO DO: verify this */
|
||||
case ADB_HW_UNKNOWN:
|
||||
default:
|
||||
@ -2805,6 +2923,7 @@ adb_prog_switch_disable(void)
|
||||
return -1;
|
||||
|
||||
case ADB_HW_II: /* II models don't do prog. switch */
|
||||
case ADB_HW_IOP: /* IOP models don't do prog. switch */
|
||||
case ADB_HW_CUDA: /* cuda doesn't do prog. switch */
|
||||
case ADB_HW_UNKNOWN:
|
||||
default:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: adbvar.h,v 1.14 1999/02/11 06:41:08 ender Exp $ */
|
||||
/* $NetBSD: adbvar.h,v 1.15 1999/06/28 01:56:56 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1994 Bradley A. Grantham
|
||||
@ -84,7 +84,8 @@ void extdms_complete __P((void));
|
||||
#define ADB_HW_IISI 0x2 /* Mac IIsi series */
|
||||
#define ADB_HW_PB 0x3 /* PowerBook series */
|
||||
#define ADB_HW_CUDA 0x4 /* Machines with a Cuda chip */
|
||||
#define MAX_ADB_HW 4 /* Number of ADB hardware types */
|
||||
#define ADB_HW_IOP 0x5 /* Machines with an IOP */
|
||||
#define MAX_ADB_HW 5 /* Number of ADB hardware types */
|
||||
|
||||
#ifndef MRG_ADB
|
||||
/* adb_direct.c */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pm_direct.c,v 1.8 1999/03/05 06:45:41 scottr Exp $ */
|
||||
/* $NetBSD: pm_direct.c,v 1.9 1999/06/28 01:56:56 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Takashi Hamada
|
||||
@ -173,13 +173,13 @@ int pm_wait_free __P((int));
|
||||
int pm_receive_pm1 __P((u_char *));
|
||||
int pm_send_pm1 __P((u_char,int));
|
||||
int pm_pmgrop_pm1 __P((PMData *));
|
||||
void pm_intr_pm1 __P((void));
|
||||
void pm_intr_pm1 __P((void *));
|
||||
|
||||
/* these functions are for the PB Duo series and the PB 5XX series */
|
||||
int pm_receive_pm2 __P((u_char *));
|
||||
int pm_send_pm2 __P((u_char));
|
||||
int pm_pmgrop_pm2 __P((PMData *));
|
||||
void pm_intr_pm2 __P((void));
|
||||
void pm_intr_pm2 __P((void *));
|
||||
|
||||
/* this function is MRG-Based (for testing) */
|
||||
int pm_pmgrop_mrg __P((PMData *));
|
||||
@ -187,8 +187,9 @@ int pm_pmgrop_mrg __P((PMData *));
|
||||
/* these functions are called from adb_direct.c */
|
||||
void pm_setup_adb __P((void));
|
||||
void pm_check_adb_devices __P((int));
|
||||
void pm_intr __P((void));
|
||||
void pm_intr __P((void *));
|
||||
int pm_adb_op __P((u_char *, void *, void *, int));
|
||||
void pm_hw_setup __P((void));
|
||||
|
||||
/* these functions also use the variables of adb_direct.c */
|
||||
void pm_adb_get_TALK_result __P((PMData *));
|
||||
@ -558,7 +559,8 @@ pm_pmgrop_pm1(pmdata)
|
||||
* My PM interrupt routine for PB1XX series
|
||||
*/
|
||||
void
|
||||
pm_intr_pm1()
|
||||
pm_intr_pm1(arg)
|
||||
void *arg;
|
||||
{
|
||||
int s;
|
||||
int rval;
|
||||
@ -827,7 +829,8 @@ pm_pmgrop_pm2(pmdata)
|
||||
* My PM interrupt routine for the PB Duo series and the PB 5XX series
|
||||
*/
|
||||
void
|
||||
pm_intr_pm2()
|
||||
pm_intr_pm2(arg)
|
||||
void *arg;
|
||||
{
|
||||
int s;
|
||||
int rval;
|
||||
@ -952,14 +955,15 @@ pmgrop(pmdata)
|
||||
* My PM interrupt routine
|
||||
*/
|
||||
void
|
||||
pm_intr()
|
||||
pm_intr(arg)
|
||||
void *arg;
|
||||
{
|
||||
switch (pmHardware) {
|
||||
case PM_HW_PB1XX:
|
||||
pm_intr_pm1();
|
||||
pm_intr_pm1(arg);
|
||||
break;
|
||||
case PM_HW_PB5XX:
|
||||
pm_intr_pm2();
|
||||
pm_intr_pm2(arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -967,6 +971,23 @@ pm_intr()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pm_hw_setup()
|
||||
{
|
||||
switch (pmHardware) {
|
||||
case PM_HW_PB1XX:
|
||||
via1_register_irq(4, pm_intr_pm1, (void *)0);
|
||||
PM_VIA_CLR_INTR();
|
||||
break;
|
||||
case PM_HW_PB5XX:
|
||||
via1_register_irq(4, pm_intr_pm2, (void *)0);
|
||||
PM_VIA_CLR_INTR();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Synchronous ADBOp routine for the Power Manager
|
||||
@ -1019,7 +1040,7 @@ pm_adb_op(buffer, compRout, data, command)
|
||||
pmdata.data[2] = 0;
|
||||
|
||||
if ((command & 0xc) != 0xc) { /* if the command is not TALK */
|
||||
/* set up stuff for adb_pass_up */
|
||||
/* set up stuff fNULLor adb_pass_up */
|
||||
packet.data[0] = 1 + pmdata.data[2];
|
||||
packet.data[1] = command;
|
||||
for (i = 0; i < pmdata.data[2]; i++)
|
||||
@ -1048,7 +1069,7 @@ pm_adb_op(buffer, compRout, data, command)
|
||||
delay = 0x80000;
|
||||
while (adbWaiting == 1) {
|
||||
if ((via_reg(VIA1, vIFR) & 0x10) == 0x10)
|
||||
pm_intr();
|
||||
pm_intr((void *)0);
|
||||
#ifdef PM_GRAB_SI
|
||||
#if 0
|
||||
zshard(0); /* grab any serial interrupts */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.h,v 1.61 1999/04/06 03:40:23 scottr Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.62 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
@ -246,6 +246,10 @@ struct mac68k_machine_S {
|
||||
int scsi96; /* Has NCR 53C96 */
|
||||
int scsi96_2; /* Has 2nd 53C96 */
|
||||
int sonic; /* Has SONIC e-net */
|
||||
|
||||
int via1_ipl;
|
||||
int via2_ipl;
|
||||
int aux_interrupts;
|
||||
};
|
||||
|
||||
/* What kind of model is this */
|
||||
|
149
sys/arch/mac68k/include/iopreg.h
Normal file
149
sys/arch/mac68k/include/iopreg.h
Normal file
@ -0,0 +1,149 @@
|
||||
/* $NetBSD: iopreg.h,v 1.1 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
#include <sys/pool.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#define IOP1_BASE 0x00004000
|
||||
|
||||
#define SCC_IOP 0
|
||||
#define ISM_IOP 1
|
||||
|
||||
#define IOP_CS_BYPASS 0x01
|
||||
#define IOP_CS_AUTOINC 0x02
|
||||
#define IOP_CS_RUN 0x04
|
||||
#define IOP_CS_IRQ 0x08
|
||||
#define IOP_CS_INT0 0x10
|
||||
#define IOP_CS_INT1 0x20
|
||||
#define IOP_CS_HWINT 0x40
|
||||
#define IOP_CS_DMAINACT 0x80
|
||||
|
||||
#define IOP_RESET (IOP_CS_DMAINACT | IOP_CS_AUTOINC)
|
||||
#define IOP_BYPASS \
|
||||
(IOP_CS_BYPASS | IOP_CS_AUTOINC | IOP_CS_RUN | IOP_CS_DMAINACT)
|
||||
#define IOP_INTERRUPT (IOP_CS_INT0 | IOP_CS_INT1)
|
||||
|
||||
#define OSS_INTLEVEL_OFFSET 0x0001A006
|
||||
|
||||
typedef struct {
|
||||
volatile u_char ram_hi;
|
||||
u_char pad0;
|
||||
volatile u_char ram_lo;
|
||||
u_char pad1;
|
||||
volatile u_char control_status;
|
||||
u_char pad2[3];
|
||||
volatile u_char data;
|
||||
u_char pad3[23];
|
||||
union {
|
||||
struct {
|
||||
volatile u_char sccb_cmd;
|
||||
u_char pad0;
|
||||
volatile u_char scca_cmd;
|
||||
u_char pad1;
|
||||
volatile u_char sccb_data;
|
||||
u_char pad2;
|
||||
volatile u_char scca_data;
|
||||
u_char pad3;
|
||||
} scc;
|
||||
struct {
|
||||
volatile u_char wdata;
|
||||
u_char pad0;
|
||||
/* etc... */
|
||||
} iwm;
|
||||
} bypass;
|
||||
} IOPHW;
|
||||
|
||||
#define IOP_MAXCHAN 7
|
||||
#define IOP_MAXMSG 8
|
||||
#define IOP_MSGLEN 32
|
||||
#define IOP_MSGBUFLEN (IOP_MSGLEN * IOP_MAXCHAN)
|
||||
|
||||
#define IOP_MSG_IDLE 0 /* idle */
|
||||
#define IOP_MSG_NEW 1 /* new message sent */
|
||||
#define IOP_MSG_RECEIVED 2 /* message received; processing */
|
||||
#define IOP_MSG_COMPLETE 3 /* message processing complete */
|
||||
|
||||
#define IOP_ADDR_MAX_SEND_CHAN 0x200
|
||||
#define IOP_ADDR_SEND_STATE 0x201
|
||||
#define IOP_ADDR_PATCH_CTRL 0x21F
|
||||
#define IOP_ADDR_SEND_MSG 0x220
|
||||
#define IOP_ADDR_MAX_RECV_CHAN 0x300
|
||||
#define IOP_ADDR_RECV_STATE 0x301
|
||||
#define IOP_ADDR_ALIVE 0x31F
|
||||
#define IOP_ADDR_RECV_MSG 0x320
|
||||
|
||||
typedef struct {
|
||||
u_char pad1[0x200];
|
||||
u_char max_send_chan; /* maximum send channel # */
|
||||
u_char send_state[IOP_MAXCHAN]; /* send channel states */
|
||||
u_char pad2[23];
|
||||
u_char patch_ctrl; /* patch control flag */
|
||||
u_char send_msg[IOP_MSGBUFLEN]; /* send channel message data */
|
||||
u_char max_recv_chan; /* max. receive channel # */
|
||||
u_char recv_state[IOP_MAXCHAN]; /* receive channel states */
|
||||
u_char pad3[23];
|
||||
u_char alive; /* IOP alive flag */
|
||||
u_char recv_msg[IOP_MSGBUFLEN]; /* receive channel msg data */
|
||||
} IOPK;
|
||||
|
||||
struct iop_msg;
|
||||
struct _s_IOP;
|
||||
|
||||
typedef void (*iop_msg_handler)(struct _s_IOP *iop, struct iop_msg *);
|
||||
|
||||
struct iop_msg {
|
||||
SIMPLEQ_ENTRY(iop_msg) iopm;
|
||||
int channel;
|
||||
int status;
|
||||
u_char msg[IOP_MSGLEN];
|
||||
|
||||
/* The routine that will handle the message */
|
||||
iop_msg_handler handler;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
#define IOP_MSGSTAT_IDLE 0 /* Message unused (invalid) */
|
||||
#define IOP_MSGSTAT_QUEUED 1 /* Message queued for send */
|
||||
#define IOP_MSGSTAT_SENDING 2 /* Message on IOP */
|
||||
#define IOP_MSGSTAT_SENT 3 /* Message complete */
|
||||
#define IOP_MSGSTAT_RECEIVING 4 /* Top of receive queue */
|
||||
#define IOP_MSGSTAT_RECEIVED 5 /* Msg received */
|
||||
#define IOP_MSGSTAT_UNEXPECTED 6 /* Unexpected msg received */
|
||||
|
||||
typedef struct _s_IOP {
|
||||
IOPHW *iop;
|
||||
struct pool pool;
|
||||
SIMPLEQ_HEAD(, iop_msg) sendq[IOP_MAXCHAN];
|
||||
SIMPLEQ_HEAD(, iop_msg) recvq[IOP_MAXCHAN];
|
||||
iop_msg_handler listeners[IOP_MAXCHAN];
|
||||
void *listener_data[IOP_MAXCHAN];
|
||||
struct iop_msg unsolicited_msg;
|
||||
} IOP;
|
||||
|
||||
#define IOP_LOADADDR(ioph,addr) (ioph->ram_lo = addr & 0xff, \
|
||||
ioph->ram_hi = (addr >> 8) & 0xff)
|
||||
|
||||
void iop_init __P((int fullinit));
|
||||
void iop_upload __P((int iop, u_char *mem, u_long nb, u_long iopbase));
|
||||
void iop_download __P((int iop, u_char *mem, u_long nb, u_long iopbase));
|
||||
int iop_send_msg __P((int iopn, int chan, u_char *msg, int msglen,
|
||||
iop_msg_handler handler, void *udata));
|
||||
int iop_queue_receipt __P((int iopn, int chan, iop_msg_handler handler,
|
||||
void *user_data));
|
||||
int iop_register_listener __P((int iopn, int chan, iop_msg_handler handler,
|
||||
void *user_data));
|
||||
|
||||
/* ADB support */
|
||||
#define IOP_CHAN_ADB 2
|
||||
|
||||
#define IOP_ADB_FL_EXPLICIT 0x80 /* Non-zero if explicit command */
|
||||
#define IOP_ADB_FL_AUTOPOLL 0x40 /* Auto/SRQ polling enabled */
|
||||
#define IOP_ADB_FL_SRQ 0x04 /* SRQ detected */
|
||||
#define IOP_ADB_FL_TIMEOUT 0x02 /* Non-zero if timeout */
|
||||
|
||||
/*
|
||||
* The structure of an ADB packet to/from the IOP is:
|
||||
* Flag byte (values above)
|
||||
* Count of bytes in data
|
||||
* Command byte
|
||||
* Data (optional)
|
||||
*/
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: viareg.h,v 1.11 1999/02/20 09:57:35 scottr Exp $ */
|
||||
/* $NetBSD: viareg.h,v 1.12 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
@ -57,6 +57,7 @@
|
||||
#define DB1I_Par_Err 0x80
|
||||
#define DB1O_vSndEnb 0x80
|
||||
#define DB1O_Par_Enb 0x40
|
||||
#define DB1O_AuxIntEnb 0x40 /* 0 = enabled, 1 = disabled */
|
||||
#define DB1O_vFDesk2 0x20
|
||||
#define DB1O_vFDesk1 0x10
|
||||
#define DB1I_vFDBInt 0x08
|
||||
@ -143,8 +144,10 @@
|
||||
extern volatile unsigned char *Via1Base;
|
||||
extern volatile unsigned char *Via2Base; /* init in VIA_Initialize */
|
||||
#define VIA1_addr Via1Base /* at PA 0x50f00000 */
|
||||
#define VIA2OFF 1 /* VIA2 addr = VIA1_addr * 0x2000 */
|
||||
#define RBVOFF 0x13 /* RBV addr = VIA1_addr * 0x13000 */
|
||||
|
||||
#define VIA2OFF 1 /* VIA2 addr = VIA1_addr + 0x2000 */
|
||||
#define RBVOFF 0x13 /* RBV addr = VIA1_addr + 0x26000 */
|
||||
#define OSSOFF 0xd /* OSS addr = VIA1_addr + 0x1A000 */
|
||||
|
||||
#define VIA1 0
|
||||
extern int VIA2;
|
||||
@ -160,7 +163,7 @@ extern int VIA2;
|
||||
#define vT1LH 0x0e00
|
||||
#define vT2C 0x1000
|
||||
#define vT2CH 0x1200
|
||||
#define vSR 0x1400 /* shift register */
|
||||
#define vSR 0x1400 /* shift register */
|
||||
#define vACR 0x1600 /* aux control register */
|
||||
#define vPCR 0x1800 /* peripheral control register */
|
||||
#define vIFR 0x1a00 /* interrupt flag register */
|
||||
@ -184,6 +187,13 @@ extern int VIA2;
|
||||
#define RBVMonIDStd 0x30 /* 12 inch BW or 13 inch color */
|
||||
#define RBVMonIDNone 0x38 /* No monitor connected */
|
||||
|
||||
/* OSS registers */
|
||||
#define OSS_IFR 0x202
|
||||
#define OSS_PENDING_IRQ (*(volatile u_short *)(Via2Base + (OSS_IFR)))
|
||||
|
||||
#define OSS_oRCR 0x204
|
||||
#define OSS_POWEROFF 0x80
|
||||
|
||||
#define via_reg(v, r) (*(Via1Base+(v)*0x2000+(r)))
|
||||
#define via2_reg(r) (*(Via2Base+(r)))
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: intr.c,v 1.4 1999/03/24 05:51:03 mrg Exp $ */
|
||||
/* $NetBSD: intr.c,v 1.5 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
|
||||
@ -92,8 +92,8 @@ int intr_debug = 0;
|
||||
|
||||
/*
|
||||
* Some of the below are not used yet, but might be used someday on the
|
||||
* Q700/900/950 where the interrupt controller may be reprogrammed to
|
||||
* interrupt on different levels as listed in locore.s
|
||||
* IIfx/Q700/900/950/etc. where the interrupt controller may be reprogrammed
|
||||
* to interrupt on different levels as listed in locore.s
|
||||
*/
|
||||
u_short mac68k_ttyipl;
|
||||
u_short mac68k_bioipl;
|
||||
@ -108,23 +108,59 @@ extern int intrcnt[]; /* from locore.s */
|
||||
|
||||
void intr_computeipl __P((void));
|
||||
|
||||
#define MAX_INAME_LENGTH 53
|
||||
#define STD_INAMES \
|
||||
"spur\0via1\0via2\0unused1\0scc\0unused2\0unused3\0nmi\0clock\0"
|
||||
#define AUX_INAMES \
|
||||
"spur\0soft\0via2\0ethernet\0scc\0sound\0via1\0nmi\0clock\0 "
|
||||
#define AV_INAMES \
|
||||
"spur\0via1\0via2\0ethernet\0scc\0dsp\0unused1\0nmi\0clock\0 "
|
||||
|
||||
void
|
||||
intr_init()
|
||||
{
|
||||
/* Standard spl(9) interrupt priorities */
|
||||
mac68k_ttyipl = (PSL_S | PSL_IPL1);
|
||||
mac68k_bioipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_netipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_impipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_statclockipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_clockipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_schedipl = (PSL_S | PSL_IPL3);
|
||||
extern long intrnames;
|
||||
char *inames, *g_inames;
|
||||
|
||||
/* Non-standard interrupt priority */
|
||||
mac68k_audioipl = (PSL_S | PSL_IPL2);
|
||||
g_inames = (char *) &intrnames;
|
||||
if (mac68k_machine.aux_interrupts) {
|
||||
|
||||
if (current_mac_model->class == MACH_CLASSAV)
|
||||
mac68k_bioipl = mac68k_netipl = (PSL_S | PSL_IPL4);
|
||||
inames = AUX_INAMES;
|
||||
|
||||
/* Standard spl(9) interrupt priorities */
|
||||
mac68k_ttyipl = (PSL_S | PSL_IPL1);
|
||||
mac68k_bioipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_netipl = (PSL_S | PSL_IPL3);
|
||||
mac68k_impipl = (PSL_S | PSL_IPL6);
|
||||
mac68k_statclockipl = (PSL_S | PSL_IPL6);
|
||||
mac68k_clockipl = (PSL_S | PSL_IPL6);
|
||||
mac68k_schedipl = (PSL_S | PSL_IPL4);
|
||||
|
||||
/* Non-standard interrupt priority */
|
||||
mac68k_audioipl = (PSL_S | PSL_IPL5);
|
||||
|
||||
} else {
|
||||
inames = STD_INAMES;
|
||||
|
||||
/* Standard spl(9) interrupt priorities */
|
||||
mac68k_ttyipl = (PSL_S | PSL_IPL1);
|
||||
mac68k_bioipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_netipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_impipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_statclockipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_clockipl = (PSL_S | PSL_IPL2);
|
||||
mac68k_schedipl = (PSL_S | PSL_IPL3);
|
||||
|
||||
/* Non-standard interrupt priority */
|
||||
mac68k_audioipl = (PSL_S | PSL_IPL2);
|
||||
|
||||
if (current_mac_model->class == MACH_CLASSAV) {
|
||||
inames = AV_INAMES;
|
||||
mac68k_bioipl = mac68k_netipl = (PSL_S | PSL_IPL4);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(g_inames, inames, MAX_INAME_LENGTH);
|
||||
|
||||
intr_computeipl();
|
||||
}
|
||||
|
441
sys/arch/mac68k/mac68k/iop.c
Normal file
441
sys/arch/mac68k/mac68k/iop.c
Normal file
@ -0,0 +1,441 @@
|
||||
/* $NetBSD: iop.c,v 1.1 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* This code handles VIA, RBV, and OSS functionality.
|
||||
*/
|
||||
|
||||
#include "opt_mac68k.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/pool.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/frame.h>
|
||||
|
||||
#include <machine/iopreg.h>
|
||||
#include <machine/viareg.h>
|
||||
|
||||
static IOP mac68k_iops[2];
|
||||
|
||||
static void iopism_hand __P((void *arg));
|
||||
static void load_msg_to_iop __P((IOPHW *ioph, struct iop_msg *msg));
|
||||
static void iop_message_sent __P((IOP *iop, int chan));
|
||||
static void receive_iop_message __P((IOP *iop, int chan));
|
||||
static void default_listener __P((IOP *iop, struct iop_msg *msg));
|
||||
|
||||
static __inline__ int iop_read1 __P((IOPHW *ioph, u_long addr));
|
||||
static __inline__ void iop_write1 __P((IOPHW *ioph, u_long addr, u_char data));
|
||||
static __inline__ void _iop_upload __P((IOPHW *, u_char *, u_long, u_long));
|
||||
static __inline__ void _iop_download __P((IOPHW *, u_char *, u_long, u_long));
|
||||
|
||||
static __inline__ int
|
||||
iop_read1(ioph, iopbase)
|
||||
IOPHW *ioph;
|
||||
u_long iopbase;
|
||||
{
|
||||
IOP_LOADADDR(ioph, iopbase);
|
||||
return ioph->data;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
iop_write1(ioph, iopbase, data)
|
||||
IOPHW *ioph;
|
||||
u_long iopbase;
|
||||
u_char data;
|
||||
{
|
||||
IOP_LOADADDR(ioph, iopbase);
|
||||
ioph->data = data;
|
||||
}
|
||||
|
||||
static void
|
||||
default_listener(iop, msg)
|
||||
IOP *iop;
|
||||
struct iop_msg *msg;
|
||||
{
|
||||
printf("unsolicited message on channel %d.\n", msg->channel);
|
||||
}
|
||||
|
||||
void
|
||||
iop_init(fullinit)
|
||||
int fullinit;
|
||||
{
|
||||
IOPHW *ioph;
|
||||
IOP *iop;
|
||||
int i, ii;
|
||||
|
||||
switch (current_mac_model->machineid) {
|
||||
default:
|
||||
return;
|
||||
case MACH_MACQ900:
|
||||
case MACH_MACQ950:
|
||||
mac68k_iops[SCC_IOP].iop = (IOPHW *)
|
||||
((u_char *)IOBase + 0xc000);
|
||||
mac68k_iops[ISM_IOP].iop = (IOPHW *)
|
||||
((u_char *)IOBase + 0x1e000);
|
||||
break;
|
||||
case MACH_MACIIFX:
|
||||
mac68k_iops[SCC_IOP].iop = (IOPHW *)
|
||||
((u_char *)IOBase + 0x4000);
|
||||
mac68k_iops[ISM_IOP].iop = (IOPHW *)
|
||||
((u_char *)IOBase + 0x12000);
|
||||
break;
|
||||
}
|
||||
|
||||
ioph = mac68k_iops[SCC_IOP].iop;
|
||||
ioph->control_status = 0x82; /* Reset */
|
||||
ioph->control_status = IOP_BYPASS; /* Set to bypass */
|
||||
|
||||
ioph = mac68k_iops[ISM_IOP].iop;
|
||||
ioph->control_status = 0x82; /* Reset */
|
||||
|
||||
if (!fullinit) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ii = 0 ; ii < 2 ; ii++) {
|
||||
iop = &mac68k_iops[ii];
|
||||
ioph = iop->iop;
|
||||
for (i = 0; i < IOP_MAXCHAN; i++) {
|
||||
SIMPLEQ_INIT(&iop->sendq[i]);
|
||||
SIMPLEQ_INIT(&iop->recvq[i]);
|
||||
iop->listeners[i] = default_listener;
|
||||
iop->listener_data[i] = NULL;
|
||||
}
|
||||
IOP_LOADADDR(ioph, 0x200);
|
||||
for (i = 0x200; i > 0; i--) {
|
||||
ioph->data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (current_mac_model->machineid) {
|
||||
default:
|
||||
return;
|
||||
case MACH_MACQ900:
|
||||
case MACH_MACQ950:
|
||||
#ifdef notyet_maybe_not_ever
|
||||
iop = &mac68k_iops[SCC_IOP];
|
||||
intr_establish(iopscc_hand, iop, 4);
|
||||
#endif
|
||||
iop = &mac68k_iops[ISM_IOP];
|
||||
via1_register_irq(2, iopism_hand, iop);
|
||||
via_reg(VIA1, vIER) = 0x84;
|
||||
via_reg(VIA1, vIFR) = 0x04;
|
||||
break;
|
||||
case MACH_MACIIFX:
|
||||
/* oss_register_irq(2, iopism_hand, &ioph); */
|
||||
break;
|
||||
}
|
||||
|
||||
iop = &mac68k_iops[SCC_IOP];
|
||||
ioph = iop->iop;
|
||||
printf("SCC IOP base: 0x%x\n", (unsigned) ioph);
|
||||
pool_init(&iop->pool, sizeof(struct iop_msg), 0, 0, 0, "mac68k_iop1",
|
||||
0, NULL, NULL, M_DEVBUF);
|
||||
ioph->control_status = 0x80 | IOP_BYPASS;
|
||||
|
||||
iop = &mac68k_iops[ISM_IOP];
|
||||
ioph = iop->iop;
|
||||
printf("ISM IOP base: 0x%x\n", (unsigned) ioph);
|
||||
pool_init(&iop->pool, sizeof(struct iop_msg), 0, 0, 0, "mac68k_iop2",
|
||||
0, NULL, NULL, M_DEVBUF);
|
||||
iop_write1(ioph, IOP_ADDR_ALIVE, 0);
|
||||
|
||||
printf("OLD cs0: 0x%x\n", (unsigned) ioph->control_status);
|
||||
|
||||
iop_write1(ioph, IOP_ADDR_MAX_SEND_CHAN, 7);
|
||||
iop_write1(ioph, IOP_ADDR_MAX_RECV_CHAN, 7);
|
||||
ioph->control_status = 0x80 | IOP_CS_RUN | IOP_CS_AUTOINC;
|
||||
iop_write1(ioph, IOP_ADDR_ALIVE, 0);
|
||||
{unsigned cs, c2;
|
||||
cs = (unsigned) ioph->control_status;
|
||||
printf("OLD cs1: 0x%x\n", cs);
|
||||
cs = 0;
|
||||
do { c2 = iop_read1(ioph, IOP_ADDR_ALIVE); cs++; } while (c2 != 0xff);
|
||||
printf("OLD cs2: 0x%x (i = %d)\n", (unsigned) ioph->control_status, cs);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
_iop_upload(ioph, mem, nb, iopbase)
|
||||
IOPHW *ioph;
|
||||
u_char *mem;
|
||||
u_long nb, iopbase;
|
||||
{
|
||||
IOP_LOADADDR(ioph, iopbase);
|
||||
while (nb--) {
|
||||
ioph->data = *mem++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iop_upload(iopn, mem, nb, iopbase)
|
||||
int iopn;
|
||||
u_char *mem;
|
||||
u_long nb, iopbase;
|
||||
{
|
||||
IOPHW *ioph;
|
||||
|
||||
if (iopn & ~1) return;
|
||||
ioph = mac68k_iops[iopn].iop;
|
||||
if (!ioph) return;
|
||||
|
||||
_iop_upload(ioph, mem, nb, iopbase);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
_iop_download(ioph, mem, nb, iopbase)
|
||||
IOPHW *ioph;
|
||||
u_char *mem;
|
||||
u_long nb, iopbase;
|
||||
{
|
||||
IOP_LOADADDR(ioph, iopbase);
|
||||
while (nb--) {
|
||||
*mem++ = ioph->data;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iop_download(iopn, mem, nb, iopbase)
|
||||
int iopn;
|
||||
u_char *mem;
|
||||
u_long nb, iopbase;
|
||||
{
|
||||
IOPHW *ioph;
|
||||
|
||||
if (iopn & ~1) return;
|
||||
ioph = mac68k_iops[iopn].iop;
|
||||
if (!ioph) return;
|
||||
|
||||
_iop_download(ioph, mem, nb, iopbase);
|
||||
}
|
||||
|
||||
static void
|
||||
iopism_hand(arg)
|
||||
void *arg;
|
||||
{
|
||||
IOP *iop;
|
||||
IOPHW *ioph;
|
||||
u_char cs;
|
||||
u_char m, s;
|
||||
int i;
|
||||
|
||||
iop = (IOP *) arg;
|
||||
ioph = iop->iop;
|
||||
cs = ioph->control_status;
|
||||
|
||||
printf("iopism_hand.\n");
|
||||
|
||||
#if DIAGNOSTIC
|
||||
if ((cs & IOP_INTERRUPT) == 0) {
|
||||
printf("IOP_ISM interrupt--no interrupt!? (cs 0x%x)\n",
|
||||
(u_int) cs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Scan send queues for complete messages.
|
||||
*/
|
||||
if (cs & IOP_CS_INT0) {
|
||||
ioph->control_status |= IOP_CS_INT0;
|
||||
m = iop_read1(ioph, IOP_ADDR_MAX_SEND_CHAN);
|
||||
for (i = 0; i < m; i++) {
|
||||
s = iop_read1(ioph, IOP_ADDR_SEND_STATE + i);
|
||||
if (s == IOP_MSG_COMPLETE) {
|
||||
iop_message_sent(iop, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan receive queue for new messages.
|
||||
*/
|
||||
if (cs & IOP_CS_INT1) {
|
||||
ioph->control_status |= IOP_CS_INT1;
|
||||
m = iop_read1(ioph, IOP_ADDR_MAX_RECV_CHAN);
|
||||
for (i = 0; i < m; i++) {
|
||||
s = iop_read1(ioph, IOP_ADDR_RECV_STATE + i);
|
||||
if (s == IOP_MSG_NEW) {
|
||||
receive_iop_message(iop, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
load_msg_to_iop(ioph, msg)
|
||||
IOPHW *ioph;
|
||||
struct iop_msg *msg;
|
||||
{
|
||||
int offset;
|
||||
|
||||
msg->status = IOP_MSGSTAT_SENDING;
|
||||
offset = IOP_ADDR_SEND_MSG + msg->channel * IOP_MSGLEN;
|
||||
_iop_upload(ioph, msg->msg, IOP_MSGLEN, offset);
|
||||
iop_write1(ioph, IOP_ADDR_SEND_STATE + msg->channel, IOP_MSG_NEW);
|
||||
|
||||
/* ioph->control_status |= IOP_CS_IRQ; */
|
||||
ioph->control_status = (ioph->control_status & 0xfe) | IOP_CS_IRQ;
|
||||
}
|
||||
|
||||
static void
|
||||
iop_message_sent(iop, chan)
|
||||
IOP *iop;
|
||||
int chan;
|
||||
{
|
||||
IOPHW *ioph;
|
||||
struct iop_msg *msg;
|
||||
|
||||
ioph = iop->iop;
|
||||
|
||||
msg = SIMPLEQ_FIRST(&iop->sendq[chan]);
|
||||
msg->status = IOP_MSGSTAT_SENT;
|
||||
SIMPLEQ_REMOVE_HEAD(&iop->sendq[chan], msg, iopm);
|
||||
|
||||
msg->handler(iop, msg);
|
||||
|
||||
pool_put(&iop->pool, msg);
|
||||
|
||||
if (!(msg = SIMPLEQ_FIRST(&iop->sendq[chan]))) {
|
||||
iop_write1(ioph, IOP_ADDR_SEND_STATE + chan, IOP_MSG_IDLE);
|
||||
} else {
|
||||
load_msg_to_iop(ioph, msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
receive_iop_message(iop, chan)
|
||||
IOP *iop;
|
||||
int chan;
|
||||
{
|
||||
IOPHW *ioph;
|
||||
struct iop_msg *msg;
|
||||
int offset;
|
||||
|
||||
msg = SIMPLEQ_FIRST(&iop->recvq[chan]);
|
||||
if (msg) {
|
||||
SIMPLEQ_REMOVE_HEAD(&iop->recvq[chan], msg, iopm);
|
||||
} else {
|
||||
msg = &iop->unsolicited_msg;
|
||||
msg->channel = chan;
|
||||
msg->handler = iop->listeners[chan];
|
||||
msg->user_data = iop->listener_data[chan];
|
||||
}
|
||||
|
||||
offset = IOP_ADDR_RECV_MSG + chan * IOP_MSGLEN;
|
||||
_iop_download(ioph, msg->msg, IOP_MSGLEN, offset);
|
||||
msg->status = IOP_MSGSTAT_RECEIVED;
|
||||
|
||||
msg->handler(iop, msg);
|
||||
|
||||
if (msg != &iop->unsolicited_msg)
|
||||
pool_put(&iop->pool, msg);
|
||||
|
||||
iop_write1(ioph, IOP_ADDR_RECV_STATE + chan, IOP_MSG_COMPLETE);
|
||||
ioph->control_status |= IOP_CS_IRQ;
|
||||
|
||||
if ((msg = SIMPLEQ_FIRST(&iop->recvq[chan])) != NULL) {
|
||||
msg->status = IOP_MSGSTAT_RECEIVING;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
iop_send_msg(iopn, chan, mesg, msglen, handler, user_data)
|
||||
int iopn, chan, msglen;
|
||||
u_char *mesg;
|
||||
iop_msg_handler handler;
|
||||
void *user_data;
|
||||
{
|
||||
struct iop_msg *msg;
|
||||
IOP *iop;
|
||||
int s;
|
||||
|
||||
if (iopn & ~1) return -1;
|
||||
iop = &mac68k_iops[iopn];
|
||||
if (!iop) return -1;
|
||||
if (msglen > IOP_MSGLEN) return -1;
|
||||
|
||||
msg = (struct iop_msg *) pool_get(&iop->pool, PR_WAITOK);
|
||||
if (msg == NULL) return -1;
|
||||
printf("have msg buffer for IOP: %#x\n", (unsigned) iop->iop);
|
||||
msg->channel = chan;
|
||||
if (msglen < IOP_MSGLEN) memset(msg->msg, '\0', IOP_MSGLEN);
|
||||
memcpy(msg->msg, mesg, msglen);
|
||||
msg->handler = handler;
|
||||
msg->user_data = user_data;
|
||||
|
||||
msg->status = IOP_MSGSTAT_QUEUED;
|
||||
|
||||
s = splhigh();
|
||||
SIMPLEQ_INSERT_TAIL(&iop->sendq[chan], msg, iopm);
|
||||
if (msg == SIMPLEQ_FIRST(&iop->sendq[chan])) {
|
||||
msg->status = IOP_MSGSTAT_SENDING;
|
||||
printf("loading msg to iop: cs: 0x%x V1-%x- ", (unsigned) iop->iop->control_status, (unsigned)via_reg(VIA1, vIFR));
|
||||
load_msg_to_iop(iop->iop, msg);
|
||||
printf("msg loaded to iop: cs: 0x%x V1-%x- ", (unsigned) iop->iop->control_status, (unsigned)via_reg(VIA1, vIFR));
|
||||
}
|
||||
|
||||
{int i; for (i=0;i<100;i++) {
|
||||
printf(" cs: 0x%x V1-%x- ", (unsigned) iop->iop->control_status, (unsigned)via_reg(VIA1, vIFR));
|
||||
delay(1000);
|
||||
}}
|
||||
splx(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iop_queue_receipt(iopn, chan, handler, user_data)
|
||||
int iopn, chan;
|
||||
iop_msg_handler handler;
|
||||
void *user_data;
|
||||
{
|
||||
struct iop_msg *msg;
|
||||
IOP *iop;
|
||||
int s;
|
||||
|
||||
if (iopn & ~1) return -1;
|
||||
iop = &mac68k_iops[iopn];
|
||||
if (!iop) return -1;
|
||||
|
||||
msg = (struct iop_msg *) pool_get(&iop->pool, PR_WAITOK);
|
||||
if (msg == NULL) return -1;
|
||||
msg->channel = chan;
|
||||
msg->handler = handler;
|
||||
msg->user_data = user_data;
|
||||
|
||||
msg->status = IOP_MSGSTAT_QUEUED;
|
||||
|
||||
s = splhigh();
|
||||
SIMPLEQ_INSERT_TAIL(&iop->recvq[chan], msg, iopm);
|
||||
if (msg == SIMPLEQ_FIRST(&iop->recvq[chan])) {
|
||||
msg->status = IOP_MSGSTAT_RECEIVING;
|
||||
}
|
||||
splx(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iop_register_listener(iopn, chan, handler, user_data)
|
||||
int iopn, chan;
|
||||
iop_msg_handler handler;
|
||||
void *user_data;
|
||||
{
|
||||
IOP *iop;
|
||||
int s;
|
||||
|
||||
if (iopn & ~1) return -1;
|
||||
iop = &mac68k_iops[iopn];
|
||||
if (!iop) return -1;
|
||||
|
||||
s = splhigh();
|
||||
iop->listeners[chan] = handler;
|
||||
iop->listener_data[chan] = user_data;
|
||||
splx(s);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.s,v 1.117 1999/06/11 06:51:39 scottr Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.118 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
@ -811,31 +811,6 @@ ENTRY_NOPROFILE(spurintr)
|
||||
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
|
||||
jra _ASM_LABEL(rei)
|
||||
|
||||
ENTRY_NOPROFILE(lev1intr)
|
||||
addql #1,_C_LABEL(intrcnt)+4
|
||||
clrl sp@-
|
||||
moveml #0xFFFF,sp@-
|
||||
movl sp, sp@-
|
||||
jbsr _C_LABEL(via1_intr)
|
||||
addql #4,sp
|
||||
moveml sp@+,#0xFFFF
|
||||
addql #4,sp
|
||||
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
|
||||
jra _ASM_LABEL(rei)
|
||||
|
||||
ENTRY_NOPROFILE(lev2intr)
|
||||
addql #1,_C_LABEL(intrcnt)+8
|
||||
clrl sp@-
|
||||
moveml #0xFFFF,sp@-
|
||||
movl sp, sp@-
|
||||
movl _C_LABEL(real_via2_intr),a2
|
||||
jbsr a2@
|
||||
addql #4,sp
|
||||
moveml sp@+,#0xFFFF
|
||||
addql #4,sp
|
||||
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
|
||||
jra _ASM_LABEL(rei)
|
||||
|
||||
ENTRY_NOPROFILE(intrhand) /* levels 3 through 6 */
|
||||
INTERRUPT_SAVEREG
|
||||
movw sp@(22),sp@- | push exception vector info
|
||||
@ -867,19 +842,21 @@ ENTRY_NOPROFILE(lev7intr)
|
||||
ENTRY_NOPROFILE(rtclock_intr)
|
||||
movl d2,sp@- | save d2
|
||||
movw sr,d2 | save SPL
|
||||
movw #SPL2,sr | raise SPL to splclock()
|
||||
movl a6@(8),a1 | get pointer to frame in via1_intr
|
||||
movl a1@(64),sp@- | push ps
|
||||
movl a1@(68),sp@- | push pc
|
||||
movl sp,sp@- | push pointer to ps, pc
|
||||
movw _C_LABEL(mac68k_clockipl),sr
|
||||
| raise SPL to splclock()
|
||||
movl a6@,a1 | unwind to frame in intr_dispatch
|
||||
lea a1@(28),a1 | push pointer to interrupt frame
|
||||
movl a1,sp@- | 28 = 16 for regs in intrhand,
|
||||
| + 4 for args to intr_dispatch
|
||||
| + 4 for return address to intrhand
|
||||
| + 4 for value of A6
|
||||
jbsr _C_LABEL(hardclock) | call generic clock int routine
|
||||
lea sp@(12),sp | pop params
|
||||
addql #4,sp | pop param
|
||||
jbsr _C_LABEL(mrg_VBLQueue) | give programs in the VBLqueue a chance
|
||||
addql #1,_C_LABEL(intrcnt)+20
|
||||
addql #1,_C_LABEL(intrcnt)+32
|
||||
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
|
||||
movw d2,sr | restore SPL
|
||||
movl sp@+,d2 | restore d2
|
||||
movl #1,d0 | clock taken care of
|
||||
rts | go back from whence we came
|
||||
|
||||
/*
|
||||
@ -1917,18 +1894,18 @@ ASGLOBAL(fullcflush)
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
/* interrupt counters */
|
||||
/* interrupt counters -- leave some space for overriding the names */
|
||||
|
||||
GLOBAL(intrnames)
|
||||
.asciz "spur"
|
||||
.asciz "via1"
|
||||
.asciz "via2"
|
||||
.asciz "scc"
|
||||
.asciz "nmi"
|
||||
.asciz "clock"
|
||||
.asciz "unused1"
|
||||
.asciz "unused2"
|
||||
.asciz "unused3"
|
||||
.asciz "spur "
|
||||
.asciz "via1 "
|
||||
.asciz "via2 "
|
||||
.asciz "unused1 "
|
||||
.asciz "scc "
|
||||
.asciz "unused2 "
|
||||
.asciz "unused3 "
|
||||
.asciz "nmi "
|
||||
.asciz "clock "
|
||||
GLOBAL(eintrnames)
|
||||
.even
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.236 1999/06/26 18:29:28 briggs Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.237 1999/06/28 01:56:57 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
@ -129,6 +129,7 @@
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/iopreg.h>
|
||||
#include <machine/psc.h>
|
||||
#include <machine/viareg.h>
|
||||
#include <mac68k/mac68k/macrom.h>
|
||||
@ -266,6 +267,9 @@ mac68k_init()
|
||||
/* Initialize the VIAs */
|
||||
via_init();
|
||||
|
||||
/* Initialize the IOPs (if present) */
|
||||
iop_init(1);
|
||||
|
||||
/* Initialize the PSC (if present) */
|
||||
psc_init();
|
||||
|
||||
@ -2076,6 +2080,10 @@ setmachdep()
|
||||
cpui = &(cpu_models[mac68k_machine.cpu_model_index]);
|
||||
current_mac_model = cpui;
|
||||
|
||||
mac68k_machine.via1_ipl = 1;
|
||||
mac68k_machine.via2_ipl = 2;
|
||||
mac68k_machine.aux_interrupts = 0;
|
||||
|
||||
/*
|
||||
* Set up any machine specific stuff that we have to before
|
||||
* ANYTHING else happens
|
||||
@ -2122,7 +2130,33 @@ setmachdep()
|
||||
break;
|
||||
case MACH_CLASSQ:
|
||||
case MACH_CLASSQ2:
|
||||
VIA2 = 1;
|
||||
IOBase = 0x50f00000;
|
||||
Via1Base = (volatile u_char *)IOBase;
|
||||
mac68k_machine.sonic = 1;
|
||||
mac68k_machine.scsi96 = 1;
|
||||
mac68k_machine.zs_chip = 0;
|
||||
via_reg(VIA1, vIER) = 0x7f; /* disable VIA1 int */
|
||||
via_reg(VIA2, vIER) = 0x7f; /* disable VIA2 int */
|
||||
|
||||
#if 1
|
||||
switch (current_mac_model->machineid) {
|
||||
default:
|
||||
/* case MACH_MACQ900: These three, at least, support the
|
||||
case MACH_MACQ950: A/UX interrupts. What Quadras don't?
|
||||
case MACH_MACQ700: */
|
||||
/* Enable A/UX interrupt scheme */
|
||||
mac68k_machine.aux_interrupts = 1;
|
||||
|
||||
via_reg(VIA1, vBufB) &= (0xff ^ DB1O_AuxIntEnb);
|
||||
via_reg(VIA1, vDirB) |= DB1O_AuxIntEnb;
|
||||
mac68k_machine.via1_ipl = 6;
|
||||
mac68k_machine.via2_ipl = 2;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case MACH_CLASSAV:
|
||||
case MACH_CLASSP580:
|
||||
VIA2 = 1;
|
||||
@ -2214,6 +2248,7 @@ mac68k_set_io_offsets(base)
|
||||
case MACH_MACQ950:
|
||||
mac68k_machine.scsi96_2 = 1;
|
||||
sccA = (volatile u_char *)base + 0xc020;
|
||||
iop_init(0); /* For console */
|
||||
break;
|
||||
case MACH_MACQ700:
|
||||
break;
|
||||
@ -2267,6 +2302,7 @@ mac68k_set_io_offsets(base)
|
||||
Via1Base = (volatile u_char *)base;
|
||||
sccA = (volatile u_char *)base + 0x4020;
|
||||
SCSIBase = base;
|
||||
iop_init(0); /* For console */
|
||||
break;
|
||||
default:
|
||||
case MACH_CLASSH:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pram.c,v 1.17 1998/02/21 00:37:08 scottr Exp $ */
|
||||
/* $NetBSD: pram.c,v 1.18 1999/06/28 01:56:58 briggs Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
@ -176,6 +176,7 @@ getPramTime(void)
|
||||
unsigned long time;
|
||||
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_IOP:
|
||||
case ADB_HW_II: /* access PRAM via VIA interface */
|
||||
time = (long)getPramTimeII();
|
||||
return time;
|
||||
@ -207,6 +208,7 @@ void
|
||||
setPramTime(unsigned long time)
|
||||
{
|
||||
switch (adbHardware) {
|
||||
case ADB_HW_IOP:
|
||||
case ADB_HW_II: /* access PRAM via ADB interface */
|
||||
setPramTimeII(time);
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
| $NetBSD: vectors.s,v 1.13 1998/10/04 23:38:56 thorpej Exp $
|
||||
| $NetBSD: vectors.s,v 1.14 1999/06/28 01:56:58 briggs Exp $
|
||||
|
||||
| Copyright (c) 1988 University of Utah
|
||||
| Copyright (c) 1990 Regents of the University of California.
|
||||
@ -76,8 +76,8 @@ GLOBAL(vectab)
|
||||
VECTOR(badtrap) /* 22: unassigned, reserved */
|
||||
VECTOR(badtrap) /* 23: unassigned, reserved */
|
||||
VECTOR(spurintr) /* 24: spurious interrupt */
|
||||
VECTOR(lev1intr) /* 25: level 1 interrupt autovector */
|
||||
VECTOR(lev2intr) /* 26: level 2 interrupt autovector */
|
||||
VECTOR(intrhand) /* 25: level 1 interrupt autovector */
|
||||
VECTOR(intrhand) /* 26: level 2 interrupt autovector */
|
||||
VECTOR(intrhand) /* 27: level 3 interrupt autovector */
|
||||
VECTOR(intrhand) /* 28: level 4 interrupt autovector */
|
||||
VECTOR(intrhand) /* 29: level 5 interrupt autovector */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: via.c,v 1.69 1999/02/20 09:57:35 scottr Exp $ */
|
||||
/* $NetBSD: via.c,v 1.70 1999/06/28 01:56:58 briggs Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
@ -46,6 +46,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/viareg.h>
|
||||
|
||||
void mrg_adbintr __P((void *));
|
||||
@ -53,10 +54,10 @@ void mrg_pmintr __P((void *));
|
||||
void rtclock_intr __P((void *));
|
||||
void profclock __P((void *));
|
||||
|
||||
void via1_intr __P((struct frame *));
|
||||
void via2_intr __P((struct frame *));
|
||||
void rbv_intr __P((struct frame *));
|
||||
void oss_intr __P((struct frame *));
|
||||
void via1_intr __P((void *));
|
||||
void via2_intr __P((void *));
|
||||
void rbv_intr __P((void *));
|
||||
void oss_intr __P((void *));
|
||||
void via2_nubus_intr __P((void *));
|
||||
void rbv_nubus_intr __P((void *));
|
||||
|
||||
@ -66,7 +67,6 @@ static void slot_ignore __P((void *));
|
||||
static void slot_noint __P((void *));
|
||||
|
||||
int VIA2 = 1; /* default for II, IIx, IIcx, SE/30. */
|
||||
void (*real_via2_intr) __P((struct frame *));
|
||||
|
||||
/* VIA1 interrupt handler table */
|
||||
void (*via1itab[7]) __P((void *)) = {
|
||||
@ -79,6 +79,17 @@ void (*via1itab[7]) __P((void *)) = {
|
||||
rtclock_intr,
|
||||
};
|
||||
|
||||
/* Arg array for VIA1 interrupts. */
|
||||
void *via1iarg[7] = {
|
||||
(void *)0,
|
||||
(void *)1,
|
||||
(void *)2,
|
||||
(void *)3,
|
||||
(void *)4,
|
||||
(void *)5,
|
||||
(void *)6
|
||||
};
|
||||
|
||||
/* VIA2 interrupt handler table */
|
||||
void (*via2itab[7]) __P((void *)) = {
|
||||
via2_noint,
|
||||
@ -144,6 +155,8 @@ via_init()
|
||||
/* turn off timer latch */
|
||||
via_reg(VIA1, vACR) &= 0x3f;
|
||||
|
||||
intr_establish((int (*)(void *)) via1_intr, NULL, mac68k_machine.via1_ipl);
|
||||
|
||||
if (VIA2 == VIA2OFF) {
|
||||
/* Initialize VIA2 */
|
||||
via2_reg(vT1L) = 0;
|
||||
@ -185,10 +198,15 @@ via_init()
|
||||
break;
|
||||
}
|
||||
|
||||
real_via2_intr = via2_intr;
|
||||
intr_establish((int (*)(void*))via2_intr, NULL,
|
||||
mac68k_machine.via2_ipl);
|
||||
via2itab[1] = via2_nubus_intr;
|
||||
} else if (current_mac_model->class == MACH_CLASSIIfx) { /* OSS */
|
||||
real_via2_intr = oss_intr;
|
||||
volatile u_char *ossintr;
|
||||
ossintr = (volatile u_char *)IOBase + 0x1a006;
|
||||
*ossintr = 0;
|
||||
intr_establish((int (*)(void*))oss_intr, NULL,
|
||||
mac68k_machine.via2_ipl);
|
||||
} else { /* RBV */
|
||||
#ifdef DISABLE_EXT_CACHE
|
||||
if (current_mac_model->class == MACH_CLASSIIci) {
|
||||
@ -198,7 +216,8 @@ via_init()
|
||||
via2_reg(rBufB) |= DB2O_CEnable;
|
||||
}
|
||||
#endif
|
||||
real_via2_intr = rbv_intr;
|
||||
intr_establish((int (*)(void*))rbv_intr, NULL,
|
||||
mac68k_machine.via2_ipl);
|
||||
via2itab[1] = rbv_nubus_intr;
|
||||
add_nubus_intr(0, slot_ignore, NULL);
|
||||
}
|
||||
@ -219,8 +238,8 @@ via_set_modem(onoff)
|
||||
}
|
||||
|
||||
void
|
||||
via1_intr(fp)
|
||||
struct frame *fp;
|
||||
via1_intr(intr_arg)
|
||||
void *intr_arg;
|
||||
{
|
||||
u_int8_t intbits, bitnum;
|
||||
u_int mask;
|
||||
@ -242,16 +261,17 @@ via1_intr(fp)
|
||||
bitnum = 0;
|
||||
do {
|
||||
if (intbits & mask) {
|
||||
via1itab[bitnum]((void *)((int)bitnum));
|
||||
via1itab[bitnum](via1iarg[bitnum]);
|
||||
/* via_reg(VIA1, vIFR) = mask; */
|
||||
}
|
||||
mask <<= 1;
|
||||
} while (intbits >= mask && ++bitnum);
|
||||
++bitnum;
|
||||
} while (intbits >= mask);
|
||||
}
|
||||
|
||||
void
|
||||
via2_intr(fp)
|
||||
struct frame *fp;
|
||||
via2_intr(intr_arg)
|
||||
void *intr_arg;
|
||||
{
|
||||
u_int8_t intbits, bitnum;
|
||||
u_int mask;
|
||||
@ -276,8 +296,8 @@ via2_intr(fp)
|
||||
}
|
||||
|
||||
void
|
||||
rbv_intr(fp)
|
||||
struct frame *fp;
|
||||
rbv_intr(intr_arg)
|
||||
void *intr_arg;
|
||||
{
|
||||
u_int8_t intbits, bitnum;
|
||||
u_int mask;
|
||||
@ -301,8 +321,8 @@ rbv_intr(fp)
|
||||
}
|
||||
|
||||
void
|
||||
oss_intr(fp)
|
||||
struct frame *fp;
|
||||
oss_intr(intr_arg)
|
||||
void *intr_arg;
|
||||
{
|
||||
u_int8_t intbits, bitnum;
|
||||
u_int mask;
|
||||
@ -461,8 +481,15 @@ via_powerdown()
|
||||
if (VIA2 == VIA2OFF) {
|
||||
via2_reg(vDirB) |= 0x04; /* Set write for bit 2 */
|
||||
via2_reg(vBufB) &= ~0x04; /* Shut down */
|
||||
} else if (VIA2 == RBVOFF)
|
||||
} else if (VIA2 == RBVOFF) {
|
||||
via2_reg(rBufB) &= ~0x04;
|
||||
} else if (VIA2 == OSSOFF) {
|
||||
/*
|
||||
* Thanks to Brad Boyer <flar@cegt201.bradley.edu> for the
|
||||
* Linux/mac68k code that I derived this from.
|
||||
*/
|
||||
via2_reg(OSS_oRCR) |= OSS_POWEROFF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -471,10 +498,13 @@ via1_register_irq(irq, irq_func, client_data)
|
||||
void (*irq_func)(void *);
|
||||
void *client_data;
|
||||
{
|
||||
if (irq_func)
|
||||
if (irq_func) {
|
||||
via1itab[irq] = irq_func;
|
||||
else
|
||||
via1iarg[irq] = client_data;
|
||||
} else {
|
||||
via1itab[irq] = via1_noint;
|
||||
via1iarg[irq] = (void *)0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: asc.c,v 1.31 1999/04/22 18:00:34 ender Exp $ */
|
||||
/* $NetBSD: asc.c,v 1.32 1999/06/28 01:56:58 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Scott Reynolds
|
||||
@ -189,7 +189,11 @@ ascattach(parent, self, aux)
|
||||
|
||||
mac68k_set_bell_callback(asc_ring_bell, sc);
|
||||
#if __notyet__
|
||||
via2_register_irq(VIA2_ASC, asc_intr, sc);
|
||||
if (mac68k_machine.aux_interrupts) {
|
||||
intr_establish((int (*)(void *))asc_intr, sc, 5);
|
||||
} else {
|
||||
via2_register_irq(VIA2_ASC, asc_intr, sc);
|
||||
}
|
||||
asc_intr_enable();
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sn_obio.c,v 1.17 1998/07/05 00:51:10 jonathan Exp $ */
|
||||
/* $NetBSD: if_sn_obio.c,v 1.18 1999/06/28 01:56:58 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Allen Briggs
|
||||
@ -186,7 +186,11 @@ sn_obio_attach(parent, self, aux)
|
||||
return;
|
||||
}
|
||||
|
||||
add_nubus_intr(sc->slotno, snintr, (void *)sc);
|
||||
if (mac68k_machine.aux_interrupts) {
|
||||
intr_establish((int (*)(void *))snintr, (void *)sc, 3);
|
||||
} else {
|
||||
add_nubus_intr(sc->slotno, snintr, (void *)sc);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user