driver-minion.c 158 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380
  1. /*
  2. * Copyright 2013-2014 Andrew Smith - BlackArrow Ltd
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include "compat.h"
  11. #include "miner.h"
  12. #include "klist.h"
  13. #include <ctype.h>
  14. #include <math.h>
  15. #ifndef LINUX
  16. static void minion_detect(__maybe_unused bool hotplug)
  17. {
  18. }
  19. #else
  20. #include <unistd.h>
  21. #include <linux/spi/spidev.h>
  22. #include <sys/ioctl.h>
  23. #include <sys/stat.h>
  24. #include <sys/mman.h>
  25. #include <fcntl.h>
  26. #include <poll.h>
  27. // Define this to 1 to enable interrupt code and enable no_nonce
  28. #define ENABLE_INT_NONO 0
  29. // Define this to 1 if compiling on RockChip and not on RPi
  30. #define MINION_ROCKCHIP 0
  31. // The code is always in - this just decides if it does it
  32. static bool minreread = false;
  33. #if MINION_ROCKCHIP == 1
  34. #define MINION_POWERCYCLE_GPIO 173
  35. #define MINION_CHIP_OFF "1"
  36. #define MINION_CHIP_ON "0"
  37. #define MINION_CHIP_DELAY 100
  38. #endif
  39. // Power cycle if the xff_list is full and the tail is less than
  40. // this long ago
  41. #define MINION_POWER_TIME 60
  42. /*
  43. * Use pins for board selection
  44. * If disabled, it will test chips just as 'pin 0'
  45. * but never do any gpio - the equivalent of the previous 'no pins' code
  46. */
  47. static bool usepins = false;
  48. #define MINION_PAGE_SIZE 4096
  49. #define BCM2835_BASE 0x20000000
  50. #define BCM2835_GPIO_BASE (BCM2835_BASE + 0x200000)
  51. #define BCM2835_GPIO_SET0 0x001c // GPIO Pin Output Set 0
  52. #define BCM2835_GPIO_CLR0 0x0028 // GPIO Pin Output Clear 0
  53. #define BCM2835_GPIO_FSEL0 0x0000
  54. #define BCM2835_GPIO_FSEL_INPUT 0b000
  55. #define BCM2835_GPIO_FSEL_OUTPUT 0b001
  56. #define BCM2835_GPIO_FSEL_MASK 0b111
  57. #define BCM2835_PIN_HIGH 0x1
  58. #define BCM2835_PIN_LOW 0x0
  59. static const char *minion_memory = "/dev/mem";
  60. static int minion_memory_addr = BCM2835_GPIO_BASE;
  61. #define MINION_SPI_BUS 0
  62. #define MINION_SPI_CHIP 0
  63. #if MINION_ROCKCHIP == 0
  64. #define MINION_SPI_SPEED 8000000
  65. #else
  66. #define MINION_SPI_SPEED 500000
  67. #endif
  68. #define MINION_SPI_BUFSIZ 1024
  69. static struct minion_select_pins {
  70. int pin;
  71. int wpi;
  72. char *name;
  73. int bcm; // this is what we use
  74. } minionPins[] = {
  75. { 24, 10, "CE0", 8, },
  76. { 26, 11, "CE1", 7, },
  77. { 16, 4, "GPIO4", 23, },
  78. { 22, 6, "GPIO6", 25, },
  79. { 12, 1, "GPIO1", 18, },
  80. { 18, 5, "GPIO5", 24, },
  81. { 11, 0, "GPIO0", 17, },
  82. { 13, 2, "GPIO2", 27, },
  83. { 15, 3, "GPIO3", 22, },
  84. { 7, 7, "GPIO7", 4, }
  85. /* The rest on the RPi
  86. { 3, 8, "SDA", 2, }
  87. { 5, 9, "SCL", 3, }
  88. { 19, 12, "MOSI", 10, }
  89. { 21, 13, "MISO", 9, }
  90. { 23, 14, "SCLK", 11, }
  91. { 8, 15, "TxD", 14, }
  92. { 10, 16, "RxD", 15, }
  93. */
  94. };
  95. /*
  96. * uS delays for GPIO pin access
  97. */
  98. #define MINION_PIN_BEFORE cgsleep_us(33)
  99. #define MINION_PIN_SLEEP cgsleep_us(133)
  100. #define MINION_PIN_AFTER
  101. #define MINION_PIN_COUNT (sizeof(minionPins)/ \
  102. sizeof(struct minion_select_pins))
  103. #define CHIP_PIN(_chip) (minioninfo->chip_pin[_chip])
  104. #define MINION_MIN_CHIP 0
  105. #define MINION_MAX_CHIP 11
  106. #define MINION_CHIP_PER_PIN (1 + MINION_MAX_CHIP - MINION_MIN_CHIP)
  107. #define MINION_CHIPS (MINION_PIN_COUNT * MINION_CHIP_PER_PIN)
  108. #define MINION_CORES 99
  109. #define FAKE_CORE MINION_CORES
  110. /*
  111. * TODO: These will need adjusting for final hardware
  112. * Look them up and calculate them?
  113. */
  114. #define MINION_QUE_MAX 64
  115. #define MINION_QUE_HIGH 48
  116. #define MINION_QUE_SEND 16
  117. #define MINION_QUE_LOW 8
  118. #define MINION_FFL " - from %s %s() line %d"
  119. #define MINION_FFL_HERE __FILE__, __func__, __LINE__
  120. #define MINION_FFL_PASS file, func, line
  121. #define MINION_FFL_ARGS __maybe_unused const char *file, \
  122. __maybe_unused const char *func, \
  123. __maybe_unused const int line
  124. #define minion_txrx(_task) _minion_txrx(minioncgpu, minioninfo, _task, MINION_FFL_HERE)
  125. #define MINION_SYS_REGS 0x00
  126. #define MINION_CORE_REGS 0x10
  127. #define MINION_RES_BUF 0x20
  128. #define MINION_CMD_QUE 0x30
  129. #define MINION_NONCE_RANGES 0x70
  130. #define DATA_SIZ (sizeof(uint32_t))
  131. // All SYS data sizes are DATA_SIZ
  132. #define MINION_SYS_CHIP_SIG 0x00
  133. #define MINION_SYS_CHIP_STA 0x01
  134. #define MINION_SYS_SPI_LED 0x02
  135. #define MINION_SYS_TEMP_CTL 0x03
  136. #define MINION_SYS_FREQ_CTL 0x04
  137. #define MINION_SYS_NONCE_LED 0x05
  138. #define MINION_SYS_MISC_CTL 0x06
  139. #define MINION_SYS_RSTN_CTL 0x07
  140. #define MINION_SYS_INT_ENA 0x08
  141. #define MINION_SYS_INT_CLR 0x09
  142. #define MINION_SYS_INT_STA 0x0a
  143. #define MINION_SYS_FIFO_STA 0x0b
  144. #define MINION_SYS_QUE_TRIG 0x0c
  145. #define MINION_SYS_BUF_TRIG 0x0d
  146. #define MINION_SYS_IDLE_CNT 0x0e
  147. // How many 32 bit reports make up all the cores - 99 cores = 4 reps
  148. #define MINION_CORE_REPS (int)((((MINION_CORES-1) >> 5) & 0xff) + 1)
  149. // All SYS data sizes are DATA_SIZ
  150. #define MINION_SYS_SIZ DATA_SIZ
  151. // Header Pin 18 = GPIO5 = BCM 24
  152. #define MINION_GPIO_RESULT_INT_PIN 24
  153. // RockChip is pin 172 ...
  154. #define MINION_GPIO_SYS "/sys/class/gpio"
  155. #define MINION_GPIO_ENA "/export"
  156. #define MINION_GPIO_ENA_VAL "%d"
  157. #define MINION_GPIO_DIS "/unexport"
  158. #define MINION_GPIO_PIN "/gpio%d"
  159. #define MINION_GPIO_DIR "/direction"
  160. #define MINION_GPIO_DIR_READ "in"
  161. #define MINION_GPIO_DIR_WRITE "out"
  162. #define MINION_GPIO_EDGE "/edge"
  163. #define MINION_GPIO_EDGE_NONE "none"
  164. #define MINION_GPIO_EDGE_RISING "rising"
  165. #define MINION_GPIO_EDGE_FALLING "falling"
  166. #define MINION_GPIO_EDGE_BOTH "both"
  167. #define MINION_GPIO_ACT "/active_low"
  168. #define MINION_GPIO_ACT_LO "1"
  169. #define MINION_GPIO_ACT_HI "0"
  170. #define MINION_GPIO_VALUE "/value"
  171. #define MINION_RESULT_INT 0x01
  172. #define MINION_RESULT_FULL_INT 0x02
  173. #define MINION_CMD_INT 0x04
  174. #define MINION_CMD_FULL_INT 0x08
  175. #define MINION_TEMP_LOW_INT 0x10
  176. #define MINION_TEMP_HI_INT 0x20
  177. #define MINION_ALL_INT MINION_RESULT_INT | \
  178. MINION_RESULT_FULL_INT | \
  179. MINION_CMD_INT | \
  180. MINION_CMD_FULL_INT | \
  181. MINION_TEMP_LOW_INT | \
  182. MINION_TEMP_HI_INT
  183. #define RSTN_CTL_RESET_CORES 0x01
  184. #define RSTN_CTL_FLUSH_RESULTS 0x02
  185. #define RSTN_CTL_FLUSH_CMD_QUEUE 0x04
  186. #define RSTN_CTL_SPI_SW_RSTN 0x08
  187. #define RSTN_CTL_SHA_MGR_RESET 0x10
  188. // Init
  189. #define SYS_RSTN_CTL_INIT (RSTN_CTL_RESET_CORES | \
  190. RSTN_CTL_FLUSH_RESULTS | \
  191. RSTN_CTL_FLUSH_CMD_QUEUE | \
  192. RSTN_CTL_SPI_SW_RSTN | \
  193. RSTN_CTL_SHA_MGR_RESET)
  194. // Block change
  195. #define SYS_RSTN_CTL_FLUSH (RSTN_CTL_RESET_CORES | \
  196. RSTN_CTL_SPI_SW_RSTN | \
  197. RSTN_CTL_FLUSH_CMD_QUEUE)
  198. #if ENABLE_INT_NONO
  199. // enable 'no nonce' report
  200. #define SYS_MISC_CTL_DEFAULT 0x04
  201. #else
  202. #define SYS_MISC_CTL_DEFAULT 0x00
  203. #endif
  204. // Temperature returned by MINION_SYS_CHIP_STA 0x01 STA_TEMP()
  205. #define MINION_TEMP_40 0
  206. #define MINION_TEMP_60 1
  207. #define MINION_TEMP_80 3
  208. #define MINION_TEMP_100 7
  209. #define MINION_TEMP_OVER 15
  210. static const char *min_temp_40 = "<40";
  211. static const char *min_temp_60 = "40-60";
  212. static const char *min_temp_80 = "60-80";
  213. static const char *min_temp_100 = "80-100";
  214. static const char *min_temp_over = ">100";
  215. static const char *min_temp_invalid = "?";
  216. /*
  217. * Temperature for MINION_SYS_TEMP_CTL 0x03 temp_thres [0:3]
  218. * i.e. it starts at 120 and goes up in steps of 5 to 160
  219. */
  220. #define MINION_TEMP_CTL_MIN 1
  221. #define MINION_TEMP_CTL_MAX 9
  222. #define MINION_TEMP_CTL_BITS 0x0f
  223. #define MINION_TEMP_CTL_DEF 135
  224. #define MINION_TEMP_CTL_STEP 5
  225. #define MINION_TEMP_CTL_MIN_VALUE 120
  226. #define MINION_TEMP_CTL_MAX_VALUE (MINION_TEMP_CTL_MIN_VALUE + \
  227. (MINION_TEMP_CTL_STEP * \
  228. (MINION_TEMP_CTL_MAX - MINION_TEMP_CTL_MIN)))
  229. #define MINION_TEMP_DISABLE "disable"
  230. #define MINION_TEMP_CTL_DISABLE -1
  231. #define MINION_TEMP_CTL_DISABLE_VALUE 0x20
  232. // CORE data size is DATA_SIZ
  233. #define MINION_CORE_ENA0_31 0x10
  234. #define MINION_CORE_ENA32_63 0x11
  235. #define MINION_CORE_ENA64_95 0x12
  236. #define MINION_CORE_ENA96_98 0x13
  237. #define MINION_CORE_ACT0_31 0x14
  238. #define MINION_CORE_ACT32_63 0x15
  239. #define MINION_CORE_ACT64_95 0x16
  240. #define MINION_CORE_ACT96_98 0x17
  241. // All CORE data sizes are DATA_SIZ
  242. #define MINION_CORE_SIZ DATA_SIZ
  243. #define MINION_CORE_ALL "all"
  244. // RES data size is minion_result
  245. #define MINION_RES_DATA 0x20
  246. #define MINION_RES_PEEK 0x21
  247. // QUE data size is minion_que
  248. #define MINION_QUE_0 0x30
  249. #define MINION_QUE_R 0x31
  250. // RANGE data sizes are DATA_SIZ
  251. #define MINION_NONCE_START 0x70
  252. #define MINION_NONCE_RANGE 0x71
  253. // This must be >= max txsiz + max rxsiz
  254. #define MINION_BUFSIZ 1024
  255. #define u8tou32(_c, _off) (((uint8_t *)(_c))[(_off)+0] + \
  256. ((uint8_t *)(_c))[(_off)+1] * 0x100 + \
  257. ((uint8_t *)(_c))[(_off)+2] * 0x10000 + \
  258. ((uint8_t *)(_c))[(_off)+3] * 0x1000000 )
  259. #define MINION_ADDR_WRITE 0x7f
  260. #define MINION_ADDR_READ 0x80
  261. #define READ_ADDR(_reg) ((_reg) | MINION_ADDR_READ)
  262. #define WRITE_ADDR(_reg) ((_reg) & MINION_ADDR_WRITE)
  263. #define IS_ADDR_READ(_reg) (((_reg) & MINION_ADDR_READ) == MINION_ADDR_READ)
  264. #define IS_ADDR_WRITE(_reg) (((_reg) & MINION_ADDR_READ) == 0)
  265. #define SET_HEAD_WRITE(_h, _reg) ((_h)->reg) = WRITE_ADDR(_reg)
  266. #define SET_HEAD_READ(_h, _reg) ((_h)->reg) = READ_ADDR(_reg)
  267. #define SET_HEAD_SIZ(_h, _siz) \
  268. do { \
  269. ((_h)->siz)[0] = (uint8_t)((_siz) & 0xff); \
  270. ((_h)->siz)[1] = (uint8_t)(((_siz) & 0xff00) >> 8); \
  271. } while (0)
  272. struct minion_header {
  273. uint8_t chipid;
  274. uint8_t reg;
  275. uint8_t siz[2];
  276. uint8_t data[4]; // placeholder
  277. };
  278. #define HSIZE() (sizeof(struct minion_header) - 4)
  279. #define MINION_NOCHIP_SIG 0x00000000
  280. #define MINION_NOCHIP_SIG2 0xffffffff
  281. #define MINION_CHIP_SIG 0xb1ac8a44
  282. /*
  283. * Number of times to try and get the SIG with each chip,
  284. * if the chip returns neither of the above values
  285. * TODO: maybe need some reset between tries, to handle a shift value?
  286. */
  287. #define MINION_SIG_TRIES 3
  288. /*
  289. * TODO: Finding these means the chip is there - but how to fix it?
  290. * The extra &'s are to ensure there is no sign bit issue since
  291. * the sign bit carry in a C bit-shift is compiler dependent
  292. */
  293. #define MINION_CHIP_SIG_SHIFT1 (((MINION_CHIP_SIG & 0x0000ffff) << 16) & 0xffff0000)
  294. #define MINION_CHIP_SIG_SHIFT2 (((MINION_CHIP_SIG & 0x00ffffff) << 8) & 0xffffff00)
  295. #define MINION_CHIP_SIG_SHIFT3 (((MINION_CHIP_SIG & 0xffffff00) >> 8) & 0x00ffffff)
  296. #define MINION_CHIP_SIG_SHIFT4 (((MINION_CHIP_SIG & 0xffff0000) >> 16) & 0x0000ffff)
  297. #define MINION_SPI_LED_ON 0xa5a5
  298. #define MINION_SPI_LED_OFF 0x0
  299. // Time since first nonce/last reset before turning on the LED
  300. #define MINION_LED_TEST_TIME 600
  301. #define MINION_FREQ_MIN 100
  302. #define MINION_FREQ_DEF 1200
  303. #define MINION_FREQ_MAX 1400
  304. #define MINION_FREQ_FACTOR 100
  305. #define MINION_FREQ_RESET_STEP MINION_FREQ_FACTOR
  306. #define MINION_FREQ_FACTOR_MIN 1
  307. #define MINION_FREQ_FACTOR_MAX 14
  308. static uint32_t minion_freq[] = {
  309. 0x0,
  310. 0x205032, // 1 = 100Mhz
  311. 0x203042, // 2 = 200Mhz
  312. 0x20204B, // 3 = 300Mhz
  313. 0x201042, // 4 = 400Mhz
  314. 0x201053, // 5 = 500Mhz
  315. 0x200032, // 6 = 600Mhz
  316. 0x20003A, // 7 = 700Mhz
  317. 0x200042, // 8 = 800Mhz
  318. 0x20004B, // 9 = 900Mhz
  319. 0x200053, // 10 = 1000Mhz
  320. 0x21005B, // 11 = 1100Mhz
  321. 0x210064, // 12 = 1200Mhz
  322. 0x21006C, // 13 = 1300Mhz
  323. 0x210074 // 14 = 1400Mhz
  324. };
  325. // When hash rate falls below this in the history hash rate, reset it
  326. #define MINION_RESET_PERCENT 75.0
  327. // When hash rate falls below this after the longer test time
  328. #define MINION_RESET2_PERCENT 85.0
  329. // After the above resets, delay sending work for:
  330. #define MINION_RESET_DELAY_s 0.088
  331. #define STA_TEMP(_sta) ((uint16_t)((_sta)[3] & 0x1f))
  332. #define STA_CORES(_sta) ((uint16_t)((_sta)[2]))
  333. #define STA_FREQ(_sta) ((uint32_t)((_sta)[1]) * 0x100 + (uint32_t)((_sta)[0]))
  334. // Randomly between 1s and 2s per chip
  335. #define MINION_STATS_UPDATE_TIME_mS 1000
  336. #define MINION_STATS_UPDATE_RAND_mS 1000
  337. // Don't report it more than once every ... 5s
  338. #define MINION_IDLE_MESSAGE_ms 5000
  339. struct minion_status {
  340. uint16_t temp;
  341. uint16_t cores;
  342. uint32_t freq;
  343. uint32_t quework;
  344. uint32_t chipwork;
  345. uint32_t realwork; // FIFO_STA
  346. struct timeval last;
  347. bool overheat;
  348. bool islow;
  349. bool tohigh;
  350. int lowcount;
  351. uint32_t overheats;
  352. struct timeval lastoverheat;
  353. struct timeval lastrecover;
  354. double overheattime;
  355. uint32_t tempsent;
  356. uint32_t idle;
  357. uint32_t last_rpt_idle;
  358. struct timeval idle_rpt;
  359. struct timeval first_nonce;
  360. uint64_t from_first_good;
  361. };
  362. #define ENABLE_CORE(_core, _n) ((_core[_n >> 3]) |= (1 << (_n % 8)))
  363. #define CORE_IDLE(_core, _n) ((_core[_n >> 3]) & (1 << (_n % 8)))
  364. #define FIFO_RES(_fifo, _off) ((_fifo)[(_off) + 0])
  365. #define FIFO_CMD(_fifo, _off) ((_fifo)[(_off) + 1])
  366. #define RES_GOLD(_res) ((((_res)->status[3]) & 0x80) == 0)
  367. #define RES_CHIPID(_res) (((_res)->status[3]) & 0x1f)
  368. #define RES_CORE(_res) ((_res)->status[2])
  369. #define RES_TASK(_res) ((int)((_res)->status[1]) * 0x100 + (int)((_res)->status[0]))
  370. #define RES_NONCE(_res) u8tou32((_res)->nonce, 0)
  371. /*
  372. * This is only valid since we avoid using task_id 0 for work
  373. * However, it isn't really necessary since we only request
  374. * the number of results the result buffer says it has
  375. * However, it is a simple failsafe
  376. */
  377. #define IS_RESULT(_res) ((_res)->status[1] || (_res)->status[0])
  378. struct minion_result {
  379. uint8_t status[DATA_SIZ];
  380. uint8_t nonce[DATA_SIZ];
  381. };
  382. #define MINION_RES_DATA_SIZ sizeof(struct minion_result)
  383. /*
  384. * (MINION_SPI_BUFSIZ - HSIZE()) / MINION_RES_DATA_SIZ
  385. * less a little bit to round it out
  386. */
  387. #define MINION_MAX_RES 120
  388. #define MIDSTATE_BYTES 32
  389. #define MERKLE7_OFFSET 64
  390. #define MERKLE_BYTES 12
  391. #define MINION_MAX_TASK_ID 0xffff
  392. struct minion_que {
  393. uint8_t task_id[2];
  394. uint8_t reserved[2];
  395. uint8_t midstate[MIDSTATE_BYTES];
  396. uint8_t merkle7[DATA_SIZ];
  397. uint8_t ntime[DATA_SIZ];
  398. uint8_t bits[DATA_SIZ];
  399. };
  400. /*
  401. * Max time to wait before checking the task list
  402. * Required, since only urgent tasks trigger an immediate check
  403. * TODO: ? for 2TH/s
  404. */
  405. #define MINION_TASK_mS 8
  406. /*
  407. * Max time to wait before checking the result list for nonces
  408. * This can be long since it's only a failsafe
  409. * cgsem_post is always sent if there are nonces ready to check
  410. */
  411. #define MINION_NONCE_mS 888
  412. // Number of results to make a GPIO interrupt
  413. //#define MINION_RESULT_INT_SIZE 1
  414. #define MINION_RESULT_INT_SIZE 2
  415. /*
  416. * Max time to wait before checking for results
  417. * The interrupt doesn't occur until MINION_RESULT_INT_SIZE results are found
  418. * See comment in minion_spi_reply() at poll()
  419. */
  420. #define MINION_REPLY_mS 88
  421. /*
  422. * Max time to wait before returning the amount of work done
  423. * A result interrupt will send a trigger for this also
  424. * See comment in minion_scanwork()
  425. * This avoids the cgminer master work loop spinning doing nothing
  426. */
  427. #define MINION_SCAN_mS 88
  428. // *** Work lists: generated, queued for a chip, sent to chip
  429. typedef struct work_item {
  430. struct work *work;
  431. uint32_t task_id;
  432. struct timeval sent;
  433. int nonces;
  434. bool urgent;
  435. bool stale; // if stale, don't decrement que/chipwork when discarded
  436. bool rolled;
  437. int errors; // uncertain since the error could mean task_id is wrong
  438. struct timeval created; // when work was generated
  439. uint64_t ioseq;
  440. } WORK_ITEM;
  441. #define ALLOC_WORK_ITEMS 4096
  442. #define LIMIT_WORK_ITEMS 0
  443. // *** Task queue ready to be sent
  444. typedef struct task_item {
  445. uint64_t tid;
  446. uint8_t chip;
  447. bool write;
  448. uint8_t address;
  449. uint32_t task_id;
  450. uint32_t wsiz;
  451. uint32_t osiz;
  452. uint32_t rsiz;
  453. uint8_t wbuf[MINION_BUFSIZ];
  454. uint8_t obuf[MINION_BUFSIZ];
  455. uint8_t rbuf[MINION_BUFSIZ];
  456. int reply;
  457. bool urgent;
  458. uint8_t work_state;
  459. struct work *work;
  460. K_ITEM *witem;
  461. uint64_t ioseq;
  462. } TASK_ITEM;
  463. #define ALLOC_TASK_ITEMS 256
  464. #define LIMIT_TASK_ITEMS 0
  465. // *** Results queue ready to be checked
  466. typedef struct res_item {
  467. int chip;
  468. int core;
  469. uint32_t task_id;
  470. uint32_t nonce;
  471. struct timeval when;
  472. /*
  473. * Only once per task_id if no nonces were found
  474. * Sent with core = 0
  475. * However, currently it always sends it at the end of every task
  476. * TODO: code assumes it doesn't - change later when we
  477. * see what the final hardware does (minor code performance gain)
  478. */
  479. bool no_nonce;
  480. // If we requested the result twice:
  481. bool another;
  482. uint32_t task_id2;
  483. uint32_t nonce2;
  484. } RES_ITEM;
  485. #define ALLOC_RES_ITEMS 256
  486. #define LIMIT_RES_ITEMS 0
  487. // *** Per chip nonce history
  488. typedef struct hist_item {
  489. struct timeval when;
  490. } HIST_ITEM;
  491. #define ALLOC_HIST_ITEMS 4096
  492. #define LIMIT_HIST_ITEMS 0
  493. // How much history to keep (5min)
  494. #define MINION_HISTORY_s 300
  495. // History required to decide a reset at MINION_FREQ_DEF Mhz
  496. #define MINION_RESET_s 10
  497. // How many times to reset before changing Freq
  498. // This doesn't include the secondary higher % check
  499. #define MINION_RESET_COUNT 6
  500. // To enable the 2nd check
  501. static bool second_check = true;
  502. // Longer time lapse to expect the higher %
  503. // This intercepts a slow GHs drop earlier
  504. #define MINION_RESET2_s 60
  505. #if (MINION_RESET_s > MINION_HISTORY_s)
  506. #error "MINION_RESET_s can't be greater than MINION_HISTORY_s"
  507. #endif
  508. #define FREQ_DELAY(freq) ((float)(MINION_RESET_s * MINION_FREQ_DEF) / (freq))
  509. #if (MINION_RESET2_s > MINION_HISTORY_s)
  510. #error "MINION_RESET2_s can't be greater than MINION_HISTORY_s"
  511. #endif
  512. // FREQ2_DELAY(MINION_FREQ_MIN) = FREQ2_FACTOR * MINION_RESET2_s
  513. #define FREQ2_FACTOR 1.5
  514. #define FREQ2_DELAY(freq) ((1.0 + (float)((freq - MINION_FREQ_DEF) * (1 - FREQ2_FACTOR)) / \
  515. (float)(MINION_FREQ_DEF - MINION_FREQ_MIN)) * MINION_RESET2_s)
  516. #if (MINION_RESET2_s <= MINION_RESET_s)
  517. #error "MINION_RESET2_s must be greater than MINION_RESET_s"
  518. #endif
  519. /* If there was no reset for this long, clear the reset history
  520. * (except the last one) since this means the current clock is ok
  521. * with rare resets */
  522. #define MINION_CLR_s 300
  523. #if (MINION_CLR_s <= MINION_RESET2_s)
  524. #error "MINION_CLR_s must be greater than MINION_RESET2_s"
  525. #endif
  526. // History must be always generated for the reset check
  527. #define MINION_MAX_RESET_CHECK 2
  528. /* Floating point reset settings required for the code to work properly
  529. * Basically: RESET2 must be after RESET and CLR must be after RESET2 */
  530. static void define_test()
  531. {
  532. float test;
  533. if (MINION_RESET2_PERCENT <= MINION_RESET_PERCENT) {
  534. quithere(1, "MINION_RESET2_PERCENT=%f must be "
  535. "> MINION_RESET_PERCENT=%f",
  536. MINION_RESET2_PERCENT, MINION_RESET_PERCENT);
  537. }
  538. test = FREQ_DELAY(MINION_FREQ_MIN);
  539. if (test >= MINION_HISTORY_s) {
  540. quithere(1, "FREQ_DELAY(MINION_FREQ_MIN)=%f must be "
  541. "< MINION_HISTORY_s=%d",
  542. test, MINION_HISTORY_s);
  543. }
  544. if (MINION_CLR_s <= test) {
  545. quithere(1, "MINION_CLR_s=%d must be > "
  546. "FREQ_DELAY(MINION_FREQ_MIN)=%f",
  547. MINION_CLR_s, test);
  548. }
  549. if (FREQ2_FACTOR <= 1.0)
  550. quithere(1, "FREQ2_FACTOR=%f must be > 1.0", FREQ2_FACTOR);
  551. test = FREQ2_DELAY(MINION_FREQ_MIN);
  552. if (test >= MINION_HISTORY_s) {
  553. quithere(1, "FREQ2_DELAY(MINION_FREQ_MIN)=%f must be "
  554. "< MINION_HISTORY_s=%d",
  555. test, MINION_HISTORY_s);
  556. }
  557. if (MINION_CLR_s <= test) {
  558. quithere(1, "MINION_CLR_s=%d must be > "
  559. "FREQ2_DELAY(MINION_FREQ_MIN)=%f",
  560. MINION_CLR_s, test);
  561. }
  562. }
  563. // *** Chip freq/MHs performance history
  564. typedef struct perf_item {
  565. double elapsed;
  566. uint64_t nonces;
  567. uint32_t freq;
  568. double ghs;
  569. struct timeval when;
  570. } PERF_ITEM;
  571. #define ALLOC_PERF_ITEMS 128
  572. #define LIMIT_PERF_ITEMS 0
  573. // *** 0xff error history
  574. typedef struct xff_item {
  575. time_t when;
  576. } XFF_ITEM;
  577. #define ALLOC_XFF_ITEMS 100
  578. #define LIMIT_XFF_ITEMS 100
  579. #define DATA_WORK(_item) ((WORK_ITEM *)(_item->data))
  580. #define DATA_TASK(_item) ((TASK_ITEM *)(_item->data))
  581. #define DATA_RES(_item) ((RES_ITEM *)(_item->data))
  582. #define DATA_HIST(_item) ((HIST_ITEM *)(_item->data))
  583. #define DATA_PERF(_item) ((PERF_ITEM *)(_item->data))
  584. #define DATA_XFF(_item) ((XFF_ITEM *)(_item->data))
  585. // Set this to 1 to enable iostats processing
  586. // N.B. it slows down mining
  587. #define DO_IO_STATS 0
  588. #if DO_IO_STATS
  589. #define IO_STAT_NOW(_tv) cgtime(_tv)
  590. #define IO_STAT_STORE(_sta, _fin, _lsta, _lfin, _tsd, _buf, _siz, _reply, _ioc) \
  591. do { \
  592. double _diff, _ldiff, _lwdiff, _1time; \
  593. int _off; \
  594. _diff = us_tdiff(_fin, _sta); \
  595. _ldiff = us_tdiff(_lfin, _lsta); \
  596. _lwdiff = us_tdiff(_sta, _lsta); \
  597. _1time = us_tdiff(_tsd, _lfin); \
  598. _off = (int)(_buf[1]) + (_reply >= 0 ? 0 : 0x100); \
  599. minioninfo->summary.count++; \
  600. minioninfo->summary.tsd += _1time; \
  601. minioninfo->iostats[_off].count++; \
  602. minioninfo->iostats[_off].tsd += _1time; \
  603. if (_diff <= 0) { \
  604. minioninfo->summary.zero_delay++; \
  605. minioninfo->iostats[_off].zero_delay++; \
  606. } else { \
  607. minioninfo->summary.total_delay += _diff; \
  608. if (minioninfo->summary.max_delay < _diff) \
  609. minioninfo->summary.max_delay = _diff; \
  610. if (minioninfo->summary.min_delay == 0 || \
  611. minioninfo->summary.min_delay > _diff) \
  612. minioninfo->summary.min_delay = _diff; \
  613. minioninfo->iostats[_off].total_delay += _diff; \
  614. if (minioninfo->iostats[_off].max_delay < _diff) \
  615. minioninfo->iostats[_off].max_delay = _diff; \
  616. if (minioninfo->iostats[_off].min_delay == 0 || \
  617. minioninfo->iostats[_off].min_delay > _diff) \
  618. minioninfo->iostats[_off].min_delay = _diff; \
  619. } \
  620. if (_ldiff <= 0) { \
  621. minioninfo->summary.zero_dlock++; \
  622. minioninfo->iostats[_off].zero_dlock++; \
  623. } else { \
  624. minioninfo->summary.total_dlock += _ldiff; \
  625. if (minioninfo->summary.max_dlock < _ldiff) \
  626. minioninfo->summary.max_dlock = _ldiff; \
  627. if (minioninfo->summary.min_dlock == 0 || \
  628. minioninfo->summary.min_dlock > _ldiff) \
  629. minioninfo->summary.min_dlock = _ldiff; \
  630. minioninfo->iostats[_off].total_dlock += _ldiff; \
  631. if (minioninfo->iostats[_off].max_dlock < _ldiff) \
  632. minioninfo->iostats[_off].max_dlock = _ldiff; \
  633. if (minioninfo->iostats[_off].min_dlock == 0 || \
  634. minioninfo->iostats[_off].min_dlock > _ldiff) \
  635. minioninfo->iostats[_off].min_dlock = _ldiff; \
  636. } \
  637. minioninfo->summary.total_dlwait += _lwdiff; \
  638. minioninfo->iostats[_off].total_dlwait += _lwdiff; \
  639. if (_siz == 0) { \
  640. minioninfo->summary.zero_bytes++; \
  641. minioninfo->iostats[_off].zero_bytes++; \
  642. } else { \
  643. minioninfo->summary.total_bytes += _siz; \
  644. if (minioninfo->summary.max_bytes < _siz) \
  645. minioninfo->summary.max_bytes = _siz; \
  646. if (minioninfo->summary.min_bytes == 0 || \
  647. minioninfo->summary.min_bytes > _siz) \
  648. minioninfo->summary.min_bytes = _siz; \
  649. minioninfo->iostats[_off].total_bytes += _siz; \
  650. if (minioninfo->iostats[_off].max_bytes < _siz) \
  651. minioninfo->iostats[_off].max_bytes = _siz; \
  652. if (minioninfo->iostats[_off].min_bytes == 0 || \
  653. minioninfo->iostats[_off].min_bytes > _siz) \
  654. minioninfo->iostats[_off].min_bytes = _siz; \
  655. } \
  656. } while (0);
  657. typedef struct iostat {
  658. uint64_t count; // total ioctl()
  659. double total_delay; // total elapsed ioctl()
  660. double min_delay;
  661. double max_delay;
  662. uint64_t zero_delay; // how many had <= 0 delay
  663. // Above but including locking
  664. double total_dlock;
  665. double min_dlock;
  666. double max_dlock;
  667. uint64_t zero_dlock;
  668. // Total time waiting to get lock
  669. double total_dlwait;
  670. // these 3 fields are ignored for now since all are '1'
  671. uint64_t total_ioc; // SPI_IOC_MESSAGE(x)
  672. uint64_t min_ioc;
  673. uint64_t max_ioc;
  674. uint64_t total_bytes; // ioctl() bytes
  675. uint64_t min_bytes;
  676. uint64_t max_bytes;
  677. uint64_t zero_bytes; // how many had siz == 0
  678. double tsd; // total doing one extra cgtime() each time
  679. } IOSTAT;
  680. #else
  681. #define IO_STAT_NOW(_tv)
  682. #define IO_STAT_STORE(_sta, _fin, _lsta, _lfin, _tsd, _buf, _siz, _reply, _ioc)
  683. #endif
  684. static double time_bands[] = { 0.1, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0 };
  685. #define TIME_BANDS ((int)(sizeof(time_bands)/sizeof(double)))
  686. struct minion_info {
  687. struct thr_info *thr;
  688. struct thr_info spiw_thr;
  689. struct thr_info spir_thr;
  690. struct thr_info res_thr;
  691. pthread_mutex_t spi_lock;
  692. pthread_mutex_t sta_lock;
  693. cgsem_t task_ready;
  694. cgsem_t nonce_ready;
  695. cgsem_t scan_work;
  696. volatile unsigned *gpio;
  697. int spifd;
  698. char gpiointvalue[64];
  699. int gpiointfd;
  700. // I/O or seconds
  701. bool spi_reset_io;
  702. int spi_reset_count;
  703. time_t last_spi_reset;
  704. uint64_t spi_resets;
  705. // TODO: need to track disabled chips - done?
  706. int chips;
  707. bool has_chip[MINION_CHIPS];
  708. int init_temp[MINION_CHIPS];
  709. uint8_t init_cores[MINION_CHIPS][DATA_SIZ*MINION_CORE_REPS];
  710. uint8_t chipid[MINION_CHIPS]; // Chip Number
  711. int chip_pin[MINION_CHIPS];
  712. uint64_t ioseq;
  713. uint32_t next_task_id;
  714. // Stats
  715. uint64_t chip_nonces[MINION_CHIPS];
  716. uint64_t chip_nononces[MINION_CHIPS];
  717. uint64_t chip_good[MINION_CHIPS];
  718. uint64_t chip_bad[MINION_CHIPS];
  719. uint64_t chip_err[MINION_CHIPS];
  720. uint64_t chip_dup[MINION_CHIPS];
  721. uint64_t core_good[MINION_CHIPS][MINION_CORES+1];
  722. uint64_t core_bad[MINION_CHIPS][MINION_CORES+1];
  723. uint32_t chip_core_ena[MINION_CORE_REPS][MINION_CHIPS];
  724. uint32_t chip_core_act[MINION_CORE_REPS][MINION_CHIPS];
  725. struct minion_status chip_status[MINION_CHIPS];
  726. uint64_t interrupts;
  727. uint64_t result_interrupts;
  728. uint64_t command_interrupts;
  729. char last_interrupt[64];
  730. pthread_mutex_t nonce_lock;
  731. uint64_t new_nonces;
  732. uint64_t ok_nonces;
  733. uint64_t untested_nonces;
  734. uint64_t tested_nonces;
  735. uint64_t work_unrolled;
  736. uint64_t work_rolled;
  737. uint64_t spi_errors;
  738. uint64_t fifo_spi_errors[MINION_CHIPS];
  739. uint64_t res_spi_errors[MINION_CHIPS];
  740. uint64_t use_res2[MINION_CHIPS];
  741. uint64_t tasks_failed[MINION_CHIPS];
  742. uint64_t tasks_recovered[MINION_CHIPS];
  743. uint64_t nonces_failed[MINION_CHIPS];
  744. uint64_t nonces_recovered[MINION_CHIPS];
  745. struct timeval last_reset[MINION_CHIPS];
  746. double do_reset[MINION_CHIPS];
  747. bool flag_reset[MINION_CHIPS];
  748. // Work items
  749. K_LIST *wfree_list;
  750. K_STORE *wwork_list;
  751. K_STORE *wstale_list;
  752. K_STORE *wque_list[MINION_CHIPS];
  753. K_STORE *wchip_list[MINION_CHIPS];
  754. uint64_t wwork_flushed;
  755. uint64_t wque_flushed;
  756. uint64_t wchip_staled;
  757. // Task list
  758. K_LIST *tfree_list;
  759. K_STORE *task_list;
  760. K_STORE *treply_list;
  761. uint64_t next_tid;
  762. // Nonce replies
  763. K_LIST *rfree_list;
  764. K_STORE *rnonce_list;
  765. struct timeval last_did;
  766. // Nonce history
  767. K_LIST *hfree_list;
  768. K_STORE *hchip_list[MINION_CHIPS];
  769. int history_gen;
  770. struct timeval chip_chk;
  771. struct timeval chip_rpt;
  772. double history_ghs[MINION_CHIPS];
  773. // Point in history for MINION_RESET_s
  774. int reset_time[MINION_CHIPS];
  775. K_ITEM *reset_mark[MINION_CHIPS];
  776. int reset_count[MINION_CHIPS];
  777. // Point in history for MINION_RESET2_s
  778. int reset2_time[MINION_CHIPS];
  779. K_ITEM *reset2_mark[MINION_CHIPS];
  780. int reset2_count[MINION_CHIPS];
  781. // Performance history
  782. K_LIST *pfree_list;
  783. K_STORE *p_list[MINION_CHIPS];
  784. // 0xff history
  785. K_LIST *xfree_list;
  786. K_STORE *xff_list;
  787. time_t last_power_cycle;
  788. uint64_t power_cycles;
  789. time_t last_xff;
  790. uint64_t xffs;
  791. uint64_t last_displayed_xff;
  792. // Gets reset to zero each time it is used in reporting
  793. int res_err_count[MINION_CHIPS];
  794. #if DO_IO_STATS
  795. // Total
  796. IOSTAT summary;
  797. // Two for each command plus wasted extras i.e. direct/fast lookup
  798. // No error uses 0x0 to 0xff, error uses 0x100 to 0x1ff
  799. IOSTAT iostats[0x200];
  800. #endif
  801. // Stats on how long work is waiting to move from wwork_list to wque_list
  802. uint64_t que_work;
  803. double que_time;
  804. double que_min;
  805. double que_max;
  806. uint64_t que_bands[TIME_BANDS+1];
  807. // From wwork_list to txrx
  808. uint64_t wt_work;
  809. double wt_time;
  810. double wt_min;
  811. double wt_max;
  812. uint64_t wt_bands[TIME_BANDS+1];
  813. bool lednow[MINION_CHIPS];
  814. bool setled[MINION_CHIPS];
  815. // When changing the frequency don't modify 'anything'
  816. bool changing[MINION_CHIPS];
  817. int init_freq[MINION_CHIPS];
  818. int want_freq[MINION_CHIPS];
  819. uint32_t freqsent[MINION_CHIPS];
  820. struct timeval lastfreq[MINION_CHIPS];
  821. int freqms[MINION_CHIPS];
  822. bool initialised;
  823. };
  824. #if MINION_ROCKCHIP == 1
  825. static bool minion_toggle_gpio(struct cgpu_info *minioncgpu, int gpionum)
  826. {
  827. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  828. char pindir[64], ena[64], pin[8], dir[64];
  829. char gpiointvalue[64];
  830. struct stat st;
  831. int file, err, chip;
  832. ssize_t ret;
  833. snprintf(pindir, sizeof(pindir), MINION_GPIO_SYS MINION_GPIO_PIN, gpionum);
  834. memset(&st, 0, sizeof(st));
  835. if (stat(pindir, &st) == 0) { // already exists
  836. if (!S_ISDIR(st.st_mode)) {
  837. applog(LOG_ERR, "%s: failed1 to enable GPIO pin %d"
  838. " - not a directory",
  839. minioncgpu->drv->dname, gpionum);
  840. return false;
  841. }
  842. } else {
  843. snprintf(ena, sizeof(ena), MINION_GPIO_SYS MINION_GPIO_ENA);
  844. file = open(ena, O_WRONLY | O_SYNC);
  845. if (file == -1) {
  846. applog(LOG_ERR, "%s: failed2 to export GPIO pin %d (%d)"
  847. " - you need to be root?",
  848. minioncgpu->drv->dname,
  849. gpionum, errno);
  850. return false;
  851. }
  852. snprintf(pin, sizeof(pin), MINION_GPIO_ENA_VAL, gpionum);
  853. ret = write(file, pin, (size_t)strlen(pin));
  854. if (ret != (ssize_t)strlen(pin)) {
  855. if (ret < 0)
  856. err = errno;
  857. else
  858. err = (int)ret;
  859. close(file);
  860. applog(LOG_ERR, "%s: failed3 to export GPIO pin %d (%d:%d)",
  861. minioncgpu->drv->dname,
  862. gpionum, err, (int)strlen(pin));
  863. return false;
  864. }
  865. close(file);
  866. // Check again if it exists
  867. memset(&st, 0, sizeof(st));
  868. if (stat(pindir, &st) != 0) {
  869. applog(LOG_ERR, "%s: failed4 to export GPIO pin %d (%d)",
  870. minioncgpu->drv->dname,
  871. gpionum, errno);
  872. return false;
  873. }
  874. }
  875. // Set the pin attributes
  876. // Direction
  877. snprintf(dir, sizeof(dir), MINION_GPIO_SYS MINION_GPIO_PIN MINION_GPIO_DIR, gpionum);
  878. file = open(dir, O_WRONLY | O_SYNC);
  879. if (file == -1) {
  880. applog(LOG_ERR, "%s: failed5 to configure GPIO pin %d (%d)"
  881. " - you need to be root?",
  882. minioncgpu->drv->dname,
  883. gpionum, errno);
  884. return false;
  885. }
  886. ret = write(file, MINION_GPIO_DIR_WRITE, sizeof(MINION_GPIO_DIR_WRITE)-1);
  887. if (ret != sizeof(MINION_GPIO_DIR_WRITE)-1) {
  888. if (ret < 0)
  889. err = errno;
  890. else
  891. err = (int)ret;
  892. close(file);
  893. applog(LOG_ERR, "%s: failed6 to configure GPIO pin %d (%d:%d)",
  894. minioncgpu->drv->dname, gpionum,
  895. err, (int)sizeof(MINION_GPIO_DIR_WRITE)-1);
  896. return false;
  897. }
  898. close(file);
  899. // Open it
  900. snprintf(gpiointvalue, sizeof(gpiointvalue),
  901. MINION_GPIO_SYS MINION_GPIO_PIN MINION_GPIO_VALUE,
  902. gpionum);
  903. int fd = open(gpiointvalue, O_WRONLY);
  904. if (fd == -1) {
  905. applog(LOG_ERR, "%s: failed7 to access GPIO pin %d (%d)",
  906. minioncgpu->drv->dname,
  907. gpionum, errno);
  908. return false;
  909. }
  910. ret = write(fd, MINION_CHIP_OFF, sizeof(MINION_CHIP_OFF)-1);
  911. if (ret != sizeof(MINION_CHIP_OFF)-1) {
  912. close(fd);
  913. applog(LOG_ERR, "%s: failed8 to toggle off GPIO pin %d (%d:%d)",
  914. minioncgpu->drv->dname,
  915. gpionum, (int)ret, errno);
  916. return false;
  917. }
  918. cgsleep_ms(MINION_CHIP_DELAY);
  919. ret = write(fd, MINION_CHIP_ON, sizeof(MINION_CHIP_ON)-1);
  920. if (ret != sizeof(MINION_CHIP_OFF)-1) {
  921. close(fd);
  922. applog(LOG_ERR, "%s: failed9 to toggle on GPIO pin %d (%d:%d)",
  923. minioncgpu->drv->dname,
  924. gpionum, (int)ret, errno);
  925. return false;
  926. }
  927. close(fd);
  928. minioninfo->last_power_cycle = time(NULL);
  929. minioninfo->power_cycles++;
  930. // Reset all chip led counters
  931. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  932. if (minioninfo->has_chip[chip])
  933. minioninfo->chip_status[chip].first_nonce.tv_sec = 0L;
  934. }
  935. return true;
  936. }
  937. #endif
  938. static void ready_work(struct cgpu_info *minioncgpu, struct work *work, bool rolled)
  939. {
  940. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  941. K_ITEM *item = NULL;
  942. K_WLOCK(minioninfo->wfree_list);
  943. item = k_unlink_head(minioninfo->wfree_list);
  944. DATA_WORK(item)->work = work;
  945. DATA_WORK(item)->task_id = 0;
  946. memset(&(DATA_WORK(item)->sent), 0, sizeof(DATA_WORK(item)->sent));
  947. DATA_WORK(item)->nonces = 0;
  948. DATA_WORK(item)->urgent = false;
  949. DATA_WORK(item)->rolled = rolled;
  950. DATA_WORK(item)->errors = 0;
  951. cgtime(&(DATA_WORK(item)->created));
  952. k_add_head(minioninfo->wwork_list, item);
  953. K_WUNLOCK(minioninfo->wfree_list);
  954. }
  955. static bool oldest_nonce(struct cgpu_info *minioncgpu, int *chip, int *core, uint32_t *task_id,
  956. uint32_t *nonce, bool *no_nonce, struct timeval *when,
  957. bool *another, uint32_t *task_id2, uint32_t *nonce2)
  958. {
  959. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  960. K_ITEM *item = NULL;
  961. bool found = false;
  962. K_WLOCK(minioninfo->rnonce_list);
  963. item = k_unlink_tail(minioninfo->rnonce_list);
  964. if (item) {
  965. found = true;
  966. *chip = DATA_RES(item)->chip;
  967. *core = DATA_RES(item)->core;
  968. *task_id = DATA_RES(item)->task_id;
  969. *nonce = DATA_RES(item)->nonce;
  970. *no_nonce = DATA_RES(item)->no_nonce;
  971. memcpy(when, &(DATA_RES(item)->when), sizeof(*when));
  972. *another = DATA_RES(item)->another;
  973. *task_id2 = DATA_RES(item)->task_id2;
  974. *nonce2 = DATA_RES(item)->nonce2;
  975. k_free_head(minioninfo->rfree_list, item);
  976. }
  977. K_WUNLOCK(minioninfo->rnonce_list);
  978. return found;
  979. }
  980. static const char *addr2txt(uint8_t addr)
  981. {
  982. switch (addr) {
  983. case READ_ADDR(MINION_SYS_CHIP_SIG):
  984. return "RChipSig";
  985. case READ_ADDR(MINION_SYS_CHIP_STA):
  986. return "RChipSta";
  987. case WRITE_ADDR(MINION_SYS_SPI_LED):
  988. return "WLed";
  989. case WRITE_ADDR(MINION_SYS_MISC_CTL):
  990. return "WMiscCtrl";
  991. case WRITE_ADDR(MINION_SYS_RSTN_CTL):
  992. return "WResetCtrl";
  993. case READ_ADDR(MINION_SYS_FIFO_STA):
  994. return "RFifoSta";
  995. case READ_ADDR(MINION_CORE_ENA0_31):
  996. return "RCoreEna0-31";
  997. case WRITE_ADDR(MINION_CORE_ENA0_31):
  998. return "WCoreEna0-31";
  999. case READ_ADDR(MINION_CORE_ENA32_63):
  1000. return "RCoreEna32-63";
  1001. case WRITE_ADDR(MINION_CORE_ENA32_63):
  1002. return "WCoreEna32-63";
  1003. case READ_ADDR(MINION_CORE_ENA64_95):
  1004. return "RCoreEna64-95";
  1005. case WRITE_ADDR(MINION_CORE_ENA64_95):
  1006. return "WCoreEna64-95";
  1007. case READ_ADDR(MINION_CORE_ENA96_98):
  1008. return "RCoreEna96-98";
  1009. case WRITE_ADDR(MINION_CORE_ENA96_98):
  1010. return "WCoreEna96-98";
  1011. case READ_ADDR(MINION_CORE_ACT0_31):
  1012. return "RCoreAct0-31";
  1013. case READ_ADDR(MINION_CORE_ACT32_63):
  1014. return "RCoreAct32-63";
  1015. case READ_ADDR(MINION_CORE_ACT64_95):
  1016. return "RCoreAct64-95";
  1017. case READ_ADDR(MINION_CORE_ACT96_98):
  1018. return "RCoreAct96-98";
  1019. case READ_ADDR(MINION_RES_DATA):
  1020. return "RResData";
  1021. case READ_ADDR(MINION_RES_PEEK):
  1022. return "RResPeek";
  1023. case WRITE_ADDR(MINION_QUE_0):
  1024. return "WQueWork";
  1025. case READ_ADDR(MINION_NONCE_START):
  1026. return "RNonceStart";
  1027. case WRITE_ADDR(MINION_NONCE_START):
  1028. return "WNonceStart";
  1029. case READ_ADDR(MINION_NONCE_RANGE):
  1030. return "RNonceRange";
  1031. case WRITE_ADDR(MINION_NONCE_RANGE):
  1032. return "WNonceRange";
  1033. case READ_ADDR(MINION_SYS_INT_STA):
  1034. return "RIntSta";
  1035. case WRITE_ADDR(MINION_SYS_INT_ENA):
  1036. return "WIntEna";
  1037. case WRITE_ADDR(MINION_SYS_INT_CLR):
  1038. return "WIntClear";
  1039. case WRITE_ADDR(MINION_SYS_BUF_TRIG):
  1040. return "WResTrigger";
  1041. case WRITE_ADDR(MINION_SYS_QUE_TRIG):
  1042. return "WCmdTrigger";
  1043. case READ_ADDR(MINION_SYS_TEMP_CTL):
  1044. return "RTempCtrl";
  1045. case WRITE_ADDR(MINION_SYS_TEMP_CTL):
  1046. return "WTempCtrl";
  1047. case READ_ADDR(MINION_SYS_FREQ_CTL):
  1048. return "RFreqCtrl";
  1049. case WRITE_ADDR(MINION_SYS_FREQ_CTL):
  1050. return "WFreqCtrl";
  1051. case READ_ADDR(MINION_SYS_IDLE_CNT):
  1052. return "RIdleCnt";
  1053. }
  1054. // gcc warning if this is in default:
  1055. if (IS_ADDR_READ(addr))
  1056. return "RUnhandled";
  1057. else
  1058. return "WUnhandled";
  1059. }
  1060. // For display_ioctl()
  1061. #define IOCTRL_LOG LOG_WARNING
  1062. // For all other debug so it can easily be switched always on
  1063. #define MINION_LOG LOG_DEBUG
  1064. // For task corruption logging
  1065. #define MINTASK_LOG LOG_DEBUG
  1066. // Set to 1 for debug
  1067. #define MINION_SHOW_IO 0
  1068. #define DATA_ALL 2048
  1069. #define DATA_OFF 512
  1070. #if MINION_SHOW_IO
  1071. static void display_ioctl(int reply, uint32_t osiz, uint8_t *obuf, uint32_t rsiz, uint8_t *rbuf)
  1072. {
  1073. struct minion_result *res;
  1074. const char *name, *dir, *ex;
  1075. char buf[4096];
  1076. int i, rescount;
  1077. name = addr2txt(obuf[1]);
  1078. if (IS_ADDR_READ(obuf[1]))
  1079. dir = "from";
  1080. else
  1081. dir = "to";
  1082. buf[0] = '\0';
  1083. ex = "";
  1084. switch (obuf[1]) {
  1085. case READ_ADDR(MINION_SYS_CHIP_SIG):
  1086. case READ_ADDR(MINION_SYS_CHIP_STA):
  1087. break;
  1088. case WRITE_ADDR(MINION_SYS_SPI_LED):
  1089. case WRITE_ADDR(MINION_SYS_MISC_CTL):
  1090. case WRITE_ADDR(MINION_SYS_RSTN_CTL):
  1091. if (osiz > HSIZE()) {
  1092. ex = " wrote ";
  1093. __bin2hex(buf, obuf + HSIZE(), osiz - HSIZE());
  1094. } else
  1095. ex = " wrote nothing";
  1096. break;
  1097. default:
  1098. if (IS_ADDR_WRITE(obuf[1])) {
  1099. if (osiz > HSIZE()) {
  1100. ex = " wrote ";
  1101. __bin2hex(buf, obuf + HSIZE(), osiz - HSIZE());
  1102. } else
  1103. ex = " wrote nothing";
  1104. }
  1105. break;
  1106. }
  1107. if (reply < 0) {
  1108. applog(IOCTRL_LOG, "%s %s chipid %d osiz %d%s%s",
  1109. name, dir, (int)obuf[0], (int)osiz, ex, buf);
  1110. applog(IOCTRL_LOG, " reply was error %d", reply);
  1111. } else {
  1112. if (IS_ADDR_WRITE(obuf[1])) {
  1113. applog(IOCTRL_LOG, "%s %s chipid %d osiz %d%s%s",
  1114. name, dir, (int)obuf[0], (int)osiz, ex, buf);
  1115. applog(IOCTRL_LOG, " write ret was %d", reply);
  1116. } else {
  1117. switch (obuf[1]) {
  1118. case READ_ADDR(MINION_RES_DATA):
  1119. rescount = (int)((float)rsiz / (float)MINION_RES_DATA_SIZ);
  1120. applog(IOCTRL_LOG, "%s %s chipid %d osiz %d%s%s",
  1121. name, dir, (int)obuf[0], (int)osiz, ex, buf);
  1122. for (i = 0; i < rescount; i++) {
  1123. res = (struct minion_result *)(rbuf + osiz - rsiz + (i * MINION_RES_DATA_SIZ));
  1124. if (!IS_RESULT(res)) {
  1125. applog(IOCTRL_LOG, " %s reply %d of %d - none", name, i+1, rescount);
  1126. } else {
  1127. __bin2hex(buf, res->nonce, DATA_SIZ);
  1128. applog(IOCTRL_LOG, " %s reply %d of %d %d(%d) was task 0x%04x"
  1129. " chipid %d core %d gold %s nonce 0x%s",
  1130. name, i+1, rescount, reply, rsiz,
  1131. RES_TASK(res),
  1132. (int)RES_CHIPID(res),
  1133. (int)RES_CORE(res),
  1134. (int)RES_GOLD(res) ? "Y" : "N",
  1135. buf);
  1136. }
  1137. }
  1138. break;
  1139. case READ_ADDR(MINION_SYS_CHIP_SIG):
  1140. case READ_ADDR(MINION_SYS_CHIP_STA):
  1141. default:
  1142. applog(IOCTRL_LOG, "%s %s chipid %d osiz %d%s%s",
  1143. name, dir, (int)obuf[0], (int)osiz, ex, buf);
  1144. __bin2hex(buf, rbuf + osiz - rsiz, rsiz);
  1145. applog(IOCTRL_LOG, " %s reply %d(%d) was %s", name, reply, rsiz, buf);
  1146. break;
  1147. }
  1148. }
  1149. }
  1150. }
  1151. #endif
  1152. #define MINION_UNEXPECTED_TASK -999
  1153. #define MINION_OVERSIZE_TASK -998
  1154. static void set_pin(struct minion_info *minioninfo, int pin, bool on)
  1155. {
  1156. volatile uint32_t *paddr;
  1157. uint32_t value;
  1158. int bcm;
  1159. bcm = minionPins[pin].bcm;
  1160. paddr = minioninfo->gpio + ((on ? BCM2835_GPIO_SET0 : BCM2835_GPIO_CLR0) / 4) + (bcm / 10);
  1161. value = 1 << (bcm % 32);
  1162. *paddr = value;
  1163. *paddr = value;
  1164. }
  1165. static void init_pins(struct minion_info *minioninfo)
  1166. {
  1167. int pin;
  1168. // Initialise all pins high as required
  1169. MINION_PIN_BEFORE;
  1170. for (pin = 0; pin < (int)MINION_PIN_COUNT; pin++) {
  1171. set_pin(minioninfo, pin, true);
  1172. MINION_PIN_SLEEP;
  1173. }
  1174. }
  1175. #define EXTRA_LOG_IO 0
  1176. static bool minion_init_spi(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int bus, int chip, bool reset);
  1177. static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minioninfo,
  1178. int pin, uint8_t *obuf, uint32_t osiz, uint8_t *rbuf,
  1179. uint32_t rsiz, uint64_t *ioseq, MINION_FFL_ARGS)
  1180. {
  1181. struct spi_ioc_transfer tran;
  1182. bool fail = false, powercycle = false, show = false;
  1183. double lastshow, total;
  1184. K_ITEM *xitem;
  1185. time_t now;
  1186. int ret;
  1187. #if MINION_SHOW_IO
  1188. char dataw[DATA_ALL], datar[DATA_ALL];
  1189. #endif
  1190. #if DO_IO_STATS
  1191. struct timeval sta, fin, lsta, lfin, tsd;
  1192. #endif
  1193. if ((int)osiz > MINION_BUFSIZ)
  1194. quitfrom(1, file, func, line, "%s() invalid osiz %u > %d (chip=%d reg=0x%02x)",
  1195. __func__, osiz, MINION_BUFSIZ, (int)(obuf[0]), obuf[1]);
  1196. if (rsiz >= osiz)
  1197. quitfrom(1, file, func, line, "%s() invalid rsiz %u >= osiz %u (chip=%u reg=0x%02x)",
  1198. __func__, rsiz, osiz, (int)(obuf[0]), obuf[1]);
  1199. memset(&obuf[0] + osiz - rsiz, 0xff, rsiz);
  1200. #if MINION_SHOW_IO
  1201. // if the a5/5a outside the data change, it means data overrun or corruption
  1202. memset(dataw, 0xa5, sizeof(dataw));
  1203. memset(datar, 0x5a, sizeof(datar));
  1204. memcpy(&dataw[DATA_OFF], &obuf[0], osiz);
  1205. char *buf = bin2hex((unsigned char *)&(dataw[DATA_OFF]), osiz);
  1206. applog(IOCTRL_LOG, "*** %s() pin %d cid %d sending %02x %02x %s %02x %02x",
  1207. __func__, pin, (int)(dataw[DATA_OFF]),
  1208. dataw[0], dataw[DATA_OFF-1], buf,
  1209. dataw[DATA_OFF+osiz], dataw[DATA_ALL-1]);
  1210. free(buf);
  1211. #endif
  1212. memset((char *)rbuf, 0x00, osiz);
  1213. // cgsleep_ms(5); // TODO: a delay ... based on the last command? But subtract elapsed
  1214. // i.e. do any commands need a delay after the I/O has completed before the next I/O?
  1215. memset(&tran, 0, sizeof(tran));
  1216. if (osiz < MINION_SPI_BUFSIZ)
  1217. tran.len = osiz;
  1218. else
  1219. return MINION_OVERSIZE_TASK;
  1220. tran.delay_usecs = opt_minion_spiusec;
  1221. tran.speed_hz = MINION_SPI_SPEED;
  1222. #if MINION_SHOW_IO
  1223. tran.tx_buf = (uintptr_t)&(dataw[DATA_OFF]);
  1224. tran.rx_buf = (uintptr_t)&(datar[DATA_OFF]);
  1225. #else
  1226. tran.tx_buf = (uintptr_t)obuf;
  1227. tran.rx_buf = (uintptr_t)rbuf;
  1228. #endif
  1229. IO_STAT_NOW(&lsta);
  1230. mutex_lock(&(minioninfo->spi_lock));
  1231. if (usepins) {
  1232. // Pin low for I/O
  1233. MINION_PIN_BEFORE;
  1234. set_pin(minioninfo, pin, false);
  1235. MINION_PIN_SLEEP;
  1236. }
  1237. IO_STAT_NOW(&sta);
  1238. ret = ioctl(minioninfo->spifd, SPI_IOC_MESSAGE(1), (void *)&tran);
  1239. *ioseq = minioninfo->ioseq++;
  1240. IO_STAT_NOW(&fin);
  1241. if (usepins) {
  1242. MINION_PIN_AFTER;
  1243. // Pin back high after I/O
  1244. set_pin(minioninfo, pin, true);
  1245. }
  1246. now = time(NULL);
  1247. if (ret >= 0 && rbuf[0] == 0xff && rbuf[ret-1] == 0xff &&
  1248. (obuf[1] == READ_ADDR(MINION_RES_DATA) || obuf[1] == READ_ADDR(MINION_SYS_FIFO_STA))) {
  1249. int i;
  1250. fail = true;
  1251. for (i = 1; i < ret-2; i++) {
  1252. if (rbuf[i] != 0xff) {
  1253. fail = false;
  1254. break;
  1255. }
  1256. }
  1257. if (fail) {
  1258. powercycle = show = false;
  1259. minioninfo->xffs++;
  1260. minioninfo->last_xff = now;
  1261. if (minioninfo->xfree_list->count > 0)
  1262. xitem = k_unlink_head(minioninfo->xfree_list);
  1263. else
  1264. xitem = k_unlink_tail(minioninfo->xff_list);
  1265. DATA_XFF(xitem)->when = now;
  1266. if (!minioninfo->xff_list->head)
  1267. show = true;
  1268. else {
  1269. // if !changing and xff_list is full
  1270. if (!minioninfo->changing[obuf[0]] &&
  1271. minioninfo->xfree_list->count == 0) {
  1272. total = DATA_XFF(xitem)->when -
  1273. DATA_XFF(minioninfo->xff_list->tail)->when;
  1274. if (total <= MINION_POWER_TIME) {
  1275. powercycle = true;
  1276. // Discard the history
  1277. k_list_transfer_to_head(minioninfo->xff_list,
  1278. minioninfo->xfree_list);
  1279. k_add_head(minioninfo->xfree_list, xitem);
  1280. xitem = NULL;
  1281. }
  1282. }
  1283. if (!powercycle) {
  1284. lastshow = DATA_XFF(xitem)->when -
  1285. DATA_XFF(minioninfo->xff_list->head)->when;
  1286. show = (lastshow >= 5);
  1287. }
  1288. }
  1289. if (xitem)
  1290. k_add_head(minioninfo->xff_list, xitem);
  1291. #if MINION_ROCKCHIP == 1
  1292. if (powercycle)
  1293. minion_toggle_gpio(minioncgpu, MINION_POWERCYCLE_GPIO);
  1294. #endif
  1295. minion_init_spi(minioncgpu, minioninfo, 0, 0, true);
  1296. }
  1297. } else if (minioninfo->spi_reset_count) {
  1298. if (minioninfo->spi_reset_io) {
  1299. if (*ioseq > 0 && (*ioseq % minioninfo->spi_reset_count) == 0)
  1300. minion_init_spi(minioncgpu, minioninfo, 0, 0, true);
  1301. } else {
  1302. if (minioninfo->last_spi_reset == 0)
  1303. minioninfo->last_spi_reset = now;
  1304. else {
  1305. if ((now - minioninfo->last_spi_reset) >= minioninfo->spi_reset_count)
  1306. minion_init_spi(minioncgpu, minioninfo, 0, 0, true);
  1307. minioninfo->last_spi_reset = now;
  1308. }
  1309. }
  1310. }
  1311. if (opt_minion_spidelay)
  1312. cgsleep_ms(opt_minion_spidelay);
  1313. mutex_unlock(&(minioninfo->spi_lock));
  1314. IO_STAT_NOW(&lfin);
  1315. IO_STAT_NOW(&tsd);
  1316. IO_STAT_STORE(&sta, &fin, &lsta, &lfin, &tsd, obuf, osiz, ret, 1);
  1317. if (fail) {
  1318. if (powercycle) {
  1319. applog(LOG_ERR, "%s%d: power cycle ioctl %"PRIu64" (%"PRIu64")",
  1320. minioncgpu->drv->name, minioncgpu->device_id, *ioseq,
  1321. minioninfo->xffs - minioninfo->last_displayed_xff);
  1322. minioninfo->last_displayed_xff = minioninfo->xffs;
  1323. } else if (show) {
  1324. char *what = "unk";
  1325. switch (obuf[1]) {
  1326. case READ_ADDR(MINION_RES_DATA):
  1327. what = "nonce";
  1328. break;
  1329. case READ_ADDR(MINION_SYS_FIFO_STA):
  1330. what = "fifo";
  1331. break;
  1332. }
  1333. applog(LOG_ERR, "%s%d: reset ioctl %"PRIu64" %s all 0xff (%"PRIu64")",
  1334. minioncgpu->drv->name, minioncgpu->device_id,
  1335. *ioseq, what, minioninfo->xffs - minioninfo->last_displayed_xff);
  1336. minioninfo->last_displayed_xff = minioninfo->xffs;
  1337. }
  1338. }
  1339. #if MINION_SHOW_IO
  1340. if (ret > 0) {
  1341. buf = bin2hex((unsigned char *)&(datar[DATA_OFF]), ret);
  1342. applog(IOCTRL_LOG, "*** %s() reply %d = pin %d cid %d %02x %02x %s %02x %02x",
  1343. __func__, ret, pin, (int)(dataw[DATA_OFF]),
  1344. datar[0], datar[DATA_OFF-1], buf,
  1345. datar[DATA_OFF+osiz], datar[DATA_ALL-1]);
  1346. free(buf);
  1347. } else
  1348. applog(LOG_ERR, "*** %s() reply = %d", __func__, ret);
  1349. memcpy(&rbuf[0], &datar[DATA_OFF], osiz);
  1350. display_ioctl(ret, osiz, (uint8_t *)(&dataw[DATA_OFF]), rsiz, (uint8_t *)(&datar[DATA_OFF]));
  1351. #endif
  1352. #if EXTRA_LOG_IO
  1353. if (obuf[1] == READ_ADDR(MINION_RES_PEEK) ||
  1354. obuf[1] == READ_ADDR(MINION_RES_DATA) ||
  1355. obuf[1] == READ_ADDR(MINION_SYS_FIFO_STA)) {
  1356. char *uf1, *uf2, c;
  1357. uf1 = bin2hex(obuf, DATA_SIZ);
  1358. uf2 = bin2hex(rbuf, (size_t)ret);
  1359. switch (obuf[1]) {
  1360. case READ_ADDR(MINION_RES_PEEK):
  1361. c = 'P';
  1362. break;
  1363. case READ_ADDR(MINION_RES_DATA):
  1364. c = 'D';
  1365. break;
  1366. case READ_ADDR(MINION_SYS_FIFO_STA):
  1367. c = 'F';
  1368. break;
  1369. }
  1370. applog(LOG_WARNING, "*** ioseq %"PRIu64" cmd %c %s rep %.8s %s",
  1371. *ioseq, c, uf1, uf2, uf2+8);
  1372. free(uf2);
  1373. free(uf1);
  1374. }
  1375. if (obuf[1] == WRITE_ADDR(MINION_QUE_0)) {
  1376. char *uf;
  1377. uf = bin2hex(obuf, osiz);
  1378. applog(LOG_WARNING, "*** ioseq %"PRIu64" work %s",
  1379. *ioseq, uf);
  1380. free(uf);
  1381. }
  1382. #endif
  1383. return ret;
  1384. }
  1385. #if 1
  1386. #define do_ioctl(_pin, _obuf, _osiz, _rbuf, _rsiz, _ioseq) \
  1387. __do_ioctl(minioncgpu, minioninfo, _pin, _obuf, _osiz, _rbuf, \
  1388. _rsiz, _ioseq, MINION_FFL_HERE)
  1389. #else
  1390. #define do_ioctl(_pin, _obuf, _osiz, _rbuf, _rsiz, _ioseq) \
  1391. _do_ioctl(minioninfo, _pin, _obuf, _osiz, _rbuf, \
  1392. _rsiz, _ioseq, MINION_FFL_HERE)
  1393. // This sends an expected to work, SPI command before each SPI command
  1394. static int _do_ioctl(struct minion_info *minioninfo, int pin, uint8_t *obuf, uint32_t osiz, uint8_t *rbuf, uint32_t rsiz, uint64_t *ioseq, MINION_FFL_ARGS)
  1395. {
  1396. struct minion_header *head;
  1397. uint8_t buf1[MINION_BUFSIZ];
  1398. uint8_t buf2[MINION_BUFSIZ];
  1399. uint32_t siz;
  1400. head = (struct minion_header *)buf1;
  1401. head->chipid = 1; // Needs to be set to a valid chip
  1402. head->reg = READ_ADDR(MINION_SYS_FIFO_STA);
  1403. SET_HEAD_SIZ(head, DATA_SIZ);
  1404. siz = HSIZE() + DATA_SIZ;
  1405. __do_ioctl(minioncgpu, minioninfo, pin, buf1, siz, buf2, MINION_CORE_SIZ, ioseq, MINION_FFL_PASS);
  1406. return __do_ioctl(minioncgpu, minioninfo, pin, obuf, osiz, rbuf, rsiz, ioseq, MINION_FFL_PASS);
  1407. }
  1408. #endif
  1409. static bool _minion_txrx(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, TASK_ITEM *task, MINION_FFL_ARGS)
  1410. {
  1411. struct minion_header *head;
  1412. head = (struct minion_header *)(task->obuf);
  1413. head->chipid = minioninfo->chipid[task->chip];
  1414. if (task->write)
  1415. SET_HEAD_WRITE(head, task->address);
  1416. else
  1417. SET_HEAD_READ(head, task->address);
  1418. SET_HEAD_SIZ(head, task->wsiz + task->rsiz);
  1419. if (task->wsiz)
  1420. memcpy(&(head->data[0]), task->wbuf, task->wsiz);
  1421. task->osiz = HSIZE() + task->wsiz + task->rsiz;
  1422. task->reply = do_ioctl(CHIP_PIN(task->chip), task->obuf, task->osiz, task->rbuf, task->rsiz,
  1423. &(task->ioseq));
  1424. if (task->reply < 0) {
  1425. applog(LOG_ERR, "%s%d: chip=%d ioctl failed reply=%d err=%d" MINION_FFL,
  1426. minioncgpu->drv->name, minioncgpu->device_id,
  1427. task->chip, task->reply, errno, MINION_FFL_PASS);
  1428. } else if (task->reply < (int)(task->osiz)) {
  1429. applog(LOG_ERR, "%s%d: chip=%d ioctl failed to write %d only wrote %d (err=%d)" MINION_FFL,
  1430. minioncgpu->drv->name, minioncgpu->device_id,
  1431. task->chip, (int)(task->osiz), task->reply, errno, MINION_FFL_PASS);
  1432. }
  1433. return (task->reply >= (int)(task->osiz));
  1434. }
  1435. // Only for DATA_SIZ commands
  1436. static int build_cmd(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip, uint8_t reg, uint8_t *rbuf, uint32_t rsiz, uint8_t *data)
  1437. {
  1438. struct minion_header *head;
  1439. uint8_t wbuf[MINION_BUFSIZ];
  1440. uint32_t wsiz;
  1441. uint64_t ioseq;
  1442. int reply;
  1443. head = (struct minion_header *)wbuf;
  1444. head->chipid = minioninfo->chipid[chip];
  1445. head->reg = reg;
  1446. SET_HEAD_SIZ(head, DATA_SIZ);
  1447. head->data[0] = data[0];
  1448. head->data[1] = data[1];
  1449. head->data[2] = data[2];
  1450. head->data[3] = data[3];
  1451. wsiz = HSIZE() + DATA_SIZ;
  1452. reply = do_ioctl(CHIP_PIN(chip), wbuf, wsiz, rbuf, rsiz, &ioseq);
  1453. if (reply != (int)wsiz) {
  1454. applog(LOG_ERR, "%s: chip %d %s returned %d (should be %d)",
  1455. minioncgpu->drv->dname, chip,
  1456. addr2txt(head->reg),
  1457. reply, (int)wsiz);
  1458. }
  1459. return reply;
  1460. }
  1461. static void set_freq(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip, int freq)
  1462. {
  1463. uint8_t rbuf[MINION_BUFSIZ];
  1464. uint8_t data[4];
  1465. uint32_t value;
  1466. __maybe_unused int reply;
  1467. freq /= MINION_FREQ_FACTOR;
  1468. if (freq < MINION_FREQ_FACTOR_MIN)
  1469. freq = MINION_FREQ_FACTOR_MIN;
  1470. if (freq > MINION_FREQ_FACTOR_MAX)
  1471. freq = MINION_FREQ_FACTOR_MAX;
  1472. value = minion_freq[freq];
  1473. data[0] = (uint8_t)(value & 0xff);
  1474. data[1] = (uint8_t)(((value & 0xff00) >> 8) & 0xff);
  1475. data[2] = (uint8_t)(((value & 0xff0000) >> 16) & 0xff);
  1476. data[3] = (uint8_t)(((value & 0xff000000) >> 24) & 0xff);
  1477. minioninfo->freqsent[chip] = value;
  1478. reply = build_cmd(minioncgpu, minioninfo,
  1479. chip, WRITE_ADDR(MINION_SYS_FREQ_CTL),
  1480. rbuf, 0, data);
  1481. cgtime(&(minioninfo->lastfreq[chip]));
  1482. applog(LOG_DEBUG, "%s%i: chip %d freq %d sec %d usec %d",
  1483. minioncgpu->drv->name, minioncgpu->device_id,
  1484. chip, freq,
  1485. (int)(minioninfo->lastfreq[chip].tv_sec) % 10,
  1486. (int)(minioninfo->lastfreq[chip].tv_usec));
  1487. // Reset all this info on chip reset or freq change
  1488. minioninfo->reset_time[chip] = (int)FREQ_DELAY(minioninfo->init_freq[chip]);
  1489. if (second_check)
  1490. minioninfo->reset2_time[chip] = (int)FREQ2_DELAY(minioninfo->init_freq[chip]);
  1491. minioninfo->chip_status[chip].first_nonce.tv_sec = 0L;
  1492. // Discard chip history (if there is any)
  1493. if (minioninfo->hfree_list) {
  1494. K_WLOCK(minioninfo->hfree_list);
  1495. k_list_transfer_to_head(minioninfo->hchip_list[chip], minioninfo->hfree_list);
  1496. minioninfo->reset_mark[chip] = NULL;
  1497. minioninfo->reset_count[chip] = 0;
  1498. K_WUNLOCK(minioninfo->hfree_list);
  1499. }
  1500. }
  1501. static void init_chip(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip)
  1502. {
  1503. uint8_t rbuf[MINION_BUFSIZ];
  1504. uint8_t data[4];
  1505. __maybe_unused int reply;
  1506. int choice;
  1507. // Complete chip reset
  1508. data[0] = 0x00;
  1509. data[1] = 0x00;
  1510. data[2] = 0xa5;
  1511. data[3] = 0xf5;
  1512. reply = build_cmd(minioncgpu, minioninfo,
  1513. chip, WRITE_ADDR(MINION_SYS_RSTN_CTL),
  1514. rbuf, 0, data);
  1515. // Default reset
  1516. data[0] = SYS_RSTN_CTL_INIT;
  1517. data[1] = 0x00;
  1518. data[2] = 0x00;
  1519. data[3] = 0x00;
  1520. reply = build_cmd(minioncgpu, minioninfo,
  1521. chip, WRITE_ADDR(MINION_SYS_RSTN_CTL),
  1522. rbuf, 0, data);
  1523. // Default initialisation
  1524. data[0] = SYS_MISC_CTL_DEFAULT;
  1525. data[1] = 0x00;
  1526. data[2] = 0x00;
  1527. data[3] = 0x00;
  1528. reply = build_cmd(minioncgpu, minioninfo,
  1529. chip, WRITE_ADDR(MINION_SYS_MISC_CTL),
  1530. rbuf, 0, data);
  1531. // Set chip frequency
  1532. choice = minioninfo->init_freq[chip];
  1533. if (choice < MINION_FREQ_MIN)
  1534. choice = MINION_FREQ_MIN;
  1535. if (choice > MINION_FREQ_MAX)
  1536. choice = MINION_FREQ_MAX;
  1537. minioninfo->init_freq[chip] = choice;
  1538. set_freq(minioncgpu, minioninfo, chip, choice);
  1539. // Set temp threshold
  1540. choice = minioninfo->init_temp[chip];
  1541. if (choice == MINION_TEMP_CTL_DISABLE)
  1542. choice = MINION_TEMP_CTL_DISABLE_VALUE;
  1543. else {
  1544. if (choice < MINION_TEMP_CTL_MIN_VALUE || choice > MINION_TEMP_CTL_MAX_VALUE)
  1545. choice = MINION_TEMP_CTL_DEF;
  1546. choice -= MINION_TEMP_CTL_MIN_VALUE;
  1547. choice /= MINION_TEMP_CTL_STEP;
  1548. choice += MINION_TEMP_CTL_MIN;
  1549. if (choice < MINION_TEMP_CTL_MIN)
  1550. choice = MINION_TEMP_CTL_MIN;
  1551. if (choice > MINION_TEMP_CTL_MAX)
  1552. choice = MINION_TEMP_CTL_MAX;
  1553. }
  1554. data[0] = (uint8_t)choice;
  1555. data[1] = 0;
  1556. data[2] = 0;
  1557. data[3] = 0;
  1558. minioninfo->chip_status[chip].tempsent = choice;
  1559. reply = build_cmd(minioncgpu, minioninfo,
  1560. chip, WRITE_ADDR(MINION_SYS_TEMP_CTL),
  1561. rbuf, 0, data);
  1562. }
  1563. static void enable_chip_cores(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip)
  1564. {
  1565. uint8_t rbuf[MINION_BUFSIZ];
  1566. uint8_t data[4];
  1567. __maybe_unused int reply;
  1568. int rep, i;
  1569. for (i = 0; i < 4; i++)
  1570. data[i] = minioninfo->init_cores[chip][i];
  1571. reply = build_cmd(minioncgpu, minioninfo,
  1572. chip, WRITE_ADDR(MINION_CORE_ENA0_31),
  1573. rbuf, 0, data);
  1574. for (i = 0; i < 4; i++)
  1575. data[i] = minioninfo->init_cores[chip][i+4];
  1576. reply = build_cmd(minioncgpu, minioninfo,
  1577. chip, WRITE_ADDR(MINION_CORE_ENA32_63),
  1578. rbuf, 0, data);
  1579. for (i = 0; i < 4; i++)
  1580. data[i] = minioninfo->init_cores[chip][i+8];
  1581. reply = build_cmd(minioncgpu, minioninfo,
  1582. chip, WRITE_ADDR(MINION_CORE_ENA64_95),
  1583. rbuf, 0, data);
  1584. for (i = 0; i < 4; i++)
  1585. data[i] = minioninfo->init_cores[chip][i+12];
  1586. reply = build_cmd(minioncgpu, minioninfo,
  1587. chip, WRITE_ADDR(MINION_CORE_ENA96_98),
  1588. rbuf, 0, data);
  1589. /* Below is for testing - disabled/use default
  1590. // 1/3 range for each of the 3 cores
  1591. // data[0] = 0x55;
  1592. // data[1] = 0x55;
  1593. // data[2] = 0x55;
  1594. // data[3] = 0x55;
  1595. // quicker replies
  1596. // data[0] = 0x05;
  1597. // data[1] = 0x05;
  1598. // data[2] = 0x05;
  1599. // data[3] = 0x05;
  1600. // 0x00000100 at 20MH/s per core = 336TH/s if 1 nonce per work item
  1601. // 0x00001000 = 21.0TH/s - so well above 2TH/s
  1602. // 0x00002000 = 10.5TH/s - above 2TH/s
  1603. // speed test
  1604. data[0] = 0x00;
  1605. data[1] = 0x01;
  1606. data[2] = 0x00;
  1607. data[3] = 0x00;
  1608. // data[3] = 0x20; // slow it down for other testing
  1609. // 2 cores
  1610. // data[0] = 0xff;
  1611. // data[1] = 0xff;
  1612. // data[2] = 0xff;
  1613. // data[3] = 0x7f;
  1614. reply = build_cmd(minioncgpu, minioninfo,
  1615. chip, WRITE_ADDR(MINION_NONCE_RANGE),
  1616. rbuf, 0, data);
  1617. // find lots more nonces in a short time on my test data
  1618. // i.e. emulate a MUCH higher hash rate on SPI and work
  1619. // generation/testing
  1620. // Current test data (same repeated 10 times) has nonce 0x05e0ed6d
  1621. data[0] = 0x00;
  1622. data[1] = 0xed;
  1623. data[2] = 0xe0;
  1624. data[3] = 0x05;
  1625. reply = build_cmd(minioncgpu, minioninfo,
  1626. chip, WRITE_ADDR(MINION_NONCE_START),
  1627. rbuf, 0, data);
  1628. */
  1629. // store the core ena state
  1630. for (rep = 0; rep < MINION_CORE_REPS; rep++) {
  1631. data[0] = 0x0;
  1632. data[1] = 0x0;
  1633. data[2] = 0x0;
  1634. data[3] = 0x0;
  1635. reply = build_cmd(minioncgpu, minioninfo,
  1636. chip, READ_ADDR(MINION_CORE_ENA0_31 + rep),
  1637. rbuf, MINION_CORE_SIZ, data);
  1638. minioninfo->chip_core_ena[rep][chip] = *((uint32_t *)&(rbuf[HSIZE()]));
  1639. }
  1640. // store the core active state
  1641. for (rep = 0; rep < MINION_CORE_REPS; rep++) {
  1642. data[0] = 0x0;
  1643. data[1] = 0x0;
  1644. data[2] = 0x0;
  1645. data[3] = 0x0;
  1646. reply = build_cmd(minioncgpu, minioninfo,
  1647. chip, READ_ADDR(MINION_CORE_ACT0_31 + rep),
  1648. rbuf, MINION_CORE_SIZ, data);
  1649. minioninfo->chip_core_act[rep][chip] = *((uint32_t *)&(rbuf[HSIZE()]));
  1650. }
  1651. }
  1652. #if ENABLE_INT_NONO
  1653. static void enable_interrupt(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int chip)
  1654. {
  1655. uint8_t rbuf[MINION_BUFSIZ];
  1656. uint8_t data[4];
  1657. __maybe_unused int reply;
  1658. data[0] = MINION_RESULT_INT_SIZE;
  1659. data[1] = 0x00;
  1660. data[2] = 0x00;
  1661. data[3] = 0x00;
  1662. reply = build_cmd(minioncgpu, minioninfo,
  1663. chip, WRITE_ADDR(MINION_SYS_BUF_TRIG),
  1664. rbuf, 0, data);
  1665. // data[0] = MINION_QUE_MAX; // spaces available ... i.e. empty
  1666. // data[0] = MINION_QUE_LOW; // spaces in use
  1667. data[0] = MINION_QUE_MAX - MINION_QUE_LOW; // spaces available
  1668. data[1] = 0x00;
  1669. data[2] = 0x00;
  1670. data[3] = 0x00;
  1671. reply = build_cmd(minioncgpu, minioninfo,
  1672. chip, WRITE_ADDR(MINION_SYS_QUE_TRIG),
  1673. rbuf, 0, data);
  1674. // data[0] = MINION_RESULT_INT;
  1675. data[0] = MINION_RESULT_INT | MINION_CMD_INT;
  1676. data[1] = 0x00;
  1677. data[2] = 0x00;
  1678. data[3] = 0x00;
  1679. reply = build_cmd(minioncgpu, minioninfo,
  1680. chip, WRITE_ADDR(MINION_SYS_INT_ENA),
  1681. rbuf, 0, data);
  1682. }
  1683. #endif
  1684. static void minion_detect_one(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int pin, int chipid)
  1685. {
  1686. struct minion_header *head;
  1687. uint8_t wbuf[MINION_BUFSIZ];
  1688. uint8_t rbuf[MINION_BUFSIZ];
  1689. uint32_t wsiz, rsiz;
  1690. int reply, tries, newchip;
  1691. uint64_t ioseq;
  1692. bool ok;
  1693. head = (struct minion_header *)wbuf;
  1694. head->chipid = chipid;
  1695. rsiz = MINION_SYS_SIZ;
  1696. SET_HEAD_READ(head, MINION_SYS_CHIP_SIG);
  1697. SET_HEAD_SIZ(head, rsiz);
  1698. wsiz = HSIZE() + rsiz;
  1699. tries = 0;
  1700. ok = false;
  1701. do {
  1702. reply = do_ioctl(pin, wbuf, wsiz, rbuf, rsiz, &ioseq);
  1703. if (reply == (int)(wsiz)) {
  1704. uint32_t sig = u8tou32(rbuf, wsiz - rsiz);
  1705. if (sig == MINION_CHIP_SIG) {
  1706. newchip = (minioninfo->chips)++;
  1707. minioninfo->has_chip[newchip] = true;
  1708. minioninfo->chipid[newchip] = chipid;
  1709. minioninfo->chip_pin[newchip] = pin;
  1710. ok = true;
  1711. } else {
  1712. if (sig == MINION_CHIP_SIG_SHIFT1 ||
  1713. sig == MINION_CHIP_SIG_SHIFT2 ||
  1714. sig == MINION_CHIP_SIG_SHIFT3 ||
  1715. sig == MINION_CHIP_SIG_SHIFT4) {
  1716. applog(LOG_WARNING, "%s: pin %d chipid %d detect offset got"
  1717. " 0x%08x wanted 0x%08x",
  1718. minioncgpu->drv->dname, pin, chipid,
  1719. sig, MINION_CHIP_SIG);
  1720. } else {
  1721. if (sig == MINION_NOCHIP_SIG ||
  1722. sig == MINION_NOCHIP_SIG2) // Assume no chip
  1723. ok = true;
  1724. else {
  1725. applog(LOG_ERR, "%s: pin %d chipid %d detect failed"
  1726. " got 0x%08x wanted 0x%08x",
  1727. minioncgpu->drv->dname, pin,
  1728. chipid, sig, MINION_CHIP_SIG);
  1729. }
  1730. }
  1731. }
  1732. } else {
  1733. applog(LOG_ERR, "%s: pin %d chipid %d reply %d ignored should be %d",
  1734. minioncgpu->drv->dname, pin, chipid, reply, (int)(wsiz));
  1735. }
  1736. } while (!ok && ++tries <= MINION_SIG_TRIES);
  1737. if (!ok) {
  1738. applog(LOG_ERR, "%s: pin %d chipid %d - detect failure status",
  1739. minioncgpu->drv->dname, pin, chipid);
  1740. }
  1741. }
  1742. // Simple detect - just check each chip for the signature
  1743. static void minion_detect_chips(struct cgpu_info *minioncgpu, struct minion_info *minioninfo)
  1744. {
  1745. int pin, chipid, chip;
  1746. int pinend, start_freq, want_freq, freqms;
  1747. #if MINION_ROCKCHIP == 1
  1748. minion_toggle_gpio(minioncgpu, MINION_POWERCYCLE_GPIO);
  1749. cgsleep_ms(100);
  1750. #endif
  1751. if (usepins) {
  1752. init_pins(minioninfo);
  1753. pinend = (int)MINION_PIN_COUNT;
  1754. } else
  1755. pinend = 1;
  1756. for (pin = 0; pin < pinend; pin++) {
  1757. for (chipid = MINION_MIN_CHIP; chipid <= MINION_MAX_CHIP; chipid++) {
  1758. minion_detect_one(minioncgpu, minioninfo, pin, chipid);
  1759. }
  1760. }
  1761. if (minioninfo->chips) {
  1762. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  1763. if (minioninfo->has_chip[chip]) {
  1764. want_freq = minioninfo->init_freq[chip];
  1765. start_freq = want_freq * opt_minion_freqpercent / 100;
  1766. start_freq -= (start_freq % MINION_FREQ_FACTOR);
  1767. if (start_freq < MINION_FREQ_MIN)
  1768. start_freq = MINION_FREQ_MIN;
  1769. minioninfo->want_freq[chip] = want_freq;
  1770. minioninfo->init_freq[chip] = start_freq;
  1771. if (start_freq != want_freq) {
  1772. freqms = opt_minion_freqchange;
  1773. freqms /= ((want_freq - start_freq) / MINION_FREQ_FACTOR);
  1774. if (freqms < 0)
  1775. freqms = -freqms;
  1776. minioninfo->freqms[chip] = freqms;
  1777. minioninfo->changing[chip] = true;
  1778. }
  1779. init_chip(minioncgpu, minioninfo, chip);
  1780. enable_chip_cores(minioncgpu, minioninfo, chip);
  1781. }
  1782. }
  1783. #if ENABLE_INT_NONO
  1784. // After everything is ready
  1785. for (chip = 0; chip < MINION_CHIPS; chip++)
  1786. if (minioninfo->has_chip[chip])
  1787. enable_interrupt(minioncgpu, minioninfo, chip);
  1788. #endif
  1789. }
  1790. }
  1791. static const char *minion_modules[] = {
  1792. #if MINION_ROCKCHIP == 0
  1793. "i2c-dev",
  1794. "i2c-bcm2708",
  1795. "spidev",
  1796. "spi-bcm2708",
  1797. #endif
  1798. NULL
  1799. };
  1800. static struct {
  1801. int request;
  1802. int value;
  1803. } minion_ioc[] = {
  1804. { SPI_IOC_RD_MODE, 0 },
  1805. { SPI_IOC_WR_MODE, 0 },
  1806. { SPI_IOC_RD_BITS_PER_WORD, 8 },
  1807. { SPI_IOC_WR_BITS_PER_WORD, 8 },
  1808. { SPI_IOC_RD_MAX_SPEED_HZ, MINION_SPI_SPEED },
  1809. { SPI_IOC_WR_MAX_SPEED_HZ, MINION_SPI_SPEED },
  1810. { -1, -1 }
  1811. };
  1812. static bool minion_init_spi(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int bus, int chip, bool reset)
  1813. {
  1814. int i, err, data;
  1815. char buf[64];
  1816. if (reset) {
  1817. // TODO: maybe slow it down?
  1818. close(minioninfo->spifd);
  1819. if (opt_minion_spisleep)
  1820. cgsleep_ms(opt_minion_spisleep);
  1821. minioninfo->spifd = open(minioncgpu->device_path, O_RDWR);
  1822. if (minioninfo->spifd < 0)
  1823. goto bad_out;
  1824. minioninfo->spi_resets++;
  1825. // minioninfo->chip_status[chip].first_nonce.tv_sec = 0L;
  1826. } else {
  1827. for (i = 0; minion_modules[i]; i++) {
  1828. snprintf(buf, sizeof(buf), "modprobe %s", minion_modules[i]);
  1829. err = system(buf);
  1830. if (err) {
  1831. applog(LOG_ERR, "%s: failed to modprobe %s (%d) - you need to be root?",
  1832. minioncgpu->drv->dname,
  1833. minion_modules[i], err);
  1834. goto bad_out;
  1835. }
  1836. }
  1837. snprintf(buf, sizeof(buf), "/dev/spidev%d.%d", bus, chip);
  1838. minioninfo->spifd = open(buf, O_RDWR);
  1839. if (minioninfo->spifd < 0) {
  1840. applog(LOG_ERR, "%s: failed to open spidev (%d)",
  1841. minioncgpu->drv->dname,
  1842. errno);
  1843. goto bad_out;
  1844. }
  1845. minioncgpu->device_path = strdup(buf);
  1846. }
  1847. for (i = 0; minion_ioc[i].value != -1; i++) {
  1848. data = minion_ioc[i].value;
  1849. err = ioctl(minioninfo->spifd, minion_ioc[i].request, (void *)&data);
  1850. if (err < 0) {
  1851. applog(LOG_ERR, "%s: failed ioctl configuration (%d) (%d)",
  1852. minioncgpu->drv->dname,
  1853. i, errno);
  1854. goto close_out;
  1855. }
  1856. }
  1857. return true;
  1858. close_out:
  1859. close(minioninfo->spifd);
  1860. minioninfo->spifd = 0;
  1861. free(minioncgpu->device_path);
  1862. minioncgpu->device_path = NULL;
  1863. bad_out:
  1864. return false;
  1865. }
  1866. static bool minion_setup_chip_select(struct cgpu_info *minioncgpu, struct minion_info *minioninfo)
  1867. {
  1868. volatile uint32_t *paddr;
  1869. uint32_t mask, value, mem;
  1870. int count, memfd, pin, bcm;
  1871. memfd = open(minion_memory, O_RDWR | O_SYNC);
  1872. if (memfd < 0) {
  1873. applog(LOG_ERR, "%s: failed open %s (%d)",
  1874. minioncgpu->drv->dname,
  1875. minion_memory, errno);
  1876. return false;
  1877. }
  1878. minioninfo->gpio = (volatile unsigned *)mmap(NULL, MINION_PAGE_SIZE,
  1879. PROT_READ | PROT_WRITE,
  1880. MAP_SHARED, memfd,
  1881. minion_memory_addr);
  1882. if (minioninfo->gpio == MAP_FAILED) {
  1883. close(memfd);
  1884. applog(LOG_ERR, "%s: failed mmap gpio (%d)",
  1885. minioncgpu->drv->dname,
  1886. errno);
  1887. return false;
  1888. }
  1889. close(memfd);
  1890. for (pin = 0; pin < (int)MINION_PIN_COUNT; pin++) {
  1891. bcm = minionPins[pin].bcm;
  1892. paddr = minioninfo->gpio + (BCM2835_GPIO_FSEL0 / 4) + (bcm / 10);
  1893. // Set each pin to be an output pin
  1894. mask = BCM2835_GPIO_FSEL_MASK << ((bcm % 10) * 3);
  1895. value = BCM2835_GPIO_FSEL_OUTPUT << ((bcm % 10) * 3);
  1896. // Read settings
  1897. mem = *paddr;
  1898. *paddr;
  1899. mem = (mem & ~mask) | (value & mask);
  1900. // Write appended setting
  1901. *paddr = mem;
  1902. *paddr = mem;
  1903. count++;
  1904. }
  1905. if (count == 0)
  1906. return false;
  1907. else
  1908. return true;
  1909. }
  1910. #if ENABLE_INT_NONO
  1911. static bool minion_init_gpio_interrupt(struct cgpu_info *minioncgpu, struct minion_info *minioninfo)
  1912. {
  1913. char pindir[64], ena[64], pin[8], dir[64], edge[64], act[64];
  1914. struct stat st;
  1915. int file, err;
  1916. ssize_t ret;
  1917. snprintf(pindir, sizeof(pindir), MINION_GPIO_SYS MINION_GPIO_PIN,
  1918. MINION_GPIO_RESULT_INT_PIN);
  1919. memset(&st, 0, sizeof(st));
  1920. if (stat(pindir, &st) == 0) { // already exists
  1921. if (!S_ISDIR(st.st_mode)) {
  1922. applog(LOG_ERR, "%s: failed1 to enable GPIO pin %d interrupt"
  1923. " - not a directory",
  1924. minioncgpu->drv->dname,
  1925. MINION_GPIO_RESULT_INT_PIN);
  1926. return false;
  1927. }
  1928. } else {
  1929. snprintf(ena, sizeof(ena), MINION_GPIO_SYS MINION_GPIO_ENA);
  1930. file = open(ena, O_WRONLY | O_SYNC);
  1931. if (file == -1) {
  1932. applog(LOG_ERR, "%s: failed2 to enable GPIO pin %d interrupt (%d)"
  1933. " - you need to be root?",
  1934. minioncgpu->drv->dname,
  1935. MINION_GPIO_RESULT_INT_PIN,
  1936. errno);
  1937. return false;
  1938. }
  1939. snprintf(pin, sizeof(pin), MINION_GPIO_ENA_VAL, MINION_GPIO_RESULT_INT_PIN);
  1940. ret = write(file, pin, (size_t)strlen(pin));
  1941. if (ret != (ssize_t)strlen(pin)) {
  1942. if (ret < 0)
  1943. err = errno;
  1944. else
  1945. err = (int)ret;
  1946. close(file);
  1947. applog(LOG_ERR, "%s: failed3 to enable GPIO pin %d interrupt (%d:%d)",
  1948. minioncgpu->drv->dname,
  1949. MINION_GPIO_RESULT_INT_PIN,
  1950. err, (int)strlen(pin));
  1951. return false;
  1952. }
  1953. close(file);
  1954. // Check again if it exists
  1955. memset(&st, 0, sizeof(st));
  1956. if (stat(pindir, &st) != 0) {
  1957. applog(LOG_ERR, "%s: failed4 to enable GPIO pin %d interrupt (%d)",
  1958. minioncgpu->drv->dname,
  1959. MINION_GPIO_RESULT_INT_PIN,
  1960. errno);
  1961. return false;
  1962. }
  1963. }
  1964. // Set the pin attributes
  1965. // Direction
  1966. snprintf(dir, sizeof(dir), MINION_GPIO_SYS MINION_GPIO_PIN MINION_GPIO_DIR,
  1967. MINION_GPIO_RESULT_INT_PIN);
  1968. file = open(dir, O_WRONLY | O_SYNC);
  1969. if (file == -1) {
  1970. applog(LOG_ERR, "%s: failed5 to enable GPIO pin %d interrupt (%d)"
  1971. " - you need to be root?",
  1972. minioncgpu->drv->dname,
  1973. MINION_GPIO_RESULT_INT_PIN,
  1974. errno);
  1975. return false;
  1976. }
  1977. ret = write(file, MINION_GPIO_DIR_READ, (size_t)strlen(MINION_GPIO_DIR_READ));
  1978. if (ret != (ssize_t)strlen(MINION_GPIO_DIR_READ)) {
  1979. if (ret < 0)
  1980. err = errno;
  1981. else
  1982. err = (int)ret;
  1983. close(file);
  1984. applog(LOG_ERR, "%s: failed6 to enable GPIO pin %d interrupt (%d:%d)",
  1985. minioncgpu->drv->dname,
  1986. MINION_GPIO_RESULT_INT_PIN,
  1987. err, (int)strlen(MINION_GPIO_DIR_READ));
  1988. return false;
  1989. }
  1990. close(file);
  1991. // Edge
  1992. snprintf(edge, sizeof(edge), MINION_GPIO_SYS MINION_GPIO_PIN MINION_GPIO_EDGE,
  1993. MINION_GPIO_RESULT_INT_PIN);
  1994. file = open(edge, O_WRONLY | O_SYNC);
  1995. if (file == -1) {
  1996. applog(LOG_ERR, "%s: failed7 to enable GPIO pin %d interrupt (%d)",
  1997. minioncgpu->drv->dname,
  1998. MINION_GPIO_RESULT_INT_PIN,
  1999. errno);
  2000. return false;
  2001. }
  2002. ret = write(file, MINION_GPIO_EDGE_RISING, (size_t)strlen(MINION_GPIO_EDGE_RISING));
  2003. if (ret != (ssize_t)strlen(MINION_GPIO_EDGE_RISING)) {
  2004. if (ret < 0)
  2005. err = errno;
  2006. else
  2007. err = (int)ret;
  2008. close(file);
  2009. applog(LOG_ERR, "%s: failed8 to enable GPIO pin %d interrupt (%d:%d)",
  2010. minioncgpu->drv->dname,
  2011. MINION_GPIO_RESULT_INT_PIN,
  2012. err, (int)strlen(MINION_GPIO_EDGE_RISING));
  2013. return false;
  2014. }
  2015. close(file);
  2016. // Active
  2017. snprintf(act, sizeof(act), MINION_GPIO_SYS MINION_GPIO_PIN MINION_GPIO_ACT,
  2018. MINION_GPIO_RESULT_INT_PIN);
  2019. file = open(act, O_WRONLY | O_SYNC);
  2020. if (file == -1) {
  2021. applog(LOG_ERR, "%s: failed9 to enable GPIO pin %d interrupt (%d)",
  2022. minioncgpu->drv->dname,
  2023. MINION_GPIO_RESULT_INT_PIN,
  2024. errno);
  2025. return false;
  2026. }
  2027. ret = write(file, MINION_GPIO_ACT_HI, (size_t)strlen(MINION_GPIO_ACT_HI));
  2028. if (ret != (ssize_t)strlen(MINION_GPIO_ACT_HI)) {
  2029. if (ret < 0)
  2030. err = errno;
  2031. else
  2032. err = (int)ret;
  2033. close(file);
  2034. applog(LOG_ERR, "%s: failed10 to enable GPIO pin %d interrupt (%d:%d)",
  2035. minioncgpu->drv->dname,
  2036. MINION_GPIO_RESULT_INT_PIN,
  2037. err, (int)strlen(MINION_GPIO_ACT_HI));
  2038. return false;
  2039. }
  2040. close(file);
  2041. // Setup fd access to Value
  2042. snprintf(minioninfo->gpiointvalue, sizeof(minioninfo->gpiointvalue),
  2043. MINION_GPIO_SYS MINION_GPIO_PIN MINION_GPIO_VALUE,
  2044. MINION_GPIO_RESULT_INT_PIN);
  2045. minioninfo->gpiointfd = open(minioninfo->gpiointvalue, O_RDONLY);
  2046. if (minioninfo->gpiointfd == -1) {
  2047. applog(LOG_ERR, "%s: failed11 to enable GPIO pin %d interrupt (%d)",
  2048. minioncgpu->drv->dname,
  2049. MINION_GPIO_RESULT_INT_PIN,
  2050. errno);
  2051. return false;
  2052. }
  2053. return true;
  2054. }
  2055. #endif
  2056. // Default meaning all cores
  2057. static void default_all_cores(uint8_t *cores)
  2058. {
  2059. int i;
  2060. // clear all bits
  2061. for (i = 0; i < (int)(DATA_SIZ * MINION_CORE_REPS); i++)
  2062. cores[i] = 0x00;
  2063. // enable (only) all cores
  2064. for (i = 0; i < MINION_CORES; i++)
  2065. ENABLE_CORE(cores, i);
  2066. }
  2067. static void minion_process_options(struct minion_info *minioninfo)
  2068. {
  2069. int last_freq, last_temp;
  2070. char *freq, *temp, *core, *comma, *buf, *plus, *minus;
  2071. uint8_t last_cores[DATA_SIZ*MINION_CORE_REPS];
  2072. int i, core1, core2;
  2073. bool cleared;
  2074. if (opt_minion_spireset && *opt_minion_spireset) {
  2075. bool is_io = true;
  2076. int val;
  2077. switch (tolower(*opt_minion_spireset)) {
  2078. case 'i':
  2079. is_io = true;
  2080. break;
  2081. case 's':
  2082. is_io = false;
  2083. break;
  2084. default:
  2085. applog(LOG_WARNING, "ERR: Invalid SPI reset '%s'",
  2086. opt_minion_spireset);
  2087. goto skip;
  2088. }
  2089. val = atoi(opt_minion_spireset+1);
  2090. if (val < 0 || val > 9999) {
  2091. applog(LOG_WARNING, "ERR: Invalid SPI reset '%s'",
  2092. opt_minion_spireset);
  2093. } else {
  2094. minioninfo->spi_reset_io = is_io;
  2095. minioninfo->spi_reset_count = val;
  2096. minioninfo->last_spi_reset = time(NULL);
  2097. }
  2098. }
  2099. skip:
  2100. last_freq = MINION_FREQ_DEF;
  2101. if (opt_minion_freq && *opt_minion_freq) {
  2102. buf = freq = strdup(opt_minion_freq);
  2103. comma = strchr(freq, ',');
  2104. if (comma)
  2105. *(comma++) = '\0';
  2106. for (i = 0; i < (int)MINION_CHIPS; i++) {
  2107. if (freq && isdigit(*freq)) {
  2108. last_freq = (int)(round((double)atoi(freq) / (double)MINION_FREQ_FACTOR)) * MINION_FREQ_FACTOR;
  2109. if (last_freq < MINION_FREQ_MIN)
  2110. last_freq = MINION_FREQ_MIN;
  2111. if (last_freq > MINION_FREQ_MAX)
  2112. last_freq = MINION_FREQ_MAX;
  2113. freq = comma;
  2114. if (comma) {
  2115. comma = strchr(freq, ',');
  2116. if (comma)
  2117. *(comma++) = '\0';
  2118. }
  2119. }
  2120. minioninfo->init_freq[i] = last_freq;
  2121. }
  2122. free(buf);
  2123. }
  2124. last_temp = MINION_TEMP_CTL_DEF;
  2125. if (opt_minion_temp && *opt_minion_temp) {
  2126. buf = temp = strdup(opt_minion_temp);
  2127. comma = strchr(temp, ',');
  2128. if (comma)
  2129. *(comma++) = '\0';
  2130. for (i = 0; i < (int)MINION_CHIPS; i++) {
  2131. if (temp) {
  2132. if (isdigit(*temp)) {
  2133. last_temp = atoi(temp);
  2134. last_temp -= (last_temp % MINION_TEMP_CTL_STEP);
  2135. if (last_temp < MINION_TEMP_CTL_MIN_VALUE)
  2136. last_temp = MINION_TEMP_CTL_MIN_VALUE;
  2137. if (last_temp > MINION_TEMP_CTL_MAX_VALUE)
  2138. last_temp = MINION_TEMP_CTL_MAX_VALUE;
  2139. } else {
  2140. if (strcasecmp(temp, MINION_TEMP_DISABLE) == 0)
  2141. last_temp = MINION_TEMP_CTL_DISABLE;
  2142. }
  2143. temp = comma;
  2144. if (comma) {
  2145. comma = strchr(temp, ',');
  2146. if (comma)
  2147. *(comma++) = '\0';
  2148. }
  2149. }
  2150. minioninfo->init_temp[i] = last_temp;
  2151. }
  2152. free(buf);
  2153. }
  2154. default_all_cores(&(last_cores[0]));
  2155. // default to all cores until we find valid data
  2156. cleared = false;
  2157. if (opt_minion_cores && *opt_minion_cores) {
  2158. buf = core = strdup(opt_minion_cores);
  2159. comma = strchr(core, ',');
  2160. if (comma)
  2161. *(comma++) = '\0';
  2162. for (i = 0; i < (int)MINION_CHIPS; i++) {
  2163. // default to previous until we find valid data
  2164. cleared = false;
  2165. if (core) {
  2166. plus = strchr(core, '+');
  2167. if (plus)
  2168. *(plus++) = '\0';
  2169. while (core) {
  2170. minus = strchr(core, '-');
  2171. if (minus)
  2172. *(minus++) = '\0';
  2173. if (isdigit(*core)) {
  2174. core1 = atoi(core);
  2175. if (core1 >= 0 && core1 < MINION_CORES) {
  2176. if (!minus) {
  2177. if (!cleared) {
  2178. memset(last_cores, 0, sizeof(last_cores));
  2179. cleared = true;
  2180. }
  2181. ENABLE_CORE(last_cores, core1);
  2182. } else {
  2183. core2 = atoi(minus);
  2184. if (core2 >= core1) {
  2185. if (core2 >= MINION_CORES)
  2186. core2 = MINION_CORES - 1;
  2187. while (core1 <= core2) {
  2188. if (!cleared) {
  2189. memset(last_cores, 0,
  2190. sizeof(last_cores));
  2191. cleared = true;
  2192. }
  2193. ENABLE_CORE(last_cores, core1);
  2194. core1++;
  2195. }
  2196. }
  2197. }
  2198. }
  2199. } else {
  2200. if (strcasecmp(core, MINION_CORE_ALL) == 0)
  2201. default_all_cores(&(last_cores[0]));
  2202. }
  2203. core = plus;
  2204. if (plus) {
  2205. plus = strchr(core, '+');
  2206. if (plus)
  2207. *(plus++) = '\0';
  2208. }
  2209. }
  2210. core = comma;
  2211. if (comma) {
  2212. comma = strchr(core, ',');
  2213. if (comma)
  2214. *(comma++) = '\0';
  2215. }
  2216. }
  2217. memcpy(&(minioninfo->init_cores[i][0]), &(last_cores[0]), sizeof(last_cores));
  2218. }
  2219. free(buf);
  2220. }
  2221. }
  2222. static void minion_detect(bool hotplug)
  2223. {
  2224. struct cgpu_info *minioncgpu = NULL;
  2225. struct minion_info *minioninfo = NULL;
  2226. char buf[512];
  2227. size_t off;
  2228. int i;
  2229. if (hotplug)
  2230. return;
  2231. define_test();
  2232. minioncgpu = calloc(1, sizeof(*minioncgpu));
  2233. if (unlikely(!minioncgpu))
  2234. quithere(1, "Failed to calloc minioncgpu");
  2235. minioncgpu->drv = &minion_drv;
  2236. minioncgpu->deven = DEV_ENABLED;
  2237. minioncgpu->threads = 1;
  2238. minioninfo = calloc(1, sizeof(*minioninfo)); // everything '0'
  2239. if (unlikely(!minioninfo))
  2240. quithere(1, "Failed to calloc minioninfo");
  2241. minioncgpu->device_data = (void *)minioninfo;
  2242. if (!minion_init_spi(minioncgpu, minioninfo, MINION_SPI_BUS, MINION_SPI_CHIP, false))
  2243. goto unalloc;
  2244. #if ENABLE_INT_NONO
  2245. if (!minion_init_gpio_interrupt(minioncgpu, minioninfo))
  2246. goto unalloc;
  2247. #endif
  2248. if (usepins) {
  2249. if (!minion_setup_chip_select(minioncgpu, minioninfo))
  2250. goto unalloc;
  2251. }
  2252. mutex_init(&(minioninfo->spi_lock));
  2253. mutex_init(&(minioninfo->sta_lock));
  2254. for (i = 0; i < (int)MINION_CHIPS; i++) {
  2255. minioninfo->init_freq[i] = MINION_FREQ_DEF;
  2256. minioninfo->init_temp[i] = MINION_TEMP_CTL_DEF;
  2257. default_all_cores(&(minioninfo->init_cores[i][0]));
  2258. }
  2259. minion_process_options(minioninfo);
  2260. applog(LOG_WARNING, "%s: checking for chips ...", minioncgpu->drv->dname);
  2261. minion_detect_chips(minioncgpu, minioninfo);
  2262. buf[0] = '\0';
  2263. for (i = 0; i < (int)MINION_CHIPS; i++) {
  2264. if (minioninfo->has_chip[i]) {
  2265. off = strlen(buf);
  2266. snprintf(buf + off, sizeof(buf) - off, " %d:%d/%d",
  2267. i, minioninfo->chip_pin[i], (int)(minioninfo->chipid[i]));
  2268. }
  2269. }
  2270. applog(LOG_WARNING, "%s: found %d chip%s:%s",
  2271. minioncgpu->drv->dname, minioninfo->chips,
  2272. (minioninfo->chips == 1) ? "" : "s", buf);
  2273. if (minioninfo->chips == 0)
  2274. goto cleanup;
  2275. if (!add_cgpu(minioncgpu))
  2276. goto cleanup;
  2277. mutex_init(&(minioninfo->nonce_lock));
  2278. minioninfo->wfree_list = k_new_list("Work", sizeof(WORK_ITEM),
  2279. ALLOC_WORK_ITEMS, LIMIT_WORK_ITEMS, true);
  2280. minioninfo->wwork_list = k_new_store(minioninfo->wfree_list);
  2281. minioninfo->wstale_list = k_new_store(minioninfo->wfree_list);
  2282. // Initialise them all in case we later decide to enable chips
  2283. for (i = 0; i < (int)MINION_CHIPS; i++) {
  2284. minioninfo->wque_list[i] = k_new_store(minioninfo->wfree_list);
  2285. minioninfo->wchip_list[i] = k_new_store(minioninfo->wfree_list);
  2286. }
  2287. minioninfo->tfree_list = k_new_list("Task", sizeof(TASK_ITEM),
  2288. ALLOC_TASK_ITEMS, LIMIT_TASK_ITEMS, true);
  2289. minioninfo->task_list = k_new_store(minioninfo->tfree_list);
  2290. minioninfo->treply_list = k_new_store(minioninfo->tfree_list);
  2291. minioninfo->rfree_list = k_new_list("Reply", sizeof(RES_ITEM),
  2292. ALLOC_RES_ITEMS, LIMIT_RES_ITEMS, true);
  2293. minioninfo->rnonce_list = k_new_store(minioninfo->rfree_list);
  2294. minioninfo->history_gen = MINION_MAX_RESET_CHECK;
  2295. minioninfo->hfree_list = k_new_list("History", sizeof(HIST_ITEM),
  2296. ALLOC_HIST_ITEMS, LIMIT_HIST_ITEMS, true);
  2297. for (i = 0; i < (int)MINION_CHIPS; i++)
  2298. minioninfo->hchip_list[i] = k_new_store(minioninfo->hfree_list);
  2299. minioninfo->pfree_list = k_new_list("Performance", sizeof(PERF_ITEM),
  2300. ALLOC_PERF_ITEMS, LIMIT_PERF_ITEMS, true);
  2301. for (i = 0; i < (int)MINION_CHIPS; i++)
  2302. minioninfo->p_list[i] = k_new_store(minioninfo->pfree_list);
  2303. minioninfo->xfree_list = k_new_list("0xff", sizeof(XFF_ITEM),
  2304. ALLOC_XFF_ITEMS, LIMIT_XFF_ITEMS, true);
  2305. minioninfo->xff_list = k_new_store(minioninfo->xfree_list);
  2306. cgsem_init(&(minioninfo->task_ready));
  2307. cgsem_init(&(minioninfo->nonce_ready));
  2308. cgsem_init(&(minioninfo->scan_work));
  2309. minioninfo->initialised = true;
  2310. dupalloc(minioncgpu, 10);
  2311. return;
  2312. cleanup:
  2313. close(minioninfo->gpiointfd);
  2314. close(minioninfo->spifd);
  2315. mutex_destroy(&(minioninfo->sta_lock));
  2316. mutex_destroy(&(minioninfo->spi_lock));
  2317. unalloc:
  2318. free(minioninfo);
  2319. free(minioncgpu);
  2320. }
  2321. static char *minion_api_set(struct cgpu_info *minioncgpu, char *option, char *setting, char *replybuf, size_t siz)
  2322. {
  2323. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  2324. int chip, val;
  2325. char *colon;
  2326. if (strcasecmp(option, "help") == 0) {
  2327. snprintf(replybuf, siz, "reset: chip 0-%d freq: 0-%d:%d-%d "
  2328. "ledcount: 0-100 ledlimit: 0-200 "
  2329. "spidelay: 0-9999 spireset i|s0-9999 "
  2330. "spisleep: 0-9999",
  2331. minioninfo->chips - 1,
  2332. minioninfo->chips - 1,
  2333. MINION_FREQ_MIN, MINION_FREQ_MAX);
  2334. return replybuf;
  2335. }
  2336. if (strcasecmp(option, "reset") == 0) {
  2337. if (!setting || !*setting) {
  2338. snprintf(replybuf, siz, "missing chip to reset");
  2339. return replybuf;
  2340. }
  2341. chip = atoi(setting);
  2342. if (chip < 0 || chip >= minioninfo->chips) {
  2343. snprintf(replybuf, siz, "invalid reset: chip '%s' valid range 0-%d",
  2344. setting,
  2345. minioninfo->chips);
  2346. return replybuf;
  2347. }
  2348. if (!minioninfo->has_chip[chip]) {
  2349. snprintf(replybuf, siz, "unable to reset chip %d - chip disabled",
  2350. chip);
  2351. return replybuf;
  2352. }
  2353. minioninfo->flag_reset[chip] = true;
  2354. return NULL;
  2355. }
  2356. // This sets up a freq step up/down to the given freq without a reset
  2357. if (strcasecmp(option, "freq") == 0) {
  2358. if (!setting || !*setting) {
  2359. snprintf(replybuf, siz, "missing chip:freq");
  2360. return replybuf;
  2361. }
  2362. colon = strchr(setting, ':');
  2363. if (!colon) {
  2364. snprintf(replybuf, siz, "missing ':' for chip:freq");
  2365. return replybuf;
  2366. }
  2367. *(colon++) = '\0';
  2368. if (!*colon) {
  2369. snprintf(replybuf, siz, "missing freq in chip:freq");
  2370. return replybuf;
  2371. }
  2372. chip = atoi(setting);
  2373. if (chip < 0 || chip >= minioninfo->chips) {
  2374. snprintf(replybuf, siz, "invalid freq: chip '%s' valid range 0-%d",
  2375. setting,
  2376. minioninfo->chips);
  2377. return replybuf;
  2378. }
  2379. if (!minioninfo->has_chip[chip]) {
  2380. snprintf(replybuf, siz, "unable to modify chip %d - chip not enabled",
  2381. chip);
  2382. return replybuf;
  2383. }
  2384. val = atoi(colon);
  2385. if (val < MINION_FREQ_MIN || val > MINION_FREQ_MAX) {
  2386. snprintf(replybuf, siz, "invalid freq: '%s' valid range %d-%d",
  2387. setting,
  2388. MINION_FREQ_MIN, MINION_FREQ_MAX);
  2389. return replybuf;
  2390. }
  2391. int want_freq = val - (val % MINION_FREQ_FACTOR);
  2392. int start_freq = minioninfo->init_freq[chip];
  2393. int freqms;
  2394. if (want_freq != start_freq) {
  2395. minioninfo->changing[chip] = false;
  2396. freqms = opt_minion_freqchange;
  2397. freqms /= ((want_freq - start_freq) / MINION_FREQ_FACTOR);
  2398. if (freqms < 0)
  2399. freqms = -freqms;
  2400. minioninfo->freqms[chip] = freqms;
  2401. minioninfo->want_freq[chip] = want_freq;
  2402. cgtime(&(minioninfo->lastfreq[chip]));
  2403. minioninfo->changing[chip] = true;
  2404. }
  2405. return NULL;
  2406. }
  2407. if (strcasecmp(option, "ledcount") == 0) {
  2408. if (!setting || !*setting) {
  2409. snprintf(replybuf, siz, "missing ledcount value");
  2410. return replybuf;
  2411. }
  2412. val = atoi(setting);
  2413. if (val < 0 || val > 100) {
  2414. snprintf(replybuf, siz, "invalid ledcount: '%s' valid range 0-100",
  2415. setting);
  2416. return replybuf;
  2417. }
  2418. opt_minion_ledcount = val;
  2419. return NULL;
  2420. }
  2421. if (strcasecmp(option, "ledlimit") == 0) {
  2422. if (!setting || !*setting) {
  2423. snprintf(replybuf, siz, "missing ledlimit value");
  2424. return replybuf;
  2425. }
  2426. val = atoi(setting);
  2427. if (val < 0 || val > 200) {
  2428. snprintf(replybuf, siz, "invalid ledlimit: GHs '%s' valid range 0-200",
  2429. setting);
  2430. return replybuf;
  2431. }
  2432. opt_minion_ledlimit = val;
  2433. return NULL;
  2434. }
  2435. if (strcasecmp(option, "spidelay") == 0) {
  2436. if (!setting || !*setting) {
  2437. snprintf(replybuf, siz, "missing spidelay value");
  2438. return replybuf;
  2439. }
  2440. val = atoi(setting);
  2441. if (val < 0 || val > 9999) {
  2442. snprintf(replybuf, siz, "invalid spidelay: ms '%s' valid range 0-9999",
  2443. setting);
  2444. return replybuf;
  2445. }
  2446. opt_minion_spidelay = val;
  2447. return NULL;
  2448. }
  2449. if (strcasecmp(option, "spireset") == 0) {
  2450. bool is_io = true;
  2451. if (!setting || !*setting) {
  2452. snprintf(replybuf, siz, "missing spireset value");
  2453. return replybuf;
  2454. }
  2455. switch (tolower(*setting)) {
  2456. case 'i':
  2457. is_io = true;
  2458. break;
  2459. case 's':
  2460. is_io = false;
  2461. break;
  2462. default:
  2463. snprintf(replybuf, siz, "invalid spireset: '%s' must start with i or s",
  2464. setting);
  2465. return replybuf;
  2466. }
  2467. val = atoi(setting+1);
  2468. if (val < 0 || val > 9999) {
  2469. snprintf(replybuf, siz, "invalid spireset: %c '%s' valid range 0-9999",
  2470. *setting, setting+1);
  2471. return replybuf;
  2472. }
  2473. minioninfo->spi_reset_io = is_io;
  2474. minioninfo->spi_reset_count = val;
  2475. minioninfo->last_spi_reset = time(NULL);
  2476. return NULL;
  2477. }
  2478. if (strcasecmp(option, "spisleep") == 0) {
  2479. if (!setting || !*setting) {
  2480. snprintf(replybuf, siz, "missing spisleep value");
  2481. return replybuf;
  2482. }
  2483. val = atoi(setting);
  2484. if (val < 0 || val > 9999) {
  2485. snprintf(replybuf, siz, "invalid spisleep: ms '%s' valid range 0-9999",
  2486. setting);
  2487. return replybuf;
  2488. }
  2489. opt_minion_spisleep = val;
  2490. return NULL;
  2491. }
  2492. if (strcasecmp(option, "spiusec") == 0) {
  2493. if (!setting || !*setting) {
  2494. snprintf(replybuf, siz, "missing spiusec value");
  2495. return replybuf;
  2496. }
  2497. val = atoi(setting);
  2498. if (val < 0 || val > 9999) {
  2499. snprintf(replybuf, siz, "invalid spiusec: '%s' valid range 0-9999",
  2500. setting);
  2501. return replybuf;
  2502. }
  2503. opt_minion_spiusec = val;
  2504. return NULL;
  2505. }
  2506. snprintf(replybuf, siz, "Unknown option: %s", option);
  2507. return replybuf;
  2508. }
  2509. static void minion_identify(__maybe_unused struct cgpu_info *minioncgpu)
  2510. {
  2511. // flash a led
  2512. }
  2513. /*
  2514. * SPI/ioctl write thread
  2515. * Non urgent work is to keep the queue full
  2516. * Urgent work is when an LP occurs (or the queue is empty/low)
  2517. */
  2518. static void *minion_spi_write(void *userdata)
  2519. {
  2520. struct cgpu_info *minioncgpu = (struct cgpu_info *)userdata;
  2521. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  2522. K_ITEM *item, *tail, *task, *work;
  2523. TASK_ITEM *titem;
  2524. applog(MINION_LOG, "%s%i: SPI writing...",
  2525. minioncgpu->drv->name, minioncgpu->device_id);
  2526. // Wait until we're ready
  2527. while (minioncgpu->shutdown == false) {
  2528. if (minioninfo->initialised) {
  2529. break;
  2530. }
  2531. cgsleep_ms(1); // asap to start mining
  2532. }
  2533. // TODO: combine all urgent into a single I/O?
  2534. // Then combine all state 1 for the same chip into a single I/O ?
  2535. // (then again for state 2?)
  2536. while (minioncgpu->shutdown == false) {
  2537. item = NULL;
  2538. K_WLOCK(minioninfo->task_list);
  2539. tail = minioninfo->task_list->tail;
  2540. if (tail) {
  2541. // Find first urgent item
  2542. item = tail;
  2543. while (item && !(DATA_TASK(item)->urgent))
  2544. item = item->prev;
  2545. // No urgent items, just do the tail
  2546. if (!item)
  2547. item = tail;
  2548. k_unlink_item(minioninfo->task_list, item);
  2549. }
  2550. K_WUNLOCK(minioninfo->task_list);
  2551. if (item) {
  2552. bool do_txrx = true;
  2553. bool store_reply = true;
  2554. struct timeval now;
  2555. double howlong;
  2556. int i;
  2557. titem = DATA_TASK(item);
  2558. switch (titem->address) {
  2559. // TODO: case MINION_SYS_TEMP_CTL:
  2560. // TODO: case MINION_SYS_FREQ_CTL:
  2561. case READ_ADDR(MINION_SYS_CHIP_STA):
  2562. case WRITE_ADDR(MINION_SYS_SPI_LED):
  2563. case WRITE_ADDR(MINION_SYS_RSTN_CTL):
  2564. case WRITE_ADDR(MINION_SYS_INT_CLR):
  2565. case READ_ADDR(MINION_SYS_IDLE_CNT):
  2566. case READ_ADDR(MINION_CORE_ENA0_31):
  2567. case READ_ADDR(MINION_CORE_ENA32_63):
  2568. case READ_ADDR(MINION_CORE_ENA64_95):
  2569. case READ_ADDR(MINION_CORE_ENA96_98):
  2570. case READ_ADDR(MINION_CORE_ACT0_31):
  2571. case READ_ADDR(MINION_CORE_ACT32_63):
  2572. case READ_ADDR(MINION_CORE_ACT64_95):
  2573. case READ_ADDR(MINION_CORE_ACT96_98):
  2574. store_reply = false;
  2575. break;
  2576. case WRITE_ADDR(MINION_QUE_0):
  2577. //applog(LOG_ERR, "%s%i: ZZZ send task_id 0x%04x - chip %d", minioncgpu->drv->name, minioncgpu->device_id, titem->task_id, titem->chip);
  2578. store_reply = false;
  2579. break;
  2580. default:
  2581. do_txrx = false;
  2582. titem->reply = MINION_UNEXPECTED_TASK;
  2583. applog(LOG_ERR, "%s%i: Unexpected task address 0x%02x (%s)",
  2584. minioncgpu->drv->name, minioncgpu->device_id,
  2585. (unsigned int)(titem->address),
  2586. addr2txt(titem->address));
  2587. break;
  2588. }
  2589. if (do_txrx) {
  2590. if (titem->witem) {
  2591. cgtime(&now);
  2592. howlong = tdiff(&now, &(DATA_WORK(titem->witem)->created));
  2593. minioninfo->wt_work++;
  2594. minioninfo->wt_time += howlong;
  2595. if (minioninfo->wt_min == 0 || minioninfo->wt_min > howlong)
  2596. minioninfo->wt_min = howlong;
  2597. else if (minioninfo->wt_max < howlong)
  2598. minioninfo->wt_max = howlong;
  2599. for (i = 0; i < TIME_BANDS; i++) {
  2600. if (howlong < time_bands[i]) {
  2601. minioninfo->wt_bands[i]++;
  2602. break;
  2603. }
  2604. }
  2605. if (i >= TIME_BANDS)
  2606. minioninfo->wt_bands[TIME_BANDS]++;
  2607. }
  2608. minion_txrx(titem);
  2609. int chip = titem->chip;
  2610. switch (titem->address) {
  2611. case READ_ADDR(MINION_SYS_CHIP_STA):
  2612. if (titem->reply >= (int)(titem->osiz)) {
  2613. uint8_t *rep = &(titem->rbuf[titem->osiz - titem->rsiz]);
  2614. mutex_lock(&(minioninfo->sta_lock));
  2615. minioninfo->chip_status[chip].temp = STA_TEMP(rep);
  2616. minioninfo->chip_status[chip].cores = STA_CORES(rep);
  2617. minioninfo->chip_status[chip].freq = STA_FREQ(rep);
  2618. mutex_unlock(&(minioninfo->sta_lock));
  2619. if (minioninfo->chip_status[chip].overheat) {
  2620. switch (STA_TEMP(rep)) {
  2621. case MINION_TEMP_40:
  2622. case MINION_TEMP_60:
  2623. case MINION_TEMP_80:
  2624. cgtime(&(minioninfo->chip_status[chip].lastrecover));
  2625. minioninfo->chip_status[chip].overheat = false;
  2626. applog(LOG_WARNING, "%s%d: chip %d cooled, restarting",
  2627. minioncgpu->drv->name,
  2628. minioncgpu->device_id,
  2629. chip);
  2630. cgtime(&(minioninfo->chip_status[chip].lastrecover));
  2631. minioninfo->chip_status[chip].overheattime +=
  2632. tdiff(&(minioninfo->chip_status[chip].lastrecover),
  2633. &(minioninfo->chip_status[chip].lastoverheat));
  2634. break;
  2635. default:
  2636. break;
  2637. }
  2638. } else {
  2639. if (opt_minion_overheat && STA_TEMP(rep) == MINION_TEMP_OVER) {
  2640. cgtime(&(minioninfo->chip_status[chip].lastoverheat));
  2641. minioninfo->chip_status[chip].overheat = true;
  2642. applog(LOG_WARNING, "%s%d: chip %d overheated! idling",
  2643. minioncgpu->drv->name,
  2644. minioncgpu->device_id,
  2645. chip);
  2646. K_WLOCK(minioninfo->tfree_list);
  2647. task = k_unlink_head(minioninfo->tfree_list);
  2648. DATA_TASK(task)->tid = ++(minioninfo->next_tid);
  2649. DATA_TASK(task)->chip = chip;
  2650. DATA_TASK(task)->write = true;
  2651. DATA_TASK(task)->address = MINION_SYS_RSTN_CTL;
  2652. DATA_TASK(task)->task_id = 0; // ignored
  2653. DATA_TASK(task)->wsiz = MINION_SYS_SIZ;
  2654. DATA_TASK(task)->rsiz = 0;
  2655. DATA_TASK(task)->wbuf[0] = SYS_RSTN_CTL_FLUSH;
  2656. DATA_TASK(task)->wbuf[1] = 0;
  2657. DATA_TASK(task)->wbuf[2] = 0;
  2658. DATA_TASK(task)->wbuf[3] = 0;
  2659. DATA_TASK(task)->urgent = true;
  2660. k_add_head(minioninfo->task_list, task);
  2661. K_WUNLOCK(minioninfo->tfree_list);
  2662. minioninfo->chip_status[chip].overheats++;
  2663. }
  2664. }
  2665. }
  2666. break;
  2667. case READ_ADDR(MINION_SYS_IDLE_CNT):
  2668. {
  2669. uint32_t *cnt = (uint32_t *)&(titem->rbuf[titem->osiz - titem->rsiz]);
  2670. minioninfo->chip_status[chip].idle = *cnt;
  2671. }
  2672. break;
  2673. case WRITE_ADDR(MINION_SYS_RSTN_CTL):
  2674. // Do this here after it has actually been flushed
  2675. if ((titem->wbuf[0] & SYS_RSTN_CTL_FLUSH) == SYS_RSTN_CTL_FLUSH) {
  2676. int cnt = 0;
  2677. K_WLOCK(minioninfo->wwork_list);
  2678. work = minioninfo->wchip_list[chip]->head;
  2679. while (work) {
  2680. cnt++;
  2681. DATA_WORK(work)->stale = true;
  2682. work = work->next;
  2683. }
  2684. minioninfo->chip_status[chip].chipwork = 0;
  2685. minioninfo->chip_status[chip].realwork = 0;
  2686. minioninfo->wchip_staled += cnt;
  2687. #if MINION_SHOW_IO
  2688. applog(IOCTRL_LOG, "RSTN chip %d (cnt=%d) cw0=%u rw0=%u qw=%u",
  2689. chip, cnt,
  2690. minioninfo->chip_status[chip].chipwork,
  2691. minioninfo->chip_status[chip].realwork,
  2692. minioninfo->chip_status[chip].quework);
  2693. #endif
  2694. K_WUNLOCK(minioninfo->wwork_list);
  2695. }
  2696. break;
  2697. case WRITE_ADDR(MINION_QUE_0):
  2698. K_WLOCK(minioninfo->wchip_list[chip]);
  2699. k_unlink_item(minioninfo->wque_list[chip], titem->witem);
  2700. k_add_head(minioninfo->wchip_list[chip], titem->witem);
  2701. DATA_WORK(titem->witem)->ioseq = titem->ioseq;
  2702. minioninfo->chip_status[chip].quework--;
  2703. minioninfo->chip_status[chip].chipwork++;
  2704. #if MINION_SHOW_IO
  2705. applog(IOCTRL_LOG, "QUE_0 chip %d cw+1=%u rw=%u qw-1=%u",
  2706. chip,
  2707. minioninfo->chip_status[chip].chipwork,
  2708. minioninfo->chip_status[chip].realwork,
  2709. minioninfo->chip_status[chip].quework);
  2710. #endif
  2711. K_WUNLOCK(minioninfo->wchip_list[chip]);
  2712. applog(LOG_DEBUG, "%s%d: task 0x%04x sent to chip %d",
  2713. minioncgpu->drv->name, minioncgpu->device_id,
  2714. titem->task_id, chip);
  2715. break;
  2716. case READ_ADDR(MINION_CORE_ENA0_31):
  2717. case READ_ADDR(MINION_CORE_ENA32_63):
  2718. case READ_ADDR(MINION_CORE_ENA64_95):
  2719. case READ_ADDR(MINION_CORE_ENA96_98):
  2720. {
  2721. uint32_t *rep = (uint32_t *)&(titem->rbuf[titem->osiz - titem->rsiz]);
  2722. int off = titem->address - READ_ADDR(MINION_CORE_ENA0_31);
  2723. minioninfo->chip_core_ena[off][chip] = *rep;
  2724. }
  2725. break;
  2726. case READ_ADDR(MINION_CORE_ACT0_31):
  2727. case READ_ADDR(MINION_CORE_ACT32_63):
  2728. case READ_ADDR(MINION_CORE_ACT64_95):
  2729. case READ_ADDR(MINION_CORE_ACT96_98):
  2730. {
  2731. uint32_t *rep = (uint32_t *)&(titem->rbuf[titem->osiz - titem->rsiz]);
  2732. int off = titem->address - READ_ADDR(MINION_CORE_ACT0_31);
  2733. minioninfo->chip_core_act[off][chip] = *rep;
  2734. }
  2735. break;
  2736. case WRITE_ADDR(MINION_SYS_INT_CLR):
  2737. case WRITE_ADDR(MINION_SYS_SPI_LED):
  2738. break;
  2739. default:
  2740. break;
  2741. }
  2742. }
  2743. K_WLOCK(minioninfo->treply_list);
  2744. if (store_reply)
  2745. k_add_head(minioninfo->treply_list, item);
  2746. else
  2747. k_free_head(minioninfo->tfree_list, item);
  2748. K_WUNLOCK(minioninfo->treply_list);
  2749. /*
  2750. * Always check for the next task immediately if we just did one
  2751. * i.e. empty the task queue
  2752. */
  2753. continue;
  2754. }
  2755. cgsem_mswait(&(minioninfo->task_ready), MINION_TASK_mS);
  2756. }
  2757. return NULL;
  2758. }
  2759. /*
  2760. * SPI/ioctl reply thread
  2761. * ioctl done every interrupt or MINION_REPLY_mS checking for results
  2762. */
  2763. static void *minion_spi_reply(void *userdata)
  2764. {
  2765. struct cgpu_info *minioncgpu = (struct cgpu_info *)userdata;
  2766. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  2767. struct minion_result *result1, *result2, *use1, *use2;
  2768. K_ITEM *item;
  2769. TASK_ITEM fifo_task, res1_task, res2_task;
  2770. int chip, resoff;
  2771. bool somelow;
  2772. struct timeval now;
  2773. #if ENABLE_INT_NONO
  2774. uint64_t ioseq;
  2775. TASK_ITEM clr_task;
  2776. struct pollfd pfd;
  2777. struct minion_header *head;
  2778. uint8_t rbuf[MINION_BUFSIZ];
  2779. uint8_t wbuf[MINION_BUFSIZ];
  2780. uint32_t wsiz, rsiz;
  2781. int ret, reply;
  2782. bool gotreplies = false;
  2783. #endif
  2784. applog(MINION_LOG, "%s%i: SPI replying...",
  2785. minioncgpu->drv->name, minioncgpu->device_id);
  2786. // Wait until we're ready
  2787. while (minioncgpu->shutdown == false) {
  2788. if (minioninfo->initialised) {
  2789. break;
  2790. }
  2791. cgsleep_ms(2);
  2792. }
  2793. fifo_task.chip = 0;
  2794. fifo_task.write = false;
  2795. fifo_task.address = MINION_SYS_FIFO_STA;
  2796. fifo_task.wsiz = 0;
  2797. fifo_task.rsiz = MINION_SYS_SIZ;
  2798. res1_task.chip = 0;
  2799. res1_task.write = false;
  2800. if (minreread)
  2801. res1_task.address = MINION_RES_PEEK;
  2802. else
  2803. res1_task.address = MINION_RES_DATA;
  2804. res1_task.wsiz = 0;
  2805. res1_task.rsiz = MINION_RES_DATA_SIZ;
  2806. res2_task.chip = 0;
  2807. res2_task.write = false;
  2808. res2_task.address = MINION_RES_DATA;
  2809. res2_task.wsiz = 0;
  2810. res2_task.rsiz = MINION_RES_DATA_SIZ;
  2811. #if ENABLE_INT_NONO
  2812. // Clear RESULT_INT after reading all results
  2813. clr_task.chip = 0;
  2814. clr_task.write = true;
  2815. clr_task.address = MINION_SYS_INT_CLR;
  2816. clr_task.wsiz = MINION_SYS_SIZ;
  2817. clr_task.rsiz = 0;
  2818. clr_task.wbuf[0] = MINION_RESULT_INT;
  2819. clr_task.wbuf[1] = 0;
  2820. clr_task.wbuf[2] = 0;
  2821. clr_task.wbuf[3] = 0;
  2822. memset(&pfd, 0, sizeof(pfd));
  2823. pfd.fd = minioninfo->gpiointfd;
  2824. pfd.events = POLLPRI;
  2825. head = (struct minion_header *)wbuf;
  2826. SET_HEAD_SIZ(head, MINION_SYS_SIZ);
  2827. wsiz = HSIZE() + MINION_SYS_SIZ;
  2828. rsiz = MINION_SYS_SIZ; // for READ, use 0 for WRITE
  2829. #endif
  2830. somelow = false;
  2831. while (minioncgpu->shutdown == false) {
  2832. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  2833. if (minioninfo->has_chip[chip]) {
  2834. int tries = 0;
  2835. uint8_t res, cmd;
  2836. if (minioninfo->changing[chip] &&
  2837. ms_tdiff(&now, &minioninfo->lastfreq[chip]) >
  2838. minioninfo->freqms[chip]) {
  2839. int want_freq = minioninfo->want_freq[chip];
  2840. int init_freq = minioninfo->init_freq[chip];
  2841. if (want_freq > init_freq) {
  2842. minioninfo->init_freq[chip] += MINION_FREQ_FACTOR;
  2843. init_freq += MINION_FREQ_FACTOR;
  2844. set_freq(minioncgpu, minioninfo, chip, init_freq);
  2845. } else if (want_freq < init_freq) {
  2846. minioninfo->init_freq[chip] -= MINION_FREQ_FACTOR;
  2847. init_freq -= MINION_FREQ_FACTOR;
  2848. set_freq(minioncgpu, minioninfo, chip, init_freq);
  2849. }
  2850. if (init_freq == want_freq)
  2851. minioninfo->changing[chip] = false;
  2852. }
  2853. while (++tries < 4) {
  2854. res = cmd = 0;
  2855. fifo_task.chip = chip;
  2856. fifo_task.reply = 0;
  2857. minion_txrx(&fifo_task);
  2858. if (fifo_task.reply <= 0) {
  2859. minioninfo->spi_errors++;
  2860. minioninfo->fifo_spi_errors[chip]++;
  2861. minioninfo->res_err_count[chip]++;
  2862. break;
  2863. } else {
  2864. if (fifo_task.reply < (int)(fifo_task.osiz)) {
  2865. char *buf = bin2hex((unsigned char *)(&(fifo_task.rbuf[fifo_task.osiz - fifo_task.rsiz])),
  2866. (int)(fifo_task.rsiz));
  2867. applog(LOG_DEBUG, "%s%i: Chip %d Bad fifo reply (%s) size %d, should be %d",
  2868. minioncgpu->drv->name, minioncgpu->device_id,
  2869. chip, buf,
  2870. fifo_task.reply, (int)(fifo_task.osiz));
  2871. free(buf);
  2872. minioninfo->spi_errors++;
  2873. minioninfo->fifo_spi_errors[chip]++;
  2874. minioninfo->res_err_count[chip]++;
  2875. } else {
  2876. if (fifo_task.reply > (int)(fifo_task.osiz)) {
  2877. applog(LOG_DEBUG, "%s%i: Chip %d Unexpected fifo reply size %d, "
  2878. "expected only %d",
  2879. minioncgpu->drv->name, minioncgpu->device_id,
  2880. chip, fifo_task.reply, (int)(fifo_task.osiz));
  2881. }
  2882. res = FIFO_RES(fifo_task.rbuf, fifo_task.osiz - fifo_task.rsiz);
  2883. cmd = FIFO_CMD(fifo_task.rbuf, fifo_task.osiz - fifo_task.rsiz);
  2884. // valid reply?
  2885. if (res <= MINION_QUE_MAX && cmd <= MINION_QUE_MAX)
  2886. break;
  2887. applog(LOG_DEBUG, "%s%i: Chip %d Bad fifo reply res %d (max is %d) "
  2888. "cmd %d (max is %d)",
  2889. minioncgpu->drv->name, minioncgpu->device_id,
  2890. chip, (int)res, MINION_QUE_MAX,
  2891. (int)cmd, MINION_QUE_MAX);
  2892. minioninfo->spi_errors++;
  2893. minioninfo->fifo_spi_errors[chip]++;
  2894. minioninfo->res_err_count[chip]++;
  2895. }
  2896. }
  2897. }
  2898. // Give up on this chip this round
  2899. if (tries >= 4)
  2900. continue;
  2901. K_WLOCK(minioninfo->wwork_list);
  2902. // have to just assume it's always correct since we can't verify it
  2903. minioninfo->chip_status[chip].realwork = (uint32_t)cmd;
  2904. #if MINION_SHOW_IO
  2905. applog(IOCTRL_LOG, "SetReal chip %d cw=%u rw==%u qw=%u",
  2906. chip,
  2907. minioninfo->chip_status[chip].chipwork,
  2908. minioninfo->chip_status[chip].realwork,
  2909. minioninfo->chip_status[chip].quework);
  2910. #endif
  2911. K_WUNLOCK(minioninfo->wwork_list);
  2912. if (cmd < MINION_QUE_LOW) {
  2913. somelow = true;
  2914. // Flag it in case the count is wrong
  2915. K_WLOCK(minioninfo->wwork_list);
  2916. minioninfo->chip_status[chip].islow = true;
  2917. minioninfo->chip_status[chip].lowcount = (int)cmd;
  2918. K_WUNLOCK(minioninfo->wwork_list);
  2919. }
  2920. /*
  2921. * Chip has results?
  2922. * You can't request results unless it says it has some.
  2923. * We don't ever directly flush the output queue while processing
  2924. * (except at startup) so the answer is always valid
  2925. * i.e. there could be more, but never less ... unless the reply was corrupt
  2926. */
  2927. if (res > MINION_MAX_RES) {
  2928. applog(LOG_ERR, "%s%i: Large work reply chip %d res %d",
  2929. minioncgpu->drv->name, minioncgpu->device_id, chip, res);
  2930. minioninfo->spi_errors++;
  2931. minioninfo->fifo_spi_errors[chip]++;
  2932. minioninfo->res_err_count[chip]++;
  2933. res = 1; // Just read one result
  2934. }
  2935. //else
  2936. //applog(LOG_ERR, "%s%i: work reply res %d", minioncgpu->drv->name, minioncgpu->device_id, res);
  2937. uint8_t left = res;
  2938. int peeks = 0;
  2939. while (left > 0) {
  2940. res = left;
  2941. if (res > MINION_MAX_RES)
  2942. res = MINION_MAX_RES;
  2943. left -= res;
  2944. repeek:
  2945. res1_task.chip = chip;
  2946. res1_task.reply = 0;
  2947. res1_task.rsiz = res * MINION_RES_DATA_SIZ;
  2948. minion_txrx(&res1_task);
  2949. if (res1_task.reply <= 0)
  2950. break;
  2951. else {
  2952. cgtime(&now);
  2953. if (res1_task.reply < (int)MINION_RES_DATA_SIZ) {
  2954. char *buf = bin2hex((unsigned char *)(&(res1_task.rbuf[res1_task.osiz - res1_task.rsiz])), (int)(res1_task.rsiz));
  2955. applog(LOG_ERR, "%s%i: Chip %d Bad work reply (%s) size %d, should be at least %d",
  2956. minioncgpu->drv->name, minioncgpu->device_id,
  2957. chip, buf,
  2958. res1_task.reply, (int)MINION_RES_DATA_SIZ);
  2959. free(buf);
  2960. minioninfo->spi_errors++;
  2961. minioninfo->res_spi_errors[chip]++;
  2962. minioninfo->res_err_count[chip]++;
  2963. } else {
  2964. if (res1_task.reply != (int)(res1_task.osiz)) {
  2965. applog(LOG_ERR, "%s%i: Chip %d Unexpected work reply size %d, expected %d",
  2966. minioncgpu->drv->name, minioncgpu->device_id,
  2967. chip, res1_task.reply, (int)(res1_task.osiz));
  2968. minioninfo->spi_errors++;
  2969. minioninfo->res_spi_errors[chip]++;
  2970. minioninfo->res_err_count[chip]++;
  2971. // Can retry a PEEK without losing data
  2972. if (minreread) {
  2973. if (++peeks < 4)
  2974. goto repeek;
  2975. break;
  2976. }
  2977. }
  2978. if (minreread) {
  2979. res2_task.chip = chip;
  2980. res2_task.reply = 0;
  2981. res2_task.rsiz = res * MINION_RES_DATA_SIZ;
  2982. minion_txrx(&res2_task);
  2983. if (res2_task.reply <= 0) {
  2984. minioninfo->spi_errors++;
  2985. minioninfo->res_spi_errors[chip]++;
  2986. minioninfo->res_err_count[chip]++;
  2987. }
  2988. }
  2989. for (resoff = res1_task.osiz - res1_task.rsiz; resoff < (int)res1_task.osiz; resoff += MINION_RES_DATA_SIZ) {
  2990. result1 = (struct minion_result *)&(res1_task.rbuf[resoff]);
  2991. if (minreread && resoff < (int)res2_task.osiz)
  2992. result2 = (struct minion_result *)&(res2_task.rbuf[resoff]);
  2993. else
  2994. result2 = NULL;
  2995. if (IS_RESULT(result1) || (minreread && result2 && IS_RESULT(result2))) {
  2996. K_WLOCK(minioninfo->rfree_list);
  2997. item = k_unlink_head(minioninfo->rfree_list);
  2998. K_WUNLOCK(minioninfo->rfree_list);
  2999. if (IS_RESULT(result1)) {
  3000. use1 = result1;
  3001. if (minreread && result2 && IS_RESULT(result2))
  3002. use2 = result2;
  3003. else
  3004. use2 = NULL;
  3005. } else {
  3006. use1 = result2;
  3007. use2 = NULL;
  3008. minioninfo->use_res2[chip]++;
  3009. }
  3010. //DATA_RES(item)->chip = RES_CHIPID(use1);
  3011. // We can avoid any SPI transmission error of the chip number
  3012. DATA_RES(item)->chip = (uint8_t)chip;
  3013. if (minioninfo->chipid[chip] != RES_CHIPID(use1)) {
  3014. minioninfo->spi_errors++;
  3015. minioninfo->res_spi_errors[chip]++;
  3016. minioninfo->res_err_count[chip]++;
  3017. }
  3018. if (use2 && minioninfo->chipid[chip] != RES_CHIPID(use2)) {
  3019. minioninfo->spi_errors++;
  3020. minioninfo->res_spi_errors[chip]++;
  3021. minioninfo->res_err_count[chip]++;
  3022. }
  3023. DATA_RES(item)->core = RES_CORE(use1);
  3024. DATA_RES(item)->task_id = RES_TASK(use1);
  3025. DATA_RES(item)->nonce = RES_NONCE(use1);
  3026. DATA_RES(item)->no_nonce = !RES_GOLD(use1);
  3027. memcpy(&(DATA_RES(item)->when), &now, sizeof(now));
  3028. applog(LOG_DEBUG, "%s%i: reply task_id 0x%04x"
  3029. " - chip %d - gold %d",
  3030. minioncgpu->drv->name,
  3031. minioncgpu->device_id,
  3032. RES_TASK(use1),
  3033. (int)RES_CHIPID(use1),
  3034. (int)RES_GOLD(use1));
  3035. if (!use2)
  3036. DATA_RES(item)->another = false;
  3037. else {
  3038. DATA_RES(item)->another = true;
  3039. DATA_RES(item)->task_id2 = RES_TASK(use2);
  3040. DATA_RES(item)->nonce2 = RES_NONCE(use2);
  3041. }
  3042. //if (RES_GOLD(use1))
  3043. //applog(MINTASK_LOG, "%s%i: found a result chip %d core %d task 0x%04x nonce 0x%08x gold=%d", minioncgpu->drv->name, minioncgpu->device_id, DATA_RES(item)->chip, DATA_RES(item)->core, DATA_RES(item)->task_id, DATA_RES(item)->nonce, (int)RES_GOLD(use1));
  3044. K_WLOCK(minioninfo->rnonce_list);
  3045. k_add_head(minioninfo->rnonce_list, item);
  3046. K_WUNLOCK(minioninfo->rnonce_list);
  3047. if (!(minioninfo->chip_status[chip].first_nonce.tv_sec)) {
  3048. cgtime(&(minioninfo->chip_status[chip].first_nonce));
  3049. minioninfo->chip_status[chip].from_first_good = 0;
  3050. }
  3051. cgsem_post(&(minioninfo->nonce_ready));
  3052. } else {
  3053. minioninfo->res_err_count[chip]++;
  3054. applog(MINTASK_LOG, "%s%i: Invalid res0 task_id 0x%04x - chip %d",
  3055. minioncgpu->drv->name, minioncgpu->device_id,
  3056. RES_TASK(result1), chip);
  3057. if (minreread && result2) {
  3058. applog(MINTASK_LOG, "%s%i: Invalid res1 task_id 0x%04x - chip %d",
  3059. minioncgpu->drv->name, minioncgpu->device_id,
  3060. RES_TASK(result2), chip);
  3061. }
  3062. }
  3063. }
  3064. }
  3065. }
  3066. }
  3067. }
  3068. }
  3069. if (somelow)
  3070. cgsem_post(&(minioninfo->scan_work));
  3071. #if ENABLE_INT_NONO
  3072. if (gotreplies)
  3073. minion_txrx(&clr_task);
  3074. #endif
  3075. #if !ENABLE_INT_NONO
  3076. cgsleep_ms(MINION_REPLY_mS);
  3077. #else
  3078. // TODO: this is going to require a bit of tuning with 2TH/s mining:
  3079. // The interrupt size MINION_RESULT_INT_SIZE should be high enough to expect
  3080. // most chips to have some results but low enough to cause negligible latency
  3081. // If all chips don't have some results when an interrupt occurs, then it is a waste
  3082. // since we have to check all chips for results anyway since we don't know which one
  3083. // caused the interrupt
  3084. // MINION_REPLY_mS needs to be low enough in the case of bad luck where no chip
  3085. // finds MINION_RESULT_INT_SIZE results in a short amount of time, so we go check
  3086. // them all anyway - to avoid high latency when there are only a few results due to low luck
  3087. ret = poll(&pfd, 1, MINION_REPLY_mS);
  3088. if (ret > 0) {
  3089. bool gotres;
  3090. int c;
  3091. minioninfo->interrupts++;
  3092. read(minioninfo->gpiointfd, &c, 1);
  3093. // applog(LOG_ERR, "%s%i: Interrupt2",
  3094. // minioncgpu->drv->name,
  3095. // minioncgpu->device_id);
  3096. gotres = false;
  3097. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  3098. if (minioninfo->has_chip[chip]) {
  3099. SET_HEAD_READ(head, MINION_SYS_INT_STA);
  3100. head->chipid = minioninfo->chipid[chip];
  3101. reply = do_ioctl(CHIP_PIN(chip), wbuf, wsiz, rbuf, rsiz, &ioseq);
  3102. if (reply != (int)wsiz) {
  3103. applog(LOG_ERR, "%s: chip %d int status returned %d"
  3104. " (should be %d)",
  3105. minioncgpu->drv->dname,
  3106. chip, reply, (int)wsiz);
  3107. }
  3108. snprintf(minioninfo->last_interrupt,
  3109. sizeof(minioninfo->last_interrupt),
  3110. "%d %d 0x%02x%02x%02x%02x%02x%02x%02x%02x %d %d 0x%02x %d %d",
  3111. (int)(minioninfo->interrupts), chip,
  3112. rbuf[0], rbuf[1], rbuf[2], rbuf[3],
  3113. rbuf[4], rbuf[5], rbuf[6], rbuf[7],
  3114. (int)wsiz, (int)rsiz, rbuf[wsiz - rsiz],
  3115. rbuf[wsiz - rsiz] & MINION_RESULT_INT,
  3116. rbuf[wsiz - rsiz] & MINION_CMD_INT);
  3117. if ((rbuf[wsiz - rsiz] & MINION_RESULT_INT) != 0) {
  3118. gotres = true;
  3119. (minioninfo->result_interrupts)++;
  3120. // applog(LOG_ERR, "%s%i: chip %d got RES interrupt",
  3121. // minioncgpu->drv->name,
  3122. // minioncgpu->device_id,
  3123. // chip);
  3124. }
  3125. if ((rbuf[wsiz - rsiz] & MINION_CMD_INT) != 0) {
  3126. // Work queue is empty
  3127. (minioninfo->command_interrupts)++;
  3128. // applog(LOG_ERR, "%s%i: chip %d got CMD interrupt",
  3129. // minioncgpu->drv->name,
  3130. // minioncgpu->device_id,
  3131. // chip);
  3132. }
  3133. // char *tmp;
  3134. // tmp = bin2hex(rbuf, wsiz);
  3135. // applog(LOG_ERR, "%s%i: chip %d interrupt: %s",
  3136. // minioncgpu->drv->name,
  3137. // minioncgpu->device_id,
  3138. // chip, tmp);
  3139. // free(tmp);
  3140. // Don't clear either interrupt until after send/recv
  3141. }
  3142. }
  3143. // Doing this last means we can't miss an interrupt
  3144. if (gotres)
  3145. cgsem_post(&(minioninfo->scan_work));
  3146. }
  3147. #endif
  3148. }
  3149. return NULL;
  3150. }
  3151. /*
  3152. * Find the matching work item for this chip
  3153. * Discard any older work items for this chip
  3154. */
  3155. enum nonce_state {
  3156. NONCE_GOOD_NONCE,
  3157. NONCE_NO_NONCE,
  3158. NONCE_DUP_NONCE,
  3159. NONCE_BAD_NONCE,
  3160. NONCE_BAD_WORK,
  3161. NONCE_NO_WORK,
  3162. NONCE_SPI_ERR
  3163. };
  3164. static void cleanup_older(struct cgpu_info *minioncgpu, int chip, K_ITEM *item, bool no_nonce)
  3165. {
  3166. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3167. K_ITEM *tail;
  3168. // bool errs;
  3169. /* remove older ioseq work items
  3170. no_nonce means this 'item' has finished also */
  3171. tail = minioninfo->wchip_list[chip]->tail;
  3172. while (tail && (DATA_WORK(tail)->ioseq < DATA_WORK(item)->ioseq)) {
  3173. k_unlink_item(minioninfo->wchip_list[chip], tail);
  3174. if (!(DATA_WORK(tail)->stale)) {
  3175. minioninfo->chip_status[chip].chipwork--;
  3176. #if MINION_SHOW_IO
  3177. applog(IOCTRL_LOG, "COld chip %d cw-1=%u rw=%u qw=%u",
  3178. chip,
  3179. minioninfo->chip_status[chip].chipwork,
  3180. minioninfo->chip_status[chip].realwork,
  3181. minioninfo->chip_status[chip].quework);
  3182. #endif
  3183. /*
  3184. // If it had no valid work (only errors) then it won't have been cleaned up
  3185. errs = (DATA_WORK(tail)->errors > 0);
  3186. applog(errs ? LOG_DEBUG : LOG_ERR,
  3187. applog(LOG_ERR,
  3188. "%s%i: discarded old task 0x%04x chip %d no reply errs=%d",
  3189. minioncgpu->drv->name, minioncgpu->device_id,
  3190. DATA_WORK(tail)->task_id, chip, DATA_WORK(tail)->errors);
  3191. */
  3192. }
  3193. applog(MINION_LOG, "%s%i: marking complete - old task 0x%04x chip %d",
  3194. minioncgpu->drv->name, minioncgpu->device_id,
  3195. DATA_WORK(tail)->task_id, chip);
  3196. if (DATA_WORK(tail)->rolled)
  3197. free_work(DATA_WORK(tail)->work);
  3198. else
  3199. work_completed(minioncgpu, DATA_WORK(tail)->work);
  3200. k_free_head(minioninfo->wfree_list, tail);
  3201. tail = minioninfo->wchip_list[chip]->tail;
  3202. }
  3203. if (no_nonce) {
  3204. if (!(DATA_WORK(item)->stale)) {
  3205. minioninfo->chip_status[chip].chipwork--;
  3206. #if MINION_SHOW_IO
  3207. applog(IOCTRL_LOG, "CONoN chip %d cw-1=%u rw=%u qw=%u",
  3208. chip,
  3209. minioninfo->chip_status[chip].chipwork,
  3210. minioninfo->chip_status[chip].realwork,
  3211. minioninfo->chip_status[chip].quework);
  3212. #endif
  3213. }
  3214. applog(MINION_LOG, "%s%i: marking complete - no_nonce task 0x%04x chip %d",
  3215. minioncgpu->drv->name, minioncgpu->device_id,
  3216. DATA_WORK(item)->task_id, chip);
  3217. if (DATA_WORK(item)->rolled)
  3218. free_work(DATA_WORK(item)->work);
  3219. else
  3220. work_completed(minioncgpu, DATA_WORK(item)->work);
  3221. }
  3222. }
  3223. // Need to put it back in the list where it was - according to ioseq
  3224. static void restorework(struct minion_info *minioninfo, int chip, K_ITEM *item)
  3225. {
  3226. K_ITEM *look;
  3227. look = minioninfo->wchip_list[chip]->tail;
  3228. while (look && DATA_WORK(look)->ioseq < DATA_WORK(item)->ioseq)
  3229. look = look->prev;
  3230. if (!look)
  3231. k_add_head(minioninfo->wchip_list[chip], item);
  3232. else
  3233. k_insert_after(minioninfo->wchip_list[chip], item, look);
  3234. }
  3235. static enum nonce_state oknonce(struct thr_info *thr, struct cgpu_info *minioncgpu, int chip, int core,
  3236. uint32_t task_id, uint32_t nonce, bool no_nonce, struct timeval *when,
  3237. bool another, uint32_t task_id2, uint32_t nonce2)
  3238. {
  3239. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3240. struct timeval now;
  3241. K_ITEM *item, *tail;
  3242. uint32_t min_task_id, max_task_id;
  3243. // uint64_t chip_good;
  3244. bool redo;
  3245. // if the chip has been disabled - but we don't do that - so not possible (yet)
  3246. if (!(minioninfo->has_chip[chip])) {
  3247. minioninfo->spi_errors++;
  3248. applog(MINTASK_LOG, "%s%i: nonce error chip %d not present",
  3249. minioncgpu->drv->name, minioncgpu->device_id, chip);
  3250. return NONCE_NO_WORK;
  3251. }
  3252. if (core < 0 || core >= MINION_CORES) {
  3253. minioninfo->spi_errors++;
  3254. minioninfo->res_spi_errors[chip]++;
  3255. minioninfo->res_err_count[chip]++;
  3256. applog(MINTASK_LOG, "%s%i: SPI nonce error invalid core %d (chip %d)",
  3257. minioncgpu->drv->name, minioncgpu->device_id, core, chip);
  3258. // use the fake core number so we don't discard the result
  3259. core = FAKE_CORE;
  3260. }
  3261. if (no_nonce)
  3262. minioninfo->chip_nononces[chip]++;
  3263. else
  3264. minioninfo->chip_nonces[chip]++;
  3265. redo = false;
  3266. retry:
  3267. K_WLOCK(minioninfo->wchip_list[chip]);
  3268. item = minioninfo->wchip_list[chip]->tail;
  3269. if (!item) {
  3270. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3271. minioninfo->spi_errors++;
  3272. minioninfo->res_spi_errors[chip]++;
  3273. minioninfo->res_err_count[chip]++;
  3274. applog(MINTASK_LOG, "%s%i: chip %d has no tasks (core %d task 0x%04x)",
  3275. minioncgpu->drv->name, minioncgpu->device_id,
  3276. chip, core, (int)task_id);
  3277. if (!no_nonce) {
  3278. minioninfo->untested_nonces++;
  3279. minioninfo->chip_err[chip]++;
  3280. }
  3281. return NONCE_NO_WORK;
  3282. }
  3283. min_task_id = DATA_WORK(item)->task_id;
  3284. while (item) {
  3285. if (DATA_WORK(item)->task_id == task_id)
  3286. break;
  3287. item = item->prev;
  3288. }
  3289. max_task_id = DATA_WORK(minioninfo->wchip_list[chip]->head)->task_id;
  3290. if (!item) {
  3291. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3292. if (another && task_id != task_id2) {
  3293. minioninfo->tasks_failed[chip]++;
  3294. task_id = task_id2;
  3295. redo = true;
  3296. goto retry;
  3297. }
  3298. minioninfo->spi_errors++;
  3299. minioninfo->res_spi_errors[chip]++;
  3300. minioninfo->res_err_count[chip]++;
  3301. applog(MINTASK_LOG, "%s%i: chip %d core %d unknown task 0x%04x "
  3302. "(min=0x%04x max=0x%04x no_nonce=%d)",
  3303. minioncgpu->drv->name, minioncgpu->device_id,
  3304. chip, core, (int)task_id, (int)min_task_id,
  3305. (int)max_task_id, no_nonce);
  3306. if (!no_nonce) {
  3307. minioninfo->untested_nonces++;
  3308. minioninfo->chip_err[chip]++;
  3309. }
  3310. return NONCE_BAD_WORK;
  3311. }
  3312. if (redo)
  3313. minioninfo->tasks_recovered[chip]++;
  3314. k_unlink_item(minioninfo->wchip_list[chip], item);
  3315. if (no_nonce) {
  3316. cleanup_older(minioncgpu, chip, item, no_nonce);
  3317. k_free_head(minioninfo->wfree_list, item);
  3318. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3319. return NONCE_NO_NONCE;
  3320. }
  3321. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3322. minioninfo->tested_nonces++;
  3323. redo = false;
  3324. retest:
  3325. if (test_nonce(DATA_WORK(item)->work, nonce)) {
  3326. /*
  3327. if (isdupnonce(minioncgpu, DATA_WORK(item)->work, nonce)) {
  3328. minioninfo->chip_dup[chip]++;
  3329. applog(LOG_WARNING, " ... nonce %02x%02x%02x%02x chip %d core %d task 0x%04x",
  3330. (nonce & 0xff), ((nonce >> 8) & 0xff),
  3331. ((nonce >> 16) & 0xff), ((nonce >> 24) & 0xff),
  3332. chip, core, task_id);
  3333. K_WLOCK(minioninfo->wchip_list[chip]);
  3334. restorework(minioninfo, chip, item);
  3335. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3336. return NONCE_DUP_NONCE;
  3337. }
  3338. */
  3339. //applog(MINTASK_LOG, "%s%i: Valid Nonce chip %d core %d task 0x%04x nonce 0x%08x", minioncgpu->drv->name, minioncgpu->device_id, chip, core, task_id, nonce);
  3340. //
  3341. submit_tested_work(thr, DATA_WORK(item)->work);
  3342. if (redo)
  3343. minioninfo->nonces_recovered[chip]++;
  3344. /* chip_good = */ ++(minioninfo->chip_good[chip]);
  3345. minioninfo->chip_status[chip].from_first_good++;
  3346. minioninfo->core_good[chip][core]++;
  3347. DATA_WORK(item)->nonces++;
  3348. mutex_lock(&(minioninfo->nonce_lock));
  3349. minioninfo->new_nonces++;
  3350. mutex_unlock(&(minioninfo->nonce_lock));
  3351. minioninfo->ok_nonces++;
  3352. K_WLOCK(minioninfo->wchip_list[chip]);
  3353. cleanup_older(minioncgpu, chip, item, no_nonce);
  3354. restorework(minioninfo, chip, item);
  3355. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3356. // add to history and remove old history and keep track of the 2 reset marks
  3357. int chip_tmp;
  3358. cgtime(&now);
  3359. K_WLOCK(minioninfo->hfree_list);
  3360. item = k_unlink_head(minioninfo->hfree_list);
  3361. memcpy(&(DATA_HIST(item)->when), when, sizeof(*when));
  3362. k_add_head(minioninfo->hchip_list[chip], item);
  3363. if (minioninfo->reset_mark[chip])
  3364. minioninfo->reset_count[chip]++;
  3365. if (second_check && minioninfo->reset2_mark[chip])
  3366. minioninfo->reset2_count[chip]++;
  3367. // N.B. this also corrects each reset_mark/reset_count within each hchip_list
  3368. for (chip_tmp = 0; chip_tmp < (int)MINION_CHIPS; chip_tmp++) {
  3369. tail = minioninfo->hchip_list[chip_tmp]->tail;
  3370. while (tail && tdiff(&(DATA_HIST(tail)->when), &now) > MINION_HISTORY_s) {
  3371. if (minioninfo->reset_mark[chip] == tail) {
  3372. minioninfo->reset_mark[chip] = tail->prev;
  3373. minioninfo->reset_count[chip]--;
  3374. }
  3375. if (second_check && minioninfo->reset2_mark[chip] == tail) {
  3376. minioninfo->reset2_mark[chip] = tail->prev;
  3377. minioninfo->reset2_count[chip]--;
  3378. }
  3379. tail = k_unlink_tail(minioninfo->hchip_list[chip_tmp]);
  3380. k_add_head(minioninfo->hfree_list, item);
  3381. tail = minioninfo->hchip_list[chip_tmp]->tail;
  3382. }
  3383. if (!(minioninfo->reset_mark[chip])) {
  3384. minioninfo->reset_mark[chip] = minioninfo->hchip_list[chip]->tail;
  3385. minioninfo->reset_count[chip] = minioninfo->hchip_list[chip]->count;
  3386. }
  3387. if (second_check && !(minioninfo->reset2_mark[chip])) {
  3388. minioninfo->reset2_mark[chip] = minioninfo->hchip_list[chip]->tail;
  3389. minioninfo->reset2_count[chip] = minioninfo->hchip_list[chip]->count;
  3390. }
  3391. tail = minioninfo->reset_mark[chip];
  3392. while (tail && tdiff(&(DATA_HIST(tail)->when), &now) > minioninfo->reset_time[chip]) {
  3393. tail = minioninfo->reset_mark[chip] = tail->prev;
  3394. minioninfo->reset_count[chip]--;
  3395. }
  3396. if (second_check) {
  3397. tail = minioninfo->reset2_mark[chip];
  3398. while (tail && tdiff(&(DATA_HIST(tail)->when), &now) > minioninfo->reset2_time[chip]) {
  3399. tail = minioninfo->reset2_mark[chip] = tail->prev;
  3400. minioninfo->reset2_count[chip]--;
  3401. }
  3402. }
  3403. }
  3404. K_WUNLOCK(minioninfo->hfree_list);
  3405. /*
  3406. // Reset the chip after 8 nonces found
  3407. if (chip_good == 8) {
  3408. memcpy(&(minioninfo->last_reset[chip]), &now, sizeof(now));
  3409. init_chip(minioncgpu, minioninfo, chip);
  3410. }
  3411. */
  3412. return NONCE_GOOD_NONCE;
  3413. }
  3414. if (another && nonce != nonce2) {
  3415. minioninfo->nonces_failed[chip]++;
  3416. nonce = nonce2;
  3417. redo = true;
  3418. goto retest;
  3419. }
  3420. DATA_WORK(item)->errors++;
  3421. K_WLOCK(minioninfo->wchip_list[chip]);
  3422. restorework(minioninfo, chip, item);
  3423. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3424. minioninfo->chip_bad[chip]++;
  3425. minioninfo->core_bad[chip][core]++;
  3426. inc_hw_errors(thr);
  3427. //applog(MINTASK_LOG, "%s%i: HW ERROR chip %d core %d task 0x%04x nonce 0x%08x", minioncgpu->drv->name, minioncgpu->device_id, chip, core, task_id, nonce);
  3428. return NONCE_BAD_NONCE;
  3429. }
  3430. /* Check each chip how long since the last nonce
  3431. * Should normally be a fraction of a second
  3432. * so (MINION_RESET_s * 1.5) will certainly be long enough,
  3433. * but also will avoid lots of resets if there is trouble getting work
  3434. * Should be longer than MINION_RESET_s to avoid interfering with normal resets */
  3435. static void check_last_nonce(struct cgpu_info *minioncgpu)
  3436. {
  3437. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3438. struct timeval now;
  3439. K_ITEM *head;
  3440. double howlong;
  3441. int chip;
  3442. cgtime(&now);
  3443. K_RLOCK(minioninfo->hfree_list);
  3444. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  3445. if (minioninfo->has_chip[chip] && !(minioninfo->changing[chip])) {
  3446. head = minioninfo->hchip_list[chip]->head;
  3447. if (head) {
  3448. howlong = tdiff(&now, &(DATA_HIST(head)->when));
  3449. if (howlong > ((double)MINION_RESET_s * 1.5)) {
  3450. // Setup a reset
  3451. minioninfo->flag_reset[chip] = true;
  3452. minioninfo->do_reset[chip] = 0.0;
  3453. }
  3454. }
  3455. }
  3456. }
  3457. K_RUNLOCK(minioninfo->hfree_list);
  3458. }
  3459. // Results checking thread
  3460. static void *minion_results(void *userdata)
  3461. {
  3462. struct cgpu_info *minioncgpu = (struct cgpu_info *)userdata;
  3463. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3464. struct thr_info *thr;
  3465. int chip = 0, core = 0;
  3466. uint32_t task_id = 0;
  3467. uint32_t nonce = 0;
  3468. bool no_nonce = false;
  3469. struct timeval when;
  3470. bool another;
  3471. uint32_t task_id2 = 0;
  3472. uint32_t nonce2 = 0;
  3473. int last_check;
  3474. applog(MINION_LOG, "%s%i: Results...",
  3475. minioncgpu->drv->name, minioncgpu->device_id);
  3476. // Wait until we're ready
  3477. while (minioncgpu->shutdown == false) {
  3478. if (minioninfo->initialised) {
  3479. break;
  3480. }
  3481. cgsleep_ms(3);
  3482. }
  3483. thr = minioninfo->thr;
  3484. last_check = 0;
  3485. while (minioncgpu->shutdown == false) {
  3486. if (!oldest_nonce(minioncgpu, &chip, &core, &task_id, &nonce,
  3487. &no_nonce, &when, &another, &task_id2, &nonce2)) {
  3488. check_last_nonce(minioncgpu);
  3489. last_check = 0;
  3490. cgsem_mswait(&(minioninfo->nonce_ready), MINION_NONCE_mS);
  3491. continue;
  3492. }
  3493. oknonce(thr, minioncgpu, chip, core, task_id, nonce, no_nonce, &when,
  3494. another, task_id2, nonce2);
  3495. // Interrupt nonce checking if low CPU and oldest_nonce() is always true
  3496. if (++last_check > 100) {
  3497. check_last_nonce(minioncgpu);
  3498. last_check = 0;
  3499. }
  3500. }
  3501. return NULL;
  3502. }
  3503. static void minion_flush_work(struct cgpu_info *minioncgpu)
  3504. {
  3505. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3506. K_ITEM *prev_unused, *task, *prev_task, *witem;
  3507. int i;
  3508. if (minioninfo->initialised == false)
  3509. return;
  3510. applog(MINION_LOG, "%s%i: flushing work",
  3511. minioncgpu->drv->name, minioncgpu->device_id);
  3512. // TODO: N.B. scanwork also gets work locks - which master thread calls flush?
  3513. K_WLOCK(minioninfo->wwork_list);
  3514. // Simply remove the whole unused wwork_list
  3515. k_list_transfer_to_head(minioninfo->wwork_list, minioninfo->wstale_list);
  3516. minioninfo->wwork_flushed += minioninfo->wstale_list->count;
  3517. // TODO: flush/work tasks should have a block sequence number so this task removal code
  3518. // might be better implemented in minion_spi_write where each work task would
  3519. // update the block sequence number and any work tasks with an old block sequence
  3520. // number would be discarded rather than sent - minion_spi_write will also need to
  3521. // prioritise flush urgent tasks above work urgent tasks - have 3 urgent states?
  3522. // They should however be 2 seperate variables in minioninfo to reduce locking
  3523. // - flush will increment one and put it in the flush task, (and work will use that)
  3524. // minion_spi_write will check/update the other and thus not need a lock
  3525. // No deadlock since this is the only code to get 2 locks
  3526. K_WLOCK(minioninfo->tfree_list);
  3527. task = minioninfo->task_list->tail;
  3528. while (task) {
  3529. prev_task = task->prev;
  3530. if (DATA_TASK(task)->address == WRITE_ADDR(MINION_QUE_0)) {
  3531. minioninfo->chip_status[DATA_TASK(task)->chip].quework--;
  3532. #if MINION_SHOW_IO
  3533. applog(IOCTRL_LOG, "QueFlush chip %d cw=%u rw=%u qw-1=%u",
  3534. (int)DATA_TASK(task)->chip,
  3535. minioninfo->chip_status[DATA_TASK(task)->chip].chipwork,
  3536. minioninfo->chip_status[DATA_TASK(task)->chip].realwork,
  3537. minioninfo->chip_status[DATA_TASK(task)->chip].quework);
  3538. #endif
  3539. witem = DATA_TASK(task)->witem;
  3540. k_unlink_item(minioninfo->wque_list[DATA_TASK(task)->chip], witem);
  3541. minioninfo->wque_flushed++;
  3542. if (DATA_WORK(witem)->rolled)
  3543. free_work(DATA_WORK(witem)->work);
  3544. else
  3545. work_completed(minioncgpu, DATA_WORK(witem)->work);
  3546. k_free_head(minioninfo->wfree_list, witem);
  3547. k_unlink_item(minioninfo->task_list, task);
  3548. k_free_head(minioninfo->tfree_list, task);
  3549. }
  3550. task = prev_task;
  3551. }
  3552. for (i = 0; i < (int)MINION_CHIPS; i++) {
  3553. if (minioninfo->has_chip[i]) {
  3554. // TODO: consider sending it now rather than adding to the task list?
  3555. task = k_unlink_head(minioninfo->tfree_list);
  3556. DATA_TASK(task)->tid = ++(minioninfo->next_tid);
  3557. DATA_TASK(task)->chip = i;
  3558. DATA_TASK(task)->write = true;
  3559. DATA_TASK(task)->address = MINION_SYS_RSTN_CTL;
  3560. DATA_TASK(task)->task_id = 0; // ignored
  3561. DATA_TASK(task)->wsiz = MINION_SYS_SIZ;
  3562. DATA_TASK(task)->rsiz = 0;
  3563. DATA_TASK(task)->wbuf[0] = SYS_RSTN_CTL_FLUSH;
  3564. DATA_TASK(task)->wbuf[1] = 0;
  3565. DATA_TASK(task)->wbuf[2] = 0;
  3566. DATA_TASK(task)->wbuf[3] = 0;
  3567. DATA_TASK(task)->urgent = true;
  3568. k_add_head(minioninfo->task_list, task);
  3569. }
  3570. }
  3571. K_WUNLOCK(minioninfo->tfree_list);
  3572. K_WUNLOCK(minioninfo->wwork_list);
  3573. // TODO: send a signal to force getting and sending new work - needs cgsem_wait in the sending thread
  3574. // TODO: should we use this thread to do the following work?
  3575. if (minioninfo->wstale_list->count) {
  3576. // mark complete all stale unused work (oldest first)
  3577. prev_unused = minioninfo->wstale_list->tail;
  3578. while (prev_unused) {
  3579. if (DATA_WORK(prev_unused)->rolled)
  3580. free_work(DATA_WORK(prev_unused)->work);
  3581. else
  3582. work_completed(minioncgpu, DATA_WORK(prev_unused)->work);
  3583. prev_unused = prev_unused->prev;
  3584. }
  3585. // put them back in the wfree_list
  3586. K_WLOCK(minioninfo->wfree_list);
  3587. k_list_transfer_to_head(minioninfo->wstale_list, minioninfo->wfree_list);
  3588. K_WUNLOCK(minioninfo->wfree_list);
  3589. }
  3590. }
  3591. static void sys_chip_sta(struct cgpu_info *minioncgpu, int chip)
  3592. {
  3593. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3594. struct timeval now;
  3595. K_ITEM *item;
  3596. int limit, rep;
  3597. cgtime(&now);
  3598. // No lock required since 'last' is only accessed here
  3599. if (minioninfo->chip_status[chip].last.tv_sec == 0) {
  3600. memcpy(&(minioninfo->chip_status[chip].last), &now, sizeof(now));
  3601. } else {
  3602. limit = MINION_STATS_UPDATE_TIME_mS +
  3603. (int)(random() % MINION_STATS_UPDATE_RAND_mS);
  3604. if (ms_tdiff(&now, &(minioninfo->chip_status[chip].last)) > limit) {
  3605. memcpy(&(minioninfo->chip_status[chip].last), &now, sizeof(now));
  3606. K_WLOCK(minioninfo->tfree_list);
  3607. item = k_unlink_head(minioninfo->tfree_list);
  3608. DATA_TASK(item)->tid = ++(minioninfo->next_tid);
  3609. K_WUNLOCK(minioninfo->tfree_list);
  3610. DATA_TASK(item)->chip = chip;
  3611. DATA_TASK(item)->write = false;
  3612. DATA_TASK(item)->address = READ_ADDR(MINION_SYS_CHIP_STA);
  3613. DATA_TASK(item)->task_id = 0;
  3614. DATA_TASK(item)->wsiz = 0;
  3615. DATA_TASK(item)->rsiz = MINION_SYS_SIZ;
  3616. DATA_TASK(item)->urgent = false;
  3617. K_WLOCK(minioninfo->task_list);
  3618. k_add_head(minioninfo->task_list, item);
  3619. item = k_unlink_head(minioninfo->tfree_list);
  3620. DATA_TASK(item)->tid = ++(minioninfo->next_tid);
  3621. K_WUNLOCK(minioninfo->task_list);
  3622. DATA_TASK(item)->chip = chip;
  3623. DATA_TASK(item)->write = false;
  3624. DATA_TASK(item)->address = READ_ADDR(MINION_SYS_IDLE_CNT);
  3625. DATA_TASK(item)->task_id = 0;
  3626. DATA_TASK(item)->wsiz = 0;
  3627. DATA_TASK(item)->rsiz = MINION_SYS_SIZ;
  3628. DATA_TASK(item)->urgent = false;
  3629. K_WLOCK(minioninfo->task_list);
  3630. k_add_head(minioninfo->task_list, item);
  3631. K_WUNLOCK(minioninfo->task_list);
  3632. // Get the core ena and act state
  3633. for (rep = 0; rep < MINION_CORE_REPS; rep++) {
  3634. // Ena
  3635. K_WLOCK(minioninfo->tfree_list);
  3636. item = k_unlink_head(minioninfo->tfree_list);
  3637. DATA_TASK(item)->tid = ++(minioninfo->next_tid);
  3638. K_WUNLOCK(minioninfo->tfree_list);
  3639. DATA_TASK(item)->chip = chip;
  3640. DATA_TASK(item)->write = false;
  3641. DATA_TASK(item)->address = READ_ADDR(MINION_CORE_ENA0_31 + rep);
  3642. DATA_TASK(item)->task_id = 0;
  3643. DATA_TASK(item)->wsiz = 0;
  3644. DATA_TASK(item)->rsiz = MINION_SYS_SIZ;
  3645. DATA_TASK(item)->urgent = false;
  3646. K_WLOCK(minioninfo->task_list);
  3647. k_add_head(minioninfo->task_list, item);
  3648. // Act
  3649. item = k_unlink_head(minioninfo->tfree_list);
  3650. DATA_TASK(item)->tid = ++(minioninfo->next_tid);
  3651. K_WUNLOCK(minioninfo->task_list);
  3652. DATA_TASK(item)->chip = chip;
  3653. DATA_TASK(item)->write = false;
  3654. DATA_TASK(item)->address = READ_ADDR(MINION_CORE_ACT0_31 + rep);
  3655. DATA_TASK(item)->task_id = 0;
  3656. DATA_TASK(item)->wsiz = 0;
  3657. DATA_TASK(item)->rsiz = MINION_SYS_SIZ;
  3658. DATA_TASK(item)->urgent = false;
  3659. K_WLOCK(minioninfo->task_list);
  3660. k_add_head(minioninfo->task_list, item);
  3661. K_WUNLOCK(minioninfo->task_list);
  3662. }
  3663. if (minioninfo->lednow[chip] != minioninfo->setled[chip]) {
  3664. uint32_t led;
  3665. minioninfo->lednow[chip] = minioninfo->setled[chip];
  3666. if (minioninfo->lednow[chip])
  3667. led = MINION_SPI_LED_ON;
  3668. else
  3669. led = MINION_SPI_LED_OFF;
  3670. K_WLOCK(minioninfo->tfree_list);
  3671. item = k_unlink_head(minioninfo->tfree_list);
  3672. DATA_TASK(item)->tid = ++(minioninfo->next_tid);
  3673. K_WUNLOCK(minioninfo->tfree_list);
  3674. DATA_TASK(item)->chip = chip;
  3675. DATA_TASK(item)->write = true;
  3676. DATA_TASK(item)->address = MINION_SYS_SPI_LED;
  3677. DATA_TASK(item)->task_id = 0;
  3678. DATA_TASK(item)->wsiz = MINION_SYS_SIZ;
  3679. DATA_TASK(item)->rsiz = 0;
  3680. DATA_TASK(item)->wbuf[0] = led & 0xff;
  3681. DATA_TASK(item)->wbuf[1] = (led >> 8) & 0xff;
  3682. DATA_TASK(item)->wbuf[2] = (led >> 16) & 0xff;
  3683. DATA_TASK(item)->wbuf[3] = (led >> 24) & 0xff;
  3684. DATA_TASK(item)->urgent = false;
  3685. K_WLOCK(minioninfo->task_list);
  3686. k_add_head(minioninfo->task_list, item);
  3687. K_WUNLOCK(minioninfo->task_list);
  3688. }
  3689. }
  3690. }
  3691. }
  3692. static void new_work_task(struct cgpu_info *minioncgpu, K_ITEM *witem, int chip, bool urgent, uint8_t state)
  3693. {
  3694. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3695. struct minion_que *que;
  3696. K_ITEM *item;
  3697. K_WLOCK(minioninfo->tfree_list);
  3698. item = k_unlink_head(minioninfo->tfree_list);
  3699. DATA_TASK(item)->tid = ++(minioninfo->next_tid);
  3700. K_WUNLOCK(minioninfo->tfree_list);
  3701. DATA_TASK(item)->chip = chip;
  3702. DATA_TASK(item)->write = true;
  3703. DATA_TASK(item)->address = MINION_QUE_0;
  3704. // if threaded access to new_work_task() is added, this will need locking
  3705. // Don't use task_id 0 so that we can ignore all '0' work replies
  3706. // ... and report them as errors
  3707. if (minioninfo->next_task_id == 0)
  3708. minioninfo->next_task_id = 1;
  3709. DATA_TASK(item)->task_id = minioninfo->next_task_id;
  3710. DATA_WORK(witem)->task_id = minioninfo->next_task_id;
  3711. minioninfo->next_task_id = (minioninfo->next_task_id + 1) & MINION_MAX_TASK_ID;
  3712. DATA_TASK(item)->urgent = urgent;
  3713. DATA_TASK(item)->work_state = state;
  3714. DATA_TASK(item)->work = DATA_WORK(witem)->work;
  3715. DATA_TASK(item)->witem = witem;
  3716. que = (struct minion_que *)&(DATA_TASK(item)->wbuf[0]);
  3717. que->task_id[0] = DATA_TASK(item)->task_id & 0xff;
  3718. que->task_id[1] = (DATA_TASK(item)->task_id & 0xff00) >> 8;
  3719. memcpy(&(que->midstate[0]), &(DATA_WORK(witem)->work->midstate[0]), MIDSTATE_BYTES);
  3720. memcpy(&(que->merkle7[0]), &(DATA_WORK(witem)->work->data[MERKLE7_OFFSET]), MERKLE_BYTES);
  3721. DATA_TASK(item)->wsiz = (int)sizeof(*que);
  3722. DATA_TASK(item)->rsiz = 0;
  3723. K_WLOCK(minioninfo->wque_list[chip]);
  3724. k_add_head(minioninfo->wque_list[chip], witem);
  3725. minioninfo->chip_status[chip].quework++;
  3726. #if MINION_SHOW_IO
  3727. applog(IOCTRL_LOG, "Que chip %d cw=%u rw=%u qw+1=%u",
  3728. chip,
  3729. minioninfo->chip_status[chip].chipwork,
  3730. minioninfo->chip_status[chip].realwork,
  3731. minioninfo->chip_status[chip].quework);
  3732. #endif
  3733. K_WUNLOCK(minioninfo->wque_list[chip]);
  3734. K_WLOCK(minioninfo->task_list);
  3735. k_add_head(minioninfo->task_list, item);
  3736. K_WUNLOCK(minioninfo->task_list);
  3737. if (urgent)
  3738. cgsem_post(&(minioninfo->task_ready));
  3739. // N.B. this will only update often enough if a chip is > ~2GH/s
  3740. if (!urgent)
  3741. sys_chip_sta(minioncgpu, chip);
  3742. }
  3743. // TODO: stale work ...
  3744. static K_ITEM *next_work(struct minion_info *minioninfo)
  3745. {
  3746. K_ITEM *item;
  3747. struct timeval now;
  3748. double howlong;
  3749. int i;
  3750. K_WLOCK(minioninfo->wwork_list);
  3751. item = k_unlink_tail(minioninfo->wwork_list);
  3752. K_WUNLOCK(minioninfo->wwork_list);
  3753. if (item) {
  3754. cgtime(&now);
  3755. howlong = tdiff(&now, &(DATA_WORK(item)->created));
  3756. minioninfo->que_work++;
  3757. minioninfo->que_time += howlong;
  3758. if (minioninfo->que_min == 0 || minioninfo->que_min > howlong)
  3759. minioninfo->que_min = howlong;
  3760. else if (minioninfo->que_max < howlong)
  3761. minioninfo->que_max = howlong;
  3762. for (i = 0; i < TIME_BANDS; i++) {
  3763. if (howlong < time_bands[i]) {
  3764. minioninfo->que_bands[i]++;
  3765. break;
  3766. }
  3767. }
  3768. if (i >= TIME_BANDS)
  3769. minioninfo->que_bands[TIME_BANDS]++;
  3770. }
  3771. return item;
  3772. }
  3773. static void minion_do_work(struct cgpu_info *minioncgpu)
  3774. {
  3775. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3776. int count, chip, j, lowcount;
  3777. TASK_ITEM fifo_task;
  3778. uint8_t state, cmd;
  3779. K_ITEM *item;
  3780. #if ENABLE_INT_NONO
  3781. K_ITEM *task;
  3782. #endif
  3783. bool islow, sentwork;
  3784. fifo_task.chip = 0;
  3785. fifo_task.write = false;
  3786. fifo_task.address = MINION_SYS_FIFO_STA;
  3787. fifo_task.wsiz = 0;
  3788. fifo_task.rsiz = MINION_SYS_SIZ;
  3789. // TODO: (remove this) Fake starved of work to test CMD Interrupt
  3790. // if (total_secs > 120) {
  3791. // cgsleep_ms(888);
  3792. // return;
  3793. // }
  3794. /*
  3795. * Fill the queues as follows:
  3796. * 1) put at least 1 in each queue or if islow then add 1
  3797. * 2) push each queue up to LOW or if count is high but islow, then add LOW-1
  3798. * 3) push each LOW queue up to HIGH
  3799. */
  3800. sentwork = false;
  3801. for (state = 0; state < 3; state++) {
  3802. #define CHP 0
  3803. //applog(LOG_ERR, "%s%i: chip %d presta %d: quew %d chw %d", minioncgpu->drv->name, minioncgpu->device_id, CHP, state, minioninfo->chip_status[CHP].quework, minioninfo->chip_status[CHP].chipwork);
  3804. for (chip = 0; chip < (int)MINION_CHIPS; chip++)
  3805. minioninfo->chip_status[chip].tohigh = false;
  3806. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  3807. if (minioninfo->has_chip[chip] && !minioninfo->chip_status[chip].overheat) {
  3808. struct timeval now;
  3809. double howlong;
  3810. cgtime(&now);
  3811. howlong = tdiff(&now, &(minioninfo->last_reset[chip]));
  3812. if (howlong < MINION_RESET_DELAY_s)
  3813. continue;
  3814. int tries = 0;
  3815. while (tries++ < 4) {
  3816. cmd = 0;
  3817. fifo_task.chip = chip;
  3818. fifo_task.reply = 0;
  3819. minion_txrx(&fifo_task);
  3820. if (fifo_task.reply <= 0) {
  3821. if (fifo_task.reply < (int)(fifo_task.osiz)) {
  3822. char *buf = bin2hex((unsigned char *)(&(fifo_task.rbuf[fifo_task.osiz - fifo_task.rsiz])),
  3823. (int)(fifo_task.rsiz));
  3824. applog(LOG_ERR, "%s%i: Chip %d Bad fifo reply (%s) size %d, should be %d",
  3825. minioncgpu->drv->name, minioncgpu->device_id,
  3826. chip, buf,
  3827. fifo_task.reply, (int)(fifo_task.osiz));
  3828. free(buf);
  3829. minioninfo->spi_errors++;
  3830. minioninfo->fifo_spi_errors[chip]++;
  3831. minioninfo->res_err_count[chip]++;
  3832. } else {
  3833. if (fifo_task.reply > (int)(fifo_task.osiz)) {
  3834. applog(LOG_ERR, "%s%i: Chip %d Unexpected fifo reply size %d, expected only %d",
  3835. minioncgpu->drv->name, minioncgpu->device_id,
  3836. chip, fifo_task.reply, (int)(fifo_task.osiz));
  3837. }
  3838. cmd = FIFO_CMD(fifo_task.rbuf, fifo_task.osiz - fifo_task.rsiz);
  3839. // valid reply?
  3840. if (cmd < MINION_QUE_MAX) {
  3841. K_WLOCK(minioninfo->wchip_list[chip]);
  3842. minioninfo->chip_status[chip].realwork = cmd;
  3843. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3844. if (cmd <= MINION_QUE_LOW || cmd >= MINION_QUE_HIGH) {
  3845. applog(LOG_DEBUG, "%s%i: Chip %d fifo cmd %d",
  3846. minioncgpu->drv->name,
  3847. minioncgpu->device_id,
  3848. chip, (int)cmd);
  3849. }
  3850. break;
  3851. }
  3852. applog(LOG_ERR, "%s%i: Chip %d Bad fifo reply cmd %d (max is %d)",
  3853. minioncgpu->drv->name, minioncgpu->device_id,
  3854. chip, (int)cmd, MINION_QUE_MAX);
  3855. minioninfo->spi_errors++;
  3856. minioninfo->fifo_spi_errors[chip]++;
  3857. minioninfo->res_err_count[chip]++;
  3858. }
  3859. }
  3860. }
  3861. K_WLOCK(minioninfo->wchip_list[chip]);
  3862. count = minioninfo->chip_status[chip].quework +
  3863. minioninfo->chip_status[chip].realwork;
  3864. islow = minioninfo->chip_status[chip].islow;
  3865. minioninfo->chip_status[chip].islow = false;
  3866. lowcount = minioninfo->chip_status[chip].lowcount;
  3867. K_WUNLOCK(minioninfo->wchip_list[chip]);
  3868. switch (state) {
  3869. case 0:
  3870. if (count == 0 || islow) {
  3871. item = next_work(minioninfo);
  3872. if (item) {
  3873. new_work_task(minioncgpu, item, chip, true, state);
  3874. sentwork = true;
  3875. applog(MINION_LOG, "%s%i: 0 task 0x%04x in chip %d list",
  3876. minioncgpu->drv->name,
  3877. minioncgpu->device_id,
  3878. DATA_WORK(item)->task_id, chip);
  3879. } else {
  3880. applog(LOG_ERR, "%s%i: chip %d urgent empty work list",
  3881. minioncgpu->drv->name,
  3882. minioncgpu->device_id,
  3883. chip);
  3884. }
  3885. }
  3886. break;
  3887. case 1:
  3888. if (count < MINION_QUE_LOW || islow) {
  3889. // do case 2: after we've done other chips
  3890. minioninfo->chip_status[chip].tohigh = true;
  3891. j = count;
  3892. if (count >= MINION_QUE_LOW) {
  3893. // islow means run a full case 1
  3894. j = 1;
  3895. applog(LOG_ERR, "%s%i: chip %d low que (%d) with high count %d",
  3896. minioncgpu->drv->name,
  3897. minioncgpu->device_id,
  3898. chip, lowcount, count);
  3899. }
  3900. for (; j < MINION_QUE_LOW; j++) {
  3901. item = next_work(minioninfo);
  3902. if (item) {
  3903. new_work_task(minioncgpu, item, chip, false, state);
  3904. sentwork = true;
  3905. applog(MINION_LOG, "%s%i: 1 task 0x%04x in chip %d list",
  3906. minioncgpu->drv->name,
  3907. minioncgpu->device_id,
  3908. DATA_WORK(item)->task_id, chip);
  3909. } else {
  3910. applog(LOG_ERR, "%s%i: chip %d non-urgent lo "
  3911. "empty work list (count=%d)",
  3912. minioncgpu->drv->name,
  3913. minioncgpu->device_id,
  3914. chip, j);
  3915. }
  3916. }
  3917. }
  3918. break;
  3919. case 2:
  3920. if (count <= MINION_QUE_LOW || minioninfo->chip_status[chip].tohigh) {
  3921. for (j = count; j < MINION_QUE_HIGH; j++) {
  3922. item = next_work(minioninfo);
  3923. if (item) {
  3924. new_work_task(minioncgpu, item, chip, false, state);
  3925. sentwork = true;
  3926. applog(MINION_LOG, "%s%i: 2 task 0x%04x in chip %d list",
  3927. minioncgpu->drv->name,
  3928. minioncgpu->device_id,
  3929. DATA_WORK(item)->task_id, chip);
  3930. } else {
  3931. applog(LOG_DEBUG, "%s%i: chip %d non-urgent hi "
  3932. "empty work list (count=%d)",
  3933. minioncgpu->drv->name,
  3934. minioncgpu->device_id,
  3935. chip, j);
  3936. }
  3937. }
  3938. }
  3939. break;
  3940. }
  3941. } else
  3942. if (minioninfo->has_chip[chip] && minioninfo->chip_status[chip].overheat && state == 2)
  3943. sys_chip_sta(minioncgpu, chip);
  3944. }
  3945. }
  3946. sentwork = sentwork;
  3947. #if ENABLE_INT_NONO
  3948. if (sentwork) {
  3949. // Clear CMD interrupt since we've now sent more
  3950. K_WLOCK(minioninfo->tfree_list);
  3951. task = k_unlink_head(minioninfo->tfree_list);
  3952. DATA_TASK(task)->tid = ++(minioninfo->next_tid);
  3953. DATA_TASK(task)->chip = 0; // ignored
  3954. DATA_TASK(task)->write = true;
  3955. DATA_TASK(task)->address = MINION_SYS_INT_CLR;
  3956. DATA_TASK(task)->task_id = 0; // ignored
  3957. DATA_TASK(task)->wsiz = MINION_SYS_SIZ;
  3958. DATA_TASK(task)->rsiz = 0;
  3959. DATA_TASK(task)->wbuf[0] = MINION_CMD_INT;
  3960. DATA_TASK(task)->wbuf[1] = 0;
  3961. DATA_TASK(task)->wbuf[2] = 0;
  3962. DATA_TASK(task)->wbuf[3] = 0;
  3963. DATA_TASK(task)->urgent = false;
  3964. k_add_head(minioninfo->task_list, task);
  3965. K_WUNLOCK(minioninfo->tfree_list);
  3966. }
  3967. #endif
  3968. //applog(LOG_ERR, "%s%i: chip %d fin: quew %d chw %d", minioncgpu->drv->name, minioncgpu->device_id, CHP, minioninfo->chip_status[CHP].quework, minioninfo->chip_status[CHP].chipwork);
  3969. }
  3970. static bool minion_thread_prepare(struct thr_info *thr)
  3971. {
  3972. struct cgpu_info *minioncgpu = thr->cgpu;
  3973. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  3974. minioninfo->thr = thr;
  3975. /*
  3976. * SPI/ioctl write thread
  3977. */
  3978. if (thr_info_create(&(minioninfo->spiw_thr), NULL, minion_spi_write, (void *)minioncgpu)) {
  3979. applog(LOG_ERR, "%s%i: SPI write thread create failed",
  3980. minioncgpu->drv->name, minioncgpu->device_id);
  3981. return false;
  3982. }
  3983. pthread_detach(minioninfo->spiw_thr.pth);
  3984. /*
  3985. * SPI/ioctl results thread
  3986. */
  3987. if (thr_info_create(&(minioninfo->spir_thr), NULL, minion_spi_reply, (void *)minioncgpu)) {
  3988. applog(LOG_ERR, "%s%i: SPI reply thread create failed",
  3989. minioncgpu->drv->name, minioncgpu->device_id);
  3990. return false;
  3991. }
  3992. pthread_detach(minioninfo->spir_thr.pth);
  3993. /*
  3994. * Seperate results checking thread so ioctl timing can ignore the results checking
  3995. */
  3996. if (thr_info_create(&(minioninfo->res_thr), NULL, minion_results, (void *)minioncgpu)) {
  3997. applog(LOG_ERR, "%s%i: Results thread create failed",
  3998. minioncgpu->drv->name, minioncgpu->device_id);
  3999. return false;
  4000. }
  4001. pthread_detach(minioninfo->res_thr.pth);
  4002. return true;
  4003. }
  4004. static void minion_shutdown(struct thr_info *thr)
  4005. {
  4006. struct cgpu_info *minioncgpu = thr->cgpu;
  4007. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4008. int i;
  4009. applog(MINION_LOG, "%s%i: shutting down",
  4010. minioncgpu->drv->name, minioncgpu->device_id);
  4011. for (i = 0; i < (int)MINION_CHIPS; i++)
  4012. if (minioninfo->has_chip[i])
  4013. // TODO: minion_shutdown(minioncgpu, minioninfo, i);
  4014. i = i;
  4015. minioncgpu->shutdown = true;
  4016. }
  4017. static bool minion_queue_full(struct cgpu_info *minioncgpu)
  4018. {
  4019. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4020. struct work *work, *usework;
  4021. int count, totneed, need, roll, roll_limit, chip;
  4022. bool ret, rolled;
  4023. if (minioninfo->initialised == false) {
  4024. cgsleep_us(42);
  4025. return true;
  4026. }
  4027. K_RLOCK(minioninfo->wwork_list);
  4028. count = minioninfo->wwork_list->count;
  4029. totneed = 0;
  4030. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  4031. if (minioninfo->has_chip[chip] &&
  4032. !minioninfo->chip_status[chip].overheat) {
  4033. totneed += MINION_QUE_HIGH;
  4034. totneed -= minioninfo->chip_status[chip].quework;
  4035. totneed -= minioninfo->chip_status[chip].realwork;
  4036. // One for the pot :)
  4037. totneed++;
  4038. }
  4039. }
  4040. K_RUNLOCK(minioninfo->wwork_list);
  4041. if (count >= totneed)
  4042. ret = true;
  4043. else {
  4044. need = totneed - count;
  4045. /* Ensure we do enough rolling to reduce CPU
  4046. but dont roll too much to have them end up stale */
  4047. if (need < 16)
  4048. need = 16;
  4049. work = get_queued(minioncgpu);
  4050. if (work) {
  4051. roll_limit = work->drv_rolllimit;
  4052. roll = 0;
  4053. do {
  4054. if (roll == 0) {
  4055. usework = work;
  4056. minioninfo->work_unrolled++;
  4057. rolled = false;
  4058. } else {
  4059. usework = copy_work_noffset(work, roll);
  4060. minioninfo->work_rolled++;
  4061. rolled = true;
  4062. }
  4063. ready_work(minioncgpu, usework, rolled);
  4064. } while (--need > 0 && ++roll <= roll_limit);
  4065. } else {
  4066. // Avoid a hard loop when we can't get work fast enough
  4067. cgsleep_us(42);
  4068. }
  4069. if (need > 0)
  4070. ret = false;
  4071. else
  4072. ret = true;
  4073. }
  4074. return ret;
  4075. }
  4076. static void idle_report(struct cgpu_info *minioncgpu)
  4077. {
  4078. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4079. struct timeval now;
  4080. uint32_t idle;
  4081. int msdiff;
  4082. int chip;
  4083. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  4084. if (minioninfo->has_chip[chip]) {
  4085. idle = minioninfo->chip_status[chip].idle;
  4086. if (idle != minioninfo->chip_status[chip].last_rpt_idle) {
  4087. cgtime(&now);
  4088. msdiff = ms_tdiff(&now, &(minioninfo->chip_status[chip].idle_rpt));
  4089. if (msdiff >= MINION_IDLE_MESSAGE_ms) {
  4090. memcpy(&(minioninfo->chip_status[chip].idle_rpt), &now, sizeof(now));
  4091. applog(LOG_WARNING,
  4092. "%s%d: chip %d internal idle changed %08x",
  4093. minioncgpu->drv->name, minioncgpu->device_id,
  4094. chip, idle);
  4095. minioninfo->chip_status[chip].last_rpt_idle = idle;
  4096. }
  4097. }
  4098. }
  4099. }
  4100. }
  4101. static void chip_report(struct cgpu_info *minioncgpu)
  4102. {
  4103. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4104. struct timeval now;
  4105. char buf[512];
  4106. char res_err_msg[2];
  4107. size_t len;
  4108. double elapsed, ghs, ghs2, expect, howlong;
  4109. char ghs2_display[64];
  4110. K_ITEM *pitem;
  4111. int msdiff, chip;
  4112. int res_err_count;
  4113. cgtime(&now);
  4114. if (!(minioninfo->chip_chk.tv_sec)) {
  4115. memcpy(&(minioninfo->chip_chk), &now, sizeof(now));
  4116. memcpy(&(minioninfo->chip_rpt), &now, sizeof(now));
  4117. return;
  4118. }
  4119. // Always run the calculations to check chip GHs for the LED
  4120. buf[0] = '\0';
  4121. res_err_msg[0] = '\0';
  4122. res_err_msg[1] = '\0';
  4123. K_RLOCK(minioninfo->hfree_list);
  4124. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  4125. if (minioninfo->has_chip[chip]) {
  4126. len = strlen(buf);
  4127. if (minioninfo->hchip_list[chip]->count < 2)
  4128. ghs = 0.0;
  4129. else {
  4130. ghs = 0xffffffffull * (minioninfo->hchip_list[chip]->count - 1);
  4131. ghs /= 1000000000.0;
  4132. ghs /= tdiff(&now, &(DATA_HIST(minioninfo->hchip_list[chip]->tail)->when));
  4133. }
  4134. if (minioninfo->chip_status[chip].first_nonce.tv_sec == 0L ||
  4135. tdiff(&now, &minioninfo->chip_status[chip].first_nonce) < MINION_LED_TEST_TIME) {
  4136. ghs2_display[0] = '\0';
  4137. minioninfo->setled[chip] = false;
  4138. } else {
  4139. ghs2 = 0xffffffffull * (minioninfo->chip_status[chip].from_first_good - 1);
  4140. ghs2 /= 1000000000.0;
  4141. ghs2 /= tdiff(&now, &minioninfo->chip_status[chip].first_nonce);
  4142. minioninfo->setled[chip] = (ghs2 >= opt_minion_ledlimit);
  4143. snprintf(ghs2_display, sizeof(ghs2_display), "[%.2f]", ghs2);
  4144. }
  4145. res_err_count = minioninfo->res_err_count[chip];
  4146. minioninfo->res_err_count[chip] = 0;
  4147. if (res_err_count > 100)
  4148. res_err_msg[0] = '!';
  4149. else if (res_err_count > 50)
  4150. res_err_msg[0] = '*';
  4151. else if (res_err_count > 0)
  4152. res_err_msg[0] = '\'';
  4153. else
  4154. res_err_msg[0] = '\0';
  4155. snprintf(buf + len, sizeof(buf) - len,
  4156. " %d=%s%.2f%s", chip, res_err_msg, ghs, ghs2_display);
  4157. minioninfo->history_ghs[chip] = ghs;
  4158. }
  4159. }
  4160. K_RUNLOCK(minioninfo->hfree_list);
  4161. // But only display it if required
  4162. if (opt_minion_chipreport > 0) {
  4163. msdiff = ms_tdiff(&now, &(minioninfo->chip_rpt));
  4164. if (msdiff >= (opt_minion_chipreport * 1000)) {
  4165. memcpy(&(minioninfo->chip_chk), &now, sizeof(now));
  4166. applogsiz(LOG_WARNING, 512,
  4167. "%s%d: Chip GHs%s",
  4168. minioncgpu->drv->name, minioncgpu->device_id, buf);
  4169. memcpy(&(minioninfo->chip_rpt), &now, sizeof(now));
  4170. }
  4171. }
  4172. msdiff = ms_tdiff(&now, &(minioninfo->chip_chk));
  4173. if (total_secs >= MINION_RESET_s && msdiff >= (minioninfo->history_gen * 1000)) {
  4174. K_RLOCK(minioninfo->hfree_list);
  4175. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  4176. if (minioninfo->has_chip[chip]) {
  4177. // Don't reset the chip while 'changing'
  4178. if (minioninfo->changing[chip])
  4179. continue;
  4180. if (!minioninfo->reset_mark[chip] ||
  4181. minioninfo->reset_count[chip] < 2) {
  4182. elapsed = 0.0;
  4183. ghs = 0.0;
  4184. } else {
  4185. // 'now' includes that it may have stopped getting nonces
  4186. elapsed = tdiff(&now, &(DATA_HIST(minioninfo->reset_mark[chip])->when));
  4187. ghs = 0xffffffffull * (minioninfo->reset_count[chip] - 1);
  4188. ghs /= 1000000000.0;
  4189. ghs /= elapsed;
  4190. }
  4191. expect = (double)(minioninfo->init_freq[chip]) *
  4192. MINION_RESET_PERCENT / 1000.0;
  4193. howlong = tdiff(&now, &(minioninfo->last_reset[chip]));
  4194. if (ghs <= expect && howlong >= minioninfo->reset_time[chip]) {
  4195. minioninfo->do_reset[chip] = expect;
  4196. // For now - no lock required since no other code accesses it
  4197. pitem = k_unlink_head(minioninfo->pfree_list);
  4198. DATA_PERF(pitem)->elapsed = elapsed;
  4199. DATA_PERF(pitem)->nonces = minioninfo->reset_count[chip] - 1;
  4200. DATA_PERF(pitem)->freq = minioninfo->init_freq[chip];
  4201. DATA_PERF(pitem)->ghs = ghs;
  4202. memcpy(&(DATA_PERF(pitem)->when), &now, sizeof(now));
  4203. k_add_head(minioninfo->p_list[chip], pitem);
  4204. } else if (second_check) {
  4205. expect = (double)(minioninfo->init_freq[chip]) *
  4206. MINION_RESET2_PERCENT / 1000.0;
  4207. if (ghs < expect && howlong >= minioninfo->reset2_time[chip]) {
  4208. /* Only do a reset, don't record it, since the ghs
  4209. is still above MINION_RESET_PERCENT */
  4210. minioninfo->do_reset[chip] = expect;
  4211. }
  4212. }
  4213. minioninfo->history_ghs[chip] = ghs;
  4214. // Expire old perf items to stop clockdown
  4215. if (minioninfo->do_reset[chip] <= 1.0 && howlong > MINION_CLR_s) {
  4216. // Always remember the last reset
  4217. while (minioninfo->p_list[chip]->count > 1) {
  4218. pitem = k_unlink_tail(minioninfo->p_list[chip]);
  4219. k_add_head(minioninfo->pfree_list, pitem);
  4220. }
  4221. }
  4222. }
  4223. }
  4224. K_RUNLOCK(minioninfo->hfree_list);
  4225. memcpy(&(minioninfo->chip_chk), &now, sizeof(now));
  4226. }
  4227. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  4228. if (minioninfo->has_chip[chip]) {
  4229. // Don't reset the chip while 'changing'
  4230. if (minioninfo->changing[chip])
  4231. continue;
  4232. if (minioninfo->do_reset[chip] > 1.0 ||
  4233. minioninfo->flag_reset[chip]) {
  4234. bool std_reset = true;
  4235. int curr_freq = minioninfo->init_freq[chip];
  4236. int new_freq = 0.0;
  4237. int count;
  4238. // Adjust frequency down?
  4239. if (!opt_minion_noautofreq &&
  4240. minioninfo->p_list[chip]->count >= MINION_RESET_COUNT) {
  4241. pitem = minioninfo->p_list[chip]->head;
  4242. count = 1;
  4243. while (pitem && pitem->next && count++ < MINION_RESET_COUNT) {
  4244. if (DATA_PERF(pitem)->freq != DATA_PERF(pitem->next)->freq)
  4245. break;
  4246. if (count >= MINION_RESET_COUNT) {
  4247. new_freq = minioninfo->init_freq[chip] -
  4248. MINION_FREQ_RESET_STEP;
  4249. if (new_freq < MINION_FREQ_MIN)
  4250. new_freq = MINION_FREQ_MIN;
  4251. if (minioninfo->init_freq[chip] != new_freq) {
  4252. minioninfo->init_freq[chip] = new_freq;
  4253. std_reset = false;
  4254. }
  4255. break;
  4256. } else
  4257. pitem = pitem->next;
  4258. }
  4259. }
  4260. if (std_reset) {
  4261. if (minioninfo->do_reset[chip] > 1.0) {
  4262. applog(LOG_WARNING, "%s%d: Chip %d %dMHz threshold "
  4263. "%.2fGHs - resetting",
  4264. minioncgpu->drv->name,
  4265. minioncgpu->device_id,
  4266. chip, curr_freq,
  4267. minioninfo->do_reset[chip]);
  4268. } else {
  4269. applog(LOG_WARNING, "%s%d: Chip %d %dMhz flagged - "
  4270. "resetting",
  4271. minioncgpu->drv->name,
  4272. minioncgpu->device_id,
  4273. chip, curr_freq);
  4274. }
  4275. } else {
  4276. if (minioninfo->do_reset[chip] > 1.0) {
  4277. applog(LOG_WARNING, "%s%d: Chip %d %dMHz threshold "
  4278. "%.2fGHs - resetting to %dMhz",
  4279. minioncgpu->drv->name,
  4280. minioncgpu->device_id,
  4281. chip, curr_freq,
  4282. minioninfo->do_reset[chip],
  4283. new_freq);
  4284. } else {
  4285. applog(LOG_WARNING, "%s%d: Chip %d %dMhz flagged - "
  4286. "resetting to %dMHz",
  4287. minioncgpu->drv->name,
  4288. minioncgpu->device_id,
  4289. chip, curr_freq, new_freq);
  4290. }
  4291. }
  4292. minioninfo->do_reset[chip] = 0.0;
  4293. memcpy(&(minioninfo->last_reset[chip]), &now, sizeof(now));
  4294. init_chip(minioncgpu, minioninfo, chip);
  4295. minioninfo->flag_reset[chip] = false;
  4296. }
  4297. }
  4298. }
  4299. }
  4300. static int64_t minion_scanwork(__maybe_unused struct thr_info *thr)
  4301. {
  4302. struct cgpu_info *minioncgpu = thr->cgpu;
  4303. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4304. int64_t hashcount = 0;
  4305. if (minioninfo->initialised == false)
  4306. return hashcount;
  4307. minion_do_work(minioncgpu);
  4308. mutex_lock(&(minioninfo->nonce_lock));
  4309. if (minioninfo->new_nonces) {
  4310. hashcount += 0xffffffffull * minioninfo->new_nonces;
  4311. minioninfo->new_nonces = 0;
  4312. }
  4313. mutex_unlock(&(minioninfo->nonce_lock));
  4314. if (opt_minion_idlecount)
  4315. idle_report(minioncgpu);
  4316. // Must always generate data to check/allow for chip reset
  4317. chip_report(minioncgpu);
  4318. /*
  4319. * To avoid wasting CPU, wait until we get an interrupt
  4320. * before returning back to the main cgminer work loop
  4321. * i.e. we then know we'll need more work
  4322. */
  4323. cgsem_mswait(&(minioninfo->scan_work), MINION_SCAN_mS);
  4324. return hashcount;
  4325. }
  4326. static const char *temp_str(uint16_t temp)
  4327. {
  4328. switch (temp) {
  4329. case MINION_TEMP_40:
  4330. return min_temp_40;
  4331. case MINION_TEMP_60:
  4332. return min_temp_60;
  4333. case MINION_TEMP_80:
  4334. return min_temp_80;
  4335. case MINION_TEMP_100:
  4336. return min_temp_100;
  4337. case MINION_TEMP_OVER:
  4338. return min_temp_over;
  4339. }
  4340. return min_temp_invalid;
  4341. }
  4342. static void minion_get_statline_before(char *buf, size_t bufsiz, struct cgpu_info *minioncgpu)
  4343. {
  4344. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4345. uint16_t max_temp, cores;
  4346. int chip, core;
  4347. max_temp = 0;
  4348. cores = 0;
  4349. mutex_lock(&(minioninfo->sta_lock));
  4350. for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
  4351. if (minioninfo->has_chip[chip]) {
  4352. if (max_temp < minioninfo->chip_status[chip].temp)
  4353. max_temp = minioninfo->chip_status[chip].temp;
  4354. for (core = 0; core < MINION_CORES; core++) {
  4355. if (minioninfo->chip_core_ena[core >> 5][chip] & (0x1 << (core % 32)))
  4356. cores++;
  4357. }
  4358. }
  4359. }
  4360. mutex_unlock(&(minioninfo->sta_lock));
  4361. tailsprintf(buf, bufsiz, "max%sC Ch:%d Co:%d",
  4362. temp_str(max_temp), minioninfo->chips, (int)cores);
  4363. }
  4364. #define CHIPS_PER_STAT 5
  4365. static struct api_data *minion_api_stats(struct cgpu_info *minioncgpu)
  4366. {
  4367. struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
  4368. struct api_data *root = NULL;
  4369. char cores[MINION_CORES+1];
  4370. char data[2048];
  4371. char buf[32];
  4372. int i, to, j;
  4373. size_t datalen, nlen;
  4374. int chip, max_chip, que_work, chip_work, temp;
  4375. if (minioninfo->initialised == false)
  4376. return NULL;
  4377. root = api_add_uint64(root, "OK Nonces", &(minioninfo->ok_nonces), true);
  4378. root = api_add_uint64(root, "New Nonces", &(minioninfo->new_nonces), true);
  4379. root = api_add_uint64(root, "Tested Nonces", &(minioninfo->tested_nonces), true);
  4380. root = api_add_uint64(root, "Untested Nonces", &(minioninfo->untested_nonces), true);
  4381. root = api_add_int(root, "Chips", &(minioninfo->chips), true);
  4382. i = MINION_PIN_COUNT;
  4383. root = api_add_int(root, "GPIO Pins", &i, true);
  4384. max_chip = 0;
  4385. for (chip = 0; chip < (int)MINION_CHIPS; chip++)
  4386. if (minioninfo->has_chip[chip]) {
  4387. max_chip = chip;
  4388. snprintf(buf, sizeof(buf), "Chip %d Pin", chip);
  4389. root = api_add_int(root, buf, &(minioninfo->chip_pin[chip]), true);
  4390. snprintf(buf, sizeof(buf), "Chip %d ChipID", chip);
  4391. i = (int)(minioninfo->chipid[chip]);
  4392. root = api_add_int(root, buf, &i, true);
  4393. snprintf(buf, sizeof(buf), "Chip %d Temperature", chip);
  4394. root = api_add_const(root, buf, temp_str(minioninfo->chip_status[chip].temp), false);
  4395. snprintf(buf, sizeof(buf), "Chip %d Cores", chip);
  4396. root = api_add_uint16(root, buf, &(minioninfo->chip_status[chip].cores), true);
  4397. snprintf(buf, sizeof(buf), "Chip %d Frequency", chip);
  4398. root = api_add_uint32(root, buf, &(minioninfo->chip_status[chip].freq), true);
  4399. snprintf(buf, sizeof(buf), "Chip %d InitFreq", chip);
  4400. root = api_add_int(root, buf, &(minioninfo->init_freq[chip]), true);
  4401. snprintf(buf, sizeof(buf), "Chip %d FreqSent", chip);
  4402. root = api_add_hex32(root, buf, &(minioninfo->freqsent[chip]), true);
  4403. snprintf(buf, sizeof(buf), "Chip %d InitTemp", chip);
  4404. temp = minioninfo->init_temp[chip];
  4405. if (temp == MINION_TEMP_CTL_DISABLE)
  4406. root = api_add_string(root, buf, MINION_TEMP_DISABLE, true);
  4407. else {
  4408. snprintf(data, sizeof(data), "%d", temp);
  4409. root = api_add_string(root, buf, data, true);
  4410. }
  4411. snprintf(buf, sizeof(buf), "Chip %d TempSent", chip);
  4412. root = api_add_hex32(root, buf, &(minioninfo->chip_status[chip].tempsent), true);
  4413. __bin2hex(data, (unsigned char *)(&(minioninfo->init_cores[chip][0])),
  4414. sizeof(minioninfo->init_cores[chip]));
  4415. snprintf(buf, sizeof(buf), "Chip %d InitCores", chip);
  4416. root = api_add_string(root, buf, data, true);
  4417. snprintf(buf, sizeof(buf), "Chip %d IdleCount", chip);
  4418. root = api_add_hex32(root, buf, &(minioninfo->chip_status[chip].idle), true);
  4419. snprintf(buf, sizeof(buf), "Chip %d QueWork", chip);
  4420. root = api_add_uint32(root, buf, &(minioninfo->chip_status[chip].quework), true);
  4421. snprintf(buf, sizeof(buf), "Chip %d ChipWork", chip);
  4422. root = api_add_uint32(root, buf, &(minioninfo->chip_status[chip].chipwork), true);
  4423. snprintf(buf, sizeof(buf), "Chip %d RealWork", chip);
  4424. root = api_add_uint32(root, buf, &(minioninfo->chip_status[chip].realwork), true);
  4425. snprintf(buf, sizeof(buf), "Chip %d QueListCount", chip);
  4426. root = api_add_int(root, buf, &(minioninfo->wque_list[chip]->count), true);
  4427. snprintf(buf, sizeof(buf), "Chip %d WorkListCount", chip);
  4428. root = api_add_int(root, buf, &(minioninfo->wchip_list[chip]->count), true);
  4429. snprintf(buf, sizeof(buf), "Chip %d Overheat", chip);
  4430. root = api_add_bool(root, buf, &(minioninfo->chip_status[chip].overheat), true);
  4431. snprintf(buf, sizeof(buf), "Chip %d Overheats", chip);
  4432. root = api_add_uint32(root, buf, &(minioninfo->chip_status[chip].overheats), true);
  4433. snprintf(buf, sizeof(buf), "Chip %d LastOverheat", chip);
  4434. root = api_add_timeval(root, buf, &(minioninfo->chip_status[chip].lastoverheat), true);
  4435. snprintf(buf, sizeof(buf), "Chip %d LastRecover", chip);
  4436. root = api_add_timeval(root, buf, &(minioninfo->chip_status[chip].lastrecover), true);
  4437. snprintf(buf, sizeof(buf), "Chip %d OverheatIdle", chip);
  4438. root = api_add_double(root, buf, &(minioninfo->chip_status[chip].overheattime), true);
  4439. for (i = 0; i < MINION_CORES; i++) {
  4440. if (minioninfo->chip_core_ena[i >> 5][chip] & (0x1 << (i % 32)))
  4441. cores[i] = 'o';
  4442. else
  4443. cores[i] = 'x';
  4444. }
  4445. cores[MINION_CORES] = '\0';
  4446. snprintf(buf, sizeof(buf), "Chip %d CoresEna", chip);
  4447. root = api_add_string(root, buf, cores, true);
  4448. for (i = 0; i < MINION_CORES; i++) {
  4449. if (minioninfo->chip_core_act[i >> 5][chip] & (0x1 << (i % 32)))
  4450. cores[i] = '-';
  4451. else
  4452. cores[i] = 'o';
  4453. }
  4454. cores[MINION_CORES] = '\0';
  4455. snprintf(buf, sizeof(buf), "Chip %d CoresAct", chip);
  4456. root = api_add_string(root, buf, cores, true);
  4457. if (opt_minion_extra) {
  4458. data[0] = '\0';
  4459. datalen = 0;
  4460. for (i = 0; i < MINION_CORES; i++) {
  4461. if (datalen < sizeof(data)) {
  4462. nlen = snprintf(data+datalen, sizeof(data)-datalen,
  4463. "%s%"PRIu64"-%s%"PRIu64,
  4464. i == 0 ? "" : "/",
  4465. minioninfo->core_good[chip][i],
  4466. minioninfo->core_bad[chip][i] ? "'" : "",
  4467. minioninfo->core_bad[chip][i]);
  4468. if (nlen < 1)
  4469. break;
  4470. datalen += nlen;
  4471. }
  4472. }
  4473. snprintf(buf, sizeof(buf), "Chip %d Cores Good-Bad", chip);
  4474. root = api_add_string(root, buf, data, true);
  4475. }
  4476. snprintf(buf, sizeof(buf), "Chip %d History GHs", chip);
  4477. root = api_add_mhs(root, buf, &(minioninfo->history_ghs[chip]), true);
  4478. }
  4479. double his = MINION_HISTORY_s;
  4480. root = api_add_double(root, "History length", &his, true);
  4481. his = MINION_RESET_s;
  4482. root = api_add_double(root, "Default reset length", &his, true);
  4483. his = MINION_RESET2_s;
  4484. root = api_add_double(root, "Default reset2 length", &his, true);
  4485. root = api_add_bool(root, "Reset2 enabled", &second_check, true);
  4486. for (i = 0; i <= max_chip; i += CHIPS_PER_STAT) {
  4487. to = i + CHIPS_PER_STAT - 1;
  4488. if (to > max_chip)
  4489. to = max_chip;
  4490. data[0] = '\0';
  4491. for (j = i; j <= to; j++) {
  4492. snprintf(buf, sizeof(buf),
  4493. "%s%d",
  4494. j == i ? "" : " ",
  4495. minioninfo->has_chip[j] ? 1 : 0);
  4496. strcat(data, buf);
  4497. }
  4498. snprintf(buf, sizeof(buf), "Detected %02d - %02d", i, to);
  4499. root = api_add_string(root, buf, data, true);
  4500. data[0] = '\0';
  4501. for (j = i; j <= to; j++) {
  4502. snprintf(buf, sizeof(buf),
  4503. "%s%8"PRIu64,
  4504. j == i ? "" : " ",
  4505. minioninfo->chip_nonces[j]);
  4506. strcat(data, buf);
  4507. }
  4508. snprintf(buf, sizeof(buf), "Nonces %02d - %02d", i, to);
  4509. root = api_add_string(root, buf, data, true);
  4510. data[0] = '\0';
  4511. for (j = i; j <= to; j++) {
  4512. snprintf(buf, sizeof(buf),
  4513. "%s%8"PRIu64,
  4514. j == i ? "" : " ",
  4515. minioninfo->chip_nononces[j]);
  4516. strcat(data, buf);
  4517. }
  4518. snprintf(buf, sizeof(buf), "NoNonces %02d - %02d", i, to);
  4519. root = api_add_string(root, buf, data, true);
  4520. data[0] = '\0';
  4521. for (j = i; j <= to; j++) {
  4522. snprintf(buf, sizeof(buf),
  4523. "%s%8"PRIu64,
  4524. j == i ? "" : " ",
  4525. minioninfo->chip_good[j]);
  4526. strcat(data, buf);
  4527. }
  4528. snprintf(buf, sizeof(buf), "Good %02d - %02d", i, to);
  4529. root = api_add_string(root, buf, data, true);
  4530. data[0] = '\0';
  4531. for (j = i; j <= to; j++) {
  4532. snprintf(buf, sizeof(buf),
  4533. "%s%8"PRIu64,
  4534. j == i ? "" : " ",
  4535. minioninfo->chip_bad[j]);
  4536. strcat(data, buf);
  4537. }
  4538. snprintf(buf, sizeof(buf), "Bad %02d - %02d", i, to);
  4539. root = api_add_string(root, buf, data, true);
  4540. data[0] = '\0';
  4541. for (j = i; j <= to; j++) {
  4542. snprintf(buf, sizeof(buf),
  4543. "%s%8"PRIu64,
  4544. j == i ? "" : " ",
  4545. minioninfo->chip_err[j]);
  4546. strcat(data, buf);
  4547. }
  4548. snprintf(buf, sizeof(buf), "Err %02d - %02d", i, to);
  4549. root = api_add_string(root, buf, data, true);
  4550. data[0] = '\0';
  4551. for (j = i; j <= to; j++) {
  4552. snprintf(buf, sizeof(buf),
  4553. "%s%8"PRIu64,
  4554. j == i ? "" : " ",
  4555. minioninfo->fifo_spi_errors[j]);
  4556. strcat(data, buf);
  4557. }
  4558. snprintf(buf, sizeof(buf), "FifoSpiErr %02d - %02d", i, to);
  4559. root = api_add_string(root, buf, data, true);
  4560. data[0] = '\0';
  4561. for (j = i; j <= to; j++) {
  4562. snprintf(buf, sizeof(buf),
  4563. "%s%8"PRIu64,
  4564. j == i ? "" : " ",
  4565. minioninfo->res_spi_errors[j]);
  4566. strcat(data, buf);
  4567. }
  4568. snprintf(buf, sizeof(buf), "ResSpiErr %02d - %02d", i, to);
  4569. root = api_add_string(root, buf, data, true);
  4570. data[0] = '\0';
  4571. for (j = i; j <= to; j++) {
  4572. snprintf(buf, sizeof(buf),
  4573. "%s%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64,
  4574. j == i ? "" : " ",
  4575. minioninfo->use_res2[j],
  4576. minioninfo->tasks_failed[j],
  4577. minioninfo->tasks_recovered[j],
  4578. minioninfo->nonces_failed[j],
  4579. minioninfo->nonces_recovered[j]);
  4580. strcat(data, buf);
  4581. }
  4582. snprintf(buf, sizeof(buf), "Redo %02d - %02d", i, to);
  4583. root = api_add_string(root, buf, data, true);
  4584. }
  4585. que_work = chip_work = 0;
  4586. for (chip = 0; chip <= max_chip; chip++) {
  4587. if (minioninfo->has_chip[chip]) {
  4588. que_work += minioninfo->wque_list[chip]->count;
  4589. chip_work += minioninfo->wchip_list[chip]->count;
  4590. }
  4591. }
  4592. root = api_add_int(root, "WFree Total", &(minioninfo->wfree_list->total), true);
  4593. root = api_add_int(root, "WFree Count", &(minioninfo->wfree_list->count), true);
  4594. root = api_add_int(root, "WWork Count", &(minioninfo->wwork_list->count), true);
  4595. root = api_add_uint64(root, "WWork Flushed", &(minioninfo->wwork_flushed), true);
  4596. root = api_add_int(root, "WQue Count", &que_work, true);
  4597. root = api_add_uint64(root, "WQue Flushed", &(minioninfo->wque_flushed), true);
  4598. root = api_add_int(root, "WChip Count", &chip_work, true);
  4599. root = api_add_uint64(root, "WChip Stale", &(minioninfo->wchip_staled), true);
  4600. root = api_add_int(root, "TFree Total", &(minioninfo->tfree_list->total), true);
  4601. root = api_add_int(root, "TFree Count", &(minioninfo->tfree_list->count), true);
  4602. root = api_add_int(root, "Task Count", &(minioninfo->task_list->count), true);
  4603. root = api_add_int(root, "Reply Count", &(minioninfo->treply_list->count), true);
  4604. root = api_add_int(root, "RFree Total", &(minioninfo->rfree_list->total), true);
  4605. root = api_add_int(root, "RFree Count", &(minioninfo->rfree_list->count), true);
  4606. root = api_add_int(root, "RNonce Count", &(minioninfo->rnonce_list->count), true);
  4607. root = api_add_int(root, "XFree Count", &(minioninfo->xfree_list->count), true);
  4608. root = api_add_int(root, "XFF Count", &(minioninfo->xff_list->count), true);
  4609. root = api_add_uint64(root, "XFFs", &(minioninfo->xffs), true);
  4610. root = api_add_uint64(root, "SPI Resets", &(minioninfo->spi_resets), true);
  4611. root = api_add_uint64(root, "Power Cycles", &(minioninfo->power_cycles), true);
  4612. root = api_add_int(root, "Chip Report", &opt_minion_chipreport, true);
  4613. root = api_add_int(root, "LED Count", &opt_minion_ledcount, true);
  4614. root = api_add_int(root, "LED Limit", &opt_minion_ledlimit, true);
  4615. bool b = !opt_minion_noautofreq;
  4616. root = api_add_bool(root, "Auto Freq", &b, true);
  4617. root = api_add_int(root, "SPI Delay", &opt_minion_spidelay, true);
  4618. root = api_add_bool(root, "SPI Reset I/O", &(minioninfo->spi_reset_io), true);
  4619. root = api_add_int(root, "SPI Reset", &(minioninfo->spi_reset_count), true);
  4620. root = api_add_int(root, "SPI Reset Sleep", &opt_minion_spisleep, true);
  4621. #if DO_IO_STATS
  4622. #define sta_api(_name, _iostat) \
  4623. do { \
  4624. if ((_iostat).count) { \
  4625. float _davg = (float)((_iostat).total_delay) / (float)((_iostat).count); \
  4626. float _dlavg = (float)((_iostat).total_dlock) / (float)((_iostat).count); \
  4627. float _dlwavg = (float)((_iostat).total_dlwait) / (float)((_iostat).count); \
  4628. float _bavg = (float)((_iostat).total_bytes) / (float)((_iostat).count); \
  4629. float _tavg = (float)((_iostat).tsd) / (float)((_iostat).count); \
  4630. snprintf(data, sizeof(data), "%s Count=%"PRIu64 \
  4631. " Delay=%.0fus DAvg=%.3f" \
  4632. " DMin=%.0f DMax=%.0f DZ=%"PRIu64 \
  4633. " DLock=%.0fus DLAvg=%.3f" \
  4634. " DLMin=%.0f DLMax=%.0f DZ=%"PRIu64 \
  4635. " DLWait=%.0fus DLWAvg=%.3f" \
  4636. " Bytes=%"PRIu64" BAvg=%.3f" \
  4637. " BMin=%"PRIu64" BMax=%"PRIu64" BZ=%"PRIu64 \
  4638. " TSD=%.0fus TAvg=%.03f", \
  4639. _name, (_iostat).count, \
  4640. (_iostat).total_delay, _davg, (_iostat).min_delay, \
  4641. (_iostat).max_delay, (_iostat).zero_delay, \
  4642. (_iostat).total_dlock, _dlavg, (_iostat).min_dlock, \
  4643. (_iostat).max_dlock, (_iostat).zero_dlock, \
  4644. (_iostat).total_dlwait, _dlwavg, \
  4645. (_iostat).total_bytes, _bavg, (_iostat).min_bytes, \
  4646. (_iostat).max_bytes, (_iostat).zero_bytes, \
  4647. (_iostat).tsd, _tavg); \
  4648. root = api_add_string(root, buf, data, true); \
  4649. } \
  4650. } while(0);
  4651. for (i = 0; i < 0x200; i++) {
  4652. snprintf(buf, sizeof(buf), "Stat-0x%02x", i);
  4653. sta_api(addr2txt((uint8_t)(i & 0xff)), minioninfo->iostats[i]);
  4654. }
  4655. // Test to avoid showing applog
  4656. if (minioninfo->summary.count) {
  4657. snprintf(buf, sizeof(buf), "Stat-S");
  4658. sta_api("Summary", minioninfo->summary);
  4659. applog(LOG_WARNING, "%s %d: (%.0f) %s - %s",
  4660. minioncgpu->drv->name, minioncgpu->device_id,
  4661. total_secs, buf, data);
  4662. }
  4663. #endif
  4664. root = api_add_uint64(root, "Total SPI Errors", &(minioninfo->spi_errors), true);
  4665. root = api_add_uint64(root, "Work Unrolled", &(minioninfo->work_unrolled), true);
  4666. root = api_add_uint64(root, "Work Rolled", &(minioninfo->work_rolled), true);
  4667. root = api_add_uint64(root, "Ints", &(minioninfo->interrupts), true);
  4668. root = api_add_uint64(root, "Res Ints", &(minioninfo->result_interrupts), true);
  4669. root = api_add_uint64(root, "Cmd Ints", &(minioninfo->command_interrupts), true);
  4670. root = api_add_string(root, "Last Int", minioninfo->last_interrupt, true);
  4671. root = api_add_hex32(root, "Next TaskID", &(minioninfo->next_task_id), true);
  4672. double avg;
  4673. root = api_add_uint64(root, "ToQue", &(minioninfo->que_work), true);
  4674. if (minioninfo->que_work)
  4675. avg = minioninfo->que_time / (double)(minioninfo->que_work);
  4676. else
  4677. avg = 0;
  4678. root = api_add_double(root, "Que Avg", &avg, true);
  4679. root = api_add_double(root, "Que Min", &(minioninfo->que_min), true);
  4680. root = api_add_double(root, "Que Max", &(minioninfo->que_max), true);
  4681. data[0] = '\0';
  4682. for (i = 0; i <= TIME_BANDS; i++) {
  4683. snprintf(buf, sizeof(buf),
  4684. "%s%"PRIu64,
  4685. i == 0 ? "" : "/",
  4686. minioninfo->que_bands[i]);
  4687. strcat(data, buf);
  4688. }
  4689. root = api_add_string(root, "Que Bands", data, true);
  4690. root = api_add_uint64(root, "ToTxRx", &(minioninfo->wt_work), true);
  4691. if (minioninfo->wt_work)
  4692. avg = minioninfo->wt_time / (double)(minioninfo->wt_work);
  4693. else
  4694. avg = 0;
  4695. root = api_add_double(root, "TxRx Avg", &avg, true);
  4696. root = api_add_double(root, "TxRx Min", &(minioninfo->wt_min), true);
  4697. root = api_add_double(root, "TxRx Max", &(minioninfo->wt_max), true);
  4698. data[0] = '\0';
  4699. for (i = 0; i <= TIME_BANDS; i++) {
  4700. snprintf(buf, sizeof(buf),
  4701. "%s%"PRIu64,
  4702. i == 0 ? "" : "/",
  4703. minioninfo->wt_bands[i]);
  4704. strcat(data, buf);
  4705. }
  4706. root = api_add_string(root, "TxRx Bands", data, true);
  4707. uint64_t checked, dups;
  4708. dupcounters(minioncgpu, &checked, &dups);
  4709. root = api_add_uint64(root, "Dups", &dups, true);
  4710. return root;
  4711. }
  4712. #endif
  4713. struct device_drv minion_drv = {
  4714. .drv_id = DRIVER_minion,
  4715. .dname = "Minion BlackArrow",
  4716. .name = "MBA",
  4717. .drv_detect = minion_detect,
  4718. #ifdef LINUX
  4719. .get_api_stats = minion_api_stats,
  4720. .get_statline_before = minion_get_statline_before,
  4721. .set_device = minion_api_set,
  4722. .identify_device = minion_identify,
  4723. .thread_prepare = minion_thread_prepare,
  4724. .hash_work = hash_queued_work,
  4725. .scanwork = minion_scanwork,
  4726. .queue_full = minion_queue_full,
  4727. .flush_work = minion_flush_work,
  4728. .thread_shutdown = minion_shutdown
  4729. #endif
  4730. };