First commit XiUOS

This commit is contained in:
xuetest
2021-04-28 17:49:18 +08:00
commit 6001051eb7
1331 changed files with 433955 additions and 0 deletions

View File

@@ -0,0 +1,323 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file clint.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __CLINT_H__
#define __CLINT_H__
#include <stddef.h>
#include <stdint.h>
#include "platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/* clang-format off */
/* Register address offsets */
#define CLINT_MSIP (0x0000)
#define CLINT_MSIP_SIZE (0x4)
#define CLINT_MTIMECMP (0x4000)
#define CLINT_MTIMECMP_SIZE (0x8)
#define CLINT_MTIME (0xBFF8)
#define CLINT_MTIME_SIZE (0x8)
/* Max number of cores */
#define CLINT_MAX_CORES (4095)
/* Real number of cores */
#define CLINT_NUM_CORES (2)
/* Clock frequency division factor */
#define CLINT_CLOCK_DIV (50)
/* clang-format on */
/**
* @brief MSIP Registers
*
* Machine-mode software interrupts are generated by writing to a
* per-core memory-mapped control register. The msip registers are
* 32-bit wide WARL registers, where the LSB is reflected in the
* msip bit of the associated cores mip register. Other bits in
* the msip registers are hardwired to zero. The mapping supports
* up to 4095 machine-mode cores.
*/
typedef struct _clint_msip
{
uint32_t msip : 1; /*!< Bit 0 is msip */
uint32_t zero : 31; /*!< Bits [32:1] is 0 */
} __attribute__((packed, aligned(4))) clint_msip_t;
/**
* @brief Timer compare Registers Machine-mode timer interrupts are
* generated by a real-time counter and a per-core comparator. The
* mtime register is a 64-bit read-only register that contains the
* current value of the real-time counter. Each mtimecmp register
* holds its cores time comparator. A timer interrupt is pending
* whenever mtime is greater than or equal to the value in a
* cores mtimecmp register. The timer interrupt is reflected in
* the mtip bit of the associated cores mip register.
*/
typedef uint64_t clint_mtimecmp_t;
/**
* @brief Timer Registers
*
* The mtime register has a 64-bit precision on all RV32, RV64,
* and RV128 systems. Platforms provide a 64-bit memory-mapped
* machine-mode timer compare register (mtimecmp), which causes a
* timer interrupt to be posted when the mtime register contains a
* value greater than or equal to the value in the mtimecmp
* register. The interrupt remains posted until it is cleared by
* writing the mtimecmp register. The interrupt will only be taken
* if interrupts are enabled and the MTIE bit is set in the mie
* register.
*/
typedef uint64_t clint_mtime_t;
/**
* @brief CLINT object
*
* Coreplex-Local INTerrupts, which includes software interrupts,
* local timer interrupts, and other interrupts routed directly to
* a core.
*/
typedef struct _clint
{
/* 0x0000 to 0x3FF8, MSIP Registers */
clint_msip_t msip[CLINT_MAX_CORES];
/* Resverd space, do not use */
uint32_t resv0;
/* 0x4000 to 0xBFF0, Timer Compare Registers */
clint_mtimecmp_t mtimecmp[CLINT_MAX_CORES];
/* 0xBFF8, Time Register */
clint_mtime_t mtime;
} __attribute__((packed, aligned(4))) clint_t;
/**
* @brief Clint object instanse
*/
extern volatile clint_t* const clint;
/**
* @brief Definitions for the timer callbacks
*/
typedef int (*clint_timer_callback_t)(void *ctx);
/**
* @brief Definitions for local interprocessor interrupt callbacks
*/
typedef int (*clint_ipi_callback_t)(void *ctx);
typedef struct _clint_timer_instance
{
uint64_t interval;
uint64_t cycles;
uint64_t single_shot;
clint_timer_callback_t callback;
void *ctx;
} clint_timer_instance_t;
typedef struct _clint_ipi_instance
{
clint_ipi_callback_t callback;
void *ctx;
} clint_ipi_instance_t;
/**
* @brief Get the time form CLINT timer register
*
* @note The CLINT must init to get right time
*
* @return 64bit Time
*/
uint64_t clint_get_time(void);
/**
* @brief Init the CLINT timer
*
* @note MIP_MTIP will be clear after init. The MSTATUS_MIE must set by
* user.
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_init(void);
/**
* @brief Stop the CLINT timer
*
* @note MIP_MTIP will be clear after stop
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_stop(void);
/**
* @brief Start the CLINT timer
*
* @param[in] interval The interval with Millisecond(ms)
* @param[in] single_shot Single shot or repeat
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_start(uint64_t interval, int single_shot);
/**
* @brief Get the interval of timer
*
* @return The interval with Millisecond(ms)
*/
uint64_t clint_timer_get_interval(void);
/**
* @brief Set the interval with Millisecond(ms)
*
* @param[in] interval The interval with Millisecond(ms)
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_set_interval(uint64_t interval);
/**
* @brief Get whether the timer is a single shot timer
*
* @return result
* - 0 It is a repeat timer
* - 1 It is a single shot timer
*/
int clint_timer_get_single_shot(void);
/**
* @brief Set the timer working as a single shot timer or repeat timer
*
* @param[in] single_shot Single shot or repeat
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_set_single_shot(int single_shot);
/**
* @brief Set user callback function when timer is timeout
*
* @param[in] callback The callback function
* @param[in] ctx The context
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_register(clint_timer_callback_t callback, void *ctx);
/**
* @brief Deregister user callback function
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_timer_unregister(void);
/**
* @brief Initialize local interprocessor interrupt
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_ipi_init(void);
/**
* @brief Enable local interprocessor interrupt
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_ipi_enable(void);
/**
* @brief Disable local interprocessor interrupt
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_ipi_disable(void);
/**
* @brief Send local interprocessor interrupt to core by core id
*
* @param[in] core_id The core identifier
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_ipi_send(size_t core_id);
/**
* @brief Clear local interprocessor interrupt
*
* @param[in] core_id The core identifier
*
* @return result
* - 1 An IPI was pending
* - 0 Non IPI was pending
* - -1 Fail
*/
int clint_ipi_clear(size_t core_id);
/**
* @brief Set user callback function when interprocessor interrupt
*
* @param[in] callback The callback function
* @param[in] ctx The context
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_ipi_register(clint_ipi_callback_t callback, void *ctx);
/**
* @brief Deregister user callback function
*
* @return result
* - 0 Success
* - Other Fail
*/
int clint_ipi_unregister(void);
#ifdef __cplusplus
}
#endif
#endif /* __CLINT_H__ */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_uart.h
* @brief define kd233-board uart function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef CONNECT_UART_H
#define CONNECT_UART_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
#define KERNEL_CONSOLE_BUS_NAME SERIAL_BUS_NAME_0
#define KERNEL_CONSOLE_DRV_NAME SERIAL_DRV_NAME_0
#define KERNEL_CONSOLE_DEVICE_NAME SERIAL_0_DEVICE_NAME_0
int HwUartInit(void);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,364 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief Universal Asynchronous Receiver/Transmitter (UART)
*
* The UART peripheral supports the following features:
*
* - 8-N-1 and 8-N-2 formats: 8 data bits, no parity bit, 1 start
* bit, 1 or 2 stop bits
*
* - 8-entry transmit and receive FIFO buffers with programmable
* watermark interrupts
*
* - 16× Rx oversampling with 2/3 majority voting per bit
*
* The UART peripheral does not support hardware flow control or
* other modem control signals, or synchronous serial data
* tranfesrs.
*
*
*/
/**
* @file hardware_uart.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __HARDWARE_UART_H__
#define __HARDWARE_UART_H__
#include <stdint.h>
#include "platform.h"
#include "plic.h"
#include "dmac.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum _uart_dev
{
UART_DEV1 = 0,
UART_DEV2,
UART_DEV3,
} uart_dev_t;
typedef struct _uart
{
union
{
volatile uint32_t RBR;
volatile uint32_t DLL;
volatile uint32_t THR;
};
union
{
volatile uint32_t DLH;
volatile uint32_t IER;
};
union
{
volatile uint32_t FCR;
volatile uint32_t IIR;
};
volatile uint32_t LCR;
volatile uint32_t MCR;
volatile uint32_t LSR;
volatile uint32_t MSR;
volatile uint32_t SCR;
volatile uint32_t LPDLL;
volatile uint32_t LPDLH;
volatile uint32_t reserved1[2];
union
{
volatile uint32_t SRBR[16];
volatile uint32_t STHR[16];
};
volatile uint32_t FAR;
volatile uint32_t TFR;
volatile uint32_t RFW;
volatile uint32_t USR;
volatile uint32_t TFL;
volatile uint32_t RFL;
volatile uint32_t SRR;
volatile uint32_t SRTS;
volatile uint32_t SBCR;
volatile uint32_t SDMAM;
volatile uint32_t SFE;
volatile uint32_t SRT;
volatile uint32_t STET;
volatile uint32_t HTX;
volatile uint32_t DMASA;
volatile uint32_t TCR;
volatile uint32_t DE_EN;
volatile uint32_t RE_EN;
volatile uint32_t DET;
volatile uint32_t TAT;
volatile uint32_t DLF;
volatile uint32_t RAR;
volatile uint32_t TAR;
volatile uint32_t LCR_EXT;
volatile uint32_t reserved2[9];
volatile uint32_t CPR;
volatile uint32_t UCV;
volatile uint32_t CTR;
} UartT;
typedef enum _uart_device_number
{
UART_DEVICE_1,
UART_DEVICE_2,
UART_DEVICE_3,
UART_DEVICE_MAX,
} UartDeviceNumberT;
typedef enum _uart_bitwidth
{
UART_BITWIDTH_5BIT = 5,
UART_BITWIDTH_6BIT,
UART_BITWIDTH_7BIT,
UART_BITWIDTH_8BIT,
} UartBitwidthPointer;
typedef enum _uart_stopbit
{
UART_STOP_1,
UART_STOP_1_5,
UART_STOP_2
} UartStopbitT;
typedef enum _uart_rede_sel
{
DISABLE = 0,
ENABLE,
} uart_rede_sel_t;
typedef enum _uart_parity
{
UART_PARITY_NONE,
UART_PARITY_ODD,
UART_PARITY_EVEN
} UartParityT;
typedef enum _uart_interrupt_mode
{
UART_SEND = 1,
UART_RECEIVE = 2,
} UartInterruptModeT;
typedef enum _uart_send_trigger
{
UART_SEND_FIFO_0,
UART_SEND_FIFO_2,
UART_SEND_FIFO_4,
UART_SEND_FIFO_8,
} uart_send_trigger_t;
typedef enum _uart_receive_trigger
{
UART_RECEIVE_FIFO_1,
UART_RECEIVE_FIFO_4,
UART_RECEIVE_FIFO_8,
UART_RECEIVE_FIFO_14,
} uart_receive_trigger_t;
typedef struct _uart_data_t
{
dmac_channel_number_t tx_channel;
dmac_channel_number_t rx_channel;
uint32_t *tx_buf;
size_t tx_len;
uint32_t *rx_buf;
size_t rx_len;
UartInterruptModeT TransferMode;
} uart_data_t;
/**
* @brief Send data from uart
*
* @param[in] channel Uart index
* @param[in] buffer The data be transfer
* @param[in] len The data length
*
* @return Transfer length
*/
int UartSendData(UartDeviceNumberT channel, const char *buffer, size_t BufLen);
/**
* @brief Read data from uart
*
* @param[in] channel Uart index
* @param[in] buffer The Data received
* @param[in] len Receive length
*
* @return Receive length
*/
int UartReceiveData(UartDeviceNumberT channel, char *buffer, size_t BufLen);
/**
* @brief Init uart
*
* @param[in] channel Uart index
*
*/
void UartInit(UartDeviceNumberT channel);
/**
* @brief Set uart param
*
* @param[in] channel Uart index
* @param[in] BaudRate Baudrate
* @param[in] DataWidth Data width
* @param[in] stopbit Stop bit
* @param[in] parity Odd Even parity
*
*/
void uart_config(UartDeviceNumberT channel, uint32_t BaudRate, UartBitwidthPointer DataWidth, UartStopbitT stopbit, UartParityT parity);
/**
* @brief Set uart param
*
* @param[in] channel Uart index
* @param[in] BaudRate Baudrate
* @param[in] DataWidth Data width
* @param[in] stopbit Stop bit
* @param[in] parity Odd Even parity
*
*/
void uart_configure(UartDeviceNumberT channel, uint32_t BaudRate, UartBitwidthPointer DataWidth, UartStopbitT stopbit, UartParityT parity);
/**
* @brief Register uart interrupt
*
* @param[in] channel Uart index
* @param[in] interrupt_mode Interrupt Mode receive or send
* @param[in] uart_callback Call back
* @param[in] ctx Param of call back
* @param[in] priority Interrupt priority
*
*/
void uart_irq_register(UartDeviceNumberT channel, UartInterruptModeT interrupt_mode, plic_irq_callback_t uart_callback, void *ctx, uint32_t priority);
/**
* @brief Deregister uart interrupt
*
* @param[in] channel Uart index
* @param[in] interrupt_mode Interrupt Mode receive or send
*
*/
void uart_irq_unregister(UartDeviceNumberT channel, UartInterruptModeT interrupt_mode);
/**
* @brief Set send interrupt threshold
*
* @param[in] channel Uart index
* @param[in] trigger Threshold of send interrupt
*
*/
void UartSetSendTrigger(UartDeviceNumberT channel, uart_send_trigger_t trigger);
/**
* @brief Set receive interrupt threshold
*
* @param[in] channel Uart index
* @param[in] trigger Threshold of receive interrupt
*
*/
void uart_set_receive_trigger(UartDeviceNumberT channel, uart_receive_trigger_t trigger);
/**
* @brief Send data by dma
*
* @param[in] channel Uart index
* @param[in] dmac_channel Dmac channel
* @param[in] buffer Send data
* @param[in] BufLen Data length
*
*/
void UartSendDataDma(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, const uint8_t *buffer, size_t BufLen);
/**
* @brief Receive data by dma
*
* @param[in] channel Uart index
* @param[in] dmac_channel Dmac channel
* @param[in] buffer Receive data
* @param[in] BufLen Data length
*
*/
void UartReceiveDataDma(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, uint8_t *buffer, size_t BufLen);
/**
* @brief Send data by dma
*
* @param[in] uart_channel Uart index
* @param[in] dmac_channel Dmac channel
* @param[in] buffer Send data
* @param[in] BufLen Data length
* @param[in] uart_callback Call back
* @param[in] ctx Param of call back
* @param[in] priority Interrupt priority
*
*/
void UartSendDataDmaIrq(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel,
const uint8_t *buffer, size_t BufLen, plic_irq_callback_t uart_callback,
void *ctx, uint32_t priority);
/**
* @brief Receive data by dma
*
* @param[in] uart_channel Uart index
* @param[in] dmac_channel Dmac channel
* @param[in] buffer Receive data
* @param[in] BufLen Data length
* @param[in] uart_callback Call back
* @param[in] ctx Param of call back
* @param[in] priority Interrupt priority
*
*/
void UartReceiveDataDmaIrq(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel,
uint8_t *buffer, size_t BufLen, plic_irq_callback_t uart_callback,
void *ctx, uint32_t priority);
/**
* @brief Uart handle transfer data operations
*
* @param[in] uart_channel Uart index
* @param[in] data Uart data information
* @param[in] buffer Uart DMA callback
*
*/
void uart_handle_data_dma(UartDeviceNumberT uart_channel ,uart_data_t data, plic_interrupt_t *cb);
#ifdef __cplusplus
}
#endif
#endif /* __UART_H__ */

View File

@@ -0,0 +1,302 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief Universal Asynchronous Receiver/Transmitter (UART)
*
* The UART peripheral supports the following features:
*
* - 8-N-1 and 8-N-2 formats: 8 data bits, no parity bit, 1 start
* bit, 1 or 2 stop bits
*
* - 8-entry transmit and receive FIFO buffers with programmable
* watermark interrupts
*
* - 16× Rx oversampling with 2/3 majority voting per bit
*
* The UART peripheral does not support hardware flow control or
* other modem control signals, or synchronous serial data
* tranfesrs.
*
* @note UART RAM Layout
*
* | Address | Name | Description |
* |-----------|----------|---------------------------------|
* | 0x000 | txdata | Transmit data register |
* | 0x004 | rxdata | Receive data register |
* | 0x008 | txctrl | Transmit control register |
* | 0x00C | rxctrl | Receive control register |
* | 0x010 | ie | UART interrupt enable |
* | 0x014 | ip | UART Interrupt pending |
* | 0x018 | div | Baud rate divisor |
*
*/
/**
* @file hardware_uarths.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __HARDWARE_UARTHS_H__
#define __HARDWARE_UARTHS_H__
#include <stddef.h>
#include <stdint.h>
#include "platform.h"
#include "plic.h"
#ifdef __cplusplus
extern "C" {
#endif
/* clang-format off */
/* Register address offsets */
#define UARTHS_REG_TXFIFO (0x00)
#define UARTHS_REG_RXFIFO (0x04)
#define UARTHS_REG_TXCTRL (0x08)
#define UARTHS_REG_RXCTRL (0x0c)
#define UARTHS_REG_IE (0x10)
#define UARTHS_REG_IP (0x14)
#define UARTHS_REG_DIV (0x18)
/* TXCTRL register */
#define UARTHS_TXEN (0x01)
#define UARTHS_TXWM(x) (((x) & 0xffff) << 16)
/* RXCTRL register */
#define UARTHS_RXEN (0x01)
#define UARTHS_RXWM(x) (((x) & 0xffff) << 16)
/* IP register */
#define UARTHS_IP_TXWM (0x01)
#define UARTHS_IP_RXWM (0x02)
/* clang-format on */
typedef struct _uarths_txdata
{
/* Bits [7:0] is data */
uint32_t data : 8;
/* Bits [30:8] is 0 */
uint32_t zero : 23;
/* Bit 31 is full status */
uint32_t full : 1;
} __attribute__((packed, aligned(4))) uarths_txdata_t;
typedef struct _uarths_rxdata
{
/* Bits [7:0] is data */
uint32_t data : 8;
/* Bits [30:8] is 0 */
uint32_t zero : 23;
/* Bit 31 is empty status */
uint32_t empty : 1;
} __attribute__((packed, aligned(4))) uarths_rxdata_t;
typedef struct _uarths_txctrl
{
/* Bit 0 is txen, controls whether the Tx channel is active. */
uint32_t txen : 1;
/* Bit 1 is nstop, 0 for one stop bit and 1 for two stop bits */
uint32_t nstop : 1;
/* Bits [15:2] is reserved */
uint32_t resv0 : 14;
/* Bits [18:16] is threshold of interrupt triggers */
uint32_t txcnt : 3;
/* Bits [31:19] is reserved */
uint32_t resv1 : 13;
} __attribute__((packed, aligned(4))) uarths_txctrl_t;
typedef struct _uarths_rxctrl
{
/* Bit 0 is txen, controls whether the Tx channel is active. */
uint32_t rxen : 1;
/* Bits [15:1] is reserved */
uint32_t resv0 : 15;
/* Bits [18:16] is threshold of interrupt triggers */
uint32_t rxcnt : 3;
/* Bits [31:19] is reserved */
uint32_t resv1 : 13;
} __attribute__((packed, aligned(4))) uarths_rxctrl_t;
typedef struct _uarths_ip
{
/* Bit 0 is txwm, raised less than txcnt */
uint32_t txwm : 1;
/* Bit 1 is txwm, raised greater than rxcnt */
uint32_t rxwm : 1;
/* Bits [31:2] is 0 */
uint32_t zero : 30;
} __attribute__((packed, aligned(4))) uarths_ip_t;
typedef struct _uarths_ie
{
/* Bit 0 is txwm, raised less than txcnt */
uint32_t txwm : 1;
/* Bit 1 is txwm, raised greater than rxcnt */
uint32_t rxwm : 1;
/* Bits [31:2] is 0 */
uint32_t zero : 30;
} __attribute__((packed, aligned(4))) uarths_ie_t;
typedef struct _uarths_div
{
/* Bits [31:2] is baud rate divisor register */
uint32_t div : 16;
/* Bits [31:16] is 0 */
uint32_t zero : 16;
} __attribute__((packed, aligned(4))) uarths_div_t;
typedef struct _uarths
{
/* Address offset 0x00 */
uarths_txdata_t txdata;
/* Address offset 0x04 */
uarths_rxdata_t rxdata;
/* Address offset 0x08 */
uarths_txctrl_t txctrl;
/* Address offset 0x0c */
uarths_rxctrl_t rxctrl;
/* Address offset 0x10 */
uarths_ie_t ie;
/* Address offset 0x14 */
uarths_ip_t ip;
/* Address offset 0x18 */
uarths_div_t div;
} __attribute__((packed, aligned(4))) UarthsT;
typedef enum _uarths_interrupt_mode
{
UARTHS_SEND = 1,
UARTHS_RECEIVE = 2,
UARTHS_SEND_RECEIVE = 3,
} uarths_interrupt_mode_t;
typedef enum _uarths_stopbit
{
UARTHS_STOP_1,
UARTHS_STOP_2
} uarths_stopbit_t;
extern volatile UarthsT *const uarths;
/**
* @brief Initialization Core UART
*
* @return result
* - 0 Success
* - Other Fail
*/
void uarths_init(void);
/**
* @brief Put a char to UART
*
* @param[in] c The char to put
*
* @note If c is '\n', a '\r' will be appended automatically
*
* @return result
* - 0 Success
* - Other Fail
*/
int uarths_putchar(char c);
/**
* @brief Send a string to UART
*
* @param[in] s The string to send
*
* @note The string must ending with '\0'
*
* @return result
* - 0 Success
* - Other Fail
*/
int uarths_puts(const char *s);
/**
* @brief Get a byte from UART
*
* @return byte as int type from UART
*/
int uarths_getc(void);
/**
* @brief Set uarths interrupt callback
*
* @param[in] interrupt_mode Interrupt mode recevice or send
* @param[in] uarths_callback Interrupt callback
* @param[in] ctx Param of callback
* @param[in] priority Interrupt priority
*
*/
void uarths_set_irq(uarths_interrupt_mode_t interrupt_mode, plic_irq_callback_t uarths_callback, void *ctx, uint32_t priority);
/**
* @brief Uarths receive data
*
* @param[in] buf The data received
* @param[in] BufLen The length of data
*
* @return Number of received data
*/
size_t uarths_receive_data(uint8_t *buf, size_t BufLen);
/**
* @brief Uarths receive data
*
* @param[in] buf The data sended
* @param[in] BufLen The length of data
*
* @return Number of sended data
*/
size_t uarths_send_data(const uint8_t *buf, size_t BufLen);
/**
* @brief Get interrupt mode
*
* @return Mode of interrupt
*/
uarths_interrupt_mode_t uarths_get_interrupt_mode(void);
/**
* @brief Set uarths baud rate and stopbit
*
* @param[in] BaudRate The baud rate
* @param[in] stopbit The stopbit of data
*
*/
void uarths_config(uint32_t BaudRate, uarths_stopbit_t stopbit);
/**
* @brief Set uart interrupt condition
*
* @param[in] interrupt_mode The interrupt mode
* @param[in] cnt The count of tigger
*
*/
void uarths_set_interrupt_cnt(uarths_interrupt_mode_t interrupt_mode, uint8_t cnt);
#ifdef __cplusplus
}
#endif
#endif /* __UARTHS_H__ */

View File

@@ -0,0 +1,60 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file io.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __IO_H__
#define __IO_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define readb(addr) (*(volatile uint8_t *)(addr))
#define readw(addr) (*(volatile uint16_t *)(addr))
#define readl(addr) (*(volatile uint32_t *)(addr))
#define readq(addr) (*(volatile uint64_t *)(addr))
#define writeb(v, addr) \
{ \
(*(volatile uint8_t *)(addr)) = (v); \
}
#define writew(v, addr) \
{ \
(*(volatile uint16_t *)(addr)) = (v); \
}
#define writel(v, addr) \
{ \
(*(volatile uint32_t *)(addr)) = (v); \
}
#define writeq(v, addr) \
{ \
(*(volatile uint64_t *)(addr)) = (v); \
}
#ifdef __cplusplus
}
#endif
#endif /* __IO_H__ */

View File

@@ -0,0 +1,467 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file plic.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __PLIC_H__
#define __PLIC_H__
#include <stdint.h>
#include "encoding.h"
#include "platform.h"
/* For c++ compatibility */
#ifdef __cplusplus
extern "C" {
#endif
/* clang-format off */
/* IRQ number settings */
#define PLIC_NUM_SOURCES (IRQN_MAX - 1)
#define PLIC_NUM_PRIORITIES (7)
/* Real number of cores */
#define PLIC_NUM_CORES (2)
/* clang-format on */
/**
* @brief PLIC External Interrupt Numbers
*
* @note PLIC interrupt sources
*
* | Source | Name | Description |
* |--------|--------------------------|------------------------------------|
* | 0 | IRQN_NO_INTERRUPT | The non-existent interrupt |
* | 1 | IRQN_SPI0_INTERRUPT | SPI0 interrupt |
* | 2 | IRQN_SPI1_INTERRUPT | SPI1 interrupt |
* | 3 | IRQN_SPI_SLAVE_INTERRUPT | SPI_SLAVE interrupt |
* | 4 | IRQN_SPI3_INTERRUPT | SPI3 interrupt |
* | 5 | IRQN_I2S0_INTERRUPT | I2S0 interrupt |
* | 6 | IRQN_I2S1_INTERRUPT | I2S1 interrupt |
* | 7 | IRQN_I2S2_INTERRUPT | I2S2 interrupt |
* | 8 | IRQN_I2C0_INTERRUPT | I2C0 interrupt |
* | 9 | IRQN_I2C1_INTERRUPT | I2C1 interrupt |
* | 10 | IRQN_I2C2_INTERRUPT | I2C2 interrupt |
* | 11 | IRQN_UART1_INTERRUPT | UART1 interrupt |
* | 12 | IRQN_UART2_INTERRUPT | UART2 interrupt |
* | 13 | IRQN_UART3_INTERRUPT | UART3 interrupt |
* | 14 | IRQN_TIMER0A_INTERRUPT | TIMER0 channel 0 or 1 interrupt |
* | 15 | IRQN_TIMER0B_INTERRUPT | TIMER0 channel 2 or 3 interrupt |
* | 16 | IRQN_TIMER1A_INTERRUPT | TIMER1 channel 0 or 1 interrupt |
* | 17 | IRQN_TIMER1B_INTERRUPT | TIMER1 channel 2 or 3 interrupt |
* | 18 | IRQN_TIMER2A_INTERRUPT | TIMER2 channel 0 or 1 interrupt |
* | 19 | IRQN_TIMER2B_INTERRUPT | TIMER2 channel 2 or 3 interrupt |
* | 20 | IRQN_RTC_INTERRUPT | RTC tick and alarm interrupt |
* | 21 | IRQN_WDT0_INTERRUPT | Watching dog timer0 interrupt |
* | 22 | IRQN_WDT1_INTERRUPT | Watching dog timer1 interrupt |
* | 23 | IRQN_APB_GPIO_INTERRUPT | APB GPIO interrupt |
* | 24 | IRQN_DVP_INTERRUPT | Digital video port interrupt |
* | 25 | IRQN_AI_INTERRUPT | AI accelerator interrupt |
* | 26 | IRQN_FFT_INTERRUPT | FFT accelerator interrupt |
* | 27 | IRQN_DMA0_INTERRUPT | DMA channel0 interrupt |
* | 28 | IRQN_DMA1_INTERRUPT | DMA channel1 interrupt |
* | 29 | IRQN_DMA2_INTERRUPT | DMA channel2 interrupt |
* | 30 | IRQN_DMA3_INTERRUPT | DMA channel3 interrupt |
* | 31 | IRQN_DMA4_INTERRUPT | DMA channel4 interrupt |
* | 32 | IRQN_DMA5_INTERRUPT | DMA channel5 interrupt |
* | 33 | IRQN_UARTHS_INTERRUPT | Hi-speed UART0 interrupt |
* | 34 | IRQN_GPIOHS0_INTERRUPT | Hi-speed GPIO0 interrupt |
* | 35 | IRQN_GPIOHS1_INTERRUPT | Hi-speed GPIO1 interrupt |
* | 36 | IRQN_GPIOHS2_INTERRUPT | Hi-speed GPIO2 interrupt |
* | 37 | IRQN_GPIOHS3_INTERRUPT | Hi-speed GPIO3 interrupt |
* | 38 | IRQN_GPIOHS4_INTERRUPT | Hi-speed GPIO4 interrupt |
* | 39 | IRQN_GPIOHS5_INTERRUPT | Hi-speed GPIO5 interrupt |
* | 40 | IRQN_GPIOHS6_INTERRUPT | Hi-speed GPIO6 interrupt |
* | 41 | IRQN_GPIOHS7_INTERRUPT | Hi-speed GPIO7 interrupt |
* | 42 | IRQN_GPIOHS8_INTERRUPT | Hi-speed GPIO8 interrupt |
* | 43 | IRQN_GPIOHS9_INTERRUPT | Hi-speed GPIO9 interrupt |
* | 44 | IRQN_GPIOHS10_INTERRUPT | Hi-speed GPIO10 interrupt |
* | 45 | IRQN_GPIOHS11_INTERRUPT | Hi-speed GPIO11 interrupt |
* | 46 | IRQN_GPIOHS12_INTERRUPT | Hi-speed GPIO12 interrupt |
* | 47 | IRQN_GPIOHS13_INTERRUPT | Hi-speed GPIO13 interrupt |
* | 48 | IRQN_GPIOHS14_INTERRUPT | Hi-speed GPIO14 interrupt |
* | 49 | IRQN_GPIOHS15_INTERRUPT | Hi-speed GPIO15 interrupt |
* | 50 | IRQN_GPIOHS16_INTERRUPT | Hi-speed GPIO16 interrupt |
* | 51 | IRQN_GPIOHS17_INTERRUPT | Hi-speed GPIO17 interrupt |
* | 52 | IRQN_GPIOHS18_INTERRUPT | Hi-speed GPIO18 interrupt |
* | 53 | IRQN_GPIOHS19_INTERRUPT | Hi-speed GPIO19 interrupt |
* | 54 | IRQN_GPIOHS20_INTERRUPT | Hi-speed GPIO20 interrupt |
* | 55 | IRQN_GPIOHS21_INTERRUPT | Hi-speed GPIO21 interrupt |
* | 56 | IRQN_GPIOHS22_INTERRUPT | Hi-speed GPIO22 interrupt |
* | 57 | IRQN_GPIOHS23_INTERRUPT | Hi-speed GPIO23 interrupt |
* | 58 | IRQN_GPIOHS24_INTERRUPT | Hi-speed GPIO24 interrupt |
* | 59 | IRQN_GPIOHS25_INTERRUPT | Hi-speed GPIO25 interrupt |
* | 60 | IRQN_GPIOHS26_INTERRUPT | Hi-speed GPIO26 interrupt |
* | 61 | IRQN_GPIOHS27_INTERRUPT | Hi-speed GPIO27 interrupt |
* | 62 | IRQN_GPIOHS28_INTERRUPT | Hi-speed GPIO28 interrupt |
* | 63 | IRQN_GPIOHS29_INTERRUPT | Hi-speed GPIO29 interrupt |
* | 64 | IRQN_GPIOHS30_INTERRUPT | Hi-speed GPIO30 interrupt |
* | 65 | IRQN_GPIOHS31_INTERRUPT | Hi-speed GPIO31 interrupt |
*
*/
/* clang-format off */
typedef enum _plic_irq
{
IRQN_NO_INTERRUPT = 0, /*!< The non-existent interrupt */
IRQN_SPI0_INTERRUPT = 1, /*!< SPI0 interrupt */
IRQN_SPI1_INTERRUPT = 2, /*!< SPI1 interrupt */
IRQN_SPI_SLAVE_INTERRUPT = 3, /*!< SPI_SLAVE interrupt */
IRQN_SPI3_INTERRUPT = 4, /*!< SPI3 interrupt */
IRQN_I2S0_INTERRUPT = 5, /*!< I2S0 interrupt */
IRQN_I2S1_INTERRUPT = 6, /*!< I2S1 interrupt */
IRQN_I2S2_INTERRUPT = 7, /*!< I2S2 interrupt */
IRQN_I2C0_INTERRUPT = 8, /*!< I2C0 interrupt */
IRQN_I2C1_INTERRUPT = 9, /*!< I2C1 interrupt */
IRQN_I2C2_INTERRUPT = 10, /*!< I2C2 interrupt */
IRQN_UART1_INTERRUPT = 11, /*!< UART1 interrupt */
IRQN_UART2_INTERRUPT = 12, /*!< UART2 interrupt */
IRQN_UART3_INTERRUPT = 13, /*!< UART3 interrupt */
IRQN_TIMER0A_INTERRUPT = 14, /*!< TIMER0 channel 0 or 1 interrupt */
IRQN_TIMER0B_INTERRUPT = 15, /*!< TIMER0 channel 2 or 3 interrupt */
IRQN_TIMER1A_INTERRUPT = 16, /*!< TIMER1 channel 0 or 1 interrupt */
IRQN_TIMER1B_INTERRUPT = 17, /*!< TIMER1 channel 2 or 3 interrupt */
IRQN_TIMER2A_INTERRUPT = 18, /*!< TIMER2 channel 0 or 1 interrupt */
IRQN_TIMER2B_INTERRUPT = 19, /*!< TIMER2 channel 2 or 3 interrupt */
IRQN_RTC_INTERRUPT = 20, /*!< RTC tick and alarm interrupt */
IRQN_WDT0_INTERRUPT = 21, /*!< Watching dog timer0 interrupt */
IRQN_WDT1_INTERRUPT = 22, /*!< Watching dog timer1 interrupt */
IRQN_APB_GPIO_INTERRUPT = 23, /*!< APB GPIO interrupt */
IRQN_DVP_INTERRUPT = 24, /*!< Digital video port interrupt */
IRQN_AI_INTERRUPT = 25, /*!< AI accelerator interrupt */
IRQN_FFT_INTERRUPT = 26, /*!< FFT accelerator interrupt */
IRQN_DMA0_INTERRUPT = 27, /*!< DMA channel0 interrupt */
IRQN_DMA1_INTERRUPT = 28, /*!< DMA channel1 interrupt */
IRQN_DMA2_INTERRUPT = 29, /*!< DMA channel2 interrupt */
IRQN_DMA3_INTERRUPT = 30, /*!< DMA channel3 interrupt */
IRQN_DMA4_INTERRUPT = 31, /*!< DMA channel4 interrupt */
IRQN_DMA5_INTERRUPT = 32, /*!< DMA channel5 interrupt */
IRQN_UARTHS_INTERRUPT = 33, /*!< Hi-speed UART0 interrupt */
IRQN_GPIOHS0_INTERRUPT = 34, /*!< Hi-speed GPIO0 interrupt */
IRQN_GPIOHS1_INTERRUPT = 35, /*!< Hi-speed GPIO1 interrupt */
IRQN_GPIOHS2_INTERRUPT = 36, /*!< Hi-speed GPIO2 interrupt */
IRQN_GPIOHS3_INTERRUPT = 37, /*!< Hi-speed GPIO3 interrupt */
IRQN_GPIOHS4_INTERRUPT = 38, /*!< Hi-speed GPIO4 interrupt */
IRQN_GPIOHS5_INTERRUPT = 39, /*!< Hi-speed GPIO5 interrupt */
IRQN_GPIOHS6_INTERRUPT = 40, /*!< Hi-speed GPIO6 interrupt */
IRQN_GPIOHS7_INTERRUPT = 41, /*!< Hi-speed GPIO7 interrupt */
IRQN_GPIOHS8_INTERRUPT = 42, /*!< Hi-speed GPIO8 interrupt */
IRQN_GPIOHS9_INTERRUPT = 43, /*!< Hi-speed GPIO9 interrupt */
IRQN_GPIOHS10_INTERRUPT = 44, /*!< Hi-speed GPIO10 interrupt */
IRQN_GPIOHS11_INTERRUPT = 45, /*!< Hi-speed GPIO11 interrupt */
IRQN_GPIOHS12_INTERRUPT = 46, /*!< Hi-speed GPIO12 interrupt */
IRQN_GPIOHS13_INTERRUPT = 47, /*!< Hi-speed GPIO13 interrupt */
IRQN_GPIOHS14_INTERRUPT = 48, /*!< Hi-speed GPIO14 interrupt */
IRQN_GPIOHS15_INTERRUPT = 49, /*!< Hi-speed GPIO15 interrupt */
IRQN_GPIOHS16_INTERRUPT = 50, /*!< Hi-speed GPIO16 interrupt */
IRQN_GPIOHS17_INTERRUPT = 51, /*!< Hi-speed GPIO17 interrupt */
IRQN_GPIOHS18_INTERRUPT = 52, /*!< Hi-speed GPIO18 interrupt */
IRQN_GPIOHS19_INTERRUPT = 53, /*!< Hi-speed GPIO19 interrupt */
IRQN_GPIOHS20_INTERRUPT = 54, /*!< Hi-speed GPIO20 interrupt */
IRQN_GPIOHS21_INTERRUPT = 55, /*!< Hi-speed GPIO21 interrupt */
IRQN_GPIOHS22_INTERRUPT = 56, /*!< Hi-speed GPIO22 interrupt */
IRQN_GPIOHS23_INTERRUPT = 57, /*!< Hi-speed GPIO23 interrupt */
IRQN_GPIOHS24_INTERRUPT = 58, /*!< Hi-speed GPIO24 interrupt */
IRQN_GPIOHS25_INTERRUPT = 59, /*!< Hi-speed GPIO25 interrupt */
IRQN_GPIOHS26_INTERRUPT = 60, /*!< Hi-speed GPIO26 interrupt */
IRQN_GPIOHS27_INTERRUPT = 61, /*!< Hi-speed GPIO27 interrupt */
IRQN_GPIOHS28_INTERRUPT = 62, /*!< Hi-speed GPIO28 interrupt */
IRQN_GPIOHS29_INTERRUPT = 63, /*!< Hi-speed GPIO29 interrupt */
IRQN_GPIOHS30_INTERRUPT = 64, /*!< Hi-speed GPIO30 interrupt */
IRQN_GPIOHS31_INTERRUPT = 65, /*!< Hi-speed GPIO31 interrupt */
IRQN_MAX
} plic_irq_t;
/* clang-format on */
/**
* @brief Interrupt Source Priorities
*
* Each external interrupt source can be assigned a priority by
* writing to its 32-bit memory-mapped priority register. The
* number and value of supported priority levels can vary by
* implementa- tion, with the simplest implementations having all
* devices hardwired at priority 1, in which case, interrupts with
* the lowest ID have the highest effective priority. The priority
* registers are all WARL.
*/
typedef struct _plic_source_priorities
{
/* 0x0C000000: Reserved, 0x0C000004-0x0C000FFC: 1-1023 priorities */
uint32_t priority[1024];
} __attribute__((packed, aligned(4))) plic_source_priorities_t;
/**
* @brief Interrupt Pending Bits
*
* The current status of the interrupt source pending bits in the
* PLIC core can be read from the pending array, organized as 32
* words of 32 bits. The pending bit for interrupt ID N is stored
* in bit (N mod 32) of word (N/32). Bit 0 of word 0, which
* represents the non-existent interrupt source 0, is always
* hardwired to zero. The pending bits are read-only. A pending
* bit in the PLIC core can be cleared by setting enable bits to
* only enable the desired interrupt, then performing a claim. A
* pending bit can be set by instructing the associated gateway to
* send an interrupt service request.
*/
typedef struct _plic_pending_bits
{
/* 0x0C001000-0x0C00107C: Bit 0 is zero, Bits 1-1023 is pending bits */
uint32_t u32[32];
/* 0x0C001080-0x0C001FFF: Reserved */
uint8_t resv[0xF80];
} __attribute__((packed, aligned(4))) plic_pending_bits_t;
/**
* @brief Target Interrupt Enables
*
* For each interrupt target, each devices interrupt can be
* enabled by setting the corresponding bit in that targets
* enables registers. The enables for a target are accessed as a
* contiguous array of 32×32-bit words, packed the same way as the
* pending bits. For each target, bit 0 of enable word 0
* represents the non-existent interrupt ID 0 and is hardwired to
* 0. Unused interrupt IDs are also hardwired to zero. The enables
* arrays for different targets are packed contiguously in the
* address space. Only 32-bit word accesses are supported by the
* enables array in RV32 systems. Implementations can trap on
* accesses to enables for non-existent targets, but must allow
* access to the full enables array for any extant target,
* treating all non-existent interrupt sources enables as
* hardwired to zero.
*/
typedef struct _plic_target_enables
{
/* 0x0C002000-0x0C1F1F80: target 0-15871 enables */
struct
{
uint32_t enable[32 * 2];/* Offset 0x00-0x7C: Bit 0 is zero, Bits 1-1023 is bits*/
} target[15872 / 2];
/* 0x0C1F2000-0x0C1FFFFC: Reserved, size 0xE000 */
uint8_t resv[0xE000];
} __attribute__((packed, aligned(4))) plic_target_enables_t;
/**
* @brief PLIC Targets
*
* Target Priority Thresholds The threshold for a pending
* interrupt priority that can interrupt each target can be set in
* the targets threshold register. The threshold is a WARL field,
* where different implementations can support different numbers
* of thresholds. The simplest implementation has a threshold
* hardwired to zero.
*
* Target Claim Each target can perform a claim by reading the
* claim/complete register, which returns the ID of the highest
* priority pending interrupt or zero if there is no pending
* interrupt for the target. A successful claim will also
* atomically clear the corresponding pending bit on the interrupt
* source. A target can perform a claim at any time, even if the
* EIP is not set. The claim operation is not affected by the
* setting of the targets priority threshold register.
*
* Target Completion A target signals it has completed running a
* handler by writing the interrupt ID it received from the claim
* to the claim/complete register. This is routed to the
* corresponding interrupt gateway, which can now send another
* interrupt request to the PLIC. The PLIC does not check whether
* the completion ID is the same as the last claim ID for that
* target. If the completion ID does not match an interrupt source
* that is currently enabled for the target, the completion is
* silently ignored.
*/
typedef struct _plic_target
{
/* 0x0C200000-0x0FFFF004: target 0-15871 */
struct {
uint32_t priority_threshold;/* Offset 0x000 */
uint32_t claim_complete; /* Offset 0x004 */
uint8_t resv[0x1FF8]; /* Offset 0x008, Size 0xFF8 */
} target[15872 / 2];
} __attribute__((packed, aligned(4))) plic_target_t;
/**
* @brief Platform-Level Interrupt Controller
*
* PLIC is Platform-Level Interrupt Controller. The PLIC complies
* with the RISC-V Privileged Architecture specification, and can
* support a maximum of 1023 external interrupt sources targeting
* up to 15,872 core contexts.
*/
typedef struct _plic
{
/* 0x0C000000-0x0C000FFC */
plic_source_priorities_t source_priorities;
/* 0x0C001000-0x0C001FFF */
const plic_pending_bits_t pending_bits;
/* 0x0C002000-0x0C1FFFFC */
plic_target_enables_t target_enables;
/* 0x0C200000-0x0FFFF004 */
plic_target_t targets;
} __attribute__((packed, aligned(4))) plic_t;
extern volatile plic_t *const plic;
/**
* @brief Definitions for the interrupt callbacks
*/
typedef int (*plic_irq_callback_t)(void *ctx);
/**
* @brief Definitions for IRQ table instance
*/
typedef struct _plic_instance_t
{
plic_irq_callback_t callback;
void *ctx;
} plic_instance_t;
typedef struct _plic_callback_t
{
plic_irq_callback_t callback;
void *ctx;
uint32_t priority;
} plic_interrupt_t;
/**
* @brief Initialize PLIC external interrupt
*
* @note This function will set MIP_MEIP. The MSTATUS_MIE must set by user.
*
* @return result
* - 0 Success
* - Other Fail
*/
void plic_init(void);
/**
* @brief Enable PLIC external interrupt
*
* @param[in] irq_number external interrupt number
*
* @return result
* - 0 Success
* - Other Fail
*/
int plic_irq_enable(plic_irq_t irq_number);
/**
* @brief Disable PLIC external interrupt
*
* @param[in] irq_number The external interrupt number
*
* @return result
* - 0 Success
* - Other Fail
*/
int plic_irq_disable(plic_irq_t irq_number);
/**
* @brief Set IRQ priority
*
* @param[in] irq_number The external interrupt number
* @param[in] priority The priority of external interrupt number
*
* @return result
* - 0 Success
* - Other Fail
*/
int plic_set_priority(plic_irq_t irq_number, uint32_t priority);
/**
* @brief Get IRQ priority
*
* @param[in] irq_number The external interrupt number
*
* @return The priority of external interrupt number
*/
uint32_t plic_get_priority(plic_irq_t irq_number);
/**
* @brief Claim an IRQ
*
* @return The current IRQ number
*/
uint32_t plic_irq_claim(void);
/**
* @brief Complete an IRQ
*
* @param[in] source The source IRQ number to complete
*
* @return result
* - 0 Success
* - Other Fail
*/
int plic_irq_complete(uint32_t source);
/**
* @brief Register user callback function by IRQ number
*
* @param[in] irq The irq
* @param[in] callback The callback
* @param ctx The context
*
* @return result
* - 0 Success
* - Other Fail
*/
void plic_irq_register(plic_irq_t irq, plic_irq_callback_t callback, void *ctx);
/**
* @brief Deegister user callback function by IRQ number
*
* @param[in] irq The irq
*
* @return result
* - 0 Success
* - Other Fail
*/
void plic_irq_deregister(plic_irq_t irq);
/**
* @brief Deegister user callback function by IRQ number
*
* @param[in] irq The irq
*
* @return result
* - 0 Success
* - Other Fail
*/
void plic_irq_unregister(plic_irq_t irq);
/**
* @brief Get IRQ table, Usage:
* plic_instance_t (*plic_instance)[IRQN_MAX] = plic_get_instance();
* ... plic_instance[x][y] ...;
*
* @return the point of IRQ table
*/
plic_instance_t (*plic_get_instance(void))[IRQN_MAX];
/* For c++ compatibility */
#ifdef __cplusplus
}
#endif
#endif /* __PLIC_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,357 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file utils.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __UTILS_H__
#define __UTILS_H__
#ifdef __cplusplus
#include <cstdbool>
#include <cstddef>
#include <cstdint>
#else /* __cplusplus */
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#endif /* __cplusplus */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define KENDRYTE_MIN(a, b) ((a) > (b) ? (b) : (a))
#define KENDRYTE_MAX(a, b) ((a) > (b) ? (a) : (b))
#ifdef __ASSEMBLY__
#define KENDRYTE_CAST(type, ptr) ptr
#else /* __ASSEMBLY__ */
/**
* @brief Cast the pointer to specified pointer type.
*
* @param[in] type The pointer type to cast to
* @param[in] ptr The pointer to apply the type cast to
*/
#define KENDRYTE_CAST(type, ptr) ((type)(ptr))
#endif /* __ASSEMBLY__ */
/**
* @addtogroup UTIL_RW_FUNC Memory Read/Write Utilities
*
* This section implements read and write functionality for various
* memory untis. The memory unit terms used for these functions are
* consistent with those used in the ARM Architecture Reference Manual
* ARMv7-A and ARMv7-R edition manual. The terms used for units of memory are:
*
* Unit of Memory | Abbreviation | Size in Bits
* :---------------|:-------------|:------------:
* Byte | byte | 8
* Half Word | hword | 16
* Word | word | 32
* Double Word | dword | 64
*
*/
/**
* @brief Write the 8 bit byte to the destination address in device memory.
*
* @param[in] dest Write destination pointer address
* @param[in] src 8 bit data byte to write to memory
*/
#define kendryte_write_byte(dest, src) \
(*KENDRYTE_CAST(volatile uint8_t*, (dest)) = (src))
/**
* @brief Read and return the 8 bit byte from the source address in device memory.
*
* @param[in] src Read source pointer address
*
* @return 8 bit data byte value
*/
#define kendryte_read_byte(src) (*KENDRYTE_CAST(volatile uint8_t*, (src)))
/**
* @brief Write the 16 bit half word to the destination address in device memory.
*
* @param[in] dest Write destination pointer address
* @param[in] src 16 bit data half word to write to memory
*/
#define kendryte_write_hword(dest, src) \
(*KENDRYTE_CAST(volatile uint16_t*, (dest)) = (src))
/**
* @brief Read and return the 16 bit half word from the source address in device
*
* @param[in] src Read source pointer address
*
* @return 16 bit data half word value
*/
#define kendryte_read_hword(src) (*KENDRYTE_CAST(volatile uint16_t*, (src)))
/**
* @brief Write the 32 bit word to the destination address in device memory.
*
* @param[in] dest Write destination pointer address
* @param[in] src 32 bit data word to write to memory
*/
#define kendryte_write_word(dest, src) \
(*KENDRYTE_CAST(volatile uint32_t*, (dest)) = (src))
/**
* @brief Read and return the 32 bit word from the source address in device memory.
*
* @param[in] src Read source pointer address
*
* @return 32 bit data half word value
*/
#define kendryte_read_word(src) (*KENDRYTE_CAST(volatile uint32_t*, (src)))
/**
* @brief Write the 64 bit double word to the destination address in device memory.
*
* @param[in] dest Write destination pointer address
* @param[in] src 64 bit data word to write to memory
*/
#define kendryte_write_dword(dest, src) \
(*KENDRYTE_CAST(volatile uint64_t*, (dest)) = (src))
/**
* @brief Read and return the 64 bit double word from the source address in device
*
* @param[in] src Read source pointer address
*
* @return 64 bit data half word value
*/
#define kendryte_read_dword(src) (*KENDRYTE_CAST(volatile uint64_t*, (src)))
/**
* @brief Set selected bits in the 8 bit byte at the destination address in device
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to set in destination byte
*/
#define kendryte_setbits_byte(dest, bits) \
(kendryte_write_byte(dest, kendryte_read_byte(dest) | (bits)))
/**
* @brief Clear selected bits in the 8 bit byte at the destination address in device
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to clear in destination byte
*/
#define kendryte_clrbits_byte(dest, bits) \
(kendryte_write_byte(dest, kendryte_read_byte(dest) & ~(bits)))
/**
* @brief Change or toggle selected bits in the 8 bit byte at the destination address
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to change in destination byte
*/
#define kendryte_xorbits_byte(dest, bits) \
(kendryte_write_byte(dest, kendryte_read_byte(dest) ^ (bits)))
/**
* @brief Replace selected bits in the 8 bit byte at the destination address in device
*
* @param[in] dest Destination pointer address
* @param[in] msk Bits to replace in destination byte
* @param[in] src Source bits to write to cleared bits in destination byte
*/
#define kendryte_replbits_byte(dest, msk, src) \
(kendryte_write_byte(dest, (kendryte_read_byte(dest) & ~(msk)) | ((src) & (msk))))
/**
* @brief Set selected bits in the 16 bit halfword at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to set in destination halfword
*/
#define kendryte_setbits_hword(dest, bits) \
(kendryte_write_hword(dest, kendryte_read_hword(dest) | (bits)))
/**
* @brief Clear selected bits in the 16 bit halfword at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to clear in destination halfword
*/
#define kendryte_clrbits_hword(dest, bits) \
(kendryte_write_hword(dest, kendryte_read_hword(dest) & ~(bits)))
/**
* @brief Change or toggle selected bits in the 16 bit halfword at the destination
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to change in destination halfword
*/
#define kendryte_xorbits_hword(dest, bits) \
(kendryte_write_hword(dest, kendryte_read_hword(dest) ^ (bits)))
/**
* @brief Replace selected bits in the 16 bit halfword at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] msk Bits to replace in destination byte
* @param[in] src Source bits to write to cleared bits in destination halfword
*/
#define kendryte_replbits_hword(dest, msk, src) \
(kendryte_write_hword(dest, (kendryte_read_hword(dest) & ~(msk)) | ((src) & (msk))))
/**
* @brief Set selected bits in the 32 bit word at the destination address in device
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to set in destination word
*/
#define kendryte_setbits_word(dest, bits) \
(kendryte_write_word(dest, kendryte_read_word(dest) | (bits)))
/**
* @brief Clear selected bits in the 32 bit word at the destination address in device
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to clear in destination word
*/
#define kendryte_clrbits_word(dest, bits) \
(kendryte_write_word(dest, kendryte_read_word(dest) & ~(bits)))
/**
* @brief Change or toggle selected bits in the 32 bit word at the destination address
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to change in destination word
*/
#define kendryte_xorbits_word(dest, bits) \
(kendryte_write_word(dest, kendryte_read_word(dest) ^ (bits)))
/**
* @brief Replace selected bits in the 32 bit word at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] msk Bits to replace in destination word
* @param[in] src Source bits to write to cleared bits in destination word
*/
#define kendryte_replbits_word(dest, msk, src) \
(kendryte_write_word(dest, (kendryte_read_word(dest) & ~(msk)) | ((src) & (msk))))
/**
* @brief Set selected bits in the 64 bit doubleword at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to set in destination doubleword
*/
#define kendryte_setbits_dword(dest, bits) \
(kendryte_write_dword(dest, kendryte_read_dword(dest) | (bits)))
/**
* @brief Clear selected bits in the 64 bit doubleword at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to clear in destination doubleword
*/
#define kendryte_clrbits_dword(dest, bits) \
(kendryte_write_dword(dest, kendryte_read_dword(dest) & ~(bits)))
/**
* @brief Change or toggle selected bits in the 64 bit doubleword at the destination
*
* @param[in] dest Destination pointer address
* @param[in] bits Bits to change in destination doubleword
*/
#define kendryte_xorbits_dword(dest, bits) \
(kendryte_write_dword(dest, kendryte_read_dword(dest) ^ (bits)))
/**
* @brief Replace selected bits in the 64 bit doubleword at the destination address in
*
* @param[in] dest Destination pointer address
* @param[in] msk its to replace in destination doubleword
* @param[in] src Source bits to write to cleared bits in destination word
*/
#define kendryte_replbits_dword(dest, msk, src) \
(kendryte_write_dword(dest, (kendryte_read_dword(dest) & ~(msk)) | ((src) & (msk))))
#define configASSERT(x) \
if ((x) == 0) \
{ \
printf("(%s:%d) %s\r\n", __FILE__, __LINE__, #x); \
for (;;) \
; \
}
/**
* @brief Set value by mask
*
* @param[in] bits The one be set
* @param[in] mask mask value
* @param[in] value The value to set
*/
void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value);
/**
* @brief Set value by mask
*
* @param[in] bits The one be set
* @param[in] mask Mask value
* @param[in] offset Mask's offset
* @param[in] value The value to set
*/
void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value);
/**
* @brief Set bit for gpio, only set one bit
*
* @param[in] bits The one be set
* @param[in] idx Offset value
* @param[in] value The value to set
*/
void set_gpio_bit(volatile uint32_t *bits, size_t idx, uint32_t value);
/**
* @brief Get bits value of mask
*
* @param[in] bits The source data
* @param[in] mask Mask value
* @param[in] offset Mask's offset
*
* @return The bits value of mask
*/
uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset);
/**
* @brief Get a bit value by offset
*
* @param[in] bits The source data
* @param[in] offset Bit's offset
*
*
* @return The bit value
*/
uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _DRIVER_COMMON_H */