12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657 |
- /*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for
- * more details.
- */
- /**
- * @file hypervisor.h
- * The hypervisor's public API.
- */
- #ifndef _HV_HV_H
- #define _HV_HV_H
- #include <arch/chip.h>
- /* Linux builds want unsigned long constants, but assembler wants numbers */
- #ifdef __ASSEMBLER__
- /** One, for assembler */
- #define __HV_SIZE_ONE 1
- #elif !defined(__tile__) && CHIP_VA_WIDTH() > 32
- /** One, for 64-bit on host */
- #define __HV_SIZE_ONE 1ULL
- #else
- /** One, for Linux */
- #define __HV_SIZE_ONE 1UL
- #endif
- /** The log2 of the span of a level-1 page table, in bytes.
- */
- #define HV_LOG2_L1_SPAN 32
- /** The span of a level-1 page table, in bytes.
- */
- #define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
- /** The log2 of the initial size of small pages, in bytes.
- * See HV_DEFAULT_PAGE_SIZE_SMALL.
- */
- #define HV_LOG2_DEFAULT_PAGE_SIZE_SMALL 16
- /** The initial size of small pages, in bytes. This value should be verified
- * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
- * It may also be modified when installing a new context.
- */
- #define HV_DEFAULT_PAGE_SIZE_SMALL \
- (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_SMALL)
- /** The log2 of the initial size of large pages, in bytes.
- * See HV_DEFAULT_PAGE_SIZE_LARGE.
- */
- #define HV_LOG2_DEFAULT_PAGE_SIZE_LARGE 24
- /** The initial size of large pages, in bytes. This value should be verified
- * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
- * It may also be modified when installing a new context.
- */
- #define HV_DEFAULT_PAGE_SIZE_LARGE \
- (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_LARGE)
- #if CHIP_VA_WIDTH() > 32
- /** The log2 of the initial size of jumbo pages, in bytes.
- * See HV_DEFAULT_PAGE_SIZE_JUMBO.
- */
- #define HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO 32
- /** The initial size of jumbo pages, in bytes. This value should
- * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO).
- * It may also be modified when installing a new context.
- */
- #define HV_DEFAULT_PAGE_SIZE_JUMBO \
- (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO)
- #endif
- /** The log2 of the granularity at which page tables must be aligned;
- * in other words, the CPA for a page table must have this many zero
- * bits at the bottom of the address.
- */
- #define HV_LOG2_PAGE_TABLE_ALIGN 11
- /** The granularity at which page tables must be aligned.
- */
- #define HV_PAGE_TABLE_ALIGN (__HV_SIZE_ONE << HV_LOG2_PAGE_TABLE_ALIGN)
- /** Normal start of hypervisor glue in client physical memory. */
- #define HV_GLUE_START_CPA 0x10000
- /** This much space is reserved at HV_GLUE_START_CPA
- * for the hypervisor glue. The client program must start at
- * some address higher than this, and in particular the address of
- * its text section should be equal to zero modulo HV_PAGE_SIZE_LARGE
- * so that relative offsets to the HV glue are correct.
- */
- #define HV_GLUE_RESERVED_SIZE 0x10000
- /** Each entry in the hv dispatch array takes this many bytes. */
- #define HV_DISPATCH_ENTRY_SIZE 32
- /** Version of the hypervisor interface defined by this file */
- #define _HV_VERSION 13
- /** Last version of the hypervisor interface with old hv_init() ABI.
- *
- * The change from version 12 to version 13 corresponds to launching
- * the client by default at PL2 instead of PL1 (corresponding to the
- * hv itself running at PL3 instead of PL2). To make this explicit,
- * the hv_init() API was also extended so the client can report its
- * desired PL, resulting in a more helpful failure diagnostic. If you
- * call hv_init() with _HV_VERSION_OLD_HV_INIT and omit the client_pl
- * argument, the hypervisor will assume client_pl = 1.
- *
- * Note that this is a deprecated solution and we do not expect to
- * support clients of the Tilera hypervisor running at PL1 indefinitely.
- */
- #define _HV_VERSION_OLD_HV_INIT 12
- /* Index into hypervisor interface dispatch code blocks.
- *
- * Hypervisor calls are invoked from user space by calling code
- * at an address HV_BASE_ADDRESS + (index) * HV_DISPATCH_ENTRY_SIZE,
- * where index is one of these enum values.
- *
- * Normally a supervisor is expected to produce a set of symbols
- * starting at HV_BASE_ADDRESS that obey this convention, but a user
- * program could call directly through function pointers if desired.
- *
- * These numbers are part of the binary API and will not be changed
- * without updating HV_VERSION, which should be a rare event.
- */
- /** reserved. */
- #define _HV_DISPATCH_RESERVED 0
- /** hv_init */
- #define HV_DISPATCH_INIT 1
- /** hv_install_context */
- #define HV_DISPATCH_INSTALL_CONTEXT 2
- /** hv_sysconf */
- #define HV_DISPATCH_SYSCONF 3
- /** hv_get_rtc */
- #define HV_DISPATCH_GET_RTC 4
- /** hv_set_rtc */
- #define HV_DISPATCH_SET_RTC 5
- /** hv_flush_asid */
- #define HV_DISPATCH_FLUSH_ASID 6
- /** hv_flush_page */
- #define HV_DISPATCH_FLUSH_PAGE 7
- /** hv_flush_pages */
- #define HV_DISPATCH_FLUSH_PAGES 8
- /** hv_restart */
- #define HV_DISPATCH_RESTART 9
- /** hv_halt */
- #define HV_DISPATCH_HALT 10
- /** hv_power_off */
- #define HV_DISPATCH_POWER_OFF 11
- /** hv_inquire_physical */
- #define HV_DISPATCH_INQUIRE_PHYSICAL 12
- /** hv_inquire_memory_controller */
- #define HV_DISPATCH_INQUIRE_MEMORY_CONTROLLER 13
- /** hv_inquire_virtual */
- #define HV_DISPATCH_INQUIRE_VIRTUAL 14
- /** hv_inquire_asid */
- #define HV_DISPATCH_INQUIRE_ASID 15
- /** hv_nanosleep */
- #define HV_DISPATCH_NANOSLEEP 16
- /** hv_console_read_if_ready */
- #define HV_DISPATCH_CONSOLE_READ_IF_READY 17
- /** hv_console_write */
- #define HV_DISPATCH_CONSOLE_WRITE 18
- /** hv_downcall_dispatch */
- #define HV_DISPATCH_DOWNCALL_DISPATCH 19
- /** hv_inquire_topology */
- #define HV_DISPATCH_INQUIRE_TOPOLOGY 20
- /** hv_fs_findfile */
- #define HV_DISPATCH_FS_FINDFILE 21
- /** hv_fs_fstat */
- #define HV_DISPATCH_FS_FSTAT 22
- /** hv_fs_pread */
- #define HV_DISPATCH_FS_PREAD 23
- /** hv_physaddr_read64 */
- #define HV_DISPATCH_PHYSADDR_READ64 24
- /** hv_physaddr_write64 */
- #define HV_DISPATCH_PHYSADDR_WRITE64 25
- /** hv_get_command_line */
- #define HV_DISPATCH_GET_COMMAND_LINE 26
- /** hv_set_caching */
- #define HV_DISPATCH_SET_CACHING 27
- /** hv_bzero_page */
- #define HV_DISPATCH_BZERO_PAGE 28
- /** hv_register_message_state */
- #define HV_DISPATCH_REGISTER_MESSAGE_STATE 29
- /** hv_send_message */
- #define HV_DISPATCH_SEND_MESSAGE 30
- /** hv_receive_message */
- #define HV_DISPATCH_RECEIVE_MESSAGE 31
- /** hv_inquire_context */
- #define HV_DISPATCH_INQUIRE_CONTEXT 32
- /** hv_start_all_tiles */
- #define HV_DISPATCH_START_ALL_TILES 33
- /** hv_dev_open */
- #define HV_DISPATCH_DEV_OPEN 34
- /** hv_dev_close */
- #define HV_DISPATCH_DEV_CLOSE 35
- /** hv_dev_pread */
- #define HV_DISPATCH_DEV_PREAD 36
- /** hv_dev_pwrite */
- #define HV_DISPATCH_DEV_PWRITE 37
- /** hv_dev_poll */
- #define HV_DISPATCH_DEV_POLL 38
- /** hv_dev_poll_cancel */
- #define HV_DISPATCH_DEV_POLL_CANCEL 39
- /** hv_dev_preada */
- #define HV_DISPATCH_DEV_PREADA 40
- /** hv_dev_pwritea */
- #define HV_DISPATCH_DEV_PWRITEA 41
- /** hv_flush_remote */
- #define HV_DISPATCH_FLUSH_REMOTE 42
- /** hv_console_putc */
- #define HV_DISPATCH_CONSOLE_PUTC 43
- /** hv_inquire_tiles */
- #define HV_DISPATCH_INQUIRE_TILES 44
- /** hv_confstr */
- #define HV_DISPATCH_CONFSTR 45
- /** hv_reexec */
- #define HV_DISPATCH_REEXEC 46
- /** hv_set_command_line */
- #define HV_DISPATCH_SET_COMMAND_LINE 47
- #if !CHIP_HAS_IPI()
- /** hv_clear_intr */
- #define HV_DISPATCH_CLEAR_INTR 48
- /** hv_enable_intr */
- #define HV_DISPATCH_ENABLE_INTR 49
- /** hv_disable_intr */
- #define HV_DISPATCH_DISABLE_INTR 50
- /** hv_raise_intr */
- #define HV_DISPATCH_RAISE_INTR 51
- /** hv_trigger_ipi */
- #define HV_DISPATCH_TRIGGER_IPI 52
- #endif /* !CHIP_HAS_IPI() */
- /** hv_store_mapping */
- #define HV_DISPATCH_STORE_MAPPING 53
- /** hv_inquire_realpa */
- #define HV_DISPATCH_INQUIRE_REALPA 54
- /** hv_flush_all */
- #define HV_DISPATCH_FLUSH_ALL 55
- #if CHIP_HAS_IPI()
- /** hv_get_ipi_pte */
- #define HV_DISPATCH_GET_IPI_PTE 56
- #endif
- /** hv_set_pte_super_shift */
- #define HV_DISPATCH_SET_PTE_SUPER_SHIFT 57
- /** hv_console_set_ipi */
- #define HV_DISPATCH_CONSOLE_SET_IPI 63
- /** hv_send_nmi */
- #define HV_DISPATCH_SEND_NMI 65
- /** One more than the largest dispatch value */
- #define _HV_DISPATCH_END 66
- #ifndef __ASSEMBLER__
- #ifdef __KERNEL__
- #include <asm/types.h>
- typedef u32 __hv32; /**< 32-bit value */
- typedef u64 __hv64; /**< 64-bit value */
- #else
- #include <stdint.h>
- typedef uint32_t __hv32; /**< 32-bit value */
- typedef uint64_t __hv64; /**< 64-bit value */
- #endif
- /** Hypervisor physical address. */
- typedef __hv64 HV_PhysAddr;
- #if CHIP_VA_WIDTH() > 32
- /** Hypervisor virtual address. */
- typedef __hv64 HV_VirtAddr;
- #else
- /** Hypervisor virtual address. */
- typedef __hv32 HV_VirtAddr;
- #endif /* CHIP_VA_WIDTH() > 32 */
- /** Hypervisor ASID. */
- typedef unsigned int HV_ASID;
- /** Hypervisor tile location for a memory access
- * ("location overridden target").
- */
- typedef unsigned int HV_LOTAR;
- /** Hypervisor size of a page. */
- typedef unsigned long HV_PageSize;
- /** A page table entry.
- */
- typedef struct
- {
- __hv64 val; /**< Value of PTE */
- } HV_PTE;
- /** Hypervisor error code. */
- typedef int HV_Errno;
- #endif /* !__ASSEMBLER__ */
- #define HV_OK 0 /**< No error */
- #define HV_EINVAL -801 /**< Invalid argument */
- #define HV_ENODEV -802 /**< No such device */
- #define HV_ENOENT -803 /**< No such file or directory */
- #define HV_EBADF -804 /**< Bad file number */
- #define HV_EFAULT -805 /**< Bad address */
- #define HV_ERECIP -806 /**< Bad recipients */
- #define HV_E2BIG -807 /**< Message too big */
- #define HV_ENOTSUP -808 /**< Service not supported */
- #define HV_EBUSY -809 /**< Device busy */
- #define HV_ENOSYS -810 /**< Invalid syscall */
- #define HV_EPERM -811 /**< No permission */
- #define HV_ENOTREADY -812 /**< Device not ready */
- #define HV_EIO -813 /**< I/O error */
- #define HV_ENOMEM -814 /**< Out of memory */
- #define HV_EAGAIN -815 /**< Try again */
- #define HV_ERR_MAX -801 /**< Largest HV error code */
- #define HV_ERR_MIN -815 /**< Smallest HV error code */
- #ifndef __ASSEMBLER__
- /** Pass HV_VERSION to hv_init to request this version of the interface. */
- typedef enum {
- HV_VERSION = _HV_VERSION,
- HV_VERSION_OLD_HV_INIT = _HV_VERSION_OLD_HV_INIT,
- } HV_VersionNumber;
- /** Initializes the hypervisor.
- *
- * @param interface_version_number The version of the hypervisor interface
- * that this program expects, typically HV_VERSION.
- * @param chip_num Architecture number of the chip the client was built for.
- * @param chip_rev_num Revision number of the chip the client was built for.
- * @param client_pl Privilege level the client is built for
- * (not required if interface_version_number == HV_VERSION_OLD_HV_INIT).
- */
- void hv_init(HV_VersionNumber interface_version_number,
- int chip_num, int chip_rev_num, int client_pl);
- /** Queries we can make for hv_sysconf().
- *
- * These numbers are part of the binary API and guaranteed not to change.
- */
- typedef enum {
- /** An invalid value; do not use. */
- _HV_SYSCONF_RESERVED = 0,
- /** The length of the glue section containing the hv_ procs, in bytes. */
- HV_SYSCONF_GLUE_SIZE = 1,
- /** The size of small pages, in bytes. */
- HV_SYSCONF_PAGE_SIZE_SMALL = 2,
- /** The size of large pages, in bytes. */
- HV_SYSCONF_PAGE_SIZE_LARGE = 3,
- /** Processor clock speed, in hertz. */
- HV_SYSCONF_CPU_SPEED = 4,
- /** Processor temperature, in degrees Kelvin. The value
- * HV_SYSCONF_TEMP_KTOC may be subtracted from this to get degrees
- * Celsius. If that Celsius value is HV_SYSCONF_OVERTEMP, this indicates
- * that the temperature has hit an upper limit and is no longer being
- * accurately tracked.
- */
- HV_SYSCONF_CPU_TEMP = 5,
- /** Board temperature, in degrees Kelvin. The value
- * HV_SYSCONF_TEMP_KTOC may be subtracted from this to get degrees
- * Celsius. If that Celsius value is HV_SYSCONF_OVERTEMP, this indicates
- * that the temperature has hit an upper limit and is no longer being
- * accurately tracked.
- */
- HV_SYSCONF_BOARD_TEMP = 6,
- /** Legal page size bitmask for hv_install_context().
- * For example, if 16KB and 64KB small pages are supported,
- * it would return "HV_CTX_PG_SM_16K | HV_CTX_PG_SM_64K".
- */
- HV_SYSCONF_VALID_PAGE_SIZES = 7,
- /** The size of jumbo pages, in bytes.
- * If no jumbo pages are available, zero will be returned.
- */
- HV_SYSCONF_PAGE_SIZE_JUMBO = 8,
- } HV_SysconfQuery;
- /** Offset to subtract from returned Kelvin temperature to get degrees
- Celsius. */
- #define HV_SYSCONF_TEMP_KTOC 273
- /** Pseudo-temperature value indicating that the temperature has
- * pegged at its upper limit and is no longer accurate; note that this is
- * the value after subtracting HV_SYSCONF_TEMP_KTOC. */
- #define HV_SYSCONF_OVERTEMP 999
- /** Query a configuration value from the hypervisor.
- * @param query Which value is requested (HV_SYSCONF_xxx).
- * @return The requested value, or -1 the requested value is illegal or
- * unavailable.
- */
- long hv_sysconf(HV_SysconfQuery query);
- /** Queries we can make for hv_confstr().
- *
- * These numbers are part of the binary API and guaranteed not to change.
- */
- typedef enum {
- /** An invalid value; do not use. */
- _HV_CONFSTR_RESERVED = 0,
- /** Board part number. */
- HV_CONFSTR_BOARD_PART_NUM = 1,
- /** Board serial number. */
- HV_CONFSTR_BOARD_SERIAL_NUM = 2,
- /** Chip serial number. */
- HV_CONFSTR_CHIP_SERIAL_NUM = 3,
- /** Board revision level. */
- HV_CONFSTR_BOARD_REV = 4,
- /** Hypervisor software version. */
- HV_CONFSTR_HV_SW_VER = 5,
- /** The name for this chip model. */
- HV_CONFSTR_CHIP_MODEL = 6,
- /** Human-readable board description. */
- HV_CONFSTR_BOARD_DESC = 7,
- /** Human-readable description of the hypervisor configuration. */
- HV_CONFSTR_HV_CONFIG = 8,
- /** Human-readable version string for the boot image (for instance,
- * who built it and when, what configuration file was used). */
- HV_CONFSTR_HV_CONFIG_VER = 9,
- /** Mezzanine part number. */
- HV_CONFSTR_MEZZ_PART_NUM = 10,
- /** Mezzanine serial number. */
- HV_CONFSTR_MEZZ_SERIAL_NUM = 11,
- /** Mezzanine revision level. */
- HV_CONFSTR_MEZZ_REV = 12,
- /** Human-readable mezzanine description. */
- HV_CONFSTR_MEZZ_DESC = 13,
- /** Control path for the onboard network switch. */
- HV_CONFSTR_SWITCH_CONTROL = 14,
- /** Chip revision level. */
- HV_CONFSTR_CHIP_REV = 15,
- /** CPU module part number. */
- HV_CONFSTR_CPUMOD_PART_NUM = 16,
- /** CPU module serial number. */
- HV_CONFSTR_CPUMOD_SERIAL_NUM = 17,
- /** CPU module revision level. */
- HV_CONFSTR_CPUMOD_REV = 18,
- /** Human-readable CPU module description. */
- HV_CONFSTR_CPUMOD_DESC = 19,
- /** Per-tile hypervisor statistics. When this identifier is specified,
- * the hv_confstr call takes two extra arguments. The first is the
- * HV_XY_TO_LOTAR of the target tile's coordinates. The second is
- * a flag word. The only current flag is the lowest bit, which means
- * "zero out the stats instead of retrieving them"; in this case the
- * buffer and buffer length are ignored. */
- HV_CONFSTR_HV_STATS = 20
- } HV_ConfstrQuery;
- /** Query a configuration string from the hypervisor.
- *
- * @param query Identifier for the specific string to be retrieved
- * (HV_CONFSTR_xxx). Some strings may require or permit extra
- * arguments to be appended which select specific objects to be
- * described; see the string descriptions above.
- * @param buf Buffer in which to place the string.
- * @param len Length of the buffer.
- * @return If query is valid, then the length of the corresponding string,
- * including the trailing null; if this is greater than len, the string
- * was truncated. If query is invalid, HV_EINVAL. If the specified
- * buffer is not writable by the client, HV_EFAULT.
- */
- int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len, ...);
- /** Tile coordinate */
- typedef struct
- {
- /** X coordinate, relative to supervisor's top-left coordinate */
- int x;
- /** Y coordinate, relative to supervisor's top-left coordinate */
- int y;
- } HV_Coord;
- #if CHIP_HAS_IPI()
- /** Get the PTE for sending an IPI to a particular tile.
- *
- * @param tile Tile which will receive the IPI.
- * @param pl Indicates which IPI registers: 0 = IPI_0, 1 = IPI_1.
- * @param pte Filled with resulting PTE.
- * @result Zero if no error, non-zero for invalid parameters.
- */
- int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte);
- /** Configure the console interrupt.
- *
- * When the console client interrupt is enabled, the hypervisor will
- * deliver the specified IPI to the client in the following situations:
- *
- * - The console has at least one character available for input.
- *
- * - The console can accept new characters for output, and the last call
- * to hv_console_write() did not write all of the characters requested
- * by the client.
- *
- * Note that in some system configurations, console interrupt will not
- * be available; clients should be prepared for this routine to fail and
- * to fall back to periodic console polling in that case.
- *
- * @param ipi Index of the IPI register which will receive the interrupt.
- * @param event IPI event number for console interrupt. If less than 0,
- * disable the console IPI interrupt.
- * @param coord Tile to be targeted for console interrupt.
- * @return 0 on success, otherwise, HV_EINVAL if illegal parameter,
- * HV_ENOTSUP if console interrupt are not available.
- */
- int hv_console_set_ipi(int ipi, int event, HV_Coord coord);
- #else /* !CHIP_HAS_IPI() */
- /** A set of interrupts. */
- typedef __hv32 HV_IntrMask;
- /** The low interrupt numbers are reserved for use by the client in
- * delivering IPIs. Any interrupt numbers higher than this value are
- * reserved for use by HV device drivers. */
- #define HV_MAX_IPI_INTERRUPT 7
- /** Enable a set of device interrupts.
- *
- * @param enab_mask Bitmap of interrupts to enable.
- */
- void hv_enable_intr(HV_IntrMask enab_mask);
- /** Disable a set of device interrupts.
- *
- * @param disab_mask Bitmap of interrupts to disable.
- */
- void hv_disable_intr(HV_IntrMask disab_mask);
- /** Clear a set of device interrupts.
- *
- * @param clear_mask Bitmap of interrupts to clear.
- */
- void hv_clear_intr(HV_IntrMask clear_mask);
- /** Raise a set of device interrupts.
- *
- * @param raise_mask Bitmap of interrupts to raise.
- */
- void hv_raise_intr(HV_IntrMask raise_mask);
- /** Trigger a one-shot interrupt on some tile
- *
- * @param tile Which tile to interrupt.
- * @param interrupt Interrupt number to trigger; must be between 0 and
- * HV_MAX_IPI_INTERRUPT.
- * @return HV_OK on success, or a hypervisor error code.
- */
- HV_Errno hv_trigger_ipi(HV_Coord tile, int interrupt);
- #endif /* !CHIP_HAS_IPI() */
- /** Store memory mapping in debug memory so that external debugger can read it.
- * A maximum of 16 entries can be stored.
- *
- * @param va VA of memory that is mapped.
- * @param len Length of mapped memory.
- * @param pa PA of memory that is mapped.
- * @return 0 on success, -1 if the maximum number of mappings is exceeded.
- */
- int hv_store_mapping(HV_VirtAddr va, unsigned int len, HV_PhysAddr pa);
- /** Given a client PA and a length, return its real (HV) PA.
- *
- * @param cpa Client physical address.
- * @param len Length of mapped memory.
- * @return physical address, or -1 if cpa or len is not valid.
- */
- HV_PhysAddr hv_inquire_realpa(HV_PhysAddr cpa, unsigned int len);
- /** RTC return flag for no RTC chip present.
- */
- #define HV_RTC_NO_CHIP 0x1
- /** RTC return flag for low-voltage condition, indicating that battery had
- * died and time read is unreliable.
- */
- #define HV_RTC_LOW_VOLTAGE 0x2
- /** Date/Time of day */
- typedef struct {
- #if CHIP_WORD_SIZE() > 32
- __hv64 tm_sec; /**< Seconds, 0-59 */
- __hv64 tm_min; /**< Minutes, 0-59 */
- __hv64 tm_hour; /**< Hours, 0-23 */
- __hv64 tm_mday; /**< Day of month, 0-30 */
- __hv64 tm_mon; /**< Month, 0-11 */
- __hv64 tm_year; /**< Years since 1900, 0-199 */
- __hv64 flags; /**< Return flags, 0 if no error */
- #else
- __hv32 tm_sec; /**< Seconds, 0-59 */
- __hv32 tm_min; /**< Minutes, 0-59 */
- __hv32 tm_hour; /**< Hours, 0-23 */
- __hv32 tm_mday; /**< Day of month, 0-30 */
- __hv32 tm_mon; /**< Month, 0-11 */
- __hv32 tm_year; /**< Years since 1900, 0-199 */
- __hv32 flags; /**< Return flags, 0 if no error */
- #endif
- } HV_RTCTime;
- /** Read the current time-of-day clock.
- * @return HV_RTCTime of current time (GMT).
- */
- HV_RTCTime hv_get_rtc(void);
- /** Set the current time-of-day clock.
- * @param time time to reset time-of-day to (GMT).
- */
- void hv_set_rtc(HV_RTCTime time);
- /** Installs a context, comprising a page table and other attributes.
- *
- * Once this service completes, page_table will be used to translate
- * subsequent virtual address references to physical memory.
- *
- * Installing a context does not cause an implicit TLB flush. Before
- * reusing an ASID value for a different address space, the client is
- * expected to flush old references from the TLB with hv_flush_asid().
- * (Alternately, hv_flush_all() may be used to flush many ASIDs at once.)
- * After invalidating a page table entry, changing its attributes, or
- * changing its target CPA, the client is expected to flush old references
- * from the TLB with hv_flush_page() or hv_flush_pages(). Making a
- * previously invalid page valid does not require a flush.
- *
- * Specifying an invalid ASID, or an invalid CPA (client physical address)
- * (either as page_table_pointer, or within the referenced table),
- * or another page table data item documented as above as illegal may
- * lead to client termination; since the validation of the table is
- * done as needed, this may happen before the service returns, or at
- * some later time, or never, depending upon the client's pattern of
- * memory references. Page table entries which supply translations for
- * invalid virtual addresses may result in client termination, or may
- * be silently ignored. "Invalid" in this context means a value which
- * was not provided to the client via the appropriate hv_inquire_* routine.
- *
- * To support changing the instruction VAs at the same time as
- * installing the new page table, this call explicitly supports
- * setting the "lr" register to a different address and then jumping
- * directly to the hv_install_context() routine. In this case, the
- * new page table does not need to contain any mapping for the
- * hv_install_context address itself.
- *
- * At most one HV_CTX_PG_SM_* flag may be specified in "flags";
- * if multiple flags are specified, HV_EINVAL is returned.
- * Specifying none of the flags results in using the default page size.
- * All cores participating in a given client must request the same
- * page size, or the results are undefined.
- *
- * @param page_table Root of the page table.
- * @param access PTE providing info on how to read the page table. This
- * value must be consistent between multiple tiles sharing a page table,
- * and must also be consistent with any virtual mappings the client
- * may be using to access the page table.
- * @param asid HV_ASID the page table is to be used for.
- * @param flags Context flags, denoting attributes or privileges of the
- * current context (HV_CTX_xxx).
- * @return Zero on success, or a hypervisor error code on failure.
- */
- int hv_install_context(HV_PhysAddr page_table, HV_PTE access, HV_ASID asid,
- __hv32 flags);
- #endif /* !__ASSEMBLER__ */
- #define HV_CTX_DIRECTIO 0x1 /**< Direct I/O requests are accepted from
- PL0. */
- #define HV_CTX_PG_SM_4K 0x10 /**< Use 4K small pages, if available. */
- #define HV_CTX_PG_SM_16K 0x20 /**< Use 16K small pages, if available. */
- #define HV_CTX_PG_SM_64K 0x40 /**< Use 64K small pages, if available. */
- #define HV_CTX_PG_SM_MASK 0xf0 /**< Mask of all possible small pages. */
- #ifndef __ASSEMBLER__
- /** Set the number of pages ganged together by HV_PTE_SUPER at a
- * particular level of the page table.
- *
- * The current TILE-Gx hardware only supports powers of four
- * (i.e. log2_count must be a multiple of two), and the requested
- * "super" page size must be less than the span of the next level in
- * the page table. The largest size that can be requested is 64GB.
- *
- * The shift value is initially "0" for all page table levels,
- * indicating that the HV_PTE_SUPER bit is effectively ignored.
- *
- * If you change the count from one non-zero value to another, the
- * hypervisor will flush the entire TLB and TSB to avoid confusion.
- *
- * @param level Page table level (0, 1, or 2)
- * @param log2_count Base-2 log of the number of pages to gang together,
- * i.e. how much to shift left the base page size for the super page size.
- * @return Zero on success, or a hypervisor error code on failure.
- */
- int hv_set_pte_super_shift(int level, int log2_count);
- /** Value returned from hv_inquire_context(). */
- typedef struct
- {
- /** Physical address of page table */
- HV_PhysAddr page_table;
- /** PTE which defines access method for top of page table */
- HV_PTE access;
- /** ASID associated with this page table */
- HV_ASID asid;
- /** Context flags */
- __hv32 flags;
- } HV_Context;
- /** Retrieve information about the currently installed context.
- * @return The data passed to the last successful hv_install_context call.
- */
- HV_Context hv_inquire_context(void);
- /** Flushes all translations associated with the named address space
- * identifier from the TLB and any other hypervisor data structures.
- * Translations installed with the "global" bit are not flushed.
- *
- * Specifying an invalid ASID may lead to client termination. "Invalid"
- * in this context means a value which was not provided to the client
- * via <tt>hv_inquire_asid()</tt>.
- *
- * @param asid HV_ASID whose entries are to be flushed.
- * @return Zero on success, or a hypervisor error code on failure.
- */
- int hv_flush_asid(HV_ASID asid);
- /** Flushes all translations associated with the named virtual address
- * and page size from the TLB and other hypervisor data structures. Only
- * pages visible to the current ASID are affected; note that this includes
- * global pages in addition to pages specific to the current ASID.
- *
- * The supplied VA need not be aligned; it may be anywhere in the
- * subject page.
- *
- * Specifying an invalid virtual address may lead to client termination,
- * or may silently succeed. "Invalid" in this context means a value
- * which was not provided to the client via hv_inquire_virtual.
- *
- * @param address Address of the page to flush.
- * @param page_size Size of pages to assume.
- * @return Zero on success, or a hypervisor error code on failure.
- */
- int hv_flush_page(HV_VirtAddr address, HV_PageSize page_size);
- /** Flushes all translations associated with the named virtual address range
- * and page size from the TLB and other hypervisor data structures. Only
- * pages visible to the current ASID are affected; note that this includes
- * global pages in addition to pages specific to the current ASID.
- *
- * The supplied VA need not be aligned; it may be anywhere in the
- * subject page.
- *
- * Specifying an invalid virtual address may lead to client termination,
- * or may silently succeed. "Invalid" in this context means a value
- * which was not provided to the client via hv_inquire_virtual.
- *
- * @param start Address to flush.
- * @param page_size Size of pages to assume.
- * @param size The number of bytes to flush. Any page in the range
- * [start, start + size) will be flushed from the TLB.
- * @return Zero on success, or a hypervisor error code on failure.
- */
- int hv_flush_pages(HV_VirtAddr start, HV_PageSize page_size,
- unsigned long size);
- /** Flushes all non-global translations (if preserve_global is true),
- * or absolutely all translations (if preserve_global is false).
- *
- * @param preserve_global Non-zero if we want to preserve "global" mappings.
- * @return Zero on success, or a hypervisor error code on failure.
- */
- int hv_flush_all(int preserve_global);
- /** Restart machine with optional restart command and optional args.
- * @param cmd Const pointer to command to restart with, or NULL
- * @param args Const pointer to argument string to restart with, or NULL
- */
- void hv_restart(HV_VirtAddr cmd, HV_VirtAddr args);
- /** Halt machine. */
- void hv_halt(void);
- /** Power off machine. */
- void hv_power_off(void);
- /** Re-enter virtual-is-physical memory translation mode and restart
- * execution at a given address.
- * @param entry Client physical address at which to begin execution.
- * @return A hypervisor error code on failure; if the operation is
- * successful the call does not return.
- */
- int hv_reexec(HV_PhysAddr entry);
- /** Chip topology */
- typedef struct
- {
- /** Relative coordinates of the querying tile */
- HV_Coord coord;
- /** Width of the querying supervisor's tile rectangle. */
- int width;
- /** Height of the querying supervisor's tile rectangle. */
- int height;
- } HV_Topology;
- /** Returns information about the tile coordinate system.
- *
- * Each supervisor is given a rectangle of tiles it potentially controls.
- * These tiles are labeled using a relative coordinate system with (0,0) as
- * the upper left tile regardless of their physical location on the chip.
- *
- * This call returns both the size of that rectangle and the position
- * within that rectangle of the querying tile.
- *
- * Not all tiles within that rectangle may be available to the supervisor;
- * to get the precise set of available tiles, you must also call
- * hv_inquire_tiles(HV_INQ_TILES_AVAIL, ...).
- **/
- HV_Topology hv_inquire_topology(void);
- /** Sets of tiles we can retrieve with hv_inquire_tiles().
- *
- * These numbers are part of the binary API and guaranteed not to change.
- */
- typedef enum {
- /** An invalid value; do not use. */
- _HV_INQ_TILES_RESERVED = 0,
- /** All available tiles within the supervisor's tile rectangle. */
- HV_INQ_TILES_AVAIL = 1,
- /** The set of tiles used for hash-for-home caching. */
- HV_INQ_TILES_HFH_CACHE = 2,
- /** The set of tiles that can be legally used as a LOTAR for a PTE. */
- HV_INQ_TILES_LOTAR = 3,
- /** The set of "shared" driver tiles that the hypervisor may
- * periodically interrupt. */
- HV_INQ_TILES_SHARED = 4
- } HV_InqTileSet;
- /** Returns specific information about various sets of tiles within the
- * supervisor's tile rectangle.
- *
- * @param set Which set of tiles to retrieve.
- * @param cpumask Pointer to a returned bitmask (in row-major order,
- * supervisor-relative) of tiles. The low bit of the first word
- * corresponds to the tile at the upper left-hand corner of the
- * supervisor's rectangle. In order for the supervisor to know the
- * buffer length to supply, it should first call hv_inquire_topology.
- * @param length Number of bytes available for the returned bitmask.
- **/
- HV_Errno hv_inquire_tiles(HV_InqTileSet set, HV_VirtAddr cpumask, int length);
- /** An identifier for a memory controller. Multiple memory controllers
- * may be connected to one chip, and this uniquely identifies each one.
- */
- typedef int HV_MemoryController;
- /** A range of physical memory. */
- typedef struct
- {
- HV_PhysAddr start; /**< Starting address. */
- __hv64 size; /**< Size in bytes. */
- HV_MemoryController controller; /**< Which memory controller owns this. */
- } HV_PhysAddrRange;
- /** Returns information about a range of physical memory.
- *
- * hv_inquire_physical() returns one of the ranges of client
- * physical addresses which are available to this client.
- *
- * The first range is retrieved by specifying an idx of 0, and
- * successive ranges are returned with subsequent idx values. Ranges
- * are ordered by increasing start address (i.e., as idx increases,
- * so does start), do not overlap, and do not touch (i.e., the
- * available memory is described with the fewest possible ranges).
- *
- * If an out-of-range idx value is specified, the returned size will be zero.
- * A client can count the number of ranges by increasing idx until the
- * returned size is zero. There will always be at least one valid range.
- *
- * Some clients might not be prepared to deal with more than one
- * physical address range; they still ought to call this routine and
- * issue a warning message if they're given more than one range, on the
- * theory that whoever configured the hypervisor to provide that memory
- * should know that it's being wasted.
- */
- HV_PhysAddrRange hv_inquire_physical(int idx);
- /** Possible DIMM types. */
- typedef enum
- {
- NO_DIMM = 0, /**< No DIMM */
- DDR2 = 1, /**< DDR2 */
- DDR3 = 2 /**< DDR3 */
- } HV_DIMM_Type;
- #ifdef __tilegx__
- /** Log2 of minimum DIMM bytes supported by the memory controller. */
- #define HV_MSH_MIN_DIMM_SIZE_SHIFT 29
- /** Max number of DIMMs contained by one memory controller. */
- #define HV_MSH_MAX_DIMMS 8
- #else
- /** Log2 of minimum DIMM bytes supported by the memory controller. */
- #define HV_MSH_MIN_DIMM_SIZE_SHIFT 26
- /** Max number of DIMMs contained by one memory controller. */
- #define HV_MSH_MAX_DIMMS 2
- #endif
- /** Number of bits to right-shift to get the DIMM type. */
- #define HV_DIMM_TYPE_SHIFT 0
- /** Bits to mask to get the DIMM type. */
- #define HV_DIMM_TYPE_MASK 0xf
- /** Number of bits to right-shift to get the DIMM size. */
- #define HV_DIMM_SIZE_SHIFT 4
- /** Bits to mask to get the DIMM size. */
- #define HV_DIMM_SIZE_MASK 0xf
- /** Memory controller information. */
- typedef struct
- {
- HV_Coord coord; /**< Relative tile coordinates of the port used by a
- specified tile to communicate with this controller. */
- __hv64 speed; /**< Speed of this controller in bytes per second. */
- } HV_MemoryControllerInfo;
- /** Returns information about a particular memory controller.
- *
- * hv_inquire_memory_controller(coord,idx) returns information about a
- * particular controller. Two pieces of information are returned:
- * - The relative coordinates of the port on the controller that the specified
- * tile would use to contact it. The relative coordinates may lie
- * outside the supervisor's rectangle, i.e. the controller may not
- * be attached to a node managed by the querying node's supervisor.
- * In particular note that x or y may be negative.
- * - The speed of the memory controller. (This is a not-to-exceed value
- * based on the raw hardware data rate, and may not be achievable in
- * practice; it is provided to give clients information on the relative
- * performance of the available controllers.)
- *
- * Clients should avoid calling this interface with invalid values.
- * A client who does may be terminated.
- * @param coord Tile for which to calculate the relative port position.
- * @param controller Index of the controller; identical to value returned
- * from other routines like hv_inquire_physical.
- * @return Information about the controller.
- */
- HV_MemoryControllerInfo hv_inquire_memory_controller(HV_Coord coord,
- int controller);
- /** A range of virtual memory. */
- typedef struct
- {
- HV_VirtAddr start; /**< Starting address. */
- __hv64 size; /**< Size in bytes. */
- } HV_VirtAddrRange;
- /** Returns information about a range of virtual memory.
- *
- * hv_inquire_virtual() returns one of the ranges of client
- * virtual addresses which are available to this client.
- *
- * The first range is retrieved by specifying an idx of 0, and
- * successive ranges are returned with subsequent idx values. Ranges
- * are ordered by increasing start address (i.e., as idx increases,
- * so does start), do not overlap, and do not touch (i.e., the
- * available memory is described with the fewest possible ranges).
- *
- * If an out-of-range idx value is specified, the returned size will be zero.
- * A client can count the number of ranges by increasing idx until the
- * returned size is zero. There will always be at least one valid range.
- *
- * Some clients may well have various virtual addresses hardwired
- * into themselves; for instance, their instruction stream may
- * have been compiled expecting to live at a particular address.
- * Such clients should use this interface to verify they've been
- * given the virtual address space they expect, and issue a (potentially
- * fatal) warning message otherwise.
- *
- * Note that the returned size is a __hv64, not a __hv32, so it is
- * possible to express a single range spanning the entire 32-bit
- * address space.
- */
- HV_VirtAddrRange hv_inquire_virtual(int idx);
- /** A range of ASID values. */
- typedef struct
- {
- HV_ASID start; /**< First ASID in the range. */
- unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
- } HV_ASIDRange;
- /** Returns information about a range of ASIDs.
- *
- * hv_inquire_asid() returns one of the ranges of address
- * space identifiers which are available to this client.
- *
- * The first range is retrieved by specifying an idx of 0, and
- * successive ranges are returned with subsequent idx values. Ranges
- * are ordered by increasing start value (i.e., as idx increases,
- * so does start), do not overlap, and do not touch (i.e., the
- * available ASIDs are described with the fewest possible ranges).
- *
- * If an out-of-range idx value is specified, the returned size will be zero.
- * A client can count the number of ranges by increasing idx until the
- * returned size is zero. There will always be at least one valid range.
- */
- HV_ASIDRange hv_inquire_asid(int idx);
- /** Waits for at least the specified number of nanoseconds then returns.
- *
- * NOTE: this deprecated function currently assumes a 750 MHz clock,
- * and is thus not generally suitable for use. New code should call
- * hv_sysconf(HV_SYSCONF_CPU_SPEED), compute a cycle count to wait for,
- * and delay by looping while checking the cycle counter SPR.
- *
- * @param nanosecs The number of nanoseconds to sleep.
- */
- void hv_nanosleep(int nanosecs);
- /** Reads a character from the console without blocking.
- *
- * @return A value from 0-255 indicates the value successfully read.
- * A negative value means no value was ready.
- */
- int hv_console_read_if_ready(void);
- /** Writes a character to the console, blocking if the console is busy.
- *
- * This call cannot fail. If the console is broken for some reason,
- * output will simply vanish.
- * @param byte Character to write.
- */
- void hv_console_putc(int byte);
- /** Writes a string to the console, blocking if the console is busy.
- * @param bytes Pointer to characters to write.
- * @param len Number of characters to write.
- * @return Number of characters written, or HV_EFAULT if the buffer is invalid.
- */
- int hv_console_write(HV_VirtAddr bytes, int len);
- /** Dispatch the next interrupt from the client downcall mechanism.
- *
- * The hypervisor uses downcalls to notify the client of asynchronous
- * events. Some of these events are hypervisor-created (like incoming
- * messages). Some are regular interrupts which initially occur in
- * the hypervisor, and are normally handled directly by the client;
- * when these occur in a client's interrupt critical section, they must
- * be delivered through the downcall mechanism.
- *
- * A downcall is initially delivered to the client as an INTCTRL_CL
- * interrupt, where CL is the client's PL. Upon entry to the INTCTRL_CL
- * vector, the client must immediately invoke the hv_downcall_dispatch
- * service. This service will not return; instead it will cause one of
- * the client's actual downcall-handling interrupt vectors to be entered.
- * The EX_CONTEXT registers in the client will be set so that when the
- * client irets, it will return to the code which was interrupted by the
- * INTCTRL_CL interrupt.
- *
- * Under some circumstances, the firing of INTCTRL_CL can race with
- * the lowering of a device interrupt. In such a case, the
- * hv_downcall_dispatch service may issue an iret instruction instead
- * of entering one of the client's actual downcall-handling interrupt
- * vectors. This will return execution to the location that was
- * interrupted by INTCTRL_CL.
- *
- * Any saving of registers should be done by the actual handling
- * vectors; no registers should be changed by the INTCTRL_CL handler.
- * In particular, the client should not use a jal instruction to invoke
- * the hv_downcall_dispatch service, as that would overwrite the client's
- * lr register. Note that the hv_downcall_dispatch service may overwrite
- * one or more of the client's system save registers.
- *
- * The client must not modify the INTCTRL_CL_STATUS SPR. The hypervisor
- * will set this register to cause a downcall to happen, and will clear
- * it when no further downcalls are pending.
- *
- * When a downcall vector is entered, the INTCTRL_CL interrupt will be
- * masked. When the client is done processing a downcall, and is ready
- * to accept another, it must unmask this interrupt; if more downcalls
- * are pending, this will cause the INTCTRL_CL vector to be reentered.
- * Currently the following interrupt vectors can be entered through a
- * downcall:
- *
- * INT_MESSAGE_RCV_DWNCL (hypervisor message available)
- * INT_DEV_INTR_DWNCL (device interrupt)
- * INT_DMATLB_MISS_DWNCL (DMA TLB miss)
- * INT_SNITLB_MISS_DWNCL (SNI TLB miss)
- * INT_DMATLB_ACCESS_DWNCL (DMA TLB access violation)
- */
- void hv_downcall_dispatch(void);
- #endif /* !__ASSEMBLER__ */
- /** We use actual interrupt vectors which never occur (they're only there
- * to allow setting MPLs for related SPRs) for our downcall vectors.
- */
- /** Message receive downcall interrupt vector */
- #define INT_MESSAGE_RCV_DWNCL INT_BOOT_ACCESS
- /** DMA TLB miss downcall interrupt vector */
- #define INT_DMATLB_MISS_DWNCL INT_DMA_ASID
- /** Static nework processor instruction TLB miss interrupt vector */
- #define INT_SNITLB_MISS_DWNCL INT_SNI_ASID
- /** DMA TLB access violation downcall interrupt vector */
- #define INT_DMATLB_ACCESS_DWNCL INT_DMA_CPL
- /** Device interrupt downcall interrupt vector */
- #define INT_DEV_INTR_DWNCL INT_WORLD_ACCESS
- /** NMI downcall interrupt vector */
- #define INT_NMI_DWNCL 64
- #define HV_NMI_FLAG_FORCE 0x1 /**< Force an NMI downcall regardless of
- the ICS bit of the client. */
- #ifndef __ASSEMBLER__
- /** Requests the inode for a specific full pathname.
- *
- * Performs a lookup in the hypervisor filesystem for a given filename.
- * Multiple calls with the same filename will always return the same inode.
- * If there is no such filename, HV_ENOENT is returned.
- * A bad filename pointer may result in HV_EFAULT instead.
- *
- * @param filename Constant pointer to name of requested file
- * @return Inode of requested file
- */
- int hv_fs_findfile(HV_VirtAddr filename);
- /** Data returned from an fstat request.
- * Note that this structure should be no more than 40 bytes in size so
- * that it can always be returned completely in registers.
- */
- typedef struct
- {
- int size; /**< Size of file (or HV_Errno on error) */
- unsigned int flags; /**< Flags (see HV_FS_FSTAT_FLAGS) */
- } HV_FS_StatInfo;
- /** Bitmask flags for fstat request */
- typedef enum
- {
- HV_FS_ISDIR = 0x0001 /**< Is the entry a directory? */
- } HV_FS_FSTAT_FLAGS;
- /** Get stat information on a given file inode.
- *
- * Return information on the file with the given inode.
- *
- * IF the HV_FS_ISDIR bit is set, the "file" is a directory. Reading
- * it will return NUL-separated filenames (no directory part) relative
- * to the path to the inode of the directory "file". These can be
- * appended to the path to the directory "file" after a forward slash
- * to create additional filenames. Note that it is not required
- * that all valid paths be decomposable into valid parent directories;
- * a filesystem may validly have just a few files, none of which have
- * HV_FS_ISDIR set. However, if clients may wish to enumerate the
- * files in the filesystem, it is recommended to include all the
- * appropriate parent directory "files" to give a consistent view.
- *
- * An invalid file inode will cause an HV_EBADF error to be returned.
- *
- * @param inode The inode number of the query
- * @return An HV_FS_StatInfo structure
- */
- HV_FS_StatInfo hv_fs_fstat(int inode);
- /** Read data from a specific hypervisor file.
- * On error, may return HV_EBADF for a bad inode or HV_EFAULT for a bad buf.
- * Reads near the end of the file will return fewer bytes than requested.
- * Reads at or beyond the end of a file will return zero.
- *
- * @param inode the hypervisor file to read
- * @param buf the buffer to read data into
- * @param length the number of bytes of data to read
- * @param offset the offset into the file to read the data from
- * @return number of bytes successfully read, or an HV_Errno code
- */
- int hv_fs_pread(int inode, HV_VirtAddr buf, int length, int offset);
- /** Read a 64-bit word from the specified physical address.
- * The address must be 8-byte aligned.
- * Specifying an invalid physical address will lead to client termination.
- * @param addr The physical address to read
- * @param access The PTE describing how to read the memory
- * @return The 64-bit value read from the given address
- */
- unsigned long long hv_physaddr_read64(HV_PhysAddr addr, HV_PTE access);
- /** Write a 64-bit word to the specified physical address.
- * The address must be 8-byte aligned.
- * Specifying an invalid physical address will lead to client termination.
- * @param addr The physical address to write
- * @param access The PTE that says how to write the memory
- * @param val The 64-bit value to write to the given address
- */
- void hv_physaddr_write64(HV_PhysAddr addr, HV_PTE access,
- unsigned long long val);
- /** Get the value of the command-line for the supervisor, if any.
- * This will not include the filename of the booted supervisor, but may
- * include configured-in boot arguments or the hv_restart() arguments.
- * If the buffer is not long enough the hypervisor will NUL the first
- * character of the buffer but not write any other data.
- * @param buf The virtual address to write the command-line string to.
- * @param length The length of buf, in characters.
- * @return The actual length of the command line, including the trailing NUL
- * (may be larger than "length").
- */
- int hv_get_command_line(HV_VirtAddr buf, int length);
- /** Set a new value for the command-line for the supervisor, which will
- * be returned from subsequent invocations of hv_get_command_line() on
- * this tile.
- * @param buf The virtual address to read the command-line string from.
- * @param length The length of buf, in characters; must be no more than
- * HV_COMMAND_LINE_LEN.
- * @return Zero if successful, or a hypervisor error code.
- */
- HV_Errno hv_set_command_line(HV_VirtAddr buf, int length);
- /** Maximum size of a command line passed to hv_set_command_line(); note
- * that a line returned from hv_get_command_line() could be larger than
- * this.*/
- #define HV_COMMAND_LINE_LEN 256
- /** Tell the hypervisor how to cache non-priority pages
- * (its own as well as pages explicitly represented in page tables).
- * Normally these will be represented as red/black pages, but
- * when the supervisor starts to allocate "priority" pages in the PTE
- * the hypervisor will need to start marking those pages as (e.g.) "red"
- * and non-priority pages as either "black" (if they cache-alias
- * with the existing priority pages) or "red/black" (if they don't).
- * The bitmask provides information on which parts of the cache
- * have been used for pinned pages so far on this tile; if (1 << N)
- * appears in the bitmask, that indicates that a 4KB region of the
- * cache starting at (N * 4KB) is in use by a "priority" page.
- * The portion of cache used by a particular page can be computed
- * by taking the page's PA, modulo CHIP_L2_CACHE_SIZE(), and setting
- * all the "4KB" bits corresponding to the actual page size.
- * @param bitmask A bitmap of priority page set values
- */
- void hv_set_caching(unsigned long bitmask);
- /** Zero out a specified number of pages.
- * The va and size must both be multiples of 4096.
- * Caches are bypassed and memory is directly set to zero.
- * This API is implemented only in the magic hypervisor and is intended
- * to provide a performance boost to the minimal supervisor by
- * giving it a fast way to zero memory pages when allocating them.
- * @param va Virtual address where the page has been mapped
- * @param size Number of bytes (must be a page size multiple)
- */
- void hv_bzero_page(HV_VirtAddr va, unsigned int size);
- /** State object for the hypervisor messaging subsystem. */
- typedef struct
- {
- #if CHIP_VA_WIDTH() > 32
- __hv64 opaque[2]; /**< No user-serviceable parts inside */
- #else
- __hv32 opaque[2]; /**< No user-serviceable parts inside */
- #endif
- }
- HV_MsgState;
- /** Register to receive incoming messages.
- *
- * This routine configures the current tile so that it can receive
- * incoming messages. It must be called before the client can receive
- * messages with the hv_receive_message routine, and must be called on
- * each tile which will receive messages.
- *
- * msgstate is the virtual address of a state object of type HV_MsgState.
- * Once the state is registered, the client must not read or write the
- * state object; doing so will cause undefined results.
- *
- * If this routine is called with msgstate set to 0, the client's message
- * state will be freed and it will no longer be able to receive messages.
- * Note that this may cause the loss of any as-yet-undelivered messages
- * for the client.
- *
- * If another client attempts to send a message to a client which has
- * not yet called hv_register_message_state, or which has freed its
- * message state, the message will not be delivered, as if the client
- * had insufficient buffering.
- *
- * This routine returns HV_OK if the registration was successful, and
- * HV_EINVAL if the supplied state object is unsuitable. Note that some
- * errors may not be detected during this routine, but might be detected
- * during a subsequent message delivery.
- * @param msgstate State object.
- **/
- HV_Errno hv_register_message_state(HV_MsgState* msgstate);
- /** Possible message recipient states. */
- typedef enum
- {
- HV_TO_BE_SENT, /**< Not sent (not attempted, or recipient not ready) */
- HV_SENT, /**< Successfully sent */
- HV_BAD_RECIP /**< Bad recipient coordinates (permanent error) */
- } HV_Recip_State;
- /** Message recipient. */
- typedef struct
- {
- /** X coordinate, relative to supervisor's top-left coordinate */
- unsigned int x:11;
- /** Y coordinate, relative to supervisor's top-left coordinate */
- unsigned int y:11;
- /** Status of this recipient */
- HV_Recip_State state:10;
- } HV_Recipient;
- /** Send a message to a set of recipients.
- *
- * This routine sends a message to a set of recipients.
- *
- * recips is an array of HV_Recipient structures. Each specifies a tile,
- * and a message state; initially, it is expected that the state will
- * be set to HV_TO_BE_SENT. nrecip specifies the number of recipients
- * in the recips array.
- *
- * For each recipient whose state is HV_TO_BE_SENT, the hypervisor attempts
- * to send that tile the specified message. In order to successfully
- * receive the message, the receiver must be a valid tile to which the
- * sender has access, must not be the sending tile itself, and must have
- * sufficient free buffer space. (The hypervisor guarantees that each
- * tile which has called hv_register_message_state() will be able to
- * buffer one message from every other tile which can legally send to it;
- * more space may be provided but is not guaranteed.) If an invalid tile
- * is specified, the recipient's state is set to HV_BAD_RECIP; this is a
- * permanent delivery error. If the message is successfully delivered
- * to the recipient's buffer, the recipient's state is set to HV_SENT.
- * Otherwise, the recipient's state is unchanged. Message delivery is
- * synchronous; all attempts to send messages are completed before this
- * routine returns.
- *
- * If no permanent delivery errors were encountered, the routine returns
- * the number of messages successfully sent: that is, the number of
- * recipients whose states changed from HV_TO_BE_SENT to HV_SENT during
- * this operation. If any permanent delivery errors were encountered,
- * the routine returns HV_ERECIP. In the event of permanent delivery
- * errors, it may be the case that delivery was not attempted to all
- * recipients; if any messages were successfully delivered, however,
- * recipients' state values will be updated appropriately.
- *
- * It is explicitly legal to specify a recipient structure whose state
- * is not HV_TO_BE_SENT; such a recipient is ignored. One suggested way
- * of using hv_send_message to send a message to multiple tiles is to set
- * up a list of recipients, and then call the routine repeatedly with the
- * same list, each time accumulating the number of messages successfully
- * sent, until all messages are sent, a permanent error is encountered,
- * or the desired number of attempts have been made. When used in this
- * way, the routine will deliver each message no more than once to each
- * recipient.
- *
- * Note that a message being successfully delivered to the recipient's
- * buffer space does not guarantee that it is received by the recipient,
- * either immediately or at any time in the future; the recipient might
- * never call hv_receive_message, or could register a different state
- * buffer, losing the message.
- *
- * Specifying the same recipient more than once in the recipient list
- * is an error, which will not result in an error return but which may
- * or may not result in more than one message being delivered to the
- * recipient tile.
- *
- * buf and buflen specify the message to be sent. buf is a virtual address
- * which must be currently mapped in the client's page table; if not, the
- * routine returns HV_EFAULT. buflen must be greater than zero and less
- * than or equal to HV_MAX_MESSAGE_SIZE, and nrecip must be less than the
- * number of tiles to which the sender has access; if not, the routine
- * returns HV_EINVAL.
- * @param recips List of recipients.
- * @param nrecip Number of recipients.
- * @param buf Address of message data.
- * @param buflen Length of message data.
- **/
- int hv_send_message(HV_Recipient *recips, int nrecip,
- HV_VirtAddr buf, int buflen);
- /** Maximum hypervisor message size, in bytes */
- #define HV_MAX_MESSAGE_SIZE 28
- /** Return value from hv_receive_message() */
- typedef struct
- {
- int msglen; /**< Message length in bytes, or an error code */
- __hv32 source; /**< Code identifying message sender (HV_MSG_xxx) */
- } HV_RcvMsgInfo;
- #define HV_MSG_TILE 0x0 /**< Message source is another tile */
- #define HV_MSG_INTR 0x1 /**< Message source is a driver interrupt */
- /** Receive a message.
- *
- * This routine retrieves a message from the client's incoming message
- * buffer.
- *
- * Multiple messages sent from a particular sending tile to a particular
- * receiving tile are received in the order that they were sent; however,
- * no ordering is guaranteed between messages sent by different tiles.
- *
- * Whenever the a client's message buffer is empty, the first message
- * subsequently received will cause the client's MESSAGE_RCV_DWNCL
- * interrupt vector to be invoked through the interrupt downcall mechanism
- * (see the description of the hv_downcall_dispatch() routine for details
- * on downcalls).
- *
- * Another message-available downcall will not occur until a call to
- * this routine is made when the message buffer is empty, and a message
- * subsequently arrives. Note that such a downcall could occur while
- * this routine is executing. If the calling code does not wish this
- * to happen, it is recommended that this routine be called with the
- * INTCTRL_1 interrupt masked, or inside an interrupt critical section.
- *
- * msgstate is the value previously passed to hv_register_message_state().
- * buf is the virtual address of the buffer into which the message will
- * be written; buflen is the length of the buffer.
- *
- * This routine returns an HV_RcvMsgInfo structure. The msglen member
- * of that structure is the length of the message received, zero if no
- * message is available, or HV_E2BIG if the message is too large for the
- * specified buffer. If the message is too large, it is not consumed,
- * and may be retrieved by a subsequent call to this routine specifying
- * a sufficiently large buffer. A buffer which is HV_MAX_MESSAGE_SIZE
- * bytes long is guaranteed to be able to receive any possible message.
- *
- * The source member of the HV_RcvMsgInfo structure describes the sender
- * of the message. For messages sent by another client tile via an
- * hv_send_message() call, this value is HV_MSG_TILE; for messages sent
- * as a result of a device interrupt, this value is HV_MSG_INTR.
- */
- HV_RcvMsgInfo hv_receive_message(HV_MsgState msgstate, HV_VirtAddr buf,
- int buflen);
- /** Start remaining tiles owned by this supervisor. Initially, only one tile
- * executes the client program; after it calls this service, the other tiles
- * are started. This allows the initial tile to do one-time configuration
- * of shared data structures without having to lock them against simultaneous
- * access.
- */
- void hv_start_all_tiles(void);
- /** Open a hypervisor device.
- *
- * This service initializes an I/O device and its hypervisor driver software,
- * and makes it available for use. The open operation is per-device per-chip;
- * once it has been performed, the device handle returned may be used in other
- * device services calls made by any tile.
- *
- * @param name Name of the device. A base device name is just a text string
- * (say, "pcie"). If there is more than one instance of a device, the
- * base name is followed by a slash and a device number (say, "pcie/0").
- * Some devices may support further structure beneath those components;
- * most notably, devices which require control operations do so by
- * supporting reads and/or writes to a control device whose name
- * includes a trailing "/ctl" (say, "pcie/0/ctl").
- * @param flags Flags (HV_DEV_xxx).
- * @return A positive integer device handle, or a negative error code.
- */
- int hv_dev_open(HV_VirtAddr name, __hv32 flags);
- /** Close a hypervisor device.
- *
- * This service uninitializes an I/O device and its hypervisor driver
- * software, and makes it unavailable for use. The close operation is
- * per-device per-chip; once it has been performed, the device is no longer
- * available. Normally there is no need to ever call the close service.
- *
- * @param devhdl Device handle of the device to be closed.
- * @return Zero if the close is successful, otherwise, a negative error code.
- */
- int hv_dev_close(int devhdl);
- /** Read data from a hypervisor device synchronously.
- *
- * This service transfers data from a hypervisor device to a memory buffer.
- * When the service returns, the data has been written from the memory buffer,
- * and the buffer will not be further modified by the driver.
- *
- * No ordering is guaranteed between requests issued from different tiles.
- *
- * Devices may choose to support both the synchronous and asynchronous read
- * operations, only one of them, or neither of them.
- *
- * @param devhdl Device handle of the device to be read from.
- * @param flags Flags (HV_DEV_xxx).
- * @param va Virtual address of the target data buffer. This buffer must
- * be mapped in the currently installed page table; if not, HV_EFAULT
- * may be returned.
- * @param len Number of bytes to be transferred.
- * @param offset Driver-dependent offset. For a random-access device, this is
- * often a byte offset from the beginning of the device; in other cases,
- * like on a control device, it may have a different meaning.
- * @return A non-negative value if the read was at least partially successful;
- * otherwise, a negative error code. The precise interpretation of
- * the return value is driver-dependent, but many drivers will return
- * the number of bytes successfully transferred.
- */
- int hv_dev_pread(int devhdl, __hv32 flags, HV_VirtAddr va, __hv32 len,
- __hv64 offset);
- #define HV_DEV_NB_EMPTY 0x1 /**< Don't block when no bytes of data can
- be transferred. */
- #define HV_DEV_NB_PARTIAL 0x2 /**< Don't block when some bytes, but not all
- of the requested bytes, can be
- transferred. */
- #define HV_DEV_NOCACHE 0x4 /**< The caller warrants that none of the
- cache lines which might contain data
- from the requested buffer are valid.
- Useful with asynchronous operations
- only. */
- #define HV_DEV_ALLFLAGS (HV_DEV_NB_EMPTY | HV_DEV_NB_PARTIAL | \
- HV_DEV_NOCACHE) /**< All HV_DEV_xxx flags */
- /** Write data to a hypervisor device synchronously.
- *
- * This service transfers data from a memory buffer to a hypervisor device.
- * When the service returns, the data has been read from the memory buffer,
- * and the buffer may be overwritten by the client; the data may not
- * necessarily have been conveyed to the actual hardware I/O interface.
- *
- * No ordering is guaranteed between requests issued from different tiles.
- *
- * Devices may choose to support both the synchronous and asynchronous write
- * operations, only one of them, or neither of them.
- *
- * @param devhdl Device handle of the device to be written to.
- * @param flags Flags (HV_DEV_xxx).
- * @param va Virtual address of the source data buffer. This buffer must
- * be mapped in the currently installed page table; if not, HV_EFAULT
- * may be returned.
- * @param len Number of bytes to be transferred.
- * @param offset Driver-dependent offset. For a random-access device, this is
- * often a byte offset from the beginning of the device; in other cases,
- * like on a control device, it may have a different meaning.
- * @return A non-negative value if the write was at least partially successful;
- * otherwise, a negative error code. The precise interpretation of
- * the return value is driver-dependent, but many drivers will return
- * the number of bytes successfully transferred.
- */
- int hv_dev_pwrite(int devhdl, __hv32 flags, HV_VirtAddr va, __hv32 len,
- __hv64 offset);
- /** Interrupt arguments, used in the asynchronous I/O interfaces. */
- #if CHIP_VA_WIDTH() > 32
- typedef __hv64 HV_IntArg;
- #else
- typedef __hv32 HV_IntArg;
- #endif
- /** Interrupt messages are delivered via the mechanism as normal messages,
- * but have a message source of HV_DEV_INTR. The message is formatted
- * as an HV_IntrMsg structure.
- */
- typedef struct
- {
- HV_IntArg intarg; /**< Interrupt argument, passed to the poll/preada/pwritea
- services */
- HV_IntArg intdata; /**< Interrupt-specific interrupt data */
- } HV_IntrMsg;
- /** Request an interrupt message when a device condition is satisfied.
- *
- * This service requests that an interrupt message be delivered to the
- * requesting tile when a device becomes readable or writable, or when any
- * data queued to the device via previous write operations from this tile
- * has been actually sent out on the hardware I/O interface. Devices may
- * choose to support any, all, or none of the available conditions.
- *
- * If multiple conditions are specified, only one message will be
- * delivered. If the event mask delivered to that interrupt handler
- * indicates that some of the conditions have not yet occurred, the
- * client must issue another poll() call if it wishes to wait for those
- * conditions.
- *
- * Only one poll may be outstanding per device handle per tile. If more than
- * one tile is polling on the same device and condition, they will all be
- * notified when it happens. Because of this, clients may not assume that
- * the condition signaled is necessarily still true when they request a
- * subsequent service; for instance, the readable data which caused the
- * poll call to interrupt may have been read by another tile in the interim.
- *
- * The notification interrupt message could come directly, or via the
- * downcall (intctrl1) method, depending on what the tile is doing
- * when the condition is satisfied. Note that it is possible for the
- * requested interrupt to be delivered after this service is called but
- * before it returns.
- *
- * @param devhdl Device handle of the device to be polled.
- * @param events Flags denoting the events which will cause the interrupt to
- * be delivered (HV_DEVPOLL_xxx).
- * @param intarg Value which will be delivered as the intarg member of the
- * eventual interrupt message; the intdata member will be set to a
- * mask of HV_DEVPOLL_xxx values indicating which conditions have been
- * satisifed.
- * @return Zero if the interrupt was successfully scheduled; otherwise, a
- * negative error code.
- */
- int hv_dev_poll(int devhdl, __hv32 events, HV_IntArg intarg);
- #define HV_DEVPOLL_READ 0x1 /**< Test device for readability */
- #define HV_DEVPOLL_WRITE 0x2 /**< Test device for writability */
- #define HV_DEVPOLL_FLUSH 0x4 /**< Test device for output drained */
- /** Cancel a request for an interrupt when a device event occurs.
- *
- * This service requests that no interrupt be delivered when the events
- * noted in the last-issued poll() call happen. Once this service returns,
- * the interrupt has been canceled; however, it is possible for the interrupt
- * to be delivered after this service is called but before it returns.
- *
- * @param devhdl Device handle of the device on which to cancel polling.
- * @return Zero if the poll was successfully canceled; otherwise, a negative
- * error code.
- */
- int hv_dev_poll_cancel(int devhdl);
- /** NMI information */
- typedef struct
- {
- /** Result: negative error, or HV_NMI_RESULT_xxx. */
- int result;
- /** PC from interrupted remote core (if result != HV_NMI_RESULT_FAIL_HV). */
- HV_VirtAddr pc;
- } HV_NMI_Info;
- /** NMI issued successfully. */
- #define HV_NMI_RESULT_OK 0
- /** NMI not issued: remote tile running at client PL with ICS set. */
- #define HV_NMI_RESULT_FAIL_ICS 1
- /** NMI not issued: remote tile waiting in hypervisor. */
- #define HV_NMI_RESULT_FAIL_HV 2
- /** Force an NMI downcall regardless of the ICS bit of the client. */
- #define HV_NMI_FLAG_FORCE 0x1
- /** Send an NMI interrupt request to a particular tile.
- *
- * This will cause the NMI to be issued on the remote tile regardless
- * of the state of the client interrupt mask. However, if the remote
- * tile is in the hypervisor, it will not execute the NMI, and
- * HV_NMI_RESULT_FAIL_HV will be returned. Similarly, if the remote
- * tile is in a client interrupt critical section at the time of the
- * NMI, it will not execute the NMI, and HV_NMI_RESULT_FAIL_ICS will
- * be returned. In this second case, however, if HV_NMI_FLAG_FORCE
- * is set in flags, then the remote tile will enter its NMI interrupt
- * vector regardless. Forcing the NMI vector during an interrupt
- * critical section will mean that the client can not safely continue
- * execution after handling the interrupt.
- *
- * @param tile Tile to which the NMI request is sent.
- * @param info NMI information which is defined by and interpreted by the
- * supervisor, is passed to the specified tile, and is
- * stored in the SPR register SYSTEM_SAVE_{CLIENT_PL}_2 on the
- * specified tile when entering the NMI handler routine.
- * Typically, this parameter stores the NMI type, or an aligned
- * VA plus some special bits, etc.
- * @param flags Flags (HV_NMI_FLAG_xxx).
- * @return Information about the requested NMI.
- */
- HV_NMI_Info hv_send_nmi(HV_Coord tile, unsigned long info, __hv64 flags);
- /** Scatter-gather list for preada/pwritea calls. */
- typedef struct
- #if CHIP_VA_WIDTH() <= 32
- __attribute__ ((packed, aligned(4)))
- #endif
- {
- HV_PhysAddr pa; /**< Client physical address of the buffer segment. */
- HV_PTE pte; /**< Page table entry describing the caching and location
- override characteristics of the buffer segment. Some
- drivers ignore this element and will require that
- the NOCACHE flag be set on their requests. */
- __hv32 len; /**< Length of the buffer segment. */
- } HV_SGL;
- #define HV_SGL_MAXLEN 16 /**< Maximum number of entries in a scatter-gather
- list */
- /** Read data from a hypervisor device asynchronously.
- *
- * This service transfers data from a hypervisor device to a memory buffer.
- * When the service returns, the read has been scheduled. When the read
- * completes, an interrupt message will be delivered, and the buffer will
- * not be further modified by the driver.
- *
- * The number of possible outstanding asynchronous requests is defined by
- * each driver, but it is recommended that it be at least two requests
- * per tile per device.
- *
- * No ordering is guaranteed between synchronous and asynchronous requests,
- * even those issued on the same tile.
- *
- * The completion interrupt message could come directly, or via the downcall
- * (intctrl1) method, depending on what the tile is doing when the read
- * completes. Interrupts do not coalesce; one is delivered for each
- * asynchronous I/O request. Note that it is possible for the requested
- * interrupt to be delivered after this service is called but before it
- * returns.
- *
- * Devices may choose to support both the synchronous and asynchronous read
- * operations, only one of them, or neither of them.
- *
- * @param devhdl Device handle of the device to be read from.
- * @param flags Flags (HV_DEV_xxx).
- * @param sgl_len Number of elements in the scatter-gather list.
- * @param sgl Scatter-gather list describing the memory to which data will be
- * written.
- * @param offset Driver-dependent offset. For a random-access device, this is
- * often a byte offset from the beginning of the device; in other cases,
- * like on a control device, it may have a different meaning.
- * @param intarg Value which will be delivered as the intarg member of the
- * eventual interrupt message; the intdata member will be set to the
- * normal return value from the read request.
- * @return Zero if the read was successfully scheduled; otherwise, a negative
- * error code. Note that some drivers may choose to pre-validate
- * their arguments, and may thus detect certain device error
- * conditions at this time rather than when the completion notification
- * occurs, but this is not required.
- */
- int hv_dev_preada(int devhdl, __hv32 flags, __hv32 sgl_len,
- HV_SGL sgl[/* sgl_len */], __hv64 offset, HV_IntArg intarg);
- /** Write data to a hypervisor device asynchronously.
- *
- * This service transfers data from a memory buffer to a hypervisor
- * device. When the service returns, the write has been scheduled.
- * When the write completes, an interrupt message will be delivered,
- * and the buffer may be overwritten by the client; the data may not
- * necessarily have been conveyed to the actual hardware I/O interface.
- *
- * The number of possible outstanding asynchronous requests is defined by
- * each driver, but it is recommended that it be at least two requests
- * per tile per device.
- *
- * No ordering is guaranteed between synchronous and asynchronous requests,
- * even those issued on the same tile.
- *
- * The completion interrupt message could come directly, or via the downcall
- * (intctrl1) method, depending on what the tile is doing when the read
- * completes. Interrupts do not coalesce; one is delivered for each
- * asynchronous I/O request. Note that it is possible for the requested
- * interrupt to be delivered after this service is called but before it
- * returns.
- *
- * Devices may choose to support both the synchronous and asynchronous write
- * operations, only one of them, or neither of them.
- *
- * @param devhdl Device handle of the device to be read from.
- * @param flags Flags (HV_DEV_xxx).
- * @param sgl_len Number of elements in the scatter-gather list.
- * @param sgl Scatter-gather list describing the memory from which data will be
- * read.
- * @param offset Driver-dependent offset. For a random-access device, this is
- * often a byte offset from the beginning of the device; in other cases,
- * like on a control device, it may have a different meaning.
- * @param intarg Value which will be delivered as the intarg member of the
- * eventual interrupt message; the intdata member will be set to the
- * normal return value from the write request.
- * @return Zero if the write was successfully scheduled; otherwise, a negative
- * error code. Note that some drivers may choose to pre-validate
- * their arguments, and may thus detect certain device error
- * conditions at this time rather than when the completion notification
- * occurs, but this is not required.
- */
- int hv_dev_pwritea(int devhdl, __hv32 flags, __hv32 sgl_len,
- HV_SGL sgl[/* sgl_len */], __hv64 offset, HV_IntArg intarg);
- /** Define a pair of tile and ASID to identify a user process context. */
- typedef struct
- {
- /** X coordinate, relative to supervisor's top-left coordinate */
- unsigned int x:11;
- /** Y coordinate, relative to supervisor's top-left coordinate */
- unsigned int y:11;
- /** ASID of the process on this x,y tile */
- HV_ASID asid:10;
- } HV_Remote_ASID;
- /** Flush cache and/or TLB state on remote tiles.
- *
- * @param cache_pa Client physical address to flush from cache (ignored if
- * the length encoded in cache_control is zero, or if
- * HV_FLUSH_EVICT_L2 is set, or if cache_cpumask is NULL).
- * @param cache_control This argument allows you to specify a length of
- * physical address space to flush (maximum HV_FLUSH_MAX_CACHE_LEN).
- * You can "or" in HV_FLUSH_EVICT_L2 to flush the whole L2 cache.
- * You can "or" in HV_FLUSH_EVICT_L1I to flush the whole L1I cache.
- * HV_FLUSH_ALL flushes all caches.
- * @param cache_cpumask Bitmask (in row-major order, supervisor-relative) of
- * tile indices to perform cache flush on. The low bit of the first
- * word corresponds to the tile at the upper left-hand corner of the
- * supervisor's rectangle. If passed as a NULL pointer, equivalent
- * to an empty bitmask. On chips which support hash-for-home caching,
- * if passed as -1, equivalent to a mask containing tiles which could
- * be doing hash-for-home caching.
- * @param tlb_va Virtual address to flush from TLB (ignored if
- * tlb_length is zero or tlb_cpumask is NULL).
- * @param tlb_length Number of bytes of data to flush from the TLB.
- * @param tlb_pgsize Page size to use for TLB flushes.
- * tlb_va and tlb_length need not be aligned to this size.
- * @param tlb_cpumask Bitmask for tlb flush, like cache_cpumask.
- * If passed as a NULL pointer, equivalent to an empty bitmask.
- * @param asids Pointer to an HV_Remote_ASID array of tile/ASID pairs to flush.
- * @param asidcount Number of HV_Remote_ASID entries in asids[].
- * @return Zero for success, or else HV_EINVAL or HV_EFAULT for errors that
- * are detected while parsing the arguments.
- */
- int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
- unsigned long* cache_cpumask,
- HV_VirtAddr tlb_va, unsigned long tlb_length,
- unsigned long tlb_pgsize, unsigned long* tlb_cpumask,
- HV_Remote_ASID* asids, int asidcount);
- /** Include in cache_control to ensure a flush of the entire L2. */
- #define HV_FLUSH_EVICT_L2 (1UL << 31)
- /** Include in cache_control to ensure a flush of the entire L1I. */
- #define HV_FLUSH_EVICT_L1I (1UL << 30)
- /** Maximum legal size to use for the "length" component of cache_control. */
- #define HV_FLUSH_MAX_CACHE_LEN ((1UL << 30) - 1)
- /** Use for cache_control to ensure a flush of all caches. */
- #define HV_FLUSH_ALL -1UL
- #else /* __ASSEMBLER__ */
- /** Include in cache_control to ensure a flush of the entire L2. */
- #define HV_FLUSH_EVICT_L2 (1 << 31)
- /** Include in cache_control to ensure a flush of the entire L1I. */
- #define HV_FLUSH_EVICT_L1I (1 << 30)
- /** Maximum legal size to use for the "length" component of cache_control. */
- #define HV_FLUSH_MAX_CACHE_LEN ((1 << 30) - 1)
- /** Use for cache_control to ensure a flush of all caches. */
- #define HV_FLUSH_ALL -1
- #endif /* __ASSEMBLER__ */
- #ifndef __ASSEMBLER__
- /** Return a 64-bit value corresponding to the PTE if needed */
- #define hv_pte_val(pte) ((pte).val)
- /** Cast a 64-bit value to an HV_PTE */
- #define hv_pte(val) ((HV_PTE) { val })
- #endif /* !__ASSEMBLER__ */
- /** Bits in the size of an HV_PTE */
- #define HV_LOG2_PTE_SIZE 3
- /** Size of an HV_PTE */
- #define HV_PTE_SIZE (1 << HV_LOG2_PTE_SIZE)
- /* Bits in HV_PTE's low word. */
- #define HV_PTE_INDEX_PRESENT 0 /**< PTE is valid */
- #define HV_PTE_INDEX_MIGRATING 1 /**< Page is migrating */
- #define HV_PTE_INDEX_CLIENT0 2 /**< Page client state 0 */
- #define HV_PTE_INDEX_CLIENT1 3 /**< Page client state 1 */
- #define HV_PTE_INDEX_NC 4 /**< L1$/L2$ incoherent with L3$ */
- #define HV_PTE_INDEX_NO_ALLOC_L1 5 /**< Page is uncached in local L1$ */
- #define HV_PTE_INDEX_NO_ALLOC_L2 6 /**< Page is uncached in local L2$ */
- #define HV_PTE_INDEX_CACHED_PRIORITY 7 /**< Page is priority cached */
- #define HV_PTE_INDEX_PAGE 8 /**< PTE describes a page */
- #define HV_PTE_INDEX_GLOBAL 9 /**< Page is global */
- #define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */
- #define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */
- #define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */
- /* Bits 13-14 are reserved for
- future use. */
- #define HV_PTE_INDEX_SUPER 15 /**< Pages ganged together for TLB */
- #define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */
- #define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */
- #define HV_PTE_INDEX_CLIENT2 19 /**< Page client state 2 */
- #define HV_PTE_INDEX_LOTAR 20 /**< Page's LOTAR; must be high bits
- of word */
- #define HV_PTE_LOTAR_BITS 12 /**< Number of bits in a LOTAR */
- /* Bits in HV_PTE's high word. */
- #define HV_PTE_INDEX_READABLE 32 /**< Page is readable */
- #define HV_PTE_INDEX_WRITABLE 33 /**< Page is writable */
- #define HV_PTE_INDEX_EXECUTABLE 34 /**< Page is executable */
- #define HV_PTE_INDEX_PTFN 35 /**< Page's PTFN; must be high bits
- of word */
- #define HV_PTE_PTFN_BITS 29 /**< Number of bits in a PTFN */
- /*
- * Legal values for the PTE's mode field
- */
- /** Data is not resident in any caches; loads and stores access memory
- * directly.
- */
- #define HV_PTE_MODE_UNCACHED 1
- /** Data is resident in the tile's local L1 and/or L2 caches; if a load
- * or store misses there, it goes to memory.
- *
- * The copy in the local L1$/L2$ is not invalidated when the copy in
- * memory is changed.
- */
- #define HV_PTE_MODE_CACHE_NO_L3 2
- /** Data is resident in the tile's local L1 and/or L2 caches. If a load
- * or store misses there, it goes to an L3 cache in a designated tile;
- * if it misses there, it goes to memory.
- *
- * If the NC bit is not set, the copy in the local L1$/L2$ is invalidated
- * when the copy in the remote L3$ is changed. Otherwise, such
- * invalidation will not occur.
- *
- * Chips for which CHIP_HAS_COHERENT_LOCAL_CACHE() is 0 do not support
- * invalidation from an L3$ to another tile's L1$/L2$. If the NC bit is
- * clear on such a chip, no copy is kept in the local L1$/L2$ in this mode.
- */
- #define HV_PTE_MODE_CACHE_TILE_L3 3
- /** Data is resident in the tile's local L1 and/or L2 caches. If a load
- * or store misses there, it goes to an L3 cache in one of a set of
- * designated tiles; if it misses there, it goes to memory. Which tile
- * is chosen from the set depends upon a hash function applied to the
- * physical address. This mode is not supported on chips for which
- * CHIP_HAS_CBOX_HOME_MAP() is 0.
- *
- * If the NC bit is not set, the copy in the local L1$/L2$ is invalidated
- * when the copy in the remote L3$ is changed. Otherwise, such
- * invalidation will not occur.
- *
- * Chips for which CHIP_HAS_COHERENT_LOCAL_CACHE() is 0 do not support
- * invalidation from an L3$ to another tile's L1$/L2$. If the NC bit is
- * clear on such a chip, no copy is kept in the local L1$/L2$ in this mode.
- */
- #define HV_PTE_MODE_CACHE_HASH_L3 4
- /** Data is not resident in memory; accesses are instead made to an I/O
- * device, whose tile coordinates are given by the PTE's LOTAR field.
- * This mode is only supported on chips for which CHIP_HAS_MMIO() is 1.
- * The EXECUTABLE bit may not be set in an MMIO PTE.
- */
- #define HV_PTE_MODE_MMIO 5
- /* C wants 1ULL so it is typed as __hv64, but the assembler needs just numbers.
- * The assembler can't handle shifts greater than 31, but treats them
- * as shifts mod 32, so assembler code must be aware of which word
- * the bit belongs in when using these macros.
- */
- #ifdef __ASSEMBLER__
- #define __HV_PTE_ONE 1 /**< One, for assembler */
- #else
- #define __HV_PTE_ONE 1ULL /**< One, for C */
- #endif
- /** Is this PTE present?
- *
- * If this bit is set, this PTE represents a valid translation or level-2
- * page table pointer. Otherwise, the page table does not contain a
- * translation for the subject virtual pages.
- *
- * If this bit is not set, the other bits in the PTE are not
- * interpreted by the hypervisor, and may contain any value.
- */
- #define HV_PTE_PRESENT (__HV_PTE_ONE << HV_PTE_INDEX_PRESENT)
- /** Does this PTE map a page?
- *
- * If this bit is set in a level-0 page table, the entry should be
- * interpreted as a level-2 page table entry mapping a jumbo page.
- *
- * If this bit is set in a level-1 page table, the entry should be
- * interpreted as a level-2 page table entry mapping a large page.
- *
- * This bit should not be modified by the client while PRESENT is set, as
- * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
- *
- * In a level-2 page table, this bit is ignored and must be zero.
- */
- #define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE)
- /** Does this PTE implicitly reference multiple pages?
- *
- * If this bit is set in the page table (either in the level-2 page table,
- * or in a higher level page table in conjunction with the PAGE bit)
- * then the PTE specifies a range of contiguous pages, not a single page.
- * The hv_set_pte_super_shift() allows you to specify the count for
- * each level of the page table.
- *
- * Note: this bit is not supported on TILEPro systems.
- */
- #define HV_PTE_SUPER (__HV_PTE_ONE << HV_PTE_INDEX_SUPER)
- /** Is this a global (non-ASID) mapping?
- *
- * If this bit is set, the translations established by this PTE will
- * not be flushed from the TLB by the hv_flush_asid() service; they
- * will be flushed by the hv_flush_page() or hv_flush_pages() services.
- *
- * Setting this bit for translations which are identical in all page
- * tables (for instance, code and data belonging to a client OS) can
- * be very beneficial, as it will reduce the number of TLB misses.
- * Note that, while it is not an error which will be detected by the
- * hypervisor, it is an extremely bad idea to set this bit for
- * translations which are _not_ identical in all page tables.
- *
- * This bit should not be modified by the client while PRESENT is set, as
- * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_GLOBAL (__HV_PTE_ONE << HV_PTE_INDEX_GLOBAL)
- /** Is this mapping accessible to users?
- *
- * If this bit is set, code running at any PL will be permitted to
- * access the virtual addresses mapped by this PTE. Otherwise, only
- * code running at PL 1 or above will be allowed to do so.
- *
- * This bit should not be modified by the client while PRESENT is set, as
- * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_USER (__HV_PTE_ONE << HV_PTE_INDEX_USER)
- /** Has this mapping been accessed?
- *
- * This bit is set by the hypervisor when the memory described by the
- * translation is accessed for the first time. It is never cleared by
- * the hypervisor, but may be cleared by the client. After the bit
- * has been cleared, subsequent references are not guaranteed to set
- * it again until the translation has been flushed from the TLB.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_ACCESSED (__HV_PTE_ONE << HV_PTE_INDEX_ACCESSED)
- /** Is this mapping dirty?
- *
- * This bit is set by the hypervisor when the memory described by the
- * translation is written for the first time. It is never cleared by
- * the hypervisor, but may be cleared by the client. After the bit
- * has been cleared, subsequent references are not guaranteed to set
- * it again until the translation has been flushed from the TLB.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_DIRTY (__HV_PTE_ONE << HV_PTE_INDEX_DIRTY)
- /** Migrating bit in PTE.
- *
- * This bit is guaranteed not to be inspected or modified by the
- * hypervisor. The name is indicative of the suggested use by the client
- * to tag pages whose L3 cache is being migrated from one cpu to another.
- */
- #define HV_PTE_MIGRATING (__HV_PTE_ONE << HV_PTE_INDEX_MIGRATING)
- /** Client-private bit in PTE.
- *
- * This bit is guaranteed not to be inspected or modified by the
- * hypervisor.
- */
- #define HV_PTE_CLIENT0 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT0)
- /** Client-private bit in PTE.
- *
- * This bit is guaranteed not to be inspected or modified by the
- * hypervisor.
- */
- #define HV_PTE_CLIENT1 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT1)
- /** Client-private bit in PTE.
- *
- * This bit is guaranteed not to be inspected or modified by the
- * hypervisor.
- */
- #define HV_PTE_CLIENT2 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT2)
- /** Non-coherent (NC) bit in PTE.
- *
- * If this bit is set, the mapping that is set up will be non-coherent
- * (also known as non-inclusive). This means that changes to the L3
- * cache will not cause a local copy to be invalidated. It is generally
- * recommended only for read-only mappings.
- *
- * In level-1 PTEs, if the Page bit is clear, this bit determines how the
- * level-2 page table is accessed.
- */
- #define HV_PTE_NC (__HV_PTE_ONE << HV_PTE_INDEX_NC)
- /** Is this page prevented from filling the L1$?
- *
- * If this bit is set, the page described by the PTE will not be cached
- * the local cpu's L1 cache.
- *
- * If CHIP_HAS_NC_AND_NOALLOC_BITS() is not true in <chip.h> for this chip,
- * it is illegal to use this attribute, and may cause client termination.
- *
- * In level-1 PTEs, if the Page bit is clear, this bit
- * determines how the level-2 page table is accessed.
- */
- #define HV_PTE_NO_ALLOC_L1 (__HV_PTE_ONE << HV_PTE_INDEX_NO_ALLOC_L1)
- /** Is this page prevented from filling the L2$?
- *
- * If this bit is set, the page described by the PTE will not be cached
- * the local cpu's L2 cache.
- *
- * If CHIP_HAS_NC_AND_NOALLOC_BITS() is not true in <chip.h> for this chip,
- * it is illegal to use this attribute, and may cause client termination.
- *
- * In level-1 PTEs, if the Page bit is clear, this bit determines how the
- * level-2 page table is accessed.
- */
- #define HV_PTE_NO_ALLOC_L2 (__HV_PTE_ONE << HV_PTE_INDEX_NO_ALLOC_L2)
- /** Is this a priority page?
- *
- * If this bit is set, the page described by the PTE will be given
- * priority in the cache. Normally this translates into allowing the
- * page to use only the "red" half of the cache. The client may wish to
- * then use the hv_set_caching service to specify that other pages which
- * alias this page will use only the "black" half of the cache.
- *
- * If the Cached Priority bit is clear, the hypervisor uses the
- * current hv_set_caching() value to choose how to cache the page.
- *
- * It is illegal to set the Cached Priority bit if the Non-Cached bit
- * is set and the Cached Remotely bit is clear, i.e. if requests to
- * the page map directly to memory.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_CACHED_PRIORITY (__HV_PTE_ONE << \
- HV_PTE_INDEX_CACHED_PRIORITY)
- /** Is this a readable mapping?
- *
- * If this bit is set, code will be permitted to read from (e.g.,
- * issue load instructions against) the virtual addresses mapped by
- * this PTE.
- *
- * It is illegal for this bit to be clear if the Writable bit is set.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_READABLE (__HV_PTE_ONE << HV_PTE_INDEX_READABLE)
- /** Is this a writable mapping?
- *
- * If this bit is set, code will be permitted to write to (e.g., issue
- * store instructions against) the virtual addresses mapped by this
- * PTE.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_WRITABLE (__HV_PTE_ONE << HV_PTE_INDEX_WRITABLE)
- /** Is this an executable mapping?
- *
- * If this bit is set, code will be permitted to execute from
- * (e.g., jump to) the virtual addresses mapped by this PTE.
- *
- * This bit applies to any processor on the tile, if there are more
- * than one.
- *
- * This bit is ignored in level-1 PTEs unless the Page bit is set.
- */
- #define HV_PTE_EXECUTABLE (__HV_PTE_ONE << HV_PTE_INDEX_EXECUTABLE)
- /** The width of a LOTAR's x or y bitfield. */
- #define HV_LOTAR_WIDTH 11
- /** Converts an x,y pair to a LOTAR value. */
- #define HV_XY_TO_LOTAR(x, y) ((HV_LOTAR)(((x) << HV_LOTAR_WIDTH) | (y)))
- /** Extracts the X component of a lotar. */
- #define HV_LOTAR_X(lotar) ((lotar) >> HV_LOTAR_WIDTH)
- /** Extracts the Y component of a lotar. */
- #define HV_LOTAR_Y(lotar) ((lotar) & ((1 << HV_LOTAR_WIDTH) - 1))
- #ifndef __ASSEMBLER__
- /** Define accessor functions for a PTE bit. */
- #define _HV_BIT(name, bit) \
- static __inline int \
- hv_pte_get_##name(HV_PTE pte) \
- { \
- return (pte.val >> HV_PTE_INDEX_##bit) & 1; \
- } \
- \
- static __inline HV_PTE \
- hv_pte_set_##name(HV_PTE pte) \
- { \
- pte.val |= 1ULL << HV_PTE_INDEX_##bit; \
- return pte; \
- } \
- \
- static __inline HV_PTE \
- hv_pte_clear_##name(HV_PTE pte) \
- { \
- pte.val &= ~(1ULL << HV_PTE_INDEX_##bit); \
- return pte; \
- }
- /* Generate accessors to get, set, and clear various PTE flags.
- */
- _HV_BIT(present, PRESENT)
- _HV_BIT(page, PAGE)
- _HV_BIT(super, SUPER)
- _HV_BIT(client0, CLIENT0)
- _HV_BIT(client1, CLIENT1)
- _HV_BIT(client2, CLIENT2)
- _HV_BIT(migrating, MIGRATING)
- _HV_BIT(nc, NC)
- _HV_BIT(readable, READABLE)
- _HV_BIT(writable, WRITABLE)
- _HV_BIT(executable, EXECUTABLE)
- _HV_BIT(accessed, ACCESSED)
- _HV_BIT(dirty, DIRTY)
- _HV_BIT(no_alloc_l1, NO_ALLOC_L1)
- _HV_BIT(no_alloc_l2, NO_ALLOC_L2)
- _HV_BIT(cached_priority, CACHED_PRIORITY)
- _HV_BIT(global, GLOBAL)
- _HV_BIT(user, USER)
- #undef _HV_BIT
- /** Get the page mode from the PTE.
- *
- * This field generally determines whether and how accesses to the page
- * are cached; the HV_PTE_MODE_xxx symbols define the legal values for the
- * page mode. The NC, NO_ALLOC_L1, and NO_ALLOC_L2 bits modify this
- * general policy.
- */
- static __inline unsigned int
- hv_pte_get_mode(const HV_PTE pte)
- {
- return (((__hv32) pte.val) >> HV_PTE_INDEX_MODE) &
- ((1 << HV_PTE_MODE_BITS) - 1);
- }
- /** Set the page mode into a PTE. See hv_pte_get_mode. */
- static __inline HV_PTE
- hv_pte_set_mode(HV_PTE pte, unsigned int val)
- {
- pte.val &= ~(((1ULL << HV_PTE_MODE_BITS) - 1) << HV_PTE_INDEX_MODE);
- pte.val |= val << HV_PTE_INDEX_MODE;
- return pte;
- }
- /** Get the page frame number from the PTE.
- *
- * This field contains the upper bits of the CPA (client physical
- * address) of the target page; the complete CPA is this field with
- * HV_LOG2_PAGE_TABLE_ALIGN zero bits appended to it.
- *
- * For all PTEs in the lowest-level page table, and for all PTEs with
- * the Page bit set in all page tables, the CPA must be aligned modulo
- * the relevant page size.
- */
- static __inline unsigned long
- hv_pte_get_ptfn(const HV_PTE pte)
- {
- return pte.val >> HV_PTE_INDEX_PTFN;
- }
- /** Set the page table frame number into a PTE. See hv_pte_get_ptfn. */
- static __inline HV_PTE
- hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
- {
- pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS)-1) << HV_PTE_INDEX_PTFN);
- pte.val |= (__hv64) val << HV_PTE_INDEX_PTFN;
- return pte;
- }
- /** Get the client physical address from the PTE. See hv_pte_set_ptfn. */
- static __inline HV_PhysAddr
- hv_pte_get_pa(const HV_PTE pte)
- {
- return (__hv64) hv_pte_get_ptfn(pte) << HV_LOG2_PAGE_TABLE_ALIGN;
- }
- /** Set the client physical address into a PTE. See hv_pte_get_ptfn. */
- static __inline HV_PTE
- hv_pte_set_pa(HV_PTE pte, HV_PhysAddr pa)
- {
- return hv_pte_set_ptfn(pte, pa >> HV_LOG2_PAGE_TABLE_ALIGN);
- }
- /** Get the remote tile caching this page.
- *
- * Specifies the remote tile which is providing the L3 cache for this page.
- *
- * This field is ignored unless the page mode is HV_PTE_MODE_CACHE_TILE_L3.
- *
- * In level-1 PTEs, if the Page bit is clear, this field determines how the
- * level-2 page table is accessed.
- */
- static __inline unsigned int
- hv_pte_get_lotar(const HV_PTE pte)
- {
- unsigned int lotar = ((__hv32) pte.val) >> HV_PTE_INDEX_LOTAR;
- return HV_XY_TO_LOTAR( (lotar >> (HV_PTE_LOTAR_BITS / 2)),
- (lotar & ((1 << (HV_PTE_LOTAR_BITS / 2)) - 1)) );
- }
- /** Set the remote tile caching a page into a PTE. See hv_pte_get_lotar. */
- static __inline HV_PTE
- hv_pte_set_lotar(HV_PTE pte, unsigned int val)
- {
- unsigned int x = HV_LOTAR_X(val);
- unsigned int y = HV_LOTAR_Y(val);
- pte.val &= ~(((1ULL << HV_PTE_LOTAR_BITS)-1) << HV_PTE_INDEX_LOTAR);
- pte.val |= (x << (HV_PTE_INDEX_LOTAR + HV_PTE_LOTAR_BITS / 2)) |
- (y << HV_PTE_INDEX_LOTAR);
- return pte;
- }
- #endif /* !__ASSEMBLER__ */
- /** Converts a client physical address to a ptfn. */
- #define HV_CPA_TO_PTFN(p) ((p) >> HV_LOG2_PAGE_TABLE_ALIGN)
- /** Converts a ptfn to a client physical address. */
- #define HV_PTFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_TABLE_ALIGN)
- #if CHIP_VA_WIDTH() > 32
- /*
- * Note that we currently do not allow customizing the page size
- * of the L0 pages, but fix them at 4GB, so we do not use the
- * "_HV_xxx" nomenclature for the L0 macros.
- */
- /** Log number of HV_PTE entries in L0 page table */
- #define HV_LOG2_L0_ENTRIES (CHIP_VA_WIDTH() - HV_LOG2_L1_SPAN)
- /** Number of HV_PTE entries in L0 page table */
- #define HV_L0_ENTRIES (1 << HV_LOG2_L0_ENTRIES)
- /** Log size of L0 page table in bytes */
- #define HV_LOG2_L0_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L0_ENTRIES)
- /** Size of L0 page table in bytes */
- #define HV_L0_SIZE (1 << HV_LOG2_L0_SIZE)
- #ifdef __ASSEMBLER__
- /** Index in L0 for a specific VA */
- #define HV_L0_INDEX(va) \
- (((va) >> HV_LOG2_L1_SPAN) & (HV_L0_ENTRIES - 1))
- #else
- /** Index in L1 for a specific VA */
- #define HV_L0_INDEX(va) \
- (((HV_VirtAddr)(va) >> HV_LOG2_L1_SPAN) & (HV_L0_ENTRIES - 1))
- #endif
- #endif /* CHIP_VA_WIDTH() > 32 */
- /** Log number of HV_PTE entries in L1 page table */
- #define _HV_LOG2_L1_ENTRIES(log2_page_size_large) \
- (HV_LOG2_L1_SPAN - log2_page_size_large)
- /** Number of HV_PTE entries in L1 page table */
- #define _HV_L1_ENTRIES(log2_page_size_large) \
- (1 << _HV_LOG2_L1_ENTRIES(log2_page_size_large))
- /** Log size of L1 page table in bytes */
- #define _HV_LOG2_L1_SIZE(log2_page_size_large) \
- (HV_LOG2_PTE_SIZE + _HV_LOG2_L1_ENTRIES(log2_page_size_large))
- /** Size of L1 page table in bytes */
- #define _HV_L1_SIZE(log2_page_size_large) \
- (1 << _HV_LOG2_L1_SIZE(log2_page_size_large))
- /** Log number of HV_PTE entries in level-2 page table */
- #define _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small) \
- (log2_page_size_large - log2_page_size_small)
- /** Number of HV_PTE entries in level-2 page table */
- #define _HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) \
- (1 << _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small))
- /** Log size of level-2 page table in bytes */
- #define _HV_LOG2_L2_SIZE(log2_page_size_large, log2_page_size_small) \
- (HV_LOG2_PTE_SIZE + \
- _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small))
- /** Size of level-2 page table in bytes */
- #define _HV_L2_SIZE(log2_page_size_large, log2_page_size_small) \
- (1 << _HV_LOG2_L2_SIZE(log2_page_size_large, log2_page_size_small))
- #ifdef __ASSEMBLER__
- #if CHIP_VA_WIDTH() > 32
- /** Index in L1 for a specific VA */
- #define _HV_L1_INDEX(va, log2_page_size_large) \
- (((va) >> log2_page_size_large) & (_HV_L1_ENTRIES(log2_page_size_large) - 1))
- #else /* CHIP_VA_WIDTH() > 32 */
- /** Index in L1 for a specific VA */
- #define _HV_L1_INDEX(va, log2_page_size_large) \
- (((va) >> log2_page_size_large))
- #endif /* CHIP_VA_WIDTH() > 32 */
- /** Index in level-2 page table for a specific VA */
- #define _HV_L2_INDEX(va, log2_page_size_large, log2_page_size_small) \
- (((va) >> log2_page_size_small) & \
- (_HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) - 1))
- #else /* __ASSEMBLER __ */
- #if CHIP_VA_WIDTH() > 32
- /** Index in L1 for a specific VA */
- #define _HV_L1_INDEX(va, log2_page_size_large) \
- (((HV_VirtAddr)(va) >> log2_page_size_large) & \
- (_HV_L1_ENTRIES(log2_page_size_large) - 1))
- #else /* CHIP_VA_WIDTH() > 32 */
- /** Index in L1 for a specific VA */
- #define _HV_L1_INDEX(va, log2_page_size_large) \
- (((HV_VirtAddr)(va) >> log2_page_size_large))
- #endif /* CHIP_VA_WIDTH() > 32 */
- /** Index in level-2 page table for a specific VA */
- #define _HV_L2_INDEX(va, log2_page_size_large, log2_page_size_small) \
- (((HV_VirtAddr)(va) >> log2_page_size_small) & \
- (_HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) - 1))
- #endif /* __ASSEMBLER __ */
- /** Position of the PFN field within the PTE (subset of the PTFN). */
- #define _HV_PTE_INDEX_PFN(log2_page_size) \
- (HV_PTE_INDEX_PTFN + (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
- /** Length of the PFN field within the PTE (subset of the PTFN). */
- #define _HV_PTE_INDEX_PFN_BITS(log2_page_size) \
- (HV_PTE_INDEX_PTFN_BITS - (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
- /** Converts a client physical address to a pfn. */
- #define _HV_CPA_TO_PFN(p, log2_page_size) ((p) >> log2_page_size)
- /** Converts a pfn to a client physical address. */
- #define _HV_PFN_TO_CPA(p, log2_page_size) \
- (((HV_PhysAddr)(p)) << log2_page_size)
- /** Converts a ptfn to a pfn. */
- #define _HV_PTFN_TO_PFN(p, log2_page_size) \
- ((p) >> (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
- /** Converts a pfn to a ptfn. */
- #define _HV_PFN_TO_PTFN(p, log2_page_size) \
- ((p) << (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
- #endif /* _HV_HV_H */
|