Home | History | Annotate | Line # | Download | only in pg68k
      1 /*	$NetBSD: control.h,v 1.1 2026/07/19 01:48:24 thorpej Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2026 Jason R. Thorpe.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #ifndef _PG68k_CONTROL_H_
     30 #define	_PG68k_CONTROL_H_
     31 
     32 #include <machine/fcode.h>
     33 
     34 #define	FC_CONTROL	4
     35 
     36 /*
     37  * Definitions for the Phaethon 1 Board Control Space.
     38  *
     39  * The Phaethon 1 has some low-level board control registers that
     40  * are used during early bootstrap and independently of the state
     41  * of the MMU.  These registers are accessible via FC#4.
     42  *
     43  * Board Control Space is defined as having an address like so:
     44  *
     45  * xxxx.xxxx xxxx.xxxx xxxx.000x
     46  *                          ^^^
     47  *              Board Control Space selector
     48  *
     49  * A GAL22V10 is programmed with equations to decode the following
     50  * addresses for these registers implemented w/ garden-variety 74HCT
     51  * logic ICs:
     52  *
     53  * xxxx.xxxx xxxx.xxxx 0000.0000 - Diagnostic 7-segment display (upper digit)
     54  * xxxx.xxxx xxxx.xxxx 0000.0001 - Diagnostic 7-segment display (lower digit)
     55  * xxxx.xxxx xxxx.xxxx 0001.000x - Configuration switches (16 bits)
     56  * xxxx.xxxx xxxx.xxxx 0010.0000 - System Enable register
     57  *
     58  * Additionally, the I/O controller has 2 registers related to software
     59  * interrupts:
     60  *
     61  * xxxx.xxxx xxxx.xxxx 0100.0000 - Interrupt Set (1 byte)
     62  * xxxx.xxxx xxxx.xxxx 0101.0000 - Interrupt Clear (1 byte)
     63  */
     64 
     65 #define	CTLREG_DD7SEG_U	0x00	/* 7-segment display, upper */
     66 #define	CTLREG_DD7SEG_L	0x01	/* 7-segment display, lower */
     67 
     68 	/* 7-segment display can be written as a single word */
     69 #define	CTLREG_DD7SEG	CTLREG_DD7SEG_U
     70 
     71 #define	CTLREG_CFGSW_U	0x10	/* configuration switches, bits 15..8 */
     72 #define	CTLREG_CFGSW_L	0x11	/* configuration switches, bits 7..0 */
     73 
     74 	/* configuration switches can be read as a single word */
     75 #define	CTLREG_CFGSW	CTLREG_CFGSW_U
     76 
     77 #define	CTLREG_SYSEN	0x20	/* system enable register */
     78 
     79 /*
     80  * 7-segment display registers.
     81  *
     82  *           A
     83  *      +---------+
     84  *      |         |
     85  *      |         |
     86  *    F |         | B
     87  *      |         |
     88  *      |    G    |
     89  *      +---------+
     90  *      |         |
     91  *      |         |
     92  *    E |         | C
     93  *      |         |
     94  *      |         |
     95  *      +---------+
     96  *           D
     97  *
     98  * The segments are active-low.
     99  */
    100 #define	DD7SEG_A	0x01
    101 #define	DD7SEG_B	0x02
    102 #define	DD7SEG_C	0x04
    103 #define	DD7SEG_D	0x08
    104 #define	DD7SEG_E	0x10
    105 #define	DD7SEG_F	0x20
    106 #define	DD7SEG_G	0x40
    107 
    108 /*
    109  * Configuration switches
    110  *
    111  * These allow for hands-on actual physical control of the computer's
    112  * behavior.  Crazy, right?
    113  *
    114  * Configuration switches are active-high.
    115  *
    116  * All bits not defined here are reserved.
    117  */
    118 /*	Yah, they're all reserved right now.	*/
    119 
    120 /*
    121  * System Enable Register
    122  *
    123  * This register contains bits that enable some important things,
    124  * namely the MMU and interrupts.
    125  *
    126  * Oh, there's also a software bit (or maybe two or three in the future?)
    127  * to let the operating system hand-shake reboot behavior with the
    128  * firmware.
    129  *
    130  * All other bits not defined here are reserved.
    131  */
    132 #define	SYSEN_MMU	0x01		/* enable MMU */
    133 #define	SYSEN_INT	0x02		/* enable interrupts */
    134 #define	SYSEN_HOWTO	0xc0		/* boot howto mask */
    135 #define	SYSEN_HOWTO_SHIFT 6
    136 
    137 #ifdef _KERNEL
    138 
    139 static inline uint8_t
    140 control_inb(unsigned long addr)
    141 {
    142 	int sfc = getsfc();
    143 	uint8_t rv;
    144 
    145 	setsfc(FC_CONTROL);
    146 	__asm __volatile("moves.b (%1),%0" : "=d" (rv) : "a" (addr));
    147 	setsfc(sfc);
    148 
    149 	return rv;
    150 }
    151 
    152 static inline void
    153 control_outb(unsigned long addr, uint8_t val)
    154 {
    155 	int dfc = getdfc();
    156 
    157 	setdfc(FC_CONTROL);
    158 	__asm __volatile("moves.b %0,(%1)" :: "d" (val), "a" (addr) : "memory");
    159 	setdfc(dfc);
    160 }
    161 
    162 static inline uint16_t
    163 control_inw(unsigned long addr)
    164 {
    165 	int sfc = getsfc();
    166 	uint16_t rv;
    167 
    168 	setsfc(FC_CONTROL);
    169 	__asm __volatile("moves.w (%1),%0" : "=d" (rv) : "a" (addr));
    170 	setsfc(sfc);
    171 
    172 	return rv;
    173 }
    174 
    175 static inline void
    176 control_outw(unsigned long addr, uint16_t val)
    177 {
    178 	int dfc = getdfc();
    179 
    180 	setdfc(FC_CONTROL);
    181 	__asm __volatile("moves.w %0,(%1)" :: "d" (val), "a" (addr) : "memory");
    182 	setdfc(dfc);
    183 }
    184 
    185 static inline uint32_t
    186 control_inl(unsigned long addr)
    187 {
    188 	int sfc = getsfc();
    189 	uint32_t rv;
    190 
    191 	setsfc(FC_CONTROL);
    192 	__asm __volatile("moves.l (%1),%0" : "=d" (rv) : "a" (addr));
    193 	setsfc(sfc);
    194 
    195 	return rv;
    196 }
    197 
    198 static inline void
    199 control_outl(unsigned long addr, uint32_t val)
    200 {
    201 	int dfc = getdfc();
    202 
    203 	setdfc(FC_CONTROL);
    204 	__asm __volatile("moves.l %0,(%1)" :: "d" (val), "a" (addr) : "memory");
    205 	setdfc(dfc);
    206 }
    207 
    208 #endif /* _KERNEL */
    209 
    210 #endif /* _PG68k_CONTROL_H_ */
    211