| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759 |
- /*
- * 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 i_share_dlm:1; /*!< bit: 23 Support IFU fetch instructions from DLM */
- 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_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, SIE_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, SIE_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, SIE_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, SIE_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, SIE_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, SIE_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__ */
|