Adjust directory structure

This commit is contained in:
Zhao_Jiasheng
2021-06-03 17:38:11 +08:00
parent 92301257f3
commit 89a2236b18
1993 changed files with 40 additions and 0 deletions
@@ -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__ */