opensbi icon indicating copy to clipboard operation
opensbi copied to clipboard

Writing drivers for Timer peripheral

Open Rajnesh28 opened this issue 1 year ago • 1 comments

Hello,

I have added a TIMER to my CPU that is being simulated through LiteX. The details of the TIMER can be found here. It is a CSR memory-mapped timer.

How do I begin writing a driver to let OpenSBI control this TIMER from my CPU.

There seems to be support for several other timers in larger modules such as the CLINT, but I can't figure out where to begin writing code to add driver support for this TIMER.

Where would function calls that set the timer disable/enable, read and write the load, timer and timercmp registers go? These are all done through CSR r/w functions.

static inline uint32_t timer0_load_read(void) {
        return csr_read_simple((CSR_BASE + 0x2000L));
}
static inline void timer0_load_write(uint32_t v) {
        csr_write_simple(v, (CSR_BASE + 0x2000L));
}
static inline uint32_t timer0_reload_read(void) {
        return csr_read_simple((CSR_BASE + 0x2004L));
}
static inline void timer0_reload_write(uint32_t v) {
        csr_write_simple(v, (CSR_BASE + 0x2004L));
}
static inline uint32_t timer0_en_read(void) {
        return csr_read_simple((CSR_BASE + 0x2008L));
}
static inline void timer0_en_write(uint32_t v) {
        csr_write_simple(v, (CSR_BASE + 0x2008L));
}
static inline uint32_t timer0_update_value_read(void) {
        return csr_read_simple((CSR_BASE + 0x200cL));
}
static inline void timer0_update_value_write(uint32_t v) {
        csr_write_simple(v, (CSR_BASE + 0x200cL));
}
static inline uint32_t timer0_value_read(void) {
        return csr_read_simple((CSR_BASE + 0x2010L));
}
static inline uint32_t timer0_ev_status_read(void) {
        return csr_read_simple((CSR_BASE + 0x2014L));
}
static inline uint32_t timer0_ev_pending_read(void) {
        return csr_read_simple((CSR_BASE + 0x2018L));
}
static inline void timer0_ev_pending_write(uint32_t v) {
        csr_write_simple(v, (CSR_BASE + 0x2018L));
}
static inline uint32_t timer0_ev_enable_read(void) {
        return csr_read_simple((CSR_BASE + 0x201cL));
}
static inline void timer0_ev_enable_write(uint32_t v) {
        csr_write_simple(v, (CSR_BASE + 0x201cL));
}

From my understanding, I will need to also initialize the TIMER as well in the platform.c file as well.

Rajnesh28 avatar Jul 10 '24 00:07 Rajnesh28

You may need to implement a driver in the lib/utils/timer directory

Regards, Xiang W

wxjstz avatar Dec 18 '24 03:12 wxjstz

This is fine now, implemented CLINT into SoC, and then used those drivers.

Rajnesh28 avatar May 05 '25 06:05 Rajnesh28