| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758 |
- /*
- * Copyright (c) 2019 Nuclei Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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
- *
- * 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.
- */
- #ifndef __CORE_FEATURE_BASE__
- #define __CORE_FEATURE_BASE__
- /*!
- * @file core_feature_base.h
- * @brief Base core feature API for Nuclei N/NX Core
- */
- /*
- * Core Base Feature Configuration Macro:
- * 1. __HARTID_OFFSET: Optional, define this macro when your cpu system first hart hartid and hart index is different.
- * eg. If your cpu system, first hart hartid is 2, hart index is 0, then set this macro to 2
- *
- */
- #include <stdint.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "nmsis_compiler.h"
- /**
- * \defgroup NMSIS_Core_Registers Register Define and Type Definitions
- * \brief Type definitions and defines for core registers.
- *
- * @{
- */
- #ifndef __RISCV_XLEN
- /** \brief Refer to the width of an integer register in bits(either 32 or 64) */
- #ifndef __riscv_xlen
- #define __RISCV_XLEN 32
- #else
- #define __RISCV_XLEN __riscv_xlen
- #endif
- #endif /* __RISCV_XLEN */
- /** \brief Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V */
- typedef unsigned long rv_csr_t;
- /** \brief Type of RISC-V Counter such as cycle, instret, time, depends on the XLEN defined in RISC-V, but for n100, it will be 32bit max */
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- typedef uint32_t rv_counter_t;
- #else
- typedef uint64_t rv_counter_t;
- #endif
- /** @} */ /* End of Doxygen Group NMSIS_Core_Registers */
- /**
- * \defgroup NMSIS_Core_Base_Registers Base Register Define and Type Definitions
- * \ingroup NMSIS_Core_Registers
- * \brief Type definitions and defines for base core registers.
- *
- * @{
- */
- /**
- * \brief Union type to access MISA CSR register.
- */
- typedef union {
- struct {
- rv_csr_t a:1; /*!< bit: 0 Atomic extension */
- rv_csr_t b:1; /*!< bit: 1 B extension */
- rv_csr_t c:1; /*!< bit: 2 Compressed extension */
- rv_csr_t d:1; /*!< bit: 3 Double-precision floating-point extension */
- rv_csr_t e:1; /*!< bit: 4 RV32E/64E base ISA */
- rv_csr_t f:1; /*!< bit: 5 Single-precision floating-point extension */
- rv_csr_t g:1; /*!< bit: 6 Reserved */
- rv_csr_t h:1; /*!< bit: 7 Hypervisor extension */
- rv_csr_t i:1; /*!< bit: 8 RV32I/64I/128I base ISA */
- rv_csr_t j:1; /*!< bit: 9 Reserved */
- rv_csr_t k:1; /*!< bit: 10 Reserved */
- rv_csr_t l:1; /*!< bit: 11 Reserved */
- rv_csr_t m:1; /*!< bit: 12 Integer Multiply/Divide extension */
- rv_csr_t n:1; /*!< bit: 13 Tentatively reserved for User-Level Interrupts extension */
- rv_csr_t o:1; /*!< bit: 14 Reserved */
- rv_csr_t p:1; /*!< bit: 15 Tentatively reserved for Packed-SIMD extension */
- rv_csr_t q:1; /*!< bit: 16 Quad-precision floating-point extension */
- rv_csr_t r:1; /*!< bit: 17 Reserved */
- rv_csr_t s:1; /*!< bit: 18 Supervisor mode implemented */
- rv_csr_t t:1; /*!< bit: 19 Reserved */
- rv_csr_t u:1; /*!< bit: 20 User mode implemented */
- rv_csr_t v:1; /*!< bit: 21 Vector extension */
- rv_csr_t w:1; /*!< bit: 22 Reserved */
- rv_csr_t x:1; /*!< bit: 23 Non-standard extensions present */
- rv_csr_t y:1; /*!< bit: 24 Reserved */
- rv_csr_t z:1; /*!< bit: 25 Reserved */
- rv_csr_t _reserved0:__RISCV_XLEN-28; /*!< bit: 26..XLEN-3 Reserved */
- rv_csr_t mxl:2; /*!< bit: XLEN-2..XLEN-1 Machine XLEN */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MISA_Type;
- /**
- * \brief Union type to access MSTATUS CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:1; /*!< bit: 0 Reserved */
- rv_csr_t sie:1; /*!< bit: 1 supervisor interrupt enable flag */
- rv_csr_t _reserved1:1; /*!< bit: 2 Reserved */
- rv_csr_t mie:1; /*!< bit: 3 machine mode interrupt enable flag */
- rv_csr_t _reserved2:1; /*!< bit: 4 Reserved */
- rv_csr_t spie:1; /*!< bit: 5 supervisor mode interrupt enable flag */
- rv_csr_t ube:1; /*!< bit: 6 U-mode non-instruction-fetch memory accesse big-endian enable flag */
- rv_csr_t mpie:1; /*!< bit: 7 machine mode previous interrupt enable flag */
- rv_csr_t spp:1; /*!< bit: 8 supervisor previous privilede mode */
- rv_csr_t vs:2; /*!< bit: 9..10 vector status flag */
- rv_csr_t mpp:2; /*!< bit: 11..12 machine previous privilede mode */
- rv_csr_t fs:2; /*!< bit: 13..14 FS status flag */
- rv_csr_t xs:2; /*!< bit: 15..16 XS status flag */
- rv_csr_t mprv:1; /*!< bit: 17 Modify PRiVilege */
- rv_csr_t sum:1; /*!< bit: 18 Supervisor Mode load and store protection */
- rv_csr_t mxr:1; /*!< bit: 19 Make eXecutable Readable */
- rv_csr_t tvm:1; /*!< bit: 20 Trap Virtual Memory */
- rv_csr_t tw:1; /*!< bit: 21 Timeout Wait */
- rv_csr_t tsr:1; /*!< bit: 22 Trap SRET */
- rv_csr_t spelp:1; /*!< bit: 23 Supervisor mode Previous Expected Landing Pad (ELP) State */
- rv_csr_t sdt:1; /*!< bit: 24 S-mode-disable-trap */
- #if defined(__RISCV_XLEN) && __RISCV_XLEN == 64
- rv_csr_t _reserved3:7; /*!< bit: 25..31 Reserved */
- rv_csr_t uxl:2; /*!< bit: 32..33 U-mode XLEN */
- rv_csr_t sxl:2; /*!< bit: 34..35 S-mode XLEN */
- rv_csr_t sbe:1; /*!< bit: 36 S-mode non-instruction-fetch memory accesse big-endian enable flag */
- rv_csr_t mbe:1; /*!< bit: 37 M-mode non-instruction-fetch memory accesse big-endian enable flag */
- rv_csr_t gva:1; /*!< bit: 38 Guest Virtual Address */
- rv_csr_t mpv:1; /*!< bit: 39 Machine Previous Virtualization Mode */
- rv_csr_t _reserved4:1; /*!< bit: 40 Reserved */
- rv_csr_t mpelp:1; /*!< bit: 41 Machine mode Previous Expected Landing Pad (ELP) State */
- rv_csr_t mdt:1; /*!< bit: 42 M-mode-disable-trap */
- rv_csr_t _reserved5:20; /*!< bit: 43..62 Reserved */
- rv_csr_t sd:1; /*!< bit: 63 Dirty status for XS or FS */
- #else
- rv_csr_t _reserved3:6; /*!< bit: 25..30 Reserved */
- rv_csr_t sd:1; /*!< bit: 31 Dirty status for XS or FS */
- #endif
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MSTATUS_Type;
- #if defined(__RISCV_XLEN) && __RISCV_XLEN == 32
- /**
- * \brief Union type to access MSTATUSH CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:4; /*!< bit: 0..3 Reserved */
- rv_csr_t sbe:1; /*!< bit: 4 S-mode non-instruction-fetch memory accesse big-endian enable flag */
- rv_csr_t mbe:1; /*!< bit: 5 M-mode non-instruction-fetch memory accesse big-endian enable flag */
- rv_csr_t gva:1; /*!< bit: 6 Guest Virtual Address */
- rv_csr_t mpv:1; /*!< bit: 7 Machine Previous Virtualization Mode */
- rv_csr_t _reserved1:1; /*!< bit: 8 Reserved */
- rv_csr_t mpelp:1; /*!< bit: 9 Machine mode Previous Expected Landing Pad (ELP) State */
- rv_csr_t mdt:1; /*!< bit: 10 M-mode-disable-trap */
- rv_csr_t _reserved5:21; /*!< bit: 11..31 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MSTATUSH_Type;
- #endif
- /**
- * \brief Union type to access MTVEC CSR register.
- */
- typedef union {
- struct {
- rv_csr_t mode:6; /*!< bit: 0..5 interrupt mode control */
- rv_csr_t addr:__RISCV_XLEN-6; /*!< bit: 6..XLEN-1 mtvec address */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MTVEC_Type;
- /**
- * \brief Union type to access MCAUSE CSR register.
- */
- typedef union {
- struct {
- rv_csr_t exccode:12; /*!< bit: 0..11 exception or interrupt code */
- rv_csr_t _reserved0:4; /*!< bit: 12..15 Reserved */
- rv_csr_t mpil:8; /*!< bit: 16..23 Previous interrupt level */
- rv_csr_t _reserved1:3; /*!< bit: 24..26 Reserved */
- rv_csr_t mpie:1; /*!< bit: 27 Interrupt enable flag before enter interrupt */
- rv_csr_t mpp:2; /*!< bit: 28..29 Privilede mode flag before enter interrupt */
- rv_csr_t minhv:1; /*!< bit: 30 Machine interrupt vector table */
- #if defined(__RISCV_XLEN) && __RISCV_XLEN == 64
- rv_csr_t _reserved2:__RISCV_XLEN-32; /*!< bit: 31..XLEN-2 Reserved */
- #endif
- rv_csr_t interrupt:1; /*!< bit: XLEN-1 trap type. 0 means exception and 1 means interrupt */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MCAUSE_Type;
- /**
- * \brief Union type to access MCOUNTINHIBIT CSR register.
- */
- typedef union {
- struct {
- rv_csr_t cy:1; /*!< bit: 0 1 means disable mcycle counter */
- rv_csr_t _reserved0:1; /*!< bit: 1 Reserved */
- rv_csr_t ir:1; /*!< bit: 2 1 means disable minstret counter */
- rv_csr_t _reserved1:__RISCV_XLEN-3; /*!< bit: 3..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MCOUNTINHIBIT_Type;
- /**
- * \brief Union type to access MSUBM CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:6; /*!< bit: 0..5 Reserved 0 */
- rv_csr_t typ:2; /*!< bit: 6..7 Current sub-mode:
- 0: Normal Machine Mode;
- 1: Interrupt Handling Mode;
- 2: Exception Handing Mode;
- 3: NMI Handing Mode. */
- rv_csr_t ptyp:2; /*!< bit: 8..9 sub-mode before entering the trap:
- 0: Normal Machine Mode;
- 1: Interrupt Handling Mode;
- 2: Exception Handing Mode;
- 3: NMI Handing Mode. */
- rv_csr_t gpridx:5; /*!< bit: 10..14 Current Register Group Select */
- rv_csr_t pgpridx:5; /*!< bit: 15..19 Previous Register Group Select */
- rv_csr_t _reserved1:__RISCV_XLEN-20; /*!< bit: 20..XLEN-1 Reserved 0 */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MSUBM_Type;
- /**
- * \brief Union type to access MDCAUSE CSR register.
- */
- typedef union {
- struct {
- rv_csr_t mdcause:3; /*!< bit: 0..2 More detailed exception information as MCAUSE supplement */
- rv_csr_t _reserved0:__RISCV_XLEN-3; /*!< bit: 3..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MDCAUSE_Type;
- /**
- * \brief Union type to access MMISC_CTRL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:1; /*!< bit: 0 Reserved */
- rv_csr_t zclsd_en:1; /*!< bit: 1 Control the Zclsd will uses the Zcf extension encoding or not */
- rv_csr_t _reserved1:1; /*!< bit: 2 Reserved */
- rv_csr_t bpu:1; /*!< bit: 3 dynamic prediction enable flag */
- rv_csr_t _reserved2:2; /*!< bit: 4..5 Reserved */
- rv_csr_t misalign:1; /*!< bit: 6 misaligned access support flag */
- rv_csr_t zcmt_zcmp:1; /*!< bit: 7 Zc Ext uses the cfdsp of D Ext's encoding or not */
- rv_csr_t core_buserr:1; /*!< bit: 8 core bus error exception or interrupt */
- rv_csr_t nmi_cause:1; /*!< bit: 9 mnvec control and nmi mcase exccode */
- rv_csr_t imreturn_en:1; /*!< bit: 10 IMRETURN mode of trace */
- rv_csr_t sijump_en:1; /*!< bit: 11 SIJUMP mode of trace */
- rv_csr_t ldspec_en:1; /*!< bit: 12 enable load speculative goes to mem interface */
- rv_csr_t _reserved3:1; /*!< bit: 13 Reserved */
- rv_csr_t dbg_sec:1; /*!< bit: 14 debug access mode, removed in latest releases */
- rv_csr_t _reserved4:2; /*!< bit: 15..16 Reserved */
- rv_csr_t csr_excl_enable:1; /*!< bit: 17 Exclusive instruction(lr,sc) on Non-cacheable/Device memory can send exclusive flag in memory bus */
- rv_csr_t _reserved5:2; /*!< bit: 18..19 Reserved */
- rv_csr_t lsu_allow_diff_en:1; /*!< bit: 20 LSU access allows the next operation can outstanding transactions when the current transaction has not been completed */
- rv_csr_t hw_auto_context:1; /*!< bit: 21 Hardware auto context saving and restoring enable */
- rv_csr_t _reserved6:__RISCV_XLEN-22; /*!< bit: 22..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MMISCCTRL_Type;
- typedef CSR_MMISCCTRL_Type CSR_MMISCCTL_Type;
- typedef CSR_MMISCCTRL_Type CSR_MMISC_CTL_Type;
- /**
- * \brief Union type to access MMISC_CTL1 CSR register.
- */
- typedef union {
- struct {
- rv_csr_t fp16mode:1; /*!< bit: 0 16 bit float precision mode */
- rv_csr_t vlsu_ooo_4k_mode:1; /*!< bit: 1 Control the size of address check region for vlsu ooo */
- rv_csr_t vlsu_ooo_force_va_4k:1; /*!< bit: 2 Control the size of virtual address check region for vlsu ooo */
- rv_csr_t vlsu_ooo_en:1; /*!< bit: 3 Control the enable of vlsu ooo feature */
- rv_csr_t vlsu_cof_en:1; /*!< bit: 4 Control the enable of vlsu check-only first feature */
- rv_csr_t vlm_path_en:1; /*!< bit: 5 Control vlm dedicated path enable */
- rv_csr_t rvv_v1_0_cmpt:1; /*!< bit: 6 Control some vpu instruction behaviour is compatible with rvv1.0 */
- rv_csr_t _reserved0:__RISCV_XLEN-7; /*!< bit: 7..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MMISC_CTL1_Type;
- /**
- * \brief Union type to access MCACHE_CTL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t ic_en:1; /*!< bit: 0 I-Cache enable */
- rv_csr_t ic_scpd_mod:1; /*!< bit: 1 Scratchpad mode, 0: Scratchpad as ICache Data RAM, 1: Scratchpad as ILM SRAM */
- rv_csr_t ic_ecc_en:1; /*!< bit: 2 I-Cache ECC enable */
- rv_csr_t ic_ecc_excp_en:1; /*!< bit: 3 I-Cache 2bit ECC error exception enable */
- rv_csr_t ic_rwtecc:1; /*!< bit: 4 Control I-Cache Tag Ram ECC code injection */
- rv_csr_t ic_rwdecc:1; /*!< bit: 5 Control I-Cache Data Ram ECC code injection */
- rv_csr_t ic_pf_en:1; /*!< bit: 6 I-Cache prefetch enable */
- rv_csr_t ic_cancel_en:1; /*!< bit: 7 I-Cache change flow canceling enable control */
- rv_csr_t ic_ecc_chk_en:1; /*!< bit: 8 I-Cache check ECC codes enable */
- rv_csr_t ic_prefetch_en:1; /*!< bit: 9 I-Cache CMO prefetch enable control */
- rv_csr_t ic_burst_type:1; /*!< bit: 10 I-Cache Burst type control */
- rv_csr_t _reserved0:5; /*!< bit: 11..15 Reserved */
- rv_csr_t dc_en:1; /*!< bit: 16 DCache enable */
- rv_csr_t dc_ecc_en:1; /*!< bit: 17 D-Cache ECC enable */
- rv_csr_t dc_ecc_excp_en:1; /*!< bit: 18 D-Cache 2bit ECC error exception enable */
- rv_csr_t dc_rwtecc:1; /*!< bit: 19 Control D-Cache Tag Ram ECC code injection */
- rv_csr_t dc_rwdecc:1; /*!< bit: 20 Control D-Cache Data Ram ECC code injection */
- rv_csr_t dc_ecc_chk_en:1; /*!< bit: 21 D-Cache check ECC codes enable */
- rv_csr_t dc_prefetch_en:1; /*!< bit: 22 D-Cache CMO prefetch enable control */
- rv_csr_t dc_burst_type:1; /*!< bit: 23 D-Cache Burst type control */
- rv_csr_t _reserved1:__RISCV_XLEN-24; /*!< bit: 24..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MCACHECTL_Type;
- typedef CSR_MCACHECTL_Type CSR_MCACHE_CTL_Type;
- /**
- * \brief Union type to access MSAVESTATUS CSR register.
- */
- typedef union {
- struct {
- rv_csr_t mpie1:1; /*!< bit: 0 interrupt enable flag of fisrt level NMI/exception nestting */
- rv_csr_t mpp1:2; /*!< bit: 1..2 privilede mode of fisrt level NMI/exception nestting */
- rv_csr_t _reserved0:3; /*!< bit: 3..5 Reserved */
- rv_csr_t ptyp1:2; /*!< bit: 6..7 NMI/exception type of before first nestting */
- rv_csr_t mpie2:1; /*!< bit: 8 interrupt enable flag of second level NMI/exception nestting */
- rv_csr_t mpp2:2; /*!< bit: 9..10 privilede mode of second level NMI/exception nestting */
- rv_csr_t _reserved1:3; /*!< bit: 11..13 Reserved */
- rv_csr_t ptyp2:2; /*!< bit: 14..15 NMI/exception type of before second nestting */
- rv_csr_t _reserved2:__RISCV_XLEN-16; /*!< bit: 16..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t w; /*!< Type used for csr data access */
- } CSR_MSAVESTATUS_Type;
- /**
- * \brief Union type to access MILM_CTL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t ilm_en:1; /*!< bit: 0 ILM enable */
- rv_csr_t ilm_ecc_en:1; /*!< bit: 1 ILM ECC eanble */
- rv_csr_t ilm_ecc_excp_en:1; /*!< bit: 2 ILM ECC exception enable */
- rv_csr_t ilm_rwecc:1; /*!< bit: 3 Control mecc_code write to ilm, simulate error injection */
- rv_csr_t ilm_ecc_chk_en:1; /*!< bit: 4 ILM check ECC codes enable */
- rv_csr_t ilm_va_en:1; /*!< bit: 5 Using virtual address to judge ILM access */
- rv_csr_t dis_lsu_ilm:1; /*!< bit: 6 Disable lsu access ILM */
- rv_csr_t _reserved0:3; /*!< bit: 7..9 Reserved */
- rv_csr_t ilm_bpa:__RISCV_XLEN-10; /*!< bit: 10..XLEN-1 ILM base physical address */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MILMCTL_Type;
- typedef CSR_MILMCTL_Type CSR_MILM_CTL_Type;
- /**
- * \brief Union type to access MDLM_CTL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t dlm_en:1; /*!< bit: 0 DLM enable */
- rv_csr_t dlm_ecc_en:1; /*!< bit: 1 DLM ECC eanble */
- rv_csr_t dlm_ecc_excp_en:1; /*!< bit: 2 DLM ECC exception enable */
- rv_csr_t dlm_rwecc:1; /*!< bit: 3 Control mecc_code write to dlm, simulate error injection */
- rv_csr_t dlm_ecc_chk_en:1; /*!< bit: 4 DLM check ECC codes enable */
- rv_csr_t dlm_va_en:1; /*!< bit: 5 Using virtual address to judge DLM access */
- rv_csr_t dis_lsu_dlm:1; /*!< bit: 6 Disable LSU access DLM */
- rv_csr_t _reserved0:3; /*!< bit: 7..9 Reserved */
- rv_csr_t dlm_bpa:__RISCV_XLEN-10; /*!< bit: 10..XLEN-1 DLM base address */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MDLMCTL_Type;
- typedef CSR_MDLMCTL_Type CSR_DILM_CTL_Type;
- /**
- * \brief Union type to access MCFG_INFO CSR register.
- */
- typedef union {
- struct {
- rv_csr_t tee:1; /*!< bit: 0 TEE present */
- rv_csr_t ecc:1; /*!< bit: 1 ECC present */
- rv_csr_t clic:1; /*!< bit: 2 CLIC present */
- rv_csr_t plic:1; /*!< bit: 3 PLIC present */
- rv_csr_t fio:1; /*!< bit: 4 FIO present */
- rv_csr_t ppi:1; /*!< bit: 5 PPI present */
- rv_csr_t nice:1; /*!< bit: 6 NICE present */
- rv_csr_t ilm:1; /*!< bit: 7 ILM present */
- rv_csr_t dlm:1; /*!< bit: 8 DLM present */
- rv_csr_t icache:1; /*!< bit: 9 ICache present */
- rv_csr_t dcache:1; /*!< bit: 10 DCache present */
- rv_csr_t smp:1; /*!< bit: 11 SMP present */
- rv_csr_t dsp_n1:1; /*!< bit: 12 DSP N1 present */
- rv_csr_t dsp_n2:1; /*!< bit: 13 DSP N2 present */
- rv_csr_t dsp_n3:1; /*!< bit: 14 DSP N3 present */
- rv_csr_t zc_xlcz:1; /*!< bit: 15 Zc and xlcz extension present */
- rv_csr_t iregion:1; /*!< bit: 16 IREGION present */
- rv_csr_t vpu_degree:2; /*!< bit: 17..18 Indicate the VPU degree of parallel */
- rv_csr_t sec_mode:1; /*!< bit: 19 Smwg extension present */
- rv_csr_t etrace:1; /*!< bit: 20 Etrace present */
- rv_csr_t safety_mecha:2; /*!< bit: 21..22 Indicate Core's safety mechanism */
- rv_csr_t vnice:1; /*!< bit: 23 VNICE present */
- rv_csr_t xlcz:1; /*!< bit: 24 XLCZ extension present */
- rv_csr_t zilsd:1; /*!< bit: 25 Zilsd/Zclsd extension present */
- rv_csr_t sstc:1; /*!< bit: 26 SSTC extension present */
- rv_csr_t _reserved1:__RISCV_XLEN-27; /*!< bit: 27..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MCFGINFO_Type;
- typedef CSR_MCFGINFO_Type CSR_MCFG_INFO_Type;
- /**
- * \brief Union type to access MICFG_INFO CSR register.
- */
- typedef union {
- struct {
- rv_csr_t set:4; /*!< bit: 0..3 I-Cache sets per way */
- rv_csr_t way:3; /*!< bit: 4..6 I-Cache way */
- rv_csr_t lsize:3; /*!< bit: 7..9 I-Cache line size */
- rv_csr_t ecc:1; /*!< bit: 10 I-Cache ECC support */
- rv_csr_t _reserved0:5; /*!< bit: 11..15 Reserved */
- rv_csr_t lm_size:5; /*!< bit: 16..20 ILM size, need to be 2^n size */
- rv_csr_t lm_xonly:1; /*!< bit: 21 ILM Execute only permission or Reserved */
- rv_csr_t lm_ecc:1; /*!< bit: 22 ILM ECC support */
- rv_csr_t _reserved1:__RISCV_XLEN-23; /*!< bit: 23..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MICFGINFO_Type;
- typedef CSR_MICFGINFO_Type CSR_MICFG_INFO_Type;
- /**
- * \brief Union type to access MDCFG_INFO CSR register.
- */
- typedef union {
- struct {
- rv_csr_t set:4; /*!< bit: 0..3 D-Cache sets per way */
- rv_csr_t way:3; /*!< bit: 4..6 D-Cache way */
- rv_csr_t lsize:3; /*!< bit: 7..9 D-Cache line size */
- rv_csr_t ecc:1; /*!< bit: 10 D-Cache ECC support */
- rv_csr_t _reserved0:5; /*!< bit: 11..15 Reserved */
- rv_csr_t lm_size:5; /*!< bit: 16..20 DLM size, need to be 2^n size */
- rv_csr_t lm_ecc:1; /*!< bit: 21 DLM ECC present */
- rv_csr_t _reserved1:__RISCV_XLEN-22; /*!< bit: 22..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MDCFGINFO_Type;
- typedef CSR_MDCFGINFO_Type CSR_MDCFG_INFO_Type;
- /**
- * \brief Union type to access MTLBCFG_INFO CSR register.
- * NOTE: the MTLBCFG_INFO CSR supports two different mapping layouts.
- * Use the `b.mapping` or `nb.mapping` field to determine the active
- * mapping type. If `mapping` field is set, use the `nb` structure for
- * field access. Otherwise, use the `b` structure for field access.
- */
- typedef union {
- struct {
- rv_csr_t set:4; /*!< bit: 0..3 Main TLB entry per way */
- rv_csr_t way:3; /*!< bit: 4..6 Main TLB ways */
- rv_csr_t lsize:3; /*!< bit: 7..9 Main TLB line size or Reserved */
- rv_csr_t ecc:1; /*!< bit: 10 Main TLB supports ECC or not */
- rv_csr_t napot:1; /*!< bit: 11 TLB supports Svnapot or not */
- rv_csr_t _reserved1:4; /*!< bit: 12..15 Reserved 0 */
- rv_csr_t i_size:3; /*!< bit: 16..18 ITLB size */
- rv_csr_t d_size:3; /*!< bit: 19..21 DTLB size */
- rv_csr_t _reserved2:__RISCV_XLEN-23; /*!< bit: 22..XLEN-2 Reserved 0 */
- rv_csr_t mapping:1; /*!< bit: XLEN-1 mapping type */
- } b; /*!< Structure used for bit access */
- struct {
- rv_csr_t set:4; /*!< bit: 0..3 Main TLB entry per way */
- rv_csr_t way:3; /*!< bit: 4..6 Main TLB ways */
- rv_csr_t lsize:3; /*!< bit: 7..9 Main TLB line size or Reserved */
- rv_csr_t ecc:1; /*!< bit: 10 Main TLB supports ECC or not */
- rv_csr_t napot:1; /*!< bit: 11 TLB supports Svnapot or not */
- rv_csr_t i_size:7; /*!< bit: 12..18 ITLB size */
- rv_csr_t d_size:8; /*!< bit: 19..26 DTLB size */
- rv_csr_t _reserved0:__RISCV_XLEN-28; /*!< bit: 27..XLEN-2 Reserved 0 */
- rv_csr_t mapping:1; /*!< bit: XLEN-1 TLB mapping type */
- } nb; /*!< Structure used for new mapping bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MTLBCFGINFO_Type;
- typedef CSR_MTLBCFGINFO_Type CSR_MTLBCFG_INFO_Type;
- /**
- * \brief Union type to access MPPICFG_INFO CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:1; /*!< bit: 0 Reserved 1 */
- rv_csr_t ppi_size:5; /*!< bit: 1..5 PPI size, need to be 2^n size */
- rv_csr_t _reserved1:3; /*!< bit: 6..8 Reserved 0 */
- rv_csr_t ppi_en:1; /*!< bit: 9 PPI Enable. Software can write this bit to control PPI */
- rv_csr_t ppi_bpa:__RISCV_XLEN-10; /*!< bit: 10..XLEN-1 PPI base address */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MPPICFGINFO_Type;
- typedef CSR_MPPICFGINFO_Type CSR_MPPICFG_INFO_Type;
- /**
- * \brief Union type to access MFIOCFG_INFO CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:1; /*!< bit: 0 Reserved */
- rv_csr_t fio_size:5; /*!< bit: 1..5 FIO size, need to be 2^n size */
- rv_csr_t _reserved1:4; /*!< bit: 6..9 Reserved */
- rv_csr_t fio_bpa:__RISCV_XLEN-10; /*!< bit: 10..XLEN-1 FIO base address */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MFIOCFGINFO_Type;
- typedef CSR_MFIOCFGINFO_Type CSR_MFIOCFG_INFO_Type;
- /**
- * \brief Union type to access MECC_LOCK CSR register.
- */
- typedef union {
- struct {
- rv_csr_t ecc_lock:1; /*!< bit: 0 RW permission, ECC Lock configure */
- rv_csr_t _reserved0:__RISCV_XLEN-1; /*!< bit: 1..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MECCLOCK_Type;
- typedef CSR_MECCLOCK_Type CSR_MECC_LOCK_Type;
- /**
- * \brief Union type to access MECC_CODE CSR register.
- */
- typedef union {
- struct {
- rv_csr_t code:9; /*!< bit: 0..8 Used to inject ECC check code */
- rv_csr_t _reserved0:7; /*!< bit: 9..15 Reserved 0 */
- rv_csr_t ramid:5; /*!< bit: 16..20 The ID of RAM that has 2bit ECC error, software can clear these bits */
- rv_csr_t _reserved1:3; /*!< bit: 21..23 Reserved 0 */
- rv_csr_t sramid:5; /*!< bit: 24..28 The ID of RAM that has 1bit ECC error, software can clear these bits */
- rv_csr_t _reserved2:2; /*!< bit: 29..30 Reserved 0 */
- rv_csr_t ecc_inj_mode:1; /*!< bit: 31 ECC injection mode */
- #if __RISCV_XLEN == 64
- rv_csr_t _reserved3:__RISCV_XLEN-32; /*!< bit: 32..XLEN-1 Reserved 0 */
- #endif
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MECCCODE_Type;
- typedef CSR_MECCCODE_Type CSR_MECC_CODE_Type;
- /**
- * \brief Union type to access MECC_CTL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t ilm_fch_msk:1; /*!< bit: 0 Write 1 to disable aggregate ILM fetch ECC fatal error to safety_error output */
- rv_csr_t ilm_acc_msk:1; /*!< bit: 1 Write 1 to disable aggregate ILM load/store access ECC fatal error to safety_error output */
- rv_csr_t dlm_acc_msk:1; /*!< bit: 2 Write 1 to disable aggregate DLM access ECC fatal error to safety_error output */
- rv_csr_t ic_fch_msk:1; /*!< bit: 3 Write 1 to disable aggregate ICache fetch ECC fatal error to safety_error output */
- rv_csr_t dc_acc_msk:1; /*!< bit: 4 Write 1 to disable aggregate DCache access ECC fatal error to safety_error output */
- rv_csr_t ilm_ext_msk:1; /*!< bit: 5 Write 1 to disable aggregate ILM external access ECC fatal error to safety_error output */
- rv_csr_t dlm_ext_msk:1; /*!< bit: 6 Write 1 to disable aggregate DLM external access ECC fatal error to safety_error output */
- rv_csr_t ic_ccm_msk:1; /*!< bit: 7 Write 1 to disable aggregate ICache CCM ECC fatal error to safety_error output */
- rv_csr_t dc_ccm_msk:1; /*!< bit: 8 Write 1 to disable aggregate DCache CCM ECC fatal error to safety_error output */
- rv_csr_t dc_cpbk_msk:1; /*!< bit: 9 Write 1 to disable aggregate DCache CPBK ECC fatal error to safety_error output */
- rv_csr_t _reserved0:21; /*!< bit: 10..30 Reserved 0 */
- rv_csr_t io_prot_chk_en:1; /*!< bit: 31 Controls to check the IO interface */
- #if defined(__RISCV_XLEN) && __RISCV_XLEN == 64
- rv_csr_t _reserved1:__RISCV_XLEN-32; /*!< bit: 32..63 Reserved 0 */
- #endif
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MECC_CTL_Type;
- /**
- * \brief Union type to access MECC_STATUS CSR register.
- */
- typedef union {
- struct {
- rv_csr_t ilm_fch_err:1; /*!< bit: 0 ILM fetch ECC fatal error has occurred */
- rv_csr_t ilm_acc_err:1; /*!< bit: 1 ILM load/store access ECC fatal error has occurred */
- rv_csr_t dlm_acc_err:1; /*!< bit: 2 DLM access ECC fatal error has occurred */
- rv_csr_t ic_fch_err:1; /*!< bit: 3 ICache fetch ECC fatal error has occurred */
- rv_csr_t dc_acc_err:1; /*!< bit: 4 DCache access ECC fatal error has occurred */
- rv_csr_t ilm_ext_err:1; /*!< bit: 5 ILM external access ECC fatal error has occurred */
- rv_csr_t dlm_ext_err:1; /*!< bit: 6 DLM external access ECC fatal error has occurred */
- rv_csr_t ic_ccm_err:1; /*!< bit: 7 ICache CCM ECC fatal error has occurred */
- rv_csr_t dc_ccm_err:1; /*!< bit: 8 DCache CCM ECC fatal error has occurred */
- rv_csr_t dc_cpbk_err:1; /*!< bit: 9 DCache CPBK ECC fatal error has occurred */
- rv_csr_t _reserved0:__RISCV_XLEN-10; /*!< bit: 10..XLEN-1 Reserved 0 */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MECC_STATUS_Type;
- /**
- * \brief Union type to access MIRGB_INFO CSR register.
- */
- typedef union {
- struct {
- rv_csr_t _reserved0:1; /*!< bit: 0 Reserved */
- rv_csr_t iregion_size:5; /*!< bit: 1..5 Indicates the size of IREGION and it should be power of 2 */
- rv_csr_t _reserved1:4; /*!< bit: 6..9 Reserved */
- rv_csr_t iregion_base:__RISCV_XLEN-10; /*!< bit: 10..PA_SIZE IREGION Base Address */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MIRGB_INFO_Type;
- /**
- * \brief Union type to access MSTACK_CTL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t ovf_track_en:1; /*!< bit: 0 Stack overflow check or track enable */
- rv_csr_t udf_en:1; /*!< bit: 1 Stack underflow check enable */
- rv_csr_t mode:1; /*!< bit: 2 Mode of stack checking */
- rv_csr_t _reserved0:__RISCV_XLEN-3; /*!< bit: 3..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MSTACK_CTL_Type;
- /**
- * \brief Union type to access MTLB_CTL CSR register.
- */
- typedef union {
- struct {
- rv_csr_t tlb_ecc_en:1; /*!< bit: 0 MTLB ECC eanble */
- rv_csr_t tlb_ecc_excp_en:1; /*!< bit: 1 MTLB double bit ECC exception enable control */
- rv_csr_t tlb_tram_ecc_inj_en:1; /*!< bit: 2 Controls to inject the ECC Code in CSR mecc_code to MTLB tag rams */
- rv_csr_t tlb_dram_ecc_inj_en:1; /*!< bit: 3 Controls to inject the ECC Code in CSR mecc_code to MTLB data rams */
- rv_csr_t _reserved0:2; /*!< bit: 4..5 Reserved */
- rv_csr_t tlb_ecc_chk_en:1; /*!< bit: 6 Controls to check the ECC when core access to MTLB */
- rv_csr_t napot_en:1; /*!< bit: 7 NAPOT page enable */
- rv_csr_t _reserved1:__RISCV_XLEN-8; /*!< bit: 8..XLEN-1 Reserved */
- } b; /*!< Structure used for bit access */
- rv_csr_t d; /*!< Type used for csr data access */
- } CSR_MTLB_CTL_Type;
- /** @} */ /* End of Doxygen Group NMSIS_Core_Base_Registers */
- /* ########################### Core Function Access ########################### */
- /**
- * \defgroup NMSIS_Core_CSR_Register_Access Core CSR Register Access
- * \ingroup NMSIS_Core
- * \brief Functions to access the Core CSR Registers
- * \details
- *
- * The following functions or macros provide access to Core CSR registers.
- * - \ref NMSIS_Core_CSR_Encoding
- * - \ref NMSIS_Core_CSR_Registers
- * @{
- */
- #ifndef __ASSEMBLER__
- #ifndef __ICCRISCV__
- /**
- * \brief CSR operation Macro for csrrw instruction.
- * \details
- * Read the content of csr register to __v,
- * then write content of val into csr register, then return __v
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \param val value to store into the CSR register
- * \return the CSR register value before written
- */
- #define __RV_CSR_SWAP(csr, val) \
- ({ \
- rv_csr_t __v = (unsigned long)(val); \
- __ASM volatile("csrrw %0, " STRINGIFY(csr) ", %1" \
- : "=r"(__v) \
- : "rK"(__v) \
- : "memory"); \
- __v; \
- })
- /**
- * \brief CSR operation Macro for csrr instruction.
- * \details
- * Read the content of csr register to __v and return it
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \return the CSR register value
- */
- #define __RV_CSR_READ(csr) \
- ({ \
- rv_csr_t __v; \
- __ASM volatile("csrr %0, " STRINGIFY(csr) \
- : "=r"(__v) \
- : \
- : "memory"); \
- __v; \
- })
- /**
- * \brief CSR operation Macro for csrw instruction.
- * \details
- * Write the content of val to csr register
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \param val value to store into the CSR register
- */
- #define __RV_CSR_WRITE(csr, val) \
- ({ \
- rv_csr_t __v = (rv_csr_t)(val); \
- __ASM volatile("csrw " STRINGIFY(csr) ", %0" \
- : \
- : "rK"(__v) \
- : "memory"); \
- })
- /**
- * \brief CSR operation Macro for csrrs instruction.
- * \details
- * Read the content of csr register to __v,
- * then set csr register to be __v | val, then return __v
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \param val Mask value to be used wih csrrs instruction
- * \return the CSR register value before written
- */
- #define __RV_CSR_READ_SET(csr, val) \
- ({ \
- rv_csr_t __v = (rv_csr_t)(val); \
- __ASM volatile("csrrs %0, " STRINGIFY(csr) ", %1" \
- : "=r"(__v) \
- : "rK"(__v) \
- : "memory"); \
- __v; \
- })
- /**
- * \brief CSR operation Macro for csrs instruction.
- * \details
- * Set csr register to be csr_content | val
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \param val Mask value to be used wih csrs instruction
- */
- #define __RV_CSR_SET(csr, val) \
- ({ \
- rv_csr_t __v = (rv_csr_t)(val); \
- __ASM volatile("csrs " STRINGIFY(csr) ", %0" \
- : \
- : "rK"(__v) \
- : "memory"); \
- })
- /**
- * \brief CSR operation Macro for csrrc instruction.
- * \details
- * Read the content of csr register to __v,
- * then set csr register to be __v & ~val, then return __v
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \param val Mask value to be used wih csrrc instruction
- * \return the CSR register value before written
- */
- #define __RV_CSR_READ_CLEAR(csr, val) \
- ({ \
- rv_csr_t __v = (rv_csr_t)(val); \
- __ASM volatile("csrrc %0, " STRINGIFY(csr) ", %1" \
- : "=r"(__v) \
- : "rK"(__v) \
- : "memory"); \
- __v; \
- })
- /**
- * \brief CSR operation Macro for csrc instruction.
- * \details
- * Set csr register to be csr_content & ~val
- * \param csr CSR macro definition defined in
- * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS
- * \param val Mask value to be used wih csrc instruction
- */
- #define __RV_CSR_CLEAR(csr, val) \
- ({ \
- rv_csr_t __v = (rv_csr_t)(val); \
- __ASM volatile("csrc " STRINGIFY(csr) ", %0" \
- : \
- : "rK"(__v) \
- : "memory"); \
- })
- #else
- #include <intrinsics.h>
- #define __RV_CSR_SWAP __write_csr
- #define __RV_CSR_READ __read_csr
- #define __RV_CSR_WRITE __write_csr
- #define __RV_CSR_READ_SET __set_bits_csr
- #define __RV_CSR_SET __set_bits_csr
- #define __RV_CSR_READ_CLEAR __clear_bits_csr
- #define __RV_CSR_CLEAR __clear_bits_csr
- #endif /* __ICCRISCV__ */
- #endif /* __ASSEMBLER__ */
- /**
- * \brief Execute fence instruction, p -> pred, s -> succ
- * \details
- * the FENCE instruction ensures that all memory accesses from instructions preceding
- * the fence in program order (the `predecessor set`) appear earlier in the global memory order than
- * memory accesses from instructions appearing after the fence in program order (the `successor set`).
- * For details, please refer to The RISC-V Instruction Set Manual
- * \param p predecessor set, such as iorw, rw, r, w
- * \param s successor set, such as iorw, rw, r, w
- **/
- #define __FENCE(p, s) __ASM volatile ("fence " #p "," #s : : : "memory")
- /**
- * \brief Fence.i Instruction
- * \details
- * The FENCE.I instruction is used to synchronize the instruction
- * and data streams.
- */
- __STATIC_FORCEINLINE void __FENCE_I(void)
- {
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- #else
- __ASM volatile("fence.i");
- #endif
- }
- /** \brief Read & Write Memory barrier */
- #define __RWMB() __FENCE(iorw,iorw)
- /** \brief Read Memory barrier */
- #define __RMB() __FENCE(ir,ir)
- /** \brief Write Memory barrier */
- #define __WMB() __FENCE(ow,ow)
- /** \brief SMP Read & Write Memory barrier */
- #define __SMP_RWMB() __FENCE(rw,rw)
- /** \brief SMP Read Memory barrier */
- #define __SMP_RMB() __FENCE(r,r)
- /** \brief SMP Write Memory barrier */
- #define __SMP_WMB() __FENCE(w,w)
- /** \brief CPU relax for busy loop */
- #define __CPU_RELAX() __ASM volatile ("" : : : "memory")
- /**
- * \brief switch privilege from machine mode to others.
- * \details
- * Execute into \ref entry_point in \ref mode(supervisor or user) with given stack
- * \param mode privilege mode
- * \param stack predefined stack, size should set enough
- * \param entry_point a function pointer to execute
- */
- __STATIC_INLINE void __switch_mode(uint8_t mode, uintptr_t stack, void(*entry_point)(void))
- {
- unsigned long val = 0;
- /* Set MPP to the requested privilege mode */
- val = __RV_CSR_READ(CSR_MSTATUS);
- val = __RV_INSERT_FIELD(val, MSTATUS_MPP, mode);
- /* Set previous MIE disabled */
- val = __RV_INSERT_FIELD(val, MSTATUS_MPIE, 0);
- __RV_CSR_WRITE(CSR_MSTATUS, val);
- /* Set the entry point in MEPC */
- __RV_CSR_WRITE(CSR_MEPC, (unsigned long)entry_point);
- /* Set the register file */
- __ASM volatile("mv sp, %0" ::"r"(stack));
- __ASM volatile("mret");
- }
- /**
- * \brief Enable IRQ Interrupts
- * \details Enables IRQ interrupts by setting the MIE-bit in the MSTATUS Register.
- * \remarks
- * Can only be executed in Privileged modes.
- */
- __STATIC_FORCEINLINE void __enable_irq(void)
- {
- __RV_CSR_SET(CSR_MSTATUS, MSTATUS_MIE);
- }
- /**
- * \brief Disable IRQ Interrupts
- * \details Disables IRQ interrupts by clearing the MIE-bit in the MSTATUS Register.
- * \remarks
- * Can only be executed in Privileged modes.
- */
- __STATIC_FORCEINLINE void __disable_irq(void)
- {
- __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MIE);
- }
- /**
- * \brief Enable External IRQ Interrupts
- * \details Enables External IRQ interrupts by setting the MEIE-bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_ext_irq(void)
- {
- __RV_CSR_SET(CSR_MIE, MIE_MEIE);
- }
- /**
- * \brief Disable External IRQ Interrupts
- * \details Disables External IRQ interrupts by clearing the MEIE-bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_ext_irq(void)
- {
- __RV_CSR_CLEAR(CSR_MIE, MIE_MEIE);
- }
- /**
- * \brief Enable Timer IRQ Interrupts
- * \details Enables Timer IRQ interrupts by setting the MTIE-bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_timer_irq(void)
- {
- __RV_CSR_SET(CSR_MIE, MIE_MTIE);
- }
- /**
- * \brief Disable Timer IRQ Interrupts
- * \details Disables Timer IRQ interrupts by clearing the MTIE-bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_timer_irq(void)
- {
- __RV_CSR_CLEAR(CSR_MIE, MIE_MTIE);
- }
- /**
- * \brief Enable software IRQ Interrupts
- * \details Enables software IRQ interrupts by setting the MSIE-bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_sw_irq(void)
- {
- __RV_CSR_SET(CSR_MIE, MIE_MSIE);
- }
- /**
- * \brief Disable software IRQ Interrupts
- * \details Disables software IRQ interrupts by clearing the MSIE-bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_sw_irq(void)
- {
- __RV_CSR_CLEAR(CSR_MIE, MIE_MSIE);
- }
- /**
- * \brief Disable Core IRQ Interrupt
- * \details Disable Core IRQ interrupt by clearing the irq bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_core_irq(uint32_t irq)
- {
- __RV_CSR_CLEAR(CSR_MIE, 1UL << irq);
- }
- /**
- * \brief Enable Core IRQ Interrupt
- * \details Enable Core IRQ interrupt by setting the irq bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_core_irq(uint32_t irq)
- {
- __RV_CSR_SET(CSR_MIE, 1UL << irq);
- }
- /**
- * \brief Get Core IRQ Interrupt Pending status
- * \details Get Core IRQ interrupt pending status of irq bit.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE uint32_t __get_core_irq_pending(uint32_t irq)
- {
- return ((__RV_CSR_READ(CSR_MIP) >> irq) & 0x1);
- }
- /**
- * \brief Clear Core IRQ Interrupt Pending status
- * \details Clear Core IRQ interrupt pending status of irq bit.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __clear_core_irq_pending(uint32_t irq)
- {
- __RV_CSR_CLEAR(CSR_MIP, 1UL << irq);
- }
- /**
- * \brief Enable IRQ Interrupts in supervisor mode
- * \details Enables IRQ interrupts by setting the SIE-bit in the SSTATUS Register.
- * \remarks
- * Can only be executed in Privileged modes.
- */
- __STATIC_FORCEINLINE void __enable_irq_s(void)
- {
- __RV_CSR_SET(CSR_SSTATUS, SSTATUS_SIE);
- }
- /**
- * \brief Disable IRQ Interrupts in supervisor mode
- * \details Disables IRQ interrupts by clearing the SIE-bit in the SSTATUS Register.
- * \remarks
- * Can only be executed in Privileged modes.
- */
- __STATIC_FORCEINLINE void __disable_irq_s(void)
- {
- __RV_CSR_CLEAR(CSR_SSTATUS, SSTATUS_SIE);
- }
- /**
- * \brief Enable External IRQ Interrupts in supervisor mode
- * \details Enables External IRQ interrupts by setting the SEIE-bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_ext_irq_s(void)
- {
- __RV_CSR_SET(CSR_SIE, MIE_SEIE);
- }
- /**
- * \brief Disable External IRQ Interrupts in supervisor mode
- * \details Disables External IRQ interrupts by clearing the SEIE-bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_ext_irq_s(void)
- {
- __RV_CSR_CLEAR(CSR_SIE, MIE_SEIE);
- }
- /**
- * \brief Enable Timer IRQ Interrupts in supervisor mode
- * \details Enables Timer IRQ interrupts by setting the STIE-bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_timer_irq_s(void)
- {
- __RV_CSR_SET(CSR_SIE, MIE_STIE);
- }
- /**
- * \brief Disable Timer IRQ Interrupts in supervisor mode
- * \details Disables Timer IRQ interrupts by clearing the STIE-bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_timer_irq_s(void)
- {
- __RV_CSR_CLEAR(CSR_SIE, MIE_STIE);
- }
- /**
- * \brief Enable software IRQ Interrupts in supervisor mode
- * \details Enables software IRQ interrupts by setting the SSIE-bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_sw_irq_s(void)
- {
- __RV_CSR_SET(CSR_SIE, MIE_SSIE);
- }
- /**
- * \brief Disable software IRQ Interrupts in supervisor mode
- * \details Disables software IRQ interrupts by clearing the SSIE-bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_sw_irq_s(void)
- {
- __RV_CSR_CLEAR(CSR_SIE, MIE_SSIE);
- }
- /**
- * \brief Disable Core IRQ Interrupt in supervisor mode
- * \details Disable Core IRQ interrupt by clearing the irq bit in the SIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __disable_core_irq_s(uint32_t irq)
- {
- __RV_CSR_CLEAR(CSR_SIE, 1UL << irq);
- }
- /**
- * \brief Enable Core IRQ Interrupt in supervisor mode
- * \details Enable Core IRQ interrupt by setting the irq bit in the MIE Register.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __enable_core_irq_s(uint32_t irq)
- {
- __RV_CSR_SET(CSR_SIE, 1UL << irq);
- }
- /**
- * \brief Get Core IRQ Interrupt Pending status in supervisor mode
- * \details Get Core IRQ interrupt pending status of irq bit.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE uint32_t __get_core_irq_pending_s(uint32_t irq)
- {
- return ((__RV_CSR_READ(CSR_SIP) >> irq) & 0x1);
- }
- /**
- * \brief Clear Core IRQ Interrupt Pending status in supervisor mode
- * \details Clear Core IRQ interrupt pending status of irq bit.
- * \remarks
- * Can only be executed in Privileged modes, available for plic interrupt mode.
- */
- __STATIC_FORCEINLINE void __clear_core_irq_pending_s(uint32_t irq)
- {
- __RV_CSR_CLEAR(CSR_SIP, 1UL << irq);
- }
- /**
- * \brief Read whole 64 bits value of mcycle counter
- * \details This function will read the whole 64 bits of MCYCLE register
- * \return The whole 64 bits value of MCYCLE
- * \remarks It will work for both RV32 and RV64 to get full 64bits value of MCYCLE
- */
- __STATIC_INLINE rv_counter_t __get_rv_cycle(void)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- #if __RISCV_XLEN == 32
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- return __RV_CSR_READ(CSR_MCYCLE);
- #else
- volatile uint32_t high0, low, high;
- uint64_t full;
- high0 = __RV_CSR_READ(CSR_MCYCLEH);
- low = __RV_CSR_READ(CSR_MCYCLE);
- high = __RV_CSR_READ(CSR_MCYCLEH);
- if (high0 != high) {
- low = __RV_CSR_READ(CSR_MCYCLE);
- }
- full = (((uint64_t)high) << 32) | low;
- return full;
- #endif
- #elif __RISCV_XLEN == 64
- return (uint64_t)__RV_CSR_READ(CSR_MCYCLE);
- #else // TODO Need cover for XLEN=128 case in future
- return (uint64_t)__RV_CSR_READ(CSR_MCYCLE);
- #endif
- }
- /**
- * \brief Set whole 64 bits value of mcycle counter
- * \details This function will set the whole 64 bits of MCYCLE register
- * \remarks It will work for both RV32 and RV64 to set full 64bits value of MCYCLE
- */
- __STATIC_FORCEINLINE void __set_rv_cycle(rv_counter_t cycle)
- {
- #if __RISCV_XLEN == 32
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- __RV_CSR_WRITE(CSR_MCYCLE, (uint32_t)(cycle));
- #else
- __RV_CSR_WRITE(CSR_MCYCLE, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MCYCLEH, (uint32_t)(cycle >> 32));
- __RV_CSR_WRITE(CSR_MCYCLE, (uint32_t)(cycle));
- #endif
- #elif __RISCV_XLEN == 64
- __RV_CSR_WRITE(CSR_MCYCLE, cycle);
- #else // TODO Need cover for XLEN=128 case in future
- #endif
- }
- /**
- * \brief Read whole 64 bits value of machine instruction-retired counter
- * \details This function will read the whole 64 bits of MINSTRET register
- * \return The whole 64 bits value of MINSTRET
- * \remarks It will work for both RV32 and RV64 to get full 64bits value of MINSTRET
- */
- __STATIC_INLINE rv_counter_t __get_rv_instret(void)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- #if __RISCV_XLEN == 32
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- return __RV_CSR_READ(CSR_MINSTRET);
- #else
- volatile uint32_t high0, low, high;
- uint64_t full;
- high0 = __RV_CSR_READ(CSR_MINSTRETH);
- low = __RV_CSR_READ(CSR_MINSTRET);
- high = __RV_CSR_READ(CSR_MINSTRETH);
- if (high0 != high) {
- low = __RV_CSR_READ(CSR_MINSTRET);
- }
- full = (((uint64_t)high) << 32) | low;
- return full;
- #endif
- #elif __RISCV_XLEN == 64
- return (uint64_t)__RV_CSR_READ(CSR_MINSTRET);
- #else // TODO Need cover for XLEN=128 case in future
- return (uint64_t)__RV_CSR_READ(CSR_MINSTRET);
- #endif
- }
- /**
- * \brief Set whole 64 bits value of machine instruction-retired counter
- * \details This function will set the whole 64 bits of MINSTRET register
- * \remarks It will work for both RV32 and RV64 to set full 64bits value of MINSTRET
- */
- __STATIC_FORCEINLINE void __set_rv_instret(rv_counter_t instret)
- {
- #if __RISCV_XLEN == 32
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- __RV_CSR_WRITE(CSR_MINSTRET, (uint32_t)(instret));
- #else
- __RV_CSR_WRITE(CSR_MINSTRET, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MINSTRETH, (uint32_t)(instret >> 32));
- __RV_CSR_WRITE(CSR_MINSTRET, (uint32_t)(instret));
- #endif
- #elif __RISCV_XLEN == 64
- __RV_CSR_WRITE(CSR_MINSTRET, instret);
- #else // TODO Need cover for XLEN=128 case in future
- #endif
- }
- /**
- * \brief Read whole 64 bits value of real-time clock
- * \details This function will read the whole 64 bits of TIME register
- * \return The whole 64 bits value of TIME CSR
- * \remarks It will work for both RV32 and RV64 to get full 64bits value of TIME
- * \attention only available when user mode available
- */
- __STATIC_INLINE rv_counter_t __get_rv_time(void)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- #if __RISCV_XLEN == 32
- #if defined(CPU_SERIES) && CPU_SERIES == 100
- // NOTE: when CSR_MIRGB_INFO CSR exist and not zero, it means eclic and systimer present
- if (__RV_CSR_READ(CSR_MIRGB_INFO) == 0) {
- return __RV_CSR_READ(CSR_MTIME);
- }
- #if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
- return *(uint32_t *) (__SYSTIMER_BASEADDR);
- #else
- return 0;
- #endif
- #else
- volatile uint32_t high0, low, high;
- uint64_t full;
- high0 = __RV_CSR_READ(CSR_TIMEH);
- low = __RV_CSR_READ(CSR_TIME);
- high = __RV_CSR_READ(CSR_TIMEH);
- if (high0 != high) {
- low = __RV_CSR_READ(CSR_TIME);
- }
- full = (((uint64_t)high) << 32) | low;
- return full;
- #endif
- #elif __RISCV_XLEN == 64
- return (uint64_t)__RV_CSR_READ(CSR_TIME);
- #else // TODO Need cover for XLEN=128 case in future
- return (uint64_t)__RV_CSR_READ(CSR_TIME);
- #endif
- }
- /**
- * \brief Read the CYCLE register
- * \details This function will read the CYCLE register without taking the
- * CYCLEH register into account
- * \return 32 bits value when XLEN=32
- * 64 bits value when XLEN=64
- * TODO: XLEN=128 need to be supported
- */
- __STATIC_FORCEINLINE unsigned long __read_cycle_csr(void)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- return __RV_CSR_READ(CSR_CYCLE);
- }
- /**
- * \brief Read the INSTRET register
- * \details This function will read the INSTRET register without taking the
- * INSTRETH register into account
- * \return 32 bits value when XLEN=32
- * 64 bits value when XLEN=64
- * TODO: XLEN=128 need to be supported
- */
- __STATIC_FORCEINLINE unsigned long __read_instret_csr(void)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- return __RV_CSR_READ(CSR_INSTRET);
- }
- /**
- * \brief Read the TIME register
- * \details This function will read the TIME register without taking the
- * TIMEH register into account
- * \return 32 bits value when XLEN=32
- * 64 bits value when XLEN=64
- * TODO: XLEN=128 need to be supported
- */
- __STATIC_FORCEINLINE unsigned long __read_time_csr(void)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- return __RV_CSR_READ(CSR_TIME);
- }
- /**
- * \brief Get cluster id of current cluster
- * \details This function will get cluster id of current cluster in a multiple cluster system
- * \return The cluster id of current cluster
- * \remarks mhartid bit 15-8 is designed for cluster id in nuclei subsystem reference design
- * \attention function is allowed in machine mode only
- */
- __STATIC_FORCEINLINE unsigned long __get_cluster_id(void)
- {
- unsigned long id;
- id = (__RV_CSR_READ(CSR_MHARTID) >> 8) & 0xFF;
- return id;
- }
- /**
- * \brief Get hart index of current cluster
- * \details This function will get hart index of current cluster in a multiple cluster system,
- * hart index is hartid - hartid offset, for example if your hartid is 1, and offset is 1, then
- * hart index is 0
- * \return The hart index of current cluster
- * \attention function is allowed in machine mode only
- */
- __STATIC_FORCEINLINE unsigned long __get_hart_index(void)
- {
- unsigned long id;
- #ifdef __HARTID_OFFSET
- id = __RV_CSR_READ(CSR_MHARTID) - __HARTID_OFFSET;
- #else
- id = __RV_CSR_READ(CSR_MHARTID);
- #endif
- return id;
- }
- /**
- * \brief Get hart id of current cluster
- * \details This function will get hart id of current cluster in a multiple cluster system
- * \return The hart id of current cluster
- * \remarks it will return full hartid not part of it for reference subsystem design,
- * if your reference subsystem design has hartid offset, please define __HARTID_OFFSET in
- * <Device>.h
- * \attention function is allowed in machine mode only
- */
- __STATIC_FORCEINLINE unsigned long __get_hart_id(void)
- {
- unsigned long id;
- id = __RV_CSR_READ(CSR_MHARTID);
- return id;
- }
- /**
- * \brief Get cluster id of current cluster in supervisor mode
- * \details This function will get cluster id of current cluster in a multiple cluster system
- * \return The cluster id of current cluster
- * \remarks hartid bit 15-8 is designed for cluster id in nuclei subsystem reference design
- * \attention function is allowed in machine/supervisor mode,
- * currently only present in 600/900 series from 2024 released version
- */
- __STATIC_FORCEINLINE unsigned long __get_cluster_id_s(void)
- {
- unsigned long id;
- id = (__RV_CSR_READ(CSR_SHARTID) >> 8) & 0xFF;
- return id;
- }
- /**
- * \brief Get hart index of current cluster in supervisor mode
- * \details This function will get hart index of current cluster in a multiple cluster system,
- * hart index is hartid - hartid offset, for example if your hartid is 1, and offset is 1, then
- * hart index is 0
- * \return The hart index of current cluster
- * \attention function is allowed in machine/supervisor mode,
- * currently only present in 600/900 series from 2024 released version
- */
- __STATIC_FORCEINLINE unsigned long __get_hart_index_s(void)
- {
- unsigned long id;
- #ifdef __HARTID_OFFSET
- id = __RV_CSR_READ(CSR_SHARTID) - __HARTID_OFFSET;
- #else
- id = __RV_CSR_READ(CSR_SHARTID);
- #endif
- return id;
- }
- /**
- * \brief Get hart id of current cluster in supervisor mode
- * \details This function will get hart id of current cluster in a multiple cluster system
- * \return The hart id of current cluster
- * \remarks it will return full hartid not part of it for reference subsystem design,
- * if your reference subsystem design has hartid offset, please define __HARTID_OFFSET in
- * <Device>.h
- * \attention function is allowed in machine/supervisor mode,
- * currently only present in 600/900 series from 2024 released version
- */
- __STATIC_FORCEINLINE unsigned long __get_hart_id_s(void)
- {
- unsigned long id;
- id = __RV_CSR_READ(CSR_SHARTID);
- return id;
- }
- /** @} */ /* End of Doxygen Group NMSIS_Core_CSR_Register_Access */
- /* ########################### CPU Intrinsic Functions ########################### */
- /**
- * \defgroup NMSIS_Core_CPU_Intrinsic Intrinsic Functions for CPU Intructions
- * \ingroup NMSIS_Core
- * \brief Functions that generate RISC-V CPU instructions.
- * \details
- *
- * The following functions generate specified RISC-V instructions that cannot be directly accessed by compiler.
- * @{
- */
- /**
- * \brief NOP Instruction
- * \details
- * No Operation does nothing.
- * This instruction can be used for code alignment purposes.
- */
- __STATIC_FORCEINLINE void __NOP(void)
- {
- __ASM volatile("nop");
- }
- /**
- * \brief Wait For Interrupt
- * \details
- * Wait For Interrupt is is executed using CSR_WFE.WFE=0 and WFI instruction.
- * It will suspends execution until interrupt, NMI or Debug happened.
- * When Core is waked up by interrupt, if
- * 1. mstatus.MIE == 1(interrupt enabled), Core will enter ISR code
- * 2. mstatus.MIE == 0(interrupt disabled), Core will resume previous execution
- */
- __STATIC_FORCEINLINE void __WFI(void)
- {
- __RV_CSR_CLEAR(CSR_WFE, WFE_WFE);
- __ASM volatile("wfi");
- }
- /**
- * \brief Wait For Event
- * \details
- * Wait For Event is executed using CSR_WFE.WFE=1 and WFI instruction.
- * It will suspends execution until event, NMI or Debug happened.
- * When Core is waked up, Core will resume previous execution
- */
- __STATIC_FORCEINLINE void __WFE(void)
- {
- __RV_CSR_SET(CSR_WFE, WFE_WFE);
- __ASM volatile("wfi");
- __RV_CSR_CLEAR(CSR_WFE, WFE_WFE);
- }
- /**
- * \brief Breakpoint Instruction
- * \details
- * Causes the processor to enter Debug state.
- * Debug tools can use this to investigate system state
- * when the instruction at a particular address is reached.
- */
- __STATIC_FORCEINLINE void __EBREAK(void)
- {
- __ASM volatile("ebreak");
- }
- /**
- * \brief Environment Call Instruction
- * \details
- * The ECALL instruction is used to make a service request to
- * the execution environment.
- */
- __STATIC_FORCEINLINE void __ECALL(void)
- {
- __ASM volatile("ecall");
- }
- /**
- * \brief WFI Sleep Mode enumeration
- */
- typedef enum WFI_SleepMode {
- WFI_SHALLOW_SLEEP = 0, /*!< Shallow sleep mode, the core_clk will poweroff */
- WFI_DEEP_SLEEP = 1 /*!< Deep sleep mode, the core_clk and core_ano_clk will poweroff */
- } WFI_SleepMode_Type;
- /**
- * \brief Set Sleep mode of WFI
- * \details
- * Set the SLEEPVALUE CSR register to control the
- * WFI Sleep mode.
- * \param[in] mode The sleep mode to be set
- */
- __STATIC_FORCEINLINE void __set_wfi_sleepmode(WFI_SleepMode_Type mode)
- {
- __RV_CSR_WRITE(CSR_SLEEPVALUE, mode);
- }
- /**
- * \brief Send TX Event
- * \details
- * Set the CSR TXEVT to control send a TX Event.
- * The Core will output signal tx_evt as output event signal.
- */
- __STATIC_FORCEINLINE void __TXEVT(void)
- {
- __RV_CSR_SET(CSR_TXEVT, 0x1);
- }
- /**
- * \brief Enable MCYCLE counter
- * \details
- * Clear the CY bit of MCOUNTINHIBIT to 0 to enable MCYCLE Counter
- */
- __STATIC_FORCEINLINE void __enable_mcycle_counter(void)
- {
- __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_CY);
- }
- /**
- * \brief Disable MCYCLE counter
- * \details
- * Set the CY bit of MCOUNTINHIBIT to 1 to disable MCYCLE Counter
- */
- __STATIC_FORCEINLINE void __disable_mcycle_counter(void)
- {
- __RV_CSR_SET(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_CY);
- }
- /**
- * \brief Enable MINSTRET counter
- * \details
- * Clear the IR bit of MCOUNTINHIBIT to 0 to enable MINSTRET Counter
- */
- __STATIC_FORCEINLINE void __enable_minstret_counter(void)
- {
- __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_IR);
- }
- /**
- * \brief Disable MINSTRET counter
- * \details
- * Set the IR bit of MCOUNTINHIBIT to 1 to disable MINSTRET Counter
- */
- __STATIC_FORCEINLINE void __disable_minstret_counter(void)
- {
- __RV_CSR_SET(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_IR);
- }
- /**
- * \brief Enable selected hardware performance monitor counter
- * \param [in] idx the index of the hardware performance monitor counter
- * \details
- * enable selected hardware performance monitor counter mhpmcounterx.
- */
- __STATIC_FORCEINLINE void __enable_mhpm_counter(unsigned long idx)
- {
- __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, (1UL << idx));
- }
- /**
- * \brief Disable selected hardware performance monitor counter
- * \param [in] idx the index of the hardware performance monitor counter
- * \details
- * Disable selected hardware performance monitor counter mhpmcounterx.
- */
- __STATIC_FORCEINLINE void __disable_mhpm_counter(unsigned long idx)
- {
- __RV_CSR_SET(CSR_MCOUNTINHIBIT, (1UL << idx));
- }
- /**
- * \brief Enable hardware performance counters with mask
- * \param [in] mask mask of selected hardware performance monitor counters
- * \details
- * enable mhpmcounterx with mask, only the masked ones will be enabled.
- * mhpmcounter3-mhpmcount31 are for high performance monitor counters.
- */
- __STATIC_FORCEINLINE void __enable_mhpm_counters(unsigned long mask)
- {
- __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, mask);
- }
- /**
- * \brief Disable hardware performance counters with mask
- * \param [in] mask mask of selected hardware performance monitor counters
- * \details
- * Disable mhpmcounterx with mask, only the masked ones will be disabled.
- * mhpmcounter3-mhpmcount31 are for high performance monitor counters.
- */
- __STATIC_FORCEINLINE void __disable_mhpm_counters(unsigned long mask)
- {
- __RV_CSR_SET(CSR_MCOUNTINHIBIT, mask);
- }
- /**
- * \brief Enable all MCYCLE & MINSTRET & MHPMCOUNTER counter
- * \details
- * Clear all to zero to enable all counters,
- * such as cycle, instret, high performance monitor counters
- */
- __STATIC_FORCEINLINE void __enable_all_counter(void)
- {
- __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, 0xFFFFFFFF);
- }
- /**
- * \brief Disable all MCYCLE & MINSTRET & MHPMCOUNTER counter
- * \details
- * Set all to one to disable all counters,
- * such as cycle, instret, high performance monitor counters
- */
- __STATIC_FORCEINLINE void __disable_all_counter(void)
- {
- __RV_CSR_SET(CSR_MCOUNTINHIBIT, 0xFFFFFFFF);
- }
- /**
- * \brief Set event for selected high performance monitor event
- * \param [in] idx HPMEVENTx CSR index(3-31)
- * \param [in] event HPMEVENTx Register value to set
- * \details
- * Set event for high performance monitor event register
- */
- __STATIC_INLINE void __set_hpm_event(unsigned long idx, unsigned long event)
- {
- switch (idx) {
- case 3: __RV_CSR_WRITE(CSR_MHPMEVENT3, event); break;
- case 4: __RV_CSR_WRITE(CSR_MHPMEVENT4, event); break;
- case 5: __RV_CSR_WRITE(CSR_MHPMEVENT5, event); break;
- case 6: __RV_CSR_WRITE(CSR_MHPMEVENT6, event); break;
- case 7: __RV_CSR_WRITE(CSR_MHPMEVENT7, event); break;
- case 8: __RV_CSR_WRITE(CSR_MHPMEVENT8, event); break;
- case 9: __RV_CSR_WRITE(CSR_MHPMEVENT9, event); break;
- case 10: __RV_CSR_WRITE(CSR_MHPMEVENT10, event); break;
- case 11: __RV_CSR_WRITE(CSR_MHPMEVENT11, event); break;
- case 12: __RV_CSR_WRITE(CSR_MHPMEVENT12, event); break;
- case 13: __RV_CSR_WRITE(CSR_MHPMEVENT13, event); break;
- case 14: __RV_CSR_WRITE(CSR_MHPMEVENT14, event); break;
- case 15: __RV_CSR_WRITE(CSR_MHPMEVENT15, event); break;
- case 16: __RV_CSR_WRITE(CSR_MHPMEVENT16, event); break;
- case 17: __RV_CSR_WRITE(CSR_MHPMEVENT17, event); break;
- case 18: __RV_CSR_WRITE(CSR_MHPMEVENT18, event); break;
- case 19: __RV_CSR_WRITE(CSR_MHPMEVENT19, event); break;
- case 20: __RV_CSR_WRITE(CSR_MHPMEVENT20, event); break;
- case 21: __RV_CSR_WRITE(CSR_MHPMEVENT21, event); break;
- case 22: __RV_CSR_WRITE(CSR_MHPMEVENT22, event); break;
- case 23: __RV_CSR_WRITE(CSR_MHPMEVENT23, event); break;
- case 24: __RV_CSR_WRITE(CSR_MHPMEVENT24, event); break;
- case 25: __RV_CSR_WRITE(CSR_MHPMEVENT25, event); break;
- case 26: __RV_CSR_WRITE(CSR_MHPMEVENT26, event); break;
- case 27: __RV_CSR_WRITE(CSR_MHPMEVENT27, event); break;
- case 28: __RV_CSR_WRITE(CSR_MHPMEVENT28, event); break;
- case 29: __RV_CSR_WRITE(CSR_MHPMEVENT29, event); break;
- case 30: __RV_CSR_WRITE(CSR_MHPMEVENT30, event); break;
- case 31: __RV_CSR_WRITE(CSR_MHPMEVENT31, event); break;
- default: break;
- }
- }
- /**
- * \brief Get event for selected high performance monitor event
- * \param [in] idx HPMEVENTx CSR index(3-31)
- * \param [in] event HPMEVENTx Register value to set
- * \details
- * Get high performance monitor event register value
- * \return HPMEVENTx Register value
- */
- __STATIC_INLINE unsigned long __get_hpm_event(unsigned long idx)
- {
- switch (idx) {
- case 3: return __RV_CSR_READ(CSR_MHPMEVENT3);
- case 4: return __RV_CSR_READ(CSR_MHPMEVENT4);
- case 5: return __RV_CSR_READ(CSR_MHPMEVENT5);
- case 6: return __RV_CSR_READ(CSR_MHPMEVENT6);
- case 7: return __RV_CSR_READ(CSR_MHPMEVENT7);
- case 8: return __RV_CSR_READ(CSR_MHPMEVENT8);
- case 9: return __RV_CSR_READ(CSR_MHPMEVENT9);
- case 10: return __RV_CSR_READ(CSR_MHPMEVENT10);
- case 11: return __RV_CSR_READ(CSR_MHPMEVENT11);
- case 12: return __RV_CSR_READ(CSR_MHPMEVENT12);
- case 13: return __RV_CSR_READ(CSR_MHPMEVENT13);
- case 14: return __RV_CSR_READ(CSR_MHPMEVENT14);
- case 15: return __RV_CSR_READ(CSR_MHPMEVENT15);
- case 16: return __RV_CSR_READ(CSR_MHPMEVENT16);
- case 17: return __RV_CSR_READ(CSR_MHPMEVENT17);
- case 18: return __RV_CSR_READ(CSR_MHPMEVENT18);
- case 19: return __RV_CSR_READ(CSR_MHPMEVENT19);
- case 20: return __RV_CSR_READ(CSR_MHPMEVENT20);
- case 21: return __RV_CSR_READ(CSR_MHPMEVENT21);
- case 22: return __RV_CSR_READ(CSR_MHPMEVENT22);
- case 23: return __RV_CSR_READ(CSR_MHPMEVENT23);
- case 24: return __RV_CSR_READ(CSR_MHPMEVENT24);
- case 25: return __RV_CSR_READ(CSR_MHPMEVENT25);
- case 26: return __RV_CSR_READ(CSR_MHPMEVENT26);
- case 27: return __RV_CSR_READ(CSR_MHPMEVENT27);
- case 28: return __RV_CSR_READ(CSR_MHPMEVENT28);
- case 29: return __RV_CSR_READ(CSR_MHPMEVENT29);
- case 30: return __RV_CSR_READ(CSR_MHPMEVENT30);
- case 31: return __RV_CSR_READ(CSR_MHPMEVENT31);
- default: return 0;
- }
- }
- /**
- * \brief Set value for selected high performance monitor counter
- * \param [in] idx HPMCOUNTERx CSR index(3-31)
- * \param [in] value HPMCOUNTERx Register value to set
- * \details
- * Set value for high performance monitor couner register
- */
- __STATIC_INLINE void __set_hpm_counter(unsigned long idx, uint64_t value)
- {
- switch (idx) {
- #if __RISCV_XLEN == 32
- case 3: __RV_CSR_WRITE(CSR_MHPMCOUNTER3, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER3H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER3, (uint32_t)(value)); break;
- case 4: __RV_CSR_WRITE(CSR_MHPMCOUNTER4, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER4H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER4, (uint32_t)(value)); break;
- case 5: __RV_CSR_WRITE(CSR_MHPMCOUNTER5, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER5H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER5, (uint32_t)(value)); break;
- case 6: __RV_CSR_WRITE(CSR_MHPMCOUNTER6, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER6H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER6, (uint32_t)(value)); break;
- case 7: __RV_CSR_WRITE(CSR_MHPMCOUNTER7, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER7H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER7, (uint32_t)(value)); break;
- case 8: __RV_CSR_WRITE(CSR_MHPMCOUNTER8, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER8H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER8, (uint32_t)(value)); break;
- case 9: __RV_CSR_WRITE(CSR_MHPMCOUNTER9, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER9H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER9, (uint32_t)(value)); break;
- case 10: __RV_CSR_WRITE(CSR_MHPMCOUNTER10, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER10H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER10, (uint32_t)(value)); break;
- case 11: __RV_CSR_WRITE(CSR_MHPMCOUNTER11, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER11H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER11, (uint32_t)(value)); break;
- case 12: __RV_CSR_WRITE(CSR_MHPMCOUNTER12, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER12H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER12, (uint32_t)(value)); break;
- case 13: __RV_CSR_WRITE(CSR_MHPMCOUNTER13, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER13H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER13, (uint32_t)(value)); break;
- case 14: __RV_CSR_WRITE(CSR_MHPMCOUNTER14, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER14H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER14, (uint32_t)(value)); break;
- case 15: __RV_CSR_WRITE(CSR_MHPMCOUNTER15, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER15H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER15, (uint32_t)(value)); break;
- case 16: __RV_CSR_WRITE(CSR_MHPMCOUNTER16, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER16H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER16, (uint32_t)(value)); break;
- case 17: __RV_CSR_WRITE(CSR_MHPMCOUNTER17, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER17H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER17, (uint32_t)(value)); break;
- case 18: __RV_CSR_WRITE(CSR_MHPMCOUNTER18, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER18H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER18, (uint32_t)(value)); break;
- case 19: __RV_CSR_WRITE(CSR_MHPMCOUNTER19, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER19H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER19, (uint32_t)(value)); break;
- case 20: __RV_CSR_WRITE(CSR_MHPMCOUNTER20, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER20H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER20, (uint32_t)(value)); break;
- case 21: __RV_CSR_WRITE(CSR_MHPMCOUNTER21, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER21H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER21, (uint32_t)(value)); break;
- case 22: __RV_CSR_WRITE(CSR_MHPMCOUNTER22, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER22H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER22, (uint32_t)(value)); break;
- case 23: __RV_CSR_WRITE(CSR_MHPMCOUNTER23, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER23H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER23, (uint32_t)(value)); break;
- case 24: __RV_CSR_WRITE(CSR_MHPMCOUNTER24, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER24H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER24, (uint32_t)(value)); break;
- case 25: __RV_CSR_WRITE(CSR_MHPMCOUNTER25, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER25H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER25, (uint32_t)(value)); break;
- case 26: __RV_CSR_WRITE(CSR_MHPMCOUNTER26, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER26H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER26, (uint32_t)(value)); break;
- case 27: __RV_CSR_WRITE(CSR_MHPMCOUNTER27, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER27H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER27, (uint32_t)(value)); break;
- case 28: __RV_CSR_WRITE(CSR_MHPMCOUNTER28, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER28H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER28, (uint32_t)(value)); break;
- case 29: __RV_CSR_WRITE(CSR_MHPMCOUNTER29, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER29H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER29, (uint32_t)(value)); break;
- case 30: __RV_CSR_WRITE(CSR_MHPMCOUNTER30, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER30H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER30, (uint32_t)(value)); break;
- case 31: __RV_CSR_WRITE(CSR_MHPMCOUNTER31, 0); // prevent carry
- __RV_CSR_WRITE(CSR_MHPMCOUNTER31H, (uint32_t)(value >> 32));
- __RV_CSR_WRITE(CSR_MHPMCOUNTER31, (uint32_t)(value)); break;
- #elif __RISCV_XLEN == 64
- case 3: __RV_CSR_WRITE(CSR_MHPMCOUNTER3, (value)); break;
- case 4: __RV_CSR_WRITE(CSR_MHPMCOUNTER4, (value)); break;
- case 5: __RV_CSR_WRITE(CSR_MHPMCOUNTER5, (value)); break;
- case 6: __RV_CSR_WRITE(CSR_MHPMCOUNTER6, (value)); break;
- case 7: __RV_CSR_WRITE(CSR_MHPMCOUNTER7, (value)); break;
- case 8: __RV_CSR_WRITE(CSR_MHPMCOUNTER8, (value)); break;
- case 9: __RV_CSR_WRITE(CSR_MHPMCOUNTER9, (value)); break;
- case 10: __RV_CSR_WRITE(CSR_MHPMCOUNTER10, (value)); break;
- case 11: __RV_CSR_WRITE(CSR_MHPMCOUNTER11, (value)); break;
- case 12: __RV_CSR_WRITE(CSR_MHPMCOUNTER12, (value)); break;
- case 13: __RV_CSR_WRITE(CSR_MHPMCOUNTER13, (value)); break;
- case 14: __RV_CSR_WRITE(CSR_MHPMCOUNTER14, (value)); break;
- case 15: __RV_CSR_WRITE(CSR_MHPMCOUNTER15, (value)); break;
- case 16: __RV_CSR_WRITE(CSR_MHPMCOUNTER16, (value)); break;
- case 17: __RV_CSR_WRITE(CSR_MHPMCOUNTER17, (value)); break;
- case 18: __RV_CSR_WRITE(CSR_MHPMCOUNTER18, (value)); break;
- case 19: __RV_CSR_WRITE(CSR_MHPMCOUNTER19, (value)); break;
- case 20: __RV_CSR_WRITE(CSR_MHPMCOUNTER20, (value)); break;
- case 21: __RV_CSR_WRITE(CSR_MHPMCOUNTER21, (value)); break;
- case 22: __RV_CSR_WRITE(CSR_MHPMCOUNTER22, (value)); break;
- case 23: __RV_CSR_WRITE(CSR_MHPMCOUNTER23, (value)); break;
- case 24: __RV_CSR_WRITE(CSR_MHPMCOUNTER24, (value)); break;
- case 25: __RV_CSR_WRITE(CSR_MHPMCOUNTER25, (value)); break;
- case 26: __RV_CSR_WRITE(CSR_MHPMCOUNTER26, (value)); break;
- case 27: __RV_CSR_WRITE(CSR_MHPMCOUNTER27, (value)); break;
- case 28: __RV_CSR_WRITE(CSR_MHPMCOUNTER28, (value)); break;
- case 29: __RV_CSR_WRITE(CSR_MHPMCOUNTER29, (value)); break;
- case 30: __RV_CSR_WRITE(CSR_MHPMCOUNTER30, (value)); break;
- case 31: __RV_CSR_WRITE(CSR_MHPMCOUNTER31, (value)); break;
- #else
- #endif
- default: break;
- }
- }
- /**
- * \brief Get value of selected high performance monitor counter
- * \param [in] idx HPMCOUNTERx CSR index(3-31)
- * \details
- * Get high performance monitor counter register value
- * \return HPMCOUNTERx Register value
- */
- __STATIC_INLINE uint64_t __get_hpm_counter(unsigned long idx)
- {
- __RWMB(); // Make sure previous memory and io operation finished
- #if __RISCV_XLEN == 32
- volatile uint32_t high0, low, high;
- uint64_t full;
- switch (idx) {
- case 0: return __get_rv_cycle();
- case 2: return __get_rv_instret();
- case 3: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER3H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER3);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER3H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER3); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 4: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER4H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER4);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER4H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER4); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 5: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER5H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER5);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER5H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER5); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 6: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER6H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER6);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER6H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER6); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 7: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER7H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER7);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER7H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER7); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 8: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER8H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER8);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER8H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER8); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 9: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER9H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER9);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER9H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER9); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 10: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER10H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER10);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER10H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER10); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 11: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER11H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER11);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER11H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER11); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 12: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER12H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER12);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER12H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER12); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 13: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER13H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER13);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER13H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER13); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 14: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER14H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER14);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER14H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER14); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 15: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER15H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER15);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER15H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER15); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 16: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER16H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER16);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER16H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER16); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 17: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER17H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER17);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER17H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER17); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 18: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER18H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER18);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER18H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER18); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 19: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER19H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER19);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER19H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER19); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 20: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER20H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER20);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER20H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER20); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 21: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER21H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER21);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER21H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER21); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 22: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER22H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER22);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER22H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER22); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 23: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER23H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER23);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER23H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER23); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 24: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER24H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER24);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER24H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER24); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 25: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER25H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER25);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER25H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER25); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 26: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER26H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER26);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER26H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER26); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 27: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER27H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER27);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER27H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER27); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 28: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER28H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER28);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER28H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER28); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 29: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER29H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER29);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER29H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER29); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 30: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER30H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER30);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER30H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER30); }
- full = (((uint64_t)high) << 32) | low; return full;
- case 31: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER31H);
- low = __RV_CSR_READ(CSR_MHPMCOUNTER31);
- high = __RV_CSR_READ(CSR_MHPMCOUNTER31H);
- if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER31); }
- full = (((uint64_t)high) << 32) | low; return full;
- #elif __RISCV_XLEN == 64
- switch (idx) {
- case 0: return __get_rv_cycle();
- case 2: return __get_rv_instret();
- case 3: return __RV_CSR_READ(CSR_MHPMCOUNTER3);
- case 4: return __RV_CSR_READ(CSR_MHPMCOUNTER4);
- case 5: return __RV_CSR_READ(CSR_MHPMCOUNTER5);
- case 6: return __RV_CSR_READ(CSR_MHPMCOUNTER6);
- case 7: return __RV_CSR_READ(CSR_MHPMCOUNTER7);
- case 8: return __RV_CSR_READ(CSR_MHPMCOUNTER8);
- case 9: return __RV_CSR_READ(CSR_MHPMCOUNTER9);
- case 10: return __RV_CSR_READ(CSR_MHPMCOUNTER10);
- case 11: return __RV_CSR_READ(CSR_MHPMCOUNTER11);
- case 12: return __RV_CSR_READ(CSR_MHPMCOUNTER12);
- case 13: return __RV_CSR_READ(CSR_MHPMCOUNTER13);
- case 14: return __RV_CSR_READ(CSR_MHPMCOUNTER14);
- case 15: return __RV_CSR_READ(CSR_MHPMCOUNTER15);
- case 16: return __RV_CSR_READ(CSR_MHPMCOUNTER16);
- case 17: return __RV_CSR_READ(CSR_MHPMCOUNTER17);
- case 18: return __RV_CSR_READ(CSR_MHPMCOUNTER18);
- case 19: return __RV_CSR_READ(CSR_MHPMCOUNTER19);
- case 20: return __RV_CSR_READ(CSR_MHPMCOUNTER20);
- case 21: return __RV_CSR_READ(CSR_MHPMCOUNTER21);
- case 22: return __RV_CSR_READ(CSR_MHPMCOUNTER22);
- case 23: return __RV_CSR_READ(CSR_MHPMCOUNTER23);
- case 24: return __RV_CSR_READ(CSR_MHPMCOUNTER24);
- case 25: return __RV_CSR_READ(CSR_MHPMCOUNTER25);
- case 26: return __RV_CSR_READ(CSR_MHPMCOUNTER26);
- case 27: return __RV_CSR_READ(CSR_MHPMCOUNTER27);
- case 28: return __RV_CSR_READ(CSR_MHPMCOUNTER28);
- case 29: return __RV_CSR_READ(CSR_MHPMCOUNTER29);
- case 30: return __RV_CSR_READ(CSR_MHPMCOUNTER30);
- case 31: return __RV_CSR_READ(CSR_MHPMCOUNTER31);
- #else
- switch (idx) {
- #endif
- default: return 0;
- }
- }
- /**
- * \brief Get value of selected high performance monitor counter
- * \param [in] idx HPMCOUNTERx CSR index(3-31)
- * \details
- * Get high performance monitor counter register value without high
- * 32 bits when XLEN=32
- * \return HPMCOUNTERx Register value
- */
- __STATIC_INLINE unsigned long __read_hpm_counter(unsigned long idx)
- {
- switch (idx) {
- case 0: return __read_cycle_csr();
- case 2: return __read_instret_csr();
- case 3: return __RV_CSR_READ(CSR_MHPMCOUNTER3);
- case 4: return __RV_CSR_READ(CSR_MHPMCOUNTER4);
- case 5: return __RV_CSR_READ(CSR_MHPMCOUNTER5);
- case 6: return __RV_CSR_READ(CSR_MHPMCOUNTER6);
- case 7: return __RV_CSR_READ(CSR_MHPMCOUNTER7);
- case 8: return __RV_CSR_READ(CSR_MHPMCOUNTER8);
- case 9: return __RV_CSR_READ(CSR_MHPMCOUNTER9);
- case 10: return __RV_CSR_READ(CSR_MHPMCOUNTER10);
- case 11: return __RV_CSR_READ(CSR_MHPMCOUNTER11);
- case 12: return __RV_CSR_READ(CSR_MHPMCOUNTER12);
- case 13: return __RV_CSR_READ(CSR_MHPMCOUNTER13);
- case 14: return __RV_CSR_READ(CSR_MHPMCOUNTER14);
- case 15: return __RV_CSR_READ(CSR_MHPMCOUNTER15);
- case 16: return __RV_CSR_READ(CSR_MHPMCOUNTER16);
- case 17: return __RV_CSR_READ(CSR_MHPMCOUNTER17);
- case 18: return __RV_CSR_READ(CSR_MHPMCOUNTER18);
- case 19: return __RV_CSR_READ(CSR_MHPMCOUNTER19);
- case 20: return __RV_CSR_READ(CSR_MHPMCOUNTER20);
- case 21: return __RV_CSR_READ(CSR_MHPMCOUNTER21);
- case 22: return __RV_CSR_READ(CSR_MHPMCOUNTER22);
- case 23: return __RV_CSR_READ(CSR_MHPMCOUNTER23);
- case 24: return __RV_CSR_READ(CSR_MHPMCOUNTER24);
- case 25: return __RV_CSR_READ(CSR_MHPMCOUNTER25);
- case 26: return __RV_CSR_READ(CSR_MHPMCOUNTER26);
- case 27: return __RV_CSR_READ(CSR_MHPMCOUNTER27);
- case 28: return __RV_CSR_READ(CSR_MHPMCOUNTER28);
- case 29: return __RV_CSR_READ(CSR_MHPMCOUNTER29);
- case 30: return __RV_CSR_READ(CSR_MHPMCOUNTER30);
- case 31: return __RV_CSR_READ(CSR_MHPMCOUNTER31);
- default: return 0;
- }
- }
- /**
- * \brief Set exceptions delegation to S mode
- * \details Set certain exceptions of supervisor mode or user mode
- * delegated from machined mode to supervisor mode.
- * \remarks
- * Exception should trigger in supervisor mode or user mode.
- */
- __STATIC_FORCEINLINE void __set_medeleg(unsigned long mask)
- {
- __RV_CSR_WRITE(CSR_MEDELEG, mask);
- }
- /**
- * \brief Set interrupt delegation to S mode
- * \details Set certain interrupt of supervisor mode or user mode
- * delegated from machined mode to supervisor mode.
- * \remarks
- * interrupt should trigger in supervisor mode or user mode.
- */
- __STATIC_FORCEINLINE void __set_mideleg(unsigned long mask)
- {
- __RV_CSR_WRITE(CSR_MIDELEG, mask);
- }
- /* ===== Load/Store Operations ===== */
- /**
- * \brief Load 8bit value from address (8 bit)
- * \details Load 8 bit value.
- * \param [in] addr Address pointer to data
- * \return value of type uint8_t at (*addr)
- */
- __STATIC_FORCEINLINE uint8_t __LB(volatile void *addr)
- {
- uint8_t result;
- __ASM volatile ("lb %0, 0(%1)" : "=r" (result) : "r" (addr));
- return result;
- }
- /**
- * \brief Load 16bit value from address (16 bit)
- * \details Load 16 bit value.
- * \param [in] addr Address pointer to data
- * \return value of type uint16_t at (*addr)
- */
- __STATIC_FORCEINLINE uint16_t __LH(volatile void *addr)
- {
- uint16_t result;
- __ASM volatile ("lh %0, 0(%1)" : "=r" (result) : "r" (addr));
- return result;
- }
- /**
- * \brief Load 32bit value from address (32 bit)
- * \details Load 32 bit value.
- * \param [in] addr Address pointer to data
- * \return value of type uint32_t at (*addr)
- */
- __STATIC_FORCEINLINE uint32_t __LW(volatile void *addr)
- {
- uint32_t result;
- __ASM volatile ("lw %0, 0(%1)" : "=r" (result) : "r" (addr));
- return result;
- }
- #if (__RISCV_XLEN != 32) || defined(__riscv_zilsd)
- /**
- * \brief Load 64bit value from address (64 bit)
- * \details Load 64 bit value.
- * \param [in] addr Address pointer to data
- * \return value of type uint64_t at (*addr)
- * \remarks RV64 only macro
- */
- __STATIC_FORCEINLINE uint64_t __LD(volatile void *addr)
- {
- uint64_t result;
- __ASM volatile ("ld %0, 0(%1)" : "=r" (result) : "r" (addr));
- return result;
- }
- #endif
- /**
- * \brief Write 8bit value to address (8 bit)
- * \details Write 8 bit value.
- * \param [in] addr Address pointer to data
- * \param [in] val Value to set
- */
- __STATIC_FORCEINLINE void __SB(volatile void *addr, uint8_t val)
- {
- __ASM volatile ("sb %0, 0(%1)" : : "r" (val), "r" (addr));
- }
- /**
- * \brief Write 16bit value to address (16 bit)
- * \details Write 16 bit value.
- * \param [in] addr Address pointer to data
- * \param [in] val Value to set
- */
- __STATIC_FORCEINLINE void __SH(volatile void *addr, uint16_t val)
- {
- __ASM volatile ("sh %0, 0(%1)" : : "r" (val), "r" (addr));
- }
- /**
- * \brief Write 32bit value to address (32 bit)
- * \details Write 32 bit value.
- * \param [in] addr Address pointer to data
- * \param [in] val Value to set
- */
- __STATIC_FORCEINLINE void __SW(volatile void *addr, uint32_t val)
- {
- __ASM volatile ("sw %0, 0(%1)" : : "r" (val), "r" (addr));
- }
- #if (__RISCV_XLEN != 32) || defined(__riscv_zilsd)
- /**
- * \brief Write 64bit value to address (64 bit)
- * \details Write 64 bit value.
- * \param [in] addr Address pointer to data
- * \param [in] val Value to set
- */
- __STATIC_FORCEINLINE void __SD(volatile void *addr, uint64_t val)
- {
- __ASM volatile ("sd %0, 0(%1)" : : "r" (val), "r" (addr));
- }
- #endif
- /**
- * \brief Compare and Swap 32bit value using LR and SC
- * \details Compare old value with memory, if identical,
- * store new value in memory. Return the initial value in memory.
- * Success is indicated by comparing return value with OLD.
- * memory address, return 0 if successful, otherwise return !0
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] oldval Old value of the data in address
- * \param [in] newval New value to be stored into the address
- * \return return the initial value in memory
- */
- __STATIC_INLINE uint32_t __CAS_W(volatile uint32_t *addr, uint32_t oldval, uint32_t newval)
- {
- uint32_t result;
- uint32_t rc;
- __ASM volatile ( \
- "0: lr.w %0, %2 \n" \
- " bne %0, %z3, 1f \n" \
- " sc.w %1, %z4, %2 \n" \
- " bnez %1, 0b \n" \
- "1:\n" \
- : "=&r"(result), "=&r"(rc), "+A"(*addr) \
- : "r"(oldval), "r"(newval) \
- : "memory");
- return result;
- }
- /**
- * \brief Atomic Swap 32bit value into memory
- * \details Atomically swap new 32bit value into memory using amoswap.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] newval New value to be stored into the address
- * \return return the original value in memory
- */
- __STATIC_FORCEINLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
- {
- uint32_t result;
- __ASM volatile ("amoswap.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(newval) : "memory");
- return result;
- }
- /**
- * \brief Atomic Add with 32bit value
- * \details Atomically ADD 32bit value with value in memory using amoadd.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be ADDed
- * \return return memory value + add value
- */
- __STATIC_FORCEINLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value)
- {
- int32_t result;
- __ASM volatile ("amoadd.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic And with 32bit value
- * \details Atomically AND 32bit value with value in memory using amoand.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be ANDed
- * \return return memory value & and value
- */
- __STATIC_FORCEINLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value)
- {
- int32_t result;
- __ASM volatile ("amoand.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic OR with 32bit value
- * \details Atomically OR 32bit value with value in memory using amoor.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be ORed
- * \return return memory value | and value
- */
- __STATIC_FORCEINLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value)
- {
- int32_t result;
- __ASM volatile ("amoor.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic XOR with 32bit value
- * \details Atomically XOR 32bit value with value in memory using amoxor.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be XORed
- * \return return memory value ^ and value
- */
- __STATIC_FORCEINLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value)
- {
- int32_t result;
- __ASM volatile ("amoxor.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic unsigned MAX with 32bit value
- * \details Atomically unsigned max compare 32bit value with value in memory using amomaxu.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be compared
- * \return return the bigger value
- */
- __STATIC_FORCEINLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
- {
- uint32_t result;
- __ASM volatile ("amomaxu.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic signed MAX with 32bit value
- * \details Atomically signed max compare 32bit value with value in memory using amomax.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be compared
- * \return the bigger value
- */
- __STATIC_FORCEINLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value)
- {
- int32_t result;
- __ASM volatile ("amomax.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic unsigned MIN with 32bit value
- * \details Atomically unsigned min compare 32bit value with value in memory using amominu.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be compared
- * \return the smaller value
- */
- __STATIC_FORCEINLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value)
- {
- uint32_t result;
- __ASM volatile ("amominu.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic signed MIN with 32bit value
- * \details Atomically signed min compare 32bit value with value in memory using amomin.d.
- * \param [in] addr Address pointer to data, address need to be 4byte aligned
- * \param [in] value value to be compared
- * \return the smaller value
- */
- __STATIC_FORCEINLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value)
- {
- int32_t result;
- __ASM volatile ("amomin.w %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- #if __RISCV_XLEN == 64
- /**
- * \brief Compare and Swap 64bit value using LR and SC
- * \details Compare old value with memory, if identical,
- * store new value in memory. Return the initial value in memory.
- * Success is indicated by comparing return value with OLD.
- * memory address, return 0 if successful, otherwise return !0
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] oldval Old value of the data in address
- * \param [in] newval New value to be stored into the address
- * \return return the initial value in memory
- */
- __STATIC_INLINE uint64_t __CAS_D(volatile uint64_t *addr, uint64_t oldval, uint64_t newval)
- {
- uint64_t result;
- uint64_t rc;
- __ASM volatile ( \
- "0: lr.d %0, %2 \n" \
- " bne %0, %z3, 1f \n" \
- " sc.d %1, %z4, %2 \n" \
- " bnez %1, 0b \n" \
- "1:\n" \
- : "=&r"(result), "=&r"(rc), "+A"(*addr) \
- : "r"(oldval), "r"(newval) \
- : "memory");
- return result;
- }
- /**
- * \brief Atomic Swap 64bit value into memory
- * \details Atomically swap new 64bit value into memory using amoswap.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] newval New value to be stored into the address
- * \return return the original value in memory
- */
- __STATIC_FORCEINLINE uint64_t __AMOSWAP_D(volatile uint64_t *addr, uint64_t newval)
- {
- uint64_t result;
- __ASM volatile ("amoswap.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(newval) : "memory");
- return result;
- }
- /**
- * \brief Atomic Add with 64bit value
- * \details Atomically ADD 64bit value with value in memory using amoadd.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be ADDed
- * \return return memory value + add value
- */
- __STATIC_FORCEINLINE int64_t __AMOADD_D(volatile int64_t *addr, int64_t value)
- {
- int64_t result;
- __ASM volatile ("amoadd.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic And with 64bit value
- * \details Atomically AND 64bit value with value in memory using amoand.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be ANDed
- * \return return memory value & and value
- */
- __STATIC_FORCEINLINE int64_t __AMOAND_D(volatile int64_t *addr, int64_t value)
- {
- int64_t result;
- __ASM volatile ("amoand.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic OR with 64bit value
- * \details Atomically OR 64bit value with value in memory using amoor.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be ORed
- * \return return memory value | and value
- */
- __STATIC_FORCEINLINE int64_t __AMOOR_D(volatile int64_t *addr, int64_t value)
- {
- int64_t result;
- __ASM volatile ("amoor.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic XOR with 64bit value
- * \details Atomically XOR 64bit value with value in memory using amoxor.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be XORed
- * \return return memory value ^ and value
- */
- __STATIC_FORCEINLINE int64_t __AMOXOR_D(volatile int64_t *addr, int64_t value)
- {
- int64_t result;
- __ASM volatile ("amoxor.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic unsigned MAX with 64bit value
- * \details Atomically unsigned max compare 64bit value with value in memory using amomaxu.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be compared
- * \return return the bigger value
- */
- __STATIC_FORCEINLINE uint64_t __AMOMAXU_D(volatile uint64_t *addr, uint64_t value)
- {
- uint64_t result;
- __ASM volatile ("amomaxu.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic signed MAX with 64bit value
- * \details Atomically signed max compare 64bit value with value in memory using amomax.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be compared
- * \return the bigger value
- */
- __STATIC_FORCEINLINE int64_t __AMOMAX_D(volatile int64_t *addr, int64_t value)
- {
- int64_t result;
- __ASM volatile ("amomax.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic unsigned MIN with 64bit value
- * \details Atomically unsigned min compare 64bit value with value in memory using amominu.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be compared
- * \return the smaller value
- */
- __STATIC_FORCEINLINE uint64_t __AMOMINU_D(volatile uint64_t *addr, uint64_t value)
- {
- uint64_t result;
- __ASM volatile ("amominu.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- /**
- * \brief Atomic signed MIN with 64bit value
- * \details Atomically signed min compare 64bit value with value in memory using amomin.d.
- * \param [in] addr Address pointer to data, address need to be 8byte aligned
- * \param [in] value value to be compared
- * \return the smaller value
- */
- __STATIC_FORCEINLINE int64_t __AMOMIN_D(volatile int64_t *addr, int64_t value)
- {
- int64_t result;
- __ASM volatile ("amomin.d %0, %2, %1" : \
- "=r"(result), "+A"(*addr) : "r"(value) : "memory");
- return *addr;
- }
- #endif /* __RISCV_XLEN == 64 */
- /**
- * \brief Enable ICache prefetch
- * \details Set the IC_PF_EN bit in the MCACHE_CTL CSR to enable
- * ICache prefetch.
- */
- __STATIC_FORCEINLINE void __enable_ic_prefetch(void)
- {
- __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_PF_EN);
- }
- /**
- * \brief Disable ICache prefetch
- * \details Clear the IC_PF_EN bit in the MCACHE_CTL CSR to disable
- * ICache prefetch.
- */
- __STATIC_FORCEINLINE void __disable_ic_prefetch(void)
- {
- __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_PF_EN);
- }
- /**
- * \brief Enable ICache CMO prefetch
- * \details Set the IC_CMO_PF_EN bit in the MCACHE_CTL CSR to enable
- * ICache prefetch.
- */
- __STATIC_FORCEINLINE void __enable_ic_cmo_prefetch(void)
- {
- __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_CMO_PF_EN);
- }
- /**
- * \brief Disable ICache CMO prefetch
- * \details Clear the IC_CMO_PF_EN bit in the MCACHE_CTL CSR to disable
- * ICache prefetch.
- */
- __STATIC_FORCEINLINE void __disable_ic_cmo_prefetch(void)
- {
- __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_CMO_PF_EN);
- }
- /**
- * \brief Enable DCache CMO prefetch
- * \details Set the DC_CMO_PF_EN bit in the MCACHE_CTL CSR to enable
- * DCache prefetch.
- */
- __STATIC_FORCEINLINE void __enable_dc_cmo_prefetch(void)
- {
- __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_CMO_PF_EN);
- }
- /**
- * \brief Disable DCache CMO prefetch
- * \details Clear the DC_CMO_PF_EN bit in the MCACHE_CTL CSR to disable
- * DCache prefetch.
- */
- __STATIC_FORCEINLINE void __disable_dc_cmo_prefetch(void)
- {
- __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_CMO_PF_EN);
- }
- /**
- * \brief Instruction prefetch operation
- * \details Performs an instruction prefetch operation for the specified address
- * using the RISC-V prefetch.i instruction.
- * \param[in] addr Address to prefetch
- * \remarks Before calling this function, ensure that the hardware supports CMO prefetch
- * and that the code is compiled with the `_zicbop` extension enabled.
- * Here is a code example to check if CMO prefetch is supported:
- *
- * \code
- * if (IINFO_IsCMOPrefetchSupported()) {
- * __cmo_prefetch_i(func);
- * }
- * \endcode
- *
- * \sa
- * - \ref IINFO_IsCMOPrefetchSupported
- *
- */
- __STATIC_FORCEINLINE void __cmo_prefetch_i(const void *addr)
- {
- __ASM volatile ("prefetch.i 0(%0)" : : "r" (addr) : "memory");
- }
- /**
- * \brief Read prefetch operation
- * \details Performs a read prefetch operation for the specified address
- * using the RISC-V prefetch.r instruction.
- * \param[in] addr Address to prefetch
- * \remarks Before calling this function, ensure that the hardware supports CMO prefetch
- * and that the code is compiled with the `_zicbop` extension enabled.
- * Here is a code example to check if CMO prefetch is supported:
- *
- * \code
- * if (IINFO_IsCMOPrefetchSupported()) {
- * __cmo_prefetch_r(data);
- * }
- * \endcode
- *
- * \sa
- * - \ref IINFO_IsCMOPrefetchSupported
- *
- */
- __STATIC_FORCEINLINE void __cmo_prefetch_r(const void *addr)
- {
- __ASM volatile ("prefetch.r 0(%0)" : : "r" (addr) : "memory");
- }
- /**
- * \brief Write prefetch operation
- * \details Performs a write prefetch operation for the specified address
- * using the RISC-V prefetch.w instruction.
- * \param[in] addr Address to prefetch
- * \remarks Before calling this function, ensure that the hardware supports CMO prefetch
- * and that the code is compiled with the `_zicbop` extension enabled.
- * Here is a code example to check if CMO prefetch is supported:
- *
- * \code
- * if (IINFO_IsCMOPrefetchSupported()) {
- * __cmo_prefetch_w(data);
- * }
- * \endcode
- *
- * \sa
- * - \ref IINFO_IsCMOPrefetchSupported
- *
- */
- __STATIC_FORCEINLINE void __cmo_prefetch_w(const void *addr)
- {
- __ASM volatile ("prefetch.w 0(%0)" : : "r" (addr) : "memory");
- }
- /** @} */ /* End of Doxygen Group NMSIS_Core_CPU_Intrinsic */
- #ifdef __cplusplus
- }
- #endif
- #endif /* __CORE_FEATURE_BASE__ */
|