1 |
/* gxemul: $Id: mc146818reg.h,v 1.4 2005/03/05 12:34:02 debug Exp $ */ |
2 |
|
3 |
#ifndef MC146818_REG_H |
4 |
#define MC146818_REG_H |
5 |
|
6 |
#ifndef __P |
7 |
#define __P(x) x |
8 |
#endif |
9 |
|
10 |
/* $NetBSD: mc146818reg.h,v 1.2 1997/03/12 06:53:42 cgd Exp $ */ |
11 |
|
12 |
/* |
13 |
* Copyright (c) 1995 Carnegie-Mellon University. |
14 |
* All rights reserved. |
15 |
* |
16 |
* Permission to use, copy, modify and distribute this software and |
17 |
* its documentation is hereby granted, provided that both the copyright |
18 |
* notice and this permission notice appear in all copies of the |
19 |
* software, derivative works or modified versions, and any portions |
20 |
* thereof, and that both notices appear in supporting documentation. |
21 |
* |
22 |
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" |
23 |
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND |
24 |
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. |
25 |
* |
26 |
* Carnegie Mellon requests users of this software to return to |
27 |
* |
28 |
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU |
29 |
* School of Computer Science |
30 |
* Carnegie Mellon University |
31 |
* Pittsburgh PA 15213-3890 |
32 |
* |
33 |
* any improvements or extensions that they make and grant Carnegie the |
34 |
* rights to redistribute these changes. |
35 |
*/ |
36 |
|
37 |
/* |
38 |
* Definitions for the Motorola MC146818A Real Time Clock. |
39 |
* They also apply for the (compatible) Dallas Semicontuctor DS1287A RTC. |
40 |
* |
41 |
* Though there are undoubtedly other (better) sources, this material was |
42 |
* culled from the DEC "KN121 System Module Programmer's Reference |
43 |
* Information." |
44 |
* |
45 |
* The MC146818A has 16 registers. The first 10 contain time-of-year |
46 |
* and alarm data. The rest contain various control and status bits. |
47 |
* |
48 |
* To read or write the registers, one writes the register number to |
49 |
* the RTC's control port, then either reads from or writes the new |
50 |
* data to the RTC's data port. Since the locations of these ports |
51 |
* and the method used to access them can be machine-dependent, the |
52 |
* low-level details of reading and writing the RTC's registers are |
53 |
* handled by machine-specific functions. |
54 |
* |
55 |
* The time-of-year and alarm data can be expressed in either binary |
56 |
* or BCD, and they are selected by a bit in register B. |
57 |
* |
58 |
* The "hour" time-of-year and alarm fields can either be expressed in |
59 |
* AM/PM format, or in 24-hour format. If AM/PM format is chosen, the |
60 |
* hour fields can have the values: 1-12 and 81-92 (the latter being |
61 |
* PM). If the 24-hour format is chosen, they can have the values |
62 |
* 0-24. The hour format is selectable by a bit in register B. |
63 |
* (XXX IS AM/PM MODE DESCRIPTION CORRECT?) |
64 |
* |
65 |
* It is assumed the if systems are going to use BCD (rather than |
66 |
* binary) mode, or AM/PM hour format, they'll do the appropriate |
67 |
* conversions in machine-dependent code. Also, if the clock is |
68 |
* switched between BCD and binary mode, or between AM/PM mode and |
69 |
* 24-hour mode, the time-of-day and alarm registers are NOT |
70 |
* automatically reset; they must be reprogrammed with correct values. |
71 |
*/ |
72 |
|
73 |
/* |
74 |
* The registers, and the bits within each register. |
75 |
*/ |
76 |
|
77 |
#define MC_SEC 0x0 /* Time of year: seconds (0-59) */ |
78 |
#define MC_ASEC 0x1 /* Alarm: seconds */ |
79 |
#define MC_MIN 0x2 /* Time of year: minutes (0-59) */ |
80 |
#define MC_AMIN 0x3 /* Alarm: minutes */ |
81 |
#define MC_HOUR 0x4 /* Time of year: hour (see above) */ |
82 |
#define MC_AHOUR 0x5 /* Alarm: hour */ |
83 |
#define MC_DOW 0x6 /* Time of year: day of week (1-7) */ |
84 |
#define MC_DOM 0x7 /* Time of year: day of month (1-31) */ |
85 |
#define MC_MONTH 0x8 /* Time of year: month (1-12) */ |
86 |
#define MC_YEAR 0x9 /* Time of year: year in century (0-99) */ |
87 |
|
88 |
#define MC_REGA 0xa /* Control register A */ |
89 |
|
90 |
#define MC_REGA_RSMASK 0x0f /* Interrupt rate select mask (see below) */ |
91 |
#define MC_REGA_DVMASK 0x70 /* Divisor select mask (see below) */ |
92 |
#define MC_REGA_UIP 0x80 /* Update in progress; read only. */ |
93 |
|
94 |
#define MC_REGB 0xb /* Control register B */ |
95 |
|
96 |
#define MC_REGB_DSE 0x01 /* Daylight Savings Enable */ |
97 |
#define MC_REGB_24HR 0x02 /* 24-hour mode (AM/PM mode when clear) */ |
98 |
#define MC_REGB_BINARY 0x04 /* Binary mode (BCD mode when clear) */ |
99 |
#define MC_REGB_SQWE 0x08 /* Square Wave Enable */ |
100 |
#define MC_REGB_UIE 0x10 /* Update End interrupt enable */ |
101 |
#define MC_REGB_AIE 0x20 /* Alarm interrupt enable */ |
102 |
#define MC_REGB_PIE 0x40 /* Periodic interrupt enable */ |
103 |
#define MC_REGB_SET 0x80 /* Allow time to be set; stops updates */ |
104 |
|
105 |
#define MC_REGC 0xc /* Control register C */ |
106 |
|
107 |
/* MC_REGC_UNUSED 0x0f UNUSED */ |
108 |
#define MC_REGC_UF 0x10 /* Update End interrupt flag */ |
109 |
#define MC_REGC_AF 0x20 /* Alarm interrupt flag */ |
110 |
#define MC_REGC_PF 0x40 /* Periodic interrupt flag */ |
111 |
#define MC_REGC_IRQF 0x80 /* Interrupt request pending flag */ |
112 |
|
113 |
#define MC_REGD 0xd /* Control register D */ |
114 |
|
115 |
/* MC_REGD_UNUSED 0x7f UNUSED */ |
116 |
#define MC_REGD_VRT 0x80 /* Valid RAM and Time bit */ |
117 |
|
118 |
|
119 |
#define MC_NREGS 0xe /* 14 registers; CMOS follows */ |
120 |
#define MC_NTODREGS 0xa /* 10 of those regs are for TOD and alarm */ |
121 |
|
122 |
#define MC_NVRAM_START 0xe /* start of NVRAM: offset 14 */ |
123 |
#define MC_NVRAM_SIZE 50 /* 50 bytes of NVRAM */ |
124 |
|
125 |
/* |
126 |
* Periodic Interrupt Rate Select constants (Control register A) |
127 |
*/ |
128 |
#define MC_RATE_NONE 0x0 /* No periodic interrupt */ |
129 |
#define MC_RATE_1 0x1 /* 256 Hz if MC_BASE_32_KHz, else 32768 Hz */ |
130 |
#define MC_RATE_2 0x2 /* 128 Hz if MC_BASE_32_KHz, else 16384 Hz */ |
131 |
#define MC_RATE_8192_Hz 0x3 /* 122.070 us period */ |
132 |
#define MC_RATE_4096_Hz 0x4 /* 244.141 us period */ |
133 |
#define MC_RATE_2048_Hz 0x5 /* 488.281 us period */ |
134 |
#define MC_RATE_1024_Hz 0x6 /* 976.562 us period */ |
135 |
#define MC_RATE_512_Hz 0x7 /* 1.953125 ms period */ |
136 |
#define MC_RATE_256_Hz 0x8 /* 3.90625 ms period */ |
137 |
#define MC_RATE_128_Hz 0x9 /* 7.8125 ms period */ |
138 |
#define MC_RATE_64_Hz 0xa /* 15.625 ms period */ |
139 |
#define MC_RATE_32_Hz 0xb /* 31.25 ms period */ |
140 |
#define MC_RATE_16_Hz 0xc /* 62.5 ms period */ |
141 |
#define MC_RATE_8_Hz 0xd /* 125 ms period */ |
142 |
#define MC_RATE_4_Hz 0xe /* 250 ms period */ |
143 |
#define MC_RATE_2_Hz 0xf /* 500 ms period */ |
144 |
|
145 |
/* |
146 |
* Time base (divisor select) constants (Control register A) |
147 |
*/ |
148 |
#define MC_BASE_4_MHz 0x00 /* 4MHz crystal */ |
149 |
#define MC_BASE_1_MHz 0x10 /* 1MHz crystal */ |
150 |
#define MC_BASE_32_KHz 0x20 /* 32KHz crystal */ |
151 |
#define MC_BASE_NONE 0x60 /* actually, both of these reset */ |
152 |
#define MC_BASE_RESET 0x70 |
153 |
|
154 |
|
155 |
/* |
156 |
* RTC register/NVRAM read and write functions -- machine-dependent. |
157 |
* Appropriately manipulate RTC registers to get/put data values. |
158 |
*/ |
159 |
u_int mc146818_read __P((void *sc, u_int reg)); |
160 |
void mc146818_write __P((void *sc, u_int reg, u_int datum)); |
161 |
|
162 |
/* |
163 |
* A collection of TOD/Alarm registers. |
164 |
*/ |
165 |
typedef u_int mc_todregs[MC_NTODREGS]; |
166 |
|
167 |
/* |
168 |
* Get all of the TOD/Alarm registers |
169 |
* Must be called at splhigh(), and with the RTC properly set up. |
170 |
*/ |
171 |
#define MC146818_GETTOD(sc, regs) \ |
172 |
do { \ |
173 |
int i; \ |
174 |
\ |
175 |
/* update in progress; spin loop */ \ |
176 |
while (mc146818_read(sc, MC_REGA) & MC_REGA_UIP) \ |
177 |
; \ |
178 |
\ |
179 |
/* read all of the tod/alarm regs */ \ |
180 |
for (i = 0; i < MC_NTODREGS; i++) \ |
181 |
(*regs)[i] = mc146818_read(sc, i); \ |
182 |
} while (0); |
183 |
|
184 |
/* |
185 |
* Set all of the TOD/Alarm registers |
186 |
* Must be called at splhigh(), and with the RTC properly set up. |
187 |
*/ |
188 |
#define MC146818_PUTTOD(sc, regs) \ |
189 |
do { \ |
190 |
int i; \ |
191 |
\ |
192 |
/* stop updates while setting */ \ |
193 |
mc146818_write(sc, MC_REGB, \ |
194 |
mc146818_read(sc, MC_REGB) | MC_REGB_SET); \ |
195 |
\ |
196 |
/* write all of the tod/alarm regs */ \ |
197 |
for (i = 0; i < MC_NTODREGS; i++) \ |
198 |
mc146818_write(sc, i, (*regs)[i]); \ |
199 |
\ |
200 |
/* reenable updates */ \ |
201 |
mc146818_write(sc, MC_REGB, \ |
202 |
mc146818_read(sc, MC_REGB) & ~MC_REGB_SET); \ |
203 |
} while (0); |
204 |
|
205 |
#endif |