File: pc_system.h

package info (click to toggle)
bochs 2.6-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 17,328 kB
  • ctags: 24,668
  • sloc: cpp: 180,816; ansic: 17,482; sh: 8,228; makefile: 3,811; yacc: 1,179; asm: 385; perl: 379; lex: 286; csh: 3
file content (178 lines) | stat: -rw-r--r-- 6,635 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/////////////////////////////////////////////////////////////////////////
// $Id: pc_system.h 10209 2011-02-24 22:05:47Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2002-2009  The Bochs Project
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////

#ifndef BX_PCSYS_H
#define BX_PCSYS_H

#define BX_MAX_TIMERS 64
#define BX_NULL_TIMER_HANDLE 10000

typedef void (*bx_timer_handler_t)(void *);

BOCHSAPI extern class bx_pc_system_c bx_pc_system;

#ifdef PROVIDE_M_IPS
extern double m_ips;
#endif

class BOCHSAPI bx_pc_system_c : private logfunctions {
private:

  // ===============================
  // Timer oriented private features
  // ===============================

  struct {
    bx_bool inUse;      // Timer slot is in-use (currently registered).
    Bit64u  period;     // Timer periodocity in cpu ticks.
    Bit64u  timeToFire; // Time to fire next (in absolute ticks).
    bx_bool active;     // 0=inactive, 1=active.
    bx_bool continuous; // 0=one-shot timer, 1=continuous periodicity.
    bx_timer_handler_t funct;  // A callback function for when the
                               //   timer fires.
    void *this_ptr;            // The this-> pointer for C++ callbacks
                               //   has to be stored as well.
#define BxMaxTimerIDLen 32
    char id[BxMaxTimerIDLen]; // String ID of timer.
  } timer[BX_MAX_TIMERS];

  unsigned   numTimers;  // Number of currently allocated timers.
  unsigned   triggeredTimer;  // ID of the actually triggered timer.
  Bit32u     currCountdown; // Current countdown ticks value (decrements to 0).
  Bit32u     currCountdownPeriod; // Length of current countdown period.
  Bit64u     ticksTotal; // Num ticks total since start of emulator execution.
  Bit64u     lastTimeUsec; // Last sequentially read time in usec.
  Bit64u     usecSinceLast; // Number of useconds claimed since then.

  // A special null timer is always inserted in the timer[0] slot.  This
  // make sure that at least one timer is always active, and that the
  // duration is always less than a maximum 32-bit integer, so a 32-bit
  // counter can be used for the current countdown.
  static const Bit64u NullTimerInterval;
  static void nullTimer(void* this_ptr);

#if !defined(PROVIDE_M_IPS)
  // This is the emulator speed, as measured in millions of
  // x86 instructions per second that it can emulate on some hypothetically
  // nomimal workload.
  double     m_ips; // Millions of Instructions Per Second
#endif

  // This handler is called when the function which decrements the clock
  // ticks finds that an event has occurred.
  void   countdownEvent(void);

public:

  // ==============================
  // Timer oriented public features
  // ==============================

  void   initialize(Bit32u ips);
  int    register_timer(void *this_ptr, bx_timer_handler_t, Bit32u useconds,
                         bx_bool continuous, bx_bool active, const char *id);
  bx_bool unregisterTimer(unsigned timerID);
  void   start_timers(void);
  void   activate_timer(unsigned timer_index, Bit32u useconds, bx_bool continuous);
  void   deactivate_timer(unsigned timer_index);
  unsigned triggeredTimerID(void) {
    return triggeredTimer;
  }
  static BX_CPP_INLINE void tick1(void) {
    if (--bx_pc_system.currCountdown == 0) {
      bx_pc_system.countdownEvent();
    }
  }
  static BX_CPP_INLINE void tickn(Bit32u n) {
    while (n >= bx_pc_system.currCountdown) {
      n -= bx_pc_system.currCountdown;
      bx_pc_system.currCountdown = 0;
      bx_pc_system.countdownEvent();
      // bx_pc_system.currCountdown is adjusted to new value by countdownevent().
    }
    // 'n' is not (or no longer) >= the countdown size.  We can just decrement
    // the remaining requested ticks and continue.
    bx_pc_system.currCountdown -= n;
  }

  int register_timer_ticks(void* this_ptr, bx_timer_handler_t, Bit64u ticks,
                           bx_bool continuous, bx_bool active, const char *id);
  void activate_timer_ticks(unsigned index, Bit64u instructions,
                            bx_bool continuous);
  Bit64u time_usec();
  Bit64u time_usec_sequential();
  static BX_CPP_INLINE Bit64u time_ticks() {
    return bx_pc_system.ticksTotal +
      Bit64u(bx_pc_system.currCountdownPeriod - bx_pc_system.currCountdown);
  }

  static BX_CPP_INLINE Bit32u  getNumCpuTicksLeftNextEvent(void) {
    return bx_pc_system.currCountdown;
  }
#if BX_DEBUGGER
  static void timebp_handler(void* this_ptr);
#endif
  static void benchmarkTimer(void* this_ptr);

  // ===========================
  // Non-timer oriented features
  // ===========================

  bx_bool HRQ;     // Hold Request

  // Address line 20 control:
  //   1 = enabled: extended memory is accessible
  //   0 = disabled: A20 address line is forced low to simulate
  //       an 8088 address map
  bx_bool enable_a20;

  // start out masking physical memory addresses to:
  //   8086:      20 bits
  //    286:      24 bits
  //    386:      32 bits
  // when A20 line is disabled, mask physical memory addresses to:
  //    286:      20 bits
  //    386:      20 bits
  bx_phy_address a20_mask;

  volatile bx_bool kill_bochs_request;

  void set_HRQ(bx_bool val);  // set the Hold ReQuest line
  void set_INTR(bx_bool value); // set the INTR line to value

  // Cpu and System Reset
  int Reset(unsigned type);
  Bit8u  IAC(void);

  bx_pc_system_c();

  Bit32u  inp(Bit16u addr, unsigned io_len) BX_CPP_AttrRegparmN(2);
  void    outp(Bit16u addr, Bit32u value, unsigned io_len) BX_CPP_AttrRegparmN(3);
  void    set_enable_a20(bx_bool value);
  bx_bool get_enable_a20(void);
  void    MemoryMappingChanged(void); // flush TLB in all CPUs
  void    invlpg(bx_address addr);    // flush TLB page in all CPUs
  void    exit(void);
  void    register_state(void);
};

#endif