- Move timerreg.h to <arch>/include and split i8253 specific defines into

i8253reg.h, and add some defines to control a speaker.
- Move PPI related defines from i386/isa/spkr.c into ppireg.h and use them.
- Move IO_{PPI,TIMER} defines into ppireg.h and timerreg.h respectively.
- Use isa/isareg.h rather than <arch>/isa/isa.h.

Tested on: i386, pc98
This commit is contained in:
Yoshihiro Takahashi 2005-05-14 09:10:02 +00:00
parent bc3729b63f
commit 24072ca35b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=146211
27 changed files with 542 additions and 370 deletions

View File

@ -60,9 +60,10 @@ __FBSDID("$FreeBSD$");
#include <machine/cpuconf.h>
#include <machine/md_var.h>
#include <machine/rpb.h> /* for CPU definitions, etc */
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <isa/isareg.h>
#include <alpha/alpha/timerreg.h>
#define SECMIN ((unsigned)60) /* seconds per minute */
#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
@ -704,8 +705,8 @@ release_timer2(void)
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
release_timer2();
ppi_spkr_off(); /* disable counter2 output to speaker */
timer_spkr_release();
beeping = 0;
}
@ -723,7 +724,7 @@ sysbeep(int pitch, int period)
mtx_lock_spin(&clock_lock);
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
if (timer_spkr_acquire())
if (!beeping) {
/* Something else owns it. */
mtx_unlock_spin(&clock_lock);
@ -732,12 +733,11 @@ sysbeep(int pitch, int period)
if (pitch) pitch = TIMER_DIV(pitch);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
spkr_set_pitch(pitch);
mtx_unlock_spin(&clock_lock);
if (!beeping) {
/* enable counter2 output to speaker */
if (pitch) outb(IO_PPI, inb(IO_PPI) | 3);
if (pitch) ppi_spkr_on();
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}

View File

@ -0,0 +1,49 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PPIREG_H_
#define _MACHINE_PPIREG_H_
#ifdef _KERNEL
#define IO_PPI 0x61 /* Programmable Peripheral Interface */
/*
* PPI speaker control values
*/
#define PIT_ENABLETMR2 0x01 /* Enable timer/counter 2 */
#define PIT_SPKRDATA 0x02 /* Direct to speaker */
#define PIT_SPKR (PIT_ENABLETMR2 | PIT_SPKRDATA)
#define ppi_spkr_on() outb(IO_PPI, inb(IO_PPI) | PIT_SPKR)
#define ppi_spkr_off() outb(IO_PPI, inb(IO_PPI) & ~PIT_SPKR)
#endif /* _KERNEL */
#endif /* _MACHINE_PPIREG_H_ */

View File

@ -0,0 +1,67 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
/*
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> dma chan 0 (for dram refresh)
* timer 2 -> speaker (via keyboard controller)
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
*/
#ifndef _MACHINE_TIMERREG_H_
#define _MACHINE_TIMERREG_H_
#ifdef _KERNEL
#include <dev/ic/i8253reg.h>
#define IO_TIMER1 0x40 /* 8253 Timer #1 */
#define TIMER_CNTR0 (IO_TIMER1 + TIMER_REG_CNTR0)
#define TIMER_CNTR1 (IO_TIMER1 + TIMER_REG_CNTR1)
#define TIMER_CNTR2 (IO_TIMER1 + TIMER_REG_CNTR2)
#define TIMER_MODE (IO_TIMER1 + TIMER_REG_MODE)
#define timer_spkr_acquire() \
acquire_timer2(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT)
#define timer_spkr_release() \
release_timer2()
static __inline void
spkr_set_pitch(u_int16_t pitch)
{
outb(TIMER_CNTR2, pitch & 0xff);
outb(TIMER_CNTR2, pitch >> 8);
}
#endif /* _KERNEL */
#endif /* _MACHINE_TIMERREG_H_ */

View File

@ -48,9 +48,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <machine/asmacros.h>
#include <i386/isa/isa.h>
#include <i386/isa/timerreg.h>
#include <machine/timerreg.h>
#ifdef GUPROF
#define CPUTIME_CLOCK_UNINITIALIZED 0

View File

@ -0,0 +1,49 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PPIREG_H_
#define _MACHINE_PPIREG_H_
#ifdef _KERNEL
#define IO_PPI 0x61 /* Programmable Peripheral Interface */
/*
* PPI speaker control values
*/
#define PIT_ENABLETMR2 0x01 /* Enable timer/counter 2 */
#define PIT_SPKRDATA 0x02 /* Direct to speaker */
#define PIT_SPKR (PIT_ENABLETMR2 | PIT_SPKRDATA)
#define ppi_spkr_on() outb(IO_PPI, inb(IO_PPI) | PIT_SPKR)
#define ppi_spkr_off() outb(IO_PPI, inb(IO_PPI) & ~PIT_SPKR)
#endif /* _KERNEL */
#endif /* _MACHINE_PPIREG_H_ */

View File

@ -0,0 +1,67 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
/*
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> dma chan 0 (for dram refresh)
* timer 2 -> speaker (via keyboard controller)
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
*/
#ifndef _MACHINE_TIMERREG_H_
#define _MACHINE_TIMERREG_H_
#ifdef _KERNEL
#include <dev/ic/i8253reg.h>
#define IO_TIMER1 0x40 /* 8253 Timer #1 */
#define TIMER_CNTR0 (IO_TIMER1 + TIMER_REG_CNTR0)
#define TIMER_CNTR1 (IO_TIMER1 + TIMER_REG_CNTR1)
#define TIMER_CNTR2 (IO_TIMER1 + TIMER_REG_CNTR2)
#define TIMER_MODE (IO_TIMER1 + TIMER_REG_MODE)
#define timer_spkr_acquire() \
acquire_timer2(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT)
#define timer_spkr_release() \
release_timer2()
static __inline void
spkr_set_pitch(u_int16_t pitch)
{
outb(TIMER_CNTR2, pitch & 0xff);
outb(TIMER_CNTR2, pitch >> 8);
}
#endif /* _KERNEL */
#endif /* _MACHINE_TIMERREG_H_ */

View File

@ -72,13 +72,14 @@ __FBSDID("$FreeBSD$");
#include <machine/psl.h>
#include <machine/apicvar.h>
#include <machine/specialreg.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <amd64/isa/isa.h>
#include <isa/rtc.h>
#ifdef DEV_ISA
#include <isa/isareg.h>
#include <isa/isavar.h>
#endif
#include <amd64/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
@ -365,8 +366,8 @@ DELAY(int n)
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
release_timer2();
ppi_spkr_off(); /* disable counter2 output to speaker */
timer_spkr_release();
beeping = 0;
}
@ -375,19 +376,18 @@ sysbeep(int pitch, int period)
{
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
if (timer_spkr_acquire())
if (!beeping) {
/* Something else owns it. */
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
mtx_lock_spin(&clock_lock);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
spkr_set_pitch(pitch);
mtx_unlock_spin(&clock_lock);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
ppi_spkr_on();
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}

View File

@ -52,10 +52,7 @@
#define IO_DMA1 0x000 /* 8237A DMA Controller #1 */
#define IO_ICU1 0x020 /* 8259A Interrupt Controller #1 */
#define IO_PMP1 0x026 /* 82347 Power Management Peripheral */
#define IO_TIMER1 0x040 /* 8253 Timer #1 */
#define IO_TIMER2 0x048 /* 8253 Timer #2 */
#define IO_KBD 0x060 /* 8042 Keyboard */
#define IO_PPI 0x061 /* Programmable Peripheral Interface */
#define IO_RTC 0x070 /* RTC */
#define IO_NMI IO_RTC /* NMI Control */
#define IO_DMAPG 0x080 /* DMA Page Registers */

View File

@ -1,90 +0,0 @@
/*-
* Copyright (c) 1993 The Regents of the University of California.
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
* $FreeBSD$
*/
/*
*
* Register definitions for the Intel 8253 Programmable Interval Timer.
*
* This chip has three independent 16-bit down counters that can be
* read on the fly. There are three mode registers and three countdown
* registers. The countdown registers are addressed directly, via the
* first three I/O ports. The three mode registers are accessed via
* the fourth I/O port, with two bits in the mode byte indicating the
* register. (Why are hardware interfaces always so braindead?).
*
* To write a value into the countdown register, the mode register
* is first programmed with a command indicating the which byte of
* the two byte register is to be modified. The three possibilities
* are load msb (TMR_MR_MSB), load lsb (TMR_MR_LSB), or load lsb then
* msb (TMR_MR_BOTH).
*
* To read the current value ("on the fly") from the countdown register,
* you write a "latch" command into the mode register, then read the stable
* value from the corresponding I/O port. For example, you write
* TMR_MR_LATCH into the corresponding mode register. Presumably,
* after doing this, a write operation to the I/O port would result
* in undefined behavior (but hopefully not fry the chip).
* Reading in this manner has no side effects.
*
* [AMD64]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> dma chan 0 (for dram refresh)
* timer 2 -> speaker (via keyboard controller)
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
*/
/*
* Macros for specifying values to be written into a mode register.
*/
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
#define TIMER_LATCH 0x00 /* latch counter for reading */
#define TIMER_LSB 0x10 /* r/w counter LSB */
#define TIMER_MSB 0x20 /* r/w counter MSB */
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
#define TIMER_BCD 0x01 /* count in BCD */

View File

@ -31,7 +31,6 @@
*/
/*
*
* Register definitions for the Intel 8253 Programmable Interval Timer.
*
* This chip has three independent 16-bit down counters that can be
@ -54,25 +53,15 @@
* after doing this, a write operation to the I/O port would result
* in undefined behavior (but hopefully not fry the chip).
* Reading in this manner has no side effects.
*
* [ALPHA]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> dma chan 0 (for dram refresh)
* timer 2 -> speaker (via keyboard controller)
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
*/
/*
* Macros for specifying values to be written into a mode register.
*/
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
#define TIMER_REG_CNTR0 0 /* timer 0 counter port */
#define TIMER_REG_CNTR1 1 /* timer 1 counter port */
#define TIMER_REG_CNTR2 2 /* timer 2 counter port */
#define TIMER_REG_MODE 3 /* timer mode port */
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
@ -87,4 +76,3 @@
#define TIMER_MSB 0x20 /* r/w counter MSB */
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
#define TIMER_BCD 0x01 /* count in BCD */

View File

@ -19,14 +19,10 @@ __FBSDID("$FreeBSD$");
#include <sys/ctype.h>
#include <sys/malloc.h>
#include <isa/isavar.h>
#ifdef PC98
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
#include <i386/isa/timerreg.h>
#include <machine/clock.h>
#include <machine/speaker.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
static d_open_t spkropen;
static d_close_t spkrclose;
@ -58,34 +54,10 @@ static MALLOC_DEFINE(M_SPKR, "spkr", "Speaker buffer");
* used to generate clicks (a square wave) of whatever frequency is desired.
*/
/*
* XXX PPI control values should be in a header and used in clock.c.
*/
#ifdef PC98
#define SPKR_DESC "PC98 speaker"
#define PPI_SPKR 0x08 /* turn these PPI bits on to pass sound */
#define PIT_COUNT 0x3fdb /* PIT count address */
#define SPEAKER_ON outb(IO_PPI, inb(IO_PPI) & ~PPI_SPKR)
#define SPEAKER_OFF outb(IO_PPI, inb(IO_PPI) | PPI_SPKR)
#define TIMER_ACQUIRE acquire_timer1(TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT)
#define TIMER_RELEASE release_timer1()
#define SPEAKER_WRITE(val) { \
outb(PIT_COUNT, (val & 0xff)); \
outb(PIT_COUNT, (val >> 8)); \
}
#else
#define SPKR_DESC "PC speaker"
#define PPI_SPKR 0x03 /* turn these PPI bits on to pass sound */
#define SPEAKER_ON outb(IO_PPI, inb(IO_PPI) | PPI_SPKR)
#define SPEAKER_OFF outb(IO_PPI, inb(IO_PPI) & ~PPI_SPKR)
#define TIMER_ACQUIRE acquire_timer2(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT)
#define TIMER_RELEASE release_timer2()
#define SPEAKER_WRITE(val) { \
outb(TIMER_CNTR2, (val & 0xff)); \
outb(TIMER_CNTR2, (val >> 8)); \
}
#endif
#define SPKRPRI PSOCK
@ -117,18 +89,18 @@ tone(thz, ticks)
/* set timer to generate clicks at given frequency in Hertz */
sps = splclock();
if (TIMER_ACQUIRE) {
if (timer_spkr_acquire()) {
/* enter list of waiting procs ??? */
splx(sps);
return;
}
splx(sps);
disable_intr();
SPEAKER_WRITE(divisor);
spkr_set_pitch(divisor);
enable_intr();
/* turn the speaker on */
SPEAKER_ON;
ppi_spkr_on();
/*
* Set timeout to endtone function, then give up the timeslice.
@ -137,9 +109,9 @@ tone(thz, ticks)
*/
if (ticks > 0)
tsleep(&endtone, SPKRPRI | PCATCH, "spkrtn", ticks);
SPEAKER_OFF;
ppi_spkr_off();
sps = splclock();
TIMER_RELEASE;
timer_spkr_release();
splx(sps);
}

49
sys/i386/include/ppireg.h Normal file
View File

@ -0,0 +1,49 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PPIREG_H_
#define _MACHINE_PPIREG_H_
#ifdef _KERNEL
#define IO_PPI 0x61 /* Programmable Peripheral Interface */
/*
* PPI speaker control values
*/
#define PIT_ENABLETMR2 0x01 /* Enable timer/counter 2 */
#define PIT_SPKRDATA 0x02 /* Direct to speaker */
#define PIT_SPKR (PIT_ENABLETMR2 | PIT_SPKRDATA)
#define ppi_spkr_on() outb(IO_PPI, inb(IO_PPI) | PIT_SPKR)
#define ppi_spkr_off() outb(IO_PPI, inb(IO_PPI) & ~PIT_SPKR)
#endif /* _KERNEL */
#endif /* _MACHINE_PPIREG_H_ */

View File

@ -0,0 +1,67 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
/*
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> dma chan 0 (for dram refresh)
* timer 2 -> speaker (via keyboard controller)
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
*/
#ifndef _MACHINE_TIMERREG_H_
#define _MACHINE_TIMERREG_H_
#ifdef _KERNEL
#include <dev/ic/i8253reg.h>
#define IO_TIMER1 0x40 /* 8253 Timer #1 */
#define TIMER_CNTR0 (IO_TIMER1 + TIMER_REG_CNTR0)
#define TIMER_CNTR1 (IO_TIMER1 + TIMER_REG_CNTR1)
#define TIMER_CNTR2 (IO_TIMER1 + TIMER_REG_CNTR2)
#define TIMER_MODE (IO_TIMER1 + TIMER_REG_MODE)
#define timer_spkr_acquire() \
acquire_timer2(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT)
#define timer_spkr_release() \
release_timer2()
static __inline void
spkr_set_pitch(u_int16_t pitch)
{
outb(TIMER_CNTR2, pitch & 0xff);
outb(TIMER_CNTR2, pitch >> 8);
}
#endif /* _KERNEL */
#endif /* _MACHINE_TIMERREG_H_ */

View File

@ -77,13 +77,14 @@ __FBSDID("$FreeBSD$");
#include <machine/apicvar.h>
#endif
#include <machine/specialreg.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <i386/isa/isa.h>
#include <isa/rtc.h>
#ifdef DEV_ISA
#include <isa/isareg.h>
#include <isa/isavar.h>
#endif
#include <i386/isa/timerreg.h>
#ifdef DEV_MCA
#include <i386/bios/mca_machdep.h>
@ -379,8 +380,8 @@ DELAY(int n)
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
release_timer2();
ppi_spkr_off(); /* disable counter2 output to speaker */
timer_spkr_release();
beeping = 0;
}
@ -389,19 +390,18 @@ sysbeep(int pitch, int period)
{
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
if (timer_spkr_acquire())
if (!beeping) {
/* Something else owns it. */
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
mtx_lock_spin(&clock_lock);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
spkr_set_pitch(pitch);
mtx_unlock_spin(&clock_lock);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
ppi_spkr_on();
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}

View File

@ -56,10 +56,7 @@
#define IO_DMA1 0x000 /* 8237A DMA Controller #1 */
#define IO_ICU1 0x020 /* 8259A Interrupt Controller #1 */
#define IO_PMP1 0x026 /* 82347 Power Management Peripheral */
#define IO_TIMER1 0x040 /* 8253 Timer #1 */
#define IO_TIMER2 0x048 /* 8253 Timer #2 */
#define IO_KBD 0x060 /* 8042 Keyboard */
#define IO_PPI 0x061 /* Programmable Peripheral Interface */
#define IO_RTC 0x070 /* RTC */
#define IO_NMI IO_RTC /* NMI Control */
#define IO_DMAPG 0x080 /* DMA Page Registers */

View File

@ -44,13 +44,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <machine/asmacros.h>
#ifdef PC98
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
#include <i386/isa/timerreg.h>
#include <machine/timerreg.h>
#ifdef GUPROF
#define CPUTIME_CLOCK_UNINITIALIZED 0

View File

@ -19,14 +19,10 @@ __FBSDID("$FreeBSD$");
#include <sys/ctype.h>
#include <sys/malloc.h>
#include <isa/isavar.h>
#ifdef PC98
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif
#include <i386/isa/timerreg.h>
#include <machine/clock.h>
#include <machine/speaker.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
static d_open_t spkropen;
static d_close_t spkrclose;
@ -58,34 +54,10 @@ static MALLOC_DEFINE(M_SPKR, "spkr", "Speaker buffer");
* used to generate clicks (a square wave) of whatever frequency is desired.
*/
/*
* XXX PPI control values should be in a header and used in clock.c.
*/
#ifdef PC98
#define SPKR_DESC "PC98 speaker"
#define PPI_SPKR 0x08 /* turn these PPI bits on to pass sound */
#define PIT_COUNT 0x3fdb /* PIT count address */
#define SPEAKER_ON outb(IO_PPI, inb(IO_PPI) & ~PPI_SPKR)
#define SPEAKER_OFF outb(IO_PPI, inb(IO_PPI) | PPI_SPKR)
#define TIMER_ACQUIRE acquire_timer1(TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT)
#define TIMER_RELEASE release_timer1()
#define SPEAKER_WRITE(val) { \
outb(PIT_COUNT, (val & 0xff)); \
outb(PIT_COUNT, (val >> 8)); \
}
#else
#define SPKR_DESC "PC speaker"
#define PPI_SPKR 0x03 /* turn these PPI bits on to pass sound */
#define SPEAKER_ON outb(IO_PPI, inb(IO_PPI) | PPI_SPKR)
#define SPEAKER_OFF outb(IO_PPI, inb(IO_PPI) & ~PPI_SPKR)
#define TIMER_ACQUIRE acquire_timer2(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT)
#define TIMER_RELEASE release_timer2()
#define SPEAKER_WRITE(val) { \
outb(TIMER_CNTR2, (val & 0xff)); \
outb(TIMER_CNTR2, (val >> 8)); \
}
#endif
#define SPKRPRI PSOCK
@ -117,18 +89,18 @@ tone(thz, ticks)
/* set timer to generate clicks at given frequency in Hertz */
sps = splclock();
if (TIMER_ACQUIRE) {
if (timer_spkr_acquire()) {
/* enter list of waiting procs ??? */
splx(sps);
return;
}
splx(sps);
disable_intr();
SPEAKER_WRITE(divisor);
spkr_set_pitch(divisor);
enable_intr();
/* turn the speaker on */
SPEAKER_ON;
ppi_spkr_on();
/*
* Set timeout to endtone function, then give up the timeslice.
@ -137,9 +109,9 @@ tone(thz, ticks)
*/
if (ticks > 0)
tsleep(&endtone, SPKRPRI | PCATCH, "spkrtn", ticks);
SPEAKER_OFF;
ppi_spkr_off();
sps = splclock();
TIMER_RELEASE;
timer_spkr_release();
splx(sps);
}

View File

@ -1,106 +0,0 @@
/*-
* Copyright (c) 1993 The Regents of the University of California.
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
* $FreeBSD$
*/
/*
*
* Register definitions for the Intel 8253 Programmable Interval Timer.
*
* This chip has three independent 16-bit down counters that can be
* read on the fly. There are three mode registers and three countdown
* registers. The countdown registers are addressed directly, via the
* first three I/O ports. The three mode registers are accessed via
* the fourth I/O port, with two bits in the mode byte indicating the
* register. (Why are hardware interfaces always so braindead?).
*
* To write a value into the countdown register, the mode register
* is first programmed with a command indicating the which byte of
* the two byte register is to be modified. The three possibilities
* are load msb (TMR_MR_MSB), load lsb (TMR_MR_LSB), or load lsb then
* msb (TMR_MR_BOTH).
*
* To read the current value ("on the fly") from the countdown register,
* you write a "latch" command into the mode register, then read the stable
* value from the corresponding I/O port. For example, you write
* TMR_MR_LATCH into the corresponding mode register. Presumably,
* after doing this, a write operation to the I/O port would result
* in undefined behavior (but hopefully not fry the chip).
* Reading in this manner has no side effects.
*
* [IBM-PC]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> dma chan 0 (for dram refresh)
* timer 2 -> speaker (via keyboard controller)
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
*
* [PC-9801]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> speaker (via keyboard controller)
* timer 2 -> RS232C
*
* Timer 0 is used to call hardclock.
* Timer 1 is used to generate console beeps.
*/
/*
* Macros for specifying values to be written into a mode register.
*/
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
#ifdef PC98
#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
#else
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
#endif
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
#define TIMER_LATCH 0x00 /* latch counter for reading */
#define TIMER_LSB 0x10 /* r/w counter LSB */
#define TIMER_MSB 0x20 /* r/w counter MSB */
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
#define TIMER_BCD 0x01 /* count in BCD */

View File

@ -77,13 +77,14 @@ __FBSDID("$FreeBSD$");
#include <machine/apicvar.h>
#endif
#include <machine/specialreg.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <i386/isa/isa.h>
#include <isa/rtc.h>
#ifdef DEV_ISA
#include <isa/isareg.h>
#include <isa/isavar.h>
#endif
#include <i386/isa/timerreg.h>
#ifdef DEV_MCA
#include <i386/bios/mca_machdep.h>
@ -379,8 +380,8 @@ DELAY(int n)
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
release_timer2();
ppi_spkr_off(); /* disable counter2 output to speaker */
timer_spkr_release();
beeping = 0;
}
@ -389,19 +390,18 @@ sysbeep(int pitch, int period)
{
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
if (timer_spkr_acquire())
if (!beeping) {
/* Something else owns it. */
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
mtx_lock_spin(&clock_lock);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
spkr_set_pitch(pitch);
mtx_unlock_spin(&clock_lock);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
ppi_spkr_on();
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}

View File

@ -56,10 +56,7 @@
#define IO_DMA1 0x000 /* 8237A DMA Controller #1 */
#define IO_ICU1 0x020 /* 8259A Interrupt Controller #1 */
#define IO_PMP1 0x026 /* 82347 Power Management Peripheral */
#define IO_TIMER1 0x040 /* 8253 Timer #1 */
#define IO_TIMER2 0x048 /* 8253 Timer #2 */
#define IO_KBD 0x060 /* 8042 Keyboard */
#define IO_PPI 0x061 /* Programmable Peripheral Interface */
#define IO_RTC 0x070 /* RTC */
#define IO_NMI IO_RTC /* NMI Control */
#define IO_DMAPG 0x080 /* DMA Page Registers */

View File

@ -43,14 +43,14 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/md_var.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <machine/pc/bios.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_param.h>
#include <i386/isa/timerreg.h>
#define BIOS_CLKED (1 << 6)
#define BIOS_NLKED (1 << 5)
#define BIOS_SLKED (1 << 4)
@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
#include <dev/syscons/syscons.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
static devclass_t sc_devclass;
@ -256,22 +255,18 @@ int
sc_tone(int herz)
{
#if defined(__i386__) || defined(__amd64__)
int pitch;
if (herz) {
/* set command for counter 2, 2 byte write */
if (acquire_timer2(TIMER_16BIT | TIMER_SQWAVE))
if (timer_spkr_acquire())
return EBUSY;
/* set pitch */
pitch = timer_freq/herz;
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, pitch >> 8);
spkr_set_pitch(timer_freq / herz);
/* enable counter 2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
ppi_spkr_on();
} else {
/* disable counter 2 output to speaker */
outb(IO_PPI, inb(IO_PPI) & 0xFC);
release_timer2();
ppi_spkr_off();
timer_spkr_release();
}
#endif

View File

@ -57,9 +57,7 @@
#define IO_ICU2 0x008 /* 8259A Interrupt Controller #2 */
#define IO_RTC 0x020 /* 4990A RTC */
#define IO_SYSPORT 0x031 /* 8255A System Port */
#define IO_PPI 0x035 /* Programmable Peripheral Interface */
#define IO_KBD 0x041 /* 8251A Keyboard */
#define IO_TIMER1 0x071 /* 8253C Timer */
#define IO_COM2 0x0B1 /* 8251A RS232C serial I/O (ext) */
#define IO_COM3 0x0B9 /* 8251A RS232C serial I/O (ext) */
#define IO_FDPORT 0x0BE /* FD I/F port (1M<->640K,EMTON) */

View File

@ -79,6 +79,8 @@
#include <machine/apicvar.h>
#endif
#include <machine/specialreg.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <i386/isa/icu.h>
#include <pc98/cbus/cbus.h>
@ -86,7 +88,6 @@
#ifdef DEV_ISA
#include <isa/isavar.h>
#endif
#include <i386/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
@ -357,8 +358,8 @@ DELAY(int n)
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)|0x08); /* disable counter1 output to speaker */
release_timer1();
ppi_spkr_off(); /* disable counter1 output to speaker */
timer_spkr_release();
beeping = 0;
}
@ -367,19 +368,18 @@ sysbeep(int pitch, int period)
{
int x = splclock();
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
if (timer_spkr_acquire())
if (!beeping) {
/* Something else owns it. */
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
disable_intr();
outb(0x3fdb, pitch);
outb(0x3fdb, (pitch>>8));
spkr_set_pitch(pitch);
enable_intr();
if (!beeping) {
/* enable counter1 output to speaker */
outb(IO_PPI, (inb(IO_PPI) & 0xf7));
ppi_spkr_on();
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}

View File

@ -79,6 +79,8 @@
#include <machine/apicvar.h>
#endif
#include <machine/specialreg.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <i386/isa/icu.h>
#include <pc98/cbus/cbus.h>
@ -86,7 +88,6 @@
#ifdef DEV_ISA
#include <isa/isavar.h>
#endif
#include <i386/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
@ -357,8 +358,8 @@ DELAY(int n)
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)|0x08); /* disable counter1 output to speaker */
release_timer1();
ppi_spkr_off(); /* disable counter1 output to speaker */
timer_spkr_release();
beeping = 0;
}
@ -367,19 +368,18 @@ sysbeep(int pitch, int period)
{
int x = splclock();
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
if (timer_spkr_acquire())
if (!beeping) {
/* Something else owns it. */
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
disable_intr();
outb(0x3fdb, pitch);
outb(0x3fdb, (pitch>>8));
spkr_set_pitch(pitch);
enable_intr();
if (!beeping) {
/* enable counter1 output to speaker */
outb(IO_PPI, (inb(IO_PPI) & 0xf7));
ppi_spkr_on();
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}

View File

@ -38,14 +38,14 @@
#include <sys/sysctl.h>
#include <machine/clock.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#include <dev/syscons/syscons.h>
#include <i386/isa/timerreg.h>
#include <isa/isavar.h>
static devclass_t sc_devclass;
@ -227,22 +227,19 @@ sc_get_bios_values(bios_values_t *values)
int
sc_tone(int herz)
{
int pitch;
if (herz) {
/* enable counter 1 */
outb(0x35, inb(0x35) & 0xf7);
ppi_spkr_on();
/* set command for counter 1, 2 byte write */
if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
if (timer_spkr_acquire())
return EBUSY;
/* set pitch */
pitch = timer_freq/herz;
outb(TIMER_CNTR1, pitch);
outb(TIMER_CNTR1, pitch >> 8);
spkr_set_pitch(timer_freq / herz);
} else {
/* disable counter 1 */
outb(0x35, inb(0x35) | 0x08);
release_timer1();
ppi_spkr_off();
timer_spkr_release();
}
return 0;
}

48
sys/pc98/include/ppireg.h Normal file
View File

@ -0,0 +1,48 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PPIREG_H_
#define _MACHINE_PPIREG_H_
#ifdef _KERNEL
#define IO_PPI 0x35 /* Programmable Peripheral Interface */
/*
* PPI speaker control values
*/
#define PIT_ENABLETMR1 0x08 /* Enable timer/counter 1 */
#define PIT_SPKR (PIT_ENABLETMR1)
#define ppi_spkr_on() outb(IO_PPI, inb(IO_PPI) & ~PIT_SPKR)
#define ppi_spkr_off() outb(IO_PPI, inb(IO_PPI) | PIT_SPKR)
#endif /* _KERNEL */
#endif /* _MACHINE_PPIREG_H_ */

View File

@ -0,0 +1,67 @@
/*-
* Copyright (C) 2005 TAKAHASHI Yoshihiro. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
*
* $FreeBSD$
*/
/*
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
* timer 1 -> speaker (via keyboard controller)
* timer 2 -> RS-232C
*
* Timer 0 is used to call hardclock.
* Timer 1 is used to generate console beeps.
*/
#ifndef _MACHINE_TIMERREG_H_
#define _MACHINE_TIMERREG_H_
#ifdef _KERNEL
#include <dev/ic/i8253reg.h>
#define IO_TIMER1 0x71 /* 8253C Timer */
#define TIMER_CNTR0 (IO_TIMER1 + TIMER_REG_CNTR0 * 2)
#define TIMER_CNTR1 0x3fdb
#define TIMER_CNTR2 (IO_TIMER1 + TIMER_REG_CNTR2 * 2)
#define TIMER_MODE (IO_TIMER1 + TIMER_REG_MODE * 2)
#define timer_spkr_acquire() \
acquire_timer1(TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT)
#define timer_spkr_release() \
release_timer1()
static __inline void
spkr_set_pitch(u_int16_t pitch)
{
outb(TIMER_CNTR1, pitch & 0xff);
outb(TIMER_CNTR1, pitch >> 8);
}
#endif /* _KERNEL */
#endif /* _MACHINE_TIMERREG_H_ */