A bunch of fixes:
- Make generic console routines not relying on running on master cpu. - Add routine to start console transmitter (after IPI). - Use real IPIs instead of the "console doorbell". - Add routines cpu_send_ipi()/cpu_handle_ipi().
This commit is contained in:
parent
461a7daf74
commit
1da9a91480
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: gencons.c,v 1.33 2001/05/16 05:36:55 matt Exp $ */
|
/* $NetBSD: gencons.c,v 1.34 2001/06/03 15:07:20 ragge Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Gordon W. Ross
|
* Copyright (c) 1994 Gordon W. Ross
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_cputype.h"
|
#include "opt_cputype.h"
|
||||||
|
#include "opt_multiprocessor.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/device.h>
|
#include <sys/device.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
|
||||||
#include <dev/cons.h>
|
#include <dev/cons.h>
|
||||||
|
|
||||||
|
@ -56,7 +58,11 @@
|
||||||
#include <machine/scb.h>
|
#include <machine/scb.h>
|
||||||
#include <machine/../vax/gencons.h>
|
#include <machine/../vax/gencons.h>
|
||||||
|
|
||||||
static struct tty *gencn_tty[4];
|
static struct gc_softc {
|
||||||
|
short alive;
|
||||||
|
short unit;
|
||||||
|
struct tty *gencn_tty;
|
||||||
|
} gc_softc[4];
|
||||||
|
|
||||||
static int consopened = 0;
|
static int consopened = 0;
|
||||||
static int maxttys = 1;
|
static int maxttys = 1;
|
||||||
|
@ -82,10 +88,12 @@ gencnopen(dev_t dev, int flag, int mode, struct proc *p)
|
||||||
if (unit >= maxttys)
|
if (unit >= maxttys)
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
|
|
||||||
if (gencn_tty[unit] == NULL)
|
if (gc_softc[unit].gencn_tty == NULL)
|
||||||
gencn_tty[unit] = ttymalloc();
|
gc_softc[unit].gencn_tty = ttymalloc();
|
||||||
|
|
||||||
tp = gencn_tty[unit];
|
gc_softc[unit].alive = 1;
|
||||||
|
gc_softc[unit].unit = unit;
|
||||||
|
tp = gc_softc[unit].gencn_tty;
|
||||||
|
|
||||||
tp->t_oproc = gencnstart;
|
tp->t_oproc = gencnstart;
|
||||||
tp->t_param = gencnparam;
|
tp->t_param = gencnparam;
|
||||||
|
@ -104,8 +112,6 @@ gencnopen(dev_t dev, int flag, int mode, struct proc *p)
|
||||||
tp->t_state |= TS_CARR_ON;
|
tp->t_state |= TS_CARR_ON;
|
||||||
if (unit == 0)
|
if (unit == 0)
|
||||||
consopened = 1;
|
consopened = 1;
|
||||||
mtpr(GC_RIE, pr_rxcs[unit]); /* Turn on interrupts */
|
|
||||||
mtpr(GC_TIE, pr_txcs[unit]);
|
|
||||||
|
|
||||||
return ((*tp->t_linesw->l_open)(dev, tp));
|
return ((*tp->t_linesw->l_open)(dev, tp));
|
||||||
}
|
}
|
||||||
|
@ -113,7 +119,7 @@ gencnopen(dev_t dev, int flag, int mode, struct proc *p)
|
||||||
int
|
int
|
||||||
gencnclose(dev_t dev, int flag, int mode, struct proc *p)
|
gencnclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||||
{
|
{
|
||||||
struct tty *tp = gencn_tty[minor(dev)];
|
struct tty *tp = gc_softc[minor(dev)].gencn_tty;
|
||||||
|
|
||||||
if (minor(dev) == 0)
|
if (minor(dev) == 0)
|
||||||
consopened = 0;
|
consopened = 0;
|
||||||
|
@ -125,13 +131,13 @@ gencnclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||||
struct tty *
|
struct tty *
|
||||||
gencntty(dev_t dev)
|
gencntty(dev_t dev)
|
||||||
{
|
{
|
||||||
return gencn_tty[minor(dev)];
|
return gc_softc[minor(dev)].gencn_tty;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gencnread(dev_t dev, struct uio *uio, int flag)
|
gencnread(dev_t dev, struct uio *uio, int flag)
|
||||||
{
|
{
|
||||||
struct tty *tp = gencn_tty[minor(dev)];
|
struct tty *tp = gc_softc[minor(dev)].gencn_tty;
|
||||||
|
|
||||||
return ((*tp->t_linesw->l_read)(tp, uio, flag));
|
return ((*tp->t_linesw->l_read)(tp, uio, flag));
|
||||||
}
|
}
|
||||||
|
@ -139,7 +145,7 @@ gencnread(dev_t dev, struct uio *uio, int flag)
|
||||||
int
|
int
|
||||||
gencnwrite(dev_t dev, struct uio *uio, int flag)
|
gencnwrite(dev_t dev, struct uio *uio, int flag)
|
||||||
{
|
{
|
||||||
struct tty *tp = gencn_tty[minor(dev)];
|
struct tty *tp = gc_softc[minor(dev)].gencn_tty;
|
||||||
|
|
||||||
return ((*tp->t_linesw->l_write)(tp, uio, flag));
|
return ((*tp->t_linesw->l_write)(tp, uio, flag));
|
||||||
}
|
}
|
||||||
|
@ -147,7 +153,7 @@ gencnwrite(dev_t dev, struct uio *uio, int flag)
|
||||||
int
|
int
|
||||||
gencnpoll(dev_t dev, int events, struct proc *p)
|
gencnpoll(dev_t dev, int events, struct proc *p)
|
||||||
{
|
{
|
||||||
struct tty *tp = gencn_tty[minor(dev)];
|
struct tty *tp = gc_softc[minor(dev)].gencn_tty;
|
||||||
|
|
||||||
return ((*tp->t_linesw->l_poll)(tp, events, p));
|
return ((*tp->t_linesw->l_poll)(tp, events, p));
|
||||||
}
|
}
|
||||||
|
@ -155,7 +161,7 @@ gencnpoll(dev_t dev, int events, struct proc *p)
|
||||||
int
|
int
|
||||||
gencnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
gencnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||||
{
|
{
|
||||||
struct tty *tp = gencn_tty[minor(dev)];
|
struct tty *tp = gc_softc[minor(dev)].gencn_tty;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
|
error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
|
||||||
|
@ -174,6 +180,11 @@ gencnstart(struct tty *tp)
|
||||||
struct clist *cl;
|
struct clist *cl;
|
||||||
int s, ch;
|
int s, ch;
|
||||||
|
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
if ((curcpu()->ci_flags & CI_MASTERCPU) == 0)
|
||||||
|
return cpu_send_ipi(IPI_DEST_MASTER, IPI_START_CNTX);
|
||||||
|
#endif
|
||||||
|
|
||||||
s = spltty();
|
s = spltty();
|
||||||
if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
|
if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -197,18 +208,23 @@ out: splx(s);
|
||||||
static void
|
static void
|
||||||
gencnrint(void *arg)
|
gencnrint(void *arg)
|
||||||
{
|
{
|
||||||
struct tty *tp = *(struct tty **) arg;
|
struct gc_softc *sc = arg;
|
||||||
int unit = (struct tty **) arg - gencn_tty;
|
struct tty *tp = sc->gencn_tty;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = mfpr(pr_rxdb[unit]) & 0377; /* Mask status flags etc... */
|
if (sc->alive == 0)
|
||||||
|
return;
|
||||||
|
i = mfpr(pr_rxdb[sc->unit]) & 0377; /* Mask status flags etc... */
|
||||||
|
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
|
||||||
|
|
||||||
#ifdef DDB
|
#ifdef DDB
|
||||||
if (tp->t_dev == cn_tab->cn_dev) {
|
if (tp->t_dev == cn_tab->cn_dev) {
|
||||||
int j = kdbrint(i);
|
int j = kdbrint(i);
|
||||||
|
|
||||||
if (j == 1) /* Escape received, just return */
|
if (j == 1) { /* Escape received, just return */
|
||||||
|
KERNEL_UNLOCK();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (j == 2) /* Second char wasn't 'D' */
|
if (j == 2) /* Second char wasn't 'D' */
|
||||||
(*tp->t_linesw->l_rint)(27, tp);
|
(*tp->t_linesw->l_rint)(27, tp);
|
||||||
|
@ -216,7 +232,7 @@ gencnrint(void *arg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(*tp->t_linesw->l_rint)(i, tp);
|
(*tp->t_linesw->l_rint)(i, tp);
|
||||||
return;
|
KERNEL_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -227,11 +243,16 @@ gencnstop(struct tty *tp, int flag)
|
||||||
static void
|
static void
|
||||||
gencntint(void *arg)
|
gencntint(void *arg)
|
||||||
{
|
{
|
||||||
struct tty *tp = *(struct tty **) arg;
|
struct gc_softc *sc = arg;
|
||||||
|
struct tty *tp = sc->gencn_tty;
|
||||||
|
|
||||||
|
if (sc->alive == 0)
|
||||||
|
return;
|
||||||
|
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
|
||||||
tp->t_state &= ~TS_BUSY;
|
tp->t_state &= ~TS_BUSY;
|
||||||
|
|
||||||
gencnstart(tp);
|
gencnstart(tp);
|
||||||
|
KERNEL_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -266,23 +287,27 @@ gencninit(struct consdev *cndev)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Allocate interrupt vectors */
|
/* Allocate interrupt vectors */
|
||||||
scb_vecalloc(SCB_G0R, gencnrint, &gencn_tty[0], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G0R, gencnrint, &gc_softc[0], SCB_ISTACK, NULL);
|
||||||
scb_vecalloc(SCB_G0T, gencntint, &gencn_tty[0], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G0T, gencntint, &gc_softc[0], SCB_ISTACK, NULL);
|
||||||
|
mtpr(GC_RIE, pr_rxcs[0]); /* Turn on interrupts */
|
||||||
|
mtpr(GC_TIE, pr_txcs[0]);
|
||||||
|
|
||||||
if (vax_cputype == VAX_TYP_8SS) {
|
if (vax_cputype == VAX_TYP_8SS) {
|
||||||
maxttys = 4;
|
maxttys = 4;
|
||||||
scb_vecalloc(SCB_G1R, gencnrint, &gencn_tty[1], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G1R, gencnrint, &gc_softc[1], SCB_ISTACK, NULL);
|
||||||
scb_vecalloc(SCB_G1T, gencntint, &gencn_tty[1], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G1T, gencntint, &gc_softc[1], SCB_ISTACK, NULL);
|
||||||
|
|
||||||
scb_vecalloc(SCB_G2R, gencnrint, &gencn_tty[2], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G2R, gencnrint, &gc_softc[2], SCB_ISTACK, NULL);
|
||||||
scb_vecalloc(SCB_G2T, gencntint, &gencn_tty[2], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G2T, gencntint, &gc_softc[2], SCB_ISTACK, NULL);
|
||||||
|
|
||||||
scb_vecalloc(SCB_G3R, gencnrint, &gencn_tty[3], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G3R, gencnrint, &gc_softc[3], SCB_ISTACK, NULL);
|
||||||
scb_vecalloc(SCB_G3T, gencntint, &gencn_tty[3], SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_G3T, gencntint, &gc_softc[3], SCB_ISTACK, NULL);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
mtpr(0, PR_RXCS);
|
mtpr(0, PR_RXCS);
|
||||||
mtpr(0, PR_TXCS);
|
mtpr(0, PR_TXCS);
|
||||||
mtpr(0, PR_TBIA); /* ??? */
|
mtpr(0, PR_TBIA); /* ??? */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -344,3 +369,11 @@ gencnpollc(dev_t dev, int pollflag)
|
||||||
mtpr(GC_TIE, PR_TXCS);
|
mtpr(GC_TIE, PR_TXCS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
void
|
||||||
|
gencnstarttx()
|
||||||
|
{
|
||||||
|
gencnstart(gc_softc[0].gencn_tty);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: gencons.h,v 1.9 2000/01/20 00:07:49 matt Exp $ */
|
/* $NetBSD: gencons.h,v 1.10 2001/06/03 15:07:20 ragge Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||||
|
@ -68,4 +68,5 @@
|
||||||
#define SCB_G3T 0xdc
|
#define SCB_G3T 0xdc
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
void gencnputc __P((dev_t, int));
|
void gencnputc(dev_t, int);
|
||||||
|
void gencnstarttx(void);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ka820.c,v 1.30 2000/08/09 03:02:54 tv Exp $ */
|
/* $NetBSD: ka820.c,v 1.31 2001/06/03 15:07:20 ragge Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1988 Regents of the University of California.
|
* Copyright (c) 1988 Regents of the University of California.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -50,6 +50,8 @@
|
||||||
#include <sys/device.h>
|
#include <sys/device.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
|
||||||
#include <uvm/uvm_extern.h>
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
|
@ -88,12 +90,14 @@ static void rxcdintr(void *);
|
||||||
static void vaxbierr(void *);
|
static void vaxbierr(void *);
|
||||||
#if defined(MULTIPROCESSOR)
|
#if defined(MULTIPROCESSOR)
|
||||||
static void ka820_startslave(struct device *, struct cpu_info *);
|
static void ka820_startslave(struct device *, struct cpu_info *);
|
||||||
|
static void ka820_send_ipi(struct device *);
|
||||||
static void ka820_txrx(int, char *, int);
|
static void ka820_txrx(int, char *, int);
|
||||||
static void ka820_sendstr(int, char *);
|
static void ka820_sendstr(int, char *);
|
||||||
static void ka820_sergeant(int);
|
static void ka820_sergeant(int);
|
||||||
static int rxchar(void);
|
static int rxchar(void);
|
||||||
static void ka820_putc(int);
|
static void ka820_putc(int);
|
||||||
static void ka820_cnintr(void);
|
static void ka820_cnintr(void);
|
||||||
|
static void ka820_ipintr(void *);
|
||||||
cons_decl(gen);
|
cons_decl(gen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -111,14 +115,19 @@ struct cpu_dep ka820_calls = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
#if defined(MULTIPROCESSOR)
|
|
||||||
ka820_startslave,
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
struct cpu_mp_dep ka820_mp_dep = {
|
||||||
|
ka820_startslave,
|
||||||
|
ka820_send_ipi,
|
||||||
|
ka820_cnintr,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ka820_softc {
|
struct ka820_softc {
|
||||||
struct device sc_dev;
|
struct device sc_dev;
|
||||||
struct cpu_info *sc_ci;
|
struct cpu_info sc_ci;
|
||||||
int sc_binid; /* CPU node ID */
|
int sc_binid; /* CPU node ID */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,15 +174,32 @@ ka820_attach(struct device *parent, struct device *self, void *aux)
|
||||||
((rev >> 11) & 15), ((rev >> 1) &1023), rev & 1);
|
((rev >> 11) & 15), ((rev >> 1) &1023), rev & 1);
|
||||||
sc->sc_binid = ba->ba_nodenr;
|
sc->sc_binid = ba->ba_nodenr;
|
||||||
|
|
||||||
if (ba->ba_nodenr != mastercpu) {
|
/* Allow for IPINTR */
|
||||||
#if defined(MULTIPROCESSOR)
|
bus_space_write_4(ba->ba_iot, ba->ba_ioh,
|
||||||
sc->sc_ci = cpu_slavesetup(self);
|
BIREG_IPINTRMSK, BIIPINTR_MASK);
|
||||||
v_putc = ka820_putc; /* Need special console handling */
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
if (ba->ba_nodenr != mastercpu) {
|
||||||
|
v_putc = ka820_putc; /* Need special console handling */
|
||||||
|
return cpu_slavesetup(self);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
/*
|
||||||
|
* Catch interprocessor interrupts.
|
||||||
|
*/
|
||||||
|
scb_vecalloc(KA820_INT_IPINTR, ka820_ipintr, sc, SCB_ISTACK, NULL);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Copy cpu_info into new position.
|
||||||
|
*/
|
||||||
|
bcopy(curcpu(), &sc->sc_ci, sizeof(struct cpu_info));
|
||||||
|
mtpr(&sc->sc_ci, PR_SSP);
|
||||||
|
proc0.p_addr->u_pcb.SSP = mfpr(PR_SSP);
|
||||||
|
proc0.p_cpu = curcpu();
|
||||||
curcpu()->ci_dev = self;
|
curcpu()->ci_dev = self;
|
||||||
|
|
||||||
/* reset the console and enable the RX50 */
|
/* reset the console and enable the RX50 */
|
||||||
ka820port_ptr = (void *)vax_map_physmem(KA820_PORTADDR, 1);
|
ka820port_ptr = (void *)vax_map_physmem(KA820_PORTADDR, 1);
|
||||||
csr = ka820port_ptr->csr;
|
csr = ka820port_ptr->csr;
|
||||||
|
@ -206,6 +232,9 @@ ka820_conf()
|
||||||
/* XXX - should be done somewhere else */
|
/* XXX - should be done somewhere else */
|
||||||
scb_vecalloc(SCB_RX50, crxintr, NULL, SCB_ISTACK, NULL);
|
scb_vecalloc(SCB_RX50, crxintr, NULL, SCB_ISTACK, NULL);
|
||||||
rx50device_ptr = (void *)vax_map_physmem(KA820_RX50ADDR, 1);
|
rx50device_ptr = (void *)vax_map_physmem(KA820_RX50ADDR, 1);
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
mp_dep_call = &ka820_mp_dep;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -442,12 +471,6 @@ rxcdintr(void *arg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(MULTIPROCESSOR)
|
#if defined(MULTIPROCESSOR)
|
||||||
if ((c & 0xff) == 0) {
|
|
||||||
if (curcpu()->ci_flags & CI_MASTERCPU)
|
|
||||||
ka820_cnintr();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expect == ((c >> 8) & 0xf))
|
if (expect == ((c >> 8) & 0xf))
|
||||||
rxbuf[got++] = c & 0xff;
|
rxbuf[got++] = c & 0xff;
|
||||||
|
|
||||||
|
@ -563,24 +586,26 @@ ka820_txrx(int id, char *fmt, int arg)
|
||||||
ka820_sergeant(id);
|
ka820_sergeant(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ka820_sendchr(int chr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* It seems like mtpr to TXCD sets the V flag if it fails.
|
||||||
|
* Cannot check that flag in C...
|
||||||
|
*/
|
||||||
|
asm __volatile("1:;mtpr %0,$92;bvs 1b" :: "g"(chr));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ka820_sendstr(int id, char *buf)
|
ka820_sendstr(int id, char *buf)
|
||||||
{
|
{
|
||||||
register u_int utchr; /* Ends up in R11 with PCC */
|
u_int utchr;
|
||||||
int ch, i;
|
int ch, i;
|
||||||
|
|
||||||
while (*buf) {
|
while (*buf) {
|
||||||
utchr = *buf | id << 8;
|
utchr = *buf | id << 8;
|
||||||
|
|
||||||
/*
|
ka820_sendchr(utchr);
|
||||||
* It seems like mtpr to TXCD sets the V flag if it fails.
|
|
||||||
* Cannot check that flag in C...
|
|
||||||
*/
|
|
||||||
#ifdef __GNUC__
|
|
||||||
asm("1:;mtpr %0,$92;bvs 1b" :: "g"(utchr));
|
|
||||||
#else
|
|
||||||
asm("1:;mtpr r11,$92;bvs 1b");
|
|
||||||
#endif
|
|
||||||
buf++;
|
buf++;
|
||||||
i = 30000;
|
i = 30000;
|
||||||
while ((ch = rxchar()) == 0 && --i)
|
while ((ch = rxchar()) == 0 && --i)
|
||||||
|
@ -612,7 +637,6 @@ ka820_sergeant(int id)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write to master console.
|
* Write to master console.
|
||||||
* Need no locking here; done in the print functions.
|
|
||||||
*/
|
*/
|
||||||
static volatile int ch = 0;
|
static volatile int ch = 0;
|
||||||
|
|
||||||
|
@ -624,7 +648,8 @@ ka820_putc(int c)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ch = c;
|
ch = c;
|
||||||
mtpr(mastercpu << 8, PR_RXCD); /* Send IPI to mastercpu */
|
|
||||||
|
cpu_send_ipi(IPI_DEST_MASTER, IPI_SEND_CNCHAR);
|
||||||
while (ch != 0)
|
while (ch != 0)
|
||||||
; /* Wait for master to handle */
|
; /* Wait for master to handle */
|
||||||
}
|
}
|
||||||
|
@ -639,4 +664,18 @@ ka820_cnintr()
|
||||||
gencnputc(0, ch);
|
gencnputc(0, ch);
|
||||||
ch = 0; /* Release slavecpu */
|
ch = 0; /* Release slavecpu */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ka820_send_ipi(struct device *dev)
|
||||||
|
{
|
||||||
|
struct ka820_softc *sc = (void *)dev;
|
||||||
|
|
||||||
|
mtpr(1 << sc->sc_binid, PR_IPIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ka820_ipintr(void *arg)
|
||||||
|
{
|
||||||
|
cpu_handle_ipi();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: multicpu.c,v 1.6 2001/05/29 21:55:00 ragge Exp $ */
|
/* $NetBSD: multicpu.c,v 1.7 2001/06/03 15:07:20 ragge Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
|
* Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
|
||||||
|
@ -46,9 +46,12 @@
|
||||||
#include <uvm/uvm_extern.h>
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
|
#include <machine/../vax/gencons.h>
|
||||||
|
|
||||||
#include "ioconf.h"
|
#include "ioconf.h"
|
||||||
|
|
||||||
|
struct cpu_mp_dep *mp_dep_call;
|
||||||
|
|
||||||
static void slaverun(void);
|
static void slaverun(void);
|
||||||
|
|
||||||
struct cpuq {
|
struct cpuq {
|
||||||
|
@ -68,7 +71,7 @@ cpu_boot_secondary_processors()
|
||||||
|
|
||||||
while ((q = SIMPLEQ_FIRST(&cpuq))) {
|
while ((q = SIMPLEQ_FIRST(&cpuq))) {
|
||||||
SIMPLEQ_REMOVE_HEAD(&cpuq, q, cq_q);
|
SIMPLEQ_REMOVE_HEAD(&cpuq, q, cq_q);
|
||||||
(*dep_call->cpu_startslave)(q->cq_dev, q->cq_ci);
|
(*mp_dep_call->cpu_startslave)(q->cq_dev, q->cq_ci);
|
||||||
free(q, M_TEMP);
|
free(q, M_TEMP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,9 +81,10 @@ cpu_boot_secondary_processors()
|
||||||
* struct and fill it in and prepare for getting started by
|
* struct and fill it in and prepare for getting started by
|
||||||
* cpu_boot_secondary_processors().
|
* cpu_boot_secondary_processors().
|
||||||
*/
|
*/
|
||||||
struct cpu_info *
|
void
|
||||||
cpu_slavesetup(struct device *dev)
|
cpu_slavesetup(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct cpu_mp_softc *sc = (struct cpu_mp_softc *)dev;
|
||||||
struct cpuq *cq;
|
struct cpuq *cq;
|
||||||
struct cpu_info *ci;
|
struct cpu_info *ci;
|
||||||
struct pglist mlist;
|
struct pglist mlist;
|
||||||
|
@ -115,8 +119,7 @@ cpu_slavesetup(struct device *dev)
|
||||||
scratch = VM_PAGE_TO_PHYS(pg) | KERNBASE;
|
scratch = VM_PAGE_TO_PHYS(pg) | KERNBASE;
|
||||||
|
|
||||||
/* Populate the PCB and the cpu_info struct */
|
/* Populate the PCB and the cpu_info struct */
|
||||||
ci = (struct cpu_info *)(scratch + VAX_NBPG);
|
ci = &sc->sc_ci;
|
||||||
memset(ci, 0, sizeof(struct cpu_info));
|
|
||||||
ci->ci_dev = dev;
|
ci->ci_dev = dev;
|
||||||
ci->ci_exit = scratch;
|
ci->ci_exit = scratch;
|
||||||
(u_long)ci->ci_pcb = (u_long)pcb & ~KERNBASE;
|
(u_long)ci->ci_pcb = (u_long)pcb & ~KERNBASE;
|
||||||
|
@ -133,17 +136,87 @@ cpu_slavesetup(struct device *dev)
|
||||||
cq->cq_ci = ci;
|
cq->cq_ci = ci;
|
||||||
cq->cq_dev = dev;
|
cq->cq_dev = dev;
|
||||||
SIMPLEQ_INSERT_TAIL(&cpuq, cq, cq_q);
|
SIMPLEQ_INSERT_TAIL(&cpuq, cq, cq_q);
|
||||||
return ci;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
volatile int sta;
|
||||||
|
|
||||||
void
|
void
|
||||||
slaverun()
|
slaverun()
|
||||||
{
|
{
|
||||||
struct cpu_info *ci = curcpu();
|
struct cpu_info *ci = curcpu();
|
||||||
|
|
||||||
((volatile struct cpu_info *)ci)->ci_flags |= CI_RUNNING;
|
((volatile struct cpu_info *)ci)->ci_flags |= CI_RUNNING;
|
||||||
|
cpu_send_ipi(IPI_DEST_MASTER, IPI_RUNNING);
|
||||||
printf("%s: running\n", ci->ci_dev->dv_xname);
|
printf("%s: running\n", ci->ci_dev->dv_xname);
|
||||||
|
while (sta != ci->ci_dev->dv_unit)
|
||||||
|
;
|
||||||
splsched();
|
splsched();
|
||||||
sched_lock_idle();
|
sched_lock_idle();
|
||||||
cpu_switch(0);
|
cpu_switch(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send an IPI of type type to the CPU with logical device number cpu.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_send_ipi(int cpu, int type)
|
||||||
|
{
|
||||||
|
struct cpu_mp_softc *sc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cpu >= 0) {
|
||||||
|
sc = cpu_cd.cd_devs[cpu];
|
||||||
|
bbssi(type, &sc->sc_ci.ci_ipimsgs);
|
||||||
|
(*mp_dep_call->cpu_send_ipi)(&sc->sc_dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < cpu_cd.cd_ndevs; i++) {
|
||||||
|
sc = cpu_cd.cd_devs[i];
|
||||||
|
if (sc == NULL)
|
||||||
|
continue;
|
||||||
|
switch (cpu) {
|
||||||
|
case IPI_DEST_MASTER:
|
||||||
|
if (sc->sc_ci.ci_flags & CI_MASTERCPU) {
|
||||||
|
bbssi(type, &sc->sc_ci.ci_ipimsgs);
|
||||||
|
(*mp_dep_call->cpu_send_ipi)(&sc->sc_dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IPI_DEST_ALL:
|
||||||
|
bbssi(type, &sc->sc_ci.ci_ipimsgs);
|
||||||
|
(*mp_dep_call->cpu_send_ipi)(&sc->sc_dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_handle_ipi()
|
||||||
|
{
|
||||||
|
struct cpu_info *ci = curcpu();
|
||||||
|
int bitno;
|
||||||
|
|
||||||
|
while ((bitno = ffs(ci->ci_ipimsgs))) {
|
||||||
|
bitno -= 1; /* ffs() starts from 1 */
|
||||||
|
bbcci(bitno, &ci->ci_ipimsgs);
|
||||||
|
switch (bitno) {
|
||||||
|
case IPI_START_CNTX:
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
if (CPU_IS_PRIMARY(ci) == 0)
|
||||||
|
panic("cpu_handle_ipi");
|
||||||
|
#endif
|
||||||
|
gencnstarttx();
|
||||||
|
break;
|
||||||
|
case IPI_SEND_CNCHAR:
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
if (CPU_IS_PRIMARY(ci) == 0)
|
||||||
|
panic("cpu_handle_ipi2");
|
||||||
|
#endif
|
||||||
|
(*mp_dep_call->cpu_cnintr)();
|
||||||
|
break;
|
||||||
|
case IPI_RUNNING:
|
||||||
|
printf("something running\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: subr.s,v 1.59 2001/05/29 21:25:11 ragge Exp $ */
|
/* $NetBSD: subr.s,v 1.60 2001/06/03 15:07:20 ragge Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||||
|
@ -587,6 +587,24 @@ ENTRY(blkclr,R6)
|
||||||
movc5 $0,(r3),$0,r6,(r3)
|
movc5 $0,(r3),$0,r6,(r3)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
#if defined(MULTIPROCESSOR)
|
||||||
|
|
||||||
|
JSBENTRY(Slock)
|
||||||
|
1: bbssi $0,(r1),1b
|
||||||
|
rsb
|
||||||
|
|
||||||
|
JSBENTRY(Slocktry)
|
||||||
|
clrl r0
|
||||||
|
bbssi $0,(r1),1f
|
||||||
|
incl r0
|
||||||
|
1: rsb
|
||||||
|
|
||||||
|
JSBENTRY(Sunlock)
|
||||||
|
bbcci $0,(r1),1f
|
||||||
|
1: rsb
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# data department
|
# data department
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: trap.c,v 1.63 2001/06/02 18:09:24 chs Exp $ */
|
/* $NetBSD: trap.c,v 1.64 2001/06/03 15:07:21 ragge Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||||
|
@ -235,6 +235,7 @@ if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
|
||||||
rv = uvm_fault(map, addr, 0, ftype);
|
rv = uvm_fault(map, addr, 0, ftype);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
if (umode == 0) {
|
if (umode == 0) {
|
||||||
|
KERNEL_UNLOCK();
|
||||||
FAULTCHK;
|
FAULTCHK;
|
||||||
panic("Segv in kernel mode: pc %x addr %x",
|
panic("Segv in kernel mode: pc %x addr %x",
|
||||||
(u_int)frame->pc, (u_int)frame->code);
|
(u_int)frame->pc, (u_int)frame->code);
|
||||||
|
|
Loading…
Reference in New Issue