dev_mc146818.cc Source File

Back to the index.

dev_mc146818.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2009 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: MC146818 real-time clock
29  *
30  * (DS1687 as used in some other machines is also similar to the MC146818.)
31  *
32  * This device contains Date/time, the machine's ethernet address (on
33  * DECstation 3100), and can cause periodic (hardware) interrupts.
34  *
35  * NOTE: Many register offsets are multiplied by 4 in this code; this is
36  * because I originally wrote it for DECstation 3100 emulation, where the
37  * registered are spaced that way.
38  */
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <time.h>
44 
45 #include "cpu.h"
46 #include "devices.h"
47 #include "machine.h"
48 #include "memory.h"
49 #include "misc.h"
50 #include "timer.h"
51 
52 #include "thirdparty/mc146818reg.h"
53 
54 
55 #define to_bcd(x) ( ((x)/10) * 16 + ((x)%10) )
56 #define from_bcd(x) ( ((x)>>4) * 10 + ((x)&15) )
57 
58 /* #define MC146818_DEBUG */
59 
60 #define MC146818_TICK_SHIFT 14
61 
62 
63 /* 256 on DECstation, SGI uses reg at 72*4 as the Century */
64 #define N_REGISTERS 1024
65 struct mc_data {
67  int last_addr;
68 
71  int addrdiv;
72 
73  int use_bcd;
74 
78  struct interrupt irq;
79  struct timer *timer;
81 
85 
88 };
89 
90 
91 /*
92  * Ugly hack to fool NetBSD/prep to accept the clock. (See mcclock_isa_match
93  * in NetBSD's arch/prep/isa/mcclock_isa.c for details.)
94  */
95 #define NETBSD_HACK_INIT 0
96 #define NETBSD_HACK_FIRST_1 1
97 #define NETBSD_HACK_FIRST_2 2
98 #define NETBSD_HACK_SECOND_1 3
99 #define NETBSD_HACK_SECOND_2 4
100 #define NETBSD_HACK_DONE 5
101 
102 
103 /*
104  * timer_tick():
105  *
106  * Called d->interrupt_hz times per (real-world) second.
107  */
108 static void timer_tick(struct timer *timer, void *extra)
109 {
110  struct mc_data *d = (struct mc_data *) extra;
112 }
113 
114 
115 DEVICE_TICK(mc146818)
116 {
117  struct mc_data *d = (struct mc_data *) extra;
118  int pti = d->pending_timer_interrupts;
119 
120  if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) && pti > 0) {
121 #if 0
122  /* For debugging, to see how much the interrupts are
123  lagging behind the real clock: */
124  {
125  static int x = 0;
126  if (++x == 1) {
127  x = 0;
128  printf("%i ", pti);
129  fflush(stdout);
130  }
131  }
132 #endif
133 
134  INTERRUPT_ASSERT(d->irq);
135 
136  d->reg[MC_REGC * 4] |= MC_REGC_PF;
137  }
138 
139  if (d->reg[MC_REGC * 4] & MC_REGC_UF ||
140  d->reg[MC_REGC * 4] & MC_REGC_AF ||
141  d->reg[MC_REGC * 4] & MC_REGC_PF)
142  d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
143 }
144 
145 
146 /*
147  * dev_mc146818_jazz_access():
148  *
149  * It seems like JAZZ machines accesses the mc146818 by writing one byte to
150  * 0x90000070 and then reading or writing another byte at 0x......0004000.
151  */
152 DEVICE_ACCESS(mc146818_jazz)
153 {
154  struct mc_data *d = (struct mc_data *) extra;
155 
156 #ifdef MC146818_DEBUG
157  if (writeflag == MEM_WRITE) {
158  int i;
159  fatal("[ mc146818_jazz: write to addr=0x%04x: ",
160  (int)relative_addr);
161  for (i=0; i<len; i++)
162  fatal("%02x ", data[i]);
163  fatal("]\n");
164  } else
165  fatal("[ mc146818_jazz: read from addr=0x%04x ]\n",
166  (int)relative_addr);
167 #endif
168 
169  if (writeflag == MEM_WRITE) {
170  d->last_addr = data[0];
171  return 1;
172  } else {
173  data[0] = d->last_addr;
174  return 1;
175  }
176 }
177 
178 
179 /*
180  * mc146818_update_time():
181  *
182  * This function updates the MC146818 registers by reading
183  * the host's clock.
184  */
185 static void mc146818_update_time(struct mc_data *d)
186 {
187  struct tm *tmp;
188  time_t timet;
189 
190  timet = time(NULL);
191  tmp = gmtime(&timet);
192 
193  d->reg[4 * MC_SEC] = tmp->tm_sec;
194  d->reg[4 * MC_MIN] = tmp->tm_min;
195  d->reg[4 * MC_HOUR] = tmp->tm_hour;
196  d->reg[4 * MC_DOW] = tmp->tm_wday + 1;
197  d->reg[4 * MC_DOM] = tmp->tm_mday;
198  d->reg[4 * MC_MONTH] = tmp->tm_mon + 1;
199  d->reg[4 * MC_YEAR] = tmp->tm_year;
200 
201  /*
202  * Special hacks for emulating the behaviour of various machines:
203  */
204  switch (d->access_style) {
205  case MC146818_ALGOR:
206  /*
207  * NetBSD/evbmips sources indicate that the Algor year base
208  * is 1920. This makes the time work with NetBSD in Malta
209  * emulation. However, for Linux, commenting out this line
210  * works better. (TODO: Find a way to make both work?)
211  */
212  d->reg[4 * MC_YEAR] += 80;
213  break;
214  case MC146818_ARC_NEC:
215  d->reg[4 * MC_YEAR] += (0x18 - 104);
216  break;
217  case MC146818_CATS:
218  d->reg[4 * MC_YEAR] %= 100;
219  break;
220  case MC146818_SGI:
221  /*
222  * NetBSD/sgimips assumes data in BCD format.
223  * Also, IRIX stores the year value in a weird
224  * format, according to ../arch/sgimips/sgimips/clockvar.h
225  * in NetBSD:
226  *
227  * "If year < 1985, store (year - 1970), else
228  * (year - 1940). This matches IRIX semantics."
229  *
230  * Another rule: It seems that a real SGI IP32 box
231  * uses the value 5 for the year 2005.
232  */
233  d->reg[4 * MC_YEAR] =
234  d->reg[4 * MC_YEAR] >= 100 ?
235  (d->reg[4 * MC_YEAR] - 100) :
236  (
237  d->reg[4 * MC_YEAR] < 85 ?
238  (d->reg[4 * MC_YEAR] - 30 + 40)
239  : (d->reg[4 * MC_YEAR] - 40)
240  );
241  /* Century: */
242  d->reg[72 * 4] = 19 + (tmp->tm_year / 100);
243  break;
244  case MC146818_DEC:
245  /*
246  * DECstations must have 72 or 73 in the
247  * Year field, or Ultrix screems. (Weird.)
248  */
249  d->reg[4 * MC_YEAR] = 72;
250 
251  /*
252  * Linux on DECstation stores the year in register 63,
253  * but no other DECstation OS does? (Hm.)
254  */
255  d->reg[4 * 63] = tmp->tm_year - 100;
256  break;
257  }
258 
259  if (d->use_bcd) {
260  d->reg[4 * MC_SEC] = to_bcd(d->reg[4 * MC_SEC]);
261  d->reg[4 * MC_MIN] = to_bcd(d->reg[4 * MC_MIN]);
262  d->reg[4 * MC_HOUR] = to_bcd(d->reg[4 * MC_HOUR]);
263  d->reg[4 * MC_DOW] = to_bcd(d->reg[4 * MC_DOW]);
264  d->reg[4 * MC_DOM] = to_bcd(d->reg[4 * MC_DOM]);
265  d->reg[4 * MC_MONTH] = to_bcd(d->reg[4 * MC_MONTH]);
266  d->reg[4 * MC_YEAR] = to_bcd(d->reg[4 * MC_YEAR]);
267 
268  /* Used by Linux on DECstation: (Hm) */
269  d->reg[4 * 63] = to_bcd(d->reg[4 * 63]);
270 
271  /* Used on SGI: */
272  d->reg[4 * 72] = to_bcd(d->reg[4 * 72]);
273  }
274 }
275 
276 
277 DEVICE_ACCESS(mc146818)
278 {
279  struct mc_data *d = (struct mc_data *) extra;
280  struct tm *tmp;
281  time_t timet;
282  size_t i;
283 
284  /* NOTE/TODO: This access function only handles 8-bit accesses! */
285 
286  relative_addr /= d->addrdiv;
287 
288  /* Different ways of accessing the registers: */
289  switch (d->access_style) {
290  case MC146818_ALGOR:
291  case MC146818_CATS:
292  case MC146818_PC_CMOS:
293  if ((relative_addr & 1) == 0x00) {
294  if (writeflag == MEM_WRITE) {
295  d->last_addr = data[0];
296  return 1;
297  } else {
298  data[0] = d->last_addr;
299  return 1;
300  }
301  } else
302  relative_addr = d->last_addr * 4;
303  break;
304  case MC146818_ARC_NEC:
305  if (relative_addr == 0x01) {
306  if (writeflag == MEM_WRITE) {
307  d->last_addr = data[0];
308  return 1;
309  } else {
310  data[0] = d->last_addr;
311  return 1;
312  }
313  } else if (relative_addr == 0x00)
314  relative_addr = d->last_addr * 4;
315  else {
316  fatal("[ mc146818: not accessed as an "
317  "MC146818_ARC_NEC device! ]\n");
318  }
319  break;
320  case MC146818_ARC_JAZZ:
321  /* See comment for dev_mc146818_jazz_access(). */
322  relative_addr = d->last_addr * 4;
323  break;
324  case MC146818_DEC:
325  case MC146818_SGI:
326  /*
327  * This device was originally written for DECstation
328  * emulation, so no changes are necessary for that access
329  * style.
330  *
331  * SGI access bytes 0x0..0xd at offsets 0x0yz..0xdyz, where yz
332  * should be ignored. It works _almost_ as DEC, if offsets are
333  * divided by 0x40.
334  */
335  break;
336  case MC146818_PMPPC:
337  relative_addr *= 4;
338  break;
339  default:
340  ;
341  }
342 
343 #ifdef MC146818_DEBUG
344  if (writeflag == MEM_WRITE) {
345  fatal("[ mc146818: write to addr=0x%04x (len %i): ",
346  (int)relative_addr, (int)len);
347  for (i=0; i<len; i++)
348  fatal("0x%02x ", data[i]);
349  fatal("]\n");
350  }
351 #endif
352 
353  /*
354  * Sprite seems to wants UF interrupt status, once every second, or
355  * it hangs forever during bootup. (These do not cause interrupts,
356  * but it is good enough... Sprite polls this, iirc.)
357  *
358  * Linux on at least sgimips and evbmips (Malta) wants the UIP bit
359  * in REGA to be updated once a second.
360  */
361  if (relative_addr == MC_REGA*4 || relative_addr == MC_REGC*4) {
362  timet = time(NULL);
363  tmp = gmtime(&timet);
364  d->reg[MC_REGC * 4] &= ~MC_REGC_UF;
365  if (tmp->tm_sec != d->previous_second) {
366  d->n_seconds_elapsed ++;
367  d->previous_second = tmp->tm_sec;
368  }
369  if (d->n_seconds_elapsed > d->uip_threshold) {
370  d->n_seconds_elapsed = 0;
371 
372  d->reg[MC_REGA * 4] |= MC_REGA_UIP;
373 
374  d->reg[MC_REGC * 4] |= MC_REGC_UF;
375  d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
376 
377  /* For some reason, some Linux/DECstation KN04
378  kernels want the PF (periodic flag) bit set,
379  even though interrupts are not enabled? */
380  d->reg[MC_REGC * 4] |= MC_REGC_PF;
381  } else
382  d->reg[MC_REGA * 4] &= ~MC_REGA_UIP;
383  }
384 
385  /* RTC data is in either BCD format or binary: */
386  if (d->use_bcd)
387  d->reg[MC_REGB * 4] &= ~(1 << 2);
388  else
389  d->reg[MC_REGB * 4] |= (1 << 2);
390 
391  /* RTC date/time is always Valid: */
392  d->reg[MC_REGD * 4] |= MC_REGD_VRT;
393 
394  if (writeflag == MEM_WRITE) {
395  /* WRITE: */
396  switch (relative_addr) {
397  case MC_REGA*4:
398  if ((data[0] & MC_REGA_DVMASK) == MC_BASE_32_KHz)
399  d->timebase_hz = 32000;
400  if ((data[0] & MC_REGA_DVMASK) == MC_BASE_1_MHz)
401  d->timebase_hz = 1000000;
402  if ((data[0] & MC_REGA_DVMASK) == MC_BASE_4_MHz)
403  d->timebase_hz = 4000000;
404  switch (data[0] & MC_REGA_RSMASK) {
405  case MC_RATE_NONE:
406  d->interrupt_hz = 0;
407  break;
408  case MC_RATE_1:
409  if (d->timebase_hz == 32000)
410  d->interrupt_hz = 256;
411  else
412  d->interrupt_hz = 32768;
413  break;
414  case MC_RATE_2:
415  if (d->timebase_hz == 32000)
416  d->interrupt_hz = 128;
417  else
418  d->interrupt_hz = 16384;
419  break;
420  case MC_RATE_8192_Hz: d->interrupt_hz = 8192; break;
421  case MC_RATE_4096_Hz: d->interrupt_hz = 4096; break;
422  case MC_RATE_2048_Hz: d->interrupt_hz = 2048; break;
423  case MC_RATE_1024_Hz: d->interrupt_hz = 1024; break;
424  case MC_RATE_512_Hz: d->interrupt_hz = 512; break;
425  case MC_RATE_256_Hz: d->interrupt_hz = 256; break;
426  case MC_RATE_128_Hz: d->interrupt_hz = 128; break;
427  case MC_RATE_64_Hz: d->interrupt_hz = 64; break;
428  case MC_RATE_32_Hz: d->interrupt_hz = 32; break;
429  case MC_RATE_16_Hz: d->interrupt_hz = 16; break;
430  case MC_RATE_8_Hz: d->interrupt_hz = 8; break;
431  case MC_RATE_4_Hz: d->interrupt_hz = 4; break;
432  case MC_RATE_2_Hz: d->interrupt_hz = 2; break;
433  default:/* debug("[ mc146818: unimplemented "
434  "MC_REGA RS: %i ]\n",
435  data[0] & MC_REGA_RSMASK); */
436  ;
437  }
438 
439  if (d->interrupt_hz != d->old_interrupt_hz) {
440  debug("[ rtc changed to interrupt at %i Hz ]\n",
441  d->interrupt_hz);
442 
444 
445  if (d->timer == NULL)
446  d->timer = timer_add(d->interrupt_hz,
447  timer_tick, d);
448  else
450  d->interrupt_hz);
451  }
452 
453  d->reg[MC_REGA * 4] =
455  break;
456  case MC_REGB*4:
457  d->reg[MC_REGB*4] = data[0];
458  if (!(data[0] & MC_REGB_PIE)) {
460  }
461 
462  /* debug("[ mc146818: write to MC_REGB, data[0] "
463  "= 0x%02x ]\n", data[0]); */
464  break;
465  case MC_REGC*4:
466  d->reg[MC_REGC * 4] = data[0];
467  debug("[ mc146818: write to MC_REGC, data[0] = "
468  "0x%02x ]\n", data[0]);
469  break;
470  case 0x128:
471  d->reg[relative_addr] = data[0];
472  if (data[0] & 8) {
473  int j;
474 
475  /* Used on SGI to power off the machine. */
476  fatal("[ md146818: power off ]\n");
477  for (j=0; j<cpu->machine->ncpus; j++)
478  cpu->machine->cpus[j]->running = 0;
479  cpu->machine->
480  exit_without_entering_debugger = 1;
481  }
482  break;
483  default:
484  d->reg[relative_addr] = data[0];
485 
486  debug("[ mc146818: unimplemented write to "
487  "relative_addr = %08lx: ", (long)relative_addr);
488  for (i=0; i<len; i++)
489  debug("%02x ", data[i]);
490  debug("]\n");
491  }
492  } else {
493  /* READ: */
494  switch (relative_addr) {
495  case 0x01: /* Station's ethernet address (6 bytes) */
496  case 0x05: /* (on DECstation 3100) */
497  case 0x09:
498  case 0x0d:
499  case 0x11:
500  case 0x15:
501  break;
502  case 4 * MC_SEC:
505  switch (d->ugly_netbsd_prep_hack_done) {
506  case NETBSD_HACK_FIRST_1:
508  from_bcd(d->reg[relative_addr]);
509  break;
510  case NETBSD_HACK_FIRST_2:
511  d->reg[relative_addr] = to_bcd(
513  break;
516  d->reg[relative_addr] = to_bcd((1 +
517  d->ugly_netbsd_prep_hack_sec) % 60);
518  break;
519  }
520  }
521  case 4 * MC_MIN:
522  case 4 * MC_HOUR:
523  case 4 * MC_DOW:
524  case 4 * MC_DOM:
525  case 4 * MC_MONTH:
526  case 4 * MC_YEAR:
527  case 4 * 63: /* 63 is used by Linux on DECstation */
528  case 4 * 72: /* 72 is Century, on SGI (DS1687) */
529  /*
530  * If the SET bit is set, then we don't automatically
531  * update the values. Otherwise, we update them by
532  * reading from the host's clock:
533  */
534  if (d->reg[MC_REGB * 4] & MC_REGB_SET)
535  break;
536 
538  mc146818_update_time(d);
539  break;
540  case 4 * MC_REGA:
541  break;
542  case 4 * MC_REGC: /* Interrupt ack. */
543  /* NOTE: Acking is done below, _after_ the
544  register has been read. */
545  break;
546  default:debug("[ mc146818: read from relative_addr = "
547  "%04x ]\n", (int)relative_addr);
548  }
549 
550  data[0] = d->reg[relative_addr];
551 
552  if (relative_addr == MC_REGC*4) {
554 
555  /*
556  * Acknowledging an interrupt decreases the
557  * number of pending "real world" timer ticks.
558  */
559  if (d->reg[MC_REGC * 4] & MC_REGC_PF &&
562 
563  d->reg[MC_REGC * 4] = 0x00;
564  }
565  }
566 
567 #ifdef MC146818_DEBUG
568  if (writeflag == MEM_READ) {
569  fatal("[ mc146818: read from addr=0x%04x (len %i): ",
570  (int)relative_addr, (int)len);
571  for (i=0; i<len; i++)
572  fatal("0x%02x ", data[i]);
573  fatal("]\n");
574  }
575 #endif
576 
577  return 1;
578 }
579 
580 
581 /*
582  * dev_mc146818_init():
583  *
584  * This needs to work for both DECstation emulation and other machine types,
585  * so it contains both rtc related stuff and the station's Ethernet address.
586  */
587 void dev_mc146818_init(struct machine *machine, struct memory *mem,
588  uint64_t baseaddr, char *irq_path, int access_style, int addrdiv)
589 {
590  unsigned char ether_address[6];
591  int i, dev_len;
592  struct mc_data *d;
593 
594  CHECK_ALLOCATION(d = (struct mc_data *) malloc(sizeof(struct mc_data)));
595  memset(d, 0, sizeof(struct mc_data));
596 
598  d->addrdiv = addrdiv;
599 
600  INTERRUPT_CONNECT(irq_path, d->irq);
601 
602  d->use_bcd = 0;
603  switch (access_style) {
604  case MC146818_SGI:
605  case MC146818_PC_CMOS:
606  case MC146818_PMPPC:
607  d->use_bcd = 1;
608  }
609 
611  /* NetBSD/prep has a really ugly clock detection code;
612  no other machines/OSes don't need this. */
614  }
615 
616  if (access_style == MC146818_DEC) {
617  /* Station Ethernet Address, on DECstation 3100: */
618  for (i=0; i<6; i++)
619  ether_address[i] = 0x10 * (i+1);
620 
621  d->reg[0x01] = ether_address[0];
622  d->reg[0x05] = ether_address[1];
623  d->reg[0x09] = ether_address[2];
624  d->reg[0x0d] = ether_address[3];
625  d->reg[0x11] = ether_address[4];
626  d->reg[0x15] = ether_address[5];
627  /* TODO: 19, 1d, 21, 25 = checksum bytes 1,2,2,1 resp. */
628  d->reg[0x29] = ether_address[5];
629  d->reg[0x2d] = ether_address[4];
630  d->reg[0x31] = ether_address[3];
631  d->reg[0x35] = ether_address[2];
632  d->reg[0x39] = ether_address[1];
633  d->reg[0x3d] = ether_address[1];
634  d->reg[0x41] = ether_address[0];
635  d->reg[0x45] = ether_address[1];
636  d->reg[0x49] = ether_address[2];
637  d->reg[0x4d] = ether_address[3];
638  d->reg[0x51] = ether_address[4];
639  d->reg[0x55] = ether_address[5];
640  /* TODO: 59, 5d = checksum bytes 1,2 resp. */
641  d->reg[0x61] = 0xff;
642  d->reg[0x65] = 0x00;
643  d->reg[0x69] = 0x55;
644  d->reg[0x6d] = 0xaa;
645  d->reg[0x71] = 0xff;
646  d->reg[0x75] = 0x00;
647  d->reg[0x79] = 0x55;
648  d->reg[0x7d] = 0xaa;
649 
650  /* Battery valid, for DECstations */
651  d->reg[0xf8] = 1;
652  }
653 
654  /*
655  * uip_threshold should ideally be 1, but when Linux polls the UIP bit
656  * it looses speed. This hack gives Linux the impression that the cpu
657  * is uip_threshold times faster than the slow clock it would
658  * otherwise detect.
659  *
660  * TODO: Find out if this messes up Sprite emulation; if so, then
661  * this hack has to be removed.
662  */
663  d->uip_threshold = 8;
664 
666  memory_device_register(mem, "mc146818_jazz", 0x90000070ULL,
667  1, dev_mc146818_jazz_access, d, DM_DEFAULT, NULL);
668 
669  dev_len = DEV_MC146818_LENGTH;
670  switch (access_style) {
671  case MC146818_CATS:
672  case MC146818_PC_CMOS:
673  dev_len = 2;
674  break;
675  case MC146818_SGI:
676  dev_len = 0x400;
677  }
678 
679  memory_device_register(mem, "mc146818", baseaddr,
680  dev_len * addrdiv, dev_mc146818_access,
681  d, DM_DEFAULT, NULL);
682 
683  mc146818_update_time(d);
684 
687 }
688 
data
u_short data
Definition: siireg.h:79
timer_add
struct timer * timer_add(double freq, void(*timer_tick)(struct timer *timer, void *extra), void *extra)
Definition: timer.cc:75
MC_RATE_16_Hz
#define MC_RATE_16_Hz
Definition: mc146818reg.h:138
MC_HOUR
#define MC_HOUR
Definition: mc146818reg.h:79
MC_REGA_RSMASK
#define MC_REGA_RSMASK
Definition: mc146818reg.h:88
MC_RATE_4_Hz
#define MC_RATE_4_Hz
Definition: mc146818reg.h:140
mc_data::interrupt_hz
int interrupt_hz
Definition: dev_mc146818.cc:76
MC146818_ARC_JAZZ
#define MC146818_ARC_JAZZ
Definition: devices.h:305
MC_MIN
#define MC_MIN
Definition: mc146818reg.h:77
NETBSD_HACK_FIRST_1
#define NETBSD_HACK_FIRST_1
Definition: dev_mc146818.cc:96
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition: interrupt.h:77
MC_RATE_8_Hz
#define MC_RATE_8_Hz
Definition: mc146818reg.h:139
from_bcd
#define from_bcd(x)
Definition: dev_mc146818.cc:56
MC_RATE_2
#define MC_RATE_2
Definition: mc146818reg.h:128
mc_data::ugly_netbsd_prep_hack_done
int ugly_netbsd_prep_hack_done
Definition: dev_mc146818.cc:86
NETBSD_HACK_SECOND_2
#define NETBSD_HACK_SECOND_2
Definition: dev_mc146818.cc:99
INTERRUPT_ASSERT
#define INTERRUPT_ASSERT(istruct)
Definition: interrupt.h:74
cpu::running
uint8_t running
Definition: cpu.h:353
MC_RATE_8192_Hz
#define MC_RATE_8192_Hz
Definition: mc146818reg.h:129
MC146818_PC_CMOS
#define MC146818_PC_CMOS
Definition: devices.h:303
MC_REGC_AF
#define MC_REGC_AF
Definition: mc146818reg.h:107
timer
Definition: timer.cc:45
memory
Definition: memory.h:75
MC_REGD_VRT
#define MC_REGD_VRT
Definition: mc146818reg.h:114
MC_REGB
#define MC_REGB
Definition: mc146818reg.h:92
debug
#define debug
Definition: dev_adb.cc:57
MC_REGD
#define MC_REGD
Definition: mc146818reg.h:111
MC_REGC_PF
#define MC_REGC_PF
Definition: mc146818reg.h:108
MC_RATE_256_Hz
#define MC_RATE_256_Hz
Definition: mc146818reg.h:134
machine::cpus
struct cpu ** cpus
Definition: machine.h:140
to_bcd
#define to_bcd(x)
Definition: dev_mc146818.cc:55
if
addr & if(addr >=0x24 &&page !=NULL)
Definition: tmp_arm_multi.cc:56
MC_REGC_UF
#define MC_REGC_UF
Definition: mc146818reg.h:106
memory_device_register
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
MC_DOW
#define MC_DOW
Definition: mc146818reg.h:81
MC_RATE_1
#define MC_RATE_1
Definition: mc146818reg.h:127
MC_REGA_DVMASK
#define MC_REGA_DVMASK
Definition: mc146818reg.h:89
MC_REGB_PIE
#define MC_REGB_PIE
Definition: mc146818reg.h:100
MEM_READ
#define MEM_READ
Definition: memory.h:116
DM_DEFAULT
#define DM_DEFAULT
Definition: memory.h:130
MC_RATE_2_Hz
#define MC_RATE_2_Hz
Definition: mc146818reg.h:141
MC_RATE_64_Hz
#define MC_RATE_64_Hz
Definition: mc146818reg.h:136
NETBSD_HACK_SECOND_1
#define NETBSD_HACK_SECOND_1
Definition: dev_mc146818.cc:98
MC_BASE_1_MHz
#define MC_BASE_1_MHz
Definition: mc146818reg.h:147
MACHINE_PREP
#define MACHINE_PREP
Definition: machine.h:228
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
mc_data::n_seconds_elapsed
int n_seconds_elapsed
Definition: dev_mc146818.cc:83
mc_data::irq
struct interrupt irq
Definition: dev_mc146818.cc:78
MC_REGC_IRQF
#define MC_REGC_IRQF
Definition: mc146818reg.h:109
machine_add_tickfunction
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
Definition: machine.cc:280
mc_data::timebase_hz
int timebase_hz
Definition: dev_mc146818.cc:75
DEV_MC146818_LENGTH
#define DEV_MC146818_LENGTH
Definition: devices.h:301
mc146818reg.h
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
NETBSD_HACK_FIRST_2
#define NETBSD_HACK_FIRST_2
Definition: dev_mc146818.cc:97
MC_SEC
#define MC_SEC
Definition: mc146818reg.h:75
misc.h
MC_RATE_32_Hz
#define MC_RATE_32_Hz
Definition: mc146818reg.h:137
machine.h
MC_YEAR
#define MC_YEAR
Definition: mc146818reg.h:84
machine
Definition: machine.h:97
timer.h
mc_data::pending_timer_interrupts
volatile int pending_timer_interrupts
Definition: dev_mc146818.cc:80
mc_data::uip_threshold
int uip_threshold
Definition: dev_mc146818.cc:84
MC_REGA
#define MC_REGA
Definition: mc146818reg.h:86
MC_REGC
#define MC_REGC
Definition: mc146818reg.h:103
mc_data::old_interrupt_hz
int old_interrupt_hz
Definition: dev_mc146818.cc:77
MC_RATE_4096_Hz
#define MC_RATE_4096_Hz
Definition: mc146818reg.h:130
MC146818_SGI
#define MC146818_SGI
Definition: devices.h:306
cpu.h
MC_REGB_SET
#define MC_REGB_SET
Definition: mc146818reg.h:101
MC146818_CATS
#define MC146818_CATS
Definition: devices.h:307
DEVICE_TICK
DEVICE_TICK(mc146818)
Definition: dev_mc146818.cc:115
MC_RATE_128_Hz
#define MC_RATE_128_Hz
Definition: mc146818reg.h:135
MC_MONTH
#define MC_MONTH
Definition: mc146818reg.h:83
mc_data::reg
int reg[N_REGISTERS]
Definition: dev_mc146818.cc:70
timer::timer_tick
void(* timer_tick)(struct timer *timer, void *extra)
Definition: timer.cc:49
mc_data::register_choice
int register_choice
Definition: dev_mc146818.cc:69
MC146818_ALGOR
#define MC146818_ALGOR
Definition: devices.h:308
cpu::machine
struct machine * machine
Definition: cpu.h:328
mc_data::addrdiv
int addrdiv
Definition: dev_mc146818.cc:71
MC_REGA_UIP
#define MC_REGA_UIP
Definition: mc146818reg.h:90
mc_data::last_addr
int last_addr
Definition: dev_mc146818.cc:67
MC_RATE_512_Hz
#define MC_RATE_512_Hz
Definition: mc146818reg.h:133
mc_data::previous_second
int previous_second
Definition: dev_mc146818.cc:82
mc_data::access_style
int access_style
Definition: dev_mc146818.cc:66
mc_data::use_bcd
int use_bcd
Definition: dev_mc146818.cc:73
timer_update_frequency
void timer_update_frequency(struct timer *t, double new_freq)
Definition: timer.cc:132
MC_DOM
#define MC_DOM
Definition: mc146818reg.h:82
MC146818_DEC
#define MC146818_DEC
Definition: devices.h:302
INTERRUPT_DEASSERT
#define INTERRUPT_DEASSERT(istruct)
Definition: interrupt.h:75
machine::machine_type
int machine_type
Definition: machine.h:111
N_REGISTERS
#define N_REGISTERS
Definition: dev_mc146818.cc:64
NETBSD_HACK_DONE
#define NETBSD_HACK_DONE
Definition: dev_mc146818.cc:100
MC_BASE_32_KHz
#define MC_BASE_32_KHz
Definition: mc146818reg.h:148
mc_data
Definition: dev_mc146818.cc:65
DEVICE_ACCESS
DEVICE_ACCESS(mc146818_jazz)
Definition: dev_mc146818.cc:152
interrupt
Definition: interrupt.h:36
MC_RATE_2048_Hz
#define MC_RATE_2048_Hz
Definition: mc146818reg.h:131
devices.h
MC_RATE_1024_Hz
#define MC_RATE_1024_Hz
Definition: mc146818reg.h:132
dev_mc146818_init
void dev_mc146818_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, char *irq_path, int access_style, int addrdiv)
Definition: dev_mc146818.cc:587
cpu
Definition: cpu.h:326
MC146818_PMPPC
#define MC146818_PMPPC
Definition: devices.h:309
MC_RATE_NONE
#define MC_RATE_NONE
Definition: mc146818reg.h:126
mc_data::timer
struct timer * timer
Definition: dev_mc146818.cc:79
mc_data::ugly_netbsd_prep_hack_sec
int ugly_netbsd_prep_hack_sec
Definition: dev_mc146818.cc:87
MC_BASE_4_MHz
#define MC_BASE_4_MHz
Definition: mc146818reg.h:146
MC146818_ARC_NEC
#define MC146818_ARC_NEC
Definition: devices.h:304
dev_mc146818_access
int dev_mc146818_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
memory.h
MC146818_TICK_SHIFT
#define MC146818_TICK_SHIFT
Definition: dev_mc146818.cc:60
dev_mc146818_tick
void dev_mc146818_tick(struct cpu *cpu, void *)
timer::extra
void * extra
Definition: timer.cc:50
machine::ncpus
int ncpus
Definition: machine.h:139
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17