hpet.rs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. // Copyright (C) 2024 Intel Corporation.
  2. // Author(s): Zhao Liu <zhai1.liu@intel.com>
  3. // SPDX-License-Identifier: GPL-2.0-or-later
  4. use std::{
  5. ffi::CStr,
  6. pin::Pin,
  7. ptr::{addr_of_mut, null_mut, NonNull},
  8. slice::from_ref,
  9. };
  10. use qemu_api::{
  11. bindings::{
  12. address_space_memory, address_space_stl_le, qdev_prop_bit, qdev_prop_bool,
  13. qdev_prop_uint32, qdev_prop_usize,
  14. },
  15. c_str,
  16. cell::{BqlCell, BqlRefCell},
  17. irq::InterruptSource,
  18. memory::{
  19. hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder, MEMTXATTRS_UNSPECIFIED,
  20. },
  21. prelude::*,
  22. qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl},
  23. qom::{ObjectImpl, ObjectType, ParentField},
  24. qom_isa,
  25. sysbus::{SysBusDevice, SysBusDeviceImpl},
  26. timer::{Timer, CLOCK_VIRTUAL},
  27. };
  28. use crate::fw_cfg::HPETFwConfig;
  29. /// Register space for each timer block (`HPET_BASE` is defined in hpet.h).
  30. const HPET_REG_SPACE_LEN: u64 = 0x400; // 1024 bytes
  31. /// Minimum recommended hardware implementation.
  32. const HPET_MIN_TIMERS: usize = 3;
  33. /// Maximum timers in each timer block.
  34. const HPET_MAX_TIMERS: usize = 32;
  35. /// Flags that HPETState.flags supports.
  36. const HPET_FLAG_MSI_SUPPORT_SHIFT: usize = 0;
  37. const HPET_NUM_IRQ_ROUTES: usize = 32;
  38. const HPET_LEGACY_PIT_INT: u32 = 0; // HPET_LEGACY_RTC_INT isn't defined here.
  39. const RTC_ISA_IRQ: usize = 8;
  40. const HPET_CLK_PERIOD: u64 = 10; // 10 ns
  41. const FS_PER_NS: u64 = 1000000; // 1000000 femtoseconds == 1 ns
  42. /// Revision ID (bits 0:7). Revision 1 is implemented (refer to v1.0a spec).
  43. const HPET_CAP_REV_ID_VALUE: u64 = 0x1;
  44. const HPET_CAP_REV_ID_SHIFT: usize = 0;
  45. /// Number of Timers (bits 8:12)
  46. const HPET_CAP_NUM_TIM_SHIFT: usize = 8;
  47. /// Counter Size (bit 13)
  48. const HPET_CAP_COUNT_SIZE_CAP_SHIFT: usize = 13;
  49. /// Legacy Replacement Route Capable (bit 15)
  50. const HPET_CAP_LEG_RT_CAP_SHIFT: usize = 15;
  51. /// Vendor ID (bits 16:31)
  52. const HPET_CAP_VENDER_ID_VALUE: u64 = 0x8086;
  53. const HPET_CAP_VENDER_ID_SHIFT: usize = 16;
  54. /// Main Counter Tick Period (bits 32:63)
  55. const HPET_CAP_CNT_CLK_PERIOD_SHIFT: usize = 32;
  56. /// Overall Enable (bit 0)
  57. const HPET_CFG_ENABLE_SHIFT: usize = 0;
  58. /// Legacy Replacement Route (bit 1)
  59. const HPET_CFG_LEG_RT_SHIFT: usize = 1;
  60. /// Other bits are reserved.
  61. const HPET_CFG_WRITE_MASK: u64 = 0x003;
  62. /// bit 0, 7, and bits 16:31 are reserved.
  63. /// bit 4, 5, 15, and bits 32:64 are read-only.
  64. const HPET_TN_CFG_WRITE_MASK: u64 = 0x7f4e;
  65. /// Timer N Interrupt Type (bit 1)
  66. const HPET_TN_CFG_INT_TYPE_SHIFT: usize = 1;
  67. /// Timer N Interrupt Enable (bit 2)
  68. const HPET_TN_CFG_INT_ENABLE_SHIFT: usize = 2;
  69. /// Timer N Type (Periodic enabled or not, bit 3)
  70. const HPET_TN_CFG_PERIODIC_SHIFT: usize = 3;
  71. /// Timer N Periodic Interrupt Capable (support Periodic or not, bit 4)
  72. const HPET_TN_CFG_PERIODIC_CAP_SHIFT: usize = 4;
  73. /// Timer N Size (timer size is 64-bits or 32 bits, bit 5)
  74. const HPET_TN_CFG_SIZE_CAP_SHIFT: usize = 5;
  75. /// Timer N Value Set (bit 6)
  76. const HPET_TN_CFG_SETVAL_SHIFT: usize = 6;
  77. /// Timer N 32-bit Mode (bit 8)
  78. const HPET_TN_CFG_32BIT_SHIFT: usize = 8;
  79. /// Timer N Interrupt Rout (bits 9:13)
  80. const HPET_TN_CFG_INT_ROUTE_MASK: u64 = 0x3e00;
  81. const HPET_TN_CFG_INT_ROUTE_SHIFT: usize = 9;
  82. /// Timer N FSB Interrupt Enable (bit 14)
  83. const HPET_TN_CFG_FSB_ENABLE_SHIFT: usize = 14;
  84. /// Timer N FSB Interrupt Delivery (bit 15)
  85. const HPET_TN_CFG_FSB_CAP_SHIFT: usize = 15;
  86. /// Timer N Interrupt Routing Capability (bits 32:63)
  87. const HPET_TN_CFG_INT_ROUTE_CAP_SHIFT: usize = 32;
  88. #[derive(qemu_api_macros::TryInto)]
  89. #[repr(u64)]
  90. #[allow(non_camel_case_types)]
  91. /// Timer registers, masked by 0x18
  92. enum TimerRegister {
  93. /// Timer N Configuration and Capability Register
  94. CFG = 0,
  95. /// Timer N Comparator Value Register
  96. CMP = 8,
  97. /// Timer N FSB Interrupt Route Register
  98. ROUTE = 16,
  99. }
  100. #[derive(qemu_api_macros::TryInto)]
  101. #[repr(u64)]
  102. #[allow(non_camel_case_types)]
  103. /// Global registers
  104. enum GlobalRegister {
  105. /// General Capabilities and ID Register
  106. CAP = 0,
  107. /// General Configuration Register
  108. CFG = 0x10,
  109. /// General Interrupt Status Register
  110. INT_STATUS = 0x20,
  111. /// Main Counter Value Register
  112. COUNTER = 0xF0,
  113. }
  114. enum HPETRegister<'a> {
  115. /// Global register in the range from `0` to `0xff`
  116. Global(GlobalRegister),
  117. /// Register in the timer block `0x100`...`0x3ff`
  118. Timer(&'a BqlRefCell<HPETTimer>, TimerRegister),
  119. /// Invalid address
  120. #[allow(dead_code)]
  121. Unknown(hwaddr),
  122. }
  123. struct HPETAddrDecode<'a> {
  124. shift: u32,
  125. len: u32,
  126. reg: HPETRegister<'a>,
  127. }
  128. const fn hpet_next_wrap(cur_tick: u64) -> u64 {
  129. (cur_tick | 0xffffffff) + 1
  130. }
  131. const fn hpet_time_after(a: u64, b: u64) -> bool {
  132. ((b - a) as i64) < 0
  133. }
  134. const fn ticks_to_ns(value: u64) -> u64 {
  135. value * HPET_CLK_PERIOD
  136. }
  137. const fn ns_to_ticks(value: u64) -> u64 {
  138. value / HPET_CLK_PERIOD
  139. }
  140. // Avoid touching the bits that cannot be written.
  141. const fn hpet_fixup_reg(new: u64, old: u64, mask: u64) -> u64 {
  142. (new & mask) | (old & !mask)
  143. }
  144. const fn activating_bit(old: u64, new: u64, shift: usize) -> bool {
  145. let mask: u64 = 1 << shift;
  146. (old & mask == 0) && (new & mask != 0)
  147. }
  148. const fn deactivating_bit(old: u64, new: u64, shift: usize) -> bool {
  149. let mask: u64 = 1 << shift;
  150. (old & mask != 0) && (new & mask == 0)
  151. }
  152. fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) {
  153. timer_cell.borrow_mut().callback()
  154. }
  155. /// HPET Timer Abstraction
  156. #[repr(C)]
  157. #[derive(Debug, qemu_api_macros::offsets)]
  158. pub struct HPETTimer {
  159. /// timer N index within the timer block (`HPETState`)
  160. #[doc(alias = "tn")]
  161. index: usize,
  162. qemu_timer: Timer,
  163. /// timer block abstraction containing this timer
  164. state: NonNull<HPETState>,
  165. // Memory-mapped, software visible timer registers
  166. /// Timer N Configuration and Capability Register
  167. config: u64,
  168. /// Timer N Comparator Value Register
  169. cmp: u64,
  170. /// Timer N FSB Interrupt Route Register
  171. fsb: u64,
  172. // Hidden register state
  173. /// comparator (extended to counter width)
  174. cmp64: u64,
  175. /// Last value written to comparator
  176. period: u64,
  177. /// timer pop will indicate wrap for one-shot 32-bit
  178. /// mode. Next pop will be actual timer expiration.
  179. wrap_flag: u8,
  180. /// last value armed, to avoid timer storms
  181. last: u64,
  182. }
  183. impl HPETTimer {
  184. fn init(&mut self, index: usize, state: &HPETState) {
  185. *self = HPETTimer {
  186. index,
  187. // SAFETY: the HPETTimer will only be used after the timer
  188. // is initialized below.
  189. qemu_timer: unsafe { Timer::new() },
  190. state: NonNull::new(state as *const _ as *mut _).unwrap(),
  191. config: 0,
  192. cmp: 0,
  193. fsb: 0,
  194. cmp64: 0,
  195. period: 0,
  196. wrap_flag: 0,
  197. last: 0,
  198. };
  199. // SAFETY: HPETTimer is only used as part of HPETState, which is
  200. // always pinned.
  201. let qemu_timer = unsafe { Pin::new_unchecked(&mut self.qemu_timer) };
  202. qemu_timer.init_full(
  203. None,
  204. CLOCK_VIRTUAL,
  205. Timer::NS,
  206. 0,
  207. timer_handler,
  208. &state.timers[self.index],
  209. )
  210. }
  211. fn get_state(&self) -> &HPETState {
  212. // SAFETY:
  213. // the pointer is convertible to a reference
  214. unsafe { self.state.as_ref() }
  215. }
  216. fn is_int_active(&self) -> bool {
  217. self.get_state().is_timer_int_active(self.index)
  218. }
  219. const fn is_fsb_route_enabled(&self) -> bool {
  220. self.config & (1 << HPET_TN_CFG_FSB_ENABLE_SHIFT) != 0
  221. }
  222. const fn is_periodic(&self) -> bool {
  223. self.config & (1 << HPET_TN_CFG_PERIODIC_SHIFT) != 0
  224. }
  225. const fn is_int_enabled(&self) -> bool {
  226. self.config & (1 << HPET_TN_CFG_INT_ENABLE_SHIFT) != 0
  227. }
  228. const fn is_32bit_mod(&self) -> bool {
  229. self.config & (1 << HPET_TN_CFG_32BIT_SHIFT) != 0
  230. }
  231. const fn is_valset_enabled(&self) -> bool {
  232. self.config & (1 << HPET_TN_CFG_SETVAL_SHIFT) != 0
  233. }
  234. fn clear_valset(&mut self) {
  235. self.config &= !(1 << HPET_TN_CFG_SETVAL_SHIFT);
  236. }
  237. /// True if timer interrupt is level triggered; otherwise, edge triggered.
  238. const fn is_int_level_triggered(&self) -> bool {
  239. self.config & (1 << HPET_TN_CFG_INT_TYPE_SHIFT) != 0
  240. }
  241. /// calculate next value of the general counter that matches the
  242. /// target (either entirely, or the low 32-bit only depending on
  243. /// the timer mode).
  244. fn calculate_cmp64(&self, cur_tick: u64, target: u64) -> u64 {
  245. if self.is_32bit_mod() {
  246. let mut result: u64 = cur_tick.deposit(0, 32, target);
  247. if result < cur_tick {
  248. result += 0x100000000;
  249. }
  250. result
  251. } else {
  252. target
  253. }
  254. }
  255. const fn get_individual_route(&self) -> usize {
  256. ((self.config & HPET_TN_CFG_INT_ROUTE_MASK) >> HPET_TN_CFG_INT_ROUTE_SHIFT) as usize
  257. }
  258. fn get_int_route(&self) -> usize {
  259. if self.index <= 1 && self.get_state().is_legacy_mode() {
  260. // If LegacyReplacement Route bit is set, HPET specification requires
  261. // timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
  262. // timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
  263. //
  264. // If the LegacyReplacement Route bit is set, the individual routing
  265. // bits for timers 0 and 1 (APIC or FSB) will have no impact.
  266. //
  267. // FIXME: Consider I/O APIC case.
  268. if self.index == 0 {
  269. 0
  270. } else {
  271. RTC_ISA_IRQ
  272. }
  273. } else {
  274. // (If the LegacyReplacement Route bit is set) Timer 2-n will be
  275. // routed as per the routing in the timer n config registers.
  276. // ...
  277. // If the LegacyReplacement Route bit is not set, the individual
  278. // routing bits for each of the timers are used.
  279. self.get_individual_route()
  280. }
  281. }
  282. fn set_irq(&mut self, set: bool) {
  283. let route = self.get_int_route();
  284. if set && self.is_int_enabled() && self.get_state().is_hpet_enabled() {
  285. if self.is_fsb_route_enabled() {
  286. // SAFETY:
  287. // the parameters are valid.
  288. unsafe {
  289. address_space_stl_le(
  290. addr_of_mut!(address_space_memory),
  291. self.fsb >> 32, // Timer N FSB int addr
  292. self.fsb as u32, // Timer N FSB int value, truncate!
  293. MEMTXATTRS_UNSPECIFIED,
  294. null_mut(),
  295. );
  296. }
  297. } else if self.is_int_level_triggered() {
  298. self.get_state().irqs[route].raise();
  299. } else {
  300. self.get_state().irqs[route].pulse();
  301. }
  302. } else if !self.is_fsb_route_enabled() {
  303. self.get_state().irqs[route].lower();
  304. }
  305. }
  306. fn update_irq(&mut self, set: bool) {
  307. // If Timer N Interrupt Enable bit is 0, "the timer will
  308. // still operate and generate appropriate status bits, but
  309. // will not cause an interrupt"
  310. self.get_state()
  311. .update_int_status(self.index as u32, set && self.is_int_level_triggered());
  312. self.set_irq(set);
  313. }
  314. fn arm_timer(&mut self, tick: u64) {
  315. let mut ns = self.get_state().get_ns(tick);
  316. // Clamp period to reasonable min value (1 us)
  317. if self.is_periodic() && ns - self.last < 1000 {
  318. ns = self.last + 1000;
  319. }
  320. self.last = ns;
  321. self.qemu_timer.modify(self.last);
  322. }
  323. fn set_timer(&mut self) {
  324. let cur_tick: u64 = self.get_state().get_ticks();
  325. self.wrap_flag = 0;
  326. self.cmp64 = self.calculate_cmp64(cur_tick, self.cmp);
  327. if self.is_32bit_mod() {
  328. // HPET spec says in one-shot 32-bit mode, generate an interrupt when
  329. // counter wraps in addition to an interrupt with comparator match.
  330. if !self.is_periodic() && self.cmp64 > hpet_next_wrap(cur_tick) {
  331. self.wrap_flag = 1;
  332. self.arm_timer(hpet_next_wrap(cur_tick));
  333. return;
  334. }
  335. }
  336. self.arm_timer(self.cmp64);
  337. }
  338. fn del_timer(&mut self) {
  339. // Just remove the timer from the timer_list without destroying
  340. // this timer instance.
  341. self.qemu_timer.delete();
  342. if self.is_int_active() {
  343. // For level-triggered interrupt, this leaves interrupt status
  344. // register set but lowers irq.
  345. self.update_irq(true);
  346. }
  347. }
  348. /// Configuration and Capability Register
  349. fn set_tn_cfg_reg(&mut self, shift: u32, len: u32, val: u64) {
  350. // TODO: Add trace point - trace_hpet_ram_write_tn_cfg(addr & 4)
  351. let old_val: u64 = self.config;
  352. let mut new_val: u64 = old_val.deposit(shift, len, val);
  353. new_val = hpet_fixup_reg(new_val, old_val, HPET_TN_CFG_WRITE_MASK);
  354. // Switch level-type interrupt to edge-type.
  355. if deactivating_bit(old_val, new_val, HPET_TN_CFG_INT_TYPE_SHIFT) {
  356. // Do this before changing timer.config; otherwise, if
  357. // HPET_TN_FSB is set, update_irq will not lower the qemu_irq.
  358. self.update_irq(false);
  359. }
  360. self.config = new_val;
  361. if activating_bit(old_val, new_val, HPET_TN_CFG_INT_ENABLE_SHIFT) && self.is_int_active() {
  362. self.update_irq(true);
  363. }
  364. if self.is_32bit_mod() {
  365. self.cmp = u64::from(self.cmp as u32); // truncate!
  366. self.period = u64::from(self.period as u32); // truncate!
  367. }
  368. if self.get_state().is_hpet_enabled() {
  369. self.set_timer();
  370. }
  371. }
  372. /// Comparator Value Register
  373. fn set_tn_cmp_reg(&mut self, shift: u32, len: u32, val: u64) {
  374. let mut length = len;
  375. let mut value = val;
  376. // TODO: Add trace point - trace_hpet_ram_write_tn_cmp(addr & 4)
  377. if self.is_32bit_mod() {
  378. // High 32-bits are zero, leave them untouched.
  379. if shift != 0 {
  380. // TODO: Add trace point - trace_hpet_ram_write_invalid_tn_cmp()
  381. return;
  382. }
  383. length = 64;
  384. value = u64::from(value as u32); // truncate!
  385. }
  386. if !self.is_periodic() || self.is_valset_enabled() {
  387. self.cmp = self.cmp.deposit(shift, length, value);
  388. }
  389. if self.is_periodic() {
  390. self.period = self.period.deposit(shift, length, value);
  391. }
  392. self.clear_valset();
  393. if self.get_state().is_hpet_enabled() {
  394. self.set_timer();
  395. }
  396. }
  397. /// FSB Interrupt Route Register
  398. fn set_tn_fsb_route_reg(&mut self, shift: u32, len: u32, val: u64) {
  399. self.fsb = self.fsb.deposit(shift, len, val);
  400. }
  401. fn reset(&mut self) {
  402. self.del_timer();
  403. self.cmp = u64::MAX; // Comparator Match Registers reset to all 1's.
  404. self.config = (1 << HPET_TN_CFG_PERIODIC_CAP_SHIFT) | (1 << HPET_TN_CFG_SIZE_CAP_SHIFT);
  405. if self.get_state().has_msi_flag() {
  406. self.config |= 1 << HPET_TN_CFG_FSB_CAP_SHIFT;
  407. }
  408. // advertise availability of ioapic int
  409. self.config |=
  410. (u64::from(self.get_state().int_route_cap)) << HPET_TN_CFG_INT_ROUTE_CAP_SHIFT;
  411. self.period = 0;
  412. self.wrap_flag = 0;
  413. }
  414. /// timer expiration callback
  415. fn callback(&mut self) {
  416. let period: u64 = self.period;
  417. let cur_tick: u64 = self.get_state().get_ticks();
  418. if self.is_periodic() && period != 0 {
  419. while hpet_time_after(cur_tick, self.cmp64) {
  420. self.cmp64 += period;
  421. }
  422. if self.is_32bit_mod() {
  423. self.cmp = u64::from(self.cmp64 as u32); // truncate!
  424. } else {
  425. self.cmp = self.cmp64;
  426. }
  427. self.arm_timer(self.cmp64);
  428. } else if self.wrap_flag != 0 {
  429. self.wrap_flag = 0;
  430. self.arm_timer(self.cmp64);
  431. }
  432. self.update_irq(true);
  433. }
  434. const fn read(&self, reg: TimerRegister) -> u64 {
  435. use TimerRegister::*;
  436. match reg {
  437. CFG => self.config, // including interrupt capabilities
  438. CMP => self.cmp, // comparator register
  439. ROUTE => self.fsb,
  440. }
  441. }
  442. fn write(&mut self, reg: TimerRegister, value: u64, shift: u32, len: u32) {
  443. use TimerRegister::*;
  444. match reg {
  445. CFG => self.set_tn_cfg_reg(shift, len, value),
  446. CMP => self.set_tn_cmp_reg(shift, len, value),
  447. ROUTE => self.set_tn_fsb_route_reg(shift, len, value),
  448. }
  449. }
  450. }
  451. /// HPET Event Timer Block Abstraction
  452. #[repr(C)]
  453. #[derive(qemu_api_macros::Object, qemu_api_macros::offsets)]
  454. pub struct HPETState {
  455. parent_obj: ParentField<SysBusDevice>,
  456. iomem: MemoryRegion,
  457. // HPET block Registers: Memory-mapped, software visible registers
  458. /// General Capabilities and ID Register
  459. capability: BqlCell<u64>,
  460. /// General Configuration Register
  461. config: BqlCell<u64>,
  462. /// General Interrupt Status Register
  463. #[doc(alias = "isr")]
  464. int_status: BqlCell<u64>,
  465. /// Main Counter Value Register
  466. #[doc(alias = "hpet_counter")]
  467. counter: BqlCell<u64>,
  468. // Internal state
  469. /// Capabilities that QEMU HPET supports.
  470. /// bit 0: MSI (or FSB) support.
  471. flags: u32,
  472. /// Offset of main counter relative to qemu clock.
  473. hpet_offset: BqlCell<u64>,
  474. hpet_offset_saved: bool,
  475. irqs: [InterruptSource; HPET_NUM_IRQ_ROUTES],
  476. rtc_irq_level: BqlCell<u32>,
  477. pit_enabled: InterruptSource,
  478. /// Interrupt Routing Capability.
  479. /// This field indicates to which interrupts in the I/O (x) APIC
  480. /// the timers' interrupt can be routed, and is encoded in the
  481. /// bits 32:64 of timer N's config register:
  482. #[doc(alias = "intcap")]
  483. int_route_cap: u32,
  484. /// HPET timer array managed by this timer block.
  485. #[doc(alias = "timer")]
  486. timers: [BqlRefCell<HPETTimer>; HPET_MAX_TIMERS],
  487. num_timers: BqlCell<usize>,
  488. /// Instance id (HPET timer block ID).
  489. hpet_id: BqlCell<usize>,
  490. }
  491. impl HPETState {
  492. const fn has_msi_flag(&self) -> bool {
  493. self.flags & (1 << HPET_FLAG_MSI_SUPPORT_SHIFT) != 0
  494. }
  495. fn is_legacy_mode(&self) -> bool {
  496. self.config.get() & (1 << HPET_CFG_LEG_RT_SHIFT) != 0
  497. }
  498. fn is_hpet_enabled(&self) -> bool {
  499. self.config.get() & (1 << HPET_CFG_ENABLE_SHIFT) != 0
  500. }
  501. fn is_timer_int_active(&self, index: usize) -> bool {
  502. self.int_status.get() & (1 << index) != 0
  503. }
  504. fn get_ticks(&self) -> u64 {
  505. ns_to_ticks(CLOCK_VIRTUAL.get_ns() + self.hpet_offset.get())
  506. }
  507. fn get_ns(&self, tick: u64) -> u64 {
  508. ticks_to_ns(tick) - self.hpet_offset.get()
  509. }
  510. fn handle_legacy_irq(&self, irq: u32, level: u32) {
  511. if irq == HPET_LEGACY_PIT_INT {
  512. if !self.is_legacy_mode() {
  513. self.irqs[0].set(level != 0);
  514. }
  515. } else {
  516. self.rtc_irq_level.set(level);
  517. if !self.is_legacy_mode() {
  518. self.irqs[RTC_ISA_IRQ].set(level != 0);
  519. }
  520. }
  521. }
  522. fn init_timer(&self) {
  523. for (index, timer) in self.timers.iter().enumerate() {
  524. timer.borrow_mut().init(index, self);
  525. }
  526. }
  527. fn update_int_status(&self, index: u32, level: bool) {
  528. self.int_status
  529. .set(self.int_status.get().deposit(index, 1, u64::from(level)));
  530. }
  531. /// General Configuration Register
  532. fn set_cfg_reg(&self, shift: u32, len: u32, val: u64) {
  533. let old_val = self.config.get();
  534. let mut new_val = old_val.deposit(shift, len, val);
  535. new_val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK);
  536. self.config.set(new_val);
  537. if activating_bit(old_val, new_val, HPET_CFG_ENABLE_SHIFT) {
  538. // Enable main counter and interrupt generation.
  539. self.hpet_offset
  540. .set(ticks_to_ns(self.counter.get()) - CLOCK_VIRTUAL.get_ns());
  541. for timer in self.timers.iter().take(self.num_timers.get()) {
  542. let mut t = timer.borrow_mut();
  543. if t.is_int_enabled() && t.is_int_active() {
  544. t.update_irq(true);
  545. }
  546. t.set_timer();
  547. }
  548. } else if deactivating_bit(old_val, new_val, HPET_CFG_ENABLE_SHIFT) {
  549. // Halt main counter and disable interrupt generation.
  550. self.counter.set(self.get_ticks());
  551. for timer in self.timers.iter().take(self.num_timers.get()) {
  552. timer.borrow_mut().del_timer();
  553. }
  554. }
  555. // i8254 and RTC output pins are disabled when HPET is in legacy mode
  556. if activating_bit(old_val, new_val, HPET_CFG_LEG_RT_SHIFT) {
  557. self.pit_enabled.set(false);
  558. self.irqs[0].lower();
  559. self.irqs[RTC_ISA_IRQ].lower();
  560. } else if deactivating_bit(old_val, new_val, HPET_CFG_LEG_RT_SHIFT) {
  561. // TODO: Add irq binding: qemu_irq_lower(s->irqs[0])
  562. self.irqs[0].lower();
  563. self.pit_enabled.set(true);
  564. self.irqs[RTC_ISA_IRQ].set(self.rtc_irq_level.get() != 0);
  565. }
  566. }
  567. /// General Interrupt Status Register: Read/Write Clear
  568. fn set_int_status_reg(&self, shift: u32, _len: u32, val: u64) {
  569. let new_val = val << shift;
  570. let cleared = new_val & self.int_status.get();
  571. for (index, timer) in self.timers.iter().take(self.num_timers.get()).enumerate() {
  572. if cleared & (1 << index) != 0 {
  573. timer.borrow_mut().update_irq(false);
  574. }
  575. }
  576. }
  577. /// Main Counter Value Register
  578. fn set_counter_reg(&self, shift: u32, len: u32, val: u64) {
  579. if self.is_hpet_enabled() {
  580. // TODO: Add trace point -
  581. // trace_hpet_ram_write_counter_write_while_enabled()
  582. //
  583. // HPET spec says that writes to this register should only be
  584. // done while the counter is halted. So this is an undefined
  585. // behavior. There's no need to forbid it, but when HPET is
  586. // enabled, the changed counter value will not affect the
  587. // tick count (i.e., the previously calculated offset will
  588. // not be changed as well).
  589. }
  590. self.counter
  591. .set(self.counter.get().deposit(shift, len, val));
  592. }
  593. unsafe fn init(&mut self) {
  594. static HPET_RAM_OPS: MemoryRegionOps<HPETState> =
  595. MemoryRegionOpsBuilder::<HPETState>::new()
  596. .read(&HPETState::read)
  597. .write(&HPETState::write)
  598. .native_endian()
  599. .valid_sizes(4, 8)
  600. .impl_sizes(4, 8)
  601. .build();
  602. // SAFETY:
  603. // self and self.iomem are guaranteed to be valid at this point since callers
  604. // must make sure the `self` reference is valid.
  605. MemoryRegion::init_io(
  606. unsafe { &mut *addr_of_mut!(self.iomem) },
  607. addr_of_mut!(*self),
  608. &HPET_RAM_OPS,
  609. "hpet",
  610. HPET_REG_SPACE_LEN,
  611. );
  612. }
  613. fn post_init(&self) {
  614. self.init_mmio(&self.iomem);
  615. for irq in self.irqs.iter() {
  616. self.init_irq(irq);
  617. }
  618. }
  619. fn realize(&self) {
  620. if self.int_route_cap == 0 {
  621. // TODO: Add error binding: warn_report()
  622. println!("Hpet's hpet-intcap property not initialized");
  623. }
  624. self.hpet_id.set(HPETFwConfig::assign_hpet_id());
  625. if self.num_timers.get() < HPET_MIN_TIMERS {
  626. self.num_timers.set(HPET_MIN_TIMERS);
  627. } else if self.num_timers.get() > HPET_MAX_TIMERS {
  628. self.num_timers.set(HPET_MAX_TIMERS);
  629. }
  630. self.init_timer();
  631. // 64-bit General Capabilities and ID Register; LegacyReplacementRoute.
  632. self.capability.set(
  633. HPET_CAP_REV_ID_VALUE << HPET_CAP_REV_ID_SHIFT |
  634. 1 << HPET_CAP_COUNT_SIZE_CAP_SHIFT |
  635. 1 << HPET_CAP_LEG_RT_CAP_SHIFT |
  636. HPET_CAP_VENDER_ID_VALUE << HPET_CAP_VENDER_ID_SHIFT |
  637. ((self.num_timers.get() - 1) as u64) << HPET_CAP_NUM_TIM_SHIFT | // indicate the last timer
  638. (HPET_CLK_PERIOD * FS_PER_NS) << HPET_CAP_CNT_CLK_PERIOD_SHIFT, // 10 ns
  639. );
  640. self.init_gpio_in(2, HPETState::handle_legacy_irq);
  641. self.init_gpio_out(from_ref(&self.pit_enabled));
  642. }
  643. fn reset_hold(&self, _type: ResetType) {
  644. for timer in self.timers.iter().take(self.num_timers.get()) {
  645. timer.borrow_mut().reset();
  646. }
  647. self.counter.set(0);
  648. self.config.set(0);
  649. self.pit_enabled.set(true);
  650. self.hpet_offset.set(0);
  651. HPETFwConfig::update_hpet_cfg(
  652. self.hpet_id.get(),
  653. self.capability.get() as u32,
  654. self.mmio_addr(0).unwrap(),
  655. );
  656. // to document that the RTC lowers its output on reset as well
  657. self.rtc_irq_level.set(0);
  658. }
  659. fn decode(&self, mut addr: hwaddr, size: u32) -> HPETAddrDecode {
  660. let shift = ((addr & 4) * 8) as u32;
  661. let len = std::cmp::min(size * 8, 64 - shift);
  662. addr &= !4;
  663. let reg = if (0..=0xff).contains(&addr) {
  664. GlobalRegister::try_from(addr).map(HPETRegister::Global)
  665. } else {
  666. let timer_id: usize = ((addr - 0x100) / 0x20) as usize;
  667. if timer_id <= self.num_timers.get() {
  668. // TODO: Add trace point - trace_hpet_ram_[read|write]_timer_id(timer_id)
  669. TimerRegister::try_from(addr & 0x18)
  670. .map(|reg| HPETRegister::Timer(&self.timers[timer_id], reg))
  671. } else {
  672. // TODO: Add trace point - trace_hpet_timer_id_out_of_range(timer_id)
  673. Err(addr)
  674. }
  675. };
  676. // reg is now a Result<HPETRegister, hwaddr>
  677. // convert the Err case into HPETRegister as well
  678. let reg = reg.unwrap_or_else(HPETRegister::Unknown);
  679. HPETAddrDecode { shift, len, reg }
  680. }
  681. fn read(&self, addr: hwaddr, size: u32) -> u64 {
  682. // TODO: Add trace point - trace_hpet_ram_read(addr)
  683. let HPETAddrDecode { shift, reg, .. } = self.decode(addr, size);
  684. use GlobalRegister::*;
  685. use HPETRegister::*;
  686. (match reg {
  687. Timer(timer, tn_reg) => timer.borrow_mut().read(tn_reg),
  688. Global(CAP) => self.capability.get(), /* including HPET_PERIOD 0x004 */
  689. Global(CFG) => self.config.get(),
  690. Global(INT_STATUS) => self.int_status.get(),
  691. Global(COUNTER) => {
  692. // TODO: Add trace point
  693. // trace_hpet_ram_read_reading_counter(addr & 4, cur_tick)
  694. if self.is_hpet_enabled() {
  695. self.get_ticks()
  696. } else {
  697. self.counter.get()
  698. }
  699. }
  700. Unknown(_) => {
  701. // TODO: Add trace point- trace_hpet_ram_read_invalid()
  702. 0
  703. }
  704. }) >> shift
  705. }
  706. fn write(&self, addr: hwaddr, value: u64, size: u32) {
  707. let HPETAddrDecode { shift, len, reg } = self.decode(addr, size);
  708. // TODO: Add trace point - trace_hpet_ram_write(addr, value)
  709. use GlobalRegister::*;
  710. use HPETRegister::*;
  711. match reg {
  712. Timer(timer, tn_reg) => timer.borrow_mut().write(tn_reg, value, shift, len),
  713. Global(CAP) => {} // General Capabilities and ID Register: Read Only
  714. Global(CFG) => self.set_cfg_reg(shift, len, value),
  715. Global(INT_STATUS) => self.set_int_status_reg(shift, len, value),
  716. Global(COUNTER) => self.set_counter_reg(shift, len, value),
  717. Unknown(_) => {
  718. // TODO: Add trace point - trace_hpet_ram_write_invalid()
  719. }
  720. }
  721. }
  722. }
  723. qom_isa!(HPETState: SysBusDevice, DeviceState, Object);
  724. unsafe impl ObjectType for HPETState {
  725. // No need for HPETClass. Just like OBJECT_DECLARE_SIMPLE_TYPE in C.
  726. type Class = <SysBusDevice as ObjectType>::Class;
  727. const TYPE_NAME: &'static CStr = crate::TYPE_HPET;
  728. }
  729. impl ObjectImpl for HPETState {
  730. type ParentType = SysBusDevice;
  731. const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
  732. const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init);
  733. const CLASS_INIT: fn(&mut Self::Class) = Self::Class::class_init::<Self>;
  734. }
  735. // TODO: Make these properties user-configurable!
  736. qemu_api::declare_properties! {
  737. HPET_PROPERTIES,
  738. qemu_api::define_property!(
  739. c_str!("timers"),
  740. HPETState,
  741. num_timers,
  742. unsafe { &qdev_prop_usize },
  743. usize,
  744. default = HPET_MIN_TIMERS
  745. ),
  746. qemu_api::define_property!(
  747. c_str!("msi"),
  748. HPETState,
  749. flags,
  750. unsafe { &qdev_prop_bit },
  751. u32,
  752. bit = HPET_FLAG_MSI_SUPPORT_SHIFT as u8,
  753. default = false,
  754. ),
  755. qemu_api::define_property!(
  756. c_str!("hpet-intcap"),
  757. HPETState,
  758. int_route_cap,
  759. unsafe { &qdev_prop_uint32 },
  760. u32,
  761. default = 0
  762. ),
  763. qemu_api::define_property!(
  764. c_str!("hpet-offset-saved"),
  765. HPETState,
  766. hpet_offset_saved,
  767. unsafe { &qdev_prop_bool },
  768. bool,
  769. default = true
  770. ),
  771. }
  772. impl DeviceImpl for HPETState {
  773. fn properties() -> &'static [Property] {
  774. &HPET_PROPERTIES
  775. }
  776. const REALIZE: Option<fn(&Self)> = Some(Self::realize);
  777. }
  778. impl ResettablePhasesImpl for HPETState {
  779. const HOLD: Option<fn(&Self, ResetType)> = Some(Self::reset_hold);
  780. }
  781. impl SysBusDeviceImpl for HPETState {}