Commit Graph

669 Commits

Author SHA1 Message Date
Samuel Holland
1f8db2f18f lib: utils/regmap: Use fdt_driver for initialization
The regmap driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. It always initializes the driver for a
specific DT node.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:45:29 +05:30
Samuel Holland
5fa510c5f6 lib: utils/ipi: Use fdt_driver for initialization
The ipi driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. The generic fdt_ipi_init() performs a
best-effort initialization of all matching DT nodes.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:42:05 +05:30
Samuel Holland
333133edaa lib: utils/i2c: Use fdt_driver for initialization
The i2c driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. It always initializes the driver for a
specific DT node.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:38:05 +05:30
Samuel Holland
bef8f9b806 lib: utils/gpio: Use fdt_driver for initialization
FDT gpio drivers have an extra .xlate operation, so they need to embed
the `struct fdt_driver` inside the subsystem-specific type. The gpio
subsystem always initializes the driver for a specific DT node.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:29:12 +05:30
Samuel Holland
1ccc52c427 lib: utils/fdt: Add helpers for generic driver initialization
Currently, each driver subsystem contains its own code for matching
drivers against the platform's devicetree blob. This bloats firmware
size because the several FDT scanning loops are almost exact copies of
each other, and is confusing because the loops do have some subtle
differences. Furthermore, the existing match algorithm is inefficient:
it scans the FDT structure separately for each driver in the list. A
faster algorithm scans the FDT blob only once, matching all drivers in
the list for each `compatible` property seen.

Add new helpers implementing this faster algorithm. Since they must
iterate through the list of drivers, the driver structure cannot be
opaque. However, since the driver list is an array of pointers, the
`struct fdt_driver` can be embedded in a subsystem-specific driver
structure if needed. These three helpers cover all existing use cases
for driver initialization within OpenSBI.

An additional benefit of centralized driver initialization is the
consistent use of fdt_node_is_enabled().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:13:05 +05:30
Samuel Holland
111772353f lib: sbi_irqchip: Set the IRQ handler when registering a chip
In addition to saving some code size, this moves the decision about
setting the top-level external interrupt handler to the irqchip core,
not the specific driver, which would be needed to support chained
interrupt handlers.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:51:56 +05:30
Samuel Holland
678f5909a3 platform: Drop irqchip warm init and exit hooks
Now that driver lifecycle is managed from within the SBI irqchip core,
platforms need only to initialize the driver once during cold init.
Remove the remaining platform hooks that are no longer used.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:46:36 +05:30
Samuel Holland
2dd6eaf680 lib: sbi_irqchip: Call driver warm_init from SBI core
Currently, each platform keeps track of which irqchip driver is in use
and calls its warm init function. Since the generic platform may use
multiple irqchip drivers, it has logic to track an array of drivers.

The code is simplified and made common across platforms by treating warm
init and exit as properties of the driver, not the platform. Then the
platform's only role is to select and prepare a driver during cold boot.

For now, only add a .warm_init hook, since none of the existing drivers
need an .exit hook. It could be added in the future if needed.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:40:17 +05:30
Samuel Holland
e3e5686ef9 lib: sbi_irqchip: Register devices during cold init
Have the SBI irqchip core keep track of registered irqchip devices. This
is useful for any callbacks the irqchip driver may have, such as for
warm initialization, the external interrupt handler function, and any
future support for handling external interrupts (beyond IPIs) in M-mode.

This improves on the tracking done in fdt_irqchip.c, as it tracks device
instances, not just drivers, so callbacks can target a specific device.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:37:25 +05:30
Samuel Holland
56fddce83f lib: utils/irqchip: Move per-hart data from fdt_plic to plic
The per-hart PLIC pointer is not really specific to FDT platforms. Move
it into the main driver and drop the extra wrapper functions.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:35:01 +05:30
Samuel Holland
c6c22f00f4 lib: utils/irqchip: plic: Common PM save/restore
Move the PLIC save/restore functions inside the driver, so they can be
reused on any platform that needs them. The memory needed to store the
PLIC context is also allocated by the driver. The PM data cannot be
completely encapsulated, as some platforms (including Allwinner D1) need
to program the IRQ enable status to a sideband interrupt controller for
wakeup capability.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:28:38 +05:30
Samuel Holland
69448a0790 lib: utils/irqchip: plic: Provide a hartindex to context map
This removes platform-specific arguments to plic_warm_irqchip_init(),
which makes the driver independent from the platform after cold init,
and allows for further refactoring.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 09:36:46 +05:30
Samuel Holland
c26e3fd2ed lib: utils/irqchip: plic: Move delegation to base PLIC driver
This needs to be in the base PLIC driver as part of the power management
save/restore flow.

This is also in preparation for moving the PLIC information in the
scratch area to the base PLIC driver. After that change, the FDT PLIC
layer will be unable to look up the `struct plic_data` after cold boot.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 09:35:11 +05:30
Samuel Holland
a786aed08d lib: utils/irqchip: plic: Allow enabling IRQs by default
Unlike other platforms, Ariane and OpenPiton enable all IRQs by default.
This was described in commit b44e844880 ("Add support for Ariane FPGA
SoC") as "due to some issue of the design." Add this workaround behind a
flag in plic_warm_irqchip_init(), so every platform can use the same
warm init function.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 09:35:10 +05:30
Samuel Holland
86d2c1797a platform: Drop IPI warm init and exit hooks
Now that the SBI IPI core clears IPIs at warm boot in a generic way,
none of the drivers or platforms use these hooks, and we can remove
them. Platforms need only to initialize the driver once during cold
init. If other hooks are needed in the future, they can be added to
struct sbi_ipi_device.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 18:21:04 +05:30
Samuel Holland
693afc818f lib: sbi_ipi: Move initial IPI clear to sbi_ipi_init()
sbi_ipi_init() expects the platform warm init function to clear IPIs
on the local hart, but there is already a generic function to do this.
After this change, none of the existing drivers need a warm init
callback.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 18:18:35 +05:30
Samuel Holland
be9752a071 lib: sbi_ipi: Make .ipi_clear always target the current hart
All existing users of this operation target the current hart, and it
seems unlikely that a future user will need to clear the pending IPI
status of a remote hart. Simplify the logic by changing .ipi_clear (and
its wrapper sbi_ipi_raw_clear()) to always operate on the current hart.

This incidentally fixes a bug introduced in commit 78c667b6fc ("lib:
sbi: Prefer hartindex over hartid in IPI framework"), which changed the
.ipi_clear parameter from a hartid to a hart index, but failed to update
the warm_init functions to match.

Fixes: 78c667b6fc ("lib: sbi: Prefer hartindex over hartid in IPI framework")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 18:17:15 +05:30
Zhang RunMin
db8f03e512 include: sbi: Fix typo error
Fix typo in comments describing SBI_SCRATCH_FW_HEAP_SIZE_OFFSET.

Signed-off-by: Zhang RunMin <runmin.zhang@ingenic.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 17:53:32 +05:30
Inochi Amaoto
dcb68dd17d platform: ensure enough heap size with debug triggers extension
DBTR introduce a big heap allocation to store hart state, this is
allocated percpu and needs big space when CPU number is high.

Increase the percpu part to fix this problem, and decrease the
fixed part to avoid too big heap size.

Fixes: 97f234f (lib: sbi: Introduce the SBI debug triggers extension support)
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 17:40:22 +05:30
Samuel Holland
9782b8847d lib: utils/regmap: Use FDT node offset as regmap ID
Since the FDT is not modified during driver initialization, node offsets
are just as suitable as phandles for use as identifiers: they are stable
and unique. With this change, it is no longer necessary to pass the
phandle to the driver init functions, so these init functions now use
the same prototype as other kinds of drivers.

This matches what is already done for I2C adapters.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:54:41 +05:30
Samuel Holland
d71150ee70 lib: utils/gpio: Use FDT node offset as GPIO chip ID
Since the FDT is not modified during driver initialization, node offsets
are just as suitable as phandles for use as identifiers: they are stable
and unique. With this change, it is no longer necessary to pass the
phandle to the driver init functions, so these init functions now use
the same prototype as other kinds of drivers.

This matches what is already done for I2C adapters.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:54:39 +05:30
Samuel Holland
99b01ab610 platform: Drop timer warm init and exit hooks
Now that driver lifecycle is managed from within the SBI timer core,
platforms need only to initialize the driver once during cold init.
Remove the remaining platform hooks that are no longer used.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:39:31 +05:30
Samuel Holland
4500828743 lib: sbi_timer: Call driver warm_init from SBI core
Currently, the platform's timer device is tracked in two places: the
core SBI implementation has `timer_dev`, and the FDT timer layer has
`current_driver`. The latter is used for warm initialization of the
timer device. However, this warm init is not specific to FDT-based
platforms; other platforms call exactly the same functions from the
same point in the boot sequence.

The code is simplified and made common across platforms by treating warm
init and exit as properties of the driver, not the platform. Then the
platform's only role is to select and prepare a driver during cold boot.

For now, only add a .warm_init hook, since none of the existing drivers
need an .exit hook. It could be added in the future if needed.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:29:13 +05:30
Samuel Holland
62447cd7aa include: sbi: Optimize reads of mhartid and mscratch
csr_read() is marked as volatile and clobbering memory, which is
generally the safe thing to do. However, these two CSRs do not have any
side effects, and the values returned do not change between calls. The
compiler can generate better code if we allow it to reorder calls to
these functions and cache the return value. Introduce csr_read_relaxed()
for this use case.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-10-28 10:51:37 +05:30
Clément Léger
c46a937fd9 lib: sbi: add Smdbltrp ISA extension support
Add support for the Smdbltrp[1] ISA extension. First thing to do is
clearing MDT on entry after setting the first MTVEC (since MDT is
reset to 1). Additionally, during trap handling, clear MDT once all
critical CSRs have been saved and in return path, restore MSTATUS/H
before restoring MEPC to avoid taking another trap which would clobber
it.

Link: https://github.com/riscv/riscv-double-trap/releases/download/v0.56/riscv-double-trap.pdf [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-26 00:00:12 +05:30
Clément Léger
3bc86854ab lib: sbi: implement firmware feature SBI_FWFT_DOUBLE_TRAP
Add support for double trap firmware feature.

Link: https://lists.riscv.org/g/tech-prs/message/985 [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:59:27 +05:30
Clément Léger
b2f77f5fa8 lib: sbi: fwft: factorize menvcfg read/write
MENVCFG access will be used as well for double trap, landing pad and
shadow stack fwft support. Factorize that in a common function.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:58:58 +05:30
Clément Léger
b0a7e4b853 lib: sbi: send a double trap SSE event to supervisor
In case the double trap handler is called and the double trap happened
in supervisor mode, send a double trap SSE event.

NOTE: this commit depends on the ratification of the new SSE event
id for double trap [1].

Link: https://lists.riscv.org/g/tech-prs/message/985 [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:58:39 +05:30
Clément Léger
9c78593269 lib: sbi: add Ssdbltrp ISA extension support
Add Ssdbltrp trap handler support for S-mode double trap handling. If
the trap is received while in VS-mode, then the trap is redirected to
S-mode. If caught while in HS-mode, then an error is returned to the top
trap handler which will panic.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:58:00 +05:30
Clément Léger
80656bdb1d lib: sbi: factorize previous mode computation
Previous privilege mode retrieval from mstatus is done at different
places, factorize it rather than copy/pasting it again.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:53:18 +05:30
Clément Léger
daa282573f lib: sbi: factorize previous virtualization mode read from regs
The same pattern is used at multiple places to verify in which mode
the exception was actually taken. Factorize it.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:52:51 +05:30
Himanshu Chauhan
b919daf495 lib: sbi: Add support to mask/unmask SSE events
Add functions to globally mask/unmask supervisor software events
on the calling hart.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-10-25 23:04:43 +05:30
Anup Patel
f609fd8584 lib: sbi_domain: Use domain data support for per-domain hart context
The per-domain hartindex_to_context_table[] is yet another per-domain
data required for implementing hart entry into (or exit from) domain.

Use the recently added domain data support for per-domain hart context
so that a dedicated hartindex_to_context_table[] in struct sbi_domain
is not needed.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
2024-10-25 23:00:10 +05:30
Anup Patel
81d79913a0 lib: sbi: Introduce domain data
Different parts of OpenSBI require their own per-domain data so
introduce domain data (or sbi_domain_data) which can be registered
by any part of OpenSBI. Using the domain data, the domain framework
will create a data pointer for every domain which can be used to
maintain some per-domain state.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
2024-10-25 23:00:07 +05:30
Anup Patel
65d4e9be95 include: sbi: Remove cyclic include in sbi_domain_context.h
The sbi_domain_context.h includes sbi_domain.h and the sbi_domain.h
also includes sbi_domain_context.h. Remove this cyclic include in
sbi_domain_context.h.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:00:04 +05:30
Anup Patel
36c1e4064f lib: sbi_domain: Make sbi_domain_root_add_memregion() as local function
The sbi_domain_root_add_memregion() is only used within sbi_domain
implementation so rename and make it a local function.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:00:00 +05:30
Elyes Haouas
7b3de48cd5 include: sbi: Don't unconditionally define '__always_inline'
Update __always_inline macro define to fix opensbi upstream
build for coreboot.
Refer, https://qa.coreboot.org/job/coreboot-gerrit/257449/testReport/junit/(root)/clang/EMULATION_QEMU_RISCV_RV64_/

Closes: https://github.com/riscv-software-src/opensbi/issues/366
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-09-27 10:52:32 +05:30
Samuel Holland
9155024972 lib: sbi: Remove unused hartid parameters
None of these functions use their hartid parameter.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:29:29 +05:30
Samuel Holland
3962be84d4 lib: sbi: Update sbi_{entry,init}_count() to take a hart index
All callers already have the hartindex available, so this removes a
hartid to hartindex conversion.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:29:27 +05:30
Samuel Holland
9f86524b58 lib: sbi: Update sbi_domain_is_assigned_hart() to take a hart index
This removes redundant hartid to hartindex conversions from four call
sites and provides a net reduction in code size.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:29:25 +05:30
Samuel Holland
fe153c5516 lib: sbi: Use sbi_hartmask in sbi_hsm_hart_interruptible_mask()
This removes several hartid/hartindex conversions, as well as two loops
through the mask for broadcast IPIs.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:28:18 +05:30
Samuel Holland
ebe0f31446 lib: sbi: Update __sbi_hsm_hart_get_state() to take a hart index
This removes some hartindex conversions in sbi_system_suspend(), but is
mostly intended to support refactoring sbi_hsm_hart_interruptible_mask()
to work exclusively with struct sbi_hartmask.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 11:30:04 +05:30
Samuel Holland
7f5fa9f9a4 lib: utils/irqchip: Look up IMSIC data by hart index
This avoids needing to map a hartid to a hart index.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 18:06:59 +05:30
Samuel Holland
15c4e285db lib: sbi: Use current_hartindex() where possible
This avoids calls to the expensive sbi_hartid_to_hartindex() function
and also makes the firmware smaller.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 12:03:30 +05:30
Samuel Holland
9d7a983060 include: sbi: Store the hart index in struct sbi_scratch
This is a more efficient way to get the index of the current hart than
calling a function to loop through the hartindex -> hartid lookup table.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 12:00:47 +05:30
Deepak Gupta
c0804ed49a lib: sbi: add zicfilp/zicfiss and elp cfi state reflect back in status
This patch adds support to check for zicfilp / zicfiss extension.

zicfilp record status of hart's ELP state in *status csr. Missing landing
pad sets MPELP in mstatus. When SBI is redirecting back to S/VS/HS, SPELP
is set in sstatus/vsstatus.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-09-23 18:58:04 +05:30
Deepak Gupta
6758a756c4 include: adding support for Zicfilp / Zicfiss encodings
Zicfilp / Zicfiss extension (see link) introduces b2 (LPE) in menvcfg CSR to
enable landing pads and b3 (SSE) in menvcfg CSR to enable shadow stack and
landing pad for privilege less than M. Additionally extension introduces new
bits in *status for recording landing pad state and a new exception type
`software check exception` with cause=0x12.

Link: https://github.com/riscv/riscv-cfi

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-09-23 18:55:07 +05:30
Zong Li
570b9ae89a include: sbi_bitops: add ULL version for BIT and GENMASK
Add BIT_ULL and GENMASK_ULL for dealing with 64-bits data on
32-bits CPU, then we don't need to separate the operation to
low part and high part. For instance, the MMIO register is
64 bits wide.

Signed-off-by: Zong Li <zong.li@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 18:33:02 +05:30
Samuel Holland
040fcf49ab lib: sbi_domain_context: Fix file permissions
These C source files should not be marked as executable.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 18:26:47 +05:30
Samuel Holland
1cb234b1c9 lib: sbi: fwft: add support for SBI_FWFT_POINTER_MASKING_PMLEN
Add support for controlling the pointer masking mode on harts which
support the Smnpm extension. This extension can only exist on harts
where XLEN >= 64 bits. This implementation selects the mode with the
smallest PMLEN that satisfies the caller's requested lower bound.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 17:50:40 +05:30