Пример #1
0
void
zscninit(struct consdev *cn)
{
	extern const struct cdevsw zstty_cdevsw;
	const char* consdev;

	if ((consdev = arcbios_GetEnvironmentVariable("ConsoleOut")) == NULL)
		panic("zscninit without valid ARCS ConsoleOut setting!");

	if (strlen(consdev) != 9 ||
	    strncmp(consdev, "serial", 6) != 0)
		panic("zscninit with ARCS console not set to serial!");

	cons_port = consdev[7] - '0';

#if 0
	/*
	 * If your IP12 serial console goes missing after consinit(),
	 * try flipping this the other way 'round.  If there are some
	 * IP12 machines that actually require this, we'll be in for
	 * a lot of funnies once again...
	 */
	if (mach_type == MACH_SGI_IP12)
		cons_port = 1 - cons_port;
#endif

	cn->cn_dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), cons_port);
	cn->cn_pri = CN_REMOTE;

	/* Mark this unit as the console */
	zs_consunit = 0;

	/* SGI hardware wires serial port 1 to channel B, port 2 to A */
	if (cons_port == 0)
		zs_conschan = 1;
	else
		zs_conschan = 0;
}
Пример #2
0
int
main(int argc, char **argv)
{
	const char     *kernel = NULL;
	const char     *bootpath = NULL;
	char            bootfile[PATH_MAX];
	void            (*entry)(int, char *[], u_int, void *);
	u_long          marks[MARK_MAX];
	int             win = 0;
	int             i;
	int             ch;

	/* print a banner */
	printf("\n");
	printf("%s Bootstrap, Revision %s\n", bootprog_name, bootprog_rev);

	memset(marks, 0, sizeof marks);

	/* initialise bootinfo structure early */
	bi_init(bootinfo);

#ifdef BOOT_DEBUG
	for (i = 0; i < argc; i++)
		printf("argv[%d] = %s\n", i, argv[i]);
#endif

	/* Parse arguments, if present.  */
	while ((ch = getopt(argc, argv, "v")) != -1) {
		switch (ch) {
		case 'v':
			debug = 1;
			break;
		}
	}

	environment = &argv[1];

	bootpath = firmware_getenv("OSLoadPartition");
	if (bootpath == NULL)
		bootpath =
		    arcbios_GetEnvironmentVariable("OSLoadPartition");

	if (bootpath == NULL) {
		/* XXX need to actually do the fixup */
		printf("OSLoadPartition is not specified.\n");
		return 0;
	}
	DPRINTF("bootpath = %s\n", bootpath);

	/*
	 * Grab OSLoadFilename from ARCS.
	 */

	kernel = firmware_getenv("OSLoadFilename");
	if (kernel == NULL)
		kernel = arcbios_GetEnvironmentVariable("OSLoadFilename");

	DPRINTF("kernel = %s\n", kernel ? kernel : "<null>");

	/*
	 * The first arg is assumed to contain the name of the kernel to boot,
	 * if it a) does not start with a hyphen and b) does not contain
	 * an equals sign.
	 */

	for (i = 1; i < argc; i++) {
		if (((strchr(argv[i], '=')) == NULL) && (argv[i][0] != '-')) {
			kernel = argv[i];
			break;
		}
	}

	if (kernel != NULL) {
		/*
		 * if the name contains parenthesis, we assume that it
		 * contains the bootpath and ignore anything passed through
		 * the environment
		 */
		if (strchr(kernel, '('))
			win = loadfile(kernel, marks, LOAD_KERNEL);
		else {
			strcpy(bootfile, bootpath);
			strcat(bootfile, kernel);
			win = loadfile(bootfile, marks, LOAD_KERNEL);
		}

	} else {
		i = 1;
		while (kernelnames[i] != NULL) {
			strcpy(bootfile, bootpath);
			strcat(bootfile, kernelnames[i]);
			kernel = kernelnames[i];
			win = loadfile(bootfile, marks, LOAD_KERNEL);
			if (win != -1)
				break;
			i++;
		}

	}

	if (win < 0) {
		printf("Boot failed!  Halting...\n");
		(void)getchar();
		return 0;
	}

	strlcpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN);
	bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));

	bi_syms.nsym = marks[MARK_NSYM];
	bi_syms.ssym = marks[MARK_SYM];
	bi_syms.esym = marks[MARK_END];
	bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));

	entry = (void *)marks[MARK_ENTRY];

	if (debug) {
		printf("Starting at %p\n\n", entry);
		printf("nsym 0x%lx ssym 0x%lx esym 0x%lx\n", marks[MARK_NSYM],
		       marks[MARK_SYM], marks[MARK_END]);
	}
	(*entry)(argc, argv, BOOTINFO_MAGIC, bootinfo);

	printf("Kernel returned!  Halting...\n");
	return 0;
}
Пример #3
0
/*
 * Attach a found zs.
 *
 * Match slave number to zs unit number, so that misconfiguration will
 * not set up the keyboard as ttya, etc.
 */
static void
zs_hpc_attach(device_t parent, device_t self, void *aux)
{
	struct zsc_softc *zsc = device_private(self);
	struct hpc_attach_args *haa = aux;
	struct zsc_attach_args zsc_args;
	struct zs_chanstate *cs;
	struct zs_channel *ch;
	int    zs_unit, channel, err, s;
	const char  *promconsdev;

	promconsdev = arcbios_GetEnvironmentVariable("ConsoleOut");

	zsc->zsc_dev = self;
	zsc->zsc_bustag = haa->ha_st;
	if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
				       haa->ha_devoff, 0x10,
				       &zsc->zsc_base)) != 0) {
		aprint_error(": unable to map 85c30 registers, error = %d\n",
		    err);
		return;
	}

	zs_unit = device_unit(self);
	aprint_normal("\n");

	/*
	 * Initialize software state for each channel.
	 *
	 * Done in reverse order of channels since the first serial port
	 * is actually attached to the *second* channel, and vice versa.
	 * Doing it this way should force a 'zstty*' to attach zstty0 to
	 * channel 1 and zstty1 to channel 0.  They couldn't have wired
	 * it up in a more sensible fashion, could they?
	 */
	for (channel = 1; channel >= 0; channel--) {
		zsc_args.channel = channel;
		ch = &zsc->zsc_cs_store[channel];
		cs = zsc->zsc_cs[channel] = (struct zs_chanstate *)ch;

		zs_lock_init(cs);
		cs->cs_reg_csr = NULL;
		cs->cs_reg_data = NULL;
		cs->cs_channel = channel;
		cs->cs_private = NULL;
		cs->cs_ops = &zsops_null;
		cs->cs_brg_clk = PCLK / 16;

		if (bus_space_subregion(zsc->zsc_bustag, zsc->zsc_base,
					zs_chan_offset[channel],
					sizeof(struct zschan),
					&ch->cs_regs) != 0) {
			aprint_error_dev(self, "cannot map regs\n");
			return;
		}
		ch->cs_bustag = zsc->zsc_bustag;

		memcpy(cs->cs_creg, zs_init_reg, 16);
		memcpy(cs->cs_preg, zs_init_reg, 16);

		zsc_args.hwflags = 0;
		zsc_args.consdev = NULL;

		if (zs_consunit == -1 && zs_conschan == -1) {
		    /*
		     * If this channel is being used by the PROM console,
		     * pass the generic zs driver a 'no reset' flag so the
		     * channel gets left in the appropriate state after
		     * attach.
		     *
		     * Note: the channel mappings are swapped.
		     */
		    if (promconsdev != NULL &&
			strlen(promconsdev) == 9 &&
			strncmp(promconsdev, "serial", 6) == 0 &&
			(promconsdev[7] == '0' || promconsdev[7] == '1')) {
			if (promconsdev[7] == '1' && channel == 0)
			    zsc_args.hwflags |= ZS_HWFLAG_NORESET;
			else if (promconsdev[7] == '0' && channel == 1)
			    zsc_args.hwflags |= ZS_HWFLAG_NORESET;
		    }
		}

		/* If console, don't stomp speed, let zstty know */
		if (zs_unit == zs_consunit && channel == zs_conschan) {
			zsc_args.consdev = &zs_cn;
			zsc_args.hwflags = ZS_HWFLAG_CONSOLE;

			cs->cs_defspeed = zs_get_speed(cs);
		} else
			cs->cs_defspeed = zs_defspeed;

		cs->cs_defcflag = zs_def_cflag;

		/* Make these correspond to cs_defcflag (-crtscts) */
		cs->cs_rr0_dcd = ZSRR0_DCD;
		cs->cs_rr0_cts = 0;
		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
		cs->cs_wr5_rts = 0;

		/*
		 * Clear the master interrupt enable.
		 * The INTENA is common to both channels,
		 * so just do it on the A channel.
		 */
		if (channel == 0) {
			zs_write_reg(cs, 9, 0);
		}
		/*
		 * Look for a child driver for this channel.
		 * The child attach will setup the hardware.
		 */
		if (!config_found(self, (void *)&zsc_args, zs_print)) {
			/* No sub-driver.  Just reset it. */
			uint8_t reset = (channel == 0) ?
				ZSWR9_A_RESET : ZSWR9_B_RESET;

			s = splhigh();
			zs_write_reg(cs, 9, reset);
			splx(s);
		}
	}


	zsc->sc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc);
	cpu_intr_establish(haa->ha_irq, IPL_TTY, zshard, NULL);

	evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL,
			     device_xname(self), "intr");

	/*
	 * Set the master interrupt enable and interrupt vector.
	 * (common to both channels, do it on A)
	 */
	cs = zsc->zsc_cs[0];
	s = splhigh();
	/* interrupt vector */
	zs_write_reg(cs, 2, zs_init_reg[2]);
	/* master interrupt control (enable) */
	zs_write_reg(cs, 9, zs_init_reg[9]);
	splx(s);
}
Пример #4
0
static void
sq_attach(device_t parent, device_t self, void *aux)
{
	int i, err;
	const char* macaddr;
	struct sq_softc *sc = device_private(self);
	struct hpc_attach_args *haa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;

	sc->sc_dev = self;
	sc->sc_hpct = haa->ha_st;
	sc->hpc_regs = haa->hpc_regs;      /* HPC register definitions */

	if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
	    haa->ha_dmaoff, sc->hpc_regs->enet_regs_size,
	    &sc->sc_hpch)) != 0) {
		printf(": unable to map HPC DMA registers, error = %d\n", err);
		goto fail_0;
	}

	sc->sc_regt = haa->ha_st;
	if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
	    haa->ha_devoff, sc->hpc_regs->enet_devregs_size,
	    &sc->sc_regh)) != 0) {
		printf(": unable to map Seeq registers, error = %d\n", err);
		goto fail_0;
	}

	sc->sc_dmat = haa->ha_dmat;

	if ((err = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct sq_control),
	    PAGE_SIZE, PAGE_SIZE, &sc->sc_cdseg, 1, &sc->sc_ncdseg,
	    BUS_DMA_NOWAIT)) != 0) {
		printf(": unable to allocate control data, error = %d\n", err);
		goto fail_0;
	}

	if ((err = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_ncdseg,
	    sizeof(struct sq_control), (void **)&sc->sc_control,
	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		printf(": unable to map control data, error = %d\n", err);
		goto fail_1;
	}

	if ((err = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct sq_control), 1, sizeof(struct sq_control), PAGE_SIZE,
	    BUS_DMA_NOWAIT, &sc->sc_cdmap)) != 0) {
		printf(": unable to create DMA map for control data, error "
		    "= %d\n", err);
		goto fail_2;
	}

	if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cdmap,
	    sc->sc_control, sizeof(struct sq_control), NULL,
	    BUS_DMA_NOWAIT)) != 0) {
		printf(": unable to load DMA map for control data, error "
		    "= %d\n", err);
		goto fail_3;
	}

	memset(sc->sc_control, 0, sizeof(struct sq_control));

	/* Create transmit buffer DMA maps */
	for (i = 0; i < SQ_NTXDESC; i++) {
		if ((err = bus_dmamap_create(sc->sc_dmat,
		    MCLBYTES, 1, MCLBYTES, 0,
		    BUS_DMA_NOWAIT, &sc->sc_txmap[i])) != 0) {
			printf(": unable to create tx DMA map %d, error = %d\n",
			    i, err);
			goto fail_4;
		}
	}

	/* Create receive buffer DMA maps */
	for (i = 0; i < SQ_NRXDESC; i++) {
		if ((err = bus_dmamap_create(sc->sc_dmat,
		    MCLBYTES, 1, MCLBYTES, 0,
		    BUS_DMA_NOWAIT, &sc->sc_rxmap[i])) != 0) {
			printf(": unable to create rx DMA map %d, error = %d\n",
			    i, err);
			goto fail_5;
		}
	}

	/* Pre-allocate the receive buffers.  */
	for (i = 0; i < SQ_NRXDESC; i++) {
		if ((err = sq_add_rxbuf(sc, i)) != 0) {
			printf(": unable to allocate or map rx buffer %d\n,"
			    " error = %d\n", i, err);
			goto fail_6;
		}
	}

	memcpy(sc->sc_enaddr, &haa->hpc_eeprom[SQ_HPC_EEPROM_ENADDR],
	    ETHER_ADDR_LEN);

	/*
	 * If our mac address is bogus, obtain it from ARCBIOS. This will
	 * be true of the onboard HPC3 on IP22, since there is no eeprom,
	 * but rather the DS1386 RTC's battery-backed ram is used.
	 */
	if (sc->sc_enaddr[0] != SGI_OUI_0 ||
	    sc->sc_enaddr[1] != SGI_OUI_1 ||
	    sc->sc_enaddr[2] != SGI_OUI_2) {
		macaddr = arcbios_GetEnvironmentVariable("eaddr");
		if (macaddr == NULL) {
			printf(": unable to get MAC address!\n");
			goto fail_6;
		}
		ether_aton_r(sc->sc_enaddr, sizeof(sc->sc_enaddr), macaddr);
	}

	evcnt_attach_dynamic(&sc->sq_intrcnt, EVCNT_TYPE_INTR, NULL,
	    device_xname(self), "intr");

	if ((cpu_intr_establish(haa->ha_irq, IPL_NET, sq_intr, sc)) == NULL) {
		printf(": unable to establish interrupt!\n");
		goto fail_6;
	}

	/* Reset the chip to a known state. */
	sq_reset(sc);

	/*
	 * Determine if we're an 8003 or 80c03 by setting the first
	 * MAC address register to non-zero, and then reading it back.
	 * If it's zero, we have an 80c03, because we will have read
	 * the TxCollLSB register.
	 */
	sq_seeq_write(sc, SEEQ_TXCOLLS0, 0xa5);
	if (sq_seeq_read(sc, SEEQ_TXCOLLS0) == 0)
		sc->sc_type = SQ_TYPE_80C03;
	else
		sc->sc_type = SQ_TYPE_8003;
	sq_seeq_write(sc, SEEQ_TXCOLLS0, 0x00);

	printf(": SGI Seeq %s\n",
	    sc->sc_type == SQ_TYPE_80C03 ? "80c03" : "8003");

	printf("%s: Ethernet address %s\n",
	    device_xname(self), ether_sprintf(sc->sc_enaddr));

	strcpy(ifp->if_xname, device_xname(self));
	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;
	ifp->if_init = sq_init;
	ifp->if_stop = sq_stop;
	ifp->if_start = sq_start;
	ifp->if_ioctl = sq_ioctl;
	ifp->if_watchdog = sq_watchdog;
	ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS | IFF_MULTICAST;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_enaddr);

	memset(&sc->sq_trace, 0, sizeof(sc->sq_trace));
	/* Done! */
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < SQ_NRXDESC; i++) {
		if (sc->sc_rxmbuf[i] != NULL) {
			bus_dmamap_unload(sc->sc_dmat, sc->sc_rxmap[i]);
			m_freem(sc->sc_rxmbuf[i]);
		}
	}
 fail_5:
	for (i = 0; i < SQ_NRXDESC; i++) {
		if (sc->sc_rxmap[i] != NULL)
			bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxmap[i]);
	}
 fail_4:
	for (i = 0; i < SQ_NTXDESC; i++) {
		if (sc->sc_txmap[i] !=  NULL)
			bus_dmamap_destroy(sc->sc_dmat, sc->sc_txmap[i]);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cdmap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cdmap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmat,
	    (void *)sc->sc_control, sizeof(struct sq_control));
 fail_1:
	bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_ncdseg);
 fail_0:
	return;
}