8ce60a75 | 15-Oct-2019 |
Philippe Mathieu-Daudé <philmd@redhat.com> |
hw/i386: Remove obsolete LoadStateHandler::load_state_old handlers
These devices implemented their load_state_old() handler 10 years ago, previous to QEMU v0.12. Since commit cc425b5ddf removed the
hw/i386: Remove obsolete LoadStateHandler::load_state_old handlers
These devices implemented their load_state_old() handler 10 years ago, previous to QEMU v0.12. Since commit cc425b5ddf removed the pc-0.10 and pc-0.11 machines, we can drop this code.
Note: the mips_r4k machine started to use the i8254 device just after QEMU v0.5.0, but the MIPS machine types are not versioned, so there is no migration compatibility issue removing this handler.
Suggested-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
show more ...
|
038adc2f | 12-Oct-2019 |
Wei Yang <richardw.yang@linux.intel.com> |
core: replace getpagesize() with qemu_real_host_page_size
There are three page size in qemu:
real host page size host page size target page size
All of them have dedicate variable to represe
core: replace getpagesize() with qemu_real_host_page_size
There are three page size in qemu:
real host page size host page size target page size
All of them have dedicate variable to represent. For the last two, we use the same form in the whole qemu project, while for the first one we use two forms: qemu_real_host_page_size and getpagesize().
qemu_real_host_page_size is defined to be a replacement of getpagesize(), so let it serve the role.
[Note] Not fully tested for some arch or device.
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com> Message-Id: <20191013021145.16011-3-richardw.yang@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
show more ...
|
673652a7 | 26-Oct-2019 |
Paolo Bonzini <pbonzini@redhat.com> |
Merge commit 'df84f17' into HEAD
This merge fixes a semantic conflict with the trivial tree.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
080f2730 | 23-Oct-2019 |
Richard Henderson <richard.henderson@linaro.org> |
target/arm: Rebuild hflags for M-profile NVIC
Continue setting, but not relying upon, env->hflags.
Suggested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.h
target/arm: Rebuild hflags for M-profile NVIC
Continue setting, but not relying upon, env->hflags.
Suggested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20191023150057.25731-22-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
show more ...
|
97c00c54 | 22-Oct-2019 |
Cédric Le Goater <clg@kaod.org> |
spapr/xive: Set the OS CAM line at reset
When a Virtual Processor is scheduled to run on a HW thread, the hypervisor pushes its identifier in the OS CAM line. When running with kernel_irqchip=off, Q
spapr/xive: Set the OS CAM line at reset
When a Virtual Processor is scheduled to run on a HW thread, the hypervisor pushes its identifier in the OS CAM line. When running with kernel_irqchip=off, QEMU needs to emulate the same behavior.
Set the OS CAM line when the interrupt presenter of the sPAPR core is reset. This will also cover the case of hot-plugged CPUs.
This change also has the benefit to remove the use of CPU_FOREACH() which can be unsafe.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org> Message-Id: <20191022163812.330-8-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
show more ...
|
d49e8a9b | 22-Oct-2019 |
Cédric Le Goater <clg@kaod.org> |
ppc: Reset the interrupt presenter from the CPU reset handler
On the sPAPR machine and PowerNV machine, the interrupt presenters are created by a machine handler at the core level and are reset inde
ppc: Reset the interrupt presenter from the CPU reset handler
On the sPAPR machine and PowerNV machine, the interrupt presenters are created by a machine handler at the core level and are reset independently. This is not consistent and it raises issues when it comes to handle hot-plugged CPUs. In that case, the presenters are not reset. This is less of an issue in XICS, although a zero MFFR could be a concern, but in XIVE, the OS CAM line is not set and this breaks the presenting algorithm. The current code has workarounds which need a global cleanup.
Extend the sPAPR IRQ backend and the PowerNV Chip class with a new cpu_intc_reset() handler called by the CPU reset handler and remove the XiveTCTX reset handler which is now redundant.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191022163812.330-6-clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
show more ...
|
605994e5 | 26-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move SpaprIrq::post_load hook to backends
The remaining logic in the post_load hook really belongs to the interrupt controller backends, and just needs to be called on the active
spapr, xics, xive: Move SpaprIrq::post_load hook to backends
The remaining logic in the post_load hook really belongs to the interrupt controller backends, and just needs to be called on the active controller (after the active controller is set to the right thing based on the incoming migration in the generic spapr_irq_post_load() logic).
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
567192d4 | 26-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
It turns out that all the logic in the SpaprIrq::reset hooks (and some in the SpaprIrq::post_load hooks) isn't really rela
spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
It turns out that all the logic in the SpaprIrq::reset hooks (and some in the SpaprIrq::post_load hooks) isn't really related to resetting the irq backend (that's handled by the backends' own reset routines). Rather its about getting the backend ready to be the active interrupt controller or stopping being the active interrupt controller - reset (and post_load) is just the only time that changes at present.
To make this flow clearer, move the logic into the explicit backend activate and deactivate hooks.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
98a39a79 | 26-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
Both XICS and XIVE have routines to connect and disconnect KVM with similar but not identical signatures. This adjusts the
spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
Both XICS and XIVE have routines to connect and disconnect KVM with similar but not identical signatures. This adjusts them to match exactly, which will be useful for further cleanups later.
While we're there, we add an explicit return value to the connect path to streamline error reporting in the callers. We remove error reporting the disconnect path. In the XICS case this wasn't used at all. In the XIVE case the only error case was if the KVM device was set up, but KVM didn't have the capability to do so which is pretty obviously impossible.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
05289273 | 29-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can
spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dispatch directly through that, rather than dispatching via SpaprIrq with the dual version having to do a second conditional dispatch.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
328d8eb2 | 26-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController
This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can
spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController
This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dispatch directly through that, rather than dispatching via SpaprIrq with the dual version having to do a second conditional dispatch.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
7bcdbcca | 26-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dis
spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
This method depends only on the active irq controller. Now that we've formalized the notion of active controller we can dispatch directly through that, rather than dispatching via SpaprIrq with the dual version having to do a second conditional dispatch.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
0b0e52b1 | 25-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
These methods, like cpu_intc_create, really belong to the interrupt controller, but need to be called on all poss
spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
These methods, like cpu_intc_create, really belong to the interrupt controller, but need to be called on all possible intcs.
Like cpu_intc_create, therefore, make them methods on the intc and always call it for all existing intcs.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
ebd6be08 | 25-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
This method essentially represents code which belongs to the interrupt controller, but needs to be called on all pos
spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
This method essentially represents code which belongs to the interrupt controller, but needs to be called on all possible intcs, rather than just the currently active one. The "dual" version therefore calls into the xics and xive versions confusingly.
Handle this more directly, by making it instead a method on the intc backend, and always calling it on every backend that exists.
While we're there, streamline the error reporting a bit.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
150e25f8 | 24-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Introduce SpaprInterruptController QOM interface
The SpaprIrq structure is used to represent ths spapr machine's irq backend. Except that it kind of conflates two concepts: one i
spapr, xics, xive: Introduce SpaprInterruptController QOM interface
The SpaprIrq structure is used to represent ths spapr machine's irq backend. Except that it kind of conflates two concepts: one is the backend proper - a specific interrupt controller that we might or might not be using, the other is the irq configuration which covers the layout of irq space and which interrupt controllers are allowed.
This leads to some pretty confusing code paths for the "dual" configuration where its hooks redirect to other SpaprIrq structures depending on the currently active irq controller.
To clean this up, we start by introducing a new SpaprInterruptController QOM interface to represent strictly an interrupt controller backend, not counting anything configuration related. We implement this interface in the XICs and XIVE interrupt controllers, and in future we'll move relevant methods from SpaprIrq into it.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
show more ...
|
106695ab | 07-Oct-2019 |
Cédric Le Goater <clg@kaod.org> |
ppc/pnv: Improve trigger data definition
The trigger data is used for both triggers of a HW source interrupts, PHB, PSI, and triggers for rerouting interrupts between interrupt controllers.
When an
ppc/pnv: Improve trigger data definition
The trigger data is used for both triggers of a HW source interrupts, PHB, PSI, and triggers for rerouting interrupts between interrupt controllers.
When an interrupt is rerouted, the trigger data follows an "END trigger" format. In that case, the remote IC needs EAS containing an END index to perform a lookup of an END.
An END trigger, bit0 of word0 set to '1', is defined as :
|0123|4567|0123|4567|0123|4567|0123|4567| W0 E=1 |1P--|BLOC| END IDX | W1 E=1 |M | END DATA |
An EAS is defined as :
|0123|4567|0123|4567|0123|4567|0123|4567| W0 |V---|BLOC| END IDX | W1 |M | END DATA |
The END trigger adds an extra 'PQ' bit, bit1 of word0 set to '1', signaling that the PQ bits have been checked. That bit is unused in the initial EAS definition.
When a HW device performs the trigger, the trigger data follows an "EAS trigger" format because the trigger data in that case contains an EAS index which the IC needs to look for.
An EAS trigger, bit0 of word0 set to '0', is defined as :
|0123|4567|0123|4567|0123|4567|0123|4567| W0 E=0 |0P--|---- ---- ---- ---- ---- ---- ----| W1 E=0 |BLOC| EAS INDEX |
There is also a 'PQ' bit, bit1 of word0 to '1', signaling that the PQ bits have been checked.
Introduce these new trigger bits and rename the XIVE_SRCNO macros in XIVE_EAS to reflect better the nature of the data.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191007084102.29776-2-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
show more ...
|
e6144bf9 | 04-Oct-2019 |
Greg Kurz <groug@kaod.org> |
xics: Make some device types not user creatable
Some device types of the XICS model are exposed to the QEMU command line:
$ ppc64-softmmu/qemu-system-ppc64 -device help | grep ic[sp] name "icp" nam
xics: Make some device types not user creatable
Some device types of the XICS model are exposed to the QEMU command line:
$ ppc64-softmmu/qemu-system-ppc64 -device help | grep ic[sp] name "icp" name "ics" name "ics-spapr" name "pnv-icp", desc "PowerNV ICP"
These are internal devices that shouldn't be instantiable by the user. By the way, they can't be because their respective realize functions expect link properties that can't be set from the command line:
qemu-system-ppc64: -device icp: required link 'xics' not found: Property '.xics' not found qemu-system-ppc64: -device ics: required link 'xics' not found: Property '.xics' not found qemu-system-ppc64: -device ics-spapr: required link 'xics' not found: Property '.xics' not found qemu-system-ppc64: -device pnv-icp: required link 'xics' not found: Property '.xics' not found
Hide them by setting dc->user_creatable to false in the base class "icp" and "ics" init functions.
Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <157017826724.337875.14822177178282524024.stgit@bahia.lan> Message-Id: <157045578962.865784.8551555523533955113.stgit@bahia.lan> [dwg: Folded reason comment into base patch] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
show more ...
|
878b2b48 | 04-Oct-2019 |
Greg Kurz <groug@kaod.org> |
xive: Make some device types not user creatable
Some device types of the XIVE model are exposed to the QEMU command line:
$ ppc64-softmmu/qemu-system-ppc64 -device help | grep xive name "xive-end-s
xive: Make some device types not user creatable
Some device types of the XIVE model are exposed to the QEMU command line:
$ ppc64-softmmu/qemu-system-ppc64 -device help | grep xive name "xive-end-source", desc "XIVE END Source" name "xive-source", desc "XIVE Interrupt Source" name "xive-tctx", desc "XIVE Interrupt Thread Context"
These are internal devices that shouldn't be instantiable by the user. By the way, they can't be because their respective realize functions expect link properties that can't be set from the command line:
qemu-system-ppc64: -device xive-source: required link 'xive' not found: Property '.xive' not found qemu-system-ppc64: -device xive-end-source: required link 'xive' not found: Property '.xive' not found qemu-system-ppc64: -device xive-tctx: required link 'cpu' not found: Property '.cpu' not found
Hide them by setting dc->user_creatable to false in their respective class init functions.
Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <157017473006.331610.2983143972519884544.stgit@bahia.lan> Message-Id: <157045578401.865784.6058183726552779559.stgit@bahia.lan> Reviewed-by: Cédric Le Goater <clg@kaod.org> [dwg: Folded comment update into base patch] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
show more ...
|
78cafff8 | 26-Sep-2019 |
Sergio Lopez <slp@redhat.com> |
hw/intc/apic: reject pic ints if isa_pic == NULL
In apic_accept_pic_intr(), reject PIC interruptions if a i8259 PIC has not been instantiated (isa_pic == NULL).
Suggested-by: Paolo Bonzini <pbonzin
hw/intc/apic: reject pic ints if isa_pic == NULL
In apic_accept_pic_intr(), reject PIC interruptions if a i8259 PIC has not been instantiated (isa_pic == NULL).
Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Sergio Lopez <slp@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
show more ...
|
f0bb276b | 22-Oct-2019 |
Paolo Bonzini <pbonzini@redhat.com> |
hw/i386: split PCMachineState deriving X86MachineState from it
Split up PCMachineState and PCMachineClass and derive X86MachineState and X86MachineClass from them. This allows sharing code with non-
hw/i386: split PCMachineState deriving X86MachineState from it
Split up PCMachineState and PCMachineClass and derive X86MachineState and X86MachineClass from them. This allows sharing code with non-PC x86 machine types.
Signed-off-by: Sergio Lopez <slp@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
show more ...
|
e1ecf8c8 | 26-Sep-2019 |
Philippe Mathieu-Daudé <f4bug@amsat.org> |
hw/arm/bcm2835_peripherals: Improve logging
Various logging improvements as once: - Use 0x prefix for hex numbers - Display value written during write accesses - Move some logs from GUEST_ERROR to U
hw/arm/bcm2835_peripherals: Improve logging
Various logging improvements as once: - Use 0x prefix for hex numbers - Display value written during write accesses - Move some logs from GUEST_ERROR to UNIMP
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-id: 20190926173428.10713-3-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
show more ...
|
f6530926 | 03-Oct-2019 |
Eric Auger <eric.auger@redhat.com> |
intc/arm_gic: Support IRQ injection for more than 256 vpus
Host kernels that expose the KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 capability allow injection of interrupts along with vcpu ids larger than 255. Le
intc/arm_gic: Support IRQ injection for more than 256 vpus
Host kernels that expose the KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 capability allow injection of interrupts along with vcpu ids larger than 255. Let's encode the vpcu id on 12 bits according to the upgraded KVM_IRQ_LINE ABI when needed.
Given that we have two callsites that need to assemble the value for kvm_set_irq(), a new helper routine, kvm_arm_set_irq is introduced.
Without that patch qemu exits with "kvm_set_irq: Invalid argument" message.
Signed-off-by: Eric Auger <eric.auger@redhat.com> Reported-by: Zenghui Yu <yuzenghui@huawei.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Andrew Jones <drjones@redhat.com> Acked-by: Marc Zyngier <maz@kernel.org> Message-id: 20191003154640.22451-3-eric.auger@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
show more ...
|
e594c2ad | 24-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
xive: Improve irq claim/free path
spapr_xive_irq_claim() returns a bool to indicate if it succeeded. But most of the callers and one callee use int return values and/or an Error * with more informat
xive: Improve irq claim/free path
spapr_xive_irq_claim() returns a bool to indicate if it succeeded. But most of the callers and one callee use int return values and/or an Error * with more information instead. In any case, ints are a more common idiom for success/failure states than bools (one never knows what sense they'll be in).
So instead change to an int return value to indicate presence of error + an Error * to describe the details through that call chain.
It also didn't actually check if the irq was already claimed, which is one of the primary purposes of the claim path, so do that.
spapr_xive_irq_free() also returned a bool... which no callers checked and was always true, so just drop it.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
show more ...
|
580dde5e | 24-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr, xics, xive: Better use of assert()s on irq claim/free paths
The irq claim and free paths for both XICS and XIVE check for some validity conditions. Some of these represent genuine runtime fa
spapr, xics, xive: Better use of assert()s on irq claim/free paths
The irq claim and free paths for both XICS and XIVE check for some validity conditions. Some of these represent genuine runtime failures, however others - particularly checking that the basic irq number is in a sane range - could only fail in the case of bugs in the callin code. Therefore use assert()s instead of runtime failures for those.
In addition the non backend-specific part of the claim/free paths should only be used for PAPR external irqs, that is in the range SPAPR_XIRQ_BASE to the maximum irq number. Put assert()s for that into the top level dispatchers as well.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
show more ...
|
14789694 | 23-Sep-2019 |
David Gibson <david@gibson.dropbear.id.au> |
spapr: Eliminate SpaprIrq:get_nodename method
This method is used to determine the name of the irq backend's node in the device tree, so that we can find its phandle (after SLOF may have modified it
spapr: Eliminate SpaprIrq:get_nodename method
This method is used to determine the name of the irq backend's node in the device tree, so that we can find its phandle (after SLOF may have modified it from the phandle we initially gave it).
But, in the two cases the only difference between the node name is the presence of a unit address. Searching for a node name without considering unit address is standard practice for the device tree, and fdt_subnode_offset() will do exactly that, making this method unecessary.
While we're there, remove the XICS_NODENAME define. The name "interrupt-controller" is required by PAPR (and IEEE1275), and a bunch of places assume it already.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Greg Kurz <groug@kaod.org>
show more ...
|