ReactOS 0.4.15-dev-7842-g558ab78
cmos.c
Go to the documentation of this file.
1/*
2 * PROJECT: NEC PC-98 series HAL
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: RTC and NVRAM access routines
5 * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
6 */
7
8/* INCLUDES ******************************************************************/
9
10#include <hal.h>
11
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS *******************************************************************/
16
17/*
18 * The PC-98 hardware maps data from the NVRAM directly into the text video
19 * memory address space. Every fourth byte is a "writable data".
20 *
21 * |0x2FE2|0x2FE3|0x2FE4|0x2FE5|0x2FE6|0x2FE7| .... |0x2FFD|0x2FFE|
22 * | D | | | | D | | .... | | D |
23 *
24 * Most of these bits of the NVRAM are already used. There are some reserved
25 * bits in the 0x3FE6 and 0x3FFE that we can use.
26 */
27#define NVRAM_START 0x3FE2
28#define NVRAM_SIZE 0x1C
29#define NVRAM_UNUSED_REG 0x14
30#define NVRAM_UNUSED_BIT 0x80
31
33
34/* PRIVATE FUNCTIONS *********************************************************/
35
36/* Avoid double calls */
37#undef BCD_INT
38static UCHAR
40 _In_ UCHAR Bcd)
41{
42 return ((Bcd & 0xF0) >> 4) * 10 + (Bcd & 0x0F);
43}
44
45static UCHAR
49{
51}
52
54static VOID
56HalpWriteNvram(
59{
63}
64
66static UCHAR
68HalpRtcReadByte(VOID)
69{
70 UCHAR i;
71 UCHAR Byte = 0;
72
73 /* Read byte from single wire bus */
74 for (i = 0; i < 8; i++)
75 {
76 Byte |= (__inbyte(PPI_IO_i_PORT_B) & 1) << i;
77
80
83 }
84
85 return Byte;
86}
87
89static VOID
91HalpRtcWriteBit(
92 _In_ UCHAR Bit)
93{
94 Bit = (Bit & 1) << 5;
95
98
101}
102
104static VOID
105NTAPI
106HalpRtcWriteCommand(
108{
109 UCHAR i;
110
111 for (i = 0; i < 4; i++)
112 HalpRtcWriteBit(Command >> i);
113
116
119}
120
121UCHAR
122NTAPI
124 _In_ UCHAR Reg)
125{
126 /* Not supported by hardware */
127 return 0;
128}
129
130VOID
131NTAPI
133 _In_ UCHAR Reg,
135{
136 /* Not supported by hardware */
137 NOTHING;
138}
139
140ULONG
141NTAPI
147{
148 /* Not supported by hardware */
149 return 0;
150}
151
152ULONG
153NTAPI
159{
160 /* Not supported by hardware */
161 return 0;
162}
163
164CODE_SEG("INIT")
165VOID
166NTAPI
168{
170
171 /* TODO: Detect TVRAM address */
172 if (TRUE)
174 else
177}
178
179/* PUBLIC FUNCTIONS **********************************************************/
180
182NTAPI
184 _In_ PCH Name,
187{
188 UCHAR Val;
189
190 /* Only variable supported on x86 */
191 if (_stricmp(Name, "LastKnownGood"))
192 return ENOENT;
193
194 if (!MappedNvram)
195 return ENOENT;
196
198
200
202
203 /* Check the flag */
204 if (Val)
205 strncpy(Value, "FALSE", ValueLength);
206 else
207 strncpy(Value, "TRUE", ValueLength);
208
209 return ESUCCESS;
210}
211
213NTAPI
215 _In_ PCH Name,
216 _In_ PCH Value)
217{
218 UCHAR Val;
219
220 /* Only variable supported on x86 */
221 if (_stricmp(Name, "LastKnownGood"))
222 return ENOMEM;
223
224 if (!MappedNvram)
225 return ENOMEM;
226
227 /* Check if this is true or false */
228 if (!_stricmp(Value, "TRUE"))
229 {
231
233 }
234 else if (!_stricmp(Value, "FALSE"))
235 {
237
238 Val = HalpReadNvram(NVRAM_UNUSED_REG) & ~NVRAM_UNUSED_BIT;
239 }
240 else
241 {
242 /* Fail */
243 return ENOMEM;
244 }
245
246 HalpWriteNvram(NVRAM_UNUSED_REG, Val);
247
249
250 return ESUCCESS;
251}
252
254NTAPI
257{
258 UCHAR Temp;
259
261
262 HalpRtcWriteCommand(RTC_CMD_TIME_READ);
263 HalpRtcWriteCommand(RTC_CMD_REGISTER_SHIFT);
265
266 /* Set the time data */
267 Time->Second = BCD_INT(HalpRtcReadByte());
268 Time->Minute = BCD_INT(HalpRtcReadByte());
269 Time->Hour = BCD_INT(HalpRtcReadByte());
270 Time->Day = BCD_INT(HalpRtcReadByte());
271 Temp = HalpRtcReadByte();
272 Time->Weekday = Temp & 0x0F;
273 Time->Month = Temp >> 4;
274 Time->Year = BCD_INT(HalpRtcReadByte());
275 Time->Milliseconds = 0;
276
277 Time->Year += (Time->Year >= 80) ? 1900 : 2000;
278
279 HalpRtcWriteCommand(RTC_CMD_REGISTER_HOLD);
280
282
283 return TRUE;
284}
285
287NTAPI
290{
291 UCHAR i, j;
292 UCHAR SysTime[6];
293
295
296 HalpRtcWriteCommand(RTC_CMD_REGISTER_SHIFT);
297
298 SysTime[0] = INT_BCD(Time->Second);
299 SysTime[1] = INT_BCD(Time->Minute);
300 SysTime[2] = INT_BCD(Time->Hour);
301 SysTime[3] = INT_BCD(Time->Day);
302 SysTime[4] = (Time->Month << 4) | (Time->Weekday & 0x0F);
303 SysTime[5] = INT_BCD(Time->Year % 100);
304
305 /* Write time fields to RTC */
306 for (i = 0; i < 6; i++)
307 {
308 for (j = 0; j < 8; j++)
309 HalpRtcWriteBit(SysTime[i] >> j);
310 }
311
312 HalpRtcWriteCommand(RTC_CMD_TIME_SET_COUNTER_HOLD);
313 HalpRtcWriteCommand(RTC_CMD_REGISTER_HOLD);
314
316
317 return TRUE;
318}
unsigned char BOOLEAN
#define ENOENT
Definition: acclib.h:79
#define ENOMEM
Definition: acclib.h:84
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
#define _stricmp
Definition: cat.c:22
Definition: bufpool.h:45
#define _Requires_lock_held_(lock)
#define TRUE
Definition: types.h:120
unsigned char Byte
Definition: zlib.h:37
#define ULONG_PTR
Definition: config.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI HalQueryRealTimeClock(OUT PTIME_FIELDS Time)
Definition: cmos.c:260
ARC_STATUS NTAPI HalGetEnvironmentVariable(_In_ PCH Name, _In_ USHORT ValueLength, _Out_writes_z_(ValueLength) PCH Value)
Definition: cmos.c:176
ULONG NTAPI HalpSetCmosData(_In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_reads_bytes_(Length) PVOID Buffer, _In_ ULONG Length)
Definition: cmos.c:104
VOID NTAPI HalpInitializeCmos(VOID)
Definition: cmos.c:160
BOOLEAN NTAPI HalSetRealTimeClock(IN PTIME_FIELDS Time)
Definition: cmos.c:295
ARC_STATUS NTAPI HalSetEnvironmentVariable(IN PCH Name, IN PCH Value)
Definition: cmos.c:216
ULONG NTAPI HalpGetCmosData(_In_ ULONG BusNumber, _In_ ULONG SlotNumber, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length)
Definition: cmos.c:49
PVOID NTAPI HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, IN PFN_COUNT PageCount)
Definition: memory.c:140
KSPIN_LOCK HalpSystemHardwareLock
Definition: spinlock.c:25
VOID NTAPI HalpReleaseCmosSpinLock(VOID)
Definition: spinlock.c:243
VOID NTAPI HalpAcquireCmosSpinLock(VOID)
Definition: spinlock.c:226
#define NVRAM_UNUSED_REG
Definition: cmos.c:29
#define NVRAM_UNUSED_BIT
Definition: cmos.c:30
#define NVRAM_START
Definition: cmos.c:27
static UCHAR NTAPI HalpReadNvram(_In_ UCHAR Register)
Definition: cmos.c:47
VOID NTAPI HalpWriteCmos(_In_ UCHAR Reg, _In_ UCHAR Value)
Definition: cmos.c:132
UCHAR NTAPI HalpReadCmos(_In_ UCHAR Reg)
Definition: cmos.c:123
static ULONG_PTR MappedNvram
Definition: cmos.c:32
#define NVRAM_SIZE
Definition: cmos.c:28
#define INT_BCD(int)
Definition: halp.h:73
#define NOTHING
Definition: input_list.c:10
PPC_QUAL unsigned char __inbyte(const unsigned long Port)
Definition: intrin_ppc.h:539
PPC_QUAL void __outbyte(unsigned long const Port, const unsigned char Data)
Definition: intrin_ppc.h:605
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
static PLARGE_INTEGER Time
Definition: time.c:105
#define _In_reads_bytes_(size)
Definition: ms_sal.h:321
#define _Out_writes_z_(size)
Definition: ms_sal.h:352
#define _Out_writes_bytes_(size)
Definition: ms_sal.h:350
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
CHAR * PCH
Definition: ntbasedef.h:391
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define BCD_INT(bcd)
Definition: hwinfo.c:13
unsigned short USHORT
Definition: pedump.c:61
#define RTC_STROBE
Definition: rtc.h:14
#define RTC_CMD_TIME_READ
Definition: rtc.h:19
#define RTC_IO_o_DATA
Definition: rtc.h:10
#define RTC_CMD_SERIAL_TRANSFER_MODE
Definition: rtc.h:23
#define RTC_CMD_REGISTER_HOLD
Definition: rtc.h:16
#define RTC_CMD_TIME_SET_COUNTER_HOLD
Definition: rtc.h:18
#define RTC_CLOCK
Definition: rtc.h:13
#define RTC_CMD_REGISTER_SHIFT
Definition: rtc.h:17
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
#define GDC1_IO_o_MODE_FLIPFLOP1
Definition: video.h:238
#define GDC1_NVRAM_PROTECT
Definition: video.h:251
#define GDC1_NVRAM_UNPROTECT
Definition: video.h:252
#define VRAM_NORMAL_TEXT
Definition: video.h:17
#define VRAM_HI_RESO_TEXT
Definition: video.h:32
Definition: shell.h:41
#define PPI_IO_i_PORT_B
Definition: sysport.h:19
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
#define BYTES_TO_PAGES(Size)
unsigned char UCHAR
Definition: xmlstorage.h:181