008-mcfv4e_coldfire_code.patch 113 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484
  1. From 70b2bd01829b38a1a79caeda05d436b2e5fecf82 Mon Sep 17 00:00:00 2001
  2. From: Kurt Mahan <[email protected]>
  3. Date: Wed, 31 Oct 2007 17:00:18 -0600
  4. Subject: [PATCH] Core Coldfire/MCF5445x specific code.
  5. LTIBName: mcfv4e-coldfire-code
  6. Signed-off-by: Kurt Mahan <[email protected]>
  7. ---
  8. arch/m68k/coldfire/Makefile | 11 +
  9. arch/m68k/coldfire/cache.c | 215 +++++++++
  10. arch/m68k/coldfire/config.c | 420 ++++++++++++++++++
  11. arch/m68k/coldfire/entry.S | 701 ++++++++++++++++++++++++++++++
  12. arch/m68k/coldfire/head.S | 474 ++++++++++++++++++++
  13. arch/m68k/coldfire/ints.c | 384 ++++++++++++++++
  14. arch/m68k/coldfire/iomap.c | 54 +++
  15. arch/m68k/coldfire/mcf5445x-pci.c | 427 ++++++++++++++++++
  16. arch/m68k/coldfire/muldi3.S | 64 +++
  17. arch/m68k/coldfire/pci.c | 245 +++++++++++
  18. arch/m68k/coldfire/signal.c | 868 +++++++++++++++++++++++++++++++++++++
  19. arch/m68k/coldfire/traps.c | 454 +++++++++++++++++++
  20. arch/m68k/coldfire/vmlinux-cf.lds | 92 ++++
  21. 13 files changed, 4409 insertions(+), 0 deletions(-)
  22. create mode 100644 arch/m68k/coldfire/Makefile
  23. create mode 100644 arch/m68k/coldfire/cache.c
  24. create mode 100644 arch/m68k/coldfire/config.c
  25. create mode 100644 arch/m68k/coldfire/entry.S
  26. create mode 100644 arch/m68k/coldfire/head.S
  27. create mode 100644 arch/m68k/coldfire/ints.c
  28. create mode 100644 arch/m68k/coldfire/iomap.c
  29. create mode 100644 arch/m68k/coldfire/mcf5445x-pci.c
  30. create mode 100644 arch/m68k/coldfire/muldi3.S
  31. create mode 100644 arch/m68k/coldfire/pci.c
  32. create mode 100644 arch/m68k/coldfire/signal.c
  33. create mode 100644 arch/m68k/coldfire/traps.c
  34. create mode 100644 arch/m68k/coldfire/vmlinux-cf.lds
  35. --- /dev/null
  36. +++ b/arch/m68k/coldfire/Makefile
  37. @@ -0,0 +1,11 @@
  38. +#
  39. +# Makefile for Linux arch/m68k/coldfire source directory
  40. +#
  41. +
  42. +obj-y:= entry.o config.o cache.o signal.o muldi3.o traps.o ints.o
  43. +
  44. +ifneq ($(strip $(CONFIG_USB) $(CONFIG_USB_GADGET_MCF5445X)),)
  45. + obj-y += usb.o usb/
  46. +endif
  47. +
  48. +obj-$(CONFIG_PCI) += pci.o mcf5445x-pci.o iomap.o
  49. --- /dev/null
  50. +++ b/arch/m68k/coldfire/cache.c
  51. @@ -0,0 +1,215 @@
  52. +/*
  53. + * linux/arch/m68k/coldifre/cache.c
  54. + *
  55. + * Matt Waddel [email protected]
  56. + * Copyright Freescale Semiconductor, Inc. 2007
  57. + *
  58. + * This program is free software; you can redistribute it and/or modify
  59. + * it under the terms of the GNU General Public License as published by
  60. + * the Free Software Foundation; either version 2 of the License, or
  61. + * (at your option) any later version.
  62. + */
  63. +
  64. +#include <linux/interrupt.h>
  65. +#include <asm/cfcache.h>
  66. +#include <asm/coldfire.h>
  67. +#include <asm/system.h>
  68. +
  69. +#define _DCACHE_SIZE (2*16384)
  70. +#define _ICACHE_SIZE (2*16384)
  71. +
  72. +#define _SET_SHIFT 4
  73. +
  74. +/*
  75. + * Masks for cache sizes. Programming note: because the set size is a
  76. + * power of two, the mask is also the last address in the set.
  77. + */
  78. +
  79. +#define _DCACHE_SET_MASK ((_DCACHE_SIZE/64-1)<<_SET_SHIFT)
  80. +#define _ICACHE_SET_MASK ((_ICACHE_SIZE/64-1)<<_SET_SHIFT)
  81. +#define LAST_DCACHE_ADDR _DCACHE_SET_MASK
  82. +#define LAST_ICACHE_ADDR _ICACHE_SET_MASK
  83. +
  84. +/************************************************************
  85. + * Routine to cleanly flush the cache, pushing all lines and
  86. + * invalidating them.
  87. + *
  88. + * The is the flash-resident version, used after copying the .text
  89. + * segment from flash to ram.
  90. + *************************************************************/
  91. +void FLASHDcacheFlushInvalidate(void)
  92. + __attribute__ ((section (".text_loader")));
  93. +
  94. +void FLASHDcacheFlushInvalidate()
  95. +{
  96. + unsigned long set;
  97. + unsigned long start_set;
  98. + unsigned long end_set;
  99. +
  100. + start_set = 0;
  101. + end_set = (unsigned long)LAST_DCACHE_ADDR;
  102. +
  103. + for (set = start_set; set < end_set; set += (0x10 - 3))
  104. + asm volatile("cpushl %%dc,(%0)\n"
  105. + "\taddq%.l #1,%0\n"
  106. + "\tcpushl %%dc,(%0)\n"
  107. + "\taddq%.l #1,%0\n"
  108. + "\tcpushl %%dc,(%0)\n"
  109. + "\taddq%.l #1,%0\n"
  110. + "\tcpushl %%dc,(%0)" : : "a" (set));
  111. +}
  112. +
  113. +/************************************************************
  114. + * Routine to cleanly flush the cache, pushing all lines and
  115. + * invalidating them.
  116. + *
  117. + *************************************************************/
  118. +void DcacheFlushInvalidate()
  119. +{
  120. + unsigned long set;
  121. + unsigned long start_set;
  122. + unsigned long end_set;
  123. +
  124. + start_set = 0;
  125. + end_set = (unsigned long)LAST_DCACHE_ADDR;
  126. +
  127. + for (set = start_set; set < end_set; set += (0x10 - 3))
  128. + asm volatile("cpushl %%dc,(%0)\n"
  129. + "\taddq%.l #1,%0\n"
  130. + "\tcpushl %%dc,(%0)\n"
  131. + "\taddq%.l #1,%0\n"
  132. + "\tcpushl %%dc,(%0)\n"
  133. + "\taddq%.l #1,%0\n"
  134. + "\tcpushl %%dc,(%0)" : : "a" (set));
  135. +}
  136. +
  137. +
  138. +
  139. +/******************************************************************************
  140. + * Routine to cleanly flush the a block of cache, pushing all relevant lines
  141. + * and invalidating them.
  142. + *
  143. + ******************************************************************************/
  144. +void DcacheFlushInvalidateCacheBlock(void *start, unsigned long size)
  145. +{
  146. + unsigned long set;
  147. + unsigned long start_set;
  148. + unsigned long end_set;
  149. +
  150. + /* if size is bigger than the cache can store
  151. + * set the size to the maximum amount
  152. + */
  153. +
  154. + if (size > LAST_DCACHE_ADDR)
  155. + size = LAST_DCACHE_ADDR;
  156. +
  157. + start_set = ((unsigned long)start) & _DCACHE_SET_MASK;
  158. + end_set = ((unsigned long)(start+size-1)) & _DCACHE_SET_MASK;
  159. +
  160. + if (start_set > end_set) {
  161. + /* from the begining to the lowest address */
  162. + for (set = 0; set <= end_set; set += (0x10 - 3))
  163. + asm volatile("cpushl %%dc,(%0)\n"
  164. + "\taddq%.l #1,%0\n"
  165. + "\tcpushl %%dc,(%0)\n"
  166. + "\taddq%.l #1,%0\n"
  167. + "\tcpushl %%dc,(%0)\n"
  168. + "\taddq%.l #1,%0\n"
  169. + "\tcpushl %%dc,(%0)" : : "a" (set));
  170. +
  171. + /* next loop will finish the cache ie pass the hole */
  172. + end_set = LAST_DCACHE_ADDR;
  173. + }
  174. + for (set = start_set; set <= end_set; set += (0x10 - 3))
  175. + asm volatile("cpushl %%dc,(%0)\n"
  176. + "\taddq%.l #1,%0\n"
  177. + "\tcpushl %%dc,(%0)\n"
  178. + "\taddq%.l #1,%0\n"
  179. + "\tcpushl %%dc,(%0)\n"
  180. + "\taddq%.l #1,%0\n"
  181. + "\tcpushl %%dc,(%0)" : : "a" (set));
  182. +}
  183. +
  184. +
  185. +void IcacheInvalidateCacheBlock(void *start, unsigned long size)
  186. +{
  187. + unsigned long set;
  188. + unsigned long start_set;
  189. + unsigned long end_set;
  190. +
  191. + /* if size is bigger than the cache can store
  192. + * set the size to the maximum ammount
  193. + */
  194. +
  195. + if (size > LAST_ICACHE_ADDR)
  196. + size = LAST_ICACHE_ADDR;
  197. +
  198. + start_set = ((unsigned long)start) & _ICACHE_SET_MASK;
  199. + end_set = ((unsigned long)(start+size-1)) & _ICACHE_SET_MASK;
  200. +
  201. + if (start_set > end_set) {
  202. + /* from the begining to the lowest address */
  203. + for (set = 0; set <= end_set; set += (0x10 - 3))
  204. + asm volatile("cpushl %%ic,(%0)\n"
  205. + "\taddq%.l #1,%0\n"
  206. + "\tcpushl %%ic,(%0)\n"
  207. + "\taddq%.l #1,%0\n"
  208. + "\tcpushl %%ic,(%0)\n"
  209. + "\taddq%.l #1,%0\n"
  210. + "\tcpushl %%ic,(%0)" : : "a" (set));
  211. +
  212. + /* next loop will finish the cache ie pass the hole */
  213. + end_set = LAST_ICACHE_ADDR;
  214. + }
  215. + for (set = start_set; set <= end_set; set += (0x10 - 3))
  216. + asm volatile("cpushl %%ic,(%0)\n"
  217. + "\taddq%.l #1,%0\n"
  218. + "\tcpushl %%ic,(%0)\n"
  219. + "\taddq%.l #1,%0\n"
  220. + "\tcpushl %%ic,(%0)\n"
  221. + "\taddq%.l #1,%0\n"
  222. + "\tcpushl %%ic,(%0)" : : "a" (set));
  223. +}
  224. +
  225. +
  226. +/********************************************************************
  227. + * Disable the data cache completely
  228. + ********************************************************************/
  229. +void DcacheDisable(void)
  230. +{
  231. + int newValue;
  232. + unsigned long flags;
  233. +
  234. + local_save_flags(flags);
  235. + local_irq_disable();
  236. +
  237. + DcacheFlushInvalidate(); /* begin by flushing the cache */
  238. + newValue = CACHE_DISABLE_MODE; /* disable it */
  239. + cacr_set(newValue);
  240. + local_irq_restore(flags);
  241. +}
  242. +
  243. +/********************************************************************
  244. + * Unconditionally enable the data cache
  245. + ********************************************************************/
  246. +void DcacheEnable(void)
  247. +{
  248. + cacr_set(CACHE_INITIAL_MODE);
  249. +}
  250. +
  251. +
  252. +unsigned long shadow_cacr;
  253. +
  254. +void cacr_set(unsigned long x)
  255. +{
  256. + shadow_cacr = x;
  257. +
  258. + __asm__ __volatile__ ("movec %0, %%cacr"
  259. + : /* no outputs */
  260. + : "r" (shadow_cacr));
  261. +}
  262. +
  263. +unsigned long cacr_get(void)
  264. +{
  265. + return shadow_cacr;
  266. +}
  267. --- /dev/null
  268. +++ b/arch/m68k/coldfire/config.c
  269. @@ -0,0 +1,420 @@
  270. +/*
  271. + * linux/arch/m68k/coldifre/config.c
  272. + *
  273. + * Matt Waddel [email protected]
  274. + * Copyright Freescale Semiconductor, Inc. 2007
  275. + *
  276. + * This program is free software; you can redistribute it and/or modify
  277. + * it under the terms of the GNU General Public License as published by
  278. + * the Free Software Foundation; either version 2 of the License, or
  279. + * (at your option) any later version.
  280. + */
  281. +
  282. +#include <linux/module.h>
  283. +#include <linux/init.h>
  284. +#include <linux/string.h>
  285. +#include <linux/kernel.h>
  286. +#include <linux/console.h>
  287. +#include <linux/bootmem.h>
  288. +#include <linux/mm.h>
  289. +#include <asm/bootinfo.h>
  290. +#include <asm/machdep.h>
  291. +#include <asm/coldfire.h>
  292. +#include <asm/cfcache.h>
  293. +#include <asm/bootinfo.h>
  294. +#include <asm/io.h>
  295. +#include <asm/cfmmu.h>
  296. +#include <asm/setup.h>
  297. +#include <asm/irq.h>
  298. +#include <asm/traps.h>
  299. +#include <asm/movs.h>
  300. +#include <asm/movs.h>
  301. +#include <asm/page.h>
  302. +#include <asm/pgalloc.h>
  303. +#include <asm/mcf5445x_intc.h>
  304. +#include <asm/mcf5445x_sdramc.h>
  305. +#include <asm/mcf5445x_fbcs.h>
  306. +#include <asm/mcf5445x_dtim.h>
  307. +
  308. +/* JKM -- testing */
  309. +#include <linux/pfn.h>
  310. +/* JKM */
  311. +
  312. +extern int get_irq_list(struct seq_file *p, void *v);
  313. +extern char _text, _end;
  314. +extern char _etext, _edata, __init_begin, __init_end;
  315. +extern struct console mcfrs_console;
  316. +extern char m68k_command_line[CL_SIZE];
  317. +extern unsigned long availmem;
  318. +
  319. +static int irq_enable[NR_IRQS];
  320. +unsigned long num_pages;
  321. +
  322. +void coldfire_sort_memrec(void)
  323. +{
  324. + int i, j;
  325. +
  326. + /* Sort the m68k_memory records by address */
  327. + for (i = 0; i < m68k_num_memory; ++i) {
  328. + for (j = i + 1; j < m68k_num_memory; ++j) {
  329. + if (m68k_memory[i].addr > m68k_memory[j].addr) {
  330. + struct mem_info tmp;
  331. + tmp = m68k_memory[i];
  332. + m68k_memory[i] = m68k_memory[j];
  333. + m68k_memory[j] = tmp;
  334. + }
  335. + }
  336. + }
  337. + /* Trim off discontiguous bits */
  338. + for (i = 1; i < m68k_num_memory; ++i) {
  339. + if ((m68k_memory[i-1].addr + m68k_memory[i-1].size) !=
  340. + m68k_memory[i].addr) {
  341. + printk(KERN_DEBUG "m68k_parse_bootinfo: addr gap between \
  342. + 0x%lx & 0x%lx\n",
  343. + m68k_memory[i-1].addr+m68k_memory[i-1].size,
  344. + m68k_memory[i].addr);
  345. + m68k_num_memory = i;
  346. + break;
  347. + }
  348. + }
  349. +}
  350. +
  351. +int __init uboot_commandline(char *bootargs)
  352. +{
  353. + int len = 0, cmd_line_len;
  354. + static struct uboot_record uboot_info;
  355. +
  356. + extern unsigned long uboot_info_stk;
  357. +
  358. + /* Add 0x80000000 to get post-remapped kernel memory location */
  359. + uboot_info.bd_info = (*(u32 *)(uboot_info_stk)) + 0x80000000;
  360. + uboot_info.initrd_start = (*(u32 *)(uboot_info_stk+4)) + 0x80000000;
  361. + uboot_info.initrd_end = (*(u32 *)(uboot_info_stk+8)) + 0x80000000;
  362. + uboot_info.cmd_line_start = (*(u32 *)(uboot_info_stk+12)) + 0x80000000;
  363. + uboot_info.cmd_line_stop = (*(u32 *)(uboot_info_stk+16)) + 0x80000000;
  364. +
  365. + cmd_line_len = uboot_info.cmd_line_stop - uboot_info.cmd_line_start;
  366. + if ((cmd_line_len > 0) && (cmd_line_len < CL_SIZE-1))
  367. + len = (int)strncpy(bootargs, (char *)uboot_info.cmd_line_start,\
  368. + cmd_line_len);
  369. +
  370. + return len;
  371. +}
  372. +
  373. +/*
  374. + * This routine does things not done in the bootloader.
  375. + */
  376. +#define DEFAULT_COMMAND_LINE "root=/dev/mtdblock1 rw rootfstype=jffs2 ip=none mtdparts=physmap-flash.0:5M(kernel)ro,-(jffs2)"
  377. +asmlinkage void __init cf_early_init(void)
  378. +{
  379. + struct bi_record *record = (struct bi_record *) &_end;
  380. +
  381. + extern char _end;
  382. +
  383. + SET_VBR((void *)MCF_RAMBAR1);
  384. +
  385. + /* Mask all interrupts */
  386. + MCF_INTC0_IMRL = 0xFFFFFFFF;
  387. + MCF_INTC0_IMRH = 0xFFFFFFFF;
  388. + MCF_INTC1_IMRL = 0xFFFFFFFF;
  389. + MCF_INTC1_IMRH = 0xFFFFFFFF;
  390. +
  391. +#if defined(CONFIG_NOR_FLASH_BASE)
  392. + MCF_FBCS_CSAR(1) = CONFIG_NOR_FLASH_BASE;
  393. +#else
  394. + MCF_FBCS_CSAR(1) = 0x00000000;
  395. +#endif
  396. +
  397. +#if CONFIG_SDRAM_SIZE > (256*1024*1024)
  398. + /* Init optional SDRAM chip select */
  399. + MCF_SDRAMC_SDCS(1) = (256*1024*1024) | 0x1B;
  400. +#endif
  401. +
  402. + m68k_machtype = MACH_CFMMU;
  403. + m68k_fputype = FPU_CFV4E;
  404. + m68k_mmutype = MMU_CFV4E;
  405. + m68k_cputype = CPU_CFV4E;
  406. +
  407. + m68k_num_memory = 0;
  408. + m68k_memory[m68k_num_memory].addr = CONFIG_SDRAM_BASE;
  409. + m68k_memory[m68k_num_memory++].size = CONFIG_SDRAM_SIZE;
  410. +
  411. + if (!uboot_commandline(m68k_command_line)) {
  412. +#if defined(CONFIG_BOOTPARAM)
  413. + strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE-1);
  414. +#else
  415. + strcpy(m68k_command_line, DEFAULT_COMMAND_LINE);
  416. +#endif
  417. + }
  418. +
  419. +
  420. +#if defined(CONFIG_BLK_DEV_INITRD)
  421. + /* add initrd image */
  422. + record = (struct bi_record *) ((void *)record + record->size);
  423. + record->tag = BI_RAMDISK;
  424. + record->size = sizeof(record->tag) + sizeof(record->size)
  425. + + sizeof(record->data[0]) + sizeof(record->data[1]);
  426. +#endif
  427. +
  428. + /* Mark end of tags. */
  429. + record = (struct bi_record *) ((void *) record + record->size);
  430. + record->tag = 0;
  431. + record->data[0] = 0;
  432. + record->data[1] = 0;
  433. + record->size = sizeof(record->tag) + sizeof(record->size)
  434. + + sizeof(record->data[0]) + sizeof(record->data[1]);
  435. +
  436. + /* Invalidate caches via CACR */
  437. + cacr_set(CACHE_DISABLE_MODE);
  438. +
  439. + /* Turn on caches via CACR, enable EUSP */
  440. + cacr_set(CACHE_INITIAL_MODE);
  441. +}
  442. +
  443. +void settimericr(unsigned int timer, unsigned int level)
  444. +{
  445. + volatile unsigned char *icrp;
  446. + unsigned int icr;
  447. + unsigned char irq;
  448. +
  449. + if (timer <= 2) {
  450. + switch (timer) {
  451. + case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
  452. + default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
  453. + }
  454. +
  455. + icrp = (volatile unsigned char *) (icr);
  456. + *icrp = level;
  457. + coldfire_enable_irq0(irq);
  458. + }
  459. +}
  460. +
  461. +/* Assembler routines */
  462. +asmlinkage void buserr(void);
  463. +asmlinkage void trap(void);
  464. +asmlinkage void system_call(void);
  465. +asmlinkage void inthandler(void);
  466. +
  467. +void __init coldfire_trap_init(void)
  468. +{
  469. + int i = 0;
  470. + e_vector *vectors;
  471. +
  472. + vectors = (e_vector *)MCF_RAMBAR1;
  473. + /*
  474. + * There is a common trap handler and common interrupt
  475. + * handler that handle almost every vector. We treat
  476. + * the system call and bus error special, they get their
  477. + * own first level handlers.
  478. + */
  479. + for (i = 3; (i <= 23); i++)
  480. + vectors[i] = trap;
  481. + for (i = 33; (i <= 63); i++)
  482. + vectors[i] = trap;
  483. + for (i = 24; (i <= 31); i++)
  484. + vectors[i] = inthandler;
  485. + for (i = 64; (i < 255); i++)
  486. + vectors[i] = inthandler;
  487. +
  488. + vectors[255] = 0;
  489. + vectors[2] = buserr;
  490. + vectors[32] = system_call;
  491. +}
  492. +
  493. +void coldfire_tick(void)
  494. +{
  495. + /* Reset the ColdFire timer */
  496. + __raw_writeb(MCF_DTIM_DTER_CAP | MCF_DTIM_DTER_REF, MCF_DTIM0_DTER);
  497. +}
  498. +
  499. +void __init coldfire_sched_init(irq_handler_t handler)
  500. +{
  501. + unsigned int mcf_timerlevel = 5;
  502. + unsigned int mcf_timervector = 64+32;
  503. +
  504. + __raw_writew(MCF_DTIM_DTMR_RST_RST, MCF_DTIM0_DTMR);
  505. + __raw_writel(((MCF_BUSCLK / 16) / HZ), MCF_DTIM0_DTRR);
  506. + __raw_writew(MCF_DTIM_DTMR_ORRI | MCF_DTIM_DTMR_CLK_DIV16 |
  507. + MCF_DTIM_DTMR_FRR | MCF_DTIM_DTMR_RST_EN, \
  508. + MCF_DTIM0_DTMR);
  509. +
  510. + request_irq(mcf_timervector, handler, SA_INTERRUPT, \
  511. + "timer", (void *)MCF_DTIM0_DTMR);
  512. +
  513. + settimericr(1, mcf_timerlevel);
  514. +}
  515. +
  516. +int timerirqpending(int timer)
  517. +{
  518. + unsigned int imr = 0;
  519. +
  520. + switch (timer) {
  521. + case 1: imr = 0x1; break;
  522. + case 2: imr = 0x2; break;
  523. + default: break;
  524. + }
  525. +
  526. + return (getiprh() & imr);
  527. +}
  528. +
  529. +unsigned long coldfire_gettimeoffset(void)
  530. +{
  531. + volatile unsigned long trr, tcn, offset;
  532. +
  533. + tcn = __raw_readw(MCF_DTIM0_DTCN);
  534. + trr = __raw_readl(MCF_DTIM0_DTRR);
  535. + offset = (tcn * (1000000 / HZ)) / trr;
  536. +
  537. + /* Check if we just wrapped the counters and maybe missed a tick */
  538. + if ((offset < (1000000 / HZ / 2)) && timerirqpending(1))
  539. + offset += 1000000 / HZ;
  540. + return offset;
  541. +}
  542. +
  543. +void coldfire_reboot(void)
  544. +{
  545. + /* disable interrupts and do a software reset */
  546. + asm("movew #0x2700, %%sr\n\t"
  547. + "moveb #0x80, %%d0\n\t"
  548. + "moveb %%d0, 0xfc0a0000\n\t"
  549. + : : : "%d0");
  550. +}
  551. +
  552. +/* int coldfire_hwclk(int i, struct rtc_time *t)
  553. +{
  554. + printk ("Real time clock needs porting.\n");
  555. + return 0;
  556. +}*/
  557. +
  558. +static void coldfire_get_model(char *model)
  559. +{
  560. + sprintf(model, "Version 4 ColdFire");
  561. +}
  562. +
  563. +void coldfire_enable_irq(unsigned int vec)
  564. +{
  565. + unsigned long flags;
  566. +
  567. + vec -= 64;
  568. +
  569. + if (((int)vec < 0) || (vec > 63)) {
  570. + printk(KERN_WARNING "enable_irq %d failed\n", vec);
  571. + return;
  572. + }
  573. +
  574. + local_irq_save(flags);
  575. + irq_enable[vec]++;
  576. + if (vec < 32)
  577. + MCF_INTC0_IMRL &= ~(1 << vec);
  578. + else
  579. + MCF_INTC0_IMRH &= ~(1 << (vec - 32));
  580. + local_irq_restore(flags);
  581. +}
  582. +
  583. +void coldfire_disable_irq(unsigned int vec)
  584. +{
  585. + unsigned long flags;
  586. +
  587. + vec -= 64;
  588. +
  589. + if (((int)vec < 0) || (vec > 63)) {
  590. + printk(KERN_WARNING "disable_irq %d failed\n", vec);
  591. + return;
  592. + }
  593. +
  594. + local_irq_save(flags);
  595. + if (--irq_enable[vec] == 0) {
  596. + if (vec < 32)
  597. + MCF_INTC0_IMRL |= (1 << vec);
  598. + else
  599. + MCF_INTC0_IMRH |= (1 << (vec - 32));
  600. +
  601. + }
  602. + local_irq_restore(flags);
  603. +}
  604. +
  605. +static void __init
  606. +coldfire_bootmem_alloc(unsigned long memory_start, unsigned long memory_end)
  607. +{
  608. + unsigned long base_pfn;
  609. +
  610. + /* compute total pages in system */
  611. + num_pages = PAGE_ALIGN(memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
  612. +
  613. + /* align start/end to page boundries */
  614. + memory_start = PAGE_ALIGN(memory_start);
  615. + memory_end = memory_end & PAGE_MASK;
  616. +
  617. + /* page numbers */
  618. + base_pfn = __pa(PAGE_OFFSET) >> PAGE_SHIFT;
  619. + min_low_pfn = __pa(memory_start) >> PAGE_SHIFT;
  620. + max_low_pfn = __pa(memory_end) >> PAGE_SHIFT;
  621. +
  622. + high_memory = (void *)memory_end;
  623. + availmem = memory_start;
  624. +
  625. + /* setup bootmem data */
  626. + m68k_setup_node(0);
  627. + availmem += init_bootmem_node(NODE_DATA(0), min_low_pfn,
  628. + base_pfn, max_low_pfn);
  629. + availmem = PAGE_ALIGN(availmem);
  630. + free_bootmem(__pa(availmem), memory_end - (availmem));
  631. +}
  632. +
  633. +void __init config_coldfire(void)
  634. +{
  635. + unsigned long endmem, startmem;
  636. + int i;
  637. +
  638. + /*
  639. + * Calculate endmem from m68k_memory, assume all are contiguous
  640. + */
  641. + startmem = ((((int) &_end) + (PAGE_SIZE - 1)) & PAGE_MASK);
  642. + endmem = PAGE_OFFSET;
  643. + for (i = 0; i < m68k_num_memory; ++i)
  644. + endmem += m68k_memory[i].size;
  645. +
  646. + printk(KERN_INFO "starting up linux startmem 0x%lx, endmem 0x%lx, \
  647. + size %luMB\n", startmem, endmem, (endmem - startmem) >> 20);
  648. +
  649. + memset(irq_enable, 0, sizeof(irq_enable));
  650. +
  651. + /*
  652. + * Setup coldfire mach-specific handlers
  653. + */
  654. + mach_max_dma_address = 0xffffffff;
  655. + mach_sched_init = coldfire_sched_init;
  656. + mach_tick = coldfire_tick;
  657. + mach_gettimeoffset = coldfire_gettimeoffset;
  658. + mach_reset = coldfire_reboot;
  659. +/* mach_hwclk = coldfire_hwclk; to be done */
  660. + mach_get_model = coldfire_get_model;
  661. +
  662. + coldfire_bootmem_alloc(startmem, endmem);
  663. +
  664. + /*
  665. + * initrd setup
  666. + */
  667. +/* #ifdef CONFIG_BLK_DEV_INITRD
  668. + if (m68k_ramdisk.size) {
  669. + reserve_bootmem (__pa(m68k_ramdisk.addr), m68k_ramdisk.size);
  670. + initrd_start = (unsigned long) m68k_ramdisk.addr;
  671. + initrd_end = initrd_start + m68k_ramdisk.size;
  672. + printk (KERN_DEBUG "initrd: %08lx - %08lx\n", initrd_start,
  673. + initrd_end);
  674. + }
  675. +#endif */
  676. +
  677. +#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_FRAMEBUFFER_CONSOLE)
  678. + conswitchp = &dummy_con;
  679. +#endif
  680. +
  681. +#if defined(CONFIG_SERIAL_COLDFIRE)
  682. + /*
  683. + * This causes trouble when it is re-registered later.
  684. + * Currently this is fixed by conditionally commenting
  685. + * out the register_console in mcf_serial.c
  686. + */
  687. + register_console(&mcfrs_console);
  688. +#endif
  689. +}
  690. --- /dev/null
  691. +++ b/arch/m68k/coldfire/entry.S
  692. @@ -0,0 +1,701 @@
  693. +/*
  694. + * arch/m68k/coldfire/entry.S
  695. + *
  696. + * Copyright (C) 1999-2002, Greg Ungerer ([email protected])
  697. + * Copyright (C) 1998 D. Jeff Dionne <[email protected]>,
  698. + * Kenneth Albanowski <[email protected]>,
  699. + * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
  700. + * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com)
  701. + * Matt Waddel [email protected]
  702. + * Kurt Mahan [email protected]
  703. + * Copyright Freescale Semiconductor, Inc. 2007
  704. + *
  705. + * Based on:
  706. + *
  707. + * arch/m68knommu/platform/5307/entry.S &
  708. + * arch/m68k/kernel/entry.S
  709. + *
  710. + * Copyright (C) 1991, 1992 Linus Torvalds
  711. + *
  712. + * This file is subject to the terms and conditions of the GNU General Public
  713. + * License. See the file README.legal in the main directory of this archive
  714. + * for more details.
  715. + *
  716. + * Linux/m68k support by Hamish Macdonald
  717. + *
  718. + * ColdFire support by Greg Ungerer ([email protected])
  719. + * 5307 fixes by David W. Miller
  720. + * linux 2.4 support David McCullough <[email protected]>
  721. + * Bug, speed and maintainability fixes by Philippe De Muyter <[email protected]>
  722. + * Ported to mmu Coldfire by Matt Waddel
  723. + */
  724. +
  725. +#include <linux/sys.h>
  726. +#include <linux/linkage.h>
  727. +#include <asm/cf_entry.h>
  728. +#include <asm/errno.h>
  729. +#include <asm/setup.h>
  730. +#include <asm/segment.h>
  731. +#include <asm/traps.h>
  732. +#include <asm/unistd.h>
  733. +
  734. +/*
  735. + * TASK_INFO:
  736. + *
  737. + * - TINFO_PREEMPT (struct thread_info / preempt_count)
  738. + * Used to keep track of preemptability
  739. + * - TINFO_FLAGS (struct thread_info / flags - include/asm-m68k/thread_info.h)
  740. + * Various bit flags that are checked for scheduling/tracing
  741. + * Bits 0-7 are checked every exception exit
  742. + * 8-15 are checked every syscall exit
  743. + *
  744. + * TIF_SIGPENDING 6
  745. + * TIF_NEED_RESCHED 7
  746. + * TIF_DELAYED_TRACE 14
  747. + * TIF_SYSCALL_TRACE 15
  748. + * TIF_MEMDIE 16 (never checked here)
  749. + */
  750. +
  751. +.bss
  752. +
  753. +sw_ksp:
  754. +.long 0
  755. +
  756. +sw_usp:
  757. +.long 0
  758. +
  759. +.text
  760. +
  761. +.globl system_call
  762. +.globl buserr
  763. +.globl trap
  764. +.globl resume
  765. +.globl ret_from_exception
  766. +.globl ret_from_signal
  767. +.globl sys_call_table
  768. +.globl ret_from_interrupt
  769. +.globl inthandler
  770. +
  771. +ENTRY(buserr)
  772. + SAVE_ALL_INT
  773. + GET_CURRENT(%d0)
  774. + movel %sp,%sp@- /* stack frame pointer argument */
  775. + jsr buserr_c
  776. + addql #4,%sp
  777. + jra .Lret_from_exception
  778. +
  779. +ENTRY(trap)
  780. + SAVE_ALL_INT
  781. + GET_CURRENT(%d0)
  782. + movel %sp,%sp@- /* stack frame pointer argument */
  783. + jsr trap_c
  784. + addql #4,%sp
  785. + jra .Lret_from_exception
  786. +
  787. + /* After a fork we jump here directly from resume,
  788. + %d1 contains the previous task schedule_tail */
  789. +ENTRY(ret_from_fork)
  790. + movel %d1,%sp@-
  791. + jsr schedule_tail
  792. + addql #4,%sp
  793. + jra .Lret_from_exception
  794. +
  795. +do_trace_entry:
  796. + movel #-ENOSYS,%d1 /* needed for strace */
  797. + movel %d1,%sp@(PT_D0)
  798. + subql #4,%sp
  799. + SAVE_SWITCH_STACK
  800. + jbsr syscall_trace
  801. + RESTORE_SWITCH_STACK
  802. + addql #4,%sp
  803. + movel %sp@(PT_ORIG_D0),%d0
  804. + cmpl #NR_syscalls,%d0
  805. + jcs syscall
  806. +badsys:
  807. + movel #-ENOSYS,%d1
  808. + movel %d1,%sp@(PT_D0)
  809. + jra ret_from_exception
  810. +
  811. +do_trace_exit:
  812. + subql #4,%sp
  813. + SAVE_SWITCH_STACK
  814. + jbsr syscall_trace
  815. + RESTORE_SWITCH_STACK
  816. + addql #4,%sp
  817. + jra .Lret_from_exception
  818. +
  819. +ENTRY(ret_from_signal)
  820. + RESTORE_SWITCH_STACK
  821. + addql #4,%sp
  822. + jra .Lret_from_exception
  823. +
  824. +ENTRY(system_call)
  825. + SAVE_ALL_SYS
  826. +
  827. + GET_CURRENT(%d1)
  828. + /* save top of frame */
  829. + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
  830. +
  831. + /* syscall trace */
  832. + tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
  833. + jmi do_trace_entry /* SYSCALL_TRACE is set */
  834. + cmpl #NR_syscalls,%d0
  835. + jcc badsys
  836. +syscall:
  837. + movel #sys_call_table,%a0
  838. + asll #2,%d0
  839. + addl %d0,%a0
  840. + movel %a0@,%a0
  841. + jsr %a0@
  842. + movel %d0,%sp@(PT_D0) /* save the return value */
  843. +ret_from_syscall:
  844. + movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
  845. + jne syscall_exit_work /* flags set so process */
  846. +1: RESTORE_ALL
  847. +
  848. +syscall_exit_work:
  849. + btst #5,%sp@(PT_SR) /* check if returning to kernel */
  850. + bnes 1b /* if so, skip resched, signals */
  851. +
  852. + btstl #15,%d0 /* check if SYSCALL_TRACE */
  853. + jne do_trace_exit
  854. + btstl #14,%d0 /* check if DELAYED_TRACE */
  855. + jne do_delayed_trace
  856. + btstl #6,%d0 /* check if SIGPENDING */
  857. + jne do_signal_return
  858. + pea resume_userspace
  859. + jra schedule
  860. +
  861. +ENTRY(ret_from_exception)
  862. +.Lret_from_exception:
  863. + btst #5,%sp@(PT_SR) /* check if returning to kernel */
  864. + bnes 1f /* if so, skip resched, signals */
  865. + movel %d0,%sp@- /* Only allow interrupts when we are */
  866. + move %sr,%d0 /* last one on the kernel stack, */
  867. + andl #ALLOWINT,%d0 /* otherwise stack overflow can occur */
  868. + move %d0,%sr /* during heavy interrupt load. */
  869. + movel %sp@+,%d0
  870. +
  871. +resume_userspace:
  872. + moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
  873. + jne exit_work /* SIGPENDING and/or NEED_RESCHED set */
  874. +1: RESTORE_ALL
  875. +
  876. +exit_work:
  877. + /* save top of frame */
  878. + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
  879. + btstl #6,%d0 /* check for SIGPENDING in flags */
  880. + jne do_signal_return
  881. + pea resume_userspace
  882. + jra schedule
  883. +
  884. +do_signal_return:
  885. + subql #4,%sp /* dummy return address */
  886. + SAVE_SWITCH_STACK
  887. + pea %sp@(SWITCH_STACK_SIZE)
  888. + clrl %sp@-
  889. + bsrl do_signal
  890. + addql #8,%sp
  891. + RESTORE_SWITCH_STACK
  892. + addql #4,%sp
  893. + jbra resume_userspace
  894. +
  895. +do_delayed_trace:
  896. + bclr #7,%sp@(PT_SR) /* clear trace bit in SR */
  897. + pea 1 /* send SIGTRAP */
  898. + movel %curptr,%sp@-
  899. + pea LSIGTRAP
  900. + jbsr send_sig
  901. + addql #8,%sp
  902. + addql #4,%sp
  903. + jbra resume_userspace
  904. +
  905. +/*
  906. + * This is the interrupt handler (for all hardware interrupt
  907. + * sources). It figures out the vector number and calls the appropriate
  908. + * interrupt service routine directly.
  909. + */
  910. +ENTRY(inthandler)
  911. + SAVE_ALL_INT
  912. + GET_CURRENT(%d0)
  913. + addql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
  914. + /* put exception # in d0 */
  915. + movel %sp@(PT_VECTOR),%d0
  916. + swap %d0 /* extract bits 25:18 */
  917. + lsrl #2,%d0
  918. + andl #0x0ff,%d0
  919. +
  920. + movel %sp,%sp@-
  921. + movel %d0,%sp@- /* put vector # on stack */
  922. +auto_irqhandler_fixup = . + 2
  923. + jbsr process_int /* process the IRQ */
  924. + addql #8,%sp /* pop parameters off stack */
  925. +
  926. +ENTRY(ret_from_interrupt)
  927. +ret_from_interrupt:
  928. +
  929. + subql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
  930. + jeq ret_from_last_interrupt
  931. +2: RESTORE_ALL
  932. +
  933. + ALIGN
  934. +ret_from_last_interrupt:
  935. + moveb %sp@(PT_SR),%d0
  936. + andl #(~ALLOWINT>>8)&0xff,%d0
  937. + jne 2b
  938. +
  939. + /* check if we need to do software interrupts */
  940. + tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
  941. + jeq .Lret_from_exception
  942. + pea ret_from_exception
  943. + jra do_softirq
  944. +
  945. +ENTRY(user_inthandler)
  946. + SAVE_ALL_INT
  947. + GET_CURRENT(%d0)
  948. + addql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
  949. + /* put exception # in d0 */
  950. + movel %sp@(PT_VECTOR),%d0
  951. +user_irqvec_fixup = . + 2
  952. + swap %d0 /* extract bits 25:18 */
  953. + lsrl #2,%d0
  954. + andl #0x0ff,%d0
  955. +
  956. + movel %sp,%sp@-
  957. + movel %d0,%sp@- /* put vector # on stack */
  958. +user_irqhandler_fixup = . + 2
  959. + jbsr process_int /* process the IRQ */
  960. + addql #8,%sp /* pop parameters off stack */
  961. +
  962. + subql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
  963. + jeq ret_from_last_interrupt
  964. + RESTORE_ALL
  965. +
  966. +/* Handler for uninitialized and spurious interrupts */
  967. +
  968. +ENTRY(bad_inthandler)
  969. + SAVE_ALL_INT
  970. + GET_CURRENT(%d0)
  971. + addql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
  972. +
  973. + movel %sp,%sp@-
  974. + jsr handle_badint
  975. + addql #4,%sp
  976. +
  977. + subql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
  978. + jeq ret_from_last_interrupt
  979. + RESTORE_ALL
  980. +
  981. +ENTRY(sys_fork)
  982. + SAVE_SWITCH_STACK
  983. + pea %sp@(SWITCH_STACK_SIZE)
  984. + jbsr m68k_fork
  985. + addql #4,%sp
  986. + RESTORE_SWITCH_STACK
  987. + rts
  988. +
  989. +ENTRY(sys_clone)
  990. + SAVE_SWITCH_STACK
  991. + pea %sp@(SWITCH_STACK_SIZE)
  992. + jbsr m68k_clone
  993. + addql #4,%sp
  994. + RESTORE_SWITCH_STACK
  995. + rts
  996. +
  997. +ENTRY(sys_vfork)
  998. + SAVE_SWITCH_STACK
  999. + pea %sp@(SWITCH_STACK_SIZE)
  1000. + jbsr m68k_vfork
  1001. + addql #4,%sp
  1002. + RESTORE_SWITCH_STACK
  1003. + rts
  1004. +
  1005. +ENTRY(sys_sigsuspend)
  1006. + SAVE_SWITCH_STACK
  1007. + pea %sp@(SWITCH_STACK_SIZE)
  1008. + jbsr do_sigsuspend
  1009. + addql #4,%sp
  1010. + RESTORE_SWITCH_STACK
  1011. + rts
  1012. +
  1013. +ENTRY(sys_rt_sigsuspend)
  1014. + SAVE_SWITCH_STACK
  1015. + pea %sp@(SWITCH_STACK_SIZE)
  1016. + jbsr do_rt_sigsuspend
  1017. + addql #4,%sp
  1018. + RESTORE_SWITCH_STACK
  1019. + rts
  1020. +
  1021. +ENTRY(sys_sigreturn)
  1022. + SAVE_SWITCH_STACK
  1023. + jbsr do_sigreturn
  1024. + RESTORE_SWITCH_STACK
  1025. + rts
  1026. +
  1027. +ENTRY(sys_rt_sigreturn)
  1028. + SAVE_SWITCH_STACK
  1029. + jbsr do_rt_sigreturn
  1030. + RESTORE_SWITCH_STACK
  1031. + rts
  1032. +
  1033. +resume:
  1034. + /*
  1035. + * Beware - when entering resume, prev (the current task) is
  1036. + * in a0, next (the new task) is in a1,so don't change these
  1037. + * registers until their contents are no longer needed.
  1038. + */
  1039. +
  1040. + /* save sr */
  1041. + movew %sr,%d0
  1042. + movew %d0,%a0@(TASK_THREAD+THREAD_SR)
  1043. +
  1044. + /* save usp */
  1045. + /* Save USP via %a1 (which is saved/restored from %d0) */
  1046. + movel %a1,%d0
  1047. + movel %usp,%a1
  1048. + movel %a1,%a0@(TASK_THREAD+THREAD_USP)
  1049. + movel %d0,%a1
  1050. +
  1051. + /* save non-scratch registers on stack */
  1052. + SAVE_SWITCH_STACK
  1053. +
  1054. + /* save current kernel stack pointer */
  1055. + movel %sp,%a0@(TASK_THREAD+THREAD_KSP)
  1056. +
  1057. + /* Return previous task in %d1 */
  1058. + movel %curptr,%d1
  1059. +
  1060. + /* switch to new task (a1 contains new task) */
  1061. + movel %a1,%curptr
  1062. +
  1063. + /* restore the kernel stack pointer */
  1064. + movel %a1@(TASK_THREAD+THREAD_KSP),%sp
  1065. +
  1066. + /* restore non-scratch registers */
  1067. + RESTORE_SWITCH_STACK
  1068. +
  1069. + /* restore user stack pointer */
  1070. + movel %a1@(TASK_THREAD+THREAD_USP),%a0
  1071. + movel %a0,%usp
  1072. +
  1073. + /* restore status register */
  1074. + movew %a1@(TASK_THREAD+THREAD_SR),%d0
  1075. + movew %d0,%sr
  1076. +
  1077. + rts
  1078. +
  1079. +.data
  1080. +ALIGN
  1081. +sys_call_table:
  1082. + .long sys_ni_syscall /* 0 - old "setup()" system call*/
  1083. + .long sys_exit
  1084. + .long sys_fork
  1085. + .long sys_read
  1086. + .long sys_write
  1087. + .long sys_open /* 5 */
  1088. + .long sys_close
  1089. + .long sys_waitpid
  1090. + .long sys_creat
  1091. + .long sys_link
  1092. + .long sys_unlink /* 10 */
  1093. + .long sys_execve
  1094. + .long sys_chdir
  1095. + .long sys_time
  1096. + .long sys_mknod
  1097. + .long sys_chmod /* 15 */
  1098. + .long sys_chown16
  1099. + .long sys_ni_syscall /* old break syscall holder */
  1100. + .long sys_stat
  1101. + .long sys_lseek
  1102. + .long sys_getpid /* 20 */
  1103. + .long sys_mount
  1104. + .long sys_oldumount
  1105. + .long sys_setuid16
  1106. + .long sys_getuid16
  1107. + .long sys_stime /* 25 */
  1108. + .long sys_ptrace
  1109. + .long sys_alarm
  1110. + .long sys_fstat
  1111. + .long sys_pause
  1112. + .long sys_utime /* 30 */
  1113. + .long sys_ni_syscall /* old stty syscall holder */
  1114. + .long sys_ni_syscall /* old gtty syscall holder */
  1115. + .long sys_access
  1116. + .long sys_nice
  1117. + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
  1118. + .long sys_sync
  1119. + .long sys_kill
  1120. + .long sys_rename
  1121. + .long sys_mkdir
  1122. + .long sys_rmdir /* 40 */
  1123. + .long sys_dup
  1124. + .long sys_pipe
  1125. + .long sys_times
  1126. + .long sys_ni_syscall /* old prof syscall holder */
  1127. + .long sys_brk /* 45 */
  1128. + .long sys_setgid16
  1129. + .long sys_getgid16
  1130. + .long sys_signal
  1131. + .long sys_geteuid16
  1132. + .long sys_getegid16 /* 50 */
  1133. + .long sys_acct
  1134. + .long sys_umount /* recycled never used phys() */
  1135. + .long sys_ni_syscall /* old lock syscall holder */
  1136. + .long sys_ioctl
  1137. + .long sys_fcntl /* 55 */
  1138. + .long sys_ni_syscall /* old mpx syscall holder */
  1139. + .long sys_setpgid
  1140. + .long sys_ni_syscall /* old ulimit syscall holder */
  1141. + .long sys_ni_syscall
  1142. + .long sys_umask /* 60 */
  1143. + .long sys_chroot
  1144. + .long sys_ustat
  1145. + .long sys_dup2
  1146. + .long sys_getppid
  1147. + .long sys_getpgrp /* 65 */
  1148. + .long sys_setsid
  1149. + .long sys_sigaction
  1150. + .long sys_sgetmask
  1151. + .long sys_ssetmask
  1152. + .long sys_setreuid16 /* 70 */
  1153. + .long sys_setregid16
  1154. + .long sys_sigsuspend
  1155. + .long sys_sigpending
  1156. + .long sys_sethostname
  1157. + .long sys_setrlimit /* 75 */
  1158. + .long sys_old_getrlimit
  1159. + .long sys_getrusage
  1160. + .long sys_gettimeofday
  1161. + .long sys_settimeofday
  1162. + .long sys_getgroups16 /* 80 */
  1163. + .long sys_setgroups16
  1164. + .long old_select
  1165. + .long sys_symlink
  1166. + .long sys_lstat
  1167. + .long sys_readlink /* 85 */
  1168. + .long sys_uselib
  1169. + .long sys_swapon
  1170. + .long sys_reboot
  1171. + .long old_readdir
  1172. + .long old_mmap /* 90 */
  1173. + .long sys_munmap
  1174. + .long sys_truncate
  1175. + .long sys_ftruncate
  1176. + .long sys_fchmod
  1177. + .long sys_fchown16 /* 95 */
  1178. + .long sys_getpriority
  1179. + .long sys_setpriority
  1180. + .long sys_ni_syscall /* old profil syscall holder */
  1181. + .long sys_statfs
  1182. + .long sys_fstatfs /* 100 */
  1183. + .long sys_ni_syscall /* ioperm for i386 */
  1184. + .long sys_socketcall
  1185. + .long sys_syslog
  1186. + .long sys_setitimer
  1187. + .long sys_getitimer /* 105 */
  1188. + .long sys_newstat
  1189. + .long sys_newlstat
  1190. + .long sys_newfstat
  1191. + .long sys_ni_syscall
  1192. + .long sys_ni_syscall /* 110 */ /* iopl for i386 */
  1193. + .long sys_vhangup
  1194. + .long sys_ni_syscall /* obsolete idle() syscall */
  1195. + .long sys_ni_syscall /* vm86old for i386 */
  1196. + .long sys_wait4
  1197. + .long sys_swapoff /* 115 */
  1198. + .long sys_sysinfo
  1199. + .long sys_ipc
  1200. + .long sys_fsync
  1201. + .long sys_sigreturn
  1202. + .long sys_clone /* 120 */
  1203. + .long sys_setdomainname
  1204. + .long sys_newuname
  1205. + .long sys_cacheflush /* modify_ldt for i386 */
  1206. + .long sys_adjtimex
  1207. + .long sys_mprotect /* 125 */
  1208. + .long sys_sigprocmask
  1209. + .long sys_ni_syscall /* old "create_module" */
  1210. + .long sys_init_module
  1211. + .long sys_delete_module
  1212. + .long sys_ni_syscall /* 130 - old "get_kernel_syms" */
  1213. + .long sys_quotactl
  1214. + .long sys_getpgid
  1215. + .long sys_fchdir
  1216. + .long sys_bdflush
  1217. + .long sys_sysfs /* 135 */
  1218. + .long sys_personality
  1219. + .long sys_ni_syscall /* for afs_syscall */
  1220. + .long sys_setfsuid16
  1221. + .long sys_setfsgid16
  1222. + .long sys_llseek /* 140 */
  1223. + .long sys_getdents
  1224. + .long sys_select
  1225. + .long sys_flock
  1226. + .long sys_msync
  1227. + .long sys_readv /* 145 */
  1228. + .long sys_writev
  1229. + .long sys_getsid
  1230. + .long sys_fdatasync
  1231. + .long sys_sysctl
  1232. + .long sys_mlock /* 150 */
  1233. + .long sys_munlock
  1234. + .long sys_mlockall
  1235. + .long sys_munlockall
  1236. + .long sys_sched_setparam
  1237. + .long sys_sched_getparam /* 155 */
  1238. + .long sys_sched_setscheduler
  1239. + .long sys_sched_getscheduler
  1240. + .long sys_sched_yield
  1241. + .long sys_sched_get_priority_max
  1242. + .long sys_sched_get_priority_min /* 160 */
  1243. + .long sys_sched_rr_get_interval
  1244. + .long sys_nanosleep
  1245. + .long sys_mremap
  1246. + .long sys_setresuid16
  1247. + .long sys_getresuid16 /* 165 */
  1248. + .long sys_getpagesize
  1249. + .long sys_ni_syscall /* old sys_query_module */
  1250. + .long sys_poll
  1251. + .long sys_nfsservctl
  1252. + .long sys_setresgid16 /* 170 */
  1253. + .long sys_getresgid16
  1254. + .long sys_prctl
  1255. + .long sys_rt_sigreturn
  1256. + .long sys_rt_sigaction
  1257. + .long sys_rt_sigprocmask /* 175 */
  1258. + .long sys_rt_sigpending
  1259. + .long sys_rt_sigtimedwait
  1260. + .long sys_rt_sigqueueinfo
  1261. + .long sys_rt_sigsuspend
  1262. + .long sys_pread64 /* 180 */
  1263. + .long sys_pwrite64
  1264. + .long sys_lchown16;
  1265. + .long sys_getcwd
  1266. + .long sys_capget
  1267. + .long sys_capset /* 185 */
  1268. + .long sys_sigaltstack
  1269. + .long sys_sendfile
  1270. + .long sys_ni_syscall /* streams1 */
  1271. + .long sys_ni_syscall /* streams2 */
  1272. + .long sys_vfork /* 190 */
  1273. + .long sys_getrlimit
  1274. + .long sys_mmap2
  1275. + .long sys_truncate64
  1276. + .long sys_ftruncate64
  1277. + .long sys_stat64 /* 195 */
  1278. + .long sys_lstat64
  1279. + .long sys_fstat64
  1280. + .long sys_chown
  1281. + .long sys_getuid
  1282. + .long sys_getgid /* 200 */
  1283. + .long sys_geteuid
  1284. + .long sys_getegid
  1285. + .long sys_setreuid
  1286. + .long sys_setregid
  1287. + .long sys_getgroups /* 205 */
  1288. + .long sys_setgroups
  1289. + .long sys_fchown
  1290. + .long sys_setresuid
  1291. + .long sys_getresuid
  1292. + .long sys_setresgid /* 210 */
  1293. + .long sys_getresgid
  1294. + .long sys_lchown
  1295. + .long sys_setuid
  1296. + .long sys_setgid
  1297. + .long sys_setfsuid /* 215 */
  1298. + .long sys_setfsgid
  1299. + .long sys_pivot_root
  1300. + .long sys_ni_syscall
  1301. + .long sys_ni_syscall
  1302. + .long sys_getdents64 /* 220 */
  1303. + .long sys_gettid
  1304. + .long sys_tkill
  1305. + .long sys_setxattr
  1306. + .long sys_lsetxattr
  1307. + .long sys_fsetxattr /* 225 */
  1308. + .long sys_getxattr
  1309. + .long sys_lgetxattr
  1310. + .long sys_fgetxattr
  1311. + .long sys_listxattr
  1312. + .long sys_llistxattr /* 230 */
  1313. + .long sys_flistxattr
  1314. + .long sys_removexattr
  1315. + .long sys_lremovexattr
  1316. + .long sys_fremovexattr
  1317. + .long sys_futex /* 235 */
  1318. + .long sys_sendfile64
  1319. + .long sys_mincore
  1320. + .long sys_madvise
  1321. + .long sys_fcntl64
  1322. + .long sys_readahead /* 240 */
  1323. + .long sys_io_setup
  1324. + .long sys_io_destroy
  1325. + .long sys_io_getevents
  1326. + .long sys_io_submit
  1327. + .long sys_io_cancel /* 245 */
  1328. + .long sys_fadvise64
  1329. + .long sys_exit_group
  1330. + .long sys_lookup_dcookie
  1331. + .long sys_epoll_create
  1332. + .long sys_epoll_ctl /* 250 */
  1333. + .long sys_epoll_wait
  1334. + .long sys_remap_file_pages
  1335. + .long sys_set_tid_address
  1336. + .long sys_timer_create
  1337. + .long sys_timer_settime /* 255 */
  1338. + .long sys_timer_gettime
  1339. + .long sys_timer_getoverrun
  1340. + .long sys_timer_delete
  1341. + .long sys_clock_settime
  1342. + .long sys_clock_gettime /* 260 */
  1343. + .long sys_clock_getres
  1344. + .long sys_clock_nanosleep
  1345. + .long sys_statfs64
  1346. + .long sys_fstatfs64
  1347. + .long sys_tgkill /* 265 */
  1348. + .long sys_utimes
  1349. + .long sys_fadvise64_64
  1350. + .long sys_mbind
  1351. + .long sys_get_mempolicy
  1352. + .long sys_set_mempolicy /* 270 */
  1353. + .long sys_mq_open
  1354. + .long sys_mq_unlink
  1355. + .long sys_mq_timedsend
  1356. + .long sys_mq_timedreceive
  1357. + .long sys_mq_notify /* 275 */
  1358. + .long sys_mq_getsetattr
  1359. + .long sys_waitid
  1360. + .long sys_ni_syscall /* for sys_vserver */
  1361. + .long sys_add_key
  1362. + .long sys_request_key /* 280 */
  1363. + .long sys_keyctl
  1364. + .long sys_ioprio_set
  1365. + .long sys_ioprio_get
  1366. + .long sys_inotify_init
  1367. + .long sys_inotify_add_watch /* 285 */
  1368. + .long sys_inotify_rm_watch
  1369. + .long sys_migrate_pages
  1370. + .long sys_openat
  1371. + .long sys_mkdirat
  1372. + .long sys_mknodat /* 290 */
  1373. + .long sys_fchownat
  1374. + .long sys_futimesat
  1375. + .long sys_fstatat64
  1376. + .long sys_unlinkat
  1377. + .long sys_renameat /* 295 */
  1378. + .long sys_linkat
  1379. + .long sys_symlinkat
  1380. + .long sys_readlinkat
  1381. + .long sys_fchmodat
  1382. + .long sys_faccessat /* 300 */
  1383. + .long sys_ni_syscall /* Reserved for pselect6 */
  1384. + .long sys_ni_syscall /* Reserved for ppoll */
  1385. + .long sys_unshare
  1386. + .long sys_set_robust_list
  1387. + .long sys_get_robust_list /* 305 */
  1388. + .long sys_splice
  1389. + .long sys_sync_file_range
  1390. + .long sys_tee
  1391. + .long sys_vmsplice
  1392. + .long sys_move_pages /* 310 */
  1393. +
  1394. --- /dev/null
  1395. +++ b/arch/m68k/coldfire/head.S
  1396. @@ -0,0 +1,474 @@
  1397. +/*
  1398. + * head.S is the MMU enabled ColdFire specific initial boot code
  1399. + *
  1400. + * Ported to ColdFire by
  1401. + * Matt Waddel [email protected]
  1402. + * Kurt Mahan [email protected]
  1403. + * Copyright Freescale Semiconductor, Inc. 2007
  1404. + *
  1405. + * This program is free software; you can redistribute it and/or modify
  1406. + * it under the terms of the GNU General Public License as published by
  1407. + * the Free Software Foundation; either version 2 of the License, or
  1408. + * (at your option) any later version.
  1409. + *
  1410. + * Parts of this code came from arch/m68k/kernel/head.S
  1411. + */
  1412. +#include <linux/linkage.h>
  1413. +#include <linux/init.h>
  1414. +#include <asm/bootinfo.h>
  1415. +#include <asm/setup.h>
  1416. +#include <asm/entry.h>
  1417. +#include <asm/pgtable.h>
  1418. +#include <asm/page.h>
  1419. +#include <asm/coldfire.h>
  1420. +#include <asm/mcfuart.h>
  1421. +#include <asm/cfcache.h>
  1422. +
  1423. +#define DEBUG
  1424. +
  1425. +.globl kernel_pg_dir
  1426. +.globl availmem
  1427. +.globl set_context
  1428. +.globl set_fpga
  1429. +
  1430. +#ifdef DEBUG
  1431. +/* When debugging use readable names for labels */
  1432. +#ifdef __STDC__
  1433. +#define L(name) .head.S.##name
  1434. +#else
  1435. +#define L(name) .head.S./**/name
  1436. +#endif
  1437. +#else
  1438. +#ifdef __STDC__
  1439. +#define L(name) .L##name
  1440. +#else
  1441. +#define L(name) .L/**/name
  1442. +#endif
  1443. +#endif
  1444. +
  1445. +/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
  1446. +#ifndef __INITDATA
  1447. +#define __INITDATA .data
  1448. +#define __FINIT .previous
  1449. +#endif
  1450. +
  1451. +/*
  1452. + * Setup ACR mappings to provide the following memory map:
  1453. + * Data
  1454. + * 0xA0000000 -> 0xAFFFFFFF [0] NO CACHE / PRECISE / SUPER ONLY
  1455. + * 0xFC000000 -> 0xFCFFFFFF [1] NO CACHE / PRECISE / SUPER ONLY
  1456. + * Code
  1457. + * None currently (mapped via TLBs)
  1458. + */
  1459. +
  1460. +#define ACR0_DEFAULT #0xA00FA048 /* ACR0 default value */
  1461. +#define ACR1_DEFAULT #0xFC00A040 /* ACR1 default value */
  1462. +#define ACR2_DEFAULT #0x00000000 /* ACR2 default value */
  1463. +#define ACR3_DEFAULT #0x00000000 /* ACR3 default value */
  1464. +
  1465. +/* ACR mapping for FPGA (maps 0) */
  1466. +#define ACR0_FPGA #0x000FA048 /* ACR0 enable FPGA */
  1467. +
  1468. +/* Several macros to make the writing of subroutines easier:
  1469. + * - func_start marks the beginning of the routine which setups the frame
  1470. + * register and saves the registers, it also defines another macro
  1471. + * to automatically restore the registers again.
  1472. + * - func_return marks the end of the routine and simply calls the prepared
  1473. + * macro to restore registers and jump back to the caller.
  1474. + * - func_define generates another macro to automatically put arguments
  1475. + * onto the stack call the subroutine and cleanup the stack again.
  1476. + */
  1477. +
  1478. +.macro load_symbol_address symbol,register
  1479. + movel #\symbol,\register
  1480. +.endm
  1481. +
  1482. +.macro func_start name,saveregs,savesize,stack=0
  1483. +L(\name):
  1484. + linkw %a6,#-\stack
  1485. + subal #(\savesize),%sp
  1486. + moveml \saveregs,%sp@
  1487. +.set stackstart,-\stack
  1488. +
  1489. +.macro func_return_\name
  1490. + moveml %sp@,\saveregs
  1491. + addal #(\savesize),%sp
  1492. + unlk %a6
  1493. + rts
  1494. +.endm
  1495. +.endm
  1496. +
  1497. +.macro func_return name
  1498. + func_return_\name
  1499. +.endm
  1500. +
  1501. +.macro func_call name
  1502. + jbsr L(\name)
  1503. +.endm
  1504. +
  1505. +.macro move_stack nr,arg1,arg2,arg3,arg4
  1506. +.if \nr
  1507. + move_stack "(\nr-1)",\arg2,\arg3,\arg4
  1508. + movel \arg1,%sp@-
  1509. +.endif
  1510. +.endm
  1511. +
  1512. +.macro func_define name,nr=0
  1513. +.macro \name arg1,arg2,arg3,arg4
  1514. + move_stack \nr,\arg1,\arg2,\arg3,\arg4
  1515. + func_call \name
  1516. +.if \nr
  1517. + lea %sp@(\nr*4),%sp
  1518. +.endif
  1519. +.endm
  1520. +.endm
  1521. +
  1522. +func_define serial_putc,1
  1523. +
  1524. +.macro putc ch
  1525. + pea \ch
  1526. + func_call serial_putc
  1527. + addql #4,%sp
  1528. +.endm
  1529. +
  1530. +.macro dputc ch
  1531. +#ifdef DEBUG
  1532. + putc \ch
  1533. +#endif
  1534. +.endm
  1535. +
  1536. +func_define putn,1
  1537. +
  1538. +.macro dputn nr
  1539. +#ifdef DEBUG
  1540. + putn \nr
  1541. +#endif
  1542. +.endm
  1543. +
  1544. +/*
  1545. + mmu_map - creates a new TLB entry
  1546. +
  1547. + virt_addr Must be on proper boundary
  1548. + phys_addr Must be on proper boundary
  1549. + itlb MMUOR_ITLB if instruction TLB or 0
  1550. + asid address space ID
  1551. + shared_global MMUTR_SG if shared between different ASIDs or 0
  1552. + size_code MMUDR_SZ1M 1 MB
  1553. + MMUDR_SZ4K 4 KB
  1554. + MMUDR_SZ8K 8 KB
  1555. + MMUDR_SZ16M 16 MB
  1556. + cache_mode MMUDR_INC instruction non-cacheable
  1557. + MMUDR_IC instruction cacheable
  1558. + MMUDR_DWT data writethrough
  1559. + MMUDR_DCB data copyback
  1560. + MMUDR_DNCP data non-cacheable, precise
  1561. + MMUDR_DNCIP data non-cacheable, imprecise
  1562. + super_prot MMUDR_SP if user mode generates exception or 0
  1563. + readable MMUDR_R if permits read access (data TLB) or 0
  1564. + writable MMUDR_W if permits write access (data TLB) or 0
  1565. + executable MMUDR_X if permits execute access (instruction TLB) or 0
  1566. + locked MMUDR_LK prevents TLB entry from being replaced or 0
  1567. + temp_data_reg a data register to use for temporary values
  1568. +*/
  1569. +.macro mmu_map virt_addr,phys_addr,itlb,asid,shared_global,size_code,cache_mode,super_prot,readable,writable,executable,locked,temp_data_reg
  1570. + /* Set up search of TLB. */
  1571. + movel #(\virt_addr+1), \temp_data_reg
  1572. + movel \temp_data_reg, MMUAR
  1573. + /* Search. */
  1574. + movel #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
  1575. + movew \temp_data_reg, (MMUOR)
  1576. + /* Set up tag value. */
  1577. + movel #(\virt_addr + \asid + \shared_global + MMUTR_V), \temp_data_reg
  1578. + movel \temp_data_reg, MMUTR
  1579. + /* Set up data value. */
  1580. + movel #(\phys_addr + \size_code + \cache_mode + \super_prot + \readable + \writable + \executable + \locked), \temp_data_reg
  1581. + movel \temp_data_reg, MMUDR
  1582. + /* Save it. */
  1583. + movel #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
  1584. + movew \temp_data_reg, (MMUOR)
  1585. +.endm /* mmu_map */
  1586. +
  1587. +.macro mmu_unmap virt_addr,itlb,temp_data_reg
  1588. + /* Set up search of TLB. */
  1589. + movel #(\virt_addr+1), \temp_data_reg
  1590. + movel \temp_data_reg, MMUAR
  1591. + /* Search. */
  1592. + movel #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
  1593. + movew \temp_data_reg, (MMUOR)
  1594. + /* Test for hit. */
  1595. + movel MMUSR,\temp_data_reg
  1596. + btst #MMUSR_HITN,\temp_data_reg
  1597. + beq 1f
  1598. + /* Read the TLB. */
  1599. + movel #(MMUOR_RW + MMUOR_ACC +\itlb), \temp_data_reg
  1600. + movew \temp_data_reg, (MMUOR)
  1601. + movel MMUSR,\temp_data_reg
  1602. + /* Set up tag value. */
  1603. + movel #0, \temp_data_reg
  1604. + movel \temp_data_reg, MMUTR
  1605. + /* Set up data value. */
  1606. + movel #0, \temp_data_reg
  1607. + movel \temp_data_reg, MMUDR
  1608. + /* Save it. */
  1609. + movel #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
  1610. + movew \temp_data_reg, (MMUOR)
  1611. +1:
  1612. +.endm /* mmu_unmap */
  1613. +
  1614. +/* .text */
  1615. +.section ".text.head","ax"
  1616. +ENTRY(_stext)
  1617. +/* Version numbers of the bootinfo interface -- if we later pass info
  1618. + * from boot ROM we might want to put something real here.
  1619. + *
  1620. + * The area from _stext to _start will later be used as kernel pointer table
  1621. + */
  1622. + bras 1f /* Jump over bootinfo version numbers */
  1623. +
  1624. + .long BOOTINFOV_MAGIC
  1625. + .long 0
  1626. +1: jmp __start-0x80000000
  1627. +
  1628. +.equ kernel_pg_dir,_stext
  1629. +.equ .,_stext+0x1000
  1630. +
  1631. +ENTRY(_start)
  1632. + jra __start
  1633. +__INIT
  1634. +ENTRY(__start)
  1635. +
  1636. +/* Save the location of u-boot info - cmd line, bd_info, etc. */
  1637. + movel %a7,%a4 /* Don't use %a4 before cf_early_init */
  1638. + addl #0x80000004,%a4 /* 0x80000004= 1 stack push + high mem offset */
  1639. +
  1640. +/* Setup initial stack pointer */
  1641. + movel #0x40001000,%sp
  1642. +
  1643. +/* Clear usp */
  1644. + subl %a0,%a0
  1645. + movel %a0,%usp
  1646. +
  1647. + movel #(MCF_RAMBAR1 + 0x221), %d0
  1648. + movec %d0, %rambar1
  1649. + movew #0x2700,%sr
  1650. +
  1651. + movel #(MMU_BASE+1),%d0
  1652. + movecl %d0,%mmubar
  1653. + movel #MMUOR_CA,%a0 /* Clear tlb entries */
  1654. + movew %a0,(MMUOR)
  1655. + movel #(MMUOR_CA + MMUOR_ITLB),%a0 /* Use ITLB for searches */
  1656. + movew %a0,(MMUOR)
  1657. + movel #0,%a0 /* Clear Addr Space User ID */
  1658. + movecl %a0,%asid
  1659. +
  1660. +/* setup ACRs */
  1661. + movel ACR0_DEFAULT, %d0 /* ACR0 (DATA) setup */
  1662. + movec %d0, %acr0
  1663. + movel ACR1_DEFAULT, %d0 /* ACR1 (DATA) setup */
  1664. + movec %d0, %acr1
  1665. + movel ACR2_DEFAULT, %d0 /* ACR2 (CODE) setup */
  1666. + movec %d0, %acr2
  1667. + movel ACR3_DEFAULT, %d0 /* ACR3 (CODE) setup */
  1668. + movec %d0, %acr3
  1669. +
  1670. + /* If you change the memory size to another value make a matching
  1671. + change in paging_init(cf-mmu.c) to zones_size[]. */
  1672. +
  1673. + /* Map 256MB as code */
  1674. + mmu_map (PAGE_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), \
  1675. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1676. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1677. + mmu_map (PAGE_OFFSET+1*0x1000000), (PHYS_OFFSET+1*0x1000000), \
  1678. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1679. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1680. + mmu_map (PAGE_OFFSET+2*0x1000000), (PHYS_OFFSET+2*0x1000000), \
  1681. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1682. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1683. + mmu_map (PAGE_OFFSET+3*0x1000000), (PHYS_OFFSET+3*0x1000000), \
  1684. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1685. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1686. + mmu_map (PAGE_OFFSET+4*0x1000000), (PHYS_OFFSET+4*0x1000000), \
  1687. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1688. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1689. + mmu_map (PAGE_OFFSET+5*0x1000000), (PHYS_OFFSET+5*0x1000000), \
  1690. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1691. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1692. + mmu_map (PAGE_OFFSET+6*0x1000000), (PHYS_OFFSET+6*0x1000000), \
  1693. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1694. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1695. + mmu_map (PAGE_OFFSET+7*0x1000000), (PHYS_OFFSET+7*0x1000000), \
  1696. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1697. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1698. + mmu_map (PAGE_OFFSET+8*0x1000000), (PHYS_OFFSET+8*0x1000000), \
  1699. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1700. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1701. + mmu_map (PAGE_OFFSET+9*0x1000000), (PHYS_OFFSET+9*0x1000000), \
  1702. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1703. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1704. + mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), \
  1705. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1706. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1707. + mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), \
  1708. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1709. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1710. + mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), \
  1711. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1712. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1713. + mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), \
  1714. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1715. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1716. + mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), \
  1717. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1718. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1719. + mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), \
  1720. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
  1721. + 0, 0, MMUDR_X, MMUDR_LK, %d0
  1722. +
  1723. + /* Map 256MB as data also */
  1724. + mmu_map (PAGE_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), 0, 0, \
  1725. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1726. + 0, MMUDR_LK, %d0
  1727. + mmu_map (PAGE_OFFSET+1*0x1000000), (PHYS_OFFSET+1*0x1000000), 0, 0, \
  1728. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1729. + 0, MMUDR_LK, %d0
  1730. + mmu_map (PAGE_OFFSET+2*0x1000000), (PHYS_OFFSET+2*0x1000000), 0, 0, \
  1731. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1732. + 0, MMUDR_LK, %d0
  1733. + mmu_map (PAGE_OFFSET+3*0x1000000), (PHYS_OFFSET+3*0x1000000), 0, 0, \
  1734. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1735. + 0, MMUDR_LK, %d0
  1736. + mmu_map (PAGE_OFFSET+4*0x1000000), (PHYS_OFFSET+4*0x1000000), 0, 0, \
  1737. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1738. + 0, MMUDR_LK, %d0
  1739. + mmu_map (PAGE_OFFSET+5*0x1000000), (PHYS_OFFSET+5*0x1000000), 0, 0, \
  1740. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1741. + 0, MMUDR_LK, %d0
  1742. + mmu_map (PAGE_OFFSET+6*0x1000000), (PHYS_OFFSET+6*0x1000000), 0, 0, \
  1743. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1744. + 0, MMUDR_LK, %d0
  1745. + mmu_map (PAGE_OFFSET+7*0x1000000), (PHYS_OFFSET+7*0x1000000), 0, 0, \
  1746. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1747. + 0, MMUDR_LK, %d0
  1748. + mmu_map (PAGE_OFFSET+8*0x1000000), (PHYS_OFFSET+8*0x1000000), 0, 0, \
  1749. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1750. + 0, MMUDR_LK, %d0
  1751. + mmu_map (PAGE_OFFSET+9*0x1000000), (PHYS_OFFSET+9*0x1000000), 0, 0, \
  1752. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1753. + 0, MMUDR_LK, %d0
  1754. + mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), 0, 0, \
  1755. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1756. + 0, MMUDR_LK, %d0
  1757. + mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), 0, 0, \
  1758. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1759. + 0, MMUDR_LK, %d0
  1760. + mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), 0, 0, \
  1761. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1762. + 0, MMUDR_LK, %d0
  1763. + mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), 0, 0, \
  1764. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1765. + 0, MMUDR_LK, %d0
  1766. + mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), 0, 0, \
  1767. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1768. + 0, MMUDR_LK, %d0
  1769. + mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), 0, 0, \
  1770. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1771. + 0, MMUDR_LK, %d0
  1772. +
  1773. + /* Do unity mapping to enable the MMU. Map first 16 MB in place as
  1774. + code (delete TLBs after MMU is enabled and we are executing in high
  1775. + memory). */
  1776. + mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), \
  1777. + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_INC, MMUDR_SP, 0, \
  1778. + 0, MMUDR_X, 0, %d0
  1779. + /* Map first 16 MB as data too. */
  1780. + mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), 0, 0, \
  1781. + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
  1782. + 0, 0, %d0
  1783. +
  1784. + /* Turn on MMU */
  1785. + movel #(MMUCR_EN),%a0
  1786. + movel %a0,MMUCR
  1787. + nop /* This synchs the pipeline after a write to MMUCR */
  1788. +
  1789. + movel #__running_high,%a0 /* Get around PC-relative addressing. */
  1790. + jmp %a0@
  1791. +
  1792. +ENTRY(__running_high)
  1793. + load_symbol_address _stext,%sp
  1794. + movel L(memory_start),%a0
  1795. + movel %a0,availmem
  1796. + load_symbol_address L(phys_kernel_start),%a0
  1797. + load_symbol_address _stext,%a1
  1798. + subl #_stext,%a1
  1799. + addl #PAGE_OFFSET,%a1
  1800. + movel %a1,%a0@
  1801. +
  1802. + /* Unmap first 16 MB, code and data. */
  1803. + mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
  1804. + mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
  1805. +
  1806. +/* Setup initial stack pointer */
  1807. + lea init_task,%a2
  1808. + lea init_thread_union+THREAD_SIZE,%sp
  1809. + subl %a6,%a6 /* clear a6 for gdb */
  1810. +
  1811. +#ifdef CONFIG_MCF_USER_HALT
  1812. +/* Setup debug control reg to allow halts from user space */
  1813. + lea wdbg_uhe,%a0
  1814. + wdebug (%a0)
  1815. +#endif
  1816. +
  1817. + movel %a4,uboot_info_stk /* save uboot info to variable */
  1818. + jsr cf_early_init
  1819. + jmp start_kernel
  1820. +
  1821. +.section ".text.head","ax"
  1822. +set_context:
  1823. +func_start set_context,%d0,(1*4)
  1824. + movel 12(%sp),%d0
  1825. + movec %d0,%asid
  1826. +func_return set_context
  1827. +
  1828. +/*
  1829. + * set_fpga(addr,val)
  1830. + *
  1831. + * Map in 0x00000000 -> 0x0fffffff and then do the write.
  1832. + */
  1833. +set_fpga:
  1834. + movew %sr,%d1
  1835. + movew #0x2700,%sr
  1836. + movel ACR0_FPGA, %d0
  1837. + movec %d0, %acr0
  1838. + nop
  1839. + moveal 4(%sp),%a0
  1840. + movel 8(%sp),%a0@
  1841. + movel ACR0_DEFAULT, %d0
  1842. + movec %d0, %acr0
  1843. + nop
  1844. + movew %d1,%sr
  1845. + rts
  1846. +
  1847. + .data
  1848. + .align 4
  1849. +
  1850. +availmem:
  1851. + .long 0
  1852. +L(phys_kernel_start):
  1853. + .long PAGE_OFFSET
  1854. +L(kernel_end):
  1855. + .long 0
  1856. +L(memory_start):
  1857. + .long PAGE_OFFSET_RAW
  1858. +
  1859. +#ifdef CONFIG_MCF_USER_HALT
  1860. +/*
  1861. + * Enable User Halt Enable in the debug control register.
  1862. + */
  1863. +wdbg_uhe:
  1864. + .word 0x2c80 /* DR0 */
  1865. + .word 0x00b0 /* 31:16 */
  1866. + .word 0x0400 /* 15:0 -- enable UHE */
  1867. + .word 0x0000 /* unused */
  1868. +#endif
  1869. +
  1870. +
  1871. --- /dev/null
  1872. +++ b/arch/m68k/coldfire/ints.c
  1873. @@ -0,0 +1,384 @@
  1874. +/*
  1875. + * linux/arch/m68k/coldfire/ints.c -- General interrupt handling code
  1876. + *
  1877. + * Copyright (C) 1999-2002 Greg Ungerer ([email protected])
  1878. + * Copyright (C) 1998 D. Jeff Dionne <[email protected]>,
  1879. + * Kenneth Albanowski <[email protected]>,
  1880. + * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
  1881. + * Matt Waddel [email protected]
  1882. + * Copyright Freescale Semiconductor, Inc. 2007
  1883. + * Kurt Mahan [email protected]
  1884. + *
  1885. + * Based on:
  1886. + * linux/arch/m68k/kernel/ints.c &
  1887. + * linux/arch/m68knommu/5307/ints.c
  1888. + *
  1889. + * This file is subject to the terms and conditions of the GNU General Public
  1890. + * License. See the file COPYING in the main directory of this archive
  1891. + * for more details.
  1892. + */
  1893. +
  1894. +#include <linux/module.h>
  1895. +#include <linux/types.h>
  1896. +#include <linux/init.h>
  1897. +#include <linux/sched.h>
  1898. +#include <linux/kernel_stat.h>
  1899. +#include <linux/errno.h>
  1900. +#include <linux/seq_file.h>
  1901. +#include <linux/interrupt.h>
  1902. +
  1903. +#include <asm/system.h>
  1904. +#include <asm/irq.h>
  1905. +#include <asm/traps.h>
  1906. +#include <asm/page.h>
  1907. +#include <asm/machdep.h>
  1908. +#include <asm/irq_regs.h>
  1909. +
  1910. +#include <asm/mcfsim.h>
  1911. +
  1912. +/*
  1913. + * IRQ Handler lists.
  1914. + */
  1915. +static struct irq_node *irq_list[SYS_IRQS];
  1916. +static struct irq_controller *irq_controller[SYS_IRQS];
  1917. +static int irq_depth[SYS_IRQS];
  1918. +
  1919. +/*
  1920. + * IRQ Controller
  1921. + */
  1922. +#ifdef CONFIG_M54455
  1923. +void m5445x_irq_enable(unsigned int irq);
  1924. +void m5445x_irq_disable(unsigned int irq);
  1925. +static struct irq_controller m5445x_irq_controller = {
  1926. + .name = "M5445X",
  1927. + .lock = SPIN_LOCK_UNLOCKED,
  1928. + .enable = m5445x_irq_enable,
  1929. + .disable = m5445x_irq_disable,
  1930. +};
  1931. +#endif
  1932. +
  1933. +#define POOL_SIZE SYS_IRQS
  1934. +static struct irq_node pool[POOL_SIZE];
  1935. +static struct irq_node *get_irq_node(void);
  1936. +
  1937. +/* The number of spurious interrupts */
  1938. +unsigned int num_spurious;
  1939. +asmlinkage void handle_badint(struct pt_regs *regs);
  1940. +
  1941. +/*
  1942. + * void init_IRQ(void)
  1943. + *
  1944. + * This function should be called during kernel startup to initialize
  1945. + * the IRQ handling routines.
  1946. + */
  1947. +void __init init_IRQ(void)
  1948. +{
  1949. + int i;
  1950. +
  1951. +#ifdef CONFIG_M54455
  1952. + for (i = 0; i < SYS_IRQS; i++)
  1953. + irq_controller[i] = &m5445x_irq_controller;
  1954. +#endif
  1955. +}
  1956. +
  1957. +/*
  1958. + * process_int(unsigned long vec, struct pt_regs *fp)
  1959. + *
  1960. + * Process an interrupt. Called from entry.S.
  1961. + */
  1962. +asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
  1963. +{
  1964. + struct pt_regs *old_regs;
  1965. + struct irq_node *node;
  1966. + old_regs = set_irq_regs(fp);
  1967. + kstat_cpu(0).irqs[vec]++;
  1968. +
  1969. + node = irq_list[vec];
  1970. + if (!node)
  1971. + handle_badint(fp);
  1972. + else {
  1973. + do {
  1974. + node->handler(vec, node->dev_id);
  1975. + node = node->next;
  1976. + } while (node);
  1977. + }
  1978. +
  1979. + set_irq_regs(old_regs);
  1980. +}
  1981. +
  1982. +/*
  1983. + * show_interrupts( struct seq_file *p, void *v)
  1984. + *
  1985. + * Called to show all the current interrupt information.
  1986. + */
  1987. +int show_interrupts(struct seq_file *p, void *v)
  1988. +{
  1989. + struct irq_controller *contr;
  1990. + struct irq_node *node;
  1991. + int i = *(loff_t *) v;
  1992. +
  1993. + if ((i < NR_IRQS) && (irq_list[i])) {
  1994. + contr = irq_controller[i];
  1995. + node = irq_list[i];
  1996. + seq_printf(p, "%-8s %3u: %10u %s", contr->name, i,
  1997. + kstat_cpu(0).irqs[i], node->devname);
  1998. + while ((node = node->next))
  1999. + seq_printf(p, ", %s", node->devname);
  2000. +
  2001. + seq_printf(p, "\n");
  2002. + }
  2003. +
  2004. + return 0;
  2005. +}
  2006. +
  2007. +/*
  2008. + * get_irq_node(void)
  2009. + *
  2010. + * Get an irq node from the pool.
  2011. + */
  2012. +struct irq_node *get_irq_node(void)
  2013. +{
  2014. + struct irq_node *p = pool;
  2015. + int i;
  2016. +
  2017. + for (i = 0; i < POOL_SIZE; i++, p++) {
  2018. + if (!p->handler) {
  2019. + memset(p, 0, sizeof(struct irq_node));
  2020. + return p;
  2021. + }
  2022. + }
  2023. + printk(KERN_INFO "%s(%s:%d): No more irq nodes, I suggest you \
  2024. + increase POOL_SIZE", __FUNCTION__, __FILE__, __LINE__);
  2025. + return NULL;
  2026. +}
  2027. +
  2028. +void init_irq_proc(void)
  2029. +{
  2030. + /* Insert /proc/irq driver here */
  2031. +}
  2032. +
  2033. +int setup_irq(unsigned int irq, struct irq_node *node)
  2034. +{
  2035. + struct irq_controller *contr;
  2036. + struct irq_node **prev;
  2037. + unsigned long flags;
  2038. +
  2039. + if (irq >= NR_IRQS || !irq_controller[irq]) {
  2040. + printk("%s: Incorrect IRQ %d from %s\n",
  2041. + __FUNCTION__, irq, node->devname);
  2042. + return -ENXIO;
  2043. + }
  2044. +
  2045. + contr = irq_controller[irq];
  2046. + spin_lock_irqsave(&contr->lock, flags);
  2047. +
  2048. + prev = irq_list + irq;
  2049. + if (*prev) {
  2050. + /* Can't share interrupts unless both agree to */
  2051. + if (!((*prev)->flags & node->flags & IRQF_SHARED)) {
  2052. + spin_unlock_irqrestore(&contr->lock, flags);
  2053. + return -EBUSY;
  2054. + }
  2055. + while (*prev)
  2056. + prev = &(*prev)->next;
  2057. + }
  2058. +
  2059. + if (!irq_list[irq]) {
  2060. + if (contr->startup)
  2061. + contr->startup(irq);
  2062. + else
  2063. + contr->enable(irq);
  2064. + }
  2065. + node->next = NULL;
  2066. + *prev = node;
  2067. +
  2068. + spin_unlock_irqrestore(&contr->lock, flags);
  2069. +
  2070. + return 0;
  2071. +}
  2072. +
  2073. +int request_irq(unsigned int irq,
  2074. + irq_handler_t handler,
  2075. + unsigned long flags, const char *devname, void *dev_id)
  2076. +{
  2077. + struct irq_node *node = get_irq_node();
  2078. + int res;
  2079. +
  2080. + if (!node)
  2081. + return -ENOMEM;
  2082. +
  2083. + node->handler = handler;
  2084. + node->flags = flags;
  2085. + node->dev_id = dev_id;
  2086. + node->devname = devname;
  2087. +
  2088. + res = setup_irq(irq, node);
  2089. + if (res)
  2090. + node->handler = NULL;
  2091. +
  2092. + return res;
  2093. +}
  2094. +EXPORT_SYMBOL(request_irq);
  2095. +
  2096. +void free_irq(unsigned int irq, void *dev_id)
  2097. +{
  2098. + struct irq_controller *contr;
  2099. + struct irq_node **p, *node;
  2100. + unsigned long flags;
  2101. +
  2102. + if (irq >= NR_IRQS || !irq_controller[irq]) {
  2103. + printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
  2104. + return;
  2105. + }
  2106. +
  2107. + contr = irq_controller[irq];
  2108. + spin_lock_irqsave(&contr->lock, flags);
  2109. +
  2110. + p = irq_list + irq;
  2111. + while ((node = *p)) {
  2112. + if (node->dev_id == dev_id)
  2113. + break;
  2114. + p = &node->next;
  2115. + }
  2116. +
  2117. + if (node) {
  2118. + *p = node->next;
  2119. + node->handler = NULL;
  2120. + } else
  2121. + printk(KERN_DEBUG "%s: Removing probably wrong IRQ %d\n",
  2122. + __FUNCTION__, irq);
  2123. +
  2124. + if (!irq_list[irq]) {
  2125. + if (contr->shutdown)
  2126. + contr->shutdown(irq);
  2127. + else
  2128. + contr->disable(irq);
  2129. + }
  2130. +
  2131. + spin_unlock_irqrestore(&contr->lock, flags);
  2132. +}
  2133. +EXPORT_SYMBOL(free_irq);
  2134. +
  2135. +void enable_irq(unsigned int irq)
  2136. +{
  2137. + struct irq_controller *contr;
  2138. + unsigned long flags;
  2139. +
  2140. + if (irq >= NR_IRQS || !irq_controller[irq]) {
  2141. + printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
  2142. + return;
  2143. + }
  2144. +
  2145. + contr = irq_controller[irq];
  2146. + spin_lock_irqsave(&contr->lock, flags);
  2147. + if (irq_depth[irq]) {
  2148. + if (!--irq_depth[irq]) {
  2149. + if (contr->enable)
  2150. + contr->enable(irq);
  2151. + }
  2152. + } else
  2153. + WARN_ON(1);
  2154. + spin_unlock_irqrestore(&contr->lock, flags);
  2155. +}
  2156. +EXPORT_SYMBOL(enable_irq);
  2157. +
  2158. +void disable_irq(unsigned int irq)
  2159. +{
  2160. + struct irq_controller *contr;
  2161. + unsigned long flags;
  2162. +
  2163. + if (irq >= NR_IRQS || !irq_controller[irq]) {
  2164. + printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
  2165. + return;
  2166. + }
  2167. +
  2168. + contr = irq_controller[irq];
  2169. + spin_lock_irqsave(&contr->lock, flags);
  2170. + if (!irq_depth[irq]++) {
  2171. + if (contr->disable)
  2172. + contr->disable(irq);
  2173. + }
  2174. + spin_unlock_irqrestore(&contr->lock, flags);
  2175. +}
  2176. +EXPORT_SYMBOL(disable_irq);
  2177. +
  2178. +unsigned long probe_irq_on(void)
  2179. +{
  2180. + return 0;
  2181. +}
  2182. +EXPORT_SYMBOL(probe_irq_on);
  2183. +
  2184. +int probe_irq_off(unsigned long irqs)
  2185. +{
  2186. + return 0;
  2187. +}
  2188. +EXPORT_SYMBOL(probe_irq_off);
  2189. +
  2190. +asmlinkage void handle_badint(struct pt_regs *regs)
  2191. +{
  2192. + kstat_cpu(0).irqs[0]++;
  2193. + num_spurious++;
  2194. + printk(KERN_DEBUG "unexpected interrupt from %u\n", regs->vector);
  2195. +}
  2196. +EXPORT_SYMBOL(handle_badint);
  2197. +
  2198. +#ifdef CONFIG_M54455
  2199. +/*
  2200. + * M5445X Implementation
  2201. + */
  2202. +void m5445x_irq_enable(unsigned int irq)
  2203. +{
  2204. + /* enable the interrupt hardware */
  2205. + if (irq < 64)
  2206. + return;
  2207. +
  2208. + /* adjust past non-hardware ints */
  2209. + irq -= 64;
  2210. +
  2211. + /* check for eport */
  2212. + if ((irq > 0) && (irq < 8)) {
  2213. + /* enable eport */
  2214. + MCF_EPORT_EPPAR &= ~(3 << (irq*2)); /* level */
  2215. + MCF_EPORT_EPDDR &= ~(1 << irq); /* input */
  2216. + MCF_EPORT_EPIER |= 1 << irq; /* irq enabled */
  2217. + }
  2218. +
  2219. + if (irq < 64) {
  2220. + /* controller 0 */
  2221. + MCF_INTC0_ICR(irq) = 0x02;
  2222. + MCF_INTC0_CIMR = irq;
  2223. + } else {
  2224. + /* controller 1 */
  2225. + irq -= 64;
  2226. + MCF_INTC1_ICR(irq) = 0x02;
  2227. + MCF_INTC1_CIMR = irq;
  2228. + }
  2229. +}
  2230. +
  2231. +void m5445x_irq_disable(unsigned int irq)
  2232. +{
  2233. + /* disable the interrupt hardware */
  2234. + if (irq < 64)
  2235. + return;
  2236. +
  2237. + /* adjust past non-hardware ints */
  2238. + irq -= 64;
  2239. +
  2240. + /* check for eport */
  2241. + if ((irq > 0) && (irq < 8)) {
  2242. + /* disable eport */
  2243. + MCF_EPORT_EPIER &= ~(1 << irq);
  2244. + }
  2245. +
  2246. + if (irq < 64) {
  2247. + /* controller 0 */
  2248. + MCF_INTC0_ICR(irq) = 0x00;
  2249. + MCF_INTC0_SIMR = irq;
  2250. + } else {
  2251. + /* controller 1 */
  2252. + irq -= 64;
  2253. + MCF_INTC1_ICR(irq) = 0x00;
  2254. + MCF_INTC1_SIMR = irq;
  2255. + }
  2256. +}
  2257. +#endif
  2258. --- /dev/null
  2259. +++ b/arch/m68k/coldfire/iomap.c
  2260. @@ -0,0 +1,54 @@
  2261. +/*
  2262. + * arch/m68k/coldfire/iomap.c
  2263. + *
  2264. + * Generic coldfire iomap interface
  2265. + *
  2266. + * Based on the sh64 iomap.c by Paul Mundt.
  2267. + *
  2268. + * This file is subject to the terms and conditions of the GNU General Public
  2269. + * License. See the file "COPYING" in the main directory of this archive
  2270. + * for more details.
  2271. + */
  2272. +#include <linux/pci.h>
  2273. +#include <asm/io.h>
  2274. +
  2275. +void __iomem *__attribute__ ((weak))
  2276. +ioport_map(unsigned long port, unsigned int len)
  2277. +{
  2278. + return (void __iomem *)port;
  2279. +}
  2280. +EXPORT_SYMBOL(pci_iomap);
  2281. +
  2282. +void ioport_unmap(void __iomem *addr)
  2283. +{
  2284. + /* Nothing .. */
  2285. +}
  2286. +EXPORT_SYMBOL(pci_iounmap);
  2287. +
  2288. +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
  2289. +{
  2290. + unsigned long start = pci_resource_start(dev, bar);
  2291. + unsigned long len = pci_resource_len(dev, bar);
  2292. + unsigned long flags = pci_resource_flags(dev, bar);
  2293. +printk(KERN_INFO "PCI_IOMAP: BAR=%d START=0x%lx LEN=0x%lx FLAGS=0x%lx\n",
  2294. + bar, start, len, flags);
  2295. +
  2296. + if (!len)
  2297. + return NULL;
  2298. + if (max && len > max)
  2299. + len = max;
  2300. + if (flags & IORESOURCE_IO)
  2301. + return ioport_map(start, len);
  2302. + if (flags & IORESOURCE_MEM)
  2303. + return (void __iomem *)start;
  2304. +
  2305. + /* What? */
  2306. + return NULL;
  2307. +}
  2308. +EXPORT_SYMBOL(ioport_map);
  2309. +
  2310. +void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
  2311. +{
  2312. + /* Nothing .. */
  2313. +}
  2314. +EXPORT_SYMBOL(ioport_unmap);
  2315. --- /dev/null
  2316. +++ b/arch/m68k/coldfire/mcf5445x-pci.c
  2317. @@ -0,0 +1,427 @@
  2318. +/*
  2319. + * arch/m68k/coldfire/mcf5445x-pci.c
  2320. + *
  2321. + * Coldfire M5445x specific PCI implementation.
  2322. + *
  2323. + * Copyright (c) 2007 Freescale Semiconductor, Inc.
  2324. + * Kurt Mahan <[email protected]>
  2325. + */
  2326. +
  2327. +#include <linux/delay.h>
  2328. +#include <linux/pci.h>
  2329. +
  2330. +#include <asm/mcfsim.h>
  2331. +#include <asm/pci.h>
  2332. +#include <asm/irq.h>
  2333. +
  2334. +/*
  2335. + * Layout MCF5445x to PCI memory mappings:
  2336. + *
  2337. + * WIN MCF5445x PCI TYPE
  2338. + * --- -------- --- ----
  2339. + * [0] 0xA0000000 -> 0xA7FFFFFF 0xA0000000 -> 0xA7FFFFFF MEM
  2340. + * [1] 0xA8000000 -> 0xABFFFFFF 0xA8000000 -> 0xABFFFFFF MEM
  2341. + * [2] 0xAC000000 -> 0xAFFFFFFF 0xAC000000 -> 0xAFFFFFFF IO
  2342. + */
  2343. +
  2344. +#define MCF5445X_PCI_MEM_BASE 0xA0000000
  2345. +#define MCF5445X_PCI_MEM_SIZE 0x0C000000
  2346. +
  2347. +#define MCF5445X_PCI_CONFIG_BASE 0xAC000000
  2348. +#define MCF5445X_PCI_CONFIG_SIZE 0x04000000
  2349. +
  2350. +#define MCF5445X_PCI_IO_BASE 0xAC000000
  2351. +#define MCF5445X_PCI_IO_SIZE 0x04000000
  2352. +
  2353. +/* PCI Bus memory resource block */
  2354. +struct resource pci_iomem_resource = {
  2355. + .name = "PCI memory space",
  2356. + .start = MCF5445X_PCI_MEM_BASE,
  2357. + .flags = IORESOURCE_MEM,
  2358. + .end = MCF5445X_PCI_MEM_BASE + MCF5445X_PCI_MEM_SIZE - 1
  2359. +};
  2360. +
  2361. +/* PCI Bus ioport resource block */
  2362. +struct resource pci_ioport_resource = {
  2363. + .name = "PCI I/O space",
  2364. + .start = MCF5445X_PCI_IO_BASE,
  2365. + .flags = IORESOURCE_IO,
  2366. + .end = MCF5445X_PCI_IO_BASE + MCF5445X_PCI_IO_SIZE - 1
  2367. +};
  2368. +
  2369. +/*
  2370. + * The M54455EVB multiplexes all the PCI interrupts via
  2371. + * the FPGA and routes them to a single interrupt. The
  2372. + * PCI spec requires all PCI interrupt routines be smart
  2373. + * enough to sort out their own interrupts.
  2374. + * The interrupt source from the FPGA is configured
  2375. + * to EPORT 3.
  2376. + */
  2377. +#define MCF5445X_PCI_IRQ 0x43
  2378. +
  2379. +#define PCI_SLOTS 4
  2380. +
  2381. +/*
  2382. + * FPGA Info
  2383. + */
  2384. +#define FPGA_PCI_IRQ_ENABLE (u32 *)0x09000000
  2385. +#define FPGA_PCI_IRQ_STATUS (u32 *)0x09000004
  2386. +#define FPGA_PCI_IRQ_ROUTE (u32 *)0x0900000c
  2387. +#define FPGA_SEVEN_LED (u32 *)0x09000014
  2388. +
  2389. +extern void set_fpga(u32 *addr, u32 val);
  2390. +
  2391. +#ifdef DEBUG
  2392. +void mcf5445x_pci_dumpregs(void);
  2393. +#endif
  2394. +
  2395. +/*
  2396. + * static void mcf5445x_conf_device(struct pci_dev *dev)
  2397. + *
  2398. + * Machine dependent Configure the given device.
  2399. + *
  2400. + * Parameters:
  2401. + *
  2402. + * dev - the pci device.
  2403. + */
  2404. +void __init
  2405. +mcf5445x_conf_device(struct pci_dev *dev)
  2406. +{
  2407. + set_fpga(FPGA_PCI_IRQ_ENABLE, 0x0f);
  2408. +}
  2409. +
  2410. +/*
  2411. + * int mcf5445x_pci_config_read(unsigned int seg, unsigned int bus,
  2412. + * unsigned int devfn, int reg,
  2413. + * u32 *value)
  2414. + *
  2415. + * Read from PCI configuration space.
  2416. + *
  2417. + */
  2418. +int mcf5445x_pci_config_read(unsigned int seg, unsigned int bus,
  2419. + unsigned int devfn, int reg, int len, u32 *value)
  2420. +{
  2421. + u32 addr = MCF_PCI_PCICAR_BUSNUM(bus) |
  2422. + MCF_PCI_PCICAR_DEVNUM(PCI_SLOT(devfn)) |
  2423. + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNC(devfn)) |
  2424. + MCF_PCI_PCICAR_DWORD(reg) |
  2425. + MCF_PCI_PCICAR_E;
  2426. +
  2427. + if ((bus > 255) || (devfn > 255) || (reg > 255)) {
  2428. + *value = -1;
  2429. + return -EINVAL;
  2430. + }
  2431. +
  2432. + /* setup for config mode */
  2433. + MCF_PCI_PCICAR = addr;
  2434. + __asm__ __volatile__("nop");
  2435. +
  2436. + switch (len) {
  2437. + case 1:
  2438. + *value = *(volatile u8 *)(MCF5445X_PCI_CONFIG_BASE+(reg&3));
  2439. + break;
  2440. + case 2:
  2441. + *value = le16_to_cpu(*(volatile u16 *)
  2442. + (MCF5445X_PCI_CONFIG_BASE + (reg&2)));
  2443. + break;
  2444. + case 4:
  2445. + *value = le32_to_cpu(*(volatile u32 *)
  2446. + (MCF5445X_PCI_CONFIG_BASE));
  2447. + break;
  2448. + }
  2449. +
  2450. + /* clear config mode */
  2451. + MCF_PCI_PCICAR = ~MCF_PCI_PCICAR_E;
  2452. + __asm__ __volatile__("nop");
  2453. +
  2454. + return 0;
  2455. +}
  2456. +
  2457. +/*
  2458. + * int mcf5445x_pci_config_write(unsigned int seg, unsigned int bus,
  2459. + * unsigned int devfn, int reg,
  2460. + * u32 *value)
  2461. + *
  2462. + * Write to PCI configuration space
  2463. + */
  2464. +int mcf5445x_pci_config_write(unsigned int seg, unsigned int bus,
  2465. + unsigned int devfn, int reg, int len, u32 value)
  2466. +{
  2467. + u32 addr = MCF_PCI_PCICAR_BUSNUM(bus) |
  2468. + MCF_PCI_PCICAR_DEVNUM(PCI_SLOT(devfn)) |
  2469. + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNC(devfn)) |
  2470. + MCF_PCI_PCICAR_DWORD(reg) |
  2471. + MCF_PCI_PCICAR_E;
  2472. +
  2473. + if ((bus > 255) || (devfn > 255) || (reg > 255))
  2474. + return -EINVAL;
  2475. +
  2476. + /* setup for config mode */
  2477. + MCF_PCI_PCICAR = addr;
  2478. + __asm__ __volatile__("nop");
  2479. +
  2480. + switch (len) {
  2481. + case 1:
  2482. + *(volatile u8 *)(MCF5445X_PCI_CONFIG_BASE+(reg&3)) = (u8)value;
  2483. + break;
  2484. + case 2:
  2485. + *(volatile u16 *)(MCF5445X_PCI_CONFIG_BASE+(reg&2)) =
  2486. + cpu_to_le16((u16)value);
  2487. + break;
  2488. + case 4:
  2489. + *(volatile u32 *)(MCF5445X_PCI_CONFIG_BASE) =
  2490. + cpu_to_le32(value);
  2491. + break;
  2492. + }
  2493. +
  2494. + /* clear config mode */
  2495. + MCF_PCI_PCICAR = ~MCF_PCI_PCICAR_E;
  2496. + __asm__ __volatile__("nop");
  2497. +
  2498. + return 0;
  2499. +}
  2500. +
  2501. +/* hardware operations */
  2502. +static struct pci_raw_ops mcf5445x_pci_ops = {
  2503. + .read = mcf5445x_pci_config_read,
  2504. + .write = mcf5445x_pci_config_write,
  2505. +};
  2506. +
  2507. +/*
  2508. + * irqreturn_t mcf5445x_pci_interrupt( int irq, void *dev)
  2509. + *
  2510. + * PCI controller interrupt handler.
  2511. + */
  2512. +static irqreturn_t
  2513. +mcf5445x_pci_interrupt(int irq, void *dev)
  2514. +{
  2515. + u32 status = MCF_PCI_PCIGSCR;
  2516. +#ifdef DEBUG
  2517. + printk(KERN_INFO "PCI: Controller irq status=0x%08x\n", status);
  2518. +#endif
  2519. + /* clear */
  2520. + MCF_PCI_PCIGSCR = status;
  2521. +
  2522. + return IRQ_HANDLED;
  2523. +}
  2524. +
  2525. +/*
  2526. + * irqreturn_t mcf5445x_pci_arb_interrupt( int irq, void *dev)
  2527. + *
  2528. + * PCI Arbiter interrupt handler.
  2529. + */
  2530. +static irqreturn_t
  2531. +mcf5445x_pci_arb_interrupt(int irq, void *dev)
  2532. +{
  2533. + u32 status = MCF_PCIARB_PASR;
  2534. +#ifdef DEBUG
  2535. + printk(KERN_INFO "PCI: Arbiter irq status=0x%08x\n", status);
  2536. +#endif
  2537. + /* clear */
  2538. + MCF_PCIARB_PASR = status;
  2539. + return IRQ_HANDLED;
  2540. +}
  2541. +
  2542. +/*
  2543. + * struct pci_bus_info *init_mcf5445x_pci(void)
  2544. + *
  2545. + * Machine specific initialisation:
  2546. + *
  2547. + * - Allocate and initialise a 'pci_bus_info' structure
  2548. + * - Initialize hardware
  2549. + *
  2550. + * Result: pointer to 'pci_bus_info' structure.
  2551. + */
  2552. +int __init
  2553. +init_mcf5445x_pci(void)
  2554. +{
  2555. + /*
  2556. + * Initialize the PCI core
  2557. + */
  2558. +
  2559. + /* arbitration controller */
  2560. + MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI |
  2561. + MCF_PCIARB_PACR_EXTMPRI(0x0f) |
  2562. + MCF_PCIARB_PACR_INTMINTEN |
  2563. + MCF_PCIARB_PACR_EXTMINTEN(0x0f);
  2564. +
  2565. + /* pci pin assignment regs */
  2566. + MCF_GPIO_PAR_PCI = MCF_GPIO_PAR_PCI_GNT0 |
  2567. + MCF_GPIO_PAR_PCI_GNT1 |
  2568. + MCF_GPIO_PAR_PCI_GNT2 |
  2569. + MCF_GPIO_PAR_PCI_GNT3_GNT3 |
  2570. + MCF_GPIO_PAR_PCI_REQ0 |
  2571. + MCF_GPIO_PAR_PCI_REQ1 |
  2572. + MCF_GPIO_PAR_PCI_REQ2 |
  2573. + MCF_GPIO_PAR_PCI_REQ3_REQ3;
  2574. +
  2575. + /* target control reg */
  2576. + MCF_PCI_PCITCR = MCF_PCI_PCITCR_P |
  2577. + MCF_PCI_PCITCR_WCT(8);
  2578. +
  2579. + /* PCI MEM address */
  2580. + MCF_PCI_PCIIW0BTAR = 0xA007A000;
  2581. +
  2582. + /* PCI MEM address */
  2583. + MCF_PCI_PCIIW1BTAR = 0xA803A800;
  2584. +
  2585. + /* PCI IO address */
  2586. + MCF_PCI_PCIIW2BTAR = 0xAC03AC00;
  2587. +
  2588. + /* window control */
  2589. + MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_ENABLE |
  2590. + MCF_PCI_PCIIWCR_WINCTRL0_MEMREAD |
  2591. + MCF_PCI_PCIIWCR_WINCTRL1_ENABLE |
  2592. + MCF_PCI_PCIIWCR_WINCTRL1_MEMREAD |
  2593. + MCF_PCI_PCIIWCR_WINCTRL2_ENABLE |
  2594. + MCF_PCI_PCIIWCR_WINCTRL2_IO;
  2595. +
  2596. + /* initiator control reg */
  2597. + MCF_PCI_PCIICR = 0x00ff;
  2598. +
  2599. + /* type 0 - command */
  2600. + MCF_PCI_PCISCR = MCF_PCI_PCISCR_MW | /* mem write/inval */
  2601. + MCF_PCI_PCISCR_B | /* bus master enable */
  2602. + MCF_PCI_PCISCR_M; /* mem access enable */
  2603. +
  2604. + /* type 0 - config reg */
  2605. + MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(8) |
  2606. + MCF_PCI_PCICR1_LATTIMER(0xff);
  2607. +
  2608. + /* type 0 - config 2 reg */
  2609. + MCF_PCI_PCICR2 = 0;
  2610. +
  2611. + /* target control reg */
  2612. + MCF_PCI_PCITCR2 = MCF_PCI_PCITCR2_B0E |
  2613. + MCF_PCI_PCITCR2_B4E;
  2614. +
  2615. + /* translate addresses from PCI[0] to CF[SDRAM] */
  2616. + MCF_PCI_PCITBATR0 = MCF_RAMBAR1 | MCF_PCI_PCITBATR0_EN;
  2617. + MCF_PCI_PCITBATR4 = MCF_RAMBAR1 | MCF_PCI_PCITBATR4_EN;
  2618. +
  2619. + /* setup controller interrupt handlers */
  2620. + if (request_irq(55+128, mcf5445x_pci_interrupt, IRQF_SHARED,
  2621. + "PCI Controller", NULL))
  2622. + printk(KERN_ERR "PCI: Unable to register controller irq\n");
  2623. +
  2624. + if (request_irq (56+128, mcf5445x_pci_arb_interrupt, IRQF_SHARED, "PCI Arbiter", NULL))
  2625. + printk(KERN_ERR "PCI: Unable to register arbiter irq\n");
  2626. +
  2627. + /* global control - clear reset bit */
  2628. + MCF_PCI_PCIGSCR = MCF_PCI_PCIGSCR_SEE |
  2629. + MCF_PCI_PCIGSCR_PEE;
  2630. +
  2631. + /* let everything settle */
  2632. + udelay(1000);
  2633. +
  2634. + /* allocate bus ioport resource */
  2635. + if (request_resource(&ioport_resource, &pci_ioport_resource) < 0)
  2636. + printk(KERN_ERR "PCI: Unable to alloc ioport resource\n");
  2637. +
  2638. + /* allocate bus iomem resource */
  2639. + if (request_resource(&iomem_resource, &pci_iomem_resource) < 0)
  2640. + printk(KERN_ERR "PCI: Unable to alloc iomem resource\n");
  2641. +
  2642. + /* setup FPGA to route PCI to IRQ3(67), SW7 to IRQ7, SW6 to IRQ4 */
  2643. + set_fpga(FPGA_PCI_IRQ_ENABLE, 0x00000000);
  2644. + set_fpga(FPGA_PCI_IRQ_ROUTE, 0x00000039);
  2645. + set_fpga(FPGA_SEVEN_LED, 0x000000FF);
  2646. +
  2647. + raw_pci_ops = &mcf5445x_pci_ops;
  2648. +
  2649. + return 0;
  2650. +}
  2651. +
  2652. +/*
  2653. + * DEBUGGING
  2654. + */
  2655. +
  2656. +#ifdef DEBUG
  2657. +struct regdump {
  2658. + u32 addr;
  2659. + char regname[16];
  2660. +};
  2661. +
  2662. +struct regdump type0regs[] = {
  2663. + { 0xfc0a8000, "PCIIDR" },
  2664. + { 0xfc0a8004, "PCISCR" },
  2665. + { 0xfc0a8008, "PCICCRIR" },
  2666. + { 0xfc0a800c, "PCICR1" },
  2667. + { 0xfc0a8010, "PCIBAR0" },
  2668. + { 0xfc0a8014, "PCIBAR1" },
  2669. + { 0xfc0a8018, "PCIBAR2" },
  2670. + { 0xfc0a801c, "PCIBAR3" },
  2671. + { 0xfc0a8020, "PCIBAR4" },
  2672. + { 0xfc0a8024, "PCIBAR5" },
  2673. + { 0xfc0a8028, "PCICCPR" },
  2674. + { 0xfc0a802c, "PCISID" },
  2675. + { 0xfc0a8030, "PCIERBAR" },
  2676. + { 0xfc0a8034, "PCICPR" },
  2677. + { 0xfc0a803c, "PCICR2" },
  2678. + { 0, "" }
  2679. +};
  2680. +
  2681. +struct regdump genregs[] = {
  2682. + { 0xfc0a8060, "PCIGSCR" },
  2683. + { 0xfc0a8064, "PCITBATR0" },
  2684. + { 0xfc0a8068, "PCITBATR1" },
  2685. + { 0xfc0a806c, "PCITCR1" },
  2686. + { 0xfc0a8070, "PCIIW0BTAR" },
  2687. + { 0xfc0a8074, "PCIIW1BTAR" },
  2688. + { 0xfc0a8078, "PCIIW2BTAR" },
  2689. + { 0xfc0a8080, "PCIIWCR" },
  2690. + { 0xfc0a8084, "PCIICR" },
  2691. + { 0xfc0a8088, "PCIISR" },
  2692. + { 0xfc0a808c, "PCITCR2" },
  2693. + { 0xfc0a8090, "PCITBATR0" },
  2694. + { 0xfc0a8094, "PCITBATR1" },
  2695. + { 0xfc0a8098, "PCITBATR2" },
  2696. + { 0xfc0a809c, "PCITBATR3" },
  2697. + { 0xfc0a80a0, "PCITBATR4" },
  2698. + { 0xfc0a80a4, "PCITBATR5" },
  2699. + { 0xfc0a80a8, "PCIINTR" },
  2700. + { 0xfc0a80f8, "PCICAR" },
  2701. + { 0, "" }
  2702. +};
  2703. +
  2704. +struct regdump arbregs[] = {
  2705. + { 0xfc0ac000, "PACR" },
  2706. + { 0xfc0ac004, "PASR" }, /* documentation error */
  2707. + { 0, "" }
  2708. +};
  2709. +
  2710. +/*
  2711. + * void mcf5445x_pci_dumpregs()
  2712. + *
  2713. + * Dump out all the PCI registers
  2714. + */
  2715. +void
  2716. +mcf5445x_pci_dumpregs(void)
  2717. +{
  2718. + struct regdump *reg;
  2719. +
  2720. + printk(KERN_INFO "*** MCF5445x PCI TARGET 0 REGISTERS ***\n");
  2721. +
  2722. + reg = type0regs;
  2723. + while (reg->addr) {
  2724. + printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr,
  2725. + *((u32 *)reg->addr), reg->regname);
  2726. + reg++;
  2727. + }
  2728. +
  2729. + printk(KERN_INFO "\n*** MCF5445x PCI GENERAL REGISTERS ***\n");
  2730. + reg = genregs;
  2731. + while (reg->addr) {
  2732. + printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr,
  2733. + *((u32 *)reg->addr), reg->regname);
  2734. + reg++;
  2735. + }
  2736. + printk(KERN_INFO "\n*** MCF5445x PCI ARBITER REGISTERS ***\n");
  2737. + reg = arbregs;
  2738. + while (reg->addr) {
  2739. + printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr,
  2740. + *((u32 *)reg->addr), reg->regname);
  2741. + reg++;
  2742. + }
  2743. +}
  2744. +#endif /* DEBUG */
  2745. --- /dev/null
  2746. +++ b/arch/m68k/coldfire/muldi3.S
  2747. @@ -0,0 +1,64 @@
  2748. +/*
  2749. + * Coldfire muldi3 assembly verion
  2750. + */
  2751. +
  2752. +#include <linux/linkage.h>
  2753. +.globl __muldi3
  2754. +
  2755. +ENTRY(__muldi3)
  2756. + linkw %fp,#0
  2757. + lea %sp@(-32),%sp
  2758. + moveml %d2-%d7/%a2-%a3,%sp@
  2759. + moveal %fp@(8), %a2
  2760. + moveal %fp@(12), %a3
  2761. + moveal %fp@(16), %a0
  2762. + moveal %fp@(20),%a1
  2763. + movel %a3,%d2
  2764. + andil #65535,%d2
  2765. + movel %a3,%d3
  2766. + clrw %d3
  2767. + swap %d3
  2768. + movel %a1,%d0
  2769. + andil #65535,%d0
  2770. + movel %a1,%d1
  2771. + clrw %d1
  2772. + swap %d1
  2773. + movel %d2,%d7
  2774. + mulsl %d0,%d7
  2775. + movel %d2,%d4
  2776. + mulsl %d1,%d4
  2777. + movel %d3,%d2
  2778. + mulsl %d0,%d2
  2779. + mulsl %d1,%d3
  2780. + movel %d7,%d0
  2781. + clrw %d0
  2782. + swap %d0
  2783. + addl %d0,%d4
  2784. + addl %d2,%d4
  2785. + cmpl %d4,%d2
  2786. + blss 1f
  2787. + addil #65536,%d3
  2788. +1:
  2789. + movel %d4,%d0
  2790. + clrw %d0
  2791. + swap %d0
  2792. + movel %d3,%d5
  2793. + addl %d0,%d5
  2794. + movew %d4,%d6
  2795. + swap %d6
  2796. + movew %d7,%d6
  2797. + movel %d5,%d0
  2798. + movel %d6,%d1
  2799. + movel %a3,%d2
  2800. + movel %a0,%d3
  2801. + mulsl %d3,%d2
  2802. + movel %a2,%d3
  2803. + movel %a1,%d4
  2804. + mulsl %d4,%d3
  2805. + addl %d3,%d2
  2806. + movel %d2,%d0
  2807. + addl %d5,%d0
  2808. + moveml %sp@, %d2-%d7/%a2-%a3
  2809. + lea %sp@(32),%sp
  2810. + unlk %fp
  2811. + rts
  2812. --- /dev/null
  2813. +++ b/arch/m68k/coldfire/pci.c
  2814. @@ -0,0 +1,245 @@
  2815. +/*
  2816. + * linux/arch/m68k/coldfire/pci.c
  2817. + *
  2818. + * PCI initialization for Coldfire architectures.
  2819. + *
  2820. + * Currently Supported:
  2821. + * M5445x
  2822. + *
  2823. + * Copyright (c) 2007 Freescale Semiconductor, Inc.
  2824. + * Kurt Mahan <[email protected]>
  2825. + */
  2826. +
  2827. +#include <linux/kernel.h>
  2828. +#include <linux/init.h>
  2829. +#include <linux/pci.h>
  2830. +
  2831. +#include <asm/mcfsim.h>
  2832. +#include <asm/pci.h>
  2833. +
  2834. +/* pci ops for reading/writing config */
  2835. +struct pci_raw_ops *raw_pci_ops;
  2836. +
  2837. +/* pci debug flag */
  2838. +static int debug_pci;
  2839. +
  2840. +#ifdef CONFIG_M54455
  2841. +extern int init_mcf5445x_pci(void);
  2842. +extern void mcf5445x_conf_device(struct pci_dev *dev);
  2843. +extern void mcf5445x_pci_dumpregs(void);
  2844. +
  2845. +extern struct resource pci_ioport_resource;
  2846. +extern struct resource pci_iomem_resource;
  2847. +#endif
  2848. +
  2849. +static int
  2850. +pci_read(struct pci_bus *bus, unsigned int devfn, int where,
  2851. + int size, u32 *value)
  2852. +{
  2853. + return raw_pci_ops->read(0, bus->number, devfn, where, size, value);
  2854. +}
  2855. +
  2856. +static int
  2857. +pci_write(struct pci_bus *bus, unsigned int devfn, int where,
  2858. + int size, u32 value)
  2859. +{
  2860. + return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
  2861. +}
  2862. +
  2863. +struct pci_ops pci_root_ops = {
  2864. + .read = pci_read,
  2865. + .write = pci_write,
  2866. +};
  2867. +
  2868. +/*
  2869. + * pcibios_setup(char *)
  2870. + *
  2871. + * Initialize the pcibios based on cmd line params.
  2872. + */
  2873. +char * __init
  2874. +pcibios_setup(char *str)
  2875. +{
  2876. + if (!strcmp(str, "debug")) {
  2877. + debug_pci = 1;
  2878. + return NULL;
  2879. + }
  2880. + return str;
  2881. +}
  2882. +
  2883. +/*
  2884. + * We need to avoid collisions with `mirrored' VGA ports
  2885. + * and other strange ISA hardware, so we always want the
  2886. + * addresses to be allocated in the 0x000-0x0ff region
  2887. + * modulo 0x400.
  2888. + *
  2889. + * Why? Because some silly external IO cards only decode
  2890. + * the low 10 bits of the IO address. The 0x00-0xff region
  2891. + * is reserved for motherboard devices that decode all 16
  2892. + * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
  2893. + * but we want to try to avoid allocating at 0x2900-0x2bff
  2894. + * which might have be mirrored at 0x0100-0x03ff..
  2895. + */
  2896. +void
  2897. +pcibios_align_resource(void *data, struct resource *res, resource_size_t size,
  2898. + resource_size_t align)
  2899. +{
  2900. + struct pci_dev *dev = data;
  2901. +
  2902. + if (res->flags & IORESOURCE_IO) {
  2903. + resource_size_t start = res->start;
  2904. +
  2905. + if (size > 0x100)
  2906. + printk(KERN_ERR "PCI: I/O Region %s/%d too large"
  2907. + " (%ld bytes)\n", pci_name(dev),
  2908. + dev->resource - res, (long int)size);
  2909. +
  2910. + if (start & 0x300) {
  2911. + start = (start + 0x3ff) & ~0x3ff;
  2912. + res->start = start;
  2913. + }
  2914. + }
  2915. +}
  2916. +
  2917. +/*
  2918. + * Swizzle the device pin each time we cross a bridge
  2919. + * and return the slot number.
  2920. + */
  2921. +static u8 __devinit
  2922. +pcibios_swizzle(struct pci_dev *dev, u8 *pin)
  2923. +{
  2924. + return 0;
  2925. +}
  2926. +
  2927. +/*
  2928. + * Map a slot/pin to an IRQ.
  2929. + */
  2930. +static int
  2931. +pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  2932. +{
  2933. + return 0x43;
  2934. +}
  2935. +
  2936. +/*
  2937. + * pcibios_update_irq(struct pci_dev *dev, int irq)
  2938. + *
  2939. + * Update a PCI interrupt.
  2940. + */
  2941. +void __init
  2942. +pcibios_update_irq(struct pci_dev *dev, int irq)
  2943. +{
  2944. + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  2945. +}
  2946. +
  2947. +/*
  2948. + * pcibios_enable_device(struct pci_dev *dev, int mask)
  2949. + *
  2950. + * Enable a device on the PCI bus.
  2951. + */
  2952. +int
  2953. +pcibios_enable_device(struct pci_dev *dev, int mask)
  2954. +{
  2955. + u16 cmd, old_cmd;
  2956. + int idx;
  2957. + struct resource *r;
  2958. +
  2959. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  2960. + old_cmd = cmd;
  2961. + for (idx = 0; idx < 6; idx++) {
  2962. + r = &dev->resource[idx];
  2963. + if (!r->start && r->end) {
  2964. + printk(KERN_ERR "PCI: Device %s not available because "
  2965. + "of resource collisions\n", pci_name(dev));
  2966. + return -EINVAL;
  2967. + }
  2968. + if (r->flags & IORESOURCE_IO)
  2969. + cmd |= PCI_COMMAND_IO;
  2970. + if (r->flags & IORESOURCE_MEM)
  2971. + cmd |= PCI_COMMAND_MEMORY;
  2972. + }
  2973. + if (cmd != old_cmd) {
  2974. + printk("PCI: Enabling device %s (%04x -> %04x)\n",
  2975. + pci_name(dev), old_cmd, cmd);
  2976. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  2977. +#ifdef CONFIG_M54455
  2978. + mcf5445x_conf_device(dev);
  2979. +#endif
  2980. + }
  2981. +
  2982. + return 0;
  2983. +}
  2984. +
  2985. +/*
  2986. + * pcibios_fixup_bus(struct pci_bus *bus)
  2987. + */
  2988. +void __init
  2989. +pcibios_fixup_bus(struct pci_bus *bus)
  2990. +{
  2991. + struct pci_dev *dev = bus->self;
  2992. +
  2993. + if (!dev) {
  2994. + /* Root bus. */
  2995. +#ifdef CONFIG_M54455
  2996. + bus->resource[0] = &pci_ioport_resource;
  2997. + bus->resource[1] = &pci_iomem_resource;
  2998. +#endif
  2999. + }
  3000. +}
  3001. +
  3002. +/*
  3003. + * pcibios_init(void)
  3004. + *
  3005. + * Allocate/initialize low level pci bus/devices.
  3006. + */
  3007. +static int __init
  3008. +pcibios_init(void)
  3009. +{
  3010. + struct pci_bus *bus;
  3011. +
  3012. + if (!raw_pci_ops) {
  3013. + printk(KERN_WARNING "PCIBIOS: FATAL: NO PCI Hardware found\n");
  3014. + return 0;
  3015. + }
  3016. +
  3017. + /* allocate and scan the (only) bus */
  3018. + bus = pci_scan_bus_parented(NULL, 0, &pci_root_ops, NULL);
  3019. +
  3020. + /* setup everything */
  3021. + if (bus) {
  3022. + /* compute the bridge window sizes */
  3023. + pci_bus_size_bridges(bus);
  3024. +
  3025. + /* (re)assign device resources */
  3026. + pci_bus_assign_resources(bus);
  3027. +
  3028. + /* add the bus to the system */
  3029. + pci_bus_add_devices(bus);
  3030. +
  3031. + /* fixup irqs */
  3032. + pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
  3033. + }
  3034. +
  3035. + return 0;
  3036. +}
  3037. +
  3038. +/*
  3039. + * pci_init(void)
  3040. + *
  3041. + * Initialize the PCI Hardware.
  3042. + */
  3043. +static int __init
  3044. +pci_init(void)
  3045. +{
  3046. +#if defined(CONFIG_M54455)
  3047. + init_mcf5445x_pci();
  3048. +#endif
  3049. + if (!raw_pci_ops)
  3050. + printk(KERN_ERR "PCI: FATAL: NO PCI Detected\n");
  3051. +
  3052. + return 0;
  3053. +}
  3054. +
  3055. +/* low level hardware (first) */
  3056. +arch_initcall(pci_init);
  3057. +
  3058. +/* basic bios init (second) */
  3059. +subsys_initcall(pcibios_init);
  3060. --- /dev/null
  3061. +++ b/arch/m68k/coldfire/signal.c
  3062. @@ -0,0 +1,868 @@
  3063. +/*
  3064. + * linux/arch/m68k/kernel/signal.c
  3065. + *
  3066. + * Copyright (C) 1991, 1992 Linus Torvalds
  3067. + *
  3068. + * This file is subject to the terms and conditions of the GNU General Public
  3069. + * License. See the file COPYING in the main directory of this archive
  3070. + * for more details.
  3071. + */
  3072. +
  3073. +/*
  3074. + * Derived from m68k/kernel/signal.c and the original authors are credited
  3075. + * there.
  3076. + *
  3077. + * Coldfire support by:
  3078. + * Matt Waddel [email protected]
  3079. + * Copyright Freescale Semiconductor, Inc 2007
  3080. + */
  3081. +
  3082. +#include <linux/sched.h>
  3083. +#include <linux/mm.h>
  3084. +#include <linux/kernel.h>
  3085. +#include <linux/signal.h>
  3086. +#include <linux/syscalls.h>
  3087. +#include <linux/errno.h>
  3088. +#include <linux/wait.h>
  3089. +#include <linux/ptrace.h>
  3090. +#include <linux/unistd.h>
  3091. +#include <linux/stddef.h>
  3092. +#include <linux/highuid.h>
  3093. +#include <linux/personality.h>
  3094. +#include <linux/tty.h>
  3095. +#include <linux/binfmts.h>
  3096. +
  3097. +#include <asm/setup.h>
  3098. +#include <asm/cf_uaccess.h>
  3099. +#include <asm/cf_pgtable.h>
  3100. +#include <asm/traps.h>
  3101. +#include <asm/ucontext.h>
  3102. +
  3103. +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  3104. +
  3105. +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
  3106. +
  3107. +const int frame_extra_sizes[16] = {
  3108. + [1] = -1,
  3109. + [2] = sizeof(((struct frame *)0)->un.fmt2),
  3110. + [3] = sizeof(((struct frame *)0)->un.fmt3),
  3111. + [4] = 0,
  3112. + [5] = -1,
  3113. + [6] = -1,
  3114. + [7] = sizeof(((struct frame *)0)->un.fmt7),
  3115. + [8] = -1,
  3116. + [9] = sizeof(((struct frame *)0)->un.fmt9),
  3117. + [10] = sizeof(((struct frame *)0)->un.fmta),
  3118. + [11] = sizeof(((struct frame *)0)->un.fmtb),
  3119. + [12] = -1,
  3120. + [13] = -1,
  3121. + [14] = -1,
  3122. + [15] = -1,
  3123. +};
  3124. +
  3125. +/*
  3126. + * Atomically swap in the new signal mask, and wait for a signal.
  3127. + */
  3128. +asmlinkage int do_sigsuspend(struct pt_regs *regs)
  3129. +{
  3130. + old_sigset_t mask = regs->d3;
  3131. + sigset_t saveset;
  3132. +
  3133. + mask &= _BLOCKABLE;
  3134. + spin_lock_irq(&current->sighand->siglock);
  3135. + saveset = current->blocked;
  3136. + siginitset(&current->blocked, mask);
  3137. + recalc_sigpending();
  3138. + spin_unlock_irq(&current->sighand->siglock);
  3139. +
  3140. + regs->d0 = -EINTR;
  3141. + while (1) {
  3142. + current->state = TASK_INTERRUPTIBLE;
  3143. + schedule();
  3144. + if (do_signal(&saveset, regs))
  3145. + return -EINTR;
  3146. + }
  3147. +}
  3148. +
  3149. +asmlinkage int
  3150. +do_rt_sigsuspend(struct pt_regs *regs)
  3151. +{
  3152. + sigset_t __user *unewset = (sigset_t __user *)regs->d1;
  3153. + size_t sigsetsize = (size_t)regs->d2;
  3154. + sigset_t saveset, newset;
  3155. +
  3156. + /* XXX: Don't preclude handling different sized sigset_t's. */
  3157. + if (sigsetsize != sizeof(sigset_t))
  3158. + return -EINVAL;
  3159. +
  3160. + if (copy_from_user(&newset, unewset, sizeof(newset)))
  3161. + return -EFAULT;
  3162. + sigdelsetmask(&newset, ~_BLOCKABLE);
  3163. +
  3164. + spin_lock_irq(&current->sighand->siglock);
  3165. + saveset = current->blocked;
  3166. + current->blocked = newset;
  3167. + recalc_sigpending();
  3168. + spin_unlock_irq(&current->sighand->siglock);
  3169. +
  3170. + regs->d0 = -EINTR;
  3171. + while (1) {
  3172. + current->state = TASK_INTERRUPTIBLE;
  3173. + schedule();
  3174. + if (do_signal(&saveset, regs))
  3175. + return -EINTR;
  3176. + }
  3177. +}
  3178. +
  3179. +asmlinkage int
  3180. +sys_sigaction(int sig, const struct old_sigaction __user *act,
  3181. + struct old_sigaction __user *oact)
  3182. +{
  3183. + struct k_sigaction new_ka, old_ka;
  3184. + int ret;
  3185. +
  3186. + if (act) {
  3187. + old_sigset_t mask;
  3188. + if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
  3189. + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
  3190. + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
  3191. + return -EFAULT;
  3192. + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
  3193. + __get_user(mask, &act->sa_mask);
  3194. + siginitset(&new_ka.sa.sa_mask, mask);
  3195. + }
  3196. +
  3197. + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  3198. +
  3199. + if (!ret && oact) {
  3200. + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
  3201. + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
  3202. + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
  3203. + return -EFAULT;
  3204. + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  3205. + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
  3206. + }
  3207. +
  3208. + return ret;
  3209. +}
  3210. +
  3211. +asmlinkage int
  3212. +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
  3213. +{
  3214. + return do_sigaltstack(uss, uoss, rdusp());
  3215. +}
  3216. +
  3217. +
  3218. +/*
  3219. + * Do a signal return; undo the signal stack.
  3220. + *
  3221. + * Keep the return code on the stack quadword aligned!
  3222. + * That makes the cache flush below easier.
  3223. + */
  3224. +
  3225. +struct sigframe
  3226. +{
  3227. + char __user *pretcode;
  3228. + int sig;
  3229. + int code;
  3230. + struct sigcontext __user *psc;
  3231. + char retcode[16];
  3232. + unsigned long extramask[_NSIG_WORDS-1];
  3233. + struct sigcontext sc;
  3234. +};
  3235. +
  3236. +struct rt_sigframe
  3237. +{
  3238. + char __user *pretcode;
  3239. + int sig;
  3240. + struct siginfo __user *pinfo;
  3241. + void __user *puc;
  3242. + char retcode[16];
  3243. + struct siginfo info;
  3244. + struct ucontext uc;
  3245. +};
  3246. +
  3247. +#define FPCONTEXT_SIZE 216
  3248. +#define uc_fpstate uc_filler[0]
  3249. +#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
  3250. +#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
  3251. +
  3252. +#ifdef CONFIG_FPU
  3253. +static unsigned char fpu_version; /* version num of fpu, set by setup_frame */
  3254. +
  3255. +static inline int restore_fpu_state(struct sigcontext *sc)
  3256. +{
  3257. + int err = 1;
  3258. +
  3259. + if (FPU_IS_EMU) {
  3260. + /* restore registers */
  3261. + memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
  3262. + memcpy(current->thread.fp, sc->sc_fpregs, 24);
  3263. + return 0;
  3264. + }
  3265. +
  3266. + if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
  3267. + /* Verify the frame format. */
  3268. + if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
  3269. + goto out;
  3270. + if (CPU_IS_020_OR_030) {
  3271. + if (m68k_fputype & FPU_68881 &&
  3272. + !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
  3273. + goto out;
  3274. + if (m68k_fputype & FPU_68882 &&
  3275. + !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
  3276. + goto out;
  3277. + } else if (CPU_IS_040) {
  3278. + if (!(sc->sc_fpstate[1] == 0x00 ||
  3279. + sc->sc_fpstate[1] == 0x28 ||
  3280. + sc->sc_fpstate[1] == 0x60))
  3281. + goto out;
  3282. + } else if (CPU_IS_060) {
  3283. + if (!(sc->sc_fpstate[3] == 0x00 ||
  3284. + sc->sc_fpstate[3] == 0x60 ||
  3285. + sc->sc_fpstate[3] == 0xe0))
  3286. + goto out;
  3287. + } else
  3288. + goto out;
  3289. +
  3290. + }
  3291. + err = 0;
  3292. +
  3293. +out:
  3294. + return err;
  3295. +}
  3296. +
  3297. +static inline int rt_restore_fpu_state(struct ucontext __user *uc)
  3298. +{
  3299. + unsigned char fpstate[FPCONTEXT_SIZE];
  3300. + int context_size = CPU_IS_060 ? 8 : 0;
  3301. + fpregset_t fpregs;
  3302. + int err = 1;
  3303. +
  3304. + if (FPU_IS_EMU) {
  3305. + /* restore fpu control register */
  3306. + if (__copy_from_user(current->thread.fpcntl,
  3307. + uc->uc_mcontext.fpregs.f_fpcntl, 12))
  3308. + goto out;
  3309. + /* restore all other fpu register */
  3310. + if (__copy_from_user(current->thread.fp,
  3311. + uc->uc_mcontext.fpregs.f_fpregs, 96))
  3312. + goto out;
  3313. + return 0;
  3314. + }
  3315. +
  3316. + if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
  3317. + goto out;
  3318. + if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
  3319. + if (!CPU_IS_060)
  3320. + context_size = fpstate[1];
  3321. + /* Verify the frame format. */
  3322. + if (!CPU_IS_060 && (fpstate[0] != fpu_version))
  3323. + goto out;
  3324. + if (CPU_IS_020_OR_030) {
  3325. + if (m68k_fputype & FPU_68881 &&
  3326. + !(context_size == 0x18 || context_size == 0xb4))
  3327. + goto out;
  3328. + if (m68k_fputype & FPU_68882 &&
  3329. + !(context_size == 0x38 || context_size == 0xd4))
  3330. + goto out;
  3331. + } else if (CPU_IS_040) {
  3332. + if (!(context_size == 0x00 ||
  3333. + context_size == 0x28 ||
  3334. + context_size == 0x60))
  3335. + goto out;
  3336. + } else if (CPU_IS_060) {
  3337. + if (!(fpstate[3] == 0x00 ||
  3338. + fpstate[3] == 0x60 ||
  3339. + fpstate[3] == 0xe0))
  3340. + goto out;
  3341. + } else
  3342. + goto out;
  3343. + if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
  3344. + sizeof(fpregs)))
  3345. + goto out;
  3346. + }
  3347. + if (context_size &&
  3348. + __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
  3349. + context_size))
  3350. + goto out;
  3351. + err = 0;
  3352. +
  3353. +out:
  3354. + return err;
  3355. +}
  3356. +#endif
  3357. +
  3358. +static inline int
  3359. +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc,
  3360. + void __user *fp, int *pd0)
  3361. +{
  3362. + int fsize, formatvec;
  3363. + struct sigcontext context;
  3364. + int err = 0;
  3365. +
  3366. + /* get previous context */
  3367. + if (copy_from_user(&context, usc, sizeof(context)))
  3368. + goto badframe;
  3369. +
  3370. + /* restore passed registers */
  3371. + regs->d1 = context.sc_d1;
  3372. + regs->a0 = context.sc_a0;
  3373. + regs->a1 = context.sc_a1;
  3374. + regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
  3375. + regs->pc = context.sc_pc;
  3376. + regs->orig_d0 = -1; /* disable syscall checks */
  3377. + wrusp(context.sc_usp);
  3378. + formatvec = context.sc_formatvec;
  3379. + regs->format = formatvec >> 12;
  3380. + regs->vector = formatvec & 0xfff;
  3381. +
  3382. +#ifdef CONFIG_FPU
  3383. + err = restore_fpu_state(&context);
  3384. +#endif
  3385. +
  3386. + fsize = frame_extra_sizes[regs->format];
  3387. + if (fsize < 0) {
  3388. + /*
  3389. + * user process trying to return with weird frame format
  3390. + */
  3391. +#ifdef DEBUG
  3392. + printk(KERN_DEBUG "user process returning with weird \
  3393. + frame format\n");
  3394. +#endif
  3395. + goto badframe;
  3396. + }
  3397. +
  3398. + /* OK. Make room on the supervisor stack for the extra junk,
  3399. + * if necessary.
  3400. + */
  3401. +
  3402. + {
  3403. + struct switch_stack *sw = (struct switch_stack *)regs - 1;
  3404. + regs->d0 = context.sc_d0;
  3405. +#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
  3406. + __asm__ __volatile__
  3407. + (" movel %0,%/sp\n\t"
  3408. + " bra ret_from_signal\n"
  3409. + "4:\n"
  3410. + ".section __ex_table,\"a\"\n"
  3411. + " .align 4\n"
  3412. + " .long 2b,4b\n"
  3413. + ".previous"
  3414. + : /* no outputs, it doesn't ever return */
  3415. + : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
  3416. + "n" (frame_offset), "a" (fp)
  3417. + : "a0");
  3418. +#undef frame_offset
  3419. + /*
  3420. + * If we ever get here an exception occurred while
  3421. + * building the above stack-frame.
  3422. + */
  3423. + goto badframe;
  3424. + }
  3425. +
  3426. + *pd0 = context.sc_d0;
  3427. + return err;
  3428. +
  3429. +badframe:
  3430. + return 1;
  3431. +}
  3432. +
  3433. +static inline int
  3434. +rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
  3435. + struct ucontext __user *uc, int *pd0)
  3436. +{
  3437. + int fsize, temp;
  3438. + greg_t __user *gregs = uc->uc_mcontext.gregs;
  3439. + unsigned long usp;
  3440. + int err;
  3441. +
  3442. + err = __get_user(temp, &uc->uc_mcontext.version);
  3443. + if (temp != MCONTEXT_VERSION)
  3444. + goto badframe;
  3445. + /* restore passed registers */
  3446. + err |= __get_user(regs->d0, &gregs[0]);
  3447. + err |= __get_user(regs->d1, &gregs[1]);
  3448. + err |= __get_user(regs->d2, &gregs[2]);
  3449. + err |= __get_user(regs->d3, &gregs[3]);
  3450. + err |= __get_user(regs->d4, &gregs[4]);
  3451. + err |= __get_user(regs->d5, &gregs[5]);
  3452. + err |= __get_user(sw->d6, &gregs[6]);
  3453. + err |= __get_user(sw->d7, &gregs[7]);
  3454. + err |= __get_user(regs->a0, &gregs[8]);
  3455. + err |= __get_user(regs->a1, &gregs[9]);
  3456. + err |= __get_user(regs->a2, &gregs[10]);
  3457. + err |= __get_user(sw->a3, &gregs[11]);
  3458. + err |= __get_user(sw->a4, &gregs[12]);
  3459. + err |= __get_user(sw->a5, &gregs[13]);
  3460. + err |= __get_user(sw->a6, &gregs[14]);
  3461. + err |= __get_user(usp, &gregs[15]);
  3462. + wrusp(usp);
  3463. + err |= __get_user(regs->pc, &gregs[16]);
  3464. + err |= __get_user(temp, &gregs[17]);
  3465. + regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
  3466. + regs->orig_d0 = -1; /* disable syscall checks */
  3467. + err |= __get_user(temp, &uc->uc_formatvec);
  3468. + regs->format = temp >> 12;
  3469. + regs->vector = temp & 0xfff;
  3470. +
  3471. +#ifdef CONFIG_FPU
  3472. + err |= rt_restore_fpu_state(uc);
  3473. +#endif
  3474. +
  3475. + if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
  3476. + goto badframe;
  3477. +
  3478. + fsize = frame_extra_sizes[regs->format];
  3479. + if (fsize < 0) {
  3480. + /*
  3481. + * user process trying to return with weird frame format
  3482. + */
  3483. +#ifdef DEBUG
  3484. + printk(KERN_DEBUG "user process returning with weird \
  3485. + frame format\n");
  3486. +#endif
  3487. + goto badframe;
  3488. + }
  3489. +
  3490. + /* OK. Make room on the supervisor stack for the extra junk,
  3491. + * if necessary.
  3492. + */
  3493. +
  3494. + {
  3495. +#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
  3496. + __asm__ __volatile__
  3497. + (" movel %0,%/sp\n\t"
  3498. + " bra ret_from_signal\n"
  3499. + "4:\n"
  3500. + ".section __ex_table,\"a\"\n"
  3501. + " .align 4\n"
  3502. + " .long 2b,4b\n"
  3503. + ".previous"
  3504. + : /* no outputs, it doesn't ever return */
  3505. + : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
  3506. + "n" (frame_offset), "a" (&uc->uc_extra)
  3507. + : "a0");
  3508. +#undef frame_offset
  3509. + /*
  3510. + * If we ever get here an exception occurred while
  3511. + * building the above stack-frame.
  3512. + */
  3513. + goto badframe;
  3514. + }
  3515. +
  3516. + *pd0 = regs->d0;
  3517. + return err;
  3518. +
  3519. +badframe:
  3520. + return 1;
  3521. +}
  3522. +
  3523. +asmlinkage int do_sigreturn(unsigned long __unused)
  3524. +{
  3525. + struct switch_stack *sw = (struct switch_stack *) &__unused;
  3526. + struct pt_regs *regs = (struct pt_regs *) (sw + 1);
  3527. + unsigned long usp = rdusp();
  3528. + struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
  3529. + sigset_t set;
  3530. + int d0;
  3531. +
  3532. + if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
  3533. + goto badframe;
  3534. + if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
  3535. + (_NSIG_WORDS > 1 &&
  3536. + __copy_from_user(&set.sig[1], &frame->extramask,
  3537. + sizeof(frame->extramask))))
  3538. + goto badframe;
  3539. +
  3540. + sigdelsetmask(&set, ~_BLOCKABLE);
  3541. + spin_lock_irq(&current->sighand->siglock);
  3542. + current->blocked = set;
  3543. + recalc_sigpending();
  3544. + spin_unlock_irq(&current->sighand->siglock);
  3545. +
  3546. + if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
  3547. + goto badframe;
  3548. + return d0;
  3549. +
  3550. +badframe:
  3551. + force_sig(SIGSEGV, current);
  3552. + return 0;
  3553. +}
  3554. +
  3555. +asmlinkage int do_rt_sigreturn(unsigned long __unused)
  3556. +{
  3557. + struct switch_stack *sw = (struct switch_stack *) &__unused;
  3558. + struct pt_regs *regs = (struct pt_regs *) (sw + 1);
  3559. + unsigned long usp = rdusp();
  3560. + struct rt_sigframe __user *frame =
  3561. + (struct rt_sigframe __user *)(usp - 4);
  3562. + sigset_t set;
  3563. + int d0;
  3564. +
  3565. + if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
  3566. + goto badframe;
  3567. + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
  3568. + goto badframe;
  3569. +
  3570. + sigdelsetmask(&set, ~_BLOCKABLE);
  3571. + spin_lock_irq(&current->sighand->siglock);
  3572. + current->blocked = set;
  3573. + recalc_sigpending();
  3574. + spin_unlock_irq(&current->sighand->siglock);
  3575. +
  3576. + if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
  3577. + goto badframe;
  3578. + return d0;
  3579. +
  3580. +badframe:
  3581. + force_sig(SIGSEGV, current);
  3582. + return 0;
  3583. +}
  3584. +
  3585. +#ifdef CONFIG_FPU
  3586. +/*
  3587. + * Set up a signal frame.
  3588. + */
  3589. +
  3590. +static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
  3591. +{
  3592. + if (FPU_IS_EMU) {
  3593. + /* save registers */
  3594. + memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
  3595. + memcpy(sc->sc_fpregs, current->thread.fp, 24);
  3596. + return;
  3597. + }
  3598. +}
  3599. +
  3600. +static inline int rt_save_fpu_state(struct ucontext __user *uc,
  3601. + struct pt_regs *regs)
  3602. +{
  3603. + int err = 0;
  3604. +
  3605. + if (FPU_IS_EMU) {
  3606. + /* save fpu control register */
  3607. + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
  3608. + current->thread.fpcntl, 12);
  3609. + /* save all other fpu register */
  3610. + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
  3611. + current->thread.fp, 96);
  3612. + return err;
  3613. + }
  3614. +
  3615. + return err;
  3616. +}
  3617. +#endif
  3618. +
  3619. +static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
  3620. + unsigned long mask)
  3621. +{
  3622. + sc->sc_mask = mask;
  3623. + sc->sc_usp = rdusp();
  3624. + sc->sc_d0 = regs->d0;
  3625. + sc->sc_d1 = regs->d1;
  3626. + sc->sc_a0 = regs->a0;
  3627. + sc->sc_a1 = regs->a1;
  3628. + sc->sc_sr = regs->sr;
  3629. + sc->sc_pc = regs->pc;
  3630. + sc->sc_formatvec = regs->format << 12 | regs->vector;
  3631. +#ifdef CONFIG_FPU
  3632. + save_fpu_state(sc, regs);
  3633. +#endif
  3634. +}
  3635. +
  3636. +static inline int rt_setup_ucontext(struct ucontext __user *uc,
  3637. + struct pt_regs *regs)
  3638. +{
  3639. + struct switch_stack *sw = (struct switch_stack *)regs - 1;
  3640. + greg_t __user *gregs = uc->uc_mcontext.gregs;
  3641. + int err = 0;
  3642. +
  3643. + err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
  3644. + err |= __put_user(regs->d0, &gregs[0]);
  3645. + err |= __put_user(regs->d1, &gregs[1]);
  3646. + err |= __put_user(regs->d2, &gregs[2]);
  3647. + err |= __put_user(regs->d3, &gregs[3]);
  3648. + err |= __put_user(regs->d4, &gregs[4]);
  3649. + err |= __put_user(regs->d5, &gregs[5]);
  3650. + err |= __put_user(sw->d6, &gregs[6]);
  3651. + err |= __put_user(sw->d7, &gregs[7]);
  3652. + err |= __put_user(regs->a0, &gregs[8]);
  3653. + err |= __put_user(regs->a1, &gregs[9]);
  3654. + err |= __put_user(regs->a2, &gregs[10]);
  3655. + err |= __put_user(sw->a3, &gregs[11]);
  3656. + err |= __put_user(sw->a4, &gregs[12]);
  3657. + err |= __put_user(sw->a5, &gregs[13]);
  3658. + err |= __put_user(sw->a6, &gregs[14]);
  3659. + err |= __put_user(rdusp(), &gregs[15]);
  3660. + err |= __put_user(regs->pc, &gregs[16]);
  3661. + err |= __put_user(regs->sr, &gregs[17]);
  3662. + err |= __put_user((regs->format << 12) | regs->vector,
  3663. + &uc->uc_formatvec);
  3664. +#ifdef CONFIG_FPU
  3665. + err |= rt_save_fpu_state(uc, regs);
  3666. +#endif
  3667. + return err;
  3668. +}
  3669. +
  3670. +extern void IcacheInvalidateCacheBlock(void *, unsigned long);
  3671. +static inline void push_cache(unsigned long vaddr)
  3672. +{
  3673. + IcacheInvalidateCacheBlock((void *)vaddr, 8);
  3674. +}
  3675. +
  3676. +static inline void __user *
  3677. +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
  3678. +{
  3679. + unsigned long usp;
  3680. +
  3681. + /* Default to using normal stack. */
  3682. + usp = rdusp();
  3683. +
  3684. + /* This is the X/Open sanctioned signal stack switching. */
  3685. + if (ka->sa.sa_flags & SA_ONSTACK) {
  3686. + if (!sas_ss_flags(usp))
  3687. + usp = current->sas_ss_sp + current->sas_ss_size;
  3688. + }
  3689. + return (void __user *)((usp - frame_size) & -8UL);
  3690. +}
  3691. +
  3692. +static void setup_frame(int sig, struct k_sigaction *ka,
  3693. + sigset_t *set, struct pt_regs *regs)
  3694. +{
  3695. + struct sigframe __user *frame;
  3696. + int fsize = frame_extra_sizes[regs->format];
  3697. + struct sigcontext context;
  3698. + int err = 0;
  3699. +
  3700. + if (fsize < 0) {
  3701. +#ifdef DEBUG
  3702. + printk(KERN_DEBUG "setup_frame: Unknown frame format %#x\n",
  3703. + regs->format);
  3704. +#endif
  3705. + goto give_sigsegv;
  3706. + }
  3707. +
  3708. + frame = get_sigframe(ka, regs, sizeof(*frame));
  3709. +
  3710. + err |= __put_user((current_thread_info()->exec_domain
  3711. + && current_thread_info()->exec_domain->signal_invmap
  3712. + && sig < 32
  3713. + ? current_thread_info()->exec_domain->signal_invmap[sig]
  3714. + : sig),
  3715. + &frame->sig);
  3716. +
  3717. + err |= __put_user(regs->vector, &frame->code);
  3718. + err |= __put_user(&frame->sc, &frame->psc);
  3719. +
  3720. + if (_NSIG_WORDS > 1)
  3721. + err |= copy_to_user(frame->extramask, &set->sig[1],
  3722. + sizeof(frame->extramask));
  3723. +
  3724. + setup_sigcontext(&context, regs, set->sig[0]);
  3725. + err |= copy_to_user(&frame->sc, &context, sizeof(context));
  3726. +
  3727. + /* Set up to return from userspace. */
  3728. + err |= __put_user(frame->retcode, &frame->pretcode);
  3729. + /* moveq #,d0; trap #0 */
  3730. + err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
  3731. + (long __user *)(frame->retcode));
  3732. +
  3733. + if (err)
  3734. + goto give_sigsegv;
  3735. +
  3736. + push_cache((unsigned long) &frame->retcode);
  3737. +
  3738. + /* Set up registers for signal handler */
  3739. + wrusp((unsigned long) frame);
  3740. + regs->pc = (unsigned long) ka->sa.sa_handler;
  3741. +
  3742. +adjust_stack:
  3743. + /* Prepare to skip over the extra stuff in the exception frame. */
  3744. + if (regs->stkadj) {
  3745. + struct pt_regs *tregs =
  3746. + (struct pt_regs *)((ulong)regs + regs->stkadj);
  3747. +#ifdef DEBUG
  3748. + printk(KERN_DEBUG "Performing stackadjust=%04x\n",
  3749. + regs->stkadj);
  3750. +#endif
  3751. + /* This must be copied with decreasing addresses to
  3752. + handle overlaps. */
  3753. + tregs->vector = 0;
  3754. + tregs->format = 0;
  3755. + tregs->pc = regs->pc;
  3756. + tregs->sr = regs->sr;
  3757. + }
  3758. + return;
  3759. +
  3760. +give_sigsegv:
  3761. + force_sigsegv(sig, current);
  3762. + goto adjust_stack;
  3763. +}
  3764. +
  3765. +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
  3766. + sigset_t *set, struct pt_regs *regs)
  3767. +{
  3768. + struct rt_sigframe __user *frame;
  3769. + int fsize = frame_extra_sizes[regs->format];
  3770. + int err = 0;
  3771. +
  3772. + if (fsize < 0) {
  3773. +#ifdef DEBUG
  3774. + printk(KERN_DEBUG "setup_frame: Unknown frame format %#x\n",
  3775. + regs->format);
  3776. +#endif
  3777. + goto give_sigsegv;
  3778. + }
  3779. +
  3780. + frame = get_sigframe(ka, regs, sizeof(*frame));
  3781. +
  3782. + if (fsize) {
  3783. + err |= copy_to_user(&frame->uc.uc_extra, regs + 1, fsize);
  3784. + regs->stkadj = fsize;
  3785. + }
  3786. +
  3787. + err |= __put_user((current_thread_info()->exec_domain
  3788. + && current_thread_info()->exec_domain->signal_invmap
  3789. + && sig < 32
  3790. + ? current_thread_info()->exec_domain->signal_invmap[sig]
  3791. + : sig),
  3792. + &frame->sig);
  3793. + err |= __put_user(&frame->info, &frame->pinfo);
  3794. + err |= __put_user(&frame->uc, &frame->puc);
  3795. + err |= copy_siginfo_to_user(&frame->info, info);
  3796. +
  3797. + /* Create the ucontext. */
  3798. + err |= __put_user(0, &frame->uc.uc_flags);
  3799. + err |= __put_user(NULL, &frame->uc.uc_link);
  3800. + err |= __put_user((void __user *)current->sas_ss_sp,
  3801. + &frame->uc.uc_stack.ss_sp);
  3802. + err |= __put_user(sas_ss_flags(rdusp()),
  3803. + &frame->uc.uc_stack.ss_flags);
  3804. + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
  3805. + err |= rt_setup_ucontext(&frame->uc, regs);
  3806. + err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  3807. +
  3808. + /* Set up to return from userspace. */
  3809. + err |= __put_user(frame->retcode, &frame->pretcode);
  3810. +
  3811. + /* moveq #,d0; andi.l #,D0; trap #0 */
  3812. + err |= __put_user(0x70AD0280, (long *)(frame->retcode + 0));
  3813. + err |= __put_user(0x000000ff, (long *)(frame->retcode + 4));
  3814. + err |= __put_user(0x4e400000, (long *)(frame->retcode + 8));
  3815. +
  3816. + if (err)
  3817. + goto give_sigsegv;
  3818. +
  3819. + push_cache((unsigned long) &frame->retcode);
  3820. +
  3821. + /* Set up registers for signal handler */
  3822. + wrusp((unsigned long) frame);
  3823. + regs->pc = (unsigned long) ka->sa.sa_handler;
  3824. +
  3825. +adjust_stack:
  3826. + /* Prepare to skip over the extra stuff in the exception frame. */
  3827. + if (regs->stkadj) {
  3828. + struct pt_regs *tregs =
  3829. + (struct pt_regs *)((ulong)regs + regs->stkadj);
  3830. +#ifdef DEBUG
  3831. + printk(KERN_DEBUG "Performing stackadjust=%04x\n",
  3832. + regs->stkadj);
  3833. +#endif
  3834. + /* This must be copied with decreasing addresses to
  3835. + handle overlaps. */
  3836. + tregs->vector = 0;
  3837. + tregs->format = 0;
  3838. + tregs->pc = regs->pc;
  3839. + tregs->sr = regs->sr;
  3840. + }
  3841. + return;
  3842. +
  3843. +give_sigsegv:
  3844. + force_sigsegv(sig, current);
  3845. + goto adjust_stack;
  3846. +}
  3847. +
  3848. +static inline void
  3849. +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
  3850. +{
  3851. + switch (regs->d0) {
  3852. + case -ERESTARTNOHAND:
  3853. + if (!has_handler)
  3854. + goto do_restart;
  3855. + regs->d0 = -EINTR;
  3856. + break;
  3857. +
  3858. + case -ERESTARTSYS:
  3859. + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
  3860. + regs->d0 = -EINTR;
  3861. + break;
  3862. + }
  3863. + /* fallthrough */
  3864. + case -ERESTARTNOINTR:
  3865. +do_restart:
  3866. + regs->d0 = regs->orig_d0;
  3867. + regs->pc -= 2;
  3868. + break;
  3869. + }
  3870. +}
  3871. +
  3872. +/*
  3873. + * OK, we're invoking a handler
  3874. + */
  3875. +static void
  3876. +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
  3877. + sigset_t *oldset, struct pt_regs *regs)
  3878. +{
  3879. + /* are we from a system call? */
  3880. + if (regs->orig_d0 >= 0)
  3881. + /* If so, check system call restarting.. */
  3882. + handle_restart(regs, ka, 1);
  3883. +
  3884. + /* set up the stack frame */
  3885. + if (ka->sa.sa_flags & SA_SIGINFO)
  3886. + setup_rt_frame(sig, ka, info, oldset, regs);
  3887. + else
  3888. + setup_frame(sig, ka, oldset, regs);
  3889. +
  3890. + if (ka->sa.sa_flags & SA_ONESHOT)
  3891. + ka->sa.sa_handler = SIG_DFL;
  3892. +
  3893. + spin_lock_irq(&current->sighand->siglock);
  3894. + sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
  3895. + if (!(ka->sa.sa_flags & SA_NODEFER))
  3896. + sigaddset(&current->blocked, sig);
  3897. + recalc_sigpending();
  3898. + spin_unlock_irq(&current->sighand->siglock);
  3899. +}
  3900. +
  3901. +/*
  3902. + * Note that 'init' is a special process: it doesn't get signals it doesn't
  3903. + * want to handle. Thus you cannot kill init even with a SIGKILL even by
  3904. + * mistake.
  3905. + */
  3906. +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
  3907. +{
  3908. + siginfo_t info;
  3909. + struct k_sigaction ka;
  3910. + int signr;
  3911. +
  3912. + current->thread.esp0 = (unsigned long) regs;
  3913. +
  3914. + if (!oldset)
  3915. + oldset = &current->blocked;
  3916. +
  3917. + signr = get_signal_to_deliver(&info, &ka, regs, NULL);
  3918. + if (signr > 0) {
  3919. + /* Whee! Actually deliver the signal. */
  3920. + handle_signal(signr, &ka, &info, oldset, regs);
  3921. + return 1;
  3922. + }
  3923. +
  3924. + /* Did we come from a system call? */
  3925. + if (regs->orig_d0 >= 0)
  3926. + /* Restart the system call - no handlers present */
  3927. + handle_restart(regs, NULL, 0);
  3928. +
  3929. + return 0;
  3930. +}
  3931. --- /dev/null
  3932. +++ b/arch/m68k/coldfire/traps.c
  3933. @@ -0,0 +1,454 @@
  3934. +/*
  3935. + * linux/arch/m68knommu/kernel/traps.c
  3936. + *
  3937. + * Copyright (C) 1993, 1994 by Hamish Macdonald
  3938. + *
  3939. + * 68040 fixes by Michael Rausch
  3940. + * 68040 fixes by Martin Apel
  3941. + * 68060 fixes by Roman Hodek
  3942. + * 68060 fixes by Jesper Skov
  3943. + *
  3944. + * This file is subject to the terms and conditions of the GNU General Public
  3945. + * License. See the file COPYING in the main directory of this archive
  3946. + * for more details.
  3947. + */
  3948. +
  3949. +/*
  3950. + * Sets up all exception vectors
  3951. + */
  3952. +#include <linux/sched.h>
  3953. +#include <linux/signal.h>
  3954. +#include <linux/kernel.h>
  3955. +#include <linux/mm.h>
  3956. +#include <linux/module.h>
  3957. +#include <linux/types.h>
  3958. +#include <linux/a.out.h>
  3959. +#include <linux/user.h>
  3960. +#include <linux/string.h>
  3961. +#include <linux/linkage.h>
  3962. +#include <linux/init.h>
  3963. +#include <linux/ptrace.h>
  3964. +#include <linux/kallsyms.h>
  3965. +
  3966. +#include <asm/setup.h>
  3967. +#include <asm/fpu.h>
  3968. +#include <asm/system.h>
  3969. +#include <asm/uaccess.h>
  3970. +#include <asm/traps.h>
  3971. +#include <asm/pgtable.h>
  3972. +#include <asm/machdep.h>
  3973. +#include <asm/siginfo.h>
  3974. +
  3975. +static char const * const vec_names[] = {
  3976. + "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
  3977. + "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
  3978. + "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
  3979. + "UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
  3980. + "FORMAT ERROR", "UNINITIALIZED INTERRUPT",
  3981. + "UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
  3982. + "UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
  3983. + "UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
  3984. + "UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
  3985. + "SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
  3986. + "LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
  3987. + "SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
  3988. + "TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
  3989. + "TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
  3990. + "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
  3991. + "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
  3992. + "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
  3993. + "FPCP UNSUPPORTED OPERATION",
  3994. + "MMU CONFIGURATION ERROR"
  3995. +};
  3996. +
  3997. +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
  3998. + unsigned long error_code);
  3999. +asmlinkage void trap_c(struct frame *fp);
  4000. +extern void __init coldfire_trap_init(void);
  4001. +
  4002. +void __init trap_init(void)
  4003. +{
  4004. + coldfire_trap_init();
  4005. +}
  4006. +
  4007. +/* The following table converts the FS encoding of a ColdFire
  4008. + exception stack frame into the error_code value needed by
  4009. + do_fault. */
  4010. +
  4011. +static const unsigned char fs_err_code[] = {
  4012. + 0, /* 0000 */
  4013. + 0, /* 0001 */
  4014. + 0, /* 0010 */
  4015. + 0, /* 0011 */
  4016. + 1, /* 0100 */
  4017. + 0, /* 0101 */
  4018. + 0, /* 0110 */
  4019. + 0, /* 0111 */
  4020. + 2, /* 1000 */
  4021. + 3, /* 1001 */
  4022. + 2, /* 1010 */
  4023. + 0, /* 1011 */
  4024. + 1, /* 1100 */
  4025. + 1, /* 1101 */
  4026. + 0, /* 1110 */
  4027. + 0 /* 1111 */
  4028. +};
  4029. +
  4030. +#ifdef DEBUG
  4031. +static const char *fs_err_msg[16] = {
  4032. + "Normal",
  4033. + "Reserved",
  4034. + "Interrupt during debug service routine",
  4035. + "Reserved",
  4036. + "X Protection",
  4037. + "TLB X miss (opword)",
  4038. + "TLB X miss (ext. word)",
  4039. + "IFP in emulator mode",
  4040. + "W Protection",
  4041. + "Write error",
  4042. + "TLB W miss",
  4043. + "Reserved",
  4044. + "R Protection",
  4045. + "R/RMW Protection",
  4046. + "TLB R miss",
  4047. + "OEP in emulator mode",
  4048. +};
  4049. +#endif
  4050. +
  4051. +static inline void access_errorCF(struct frame *fp)
  4052. +{
  4053. + unsigned long int mmusr, complainingAddress;
  4054. + unsigned int err_code, fs;
  4055. + int need_page_fault;
  4056. +
  4057. + mmusr = fp->ptregs.mmusr;
  4058. + complainingAddress = fp->ptregs.mmuar;
  4059. +#ifdef DEBUG
  4060. + printk(KERN_DEBUG "pc %#lx, mmusr %#lx, complainingAddress %#lx\n", \
  4061. + fp->ptregs.pc, mmusr, complainingAddress);
  4062. +#endif
  4063. +
  4064. + /*
  4065. + * error_code:
  4066. + * bit 0 == 0 means no page found, 1 means protection fault
  4067. + * bit 1 == 0 means read, 1 means write
  4068. + */
  4069. +
  4070. + fs = (fp->ptregs.fs2 << 2) | fp->ptregs.fs1;
  4071. + switch (fs) {
  4072. + case 5: /* 0101 TLB opword X miss */
  4073. + need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 0);
  4074. + complainingAddress = fp->ptregs.pc;
  4075. + break;
  4076. + case 6: /* 0110 TLB extension word X miss */
  4077. + need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 1);
  4078. + complainingAddress = fp->ptregs.pc + sizeof(long);
  4079. + break;
  4080. + case 10: /* 1010 TLB W miss */
  4081. + need_page_fault = cf_tlb_miss(&fp->ptregs, 1, 1, 0);
  4082. + break;
  4083. + case 14: /* 1110 TLB R miss */
  4084. + need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 1, 0);
  4085. + break;
  4086. + default:
  4087. + /* 0000 Normal */
  4088. + /* 0001 Reserved */
  4089. + /* 0010 Interrupt during debug service routine */
  4090. + /* 0011 Reserved */
  4091. + /* 0100 X Protection */
  4092. + /* 0111 IFP in emulator mode */
  4093. + /* 1000 W Protection*/
  4094. + /* 1001 Write error*/
  4095. + /* 1011 Reserved*/
  4096. + /* 1100 R Protection*/
  4097. + /* 1101 R Protection*/
  4098. + /* 1111 OEP in emulator mode*/
  4099. + need_page_fault = 1;
  4100. + break;
  4101. + }
  4102. +
  4103. + if (need_page_fault) {
  4104. + err_code = fs_err_code[fs];
  4105. + if ((fs == 13) && (mmusr & MMUSR_WF)) /* rd-mod-wr access */
  4106. + err_code |= 2; /* bit1 - write, bit0 - protection */
  4107. + do_page_fault(&fp->ptregs, complainingAddress, err_code);
  4108. + }
  4109. +}
  4110. +
  4111. +void die_if_kernel(char *str, struct pt_regs *fp, int nr)
  4112. +{
  4113. + if (!(fp->sr & PS_S))
  4114. + return;
  4115. +
  4116. + console_verbose();
  4117. + printk(KERN_EMERG "%s: %08x\n", str, nr);
  4118. + printk(KERN_EMERG "PC: [<%08lx>]", fp->pc);
  4119. + print_symbol(" %s", fp->pc);
  4120. + printk(KERN_EMERG "\nSR: %04x SP: %p a2: %08lx\n",
  4121. + fp->sr, fp, fp->a2);
  4122. + printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
  4123. + fp->d0, fp->d1, fp->d2, fp->d3);
  4124. + printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
  4125. + fp->d4, fp->d5, fp->a0, fp->a1);
  4126. +
  4127. + printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
  4128. + current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
  4129. + show_stack(NULL, (unsigned long *)fp);
  4130. + do_exit(SIGSEGV);
  4131. +}
  4132. +
  4133. +asmlinkage void buserr_c(struct frame *fp)
  4134. +{
  4135. + unsigned int fs;
  4136. +
  4137. + /* Only set esp0 if coming from user mode */
  4138. + if (user_mode(&fp->ptregs))
  4139. + current->thread.esp0 = (unsigned long) fp;
  4140. +
  4141. + fs = (fp->ptregs.fs2 << 2) | fp->ptregs.fs1;
  4142. +#if defined(DEBUG)
  4143. + printk(KERN_DEBUG "*** Bus Error *** (%x)%s\n", fs,
  4144. + fs_err_msg[fs & 0xf]);
  4145. +#endif
  4146. + switch (fs) {
  4147. + case 0x5:
  4148. + case 0x6:
  4149. + case 0x7:
  4150. + case 0x9:
  4151. + case 0xa:
  4152. + case 0xd:
  4153. + case 0xe:
  4154. + case 0xf:
  4155. + access_errorCF(fp);
  4156. + break;
  4157. + default:
  4158. + die_if_kernel("bad frame format", &fp->ptregs, 0);
  4159. +#if defined(DEBUG)
  4160. + printk(KERN_DEBUG "Unknown SIGSEGV - 4\n");
  4161. +#endif
  4162. + force_sig(SIGSEGV, current);
  4163. + }
  4164. +}
  4165. +
  4166. +
  4167. +int kstack_depth_to_print = 48;
  4168. +
  4169. +void show_stack(struct task_struct *task, unsigned long *stack)
  4170. +{
  4171. + unsigned long *endstack, addr, symaddr;
  4172. + extern char _start, _etext;
  4173. + int i;
  4174. +
  4175. + if (!stack) {
  4176. + if (task)
  4177. + stack = (unsigned long *)task->thread.ksp;
  4178. + else
  4179. + stack = (unsigned long *)&stack;
  4180. + }
  4181. +
  4182. + addr = (unsigned long) stack;
  4183. + endstack = (unsigned long *) PAGE_ALIGN(addr);
  4184. +
  4185. + printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
  4186. + for (i = 0; i < kstack_depth_to_print; i++) {
  4187. + if (stack + 1 > endstack)
  4188. + break;
  4189. + if (i % 8 == 0)
  4190. + printk("\n" KERN_EMERG " ");
  4191. + symaddr = *stack;
  4192. + printk(KERN_EMERG " %08lx", *stack++);
  4193. + if ((symaddr >= 0xc0000000) && (symaddr < 0xc1000000))
  4194. + print_symbol("(%s)", symaddr);
  4195. + }
  4196. + printk("\n");
  4197. +
  4198. + printk(KERN_EMERG "Call Trace:");
  4199. + i = 0;
  4200. + while (stack + 1 <= endstack) {
  4201. + addr = *stack++;
  4202. + /*
  4203. + * If the address is either in the text segment of the
  4204. + * kernel, or in the region which contains vmalloc'ed
  4205. + * memory, it *may* be the address of a calling
  4206. + * routine; if so, print it so that someone tracing
  4207. + * down the cause of the crash will be able to figure
  4208. + * out the call path that was taken.
  4209. + */
  4210. + if (((addr >= (unsigned long) &_start) &&
  4211. + (addr <= (unsigned long) &_etext))) {
  4212. + if (i % 4 == 0)
  4213. + printk("\n" KERN_EMERG " ");
  4214. + printk(KERN_EMERG " [<%08lx>]", addr);
  4215. + i++;
  4216. + }
  4217. + }
  4218. + printk("\n");
  4219. +}
  4220. +
  4221. +void bad_super_trap(struct frame *fp)
  4222. +{
  4223. + console_verbose();
  4224. + if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
  4225. + printk(KERN_WARNING "*** %s *** FORMAT=%X\n",
  4226. + vec_names[(fp->ptregs.vector) >> 2],
  4227. + fp->ptregs.format);
  4228. + else
  4229. + printk(KERN_WARNING "*** Exception %d *** FORMAT=%X\n",
  4230. + (fp->ptregs.vector) >> 2,
  4231. + fp->ptregs.format);
  4232. + printk(KERN_WARNING "Current process id is %d\n", current->pid);
  4233. + die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
  4234. +}
  4235. +
  4236. +asmlinkage void trap_c(struct frame *fp)
  4237. +{
  4238. + int sig;
  4239. + siginfo_t info;
  4240. +
  4241. + if (fp->ptregs.sr & PS_S) {
  4242. + if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
  4243. + /* traced a trapping instruction */
  4244. + current->ptrace |= PT_DTRACE;
  4245. + } else
  4246. + bad_super_trap(fp);
  4247. + return;
  4248. + }
  4249. +
  4250. + /* send the appropriate signal to the user program */
  4251. + switch ((fp->ptregs.vector) >> 2) {
  4252. + case VEC_ADDRERR:
  4253. + info.si_code = BUS_ADRALN;
  4254. + sig = SIGBUS;
  4255. + break;
  4256. + case VEC_ILLEGAL:
  4257. + case VEC_LINE10:
  4258. + case VEC_LINE11:
  4259. + info.si_code = ILL_ILLOPC;
  4260. + sig = SIGILL;
  4261. + break;
  4262. + case VEC_PRIV:
  4263. + info.si_code = ILL_PRVOPC;
  4264. + sig = SIGILL;
  4265. + break;
  4266. + case VEC_COPROC:
  4267. + info.si_code = ILL_COPROC;
  4268. + sig = SIGILL;
  4269. + break;
  4270. + case VEC_TRAP1: /* gdbserver breakpoint */
  4271. + fp->ptregs.pc -= 2;
  4272. + info.si_code = TRAP_TRACE;
  4273. + sig = SIGTRAP;
  4274. + break;
  4275. + case VEC_TRAP2:
  4276. + case VEC_TRAP3:
  4277. + case VEC_TRAP4:
  4278. + case VEC_TRAP5:
  4279. + case VEC_TRAP6:
  4280. + case VEC_TRAP7:
  4281. + case VEC_TRAP8:
  4282. + case VEC_TRAP9:
  4283. + case VEC_TRAP10:
  4284. + case VEC_TRAP11:
  4285. + case VEC_TRAP12:
  4286. + case VEC_TRAP13:
  4287. + case VEC_TRAP14:
  4288. + info.si_code = ILL_ILLTRP;
  4289. + sig = SIGILL;
  4290. + break;
  4291. + case VEC_FPBRUC:
  4292. + case VEC_FPOE:
  4293. + case VEC_FPNAN:
  4294. + info.si_code = FPE_FLTINV;
  4295. + sig = SIGFPE;
  4296. + break;
  4297. + case VEC_FPIR:
  4298. + info.si_code = FPE_FLTRES;
  4299. + sig = SIGFPE;
  4300. + break;
  4301. + case VEC_FPDIVZ:
  4302. + info.si_code = FPE_FLTDIV;
  4303. + sig = SIGFPE;
  4304. + break;
  4305. + case VEC_FPUNDER:
  4306. + info.si_code = FPE_FLTUND;
  4307. + sig = SIGFPE;
  4308. + break;
  4309. + case VEC_FPOVER:
  4310. + info.si_code = FPE_FLTOVF;
  4311. + sig = SIGFPE;
  4312. + break;
  4313. + case VEC_ZERODIV:
  4314. + info.si_code = FPE_INTDIV;
  4315. + sig = SIGFPE;
  4316. + break;
  4317. + case VEC_CHK:
  4318. + case VEC_TRAP:
  4319. + info.si_code = FPE_INTOVF;
  4320. + sig = SIGFPE;
  4321. + break;
  4322. + case VEC_TRACE: /* ptrace single step */
  4323. + info.si_code = TRAP_TRACE;
  4324. + sig = SIGTRAP;
  4325. + break;
  4326. + case VEC_TRAP15: /* breakpoint */
  4327. + info.si_code = TRAP_BRKPT;
  4328. + sig = SIGTRAP;
  4329. + break;
  4330. + default:
  4331. + info.si_code = ILL_ILLOPC;
  4332. + sig = SIGILL;
  4333. + break;
  4334. + }
  4335. + info.si_signo = sig;
  4336. + info.si_errno = 0;
  4337. + switch (fp->ptregs.format) {
  4338. + default:
  4339. + info.si_addr = (void *) fp->ptregs.pc;
  4340. + break;
  4341. + case 2:
  4342. + info.si_addr = (void *) fp->un.fmt2.iaddr;
  4343. + break;
  4344. + case 7:
  4345. + info.si_addr = (void *) fp->un.fmt7.effaddr;
  4346. + break;
  4347. + case 9:
  4348. + info.si_addr = (void *) fp->un.fmt9.iaddr;
  4349. + break;
  4350. + case 10:
  4351. + info.si_addr = (void *) fp->un.fmta.daddr;
  4352. + break;
  4353. + case 11:
  4354. + info.si_addr = (void *) fp->un.fmtb.daddr;
  4355. + break;
  4356. + }
  4357. + force_sig_info(sig, &info, current);
  4358. +}
  4359. +
  4360. +asmlinkage void set_esp0(unsigned long ssp)
  4361. +{
  4362. + current->thread.esp0 = ssp;
  4363. +}
  4364. +
  4365. +/*
  4366. + * The architecture-independent backtrace generator
  4367. + */
  4368. +void dump_stack(void)
  4369. +{
  4370. + unsigned long stack;
  4371. +
  4372. + show_stack(current, &stack);
  4373. +}
  4374. +EXPORT_SYMBOL(dump_stack);
  4375. +
  4376. +#ifdef CONFIG_M68KFPU_EMU
  4377. +asmlinkage void fpemu_signal(int signal, int code, void *addr)
  4378. +{
  4379. + siginfo_t info;
  4380. +
  4381. + info.si_signo = signal;
  4382. + info.si_errno = 0;
  4383. + info.si_code = code;
  4384. + info.si_addr = addr;
  4385. + force_sig_info(signal, &info, current);
  4386. +}
  4387. +#endif
  4388. --- /dev/null
  4389. +++ b/arch/m68k/coldfire/vmlinux-cf.lds
  4390. @@ -0,0 +1,92 @@
  4391. +/* ld script to make m68k Coldfire Linux kernel */
  4392. +
  4393. +#include <asm-generic/vmlinux.lds.h>
  4394. +
  4395. +OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
  4396. +OUTPUT_ARCH(m68k)
  4397. +ENTRY(_start)
  4398. +jiffies = jiffies_64 + 4;
  4399. +SECTIONS
  4400. +{
  4401. + . = 0xC0020000;
  4402. + _text = .; /* Text and read-only data */
  4403. + .text : {
  4404. + *(.text.head)
  4405. + TEXT_TEXT
  4406. + SCHED_TEXT
  4407. + LOCK_TEXT
  4408. + *(.fixup)
  4409. + *(.gnu.warning)
  4410. + } :text = 0x4e75
  4411. +
  4412. + _etext = .; /* End of text section */
  4413. +
  4414. + . = ALIGN(16);
  4415. + __start___ex_table = .;
  4416. + __ex_table : { *(__ex_table) }
  4417. + __stop___ex_table = .;
  4418. +
  4419. + RODATA
  4420. +
  4421. + .data : { /* Data */
  4422. + DATA_DATA
  4423. + CONSTRUCTORS
  4424. + }
  4425. +
  4426. + .bss : { *(.bss) } /* BSS */
  4427. +
  4428. + . = ALIGN(16);
  4429. + .data.cacheline_aligned : { *(.data.cacheline_aligned) } :data
  4430. +
  4431. + _edata = .; /* End of data section */
  4432. +
  4433. + . = ALIGN(8192); /* Initrd */
  4434. + __init_begin = .;
  4435. + .init.text : {
  4436. + _sinittext = .;
  4437. + *(.init.text)
  4438. + _einittext = .;
  4439. + }
  4440. + .init.data : { *(.init.data) }
  4441. + . = ALIGN(16);
  4442. + __setup_start = .;
  4443. + .init.setup : { *(.init.setup) }
  4444. + __setup_end = .;
  4445. + __initcall_start = .;
  4446. + .initcall.init : {
  4447. + INITCALLS
  4448. + }
  4449. + __initcall_end = .;
  4450. + __con_initcall_start = .;
  4451. + .con_initcall.init : { *(.con_initcall.init) }
  4452. + __con_initcall_end = .;
  4453. + SECURITY_INIT
  4454. +#ifdef CONFIG_BLK_DEV_INITRD
  4455. + . = ALIGN(8192);
  4456. + __initramfs_start = .;
  4457. + .init.ramfs : { *(.init.ramfs) }
  4458. + __initramfs_end = .;
  4459. +#endif
  4460. + . = ALIGN(8192);
  4461. + __init_end = .;
  4462. +
  4463. + .data.init_task : { *(.data.init_task) } /* The initial task and kernel stack */
  4464. +
  4465. + _end = . ;
  4466. +
  4467. + /* Sections to be discarded */
  4468. + /DISCARD/ : {
  4469. + *(.exit.text)
  4470. + *(.exit.data)
  4471. + *(.exitcall.exit)
  4472. + }
  4473. +
  4474. + /* Stabs debugging sections. */
  4475. + .stab 0 : { *(.stab) }
  4476. + .stabstr 0 : { *(.stabstr) }
  4477. + .stab.excl 0 : { *(.stab.excl) }
  4478. + .stab.exclstr 0 : { *(.stab.exclstr) }
  4479. + .stab.index 0 : { *(.stab.index) }
  4480. + .stab.indexstr 0 : { *(.stab.indexstr) }
  4481. + .comment 0 : { *(.comment) }
  4482. +}