xref: /qemu/rust/hw/char/pl011/src/registers.rs (revision f8a113701dd2d28f3bedb216e59125ddcb77fd05)
1959fd759SPaolo Bonzini // Copyright 2024, Linaro Limited
2959fd759SPaolo Bonzini // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
3959fd759SPaolo Bonzini // SPDX-License-Identifier: GPL-2.0-or-later
4959fd759SPaolo Bonzini 
5959fd759SPaolo Bonzini //! Device registers exposed as typed structs which are backed by arbitrary
6959fd759SPaolo Bonzini //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc.
7959fd759SPaolo Bonzini 
86414b770SPeter Maydell // For more detail see the PL011 Technical Reference Manual DDI0183:
96414b770SPeter Maydell // https://developer.arm.com/documentation/ddi0183/latest/
106414b770SPeter Maydell 
11959fd759SPaolo Bonzini use bilge::prelude::*;
12*9c8ff2a1SPaolo Bonzini use bits::bits;
13*9c8ff2a1SPaolo Bonzini use qemu_api::{impl_vmstate_bitsized, impl_vmstate_forward};
14959fd759SPaolo Bonzini 
15959fd759SPaolo Bonzini /// Offset of each register from the base memory address of the device.
16959fd759SPaolo Bonzini #[doc(alias = "offset")]
17959fd759SPaolo Bonzini #[allow(non_camel_case_types)]
18959fd759SPaolo Bonzini #[repr(u64)]
19959fd759SPaolo Bonzini #[derive(Debug, Eq, PartialEq, qemu_api_macros::TryInto)]
20959fd759SPaolo Bonzini pub enum RegisterOffset {
21959fd759SPaolo Bonzini     /// Data Register
22959fd759SPaolo Bonzini     ///
23959fd759SPaolo Bonzini     /// A write to this register initiates the actual data transmission
24959fd759SPaolo Bonzini     #[doc(alias = "UARTDR")]
25959fd759SPaolo Bonzini     DR = 0x000,
26959fd759SPaolo Bonzini     /// Receive Status Register or Error Clear Register
27959fd759SPaolo Bonzini     #[doc(alias = "UARTRSR")]
28959fd759SPaolo Bonzini     #[doc(alias = "UARTECR")]
29959fd759SPaolo Bonzini     RSR = 0x004,
30959fd759SPaolo Bonzini     /// Flag Register
31959fd759SPaolo Bonzini     ///
32959fd759SPaolo Bonzini     /// A read of this register shows if transmission is complete
33959fd759SPaolo Bonzini     #[doc(alias = "UARTFR")]
34959fd759SPaolo Bonzini     FR = 0x018,
35959fd759SPaolo Bonzini     /// Fractional Baud Rate Register
36959fd759SPaolo Bonzini     ///
37959fd759SPaolo Bonzini     /// responsible for baud rate speed
38959fd759SPaolo Bonzini     #[doc(alias = "UARTFBRD")]
39959fd759SPaolo Bonzini     FBRD = 0x028,
40959fd759SPaolo Bonzini     /// `IrDA` Low-Power Counter Register
41959fd759SPaolo Bonzini     #[doc(alias = "UARTILPR")]
42959fd759SPaolo Bonzini     ILPR = 0x020,
43959fd759SPaolo Bonzini     /// Integer Baud Rate Register
44959fd759SPaolo Bonzini     ///
45959fd759SPaolo Bonzini     /// Responsible for baud rate speed
46959fd759SPaolo Bonzini     #[doc(alias = "UARTIBRD")]
47959fd759SPaolo Bonzini     IBRD = 0x024,
48959fd759SPaolo Bonzini     /// line control register (data frame format)
49959fd759SPaolo Bonzini     #[doc(alias = "UARTLCR_H")]
50959fd759SPaolo Bonzini     LCR_H = 0x02C,
51959fd759SPaolo Bonzini     /// Toggle UART, transmission or reception
52959fd759SPaolo Bonzini     #[doc(alias = "UARTCR")]
53959fd759SPaolo Bonzini     CR = 0x030,
54959fd759SPaolo Bonzini     /// Interrupt FIFO Level Select Register
55959fd759SPaolo Bonzini     #[doc(alias = "UARTIFLS")]
56959fd759SPaolo Bonzini     FLS = 0x034,
57959fd759SPaolo Bonzini     /// Interrupt Mask Set/Clear Register
58959fd759SPaolo Bonzini     #[doc(alias = "UARTIMSC")]
59959fd759SPaolo Bonzini     IMSC = 0x038,
60959fd759SPaolo Bonzini     /// Raw Interrupt Status Register
61959fd759SPaolo Bonzini     #[doc(alias = "UARTRIS")]
62959fd759SPaolo Bonzini     RIS = 0x03C,
63959fd759SPaolo Bonzini     /// Masked Interrupt Status Register
64959fd759SPaolo Bonzini     #[doc(alias = "UARTMIS")]
65959fd759SPaolo Bonzini     MIS = 0x040,
66959fd759SPaolo Bonzini     /// Interrupt Clear Register
67959fd759SPaolo Bonzini     #[doc(alias = "UARTICR")]
68959fd759SPaolo Bonzini     ICR = 0x044,
69959fd759SPaolo Bonzini     /// DMA control Register
70959fd759SPaolo Bonzini     #[doc(alias = "UARTDMACR")]
71959fd759SPaolo Bonzini     DMACR = 0x048,
72959fd759SPaolo Bonzini     ///// Reserved, offsets `0x04C` to `0x07C`.
73959fd759SPaolo Bonzini     //Reserved = 0x04C,
74959fd759SPaolo Bonzini }
75959fd759SPaolo Bonzini 
76959fd759SPaolo Bonzini /// Receive Status Register / Data Register common error bits
77959fd759SPaolo Bonzini ///
78959fd759SPaolo Bonzini /// The `UARTRSR` register is updated only when a read occurs
79959fd759SPaolo Bonzini /// from the `UARTDR` register with the same status information
80959fd759SPaolo Bonzini /// that can also be obtained by reading the `UARTDR` register
81959fd759SPaolo Bonzini #[bitsize(8)]
82959fd759SPaolo Bonzini #[derive(Clone, Copy, Default, DebugBits, FromBits)]
83959fd759SPaolo Bonzini pub struct Errors {
84959fd759SPaolo Bonzini     pub framing_error: bool,
85959fd759SPaolo Bonzini     pub parity_error: bool,
86959fd759SPaolo Bonzini     pub break_error: bool,
87959fd759SPaolo Bonzini     pub overrun_error: bool,
88959fd759SPaolo Bonzini     _reserved_unpredictable: u4,
89959fd759SPaolo Bonzini }
90959fd759SPaolo Bonzini 
91959fd759SPaolo Bonzini /// Data Register, `UARTDR`
92959fd759SPaolo Bonzini ///
936414b770SPeter Maydell /// The `UARTDR` register is the data register; write for TX and
946414b770SPeter Maydell /// read for RX. It is a 12-bit register, where bits 7..0 are the
956414b770SPeter Maydell /// character and bits 11..8 are error bits.
96959fd759SPaolo Bonzini #[bitsize(32)]
97959fd759SPaolo Bonzini #[derive(Clone, Copy, Default, DebugBits, FromBits)]
98959fd759SPaolo Bonzini #[doc(alias = "UARTDR")]
99959fd759SPaolo Bonzini pub struct Data {
100959fd759SPaolo Bonzini     pub data: u8,
101959fd759SPaolo Bonzini     pub errors: Errors,
102959fd759SPaolo Bonzini     _reserved: u16,
103959fd759SPaolo Bonzini }
104959fd759SPaolo Bonzini impl_vmstate_bitsized!(Data);
105959fd759SPaolo Bonzini 
106959fd759SPaolo Bonzini impl Data {
107959fd759SPaolo Bonzini     // bilge is not very const-friendly, unfortunately
108959fd759SPaolo Bonzini     pub const BREAK: Self = Self { value: 1 << 10 };
109959fd759SPaolo Bonzini }
110959fd759SPaolo Bonzini 
111959fd759SPaolo Bonzini /// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR`
112959fd759SPaolo Bonzini ///
1136414b770SPeter Maydell /// This register provides a different way to read the four receive
1146414b770SPeter Maydell /// status error bits that can be found in bits 11..8 of the UARTDR
1156414b770SPeter Maydell /// on a read. It gets updated when the guest reads UARTDR, and the
1166414b770SPeter Maydell /// status bits correspond to that character that was just read.
117959fd759SPaolo Bonzini ///
1186414b770SPeter Maydell /// The TRM confusingly describes this offset as UARTRSR for reads
1196414b770SPeter Maydell /// and UARTECR for writes, but really it's a single error status
1206414b770SPeter Maydell /// register where writing anything to the register clears the error
1216414b770SPeter Maydell /// bits.
122959fd759SPaolo Bonzini #[bitsize(32)]
123959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)]
124959fd759SPaolo Bonzini pub struct ReceiveStatusErrorClear {
125959fd759SPaolo Bonzini     pub errors: Errors,
126959fd759SPaolo Bonzini     _reserved_unpredictable: u24,
127959fd759SPaolo Bonzini }
128959fd759SPaolo Bonzini impl_vmstate_bitsized!(ReceiveStatusErrorClear);
129959fd759SPaolo Bonzini 
130959fd759SPaolo Bonzini impl ReceiveStatusErrorClear {
set_from_data(&mut self, data: Data)131959fd759SPaolo Bonzini     pub fn set_from_data(&mut self, data: Data) {
132959fd759SPaolo Bonzini         self.set_errors(data.errors());
133959fd759SPaolo Bonzini     }
134959fd759SPaolo Bonzini 
reset(&mut self)135959fd759SPaolo Bonzini     pub fn reset(&mut self) {
136959fd759SPaolo Bonzini         // All the bits are cleared to 0 on reset.
137959fd759SPaolo Bonzini         *self = Self::default();
138959fd759SPaolo Bonzini     }
139959fd759SPaolo Bonzini }
140959fd759SPaolo Bonzini 
141959fd759SPaolo Bonzini impl Default for ReceiveStatusErrorClear {
default() -> Self142959fd759SPaolo Bonzini     fn default() -> Self {
143959fd759SPaolo Bonzini         0.into()
144959fd759SPaolo Bonzini     }
145959fd759SPaolo Bonzini }
146959fd759SPaolo Bonzini 
147959fd759SPaolo Bonzini #[bitsize(32)]
148959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)]
149959fd759SPaolo Bonzini /// Flag Register, `UARTFR`
1506414b770SPeter Maydell ///
1516414b770SPeter Maydell /// This has the usual inbound RS232 modem-control signals, plus flags
1526414b770SPeter Maydell /// for RX and TX FIFO fill levels and a BUSY flag.
153959fd759SPaolo Bonzini #[doc(alias = "UARTFR")]
154959fd759SPaolo Bonzini pub struct Flags {
1556414b770SPeter Maydell     /// CTS: Clear to send
156959fd759SPaolo Bonzini     pub clear_to_send: bool,
1576414b770SPeter Maydell     /// DSR: Data set ready
158959fd759SPaolo Bonzini     pub data_set_ready: bool,
1596414b770SPeter Maydell     /// DCD: Data carrier detect
160959fd759SPaolo Bonzini     pub data_carrier_detect: bool,
1616414b770SPeter Maydell     /// BUSY: UART busy. In real hardware, set while the UART is
1626414b770SPeter Maydell     /// busy transmitting data. QEMU's implementation never sets BUSY.
163959fd759SPaolo Bonzini     pub busy: bool,
1646414b770SPeter Maydell     /// RXFE: Receive FIFO empty
165959fd759SPaolo Bonzini     pub receive_fifo_empty: bool,
1666414b770SPeter Maydell     /// TXFF: Transmit FIFO full
167959fd759SPaolo Bonzini     pub transmit_fifo_full: bool,
1686414b770SPeter Maydell     /// RXFF: Receive FIFO full
169959fd759SPaolo Bonzini     pub receive_fifo_full: bool,
1706414b770SPeter Maydell     /// TXFE: Transmit FIFO empty
171959fd759SPaolo Bonzini     pub transmit_fifo_empty: bool,
1726414b770SPeter Maydell     /// RI: Ring indicator
173959fd759SPaolo Bonzini     pub ring_indicator: bool,
174959fd759SPaolo Bonzini     _reserved_zero_no_modify: u23,
175959fd759SPaolo Bonzini }
176959fd759SPaolo Bonzini impl_vmstate_bitsized!(Flags);
177959fd759SPaolo Bonzini 
178959fd759SPaolo Bonzini impl Flags {
reset(&mut self)179959fd759SPaolo Bonzini     pub fn reset(&mut self) {
180959fd759SPaolo Bonzini         *self = Self::default();
181959fd759SPaolo Bonzini     }
182959fd759SPaolo Bonzini }
183959fd759SPaolo Bonzini 
184959fd759SPaolo Bonzini impl Default for Flags {
default() -> Self185959fd759SPaolo Bonzini     fn default() -> Self {
186959fd759SPaolo Bonzini         let mut ret: Self = 0.into();
187959fd759SPaolo Bonzini         // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1
188959fd759SPaolo Bonzini         ret.set_receive_fifo_empty(true);
189959fd759SPaolo Bonzini         ret.set_transmit_fifo_empty(true);
190959fd759SPaolo Bonzini         ret
191959fd759SPaolo Bonzini     }
192959fd759SPaolo Bonzini }
193959fd759SPaolo Bonzini 
194959fd759SPaolo Bonzini #[bitsize(32)]
195959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)]
196959fd759SPaolo Bonzini /// Line Control Register, `UARTLCR_H`
197959fd759SPaolo Bonzini #[doc(alias = "UARTLCR_H")]
198959fd759SPaolo Bonzini pub struct LineControl {
1996414b770SPeter Maydell     /// BRK: Send break
200959fd759SPaolo Bonzini     pub send_break: bool,
2016414b770SPeter Maydell     /// PEN: Parity enable
202959fd759SPaolo Bonzini     pub parity_enabled: bool,
2036414b770SPeter Maydell     /// EPS: Even parity select
204959fd759SPaolo Bonzini     pub parity: Parity,
2056414b770SPeter Maydell     /// STP2: Two stop bits select
206959fd759SPaolo Bonzini     pub two_stops_bits: bool,
2076414b770SPeter Maydell     /// FEN: Enable FIFOs
208959fd759SPaolo Bonzini     pub fifos_enabled: Mode,
2096414b770SPeter Maydell     /// WLEN: Word length in bits
2106414b770SPeter Maydell     /// b11 = 8 bits
211959fd759SPaolo Bonzini     /// b10 = 7 bits
212959fd759SPaolo Bonzini     /// b01 = 6 bits
213959fd759SPaolo Bonzini     /// b00 = 5 bits.
214959fd759SPaolo Bonzini     pub word_length: WordLength,
2156414b770SPeter Maydell     /// SPS Stick parity select
216959fd759SPaolo Bonzini     pub sticky_parity: bool,
217959fd759SPaolo Bonzini     /// 31:8 - Reserved, do not modify, read as zero.
218959fd759SPaolo Bonzini     _reserved_zero_no_modify: u24,
219959fd759SPaolo Bonzini }
220959fd759SPaolo Bonzini impl_vmstate_bitsized!(LineControl);
221959fd759SPaolo Bonzini 
222959fd759SPaolo Bonzini impl LineControl {
reset(&mut self)223959fd759SPaolo Bonzini     pub fn reset(&mut self) {
224959fd759SPaolo Bonzini         // All the bits are cleared to 0 when reset.
225959fd759SPaolo Bonzini         *self = 0.into();
226959fd759SPaolo Bonzini     }
227959fd759SPaolo Bonzini }
228959fd759SPaolo Bonzini 
229959fd759SPaolo Bonzini impl Default for LineControl {
default() -> Self230959fd759SPaolo Bonzini     fn default() -> Self {
231959fd759SPaolo Bonzini         0.into()
232959fd759SPaolo Bonzini     }
233959fd759SPaolo Bonzini }
234959fd759SPaolo Bonzini 
235959fd759SPaolo Bonzini #[bitsize(1)]
236959fd759SPaolo Bonzini #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
237959fd759SPaolo Bonzini /// `EPS` "Even parity select", field of [Line Control
238959fd759SPaolo Bonzini /// register](LineControl).
239959fd759SPaolo Bonzini pub enum Parity {
240959fd759SPaolo Bonzini     Odd = 0,
241959fd759SPaolo Bonzini     Even = 1,
242959fd759SPaolo Bonzini }
243959fd759SPaolo Bonzini 
244959fd759SPaolo Bonzini #[bitsize(1)]
245959fd759SPaolo Bonzini #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
246959fd759SPaolo Bonzini /// `FEN` "Enable FIFOs" or Device mode, field of [Line Control
247959fd759SPaolo Bonzini /// register](LineControl).
248959fd759SPaolo Bonzini pub enum Mode {
249959fd759SPaolo Bonzini     /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become
250959fd759SPaolo Bonzini     /// 1-byte-deep holding registers
251959fd759SPaolo Bonzini     Character = 0,
252959fd759SPaolo Bonzini     /// 1 = transmit and receive FIFO buffers are enabled (FIFO mode).
253959fd759SPaolo Bonzini     FIFO = 1,
254959fd759SPaolo Bonzini }
255959fd759SPaolo Bonzini 
256959fd759SPaolo Bonzini #[bitsize(2)]
257959fd759SPaolo Bonzini #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
258959fd759SPaolo Bonzini /// `WLEN` Word length, field of [Line Control register](LineControl).
259959fd759SPaolo Bonzini ///
260959fd759SPaolo Bonzini /// These bits indicate the number of data bits transmitted or received in a
261959fd759SPaolo Bonzini /// frame as follows:
262959fd759SPaolo Bonzini pub enum WordLength {
263959fd759SPaolo Bonzini     /// b11 = 8 bits
264959fd759SPaolo Bonzini     _8Bits = 0b11,
265959fd759SPaolo Bonzini     /// b10 = 7 bits
266959fd759SPaolo Bonzini     _7Bits = 0b10,
267959fd759SPaolo Bonzini     /// b01 = 6 bits
268959fd759SPaolo Bonzini     _6Bits = 0b01,
269959fd759SPaolo Bonzini     /// b00 = 5 bits.
270959fd759SPaolo Bonzini     _5Bits = 0b00,
271959fd759SPaolo Bonzini }
272959fd759SPaolo Bonzini 
273959fd759SPaolo Bonzini /// Control Register, `UARTCR`
274959fd759SPaolo Bonzini ///
2756414b770SPeter Maydell /// The `UARTCR` register is the control register. It contains various
2766414b770SPeter Maydell /// enable bits, and the bits to write to set the usual outbound RS232
2776414b770SPeter Maydell /// modem control signals. All bits reset to 0 except TXE and RXE.
278959fd759SPaolo Bonzini #[bitsize(32)]
279959fd759SPaolo Bonzini #[doc(alias = "UARTCR")]
280959fd759SPaolo Bonzini #[derive(Clone, Copy, DebugBits, FromBits)]
281959fd759SPaolo Bonzini pub struct Control {
2826414b770SPeter Maydell     /// `UARTEN` UART enable: 0 = UART is disabled.
283959fd759SPaolo Bonzini     pub enable_uart: bool,
2846414b770SPeter Maydell     /// `SIREN` `SIR` enable: disable or enable IrDA SIR ENDEC.
2856414b770SPeter Maydell     /// QEMU does not model this.
286959fd759SPaolo Bonzini     pub enable_sir: bool,
2876414b770SPeter Maydell     /// `SIRLP` SIR low-power IrDA mode. QEMU does not model this.
288959fd759SPaolo Bonzini     pub sir_lowpower_irda_mode: u1,
289959fd759SPaolo Bonzini     /// Reserved, do not modify, read as zero.
290959fd759SPaolo Bonzini     _reserved_zero_no_modify: u4,
2916414b770SPeter Maydell     /// `LBE` Loopback enable: feed UART output back to the input
292959fd759SPaolo Bonzini     pub enable_loopback: bool,
2936414b770SPeter Maydell     /// `TXE` Transmit enable
294959fd759SPaolo Bonzini     pub enable_transmit: bool,
2956414b770SPeter Maydell     /// `RXE` Receive enable
296959fd759SPaolo Bonzini     pub enable_receive: bool,
2976414b770SPeter Maydell     /// `DTR` Data transmit ready
298959fd759SPaolo Bonzini     pub data_transmit_ready: bool,
2996414b770SPeter Maydell     /// `RTS` Request to send
300959fd759SPaolo Bonzini     pub request_to_send: bool,
3016414b770SPeter Maydell     /// `Out1` UART Out1 signal; can be used as DCD
302959fd759SPaolo Bonzini     pub out_1: bool,
3036414b770SPeter Maydell     /// `Out2` UART Out2 signal; can be used as RI
304959fd759SPaolo Bonzini     pub out_2: bool,
3056414b770SPeter Maydell     /// `RTSEn` RTS hardware flow control enable
306959fd759SPaolo Bonzini     pub rts_hardware_flow_control_enable: bool,
3076414b770SPeter Maydell     /// `CTSEn` CTS hardware flow control enable
308959fd759SPaolo Bonzini     pub cts_hardware_flow_control_enable: bool,
309959fd759SPaolo Bonzini     /// 31:16 - Reserved, do not modify, read as zero.
310959fd759SPaolo Bonzini     _reserved_zero_no_modify2: u16,
311959fd759SPaolo Bonzini }
312959fd759SPaolo Bonzini impl_vmstate_bitsized!(Control);
313959fd759SPaolo Bonzini 
314959fd759SPaolo Bonzini impl Control {
reset(&mut self)315959fd759SPaolo Bonzini     pub fn reset(&mut self) {
316959fd759SPaolo Bonzini         *self = 0.into();
317959fd759SPaolo Bonzini         self.set_enable_receive(true);
318959fd759SPaolo Bonzini         self.set_enable_transmit(true);
319959fd759SPaolo Bonzini     }
320959fd759SPaolo Bonzini }
321959fd759SPaolo Bonzini 
322959fd759SPaolo Bonzini impl Default for Control {
default() -> Self323959fd759SPaolo Bonzini     fn default() -> Self {
324959fd759SPaolo Bonzini         let mut ret: Self = 0.into();
325959fd759SPaolo Bonzini         ret.reset();
326959fd759SPaolo Bonzini         ret
327959fd759SPaolo Bonzini     }
328959fd759SPaolo Bonzini }
329959fd759SPaolo Bonzini 
330*9c8ff2a1SPaolo Bonzini bits! {
331959fd759SPaolo Bonzini     /// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC
332*9c8ff2a1SPaolo Bonzini     #[derive(Default)]
333*9c8ff2a1SPaolo Bonzini     pub struct Interrupt(u32) {
334*9c8ff2a1SPaolo Bonzini         OE = 1 << 10,
335*9c8ff2a1SPaolo Bonzini         BE = 1 << 9,
336*9c8ff2a1SPaolo Bonzini         PE = 1 << 8,
337*9c8ff2a1SPaolo Bonzini         FE = 1 << 7,
338*9c8ff2a1SPaolo Bonzini         RT = 1 << 6,
339*9c8ff2a1SPaolo Bonzini         TX = 1 << 5,
340*9c8ff2a1SPaolo Bonzini         RX = 1 << 4,
341*9c8ff2a1SPaolo Bonzini         DSR = 1 << 3,
342*9c8ff2a1SPaolo Bonzini         DCD = 1 << 2,
343*9c8ff2a1SPaolo Bonzini         CTS = 1 << 1,
344*9c8ff2a1SPaolo Bonzini         RI = 1 << 0,
345959fd759SPaolo Bonzini 
346*9c8ff2a1SPaolo Bonzini         E = bits!(Self as u32: OE | BE | PE | FE),
347*9c8ff2a1SPaolo Bonzini         MS = bits!(Self as u32: RI | DSR | DCD | CTS),
348959fd759SPaolo Bonzini     }
349*9c8ff2a1SPaolo Bonzini }
350*9c8ff2a1SPaolo Bonzini impl_vmstate_forward!(Interrupt);
351