Add preliminary PROM internal function based framebuffer console support,

which was demonstrated at Open Source Conference 2011 Kansai @ Kyoto
back in July:
http://www.NetBSD.org/gallery/events.html#opensourceconf2011-Kansai

- map 0xc0000000-0xffffffff PA region (which is mirror of PA 0x0-0x3fffffff)
  to the same VA via %tt0 and %tt1 registers and move KVA space accordingly
  (like luna68k does for its devices)
- save trap #0 vector for PROM function calls in early bootstrap
  and register it to trap #14 to call it from kernel for console output
- add dumb romcall based tty attachment taken from src/sys/dev/ofw/ofcons.c
- add rom function call stubs from news68k/stand/common/romcalls.S
- remove IIOV() macro for device registers where now mapped PA==VA via %tt1

XXX: romcons is not enabled yet because there is no generic interface
XXX: to attach wskbd(4) to non wsdisplay(4) devices like this romcons.
This commit is contained in:
tsutsui 2011-11-20 15:38:00 +00:00
parent 4255d01378
commit 217e34e4b6
15 changed files with 531 additions and 55 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.106 2011/03/06 17:08:28 bouyer Exp $
# $NetBSD: GENERIC,v 1.107 2011/11/20 15:38:00 tsutsui Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/news68k/conf/std.news68k"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.106 $"
#ident "GENERIC-$Revision: 1.107 $"
maxusers 8
@ -221,6 +221,9 @@ ch* at scsibus? target ? lun ? # SCSI changer devices
ss* at scsibus? target ? lun ? # SCSI scanners
uk* at scsibus? target ? lun ? # unknown SCSI devices
# PROM console support
#romcons0 at mainbus0
#
# accept filters
pseudo-device accf_data # "dataready" accept filter

View File

@ -1,4 +1,4 @@
# $NetBSD: INSTALL,v 1.53 2011/03/13 12:58:02 he Exp $
# $NetBSD: INSTALL,v 1.54 2011/11/20 15:38:00 tsutsui Exp $
# config for bootable floppy kernel
#
@ -146,6 +146,9 @@ sd* at scsibus? target ? lun ? # SCSI disks
st* at scsibus? target ? lun ? # SCSI tapes
cd* at scsibus? target ? lun ? # SCSI CD-ROMs
# PROM console support
#romcons0 at mainbus0
# Misc.
pseudo-device loop # loopback interface; required
pseudo-device pty 2 # pseudo-terminals (Sysinst needs two)

View File

@ -1,4 +1,4 @@
# $NetBSD: files.news68k,v 1.32 2011/06/12 03:35:44 rmind Exp $
# $NetBSD: files.news68k,v 1.33 2011/11/20 15:38:00 tsutsui Exp $
# NEWS68K-specific configuration info
@ -19,6 +19,7 @@ file arch/news68k/news68k/isr.c
file arch/news68k/news68k/machdep.c
file arch/news68k/news68k/mainbus.c
file arch/news68k/news68k/pmap_bootstrap.c compile-with "${NOPROF_C}"
file arch/news68k/news68k/romcalls.S
file arch/news68k/news68k/trap.c
file arch/m68k/m68k/cacheops.c
file arch/m68k/m68k/db_memrw.c ddb | kgdb
@ -99,6 +100,11 @@ device fd: disk
attach fd at fdc
file arch/news68k/dev/fd.c fdc | fd needs-flag
# PROM console support
device romcons
attach romcons at mainbus
file arch/news68k/news68k/romcons.c romcons needs-flag
# Machine-independent SCSI driver
include "dev/scsipi/files.scsipi"

View File

@ -1,4 +1,4 @@
# $NetBSD: majors.news68k,v 1.22 2011/06/30 20:09:34 wiz Exp $
# $NetBSD: majors.news68k,v 1.23 2011/11/20 15:38:00 tsutsui Exp $
#
# Device majors for news68k
#
@ -44,6 +44,7 @@ device-major clockctl char 76 clockctl
device-major cgd char 78 block 33 cgd
device-major ksyms char 79 ksyms
device-major wsfont char 80 wsfont
device-major romcons char 81 romcons
device-major nsmb char 98 nsmb

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_le.c,v 1.18 2010/01/19 22:06:21 pooka Exp $ */
/* $NetBSD: if_le.c,v 1.19 2011/11/20 15:38:00 tsutsui Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.18 2010/01/19 22:06:21 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.19 2011/11/20 15:38:00 tsutsui Exp $");
#include "opt_inet.h"
@ -137,7 +137,7 @@ le_match(device_t parent, cfdata_t cf, void *aux)
if (strcmp(ha->ha_name, "le"))
return 0;
addr = IIOV(ha->ha_address);
addr = (ha->ha_address);
if (badaddr((void *)addr, 1))
return 0;
@ -154,10 +154,10 @@ le_attach(device_t parent, device_t self, void *aux)
const uint8_t *p;
sc->sc_dev = self;
lesc->sc_r1 = (void *)IIOV(ha->ha_address);
lesc->sc_r1 = (void *)(ha->ha_address);
if (ISIIOPA(ha->ha_address)) {
sc->sc_mem = (u_char *)IIOV(lance_mem_phys);
sc->sc_mem = (u_char *)(lance_mem_phys);
p = idrom_addr + 0x10;
} else {
sc->sc_mem = lesc->sc_r1 - 0x10000;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kb_hb.c,v 1.12 2008/05/14 13:29:28 tsutsui Exp $ */
/* $NetBSD: kb_hb.c,v 1.13 2011/11/20 15:38:00 tsutsui Exp $ */
/*-
* Copyright (c) 2001 Izumi Tsutsui. All rights reserved.
@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kb_hb.c,v 1.12 2008/05/14 13:29:28 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: kb_hb.c,v 1.13 2011/11/20 15:38:00 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -74,7 +74,7 @@ kb_hb_match(device_t parent, cfdata_t cf, void *aux)
if (ha->ha_address == (u_int)-1)
return 0;
addr = IIOV(ha->ha_address); /* XXX */
addr = (ha->ha_address); /* XXX */
if (badaddr((void *)addr, 1))
return 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: si.c,v 1.25 2008/06/17 18:24:21 tsutsui Exp $ */
/* $NetBSD: si.c,v 1.26 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: si.c,v 1.25 2008/06/17 18:24:21 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: si.c,v 1.26 2011/11/20 15:38:00 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -107,7 +107,7 @@ si_match(device_t parent, cfdata_t cf, void *aux)
if (strcmp(ha->ha_name, "si"))
return 0;
addr = IIOV(ha->ha_address);
addr = (ha->ha_address);
if (badaddr((void *)addr, 1))
return 0;
@ -182,7 +182,7 @@ si_attach(device_t parent, device_t self, void *aux)
ncr_sc->sc_channel.chan_id = 7;
/* soft reset DMAC */
sc->sc_regs = (void *)IIOV(DMAC_BASE);
sc->sc_regs = (void *)(DMAC_BASE);
sc->sc_regs->ctl = DC_CTL_RST;
ncr5380_attach(ncr_sc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.30 2008/04/28 20:23:30 martin Exp $ */
/* $NetBSD: zs.c,v 1.31 2011/11/20 15:38:00 tsutsui Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.30 2008/04/28 20:23:30 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.31 2011/11/20 15:38:00 tsutsui Exp $");
#include "opt_ddb.h"
@ -166,7 +166,7 @@ zs_match(device_t parent, cfdata_t cf, void *aux)
if (ha->ha_address == (u_int)-1)
return 0;
addr = IIOV(ha->ha_address);
addr = (ha->ha_address);
/* This returns -1 on a fault (bus error). */
if (badaddr((void *)addr, 1))
return 0;
@ -191,7 +191,7 @@ zs_attach(device_t parent, device_t self, void *aux)
zsc->zsc_dev = self;
zs = (void *)IIOV(ha->ha_address);
zs = (void *)(ha->ha_address);
clk = cf->cf_flags;
if (clk < 0 || clk >= NPCLK)

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.39 2011/05/16 13:22:54 tsutsui Exp $ */
/* $NetBSD: cpu.h,v 1.40 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -162,6 +162,7 @@ extern u_int extiobase_phys, extiotop_phys;
extern u_int intrcnt[];
extern void (*vectab[])(void);
extern void *romcallvec;
struct frame;

View File

@ -1,4 +1,4 @@
/* $NetBSD: vmparam.h,v 1.18 2011/02/08 20:20:20 rmind Exp $ */
/* $NetBSD: vmparam.h,v 1.19 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -109,7 +109,7 @@
#define VM_MAXUSER_ADDRESS ((vaddr_t)0xFFF00000)
#define VM_MAX_ADDRESS ((vaddr_t)0xFFF00000)
#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0)
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)(0-PAGE_SIZE*NPTEPG))
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)(0xC0000000-PAGE_SIZE*NPTEPG))
/* virtual sizes (bytes) for various kernel submaps */
#define VM_PHYS_SIZE (USRIOSIZE*PAGE_SIZE)

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.59 2011/11/15 10:57:03 tsutsui Exp $ */
/* $NetBSD: locore.s,v 1.60 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -148,6 +148,7 @@ ASENTRY_NOPROFILE(start)
movc %vbr,%a0
movl %a0@(188),_ASM_LABEL(monitor)| save trap #15 to return PROM monitor
movl %a0@(128),_ASM_LABEL(romcallvec)| save trap #0 to use PROM calls
RELOC(esym, %a0)
#if NKSYMS || defined(DDB) || defined(LKM)
@ -395,11 +396,15 @@ Lstploaddone:
movc %d0,%cacr | turn on both caches
jmp Lenab1
Lmotommu2:
#if 0 /* XXX use %tt0 register to map I/O space temporary */
/* Use %tt0 register to map I/O space */
RELOC(protott0, %a0)
movl #0xe01f8550,%a0@ | use %tt0 (0xe0000000-0xffffffff)
movl #0xe01f8543,%a0@ | use %tt0 (0xe0000000-0xffffffff)
.long 0xf0100800 | pmove %a0@,%tt0
#endif
/* Use %tt1 register to map RAM to use PROM calls */
RELOC(protott1, %a0)
movl #0xc01f8143,%a0@ | use %tt1 (0xc0000000-0xdfffffff)
.long 0xf0100c00 | pmove %a0@,%tt1
RELOC(prototc, %a2)
#if PGSHIFT == 13
movl #0x82d08b00,%a2@ | value to load TC with
@ -1221,6 +1226,9 @@ GLOBAL(cache_ctl)
GLOBAL(cache_clr)
.long 0 | KVA of external cache clear port
GLOBAL(romcallvec)
.long 0
/* interrupt counters */
GLOBAL(intrnames)

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.95 2011/06/12 03:35:45 rmind Exp $ */
/* $NetBSD: machdep.c,v 1.96 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.95 2011/06/12 03:35:45 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.96 2011/11/20 15:38:00 tsutsui Exp $");
#include "opt_ddb.h"
#include "opt_compat_netbsd.h"
@ -99,6 +99,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.95 2011/06/12 03:35:45 rmind Exp $");
#include "ms.h"
#include "si.h"
#include "ksyms.h"
#include "romcons.h"
/* XXX etc. etc. */
/* the following is used externally (sysctl_hw) */
@ -795,15 +796,15 @@ news1700_init(void)
uint8_t *q;
u_int i;
dip_switch = (uint8_t *)IIOV(0xe1c00100);
int_status = (uint8_t *)IIOV(0xe1c00200);
dip_switch = (uint8_t *)(0xe1c00100);
int_status = (uint8_t *)(0xe1c00200);
idrom_addr = (uint8_t *)IIOV(0xe1c00000);
ctrl_ast = (uint8_t *)IIOV(0xe1280000);
ctrl_int2 = (uint8_t *)IIOV(0xe1180000);
ctrl_led = (uint8_t *)IIOV(ctrl_led_phys);
idrom_addr = (uint8_t *)(0xe1c00000);
ctrl_ast = (uint8_t *)(0xe1280000);
ctrl_int2 = (uint8_t *)(0xe1180000);
ctrl_led = (uint8_t *)(ctrl_led_phys);
sccport0a = IIOV(0xe0d40002);
sccport0a = (0xe0d40002);
lance_mem_phys = 0xe0e00000;
p = idrom_addr;
@ -824,9 +825,9 @@ news1700_init(void)
strcat(cpu_model, t);
news_machine_id = (idrom.id_serial[0] << 8) + idrom.id_serial[1];
ctrl_parity = (uint8_t *)IIOV(0xe1080000);
ctrl_parity_clr = (uint8_t *)IIOV(0xe1a00000);
parity_vector = (uint8_t *)IIOV(0xe1c00200);
ctrl_parity = (uint8_t *)(0xe1080000);
ctrl_parity_clr = (uint8_t *)(0xe1a00000);
parity_vector = (uint8_t *)(0xe1c00200);
parityenable();
@ -981,20 +982,26 @@ intrhand_lev4(void)
#define SW_AUTOSEL 0x07
struct consdev *cn_tab = NULL;
extern struct consdev consdev_bm, consdev_zs;
extern struct consdev consdev_rom, consdev_zs;
int tty00_is_console = 0;
void
consinit(void)
{
uint8_t dipsw;
int dipsw = *dip_switch;
dipsw = *dip_switch;
dipsw &= ~SW_CONSOLE;
dipsw = ~dipsw;
switch (dipsw & SW_CONSOLE) {
default: /* XXX no fb support yet */
default: /* XXX no real fb support yet */
#if NROMCONS > 0
cn_tab = &consdev_rom;
(*cn_tab->cn_init)(cn_tab);
break;
#endif
case 0:
tty00_is_console = 1;
cn_tab = &consdev_zs;

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.36 2011/01/02 18:48:06 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.37 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.36 2011/01/02 18:48:06 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.37 2011/11/20 15:38:00 tsutsui Exp $");
#include "opt_m68k_arch.h"
@ -162,8 +162,13 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* each mapping 256kb. Note that there may be additional "segment
* table" pages depending on how large MAXKL2SIZE is.
*
* Portions of the last segment of KVA space (0xFFC00000 -
* 0xFFFFFFFF) are mapped for the kernel page tables.
* Portions of the last segment of KVA space (0xBFC00000 -
* 0xBFFFFFFF) are mapped for the kernel page tables.
*
* The region 0xC0000000 - 0xCFFFFFFF is mapped via the %tt1 register
* for RAM accesses for PROM.
* The region 0xE0000000 - 0xFFFFFFFF is mapped via the %tt0 register
* for I/O accesses.
*
* XXX cramming two levels of mapping into the single "segment"
* table on the 68040 is intended as a temporary hack to get things
@ -213,19 +218,20 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
* Initialize the level 1 descriptor correspond to
* SYSMAP_VA to map the last block of level 2 descriptors
* for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
ste = &ste[SYSMAP_VA >> SG4_SHIFT1];
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map Sysmap.
* Now initialize the portion of that block of
* descriptors to map Sysptmap.
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
ste = &ste[i + ((SYSMAP_VA & SG4_MASK2) >> SG4_SHIFT2)];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
@ -269,7 +275,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
* Initialize the one corresponding to SYSMAP_VA
* to point to Sysptmap.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[SYSMAP_VA >> SEGSHIFT];

View File

@ -0,0 +1,86 @@
/* $NetBSD: romcalls.S,v 1.1 2011/11/20 15:38:00 tsutsui Exp $ */
/*-
* Copyright (c) 1999 Izumi Tsutsui. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <m68k/asm.h>
#include <machine/romcall.h>
.text
.align 4
#define SYSCALL trap #14 /* XXX */
#if 0
ENTRY_NOPROFILE(rom_halt)
moveq #8, %d7 | RB_HALT
trap #15
#endif
#if 0
ENTRY_NOPROFILE(rom_open)
linkw %a6, #0
moveml %d2-%d7/%a2-%a5,%sp@- | save %d2-%d7, %a2-%a5
moveq #SYS_open, %d0
SYSCALL
moveml %a6@(-40),%d2-%d7/%a2-%a5
unlk %a6
rts
ENTRY_NOPROFILE(rom_close)
linkw %a6, #0
moveml %d2-%d7/%a2-%a5,%sp@- | save %d2-%d7, %a2-%a5
moveq #SYS_close, %d0
SYSCALL
moveml %a6@(-40),%d2-%d7/%a2-%a5
unlk %a6
rts
#endif
ENTRY_NOPROFILE(rom_read)
linkw %a6, #0
moveml %d2-%d7/%a2-%a5,%sp@- | save %d2-%d7, %a2-%a5
moveq #SYS_read, %d0
SYSCALL
moveml %a6@(-40),%d2-%d7/%a2-%a5
unlk %a6
rts
ENTRY_NOPROFILE(rom_write)
linkw %a6, #0
moveml %d2-%d7/%a2-%a5,%sp@- | save %d2-%d7, %a2-%a5
moveq #SYS_write, %d0
SYSCALL
moveml %a6@(-40),%d2-%d7/%a2-%a5
unlk %a6
rts
ENTRY_NOPROFILE(rom_lseek)
linkw %a6, #0
moveml %d2-%d7/%a0-%a5,%sp@- | save %d2-%d7, %a2-%a5
moveq #SYS_lseek, %d0
SYSCALL
moveml %a6@(-40),%d0-%d7/%a2-%a5
unlk %a6
rts

View File

@ -0,0 +1,354 @@
/* $NetBSD: romcons.c,v 1.1 2011/11/20 15:38:00 tsutsui Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
* Copyright (C) 1995, 1996 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* romcons.c - from sys/dev/ofw/ofcons.c
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: romcons.c,v 1.1 2011/11/20 15:38:00 tsutsui Exp $");
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/callout.h>
#include <sys/tty.h>
#include <sys/kauth.h>
#include <dev/cons.h>
#include <machine/autoconf.h>
#include <machine/romcall.h>
#include "ioconf.h"
struct romcons_softc {
device_t sc_dev;
struct tty *sc_tty;
struct callout sc_poll_ch;
int sc_flags;
#define CONS_POLL 1
};
#define BURSTLEN 128 /* max number of bytes to write in one chunk */
cons_decl(romcons_);
static int romcons_match(device_t, cfdata_t, void *);
static void romcons_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(romcons, sizeof(struct romcons_softc),
romcons_match, romcons_attach, NULL, NULL);
dev_type_open(romcons_open);
dev_type_close(romcons_close);
dev_type_read(romcons_read);
dev_type_write(romcons_write);
dev_type_ioctl(romcons_ioctl);
dev_type_tty(romcons_tty);
dev_type_poll(romcons_poll);
void romcons_kbdinput(int);
const struct cdevsw romcons_cdevsw = {
romcons_open, romcons_close, romcons_read, romcons_write, romcons_ioctl,
nostop, romcons_tty, romcons_poll, nommap, ttykqfilter, D_TTY
};
struct consdev consdev_rom = cons_init(romcons_);
bool romcons_is_console;
static int
romcons_match(device_t parent, cfdata_t match, void *aux)
{
struct mainbus_attach_args *ma = aux;
static bool romcons_matched;
if (strcmp(ma->ma_name, "romcons"))
return 0;
if (!romcons_is_console)
return 0;
if (romcons_matched)
return 0;
romcons_matched = true;
return 1;
}
static void
romcons_attach(device_t parent, device_t self, void *aux)
{
struct romcons_softc *sc = device_private(self);
sc->sc_dev = self;
vectab[46] = romcallvec; /* XXX */
aprint_normal("\n");
callout_init(&sc->sc_poll_ch, 0);
}
static void romcons_start(struct tty *);
static int romcons_param(struct tty *, struct termios *);
static void romcons_pollin(void *);
int
romcons_open(dev_t dev, int flag, int mode, struct lwp *l)
{
struct romcons_softc *sc;
struct tty *tp;
sc = device_lookup_private(&romcons_cd, minor(dev));
if (sc == NULL)
return ENXIO;
if ((tp = sc->sc_tty) == 0)
sc->sc_tty = tp = tty_alloc();
tp->t_oproc = romcons_start;
tp->t_param = romcons_param;
tp->t_dev = dev;
if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
return EBUSY;
if ((tp->t_state & TS_ISOPEN) == 0) {
ttychars(tp);
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_cflag = TTYDEF_CFLAG;
tp->t_lflag = TTYDEF_LFLAG;
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
romcons_param(tp, &tp->t_termios);
ttsetwater(tp);
}
tp->t_state |= TS_CARR_ON;
if ((sc->sc_flags & CONS_POLL) == 0) {
sc->sc_flags |= CONS_POLL;
callout_reset(&sc->sc_poll_ch, 1, romcons_pollin, sc);
}
return (*tp->t_linesw->l_open)(dev, tp);
}
int
romcons_close(dev_t dev, int flag, int mode, struct lwp *l)
{
struct romcons_softc *sc;
struct tty *tp;
sc = device_lookup_private(&romcons_cd, minor(dev));
tp = sc->sc_tty;
callout_stop(&sc->sc_poll_ch);
sc->sc_flags &= ~CONS_POLL;
(*tp->t_linesw->l_close)(tp, flag);
ttyclose(tp);
return 0;
}
int
romcons_read(dev_t dev, struct uio *uio, int flag)
{
struct romcons_softc *sc;
struct tty *tp;
sc = device_lookup_private(&romcons_cd, minor(dev));
tp = sc->sc_tty;
return (*tp->t_linesw->l_read)(tp, uio, flag);
}
int
romcons_write(dev_t dev, struct uio *uio, int flag)
{
struct romcons_softc *sc;
struct tty *tp;
sc = device_lookup_private(&romcons_cd, minor(dev));
tp = sc->sc_tty;
return (*tp->t_linesw->l_write)(tp, uio, flag);
}
int
romcons_poll(dev_t dev, int events, struct lwp *l)
{
struct romcons_softc *sc;
struct tty *tp;
sc = device_lookup_private(&romcons_cd, minor(dev));
tp = sc->sc_tty;
return (*tp->t_linesw->l_poll)(tp, events, l);
}
int
romcons_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
struct romcons_softc *sc;
struct tty *tp;
int error;
sc = device_lookup_private(&romcons_cd, minor(dev));
tp = sc->sc_tty;
if ((error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l)) !=
EPASSTHROUGH)
return error;
return ttioctl(tp, cmd, data, flag, l);
}
struct tty *
romcons_tty(dev_t dev)
{
struct romcons_softc *sc;
sc = device_lookup_private(&romcons_cd, minor(dev));
return sc->sc_tty;
}
static void
romcons_start(struct tty *tp)
{
int s, len;
uint8_t buf[BURSTLEN];
s = spltty();
if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
splx(s);
return;
}
tp->t_state |= TS_BUSY;
splx(s);
len = q_to_b(&tp->t_outq, buf, BURSTLEN);
s = splhigh();
rom_write(1, buf, len);
splx(s);
s = spltty();
tp->t_state &= ~TS_BUSY;
if (ttypull(tp)) {
tp->t_state |= TS_TIMEOUT;
callout_schedule(&tp->t_rstrt_ch, 1);
}
splx(s);
}
static int
romcons_param(struct tty *tp, struct termios *t)
{
tp->t_ispeed = t->c_ispeed;
tp->t_ospeed = t->c_ospeed;
tp->t_cflag = t->c_cflag;
return 0;
}
static void
romcons_pollin(void *aux)
{
struct romcons_softc *sc = aux;
struct tty *tp = sc->sc_tty;
char ch;
int rv;
while (0 && (rv = rom_read(1, &ch, 1)) > 0) {
if (tp && (tp->t_state & TS_ISOPEN))
(*tp->t_linesw->l_rint)(ch, tp);
}
callout_reset(&sc->sc_poll_ch, 1, romcons_pollin, sc);
}
void
romcons_kbdinput(int ks)
{
struct romcons_softc *sc;
struct tty *tp;
sc = device_lookup_private(&romcons_cd, 0);
tp = sc->sc_tty;
if (tp && (tp->t_state & TS_ISOPEN))
(*tp->t_linesw->l_rint)(ks, tp);
}
void
romcons_cnprobe(struct consdev *cd)
{
}
void
romcons_cninit(struct consdev *cd)
{
int maj;
maj = cdevsw_lookup_major(&romcons_cdevsw);
cd->cn_dev = makedev(maj, 0);
romcons_is_console = true;
vectab[46] = romcallvec; /* XXX */
}
int
romcons_cngetc(dev_t dev)
{
unsigned char ch = '\0';
int l;
while ((l = rom_read(1, &ch, 1)) != 1)
if (l != -2 && l != 0)
return -1;
return ch;
}
void
romcons_cnputc(dev_t dev, int c)
{
char ch = c;
rom_write(1, &ch, 1);
}
void
romcons_cnpollc(dev_t dev, int on)
{
struct romcons_softc *sc;
sc = device_lookup_private(&romcons_cd, minor(dev));
if (sc == NULL)
return;
if (on) {
if (sc->sc_flags & CONS_POLL)
callout_stop(&sc->sc_poll_ch);
sc->sc_flags &= ~CONS_POLL;
} else {
if ((sc->sc_flags & CONS_POLL) == 0) {
sc->sc_flags |= CONS_POLL;
callout_reset(&sc->sc_poll_ch, 1, romcons_pollin, sc);
}
}
}