OS-A SEE Meeting October 4th @ 9am Pacific
Hi All,
This is a reminder that we'll be having the OS-A SEE meeting on October 4th at 9am Pacific Time.
Thank you.
-Aaron
|
|
Re: [RISC-V] [tech-debug] SBI Debug Trigger Extension Proposal (Draft v4)

Anup Patel
On Wed, Sep 28, 2022 at 10:59 PM merle w <merlew4n6@...> wrote: Anup Patel <apatel@...> 于2022年7月14日周四 17:39写道:
Hi All,
To support native debugging in S-mode and VS-mode, we need a SBI Debug Trigger extension which complements the Sdtrig extension.
Below is the draft proposal of the SBI Debug Trigger Extension...
Many thanks to folks (CC'ed here) who provided early feedback and helped improve this proposal.
The proposed SBI extension is highly inspired from Linux HW breakpoint infrastructure which is built on top of the Linux perf subsystem.
Please review and provide your feedback.
Regards, Anup
SBI Debug Trigger Extension (EID #0x44425452 "DBTR") ====================================================
The RISC-V Sdtrig ISA extension allows machine-mode software to directly configure debug triggers which in-turn allows native (or hosted) debugging without any external debugger.
The SBI debug trigger extension defines a SBI based abstraction to provide native debugging for supervisor-mode software such that it: 1) Suitable for the rich operating systems and hypervisors running in supervisor-mode. 2) Allows Guest (VS-mode) and Hypervisor (HS-mode) to share debug triggers on a HART.
Some of the functions defined by this SBI extension have physical memory as parameters for input and/or output. This physical memory parameter MUST satisfy following requirements: 1) The base address of the physical memory MUST be 16-byte aligned so that it is machine word aligned for RV32, RV64 and RV128. 2) The SBI implementation MUST check that the supervisor-mode software is allowed to read and write the specified physical memory on the calling HART. 3) The SBI implementation MUST access the specified physical memory using the PMA attribute. Note: If the supervisor-mode software access the same physical memory using memory type different from PMA then a loss of coherence or unexpected memory ordering may occur and the invoking software should follow the rules and sequences defined in the RISC-V Svpbmt specification to prevent the loss of coherence and memory ordering.
Each debug trigger is assigned a logical number called `trig_idx` by the SBI implementation. If total number of debug triggers are `N` then `0 <= trig_idx < N`. If I understand correctly, the N here should refer to the logical trigger, not the physical number. sbi needs to maintain these logic data, and this is related to runtime, which is difficult for sbi to implement (if many programs are debugged at the same time, it may take up a lot of logic triggers). I think this logical data should be handed over to low-privilege level maintenance.
The `trig_idx` is intentionally a logical index so that Hypervisors can share the debug triggers between guest and host. As an example, you can look at `counter_idx` defined by SBI PMU extension which follows a similar rationale. This does not put any burden on M-mode firmware because M-mode firmware can always treat "logical index" equals "physical index".
The configuration of each debug trigger is expressed by three entities `trig_tdata1`, `trig_tdata2`, and `trig_tdata3` which are same as the `tdata1`, `tdata2`, and `tdata3` CSRs defined by the RISC-V Sdtrig specification but with the following additional constraints: 1) The `trig_tdata1.dmode` bit should always be zero. 2) The `trig_tdata1.m` bit should always be zero. 3) The `trig_tdata1.action` bits should always be zero.
The SBI implementation must also maintain an additional software state for each debug trigger called `trig_state` which is encoded as follows: reserved [XLEN-1:5] - Reserved for future use. vs [4:4] - Saved copy of the `trig_tdata1.vs` bit. vu [3:3] - Saved copy of the `trig_tdata1.vu` bit. s [2:2] - Saved copy of the `trig_tdata1.s` bit. u [1:1] - Saved copy of the `trig_tdata1.u` bit. mapped [0:0] - When set, the trigger has been mapped to some HW debug trigger.
Function: Get number of triggers (FID #0) -----------------------------------------
struct sbiret sbi_debug_num_triggers(unsigned long trig_tdata1)
Get the number of per-HART debug triggers which can support the trigger configuration specified by `trig_tdata1` parameter.
The SBI implementation must return the total number of per-HART debug triggers when `trig_tdata1 == 0`.
Returns the number of per-HART debug triggers in `sbiret.value` and always returns SBI_SUCCESS in `sbiret.error`.
Function: Read triggers (FID #1) --------------------------------
struct sbiret sbi_debug_read_triggers(unsigned long trig_idx_base, unsigned long trig_count, unsigned long out_addr_div_by_16)
Read the trigger state and configuration for a range of debug triggers specified by `trig_idx_base` and `trig_count` parameters on the calling HART.
The state and configuration of triggers will be written to an output memory of size `trig_count * 4 * (XLEN / 8)` bytes. The base physical address of the output memory right shifted by 4 is specified by the `out_addr_div_by_16` parameter.
For i'th debug trigger in the specified range, the trigger configuration consists of four XLEN-bit words written in little-endian format at `offset = i * 4 * (XLEN / 8)` of the output memory. The contents of output trigger configuration words are as follows: word[0] = trig_state word[1] = trig_tdata1 word[2] = trig_tdata2 word[3] = trig_tdata3
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Configuration read successfully. SBI_ERR_INVALID_ADDRESS - The physical memory pointed by the `out_addr_div_by_16` parameter is not accessible to supervisor-mode. SBI_ERR_INVALID_PARAM - Either `trig_idx_base + trig_count` or `trig_idx_base` is greater than the total number of triggers.
Function: Install triggers (FID #2) -----------------------------------
struct sbiret sbi_debug_install_triggers(unsigned long trig_count, unsigned long in_addr_div_by_16, unsigned long out_addr_div_by_16)
Install debug triggers based on an array of trigger configurations specified through an input memory and return the `trig_idx` of each installed debug trigger in an output memory.
The `trig_count` parameter represents the number of debug triggers to be installed.
The base physical address of the input memory right shifted by 4 is specified by the `in_addr_div_by_16` parameter and the size of input memory is `trig_count * 4 * (XLEN / 8)` bytes. The i'th input trigger configuration is at `offset = i * 4 * (XLEN / 8)` of the input memory consisting of four consecutive XLEN-bit words in little-endian format. The contents of each trigger configuration are follows: word[0] = Reserved for future use and should be zero word[1] = trig_tdata1 word[2] = trig_tdata2 word[3] = trig_tdata3 The current debug specification has many variants: type 1, type 2, type 6. There may be more manufacturer-defined specifications. Instead of passing register information directly, we should need more abstraction, which also simplifies the design of low-privilege software
We had started off with a simple abstraction which only covered type2 and type6 but quite a few folks are interested in having SBI extension future proof so that we don't have to keep improving for other debug trigger types. Due to the above, we have a very generic SBI debug trigger extension and we have sbi_debug_num_triggers() which provides some level of discovery to S-mode software. This means if a SBI implementation (M-mode firmware or Hypervisor) wants to only support type2 or type6 triggers then sbi_debug_num_triggers() will return non-zero only for those types of trigger.
The base physical address of the output memory right shifted by 4 is specified by the `out_addr_div_by_16` parameter and the size of output memory is `trig_count * (XLEN / 8)` bytes. The `trig_idx` assigned for the i'th input trigger configuration is written at `offset = i * (XLEN / 8)` of the output memory in little-endian format.
For each input trigger configuration in the input memory, the SBI implementation should: 1) Map a free `trig_idx` with an unused HW debug trigger that matches the trigger configuration. 2) Save a copy of the `trig_tdata1.vs`, `trig_tdata1.vu`, `trig_tdata1.s`, and `trig_tdata.u` bits in `trig_state`. 3) Update the `tdata1`, `tdata2`, and `tdata3` CSRs of the HW debug trigger.
Additionally for each input trigger configuration chain, the SBI implementation MUST assign contiguous `trig_idx` values and contiguous HW debug triggers when installing debug triggers.
The last trigger configuration in the input memory MUST not have `trig_tdata1.chain == 1` for `trig_tdata1.type = 2 or 6` to prevent incomplete trigger configuration chain in input memory.
This function succeeds and output memory is written with `trig_idx` values only if the SBI implementation is able to install a debug trigger for each input trigger configuration.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Triggers installed successfully. The `sbiret.value` will be set to zero. SBI_ERR_INVALID_ADDRESS - The physical memory pointed by the `in_addr_div_by_16` or `out_addr_div_by_16` parameter is not accessible to supervisor-mode. The `sbiret.value` will be set to zero. SBI_ERR_INVALID_PARAM - One of the input trigger configuration has an invalid value. The `sbiret.value` will be set to the array index of failing input trigger configuration. SBI_ERR_NOT_SUPPORTED - One of the input trigger configuration can't be programmed due to unimplemented optional bits in `tdata1`, `tdata2`, or `tdata3` CSRs. The `sbiret.value` will be set to the array index of failing input trigger configuration. SBI_ERR_FAILED - Failed to assign `trig_idx` or HW debug trigger for one of the input trigger configuration. The `sbiret.value` will be set to the array index of failing input trigger configuration.
Function: Uninstall a set of triggers (FID #3) ----------------------------------------------
struct sbiret sbi_debug_uninstall_triggers(unsigned long trig_idx_base, unsigned long trig_idx_mask)
Uninstall a set of debug triggers specified by the `trig_idx_base` and `trig_idx_mask` parameters on the calling HART.
For each debug trigger in the specified set of debug triggers, the SBI implementation should: 1) Clear the `tdata1`, `tdata2`, and `tdata3` CSRs of the mapped HW debug trigger. 2) Clear the `trig_state` of the debug trigger. 3) Unmap the HW debug trigger from `trig_idx` and free both of them for future trigger installations.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Trigger uninstalled successfully. SBI_ERR_INVALID_PARAM - One of the `trig_idx` in the specified set of debug triggers is either: 1) Greater than the total number of triggers. 2) Represents a debug trigger that is not mapped to any HW debug trigger.
Function: Enable a set of triggers (FID #4) -------------------------------------------
struct sbiret sbi_debug_enable_triggers(unsigned long trig_idx_base, unsigned long trig_idx_mask)
Enable a set of debug triggers specified by `trig_idx_base` and `trig_idx_mask` parameters on the calling HART.
To enable a debug trigger, SBI implementation MUST restore the `vs`, `vu`, `s`, and `u` bits of the mapped HW debug trigger from their saved copy in `trig_state`.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Trigger enabled successfully. SBI_ERR_INVALID_PARAM - One of the `trig_idx` in the specified set of debug triggers is either: 1) Greater than the total number of triggers. 2) Represents a debug trigger that is not mapped to any HW debug trigger.
Function: Disable a set of triggers (FID #5) --------------------------------------------
struct sbiret sbi_debug_disable_triggers(unsigned long trig_idx_base, unsigned long trig_idx_mask)
Disable a set of debug triggers specified by `trig_idx_base` and `trig_idx_mask` parameters on the calling HART.
To disable a debug trigger, SBI implementation MUST clear the `vs`, `vu`, `s`, and `u` bits of the mapped HW debug trigger.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Trigger disabled successfully. SBI_ERR_INVALID_PARAM - One of the `trig_idx` in the specified set of debug triggers is either: 1) Greater than the total number of triggers. 2) Represents a debug trigger that is not mapped to any HW debug trigger.
We need to abstract out the breakpoint information. e.g
struct trigger { unsigned long addr; unsigned long length; unsigned long rwx_mask; /* bit 0 -> read; bit 1 -> write; bit 2 -> execute */ unsigned long priv_mask; /* bit 0 -> u; bit 1 -> s; bit 2 -> vu; bit 3 -> vs */
unsigned long resource_id; /* This records which triggers are occupied, which is needed to undo the trigger settings */ unsigned long result; /* This variable will be set by sbi to identify whether the setting is successful or not */
/* Other information that may be required */ };
Different triggers can perform specific settings instead of directly passing tdata1~tdata3
We only need two interfaces, one for install and one for uninstall.
struct sbiret sbi_debug_install_triggers( unsigned long trig_count, unsigned long in_addr_div_by_16);
struct sbiret sbi_debug_uninstall_triggers( unsigned long trig_count, unsigned long in_addr_div_by_16);
in_addr_div_by_16 points to an array of struct triggers.
See above comment. Regards, Anup Regards, Xiang W
|
|
Re: [RISC-V] [tech-debug] SBI Debug Trigger Extension Proposal (Draft v4)
Anup Patel <apatel@...> 于2022年7月14日周四 17:39写道: Hi All,
To support native debugging in S-mode and VS-mode, we need a SBI Debug Trigger extension which complements the Sdtrig extension.
Below is the draft proposal of the SBI Debug Trigger Extension...
Many thanks to folks (CC'ed here) who provided early feedback and helped improve this proposal.
The proposed SBI extension is highly inspired from Linux HW breakpoint infrastructure which is built on top of the Linux perf subsystem.
Please review and provide your feedback.
Regards, Anup
SBI Debug Trigger Extension (EID #0x44425452 "DBTR") ====================================================
The RISC-V Sdtrig ISA extension allows machine-mode software to directly configure debug triggers which in-turn allows native (or hosted) debugging without any external debugger.
The SBI debug trigger extension defines a SBI based abstraction to provide native debugging for supervisor-mode software such that it: 1) Suitable for the rich operating systems and hypervisors running in supervisor-mode. 2) Allows Guest (VS-mode) and Hypervisor (HS-mode) to share debug triggers on a HART.
Some of the functions defined by this SBI extension have physical memory as parameters for input and/or output. This physical memory parameter MUST satisfy following requirements: 1) The base address of the physical memory MUST be 16-byte aligned so that it is machine word aligned for RV32, RV64 and RV128. 2) The SBI implementation MUST check that the supervisor-mode software is allowed to read and write the specified physical memory on the calling HART. 3) The SBI implementation MUST access the specified physical memory using the PMA attribute. Note: If the supervisor-mode software access the same physical memory using memory type different from PMA then a loss of coherence or unexpected memory ordering may occur and the invoking software should follow the rules and sequences defined in the RISC-V Svpbmt specification to prevent the loss of coherence and memory ordering.
Each debug trigger is assigned a logical number called `trig_idx` by the SBI implementation. If total number of debug triggers are `N` then `0 <= trig_idx < N`.
If I understand correctly, the N here should refer to the logical trigger, not the physical number. sbi needs to maintain these logic data, and this is related to runtime, which is difficult for sbi to implement (if many programs are debugged at the same time, it may take up a lot of logic triggers). I think this logical data should be handed over to low-privilege level maintenance. The configuration of each debug trigger is expressed by three entities `trig_tdata1`, `trig_tdata2`, and `trig_tdata3` which are same as the `tdata1`, `tdata2`, and `tdata3` CSRs defined by the RISC-V Sdtrig specification but with the following additional constraints: 1) The `trig_tdata1.dmode` bit should always be zero. 2) The `trig_tdata1.m` bit should always be zero. 3) The `trig_tdata1.action` bits should always be zero.
The SBI implementation must also maintain an additional software state for each debug trigger called `trig_state` which is encoded as follows: reserved [XLEN-1:5] - Reserved for future use. vs [4:4] - Saved copy of the `trig_tdata1.vs` bit. vu [3:3] - Saved copy of the `trig_tdata1.vu` bit. s [2:2] - Saved copy of the `trig_tdata1.s` bit. u [1:1] - Saved copy of the `trig_tdata1.u` bit. mapped [0:0] - When set, the trigger has been mapped to some HW debug trigger.
Function: Get number of triggers (FID #0) -----------------------------------------
struct sbiret sbi_debug_num_triggers(unsigned long trig_tdata1)
Get the number of per-HART debug triggers which can support the trigger configuration specified by `trig_tdata1` parameter.
The SBI implementation must return the total number of per-HART debug triggers when `trig_tdata1 == 0`.
Returns the number of per-HART debug triggers in `sbiret.value` and always returns SBI_SUCCESS in `sbiret.error`.
Function: Read triggers (FID #1) --------------------------------
struct sbiret sbi_debug_read_triggers(unsigned long trig_idx_base, unsigned long trig_count, unsigned long out_addr_div_by_16)
Read the trigger state and configuration for a range of debug triggers specified by `trig_idx_base` and `trig_count` parameters on the calling HART.
The state and configuration of triggers will be written to an output memory of size `trig_count * 4 * (XLEN / 8)` bytes. The base physical address of the output memory right shifted by 4 is specified by the `out_addr_div_by_16` parameter.
For i'th debug trigger in the specified range, the trigger configuration consists of four XLEN-bit words written in little-endian format at `offset = i * 4 * (XLEN / 8)` of the output memory. The contents of output trigger configuration words are as follows: word[0] = trig_state word[1] = trig_tdata1 word[2] = trig_tdata2 word[3] = trig_tdata3
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Configuration read successfully. SBI_ERR_INVALID_ADDRESS - The physical memory pointed by the `out_addr_div_by_16` parameter is not accessible to supervisor-mode. SBI_ERR_INVALID_PARAM - Either `trig_idx_base + trig_count` or `trig_idx_base` is greater than the total number of triggers.
Function: Install triggers (FID #2) -----------------------------------
struct sbiret sbi_debug_install_triggers(unsigned long trig_count, unsigned long in_addr_div_by_16, unsigned long out_addr_div_by_16)
Install debug triggers based on an array of trigger configurations specified through an input memory and return the `trig_idx` of each installed debug trigger in an output memory.
The `trig_count` parameter represents the number of debug triggers to be installed.
The base physical address of the input memory right shifted by 4 is specified by the `in_addr_div_by_16` parameter and the size of input memory is `trig_count * 4 * (XLEN / 8)` bytes. The i'th input trigger configuration is at `offset = i * 4 * (XLEN / 8)` of the input memory consisting of four consecutive XLEN-bit words in little-endian format. The contents of each trigger configuration are follows: word[0] = Reserved for future use and should be zero word[1] = trig_tdata1 word[2] = trig_tdata2 word[3] = trig_tdata3
The current debug specification has many variants: type 1, type 2, type 6. There may be more manufacturer-defined specifications. Instead of passing register information directly, we should need more abstraction, which also simplifies the design of low-privilege software The base physical address of the output memory right shifted by 4 is specified by the `out_addr_div_by_16` parameter and the size of output memory is `trig_count * (XLEN / 8)` bytes. The `trig_idx` assigned for the i'th input trigger configuration is written at `offset = i * (XLEN / 8)` of the output memory in little-endian format.
For each input trigger configuration in the input memory, the SBI implementation should: 1) Map a free `trig_idx` with an unused HW debug trigger that matches the trigger configuration. 2) Save a copy of the `trig_tdata1.vs`, `trig_tdata1.vu`, `trig_tdata1.s`, and `trig_tdata.u` bits in `trig_state`. 3) Update the `tdata1`, `tdata2`, and `tdata3` CSRs of the HW debug trigger.
Additionally for each input trigger configuration chain, the SBI implementation MUST assign contiguous `trig_idx` values and contiguous HW debug triggers when installing debug triggers.
The last trigger configuration in the input memory MUST not have `trig_tdata1.chain == 1` for `trig_tdata1.type = 2 or 6` to prevent incomplete trigger configuration chain in input memory.
This function succeeds and output memory is written with `trig_idx` values only if the SBI implementation is able to install a debug trigger for each input trigger configuration.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Triggers installed successfully. The `sbiret.value` will be set to zero. SBI_ERR_INVALID_ADDRESS - The physical memory pointed by the `in_addr_div_by_16` or `out_addr_div_by_16` parameter is not accessible to supervisor-mode. The `sbiret.value` will be set to zero. SBI_ERR_INVALID_PARAM - One of the input trigger configuration has an invalid value. The `sbiret.value` will be set to the array index of failing input trigger configuration. SBI_ERR_NOT_SUPPORTED - One of the input trigger configuration can't be programmed due to unimplemented optional bits in `tdata1`, `tdata2`, or `tdata3` CSRs. The `sbiret.value` will be set to the array index of failing input trigger configuration. SBI_ERR_FAILED - Failed to assign `trig_idx` or HW debug trigger for one of the input trigger configuration. The `sbiret.value` will be set to the array index of failing input trigger configuration.
Function: Uninstall a set of triggers (FID #3) ----------------------------------------------
struct sbiret sbi_debug_uninstall_triggers(unsigned long trig_idx_base, unsigned long trig_idx_mask)
Uninstall a set of debug triggers specified by the `trig_idx_base` and `trig_idx_mask` parameters on the calling HART.
For each debug trigger in the specified set of debug triggers, the SBI implementation should: 1) Clear the `tdata1`, `tdata2`, and `tdata3` CSRs of the mapped HW debug trigger. 2) Clear the `trig_state` of the debug trigger. 3) Unmap the HW debug trigger from `trig_idx` and free both of them for future trigger installations.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Trigger uninstalled successfully. SBI_ERR_INVALID_PARAM - One of the `trig_idx` in the specified set of debug triggers is either: 1) Greater than the total number of triggers. 2) Represents a debug trigger that is not mapped to any HW debug trigger.
Function: Enable a set of triggers (FID #4) -------------------------------------------
struct sbiret sbi_debug_enable_triggers(unsigned long trig_idx_base, unsigned long trig_idx_mask)
Enable a set of debug triggers specified by `trig_idx_base` and `trig_idx_mask` parameters on the calling HART.
To enable a debug trigger, SBI implementation MUST restore the `vs`, `vu`, `s`, and `u` bits of the mapped HW debug trigger from their saved copy in `trig_state`.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Trigger enabled successfully. SBI_ERR_INVALID_PARAM - One of the `trig_idx` in the specified set of debug triggers is either: 1) Greater than the total number of triggers. 2) Represents a debug trigger that is not mapped to any HW debug trigger.
Function: Disable a set of triggers (FID #5) --------------------------------------------
struct sbiret sbi_debug_disable_triggers(unsigned long trig_idx_base, unsigned long trig_idx_mask)
Disable a set of debug triggers specified by `trig_idx_base` and `trig_idx_mask` parameters on the calling HART.
To disable a debug trigger, SBI implementation MUST clear the `vs`, `vu`, `s`, and `u` bits of the mapped HW debug trigger.
The possible error codes returned in `sbiret.error` are below.
Errors: SBI_SUCCESS - Trigger disabled successfully. SBI_ERR_INVALID_PARAM - One of the `trig_idx` in the specified set of debug triggers is either: 1) Greater than the total number of triggers. 2) Represents a debug trigger that is not mapped to any HW debug trigger.
We need to abstract out the breakpoint information. e.g struct trigger { unsigned long addr; unsigned long length; unsigned long rwx_mask; /* bit 0 -> read; bit 1 -> write; bit 2 -> execute */ unsigned long priv_mask; /* bit 0 -> u; bit 1 -> s; bit 2 -> vu; bit 3 -> vs */ unsigned long resource_id; /* This records which triggers are occupied, which is needed to undo the trigger settings */ unsigned long result; /* This variable will be set by sbi to identify whether the setting is successful or not */ /* Other information that may be required */ }; Different triggers can perform specific settings instead of directly passing tdata1~tdata3 We only need two interfaces, one for install and one for uninstall. struct sbiret sbi_debug_install_triggers( unsigned long trig_count, unsigned long in_addr_div_by_16); struct sbiret sbi_debug_uninstall_triggers( unsigned long trig_count, unsigned long in_addr_div_by_16); in_addr_div_by_16 points to an array of struct triggers. Regards, Xiang W
|
|
Re: [RISC-V] [tech-debug] gdb needs an sbi extension
toggle quoted message
Show quoted text
To implement hardware breakpoints and watchpoints on the riscv, the trigger in M
mode is required. We need an sbi extension for debugging to set the trigger.
Please give suggestions and feedback.
Regards,
Xiang W
Debug Extension (EID #0x44424755 "DBG")
=======================================
Function: Set Tiggers(FID #0)
-----------------------------
```c
struct trigger {
unsigned long address;
unsigned long length;
unsigned long rwx_mask;
unsigned long privilege_mask;
unsigned long resource_id;
};
```
rwx_mask:
bit 0: read
bit 1: write
bit 2: execute
privilege_mask:
bit 0: U-Mode
bit 1: S-Mode
bit 2: H-Mode
bit 3: M-Mode
resource_id: This is a resource identifier, non-0, 0 is used to indicate that
the resource is free. This flag is used to associate which trigger is used, and
is useful when clearing settings.
```c
struct sbiret sbi_debug_set_triggers(unsigned long addr_lo, unsigned long addr_hi, unsigned long num);
```
addr_lo and addr_hi are used to access address ranges whose physical address
width is greater than XLEN. The addr_lo and addr_hi point to the struct trigger
array.
num represents the number of elements in the array.
Trigger is a scarce resource and should be used as the context of the program,
set when resuming execution, and cleared when swapped out. In order to reduce
the number of sbi calls, the breakpoint information is passed through an array
here.
Function: Clear Tiggers(FID #1)
--------------------------------
```c
struct sbiret sbi_debug_clear_triggers(unsigned long addr_lo, unsigned long addr_hi, unsigned long num);
```
addr_lo and addr_hi are used to access address ranges whose physical address
width is greater than XLEN. The addr_lo and addr_hi point to the struct trigger
array.
num represents the number of elements in the array.
This call will undo all trigger settings.
|
|
gdb needs an sbi extension
To implement hardware breakpoints and watchpoints on the riscv, the trigger in M mode is required. We need an sbi extension for debugging to set the trigger.
Please give suggestions and feedback.
Regards, Xiang W
Debug Extension (EID #0x44424755 "DBG") =======================================
Function: Set Tiggers(FID #0) -----------------------------
```c struct trigger { unsigned long address; unsigned long length; unsigned long rwx_mask; unsigned long privilege_mask; unsigned long resource_id; }; ```
rwx_mask: bit 0: read bit 1: write bit 2: execute
privilege_mask: bit 0: U-Mode bit 1: S-Mode bit 2: H-Mode bit 3: M-Mode
resource_id: This is a resource identifier, non-0, 0 is used to indicate that the resource is free. This flag is used to associate which trigger is used, and is useful when clearing settings.
```c struct sbiret sbi_debug_set_triggers(unsigned long addr_lo, unsigned long addr_hi, unsigned long num); ```
addr_lo and addr_hi are used to access address ranges whose physical address width is greater than XLEN. The addr_lo and addr_hi point to the struct trigger array.
num represents the number of elements in the array.
Trigger is a scarce resource and should be used as the context of the program, set when resuming execution, and cleared when swapped out. In order to reduce the number of sbi calls, the breakpoint information is passed through an array here.
Function: Clear Tiggers(FID #1) -------------------------------- ```c struct sbiret sbi_debug_clear_triggers(unsigned long addr_lo, unsigned long addr_hi, unsigned long num); ```
addr_lo and addr_hi are used to access address ranges whose physical address width is greater than XLEN. The addr_lo and addr_hi point to the struct trigger array.
num represents the number of elements in the array.
This call will undo all trigger settings.
|
|
Re: Meeting Sept 27 9am PT
I declared failure on my part. I'll schedule something early next week (unless people think we can squeeze something in tomorrow or Thurs - appears to be a lot conflicts, though). My apologies for not sending out a reminder. I'll get something scheduled and sent out.
toggle quoted message
Show quoted text
On Tue, Sep 27, 2022 at 10:05 AM Aaron Durbin < adurbin@...> wrote: Hi All,
Ved let me know I accidentally had a Google Meet Invite link. The Zoom meeting id is:
Thanks.
-Aaron
|
|
Hi All,
Ved let me know I accidentally had a Google Meet Invite link. The Zoom meeting id is:
Thanks.
-Aaron
|
|
OS-A SEE TG Meeting 2022/09/12
Hi All,
We had our first meeting this past Monday (2022/09/12).
I pushed the notes to GitHub. As a reminder each group in RVI has their own folder for stashing collateral. For OS-A SEE TG, the folder is here. Under that there is a Meetings folder that has a doc that has a link to the GitHub notes in addition to the meeting presentations. The other, and most important doc, is the Future Topics doc where people can put their concerns/comments/requests to cover in the next meeting(s).
We'll have our next meeting on Monday 2022/09/26 at 9am PT. It's already been put on the tech.meetings@... calendar. We hope to have an initial framework in the spec repository as well as some initial content that we can discuss. 2022/09/12- Meeting Presentation
- Went over the Charter
- Discussed what is in scope for OS-A SEE
- Paul W. asked about hardware requirements. In alignment with the Charter, we should be focusing on compatibility across RISC-V systems for loading and running operating systems. Hardware requirements should fall under the Platform specifications.
- Additionally Kumar indicated SW view of the world should be the focus.
- Paul brought up a distinction of feature / device binding required in both early and later stages of kernel startup.
- Target Audience of OS-A SEE? Ideally would be standar operating system distributions to further expand the ecosystem. Users of the RISC-V systems would benefit, but it's important to allow operating system distributions to target a conformant spec.
- psABI would not fall into the purview of the OS-A SEE spec. Reason: Kumar syas focus should be on ability to run same OS on multiple implementations.
- ACPI vs DT. Acknowledge we need to support both. May want to allow an OS to choose which one to support (or both) instead of mandating both. Allows for OS vendors to define their own product. Topic to still be discussed.
- Need to start framework of document and start seeding content.
Thank you.
-Aaron
|
|
Re: Access problem of mtimercmp in a platform with multiple MTIMER devices

Anup Patel
On Wed, Sep 7, 2022 at 8:44 AM Tianyi Xia via lists.riscv.org <tianshi.xty=alibaba-inc.com@...> wrote: each "cluster" can have its own unique mmio address for mtimecmp (which may or may not be accessible to other "clusters")
I think this description is better.
Assume there are two clusters,each cluster have two cores,and each cluster have there own MTIMER device. The mmio address of mtimecmp for each hart may like this:
Cluster0
Core0: base0+0x0000_0000
Core1: base0+0x0000_0008
Cluster1
Core0: base1+0x0000_0000
Core1: base1+0x0000_0008
Base0 is the MTIER device base address of cluster0, Base1 is the MTIER device base address of cluster0. the mtimecmp of cluster0 core0 may or maynot be accessible to cluster1, depending on the implementation. If core try to access mtimecmp of other cluster, the action of the access may be write ignore read zero.
The latter sounds like it would be difficult for SW
I think in a platform with multiple MTIMER devices, the mmio address of mtimecmp should be unique to distinguish different MTIMER devices. The hardware can set regular base address to different Mtimer devices. In the above example, assuming base is 0, then base1 may be set to 0x0000_0010. If cluster0 has four cores, then base1 may be set to 0x0000_0020.Then from a software perspective, all mtimecmp registers are addressed consecutively.
This case is already handled by ACLINT device tree bindings. We just need two separate MTIMER DT nodes where the mtimecmp base address will be different in each DT node. Please refer to the latest OpenSBI sources. Regards, Anup
|
|
Re: Access problem of mtimercmp in a platform with multiple MTIMER devices

Allen Baum
That makes sense, but it does mean that discovery gets more complicated, and (maybe) you need to build separate device trees for each. But maybe that has to happen anyway? I don't know if DT can be parameterized based on HartID, but that would greatly simplify the work.
toggle quoted message
Show quoted text
each "cluster" can have its own unique mmio address for mtimecmp (which may or may not be accessible to other "clusters")
I think this description is better.
Assume there are two clusters,each cluster have two cores,and each cluster have there own MTIMER device. The mmio address of mtimecmp for each hart may like this:
Cluster0
Core0: base0+0x0000_0000
Core1: base0+0x0000_0008
Cluster1
Core0: base1+0x0000_0000
Core1: base1+0x0000_0008
Base0 is the MTIER device base address of cluster0, Base1 is the MTIER device base address of cluster0. the mtimecmp of cluster0 core0 may or maynot be accessible to cluster1, depending on the implementation. If core try to access mtimecmp of other cluster, the action of the access may be write ignore read zero.
The latter sounds like it would be difficult for SW
I think in a platform with multiple MTIMER devices, the mmio address of mtimecmp should be unique to distinguish different MTIMER devices. The hardware can set regular base address to different Mtimer devices. In the above example, assuming base is 0, then base1 may be set to 0x0000_0010. If cluster0 has four cores, then base1 may be set to 0x0000_0020.Then from a software perspective, all mtimecmp registers are addressed consecutively.
|
|
Re: Access problem of mtimercmp in a platform with multiple MTIMER devices
Tianyi Xia <tianshi.xty@...>
each "cluster" can have its own unique mmio address for mtimecmp (which may or may not be accessible to other "clusters")
I think this description is better.
Assume there are two clusters,each cluster have two cores,and each cluster have there own MTIMER device. The mmio address of mtimecmp for each hart may like this:
Cluster0
Core0: base0+0x0000_0000
Core1: base0+0x0000_0008
Cluster1
Core0: base1+0x0000_0000
Core1: base1+0x0000_0008
Base0 is the MTIER device base address of cluster0, Base1 is the MTIER device base address of cluster0. the mtimecmp of cluster0 core0 may or maynot be accessible to cluster1, depending on the implementation. If core try to access mtimecmp of other cluster, the action of the access may be write ignore read zero.
The latter sounds like it would be difficult for SW
I think in a platform with multiple MTIMER devices, the mmio address of mtimecmp should be unique to distinguish different MTIMER devices. The hardware can set regular base address to different Mtimer devices. In the above example, assuming base is 0, then base1 may be set to 0x0000_0010. If cluster0 has four cores, then base1 may be set to 0x0000_0020.Then from a software perspective, all mtimecmp registers are addressed consecutively.
|
|
First Platform Runtime Services (PRS) TG meeting 09/07 8AM PDT
Hi All, Apologies for cross posting multiple lists. Just wanted to reach out to the maximum audience as this is a short notice to set up the first meeting.
This is just a quick notice that the first PRS TG meeting has been scheduled. It will take place on Wednesday, Sep 7th, at 8am Pacific. You should see the meeting on the RISC-V Tech Meetings calendar shortly.
Agenda: - Introductions (10 min)
- Discuss regular meeting time and cadence (10 min)
- Review charter (20 min)
- Order of SBI/ACPI proposal discussions (10 min)
Looking forward to meeting everyone!
Regards, Atish
|
|
Re: [RISC-V] Platform Runtime Services preliminary charter & meetings
Hi All, The doodle poll indicates that the 8AM PDT Wednesday is the most preferred slot. This will probably conflict with hypervisor SIG meetings once in a while. We will reschedule that meeting whenever required. I will schedule the first PRS meeting for tomorrow at 8AM PDT. This is probably a short notice but I want to get the ball rolling as soon as possible and avoid more conflicts.
I will send the agenda and meeting links in a separate email. We are very excited to get started!
toggle quoted message
Show quoted text
On Thu, Sep 1, 2022 at 11:45 AM Atish Kumar Patra < atishp@...> wrote: Hi All,
We are pleased to announce the early formation of Platform Runtime Services(PRS) Task Group with Atish Patra from Rivos as the acting chair and Sunil VL from ventana as the acting vice chair. The PRS TG will drive various runtime services specifications i.e. SBI, UEFI & ACPI in RISC-V.
The TG details, including the charter can be found at
Charter: https://github.com/riscv-admin/prs/blob/main/CHARTER.md The community page: https://lists.riscv.org/g/tech-prs Mailing list address : tech-prs@... Github Repo : https://github.com/riscv-admin/prs
We encourage you to participate in the PRS TG. Please “Join This Group” by clicking the blue button on the bottom of the community page: Please review the charter if you are interested and let us know your feedback.
We are planning to have biweekly meetings to discuss various ACPI ECRs and SBI improvement proposals first. Here is a doodle poll for the least conflicting time slots for the zoom meeting.
https://doodle.com/meeting/organize/id/b2vWxn1b Please select your preferred slots by Tuesday(6th Sep). We will schedule the meeting as per the majority preference.
Here are some of the SBI & ACPI proposals that need to be discussed (not necessarily in this order).
SBI:
- Debug Console SBI extension
- Steal time accounting
- AP-TEE SBI extension
- Attestation SBI extension
- SBI PMU improvements (including snapshot)
- SBI debug extension
ACPI: - MADT - RINTC
- MADT - AIA RINTC
- MADT - AIA IMSIC/APLIC
- RHCT
UEFI: We don't have any proposals in flight right now.
Regards, Atish, Sunil
|
|
Re: Access problem of mtimercmp in a platform with multiple MTIMER devices

Allen Baum
The implication of that is that either - there is an mmio address that can access different instantiations of mtime/mtimecmp for each requesting hart (depending on the "cluster") - each "cluster" can have its own unique mmio address for mtimecmp (which may or may not be accessible to other "clusters")
Is one or either of those a preferred option? The latter sounds like it would be difficult for SW
toggle quoted message
Show quoted text
In the SiFive Core-Local Interruptor (CLINT) device , a core can access the mtimcmp register of all cores in the platform.
In the ACLINT spec, If a platform implements multiple MTIMER devices, such as multiple clusters, each cluster implements one MTIMER device, then a core may not be able to access the MTIMER devices of other clusters.
As I understand, it is not necessary for a core to access the mtimecmp of other cores. Is it possible to add a recommended software usage method to the ACLINT spec, for example, it is recommended that the software only use a core to access its own mtimcmp register, but not access mtimcmp of other cores. This can avoid the problem that the software uses a core to access the MTIMER devices of other clusters, but the hardware cannot support it.
|
|
Access problem of mtimercmp in a platform with multiple MTIMER devices
Tianyi Xia <tianshi.xty@...>
In the SiFive Core-Local Interruptor (CLINT) device , a core can access the mtimcmp register of all cores in the platform.
In the ACLINT spec, If a platform implements multiple MTIMER devices, such as multiple clusters, each cluster implements one MTIMER device, then a core may not be able to access the MTIMER devices of other clusters.
As I understand, it is not necessary for a core to access the mtimecmp of other cores. Is it possible to add a recommended software usage method to the ACLINT spec, for example, it is recommended that the software only use a core to access its own mtimcmp register, but not access mtimcmp of other cores. This can avoid the problem that the software uses a core to access the MTIMER devices of other clusters, but the hardware cannot support it.
|
|
Call for Chair/Vice-Chair Candidates for Platform Runtime Services(PRS) TG
cross-posting for more visibility. ---------- Forwarded message --------- From: Atish Kumar Patra <atishp@...>Date: Thu, Sep 1, 2022 at 11:55 AM Subject: Call for Chair/Vice-Chair Candidates for Platform Runtime Services(PRS) TG To: < tech-announce@...> This is a call for chair and vice-chair candidates for the recently created Platform Runtime Services(PRS) TG. All candidates must submit a biography (bio) and statements of intent by Sep 15th 2022. The policy describing this process is here.
The current draft charter of the PRS TG can be found here. Nomination process, requirements, and duties:
If you would like to be included or know someone who should be, please send an email to help@... with the candidate's name, member affiliation, qualifications, a small bio and a statement of intent (both less than 250 words each).
Qualifications include: - Experience with ACPI/UEFI specifications development - Familiarity with RISC-V SBI specification - Experience with systems software (OS, hypervisors, drivers, firmware) - Familiarity with RISC-V ISA specifications
Duties as chair/vice-chair (see Best Practices document) include: - Collaboration with existing task groups within the RISC-V Foundation - Seek contributions/collaborations while keeping focus on TG charter - Publish meeting minutes - Serve as an editor for some of the proposals - Community interactions through meetings, mail list, GitHub, Wiki - Respond to queries within 48 hours - Manage and run regular meetings as per the group charter - Attend weekly tech-chairs meetings Thanks,
Atish, Sunil
|
|
[RISC-V] Platform Runtime Services preliminary charter & meetings
Hi All,
We are pleased to announce the early formation of Platform Runtime Services(PRS) Task Group with Atish Patra from Rivos as the acting chair and Sunil VL from ventana as the acting vice chair. The PRS TG will drive various runtime services specifications i.e. SBI, UEFI & ACPI in RISC-V.
The TG details, including the charter can be found at
Charter: https://github.com/riscv-admin/prs/blob/main/CHARTER.md The community page: https://lists.riscv.org/g/tech-prs Mailing list address : tech-prs@... Github Repo : https://github.com/riscv-admin/prs
We encourage you to participate in the PRS TG. Please “Join This Group” by clicking the blue button on the bottom of the community page: Please review the charter if you are interested and let us know your feedback.
We are planning to have biweekly meetings to discuss various ACPI ECRs and SBI improvement proposals first. Here is a doodle poll for the least conflicting time slots for the zoom meeting.
https://doodle.com/meeting/organize/id/b2vWxn1b Please select your preferred slots by Tuesday(6th Sep). We will schedule the meeting as per the majority preference.
Here are some of the SBI & ACPI proposals that need to be discussed (not necessarily in this order).
SBI:
- Debug Console SBI extension
- Steal time accounting
- AP-TEE SBI extension
- Attestation SBI extension
- SBI PMU improvements (including snapshot)
- SBI debug extension
ACPI: - MADT - RINTC
- MADT - AIA RINTC
- MADT - AIA IMSIC/APLIC
- RHCT
UEFI: We don't have any proposals in flight right now.
Regards, Atish, Sunil
|
|
Re: OS-A SEE TG Meeting Thurs Sept 1 @ 9am PT
Hi All,
I received some feedback that they had some conflicts with the proposed time. I adjusted the calendar invite to be for Mon Sept 12th at 8am PT. I will still send out slides prior to that so we can collaborate prior and set us up for an efficient meeting.
Regards,
-Aaron
toggle quoted message
Show quoted text
On Fri, Aug 26, 2022 at 2:41 PM Aaron Durbin < adurbin@...> wrote: Hi All,
I put a meeting on the RISC-V calendar for Thursday September 1 @ 9am PT. I'll send the slides out earlier in the week for people to critique and add suggestions of topics. We'll go over the charter and discuss various requirements we think should go into the OS-A SEE specification (and its dependencies).
I hope people can make it. I know it's less than a week's notice, but I believe with some persistence we can complete most of the spec by the end of the year.
-Aaron
|
|
OS-A SEE TG Meeting Thurs Sept 1 @ 9am PT
Hi All,
I put a meeting on the RISC-V calendar for Thursday September 1 @ 9am PT. I'll send the slides out earlier in the week for people to critique and add suggestions of topics. We'll go over the charter and discuss various requirements we think should go into the OS-A SEE specification (and its dependencies).
I hope people can make it. I know it's less than a week's notice, but I believe with some persistence we can complete most of the spec by the end of the year.
-Aaron
|
|
Re: [RISC-V] [tech-aia] [RISC-V] [tech-unixplatformspec] Review request for ACPI ECRs
On Thu, Aug 4, 2022 at 10:16 AM Sunil V L < sunilvl@...> wrote: Hi Aaron,
On Thu, Aug 04, 2022 at 09:16:21AM -0600, Aaron Durbin wrote:
> On Wed, Aug 3, 2022 at 8:17 AM Sunil V L <sunilvl@...> wrote:
>
> > Hi All,
> >
> > We plan to send below two ECRs to UEFI forum on 08/08/2022. These two
> > ECRs don't have any dependency on any unfrozen specs.
> > Getting these two ECRs accepted by UEFI forum would help us to enable big
> > chunk of ACPI infrastructure patches for RISC-V.
> >
> > a) RHCT
> >
> > https://docs.google.com/document/d/1LlCefO_0GQ_7Tf3lzfMPETEfMlGo2FfLRJ09IMqJKEk/edit?usp=sharing
>
>
> I don't think we should submit this one until we settle on how we convey
> behaviors outside of an ISA string. I suspect that will change so we should
> anticipate that. Right now we have ISA string plus CMO parameters as
> specific RHCT Nodes. Are we concerned about timing on adoption to push this
> in its current form? I ask because I'd rather not have this set in stone
> only for us to quickly come back and say "stop using these fields. we have
> a new node/mechanism to convey this information". What do you think?
I was under the impression that it is decided not to use the
extension names mentioned in profile spec. Sorry I didn't know you are
still working with TSC to conclude on this.
In that case, let's remove the CMO structure from the RHCT and submit
the ECR. CMO structure is not really mandatory for OS.
>
> I brought up this topic in the TSC meeting this week as I indicated I
> would. I need to work with some others to formalize the direction, but
> that's going to take a little more time.
Right. My preference is, to keep sending multiple revisions of the ECRs
with incremental changes, while making sure we don't obsolete things
fairly quickly as you mentioned. I think removing CMO strucutre helps us
to take care of both requirements. When you get clarity from TSC, we can
add in next revision. What do you think?
Sounds good. As long as we don't annoy anyone with a stream ECR updates to the same table I think that's a fine approach.
Thanks
Sunil
>
>
> >
> > b)MADT RINTC
> >
> > https://docs.google.com/document/d/1waaAqDyTWvYcCSd1Df-vj0EKCA1nukKF_puclaVYkSo/edit?usp=sharing
>
>
> Aside from maybe wordsmithing a little more for clarity purposes (based on
> commentary) I think this one seems fine from my standpoint.
>
>
> >
> > Please feel free to provide comments in the document before 08/08.
> > The documents and feedback will be archived in the same folder.
> >
> > Thanks
> > Sunil
> >
> > On Tue, Jul 05, 2022 at 10:46:18PM +0530, Sunil V L via lists.riscv.org
> > wrote:
> > > Hi All,
> > >
> > > Thanks a lot for great feedback over last week on the ECRs. I have
> > > created version 2 of the ECRs addressing most of the comments. We will be
> > > discussing this version of the ECRs in this week's meeting. Please
> > > provide your comments in this version of the documents.
> > >
> > > 1) Non-AIA ECRs
> > > a) RHCT - version 2:
> > >
> > https://docs.google.com/document/d/1LlCefO_0GQ_7Tf3lzfMPETEfMlGo2FfLRJ09IMqJKEk/edit?usp=sharing
> > > b)MADT RINTC - version 2:
> > >
> > https://docs.google.com/document/d/1waaAqDyTWvYcCSd1Df-vj0EKCA1nukKF_puclaVYkSo/edit?usp=sharing
> > > 2) AIA ECRs
> > > a) MADT - AIA RINTC (version 2) :
> > >
> > https://docs.google.com/document/d/1LBKD1gyi6kOfE3V2WiFOPz1h4MlmxHDj7vkjjfSygBo/edit?usp=sharing
> > > b) MADT - AIA IMSIC/APLIC version 2:
> > >
> > https://docs.google.com/document/d/1zDainvcxD14eawsyc3y1s78zP7ruefyGzcsP1bBak3w/edit?usp=sharing
> > >
> > > PoC Code has been updated at same location as earlier.
> > >
> > > Thanks
> > > Sunil
> > >
> > > On Tue, Jun 21, 2022 at 11:18:02PM +0530, Sunil V L via lists.riscv.org
> > wrote:
> > > > Hi All,
> > > >
> > > > Please review below Engineering Change Request (ECR) to update the ACPI
> > > > spec for enabling basic ACPI support for RISC-V.
> > > >
> > > > 1) Add INTC structure in MADT Table -
> >
> >
> > > >
> > https://docs.google.com/document/d/13YdZzUv0mRHBotdy4Qjqrzb-83mjM31AyEXXfgodcNw/edit?usp=sharing
> > > >
> > > > 2) Add new RISC-V Hart Capabilities Table (RHCT).
> > > >
> > https://docs.google.com/document/d/1-hQMzSNTEfNqudIENhGxrrb0Yr5MEo4NcZwXZlvdx6k/edit?usp=sharing
> > > >
> > > > 3) Add AIA interrupt controllers in MADT table
> > > >
> > https://docs.google.com/document/d/1rbdXsON4OMJ0QB3UvkfkIa8hdySbWArIKqPRUli7AU0/edit?usp=sharing
> > > >
> > > > First two ECRs do not have a dependency on any RVI specs which are not
> > > > frozen. But the third ECR has a dependency on AIA spec to be frozen.
> > > > Hence this AIA ECR will NOT be sent to UEFI forum until AIA spec is
> > frozen.
> > > >
> > > > The PoC for these ECRs is complete and ACPI enabled Linux boots on qemu
> > > > platform. Below are links to the source code for the PoC.
> > > > qemu - https://github.com/ventanamicro/qemu/tree/dev-upstream
> > > > edk2 - https://github.com/ventanamicro/edk2/tree/dev-upstream
> > > > edk2-platforms -
> > https://github.com/ventanamicro/edk2-platforms/tree/dev-upstream
> > > > linux - https://github.com/ventanamicro/linux/tree/dev-upstream
> > > >
> > > > You can find how to build and test these changes in this link -
> > > >
> > https://github.com/riscv-non-isa/riscv-acpi/wiki/PoC-:-How-to-build-and-test-ACPI-enabled-kernel
> > > >
> >
> >
> > > > You can provide the feedback by commenting in the document itself. I am
> > > > hoping to send at least first two ECRs to UEFI forum by 8th August
> > 2022.
> > > > So, appreciate your help to improve these ECRs before 4th August 2022
> > > > (45 days from today).
> > > >
> >
> >
> > > > Feel free to reach out if you have any questions.
> > > >
> >
> >
> > > > Thanks!
> > > > Sunil
> > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > >
> > >
> > >
> > >
> >
> >
> >
> >
> >
> >
>
>
>
>
>
|
|